Skip to content

refactor(core): move the command descriptor registry into its own workspace package - #2348

Open
thymikee wants to merge 2 commits into
mainfrom
claude/2336-command-registry-package
Open

refactor(core): move the command descriptor registry into its own workspace package#2348
thymikee wants to merge 2 commits into
mainfrom
claude/2336-command-registry-package

Conversation

@thymikee

@thymikee thymikee commented Sep 6, 2026

Copy link
Copy Markdown
Member

Summary

src/core/command-descriptor/, src/command-catalog.ts, src/core/wait-positionals.ts and src/core/parse-timeout.ts imported nothing from root src/, yet were the daemon's largest root coupling. They move as git renames into a new private package @agent-device/command-registry (deps: contracts, selectors), one subpath per module pointing straight at the moved file; no index.ts, no re-export at the old path. Every consumer — daemon, commands, mcp, cli, cli-schema, core, root, client, ai-sdk, scripts, tests — switches to the owning specifier; contracts is untouched. Six descriptor tests that import root src/ stay there, which a package may not do; the rest move unchanged. The __OWNER_FILES__ declaration moves with its only consumer. Enforcement edits are the final chore(gates) commit; no APPROVED_OVER_CEILING row, since rename detection carries each entry's merge-base baseline.

Rename-only proof — git diff -M90% --stat origin/main...HEAD: 217 files changed, 421 insertions(+), 320 deletions(-); 42 renames, all 12 moved sources at 92–100%.

Closes #2336.

Validation

pnpm check:affected --run at e18aa8f: format, lint, typecheck, layering, di-seams, fallow, mcp-metadata, build, package, integration-node, macos-coverage green. vitest-related: 9714 passed, 3 failed — durable-capture-resource, capture-kit adoption, app-log-session-resource. All three assert a chmod 0500 directory is unwritable, which uid 0 ignores, and fail identically on origin/main here.

Daemon → root src/ value edges 150 → 114 (−36, ceiling 118), both from pnpm depgraph (scripts/depgraph/build.ts): value edges from daemon/** into non-package, non-daemon nodes. Including type-only and dynamic edges: 174 → 134.

Versioned CLI help is byte-identical: 82 sections (root help, 12 topics, 69 command usages) rendered from src/bin.ts on origin/main and this head share one sha256. test/integration/smoke-cli: 5/5.

🤖 Generated with Claude Code

https://claude.ai/code/session_016DkNZCMWtm1KUbseKANADi


Generated by Claude Code

…kage

The descriptor registry, its catalogs, and the two parsing leaves it owns
(`wait-positionals`, `parse-timeout`) depended on nothing in root `src/`:
their only imports are `@agent-device/contracts` and
`@agent-device/selectors`. They were nonetheless the daemon's largest root
coupling, and under R11 the reason the daemon client and the session event
journal cannot become packages.

They move as-is into `@agent-device/command-registry`, one exported subpath
per module pointing directly at the moved source file, and every consumer
switches to the owning specifier. No compatibility re-export stays behind at
the old path.

The `__OWNER_FILES__` build-flag declaration moves with its only consumer;
the root program and the SDK examples include it from its new home.

Six descriptor tests reach into root `src/` (daemon parity, ref-frame
classification, the CLI-route coherence gate, the cross-surface
post-action-observation gate, the timeout-policy gate, and the shutdown
mechanics gate), which a package may not do, so they stay in root beside the
other cross-surface suites; the rest move unchanged with their subjects.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016DkNZCMWtm1KUbseKANADi
The rules that name the registry by path follow it: R66's
`COMMAND_DESCRIPTOR_MODULE`, R16's record-runtime join subject, and the
Fallow `AssertTrue` totality-guard key. The two descriptor hubs leave
`HUB_ENTRY_FILES` because the package manifest now publishes them — the
eager-closure gate discovers them as facades, and one entry gets one rule.
`command-registry` joins the ranked spine at rank 1, beside the contracts and
selectors it depends on. Two illustrative paths in gate comments and a
model test are re-pointed at root files that still exist.

No `APPROVED_OVER_CEILING` row: rename detection carries every moved entry's
merge-base baseline, so all twelve fall under the no-growth rule rather than
a ceiling.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016DkNZCMWtm1KUbseKANADi
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://callstack.github.io/agent-device/pr-preview/pr-2348/

Built to branch gh-pages at 2026-09-06 09:06 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown

Size Report

Metric Base Current Diff
Installed (including dependencies) 4.49 MB 4.49 MB -28 B
Package (unpacked) 4.49 MB 4.49 MB -28 B
Package (download) 1.33 MB 1.33 MB -18 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 28.2 ms 27.8 ms -0.4 ms
CLI --help 81.9 ms 80.9 ms -1.0 ms

thymikee commented Sep 6, 2026

Copy link
Copy Markdown
Member Author

Android / Smoke Tests failed on e18aa8f (run 34023633671), and I do not believe it belongs to this PR.

The failing step is the live emulator orientation check in smoke-android-emulator:

step: wait for landscape
command: agent-device wait text landscape 10000 --platform android --serial emulator-5554 ...
error.details: { reason: "wait_capture_stalled", captureStalled: true, readableCaptures: 0, timeoutMs: 10000, waitedMs: 10332 }

readableCaptures: 0 means the wait dispatched and its budget resolved correctly — no readable snapshot capture completed on the emulator inside the window. Nothing in this diff touches the capture path: it is a module move, all twelve sources rename at 92–100% with only import specifiers edited, the descriptor tables are unchanged, and the whole versioned help surface is byte-identical to origin/main (82 sections, same sha256). The wait positionals and timeout policy moved unmodified and their unit coverage passes.

This lane is also independently red on recent main pushes — runs 7795, 7788, 7761 — though it passed on this PR's merge base 27a97ee. No fix for it exists that I could port here.

I have re-run the failed job once (my one allowed re-run). Every other completed check on this head is green: Lint & Format, Typecheck & Package, Integration Tests, Compatibility & Provenance, Bundle Size, Ownership and context budgets, command-docs-gate, CodeQL, and the other Smoke Tests lane. If the re-run fails the same way, that is evidence about the emulator lane, not this diff, and I will say so rather than change the PR to chase it.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor(core): move the command descriptor registry into its own workspace package

2 participants