refactor: remove stale SDK router shim wrappers (#298)

* refactor(#297): remove stale sdk router shim wrappers

* test: remove sdk-era refusal wording fixtures
This commit is contained in:
Tom Boucher
2026-05-26 12:21:04 -04:00
committed by GitHub
parent e905ca1c32
commit e4f29feabc
8 changed files with 27 additions and 68 deletions

View File

@@ -9,12 +9,9 @@ const { createHub, ERROR_KINDS, makeInvalidArgs } = require('./command-routing-h
* Manifest-backed phase subcommand router.
* Keeps gsd-tools.cjs thin while preserving existing command semantics.
*
* #175: Hub is CJS-only. The SDK bridge is still separately invokable via
* bin/lib/cjs-sdk-bridge.cjs, but the Hub no longer routes to it.
*
* SDK-only (unsupported in CJS router — error returned before dispatch):
* - list-plans: SDK-only.
* - list-artifacts: SDK-only.
* Unsupported in this router (error returned before dispatch):
* - list-plans.
* - list-artifacts.
* - scaffold: routed through top-level scaffold command.
*
* CJS-only subcommands: mvp-mode (dispatched directly, before hub).
@@ -23,11 +20,11 @@ const { createHub, ERROR_KINDS, makeInvalidArgs } = require('./command-routing-h
* and observable CLI behaviour are unchanged.
*/
function routePhaseCommand({ phase, args, cwd, raw, error }) {
// ── Unsupported / SDK-only subcommands ─────────────────────────────────────
// ── Unsupported subcommands ────────────────────────────────────────────────
// Resolved before dispatch so the error message matches the pre-#3788 text.
const UNSUPPORTED = {
'list-plans': 'phase list-plans is SDK-only. Use: gsd-sdk query phase.list-plans ...',
'list-artifacts': 'phase list-artifacts is SDK-only. Use: gsd-sdk query phase.list-artifacts ...',
'list-plans': 'phase list-plans is not supported in this router.',
'list-artifacts': 'phase list-artifacts is not supported in this router.',
scaffold: 'phase scaffold is routed through the top-level scaffold command.',
};
@@ -149,7 +146,7 @@ function routePhaseCommand({ phase, args, cwd, raw, error }) {
// ── Build manifest (available subcommands for UnknownCommand detection) ─────
// `availableSubcommands` is what the error message shows. It excludes
// SDK-only unsupported commands (already handled above) but does NOT include
// unsupported commands (already handled above) but does NOT include
// 'mvp-mode' because it was absent from PHASE_SUBCOMMANDS in the original
// and was not shown in the "Available:" list there either.
//

View File

@@ -7,25 +7,14 @@ const { routeCjsCommandFamily } = require('./cjs-command-router-adapter.cjs');
* Manifest-backed phases subcommand router.
* Keeps gsd-tools.cjs thin while preserving current CJS semantics.
*
* Phase 6: phases.list and phases.clear are dispatched via executeForCjs when
* the SDK is available. CJS fallback retained when:
* - GSD_WORKSTREAM is active (workstream-scoped requests fall through to CJS).
* - SDK is unavailable (build not present).
*
* SDK-only (not in CJS router, treated as unknown):
* - archive: `phases archive` is SDK-only (`phases.archive` handler in SDK
* query registry). CJS `gsd-tools phases` intentionally supports list/clear only.
* `archive` is excluded from the subcommands list so it falls through to the
* "unknown subcommand" error path (matching pre-Phase 6 behavior).
*
* CJS-only subcommands: none.
* Unsupported in this router (treated as unknown):
* - archive: `phases archive` is excluded from the subcommands list so it
* falls through to the unknown-subcommand error path.
*/
function routePhasesCommand({ phase, milestone, args, cwd, raw, error }) {
routeCjsCommandFamily({
args,
// Exclude 'archive' — it's SDK-only and not supported in CJS. Excluding
// from this list causes it to hit the unknownMessage path, preserving the
// pre-Phase 6 error message for callers that pass 'archive'.
// Exclude 'archive' so it hits the unknownMessage path.
subcommands: PHASES_SUBCOMMANDS.filter((s) => s !== 'archive'),
error,
unknownMessage: (_subcommand, available) => `Unknown phases subcommand. Available: ${available.join(', ')}`,

View File

@@ -6,14 +6,6 @@ const { routeCjsCommandFamily } = require('./cjs-command-router-adapter.cjs');
/**
* Manifest-backed roadmap subcommand router.
* Keeps gsd-tools.cjs thin while preserving existing command semantics.
*
* Phase 6: all roadmap.* subcommands have SDK equivalents and are dispatched
* via executeForCjs (the sync bridge). CJS fallback retained when:
* - GSD_WORKSTREAM is active (workstream-scoped requests fall through to CJS).
* - SDK is unavailable (build not present).
*
* CJS-only subcommands: none.
* SDK-only (unsupported in CJS router): none.
*/
function routeRoadmapCommand({ roadmap, args, cwd, raw, error }) {
routeCjsCommandFamily({

View File

@@ -6,14 +6,6 @@ const { routeCjsCommandFamily } = require('./cjs-command-router-adapter.cjs');
/**
* Manifest-backed verify subcommand router.
* Keeps gsd-tools.cjs thin while preserving existing command semantics.
*
* Phase 6: all verify.* subcommands have SDK equivalents and are dispatched
* via executeForCjs (the sync bridge). CJS fallback retained when:
* - GSD_WORKSTREAM is active (workstream-scoped requests fall through to CJS).
* - SDK is unavailable (build not present).
*
* CJS-only subcommands: none.
* SDK-only (unsupported in CJS router): none.
*/
function routeVerifyCommand({ verify, args, cwd, raw, error }) {
routeCjsCommandFamily({
@@ -37,9 +29,7 @@ function routeVerifyCommand({ verify, args, cwd, raw, error }) {
},
// verify codebase-drift dispatches direct to CJS — drift is out-of-seam
// per ADR/PRD 3524 §3 / L160 (CJS-only by design). Routing through
// sdkHandler would re-enter the SDK bridge, and Phase 6's removed
// verifyCodebaseDrift stub used to execFileSync back to the CLI,
// creating an infinite spawn loop.
// recursive dispatch would re-enter this router path.
'codebase-drift': () => verify.cmdVerifyCodebaseDrift(cwd, raw),
},
});

View File

@@ -292,7 +292,7 @@ describe('CommandRoutingHub — kind: HandlerRefusal', () => {
'list-plans': (_ctx) => ({
ok: false,
kind: ERROR_KINDS.HandlerRefusal,
reason: 'phase list-plans is SDK-only',
reason: 'phase list-plans is not supported in this router.',
}),
},
},
@@ -457,7 +457,7 @@ describe('CommandRoutingHub — P1.2 typed-payload discriminated union (#176)',
'list-plans': (_ctx) => ({
ok: false,
kind: ERROR_KINDS.HandlerRefusal,
reason: 'phase list-plans is SDK-only',
reason: 'phase list-plans is not supported in this router.',
}),
},
},
@@ -467,7 +467,7 @@ describe('CommandRoutingHub — P1.2 typed-payload discriminated union (#176)',
assert.ok(!result.ok);
assert.equal(result.kind, ERROR_KINDS.HandlerRefusal);
assert.ok(result.reason.includes('SDK-only'));
assert.ok(result.reason.includes('not supported'));
// Strict field set
const keys = Object.keys(result).sort();
assert.deepStrictEqual(keys, ['kind', 'ok', 'reason']);
@@ -781,7 +781,7 @@ describe('CommandRoutingHub — Finding 3: factory returns are Object.frozen', (
});
test('makeHandlerRefusal returns a frozen object', () => {
const result = makeHandlerRefusal('SDK-only');
const result = makeHandlerRefusal('not supported');
assert.ok(Object.isFrozen(result),
'makeHandlerRefusal must return a frozen object');
});

View File

@@ -6,7 +6,7 @@
* Shape:
* 1. Adapter translation — CLI args → hub dispatch shape
* 2. Result translation — hub result → stdout / error callback
* 3. Unsupported subcommands — SDK-only commands produce the documented error
* 3. Unsupported subcommands — unsupported commands produce the documented error
* 4. Unknown subcommand — unmapped subcommands produce a well-formed error
* 5. Integration — real hub + real CJS phase handler invocation
*
@@ -22,8 +22,7 @@ const assert = require('node:assert/strict');
const { routePhaseCommand } = require('../get-shit-done/bin/lib/phase-command-router.cjs');
// Force CJS path throughout: set GSD_WORKSTREAM so tryLoadSdk() is bypassed.
// This makes unit-level assertions deterministic regardless of SDK build state.
// Set GSD_WORKSTREAM for deterministic routing context in tests.
let _prevWorkstream;
before(() => {
_prevWorkstream = process.env.GSD_WORKSTREAM;
@@ -282,10 +281,10 @@ describe('phase-command-router — result translation (error path)', () => {
});
});
// ─── 3. Unsupported (SDK-only) subcommands ────────────────────────────────────
// ─── 3. Unsupported subcommands ───────────────────────────────────────────────
describe('phase-command-router — SDK-only subcommands', () => {
test('phase list-plans calls error() with SDK-only message', () => {
describe('phase-command-router — unsupported subcommands', () => {
test('phase list-plans calls error() with unsupported message', () => {
let msg = null;
routePhaseCommand({
phase: makePhase(),
@@ -296,11 +295,11 @@ describe('phase-command-router — SDK-only subcommands', () => {
});
assert.ok(msg !== null);
assert.ok(msg.includes('SDK-only'), `expected "SDK-only" in: ${msg}`);
assert.ok(msg.includes('not supported'), `expected unsupported text in: ${msg}`);
assert.ok(msg.includes('list-plans'));
});
test('phase list-artifacts calls error() with SDK-only message', () => {
test('phase list-artifacts calls error() with unsupported message', () => {
let msg = null;
routePhaseCommand({
phase: makePhase(),
@@ -311,7 +310,7 @@ describe('phase-command-router — SDK-only subcommands', () => {
});
assert.ok(msg !== null);
assert.ok(msg.includes('SDK-only'));
assert.ok(msg.includes('not supported'));
assert.ok(msg.includes('list-artifacts'));
});
@@ -363,7 +362,7 @@ describe('phase-command-router — unknown subcommand', () => {
assert.ok(msg.includes('add'), `expected add in available list: ${msg}`);
assert.ok(msg.includes('complete'), `expected complete in available list: ${msg}`);
assert.ok(!msg.includes('list-plans'), `list-plans (SDK-only) must not appear in available list: ${msg}`);
assert.ok(!msg.includes('list-plans'), `list-plans (unsupported) must not appear in available list: ${msg}`);
});
});

View File

@@ -5,11 +5,7 @@ const assert = require('node:assert/strict');
const { routePhasesCommand } = require('../get-shit-done/bin/lib/phases-command-router.cjs');
// These tests exercise the CJS dispatch path of the router. Since #3577 the
// router prefers the SDK bridge when sdk/dist is present, which would bypass
// the mocked `phase`/`milestone` handlers below. The router gates SDK
// dispatch on `process.env.GSD_WORKSTREAM` being unset, so set it for these
// tests to deterministically take the CJS path that the mocks model.
// These tests exercise router dispatch with a deterministic runtime context.
let _prevWorkstream;
before(() => {
_prevWorkstream = process.env.GSD_WORKSTREAM;

View File

@@ -5,11 +5,7 @@ const assert = require('node:assert/strict');
const { routeRoadmapCommand } = require('../get-shit-done/bin/lib/roadmap-command-router.cjs');
// These tests exercise the CJS dispatch path of the router. Since #3577 the
// router prefers the SDK bridge when sdk/dist is present, which would bypass
// the mocked `roadmap` handlers below. The router gates SDK dispatch on
// `process.env.GSD_WORKSTREAM` being unset, so set it here to deterministically
// take the CJS path that the mocks model.
// These tests exercise router dispatch with a deterministic runtime context.
let _prevWorkstream;
before(() => {
_prevWorkstream = process.env.GSD_WORKSTREAM;