* feat(#961): capability command mechanism — commandFamilies index + default-case dispatch (ADR-857 phase 4d-impl-1) Build the capability command mechanism per ADR-959: the `commands` declaration field on the feature role, the registry commandFamilies index, and a real dispatchCapabilityCommand consulted in runCommand's default case (replacing the dead _dispatchNonFamily shim's role). The registry DISCOVERS a standard route*Command (no rebuilt handler table). On a default-case command, dispatch enforces a bare-.cjs-basename, resolves the module under gsd-core/bin/lib/, asserts confinement, requires the resolved path, and own-property-guards the router export before calling it. A require.main===module guard makes gsd-tools.cjs importable for tests; the CLI path is unchanged. Additive: commandFamilies is empty today, so the default case is behavior- preserving for every command; the 10 dead _dispatchNonFamily sites are untouched (future migration markers). The graphify cutover is the separate next step. Closes #961 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#961): surface capability router failures structurally + enforce sync contract Review follow-up: dispatchCapabilityCommand now wraps the router invocation so an unexpected (non-ExitError) throw is converted to a structured, attributed error(msg, SDK_FAIL_FAST) — honoring --json-errors — instead of escaping as a raw stack trace; an intentional ExitError propagates unchanged. An async router (returns a thenable) is rejected loudly with a structured error (the contract is synchronous, like the 12 host routers). Not shipped as "consistent with existing behavior": the host's pre-existing version of this gap is filed as #965. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
28 KiB
28 KiB