SLOPSHOPPER

AI-DLC ids

Keeps an AI-DLC project's own id map (US, AC, FR, NFR, BR, Q, U, C, E, ADR, R and the rest): /aidlc-ids:sync builds or brings it up to date without a model…

newcommandprocess
v0.1.0no licenseupdated 2026-10-26maksymskuibida/mskuibida-ai-tools/plugins/aidlc-ids
A shopper browsing a rack in a slop shop
README

aidlc-ids

Every id an AI-DLC project's documents define (US1.1, AC1.1.2, FR1.4, NFR3, BR1.2, Q4, U31, C2, E7, ADR-009, R-01 and the rest) becomes, on the plugins' pages, a link with a tooltip saying what it is. This plugin keeps the map those pages read: for each id, its kind, its title, the start of its text and the document that defines it.

/aidlc-ids:sync            build the map, or bring it up to date (only changed documents are read again)
/aidlc-ids:sync --force    build it from scratch

The command runs without a model turn, so it costs no tokens. Agents run the same script before they build a page:

python3 "${CLAUDE_PLUGIN_ROOT}/scripts/aidlc_ids.py" sync

The map is kept outside the project, in ~/.claude/plugins/data/aidlc-ids/maps/<checkout>/<space>--<intent>.json: one per checkout, as a worktree's branch may hold other documents. AIDLC_IDS_DIR moves the folder. Nothing of a project is in the plugin.

The plugins that draw pages (approval-gates, question-forms, story-points, review-findings) carry their own copy of the script, so they work without this plugin; the map they read and write is the same file. How a page uses it, and which of several definitions of an id it gets (every stage has its own Q1, every Unit its own BR1.1), is in shared/aidlc-ids/README.md.

Install

claude plugin marketplace add maksymskuibida/mskuibida-ai-tools
claude plugin install aidlc-ids@mskuibida-tooling

Tests

python3 -m unittest scripts/tests/test_sync_shared.py
claude plugin test plugins/aidlc-ids
Source 1 files
hooks/register.ts 34 lines
1import type { EngineInterface, Register } from 'claude-code'
2
3// /aidlc-ids:sync builds or brings up to date the id map of the session's AI-DLC project, without a model turn: the
4// command runs scripts/aidlc_ids.py sync and answers with what it printed. Agents run the same script before they
5// build a page; the command is for the developer, and for a session that wants the map fresh without spending tokens.
6
7const COMMAND = 'sync'
8
9async function sync($: EngineInterface, args: string): Promise<string> {
10  const argv = ['python3', `${$.plugin.root}/scripts/aidlc_ids.py`, 'sync']
11  if (/(^|\s)--force(\s|$)/.test(args)) argv.push('--force')
12  const proc = $.process.spawn({ argv, cwd: await $.session.cwd() })
13  let out = ''
14  for await (const { text } of proc) out += text
15  const done = await proc.result
16
17  return done.code === 0 ? out.trim() : `The id map could not be synced: ${out.trim() || `exit ${done.code}`}`
18}
19
20export const register: Register = on => {
21  on('session.start', async ($, e, next) => {
22    await $.command.register({
23      name: COMMAND,
24      description: "Build or bring up to date this AI-DLC project's id map (US, AC, FR, NFR, BR, Q, U, ADR, ...)",
25      argumentHint: '[--force]',
26      immediate: true,
27    })
28
29    return next(e)
30  })
31
32  on('command.run', { command: COMMAND }, async ($, e) => ({ text: await sync($, e.args) }))
33}
34