* refactor: tighten sdk-first architecture seams Refs #3312 * refactor: finish state document seam cleanup Refs #3312 * test: harden minimal install cleanup assertion * ci: support sdk-scoped package lock * fix(3316): restore root package-lock.json and align changeset pr ref Reverts dec57a83 ("ci: support sdk-scoped package lock") and restores the root package-lock.json that c249d34d deleted. The deletion was the wrong direction: - The root package.json declares its own runtime and dev deps (@anthropic-ai/claude-agent-sdk, ws, c8). Without a root lockfile, `npm install --no-package-lock` resolves whatever satisfies semver at install time — CI today and CI in six months can install different transitive trees, defeating reproducibility. - The lockfile has been part of every release on this repo (long history on main); removing it loses the npm audit / Dependabot target without compensating benefit. - The CI workaround pattern (cache-dependency-path: sdk/package-lock.json + `npm install --no-package-lock`) papered over the symptom rather than fix the cause. Also fix the changeset pr: from 3312 (issue) to 3316 (PR). CONTEXT.md flags this exact failure mode as a recurring CodeRabbit finding. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: address coderabbit review findings * fix: close remaining coderabbit threads --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
41 KiB
Query handler conventions (sdk/src/query/)
This document records contracts for the typed query layer consumed by gsd-sdk query and programmatic createRegistry() callers.
Registry coverage vs gsd-tools.cjs
- In scope: Native handlers are registered in
createRegistry()(index.ts) so SDK output can matchget-shit-done/bin/gsd-tools.cjsJSON (seesdk/src/golden/). - Explicitly not registered (product decision):
**graphify**,**from-gsd2**/**gsd2-import**— remain CLI-only. - CLI name differences (same behavior, different dispatch string):
- CJS
**summary-extract**→ SDK**summary.extract**/**summary extract**/**history-digest**(seeindex.ts). - CJS top-level
**scaffold <type> ...**→ SDK**phase.scaffold**/**phase scaffold**with the scaffold type as the first argument (no separatescaffoldalias on the registry).
- CJS
Manifest-backed family ownership
These families are sourced from command-manifest.*.ts files and expanded into generated alias artifacts (command-aliases.generated.ts + CJS mirror):
state.*→command-manifest.state.tsverify.*→command-manifest.verify.tsinit.*→command-manifest.init.tsphase.*→command-manifest.phase.tsphases.*→command-manifest.phases.tsvalidate.*→command-manifest.validate.tsroadmap.*→command-manifest.roadmap.ts
CJS routing seams mirror these families with thin adapters (state/verify/init/phase/phases/validate/roadmap-command-router.cjs) so gsd-tools.cjs stays orchestration-only.
SDK Runtime Bridge Module (GSDTools path)
GSDTools dispatch routes through sdk/src/query-runtime-bridge.ts.
- Native registry dispatch is preferred at the bridge seam.
- Subprocess fallback is explicit (
allowFallbackToSubprocess), not implicit. strictSdkcan fail fast when a command has no native adapter.onDispatchEventemits structured dispatch observability (query_dispatch/query_hotpath_dispatch) with dispatch mode, fallback reason, latency, outcome, and error kind.
gsd-sdk query routing
normalizeQueryCommand()(query-command-resolution-strategy.ts) — maps the first argv tokens to the same command + subcommand patterns asgsd-toolsrunCommand()where needed (e.g.state json→state.json,init execute-phase 9→init.execute-phasewith args['9'],scaffold …→phase.scaffold). Re-exported from@gsd-build/sdkandcreateRegistry’s module (sdk/src/query/index.ts) so programmatic callers can mirror CLI tokenization without importing a deep path.resolveQueryArgv()(registry.ts) — longest-prefix match on the normalized argv: tries joined keysa.b.cthena b cfor each prefix length, longest first. Example:state update status X→ handlerstate.updatewith args[status, X].- Dotted single token: one token like
init.new-projectmatches the registry; if the first pass finds no handler, a single dotted token is split and matching runs again. - CJS fallback (CLI): if nothing matches a registered handler and
GSD_QUERY_FALLBACKis notoff/never/false/0, the CLI shells out togsd-tools.cjswith argv derived from the normalized tokens (dotted commands are split into CJS-style segments). stderr receives a short bridge warning. SetGSD_QUERY_FALLBACK=offfor strict mode (parity tests). CLI-only commands such asgraphifyrely on this path until native handlers exist. - Output: JSON written to stdout for successful handler results.
Registered: phase.add-batch / phase add-batch — batch append (see phaseAddBatch in phase-lifecycle.ts).
Error handling
- Validation and programmer errors: Handlers throw
GSDErrorwith anErrorClassification(e.g. missing required args, invalid phase). The Dispatch Policy Module maps native failures into structured dispatch errors. - Expected domain failures: Handlers return
{ data: { error: string, ... } }for cases that are not exceptional in normal use (file not found, intel disabled, todo missing, etc.). Callers must checkdata.errorwhen present. - Do not mix both styles for the same failure mode in new code: prefer throw for "caller must fix input"; prefer
**data.error** for "operation could not complete in this project state."
Dispatch Policy Module contract
runQueryDispatch() returns a structured union contract:
- success:
{ ok: true, stdout, stderr, exit_code: 0 } - failure:
{ ok: false, error: { kind, code, message, details }, stderr, exit_code }
Current error kind values:
unknown_commandnative_failurenative_timeoutfallback_failurevalidation_errorinternal_error
CLI is a thin adapter over this seam and uses exit_code directly.
Mutation commands and events
QUERY_MUTATION_COMMANDSinindex.tslists every command name (including space-delimited aliases) that performs durable writes. It drives optionalGSDEventStreamwrapping so mutations emit structured events.- Init composition handlers (
init.*) are not included: they return JSON for workflows; agents perform filesystem work. **state.validate** is read-only — not listed inQUERY_MUTATION_COMMANDS.**skill-manifest**: writes to disk only when invoked with**--write**. It is not inQUERY_MUTATION_COMMANDS, so conditional writes do not emit mutation events today. If event consumers needskill-manifestwrites, add a follow-up that either registers a dedicated command name for the write path or documents the exception.
Intel: intel.update
**intel.update** /**intel update**matches CJSintel.cjsintelUpdateJSON (not an in-process graph refresh): when intel is enabled it returns{ action: 'spawn_agent', message: '...' }; when disabled,{ disabled: true, message: '...' }. The gsd-intel-updater agent performs the actual refresh after spawn. Golden tests use fulltoEqualvsgsd-tools.cjson this repo’s intel config.
Session correlation (sessionId)
createRegistry(eventStream, sessionId)threads the optionalsessionIdstring into mutation-related events emitted viaeventStream.GSDToolsacceptssessionIdin its constructor and forwards it tocreateRegistry;GSDacceptssessionIdinGSDOptionsand passes it throughcreateTools(). When omitted,sessionIdis empty.
Lockfiles (state-mutation.ts)
STATE.md(and ROADMAP) locks use a sibling.lockfile with the holder's PID. Stale locks are cleared when the PID no longer exists (process.kill(pid, 0)fails) or when the lock file is older than the existing time-based threshold.
Intel JSON search
searchJsonEntriesinintel.tscaps recursion depth (MAX_JSON_SEARCH_DEPTH) to avoid stack overflow on pathological nested JSON.
Phase / plan listing (SDK-only)
No gsd-tools.cjs mirror — agents use these instead of shell ls/find/grep:
**phase.list-plans**<phase>[**--with-schema**<yamlKey>] — PLAN files in the phase dir; optional filter when a frontmatter key is present (phase-list-queries.ts).**phase.list-artifacts**<phase>**--type**context|summary|verification|research— matching*-CONTEXT.md,*-SUMMARY.md, etc.**plan.task-structure**<path-to-PLAN.md>— wave,depends_on, task/checkpoint counts viaparsePlan().**requirements.extract-from-plans**<phase>— dedupedrequirements:frontmatter across plans.
State extensions (Phase 3)
Handlers for **state.signal-waiting**, **state.signal-resume**, **state.validate**, **state.sync** (supports --verify dry-run), and **state.prune** live in state-mutation.ts, with dotted and state … space aliases in index.ts.
state.add-roadmap-evolution (bug #2662) — appends one entry to the ### Roadmap Evolution subsection under ## Accumulated Context in STATE.md, creating the subsection if missing. argv: --phase, --action (inserted|removed|moved|edited|added), optional --note, --after (for inserted), and --urgent flag. Returns { added: true, entry } or { added: false, reason: 'duplicate', entry }. Throws GSDError(Validation) when --phase / --action are missing or action is not in the allowed set. Canonical replacement for raw Edit/Write on STATE.md in insert-phase.md / add-phase.md workflows — required when projects ship a protect-files.sh PreToolUse hook that blocks direct STATE.md writes.
state.json vs state.load (different CJS commands):
state.json/state json— port ofcmdStateJson(state.tsstateJson): rebuilt STATE.md frontmatter JSON. Read-only golden:read-only-parity.integration.test.tscompares to CJSstate jsonwithlast_updatedstripped.state.load/state load— port ofcmdStateLoad(state-project-load.tsstateProjectLoad):{ config, state_raw, state_exists, roadmap_exists, config_exists };configcomes fromget-shit-done/bin/lib/core.cjsloadConfig, but discovery now routes through the SDK Package Seam Module (sdk-package-compatibility.ts) so install-layout probing stays behind one compatibility Adapter. Read-only golden: fulltoEqualvsstate load. Ifcore.cjscannot be resolved, dispatch throwsGSDErrorwith the checked probe list (document for minimal@gsd-build/sdk-only installs).
stateExtractField in state-document.ts (re-exported by helpers.ts) uses horizontal whitespace only after Field: so YAML keys such as lowercase progress: in frontmatter are not mistaken for the body Progress: line (see get-shit-done/bin/lib/state-document.cjs — same rule).
Golden parity: coverage and exceptions
Subprocess reference: captureGsdToolsOutput() / captureGsdToolsStdout() → get-shit-done/bin/gsd-tools.cjs (sdk/src/golden/capture.ts). Plain-text commands (e.g. config-path) use stdout string comparison in read-only-parity.integration.test.ts.
Authoritative accounting (every canonical handler): sdk/src/golden/golden-policy.ts merges golden-integration-covered.ts (canonicals hit by golden.integration.test.ts) with read-only-golden-rows.ts / special cases (verify.commits, config-path) into GOLDEN_PARITY_INTEGRATION_COVERED, and builds GOLDEN_PARITY_EXCEPTIONS for the rest. getCanonicalRegistryCommands() (registry-canonical-commands.ts) lists one dispatch string per unique handler; each canonical must be either covered or receive a built-in exception string (mutations → shared rationale; read-only without a subprocess row → per-command note). sdk/src/golden/golden-policy.test.ts calls verifyGoldenPolicyComplete() so the policy cannot drift silently.
Integration test files:
| File | Role |
|---|---|
sdk/src/golden/golden.integration.test.ts |
Primary golden suite: subset/shape/full parity as documented in the tables below. |
sdk/src/golden/read-only-parity.integration.test.ts |
Read-only handlers with full toEqual on sdkResult.data vs CJS JSON; rows listed in read-only-golden-rows.ts. Also config-path / verify.commits, dedicated blocks for state.json (strip last_updated) and state.load (full cmdStateLoad parity). |
This section summarizes how each covered command is compared so readers do not have to infer rules from assertions alone.
Golden registry coverage matrix (human summary)
- Covered by subprocess golden — canonical names appear in
GOLDEN_PARITY_INTEGRATION_COVERED; see the tables below and the two integration files for assertion style (mostly fulltoEqual; remaining subset cases:frontmatter.get,find-phase). - Not in covered set — either listed in
QUERY_MUTATION_COMMANDS(durable writes; handler tests insdk/src/query/*.test.tsand mutation-focused tests) or a read-only handler whose full CJS JSON match is deferred (see auto-generated exception text ingolden-policy.ts).
Full JSON equality (toEqual on result data)
These tests expect sdkResult.data to match the parsed CJS stdout JSON (possibly after shared normalization helpers):
| SDK dispatch (representative) | Notes |
|---|---|
generate-slug |
Includes fixture + multi-word cases. |
config-get |
Sample: top-level key model_profile. |
config-set |
Temp .planning/ tree; reset between CJS capture and SDK dispatch; toEqual on { updated, key, value, previousValue? }. |
state.validate |
Full object parity. |
state.sync |
With --verify (dry-run); full object parity. |
detect-custom-files |
Temp --config-dir fixture; full object parity. |
roadmap.analyze / progress |
Full object parity (progress uses progress json CJS path). |
frontmatter.validate |
Plan schema fixture under .planning/phases/11-state-mutations/. |
verify.plan-structure / validate.consistency / verify.phase-completeness |
Full object parity on representative repo paths. |
init.execute-phase / init.plan-phase / init.resume / init.verify-work |
Full toEqual vs CJS. |
init.quick |
Full parity after stripping quick_id, timestamp, branch_name, task_dir (init-golden-normalize.ts). |
intel.update |
Full toEqual vs CJS for this project (disabled vs spawn-hint payload per intel.cjs). |
From read-only-parity.integration.test.ts (full toEqual on this repo):
| SDK dispatch (canonical) | Notes |
|---|---|
resolve-model |
Args e.g. gsd-planner. |
phase-plan-index |
Phase number arg. |
roadmap.get-phase |
Phase number arg. |
list.todos |
No args. |
phase.next-decimal |
Phase number arg. |
phases.list |
No args. |
verify.summary |
Plan path. |
verify.path-exists |
Path under repo. |
verify.artifacts |
Plan path. |
verify.commits |
Two git SHAs (HEAD~1 / HEAD or fallback). |
websearch |
Limited query (may hit network — test uses small limit). |
workstream.get / workstream.list / workstream.status |
Default workstream where applicable (status uses full CJS shape when the workstream dir exists). |
learnings.list |
No args. |
intel.status |
No args. |
intel.diff / intel.validate / intel.query |
When intel is disabled, disabled payload matches CJS (including message text). |
init.list-workspaces |
No args. |
agent-skills |
No agent type → JSON "" (same as CJS). |
scan-sessions |
--json; SDK scanSessions output matches CJS project array (profile-scan-sessions.ts). |
summary.extract |
Fixture sdk/src/golden/fixtures/summary-extract-sample.md; uses extractFrontmatterLeading (first --- block) for parity with frontmatter.cjs. |
history.digest |
No args; aggregate over .planning/phases + archived milestone phase dirs (commands.cjs cmdHistoryDigest). |
audit-uat |
No args; full JSON parity with uat.cjs cmdAuditUat (results, summary with by_category / by_phase). |
skill-manifest |
No args; full manifest parity with init.cjs buildSkillManifest / cmdSkillManifest. Handler uses extractFrontmatterLeading (first --- block) like CJS frontmatter.cjs extractFrontmatter — not TS extractFrontmatter (last block), so skills with multiple --- sections match CJS. Runtime-global skill roots now route through the Runtime-Global Skills Policy Module; legacy import-only skill root discovery (~/.claude/get-shit-done/skills) routes through the SDK Package Seam Module. |
validate.agents |
No args; agents_dir matches core.cjs getAgentsDir (GSD_AGENTS_DIR or sdk/dist/query/../../../agents in this monorepo — same absolute path as CLI). MODEL_PROFILES / expected list stays aligned with get-shit-done/bin/lib/model-profiles.cjs. |
agent-skills |
Reads config.agent_skills[agentType] and emits raw <agent_skills> XML. Project-relative entries stay project-root validated; global:<name> resolves through the Runtime-Global Skills Policy Module instead of a Claude-only path. |
state.get |
Dedicated tests: no args → full { content } vs state get; one field (milestone) → { milestone: "…" } vs state get milestone (frontmatter line match). |
state.json |
state json vs SDK; last_updated stripped before toEqual (volatile). |
state.load |
state load vs SDK; full cmdStateLoad object graph (config, state_raw, existence flags). |
uat.render-checkpoint |
Fixture sdk/src/golden/fixtures/uat-render-checkpoint-sample.md; full JSON parity with uat.cjs cmdRenderCheckpoint (file_path, test_number, test_name, checkpoint — same box + buildCheckpoint text as CJS; sanitizeForDisplay on name/expected). |
config-path |
Plain stdout path vs { path } — compared with path.normalize in tests. |
Normalized or field-omitted comparison
| SDK / test | Rule |
|---|---|
audit-open |
audit-open --json: **scanned_at** stripped before toEqual (volatile ISO time). sanitizeForDisplay in audit-open.ts matches security.cjs (CRLF body lines can leave \r in items.todos[].summary, matching CLI). |
extract.messages / extract-messages |
Fixture sdk/src/golden/fixtures/extract-messages-sessions/ passed as --path (sessions root). **output_file** stripped before toEqual (temp path under os.tmpdir()); then the two JSONL files are compared byte-for-byte. Parity with profile-pipeline.cjs cmdExtractMessages (streamExtractMessages, isGenuineUserMessage, batch limit 300). |
docs-init |
existing_docs sorted by path before compare; **agents_installed** and **missing_agents** omitted (subprocess vs in-process path resolution for ~/.claude/...). |
Structural, subset, or shape-only parity
Assertions deliberately compare only selected fields (not full toEqual):
| SDK dispatch (representative) | What is compared |
|---|---|
frontmatter.get |
Scalar fields phase, plan, type; same top-level key set as CJS. |
find-phase |
found, directory, phase_number, phase_name, plans (SDK payload is a subset of CJS — extra CJS fields ignored). |
template.select is not in golden.integration.test.ts: CJS template select <plan-path> scores PLAN content for summary templates; SDK template.select <phase> uses phase-directory heuristics — different algorithms. Covered in sdk/src/query/template.test.ts.
Time- and environment-dependent
| Command | Rule |
|---|---|
current-timestamp |
**full**: same shape and valid ISO strings; not the same instant. **date**: same calendar day when the test does not cross midnight. **filename**: full toEqual (back-to-back capture vs SDK). |
Conditional writes (not in QUERY_MUTATION_COMMANDS)
| Command | Rule |
|---|---|
skill-manifest |
Disk writes only with **--write**; registry does not emit mutation events for this command (see Mutation commands and events above). |
Registered but not in the golden suite
Handlers in createRegistry() that are not covered by golden.integration.test.ts are not automatically “non-parity” — they simply have no automated cross-check against CJS yet. Add golden tests when tightening coverage; until then, treat absence here as a test gap, not a behavior guarantee.
Decision routing (SDK-only)
These handlers implement .planning/research/decision-routing-audit.md — no gsd-tools.cjs mirror yet (orchestration JSON only). Invoke via gsd-sdk query / registry.dispatch() after normalizeQueryCommand() where argv uses check … / detect … / route … prefixes.
Tier 1
| Dispatch | Purpose |
|---|---|
check.config-gates / check config-gates [workflow] |
Single JSON blob of merged workflow.* (+ context_window) for batch config gates. |
check.phase-ready / check phase-ready <phase> |
Phase directory stats, dependencies_met, next_step (discuss / plan / execute / verify / complete). |
route.next-action / route next-action |
Suggested next slash command from next.md-style rules (/gsd-discuss-phase, /gsd-execute-phase, /gsd-resume-work, gates, etc.). |
Tier 2
| Dispatch | Purpose |
|---|---|
check.auto-mode / check auto-mode |
active (OR of workflow.auto_advance and workflow._auto_chain_active), source (none / auto_advance / auto_chain / both), plus the two booleans. Replaces paired config-get calls in checkpoint and auto-advance steps. Use --pick active or --pick auto_chain_active when a workflow only needs one field. |
detect.phase-type / detect phase-type <phase> |
Structured UI/schema/API/infra detection for a phase. Returns has_frontend, frontend_indicators, has_schema, schema_orm, schema_files, has_api, has_infra, push_command (null, reserved). Replaces fragile grep-based UI detection in autonomous.md, plan-phase.md, etc. (audit §3.6). |
check.completion / check completion <phase|milestone> <id> |
Phase or milestone completion rollup. Phase mode: plans_total, plans_with_summaries, missing_summaries, verification_status, uat_status, debt (uat_gaps, verification_failures, human_needed), complete. Milestone mode: phase_count, phases_complete, phases_incomplete, complete. Replaces PLAN/SUMMARY counting in transition.md, complete-milestone.md (audit §3.7). |
Tier 3
| Dispatch | Purpose |
|---|---|
check.gates / check gates <workflow> [--phase <N>] |
Safety gate consolidation. Checks .continue-here.md presence (blocker), STATE.md error/failed status (blocker), and VERIFICATION.md FAIL rows (warning). Returns passed, blockers, warnings. Replaces per-workflow gate logic in next.md, execute-phase.md, discuss-phase.md (audit §3.2). SDK-only — no CJS mirror. |
check.verification-status / check verification-status <phase> |
VERIFICATION.md parser. Returns status (pass/fail/partial/missing), score (e.g. "3/4"), gaps, human_items, deferred. Handles prefixed filenames and missing files. Replaces VERIFICATION.md grep/parse in execute-phase.md, autonomous.md, progress.md (audit §3.8). SDK-only — no CJS mirror. |
check.ship-ready / check ship-ready <phase> |
Ship preflight: clean_tree, on_feature_branch, current_branch, base_branch, remote_configured, gh_available, gh_authenticated (always false — advisory, no network call), verification_passed, blockers, ready. Replaces ship.md preflight checks (audit §3.9). SDK-only — no CJS mirror. |
Stability: Shapes are versioned with the audit doc; add integration tests when workflows adopt these queries. Re-run after file writes that change .planning/ (stale read caveat in audit §6). All Tier 1–3 handlers are implemented and unit-tested.
CJS command surface vs SDK registry
Authoritative CJS entry points: runCommand switch (command) in get-shit-done/bin/gsd-tools.cjs. SDK entry points: createRegistry() in sdk/src/query/index.ts.
Naming aliases (registered, different string):
- CJS
**summary-extract** → SDK**summary.extract**,**summary extract**,**history-digest**(history digest helpers). - CJS top-level
**scaffold <type> …**→ SDK**phase.scaffold**/**phase scaffold**(type + options in args).
CLI-only (no SDK registry handler; intentional unless requirements change):
| CJS surface | Justification |
|---|---|
**graphify** |
Depends on Graphify CLI / Python stack; not ported to the typed query layer. |
**from-gsd2** |
Legacy GSD2 → GSD migration (gsd2-import.cjs); CLI-only helper. |
SDK-only (registered dispatch without an equivalent gsd-tools top-level subcommand):
| SDK dispatch | Notes |
|---|---|
**phases.archive** / **phases archive** |
CJS phases supports only **list** and **clear**; archive behavior is available via SDK (and workflows), not as gsd-tools phases archive. |
Matrix: top-level gsd-tools command → SDK
Disposition: Registered = handled in createRegistry() under the listed SDK name(s); CLI-only = no registry handler; Alias = same behavior, different primary dispatch string.
CJS command (first argv) |
SDK dispatch name(s) | Disposition | Notes |
|---|---|---|---|
state (subcommands) |
state.load, state.json, state.get, state.update, state.patch, … |
Registered | Dotted and state … space aliases in index.ts. |
resolve-model |
resolve-model |
Registered | |
find-phase |
find-phase |
Registered | Golden: subset parity (see above). |
commit, check-commit, commit-to-subrepo |
commit, check-commit, commit-to-subrepo |
Registered | |
verify-summary |
verify-summary, verify.summary, verify summary |
Registered | |
template |
template.fill, template.select, … |
Registered | |
frontmatter |
frontmatter.get, frontmatter.set, … |
Registered | |
verify |
verify.plan-structure, verify.phase-completeness, … |
Registered | |
generate-slug |
generate-slug |
Registered | |
current-timestamp |
current-timestamp |
Registered | Golden: time semantics (see above). |
list-todos |
list-todos, list.todos |
Registered | |
verify-path-exists |
verify-path-exists, verify.path-exists, … |
Registered | |
config-ensure-section, config-set, config-set-model-profile, config-get, config-new-project, config-path |
same kebab-case names | Registered | |
agent-skills |
agent-skills |
Registered | |
skill-manifest |
skill-manifest, skill manifest |
Registered | Writes only with --write. |
history-digest |
history-digest, history.digest, … |
Alias | Same as **summary.extract** family for digest-style output. |
phases |
phases.list, phases.clear, phases.archive, … |
Registered (+ SDK-only) | CJS: **list**, **clear** only; **archive** is SDK-only (see above). |
roadmap |
roadmap.analyze, roadmap.get-phase, roadmap.update-plan-progress, … |
Registered | |
requirements |
requirements.mark-complete, … |
Registered | |
phase |
phase.add, phase.add-batch, phase.insert, … |
Registered | |
milestone |
milestone.complete, … |
Registered | |
validate |
validate.consistency, validate.health, validate.agents, … |
Registered | |
progress |
progress, progress.json, progress.bar, … |
Registered | |
audit-uat |
audit-uat |
Registered | |
audit-open |
audit-open, audit open |
Registered | |
uat |
uat.render-checkpoint, … |
Registered | |
stats |
stats, stats.json, … |
Registered | |
todo |
todo.complete, todo.match-phase, … |
Registered | |
scaffold |
phase.scaffold, phase scaffold |
Alias | Top-level **scaffold** in CJS; no separate scaffold registry key. |
init |
init.execute-phase, init.new-project, … |
Registered | Dotted and init … space aliases. |
phase-plan-index |
phase-plan-index |
Registered | |
state-snapshot |
state-snapshot |
Registered | |
summary-extract |
summary.extract, summary extract, history-digest, … |
Alias | |
websearch |
websearch |
Registered | |
scan-sessions |
scan-sessions |
Registered | |
extract-messages |
extract-messages, extract.messages |
Registered | Golden: output_file strip + JSONL bytes (see Normalized table). |
profile-sample, profile-questionnaire, write-profile, generate-dev-preferences, generate-claude-profile, generate-claude-md |
same kebab-case names | Registered | |
workstream |
workstream.get, workstream.list, … |
Registered | |
intel |
intel.status, intel.diff, intel.update, … |
Registered | **intel.update**: JSON parity with CJS spawn hint / disabled payload (see Intel: intel.update). |
graphify |
— | CLI-only | See CLI-only table. |
docs-init |
docs-init |
Registered | Golden: normalized compare (see above). |
learnings |
learnings.list, learnings.query, … |
Registered | |
detect-custom-files |
detect-custom-files |
Registered | Requires --config-dir. |
from-gsd2 |
— | CLI-only | See CLI-only table. |
Other registered areas
**detect-custom-files**: requires--config-dir <path>; scans installer manifest vs GSD-managed dirs (detect-custom-files.ts).**docs-init**: docs-update workflow payload (docs-init.ts), aligned withdocs.cjs. Golden tests omit**agents_installed**/**missing_agents**when comparing SDK vs CLI because the subprocess may resolve~/.claude/...differently than in-process checks.