feat(sdk): add NON_FAMILY_COMMAND_ALIASES to manifest — 14 missing commands (#3305)
* test(3251): red — assert 14 missing commands in command-aliases.generated.cjs Parametrized test covering all 14 commands from issue #3251. Requires the CJS manifest and asserts structurally (never greps source). Currently fails because NON_FAMILY_COMMAND_ALIASES is not exported and all 14 are missing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(3251): add 14 missing commands to command-aliases.generated.cjs Adds NON_FAMILY_COMMAND_ALIASES export to command-aliases.generated.cjs and extends sdk/src/query/command-manifest.non-family.ts with the 10 commands that were registered in static catalogs but absent from the manifest source-of-truth: - check.decision-coverage-plan / check.decision-coverage-verify - frontmatter.get - phase.mvp-mode - progress.bar - stats.json - task.is-behavior-adding - todo.match-phase - uat.render-checkpoint - workstream.list The other 4 (frontmatter.set, learnings.copy, milestone.complete, requirements.mark-complete) were already in non-family.ts but unexported. Generator (sdk/scripts/gen-command-aliases.ts) now produces both the TS and CJS artifacts including the non-family section, sorted by canonical for determinism. Freshness check (sdk/scripts/check-command-aliases-fresh.mjs) verifies TS and CJS non-family parity against the manifest source-of-truth. Fixes #3251 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(3251): add changeset and CHANGELOG entry for PR #3305 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(gen-command-aliases): preserve TS type interfaces and annotations on regen (#3251) - Add FamilyCommandAlias and NonFamilyCommandAlias interface declarations to tsBody so regen never strips them - Replace JSON.stringify with single-line compact serialisers for TS output (matches committed file format) - Apply typed annotations (readonly FamilyCommandAlias[] / readonly NonFamilyCommandAlias[]) to all exported TS constants - CJS path unchanged: remains untyped pure-JS with JSON.stringify multi-line format - Regenerate sdk/src/query/command-aliases.generated.ts to sync with updated generator Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: drop redundant CHANGELOG.md edit (use .changeset/ fragment per CONTRIBUTING.md) --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
5
.changeset/3251-non-family-aliases.md
Normal file
5
.changeset/3251-non-family-aliases.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
type: Fixed
|
||||
pr: 3305
|
||||
---
|
||||
**`command-aliases.generated.cjs` now exports `NON_FAMILY_COMMAND_ALIASES` with all 14 previously-missing commands** — the CJS manifest used by the SDK query registry only exposed the 7 "family" command arrays (state, verify, init, phase, phases, validate, roadmap). Commands registered in static catalogs (foundation + domain) had no manifest entry, so tooling that queries the manifest could not discover them. `command-manifest.non-family.ts` is extended with 10 new entries (`check.decision-coverage-plan`, `check.decision-coverage-verify`, `frontmatter.get`, `phase.mvp-mode`, `progress.bar`, `stats.json`, `task.is-behavior-adding`, `todo.match-phase`, `uat.render-checkpoint`, `workstream.list`); the other 4 were already in the source but not exported. Both the TS generated file and CJS manifest now include a `NON_FAMILY_COMMAND_ALIASES` array (40 entries, sorted by canonical). The generator and freshness check are extended to cover the non-family section. (#3305)
|
||||
@@ -1,95 +1,807 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* GENERATED FILE — state.*, verify.*, init.*, phase.*, phases.*, validate.*, and roadmap.* alias/subcommand metadata for CJS routing.
|
||||
* Source: sdk/src/query/command-manifest.{state,verify,init,phase,phases,validate,roadmap}.ts
|
||||
* GENERATED FILE — state.*, verify.*, init.*, phase.*, phases.*, validate.*, roadmap.*, and non-family alias/subcommand metadata for CJS routing.
|
||||
* Source: sdk/src/query/command-manifest.{state,verify,init,phase,phases,validate,roadmap,non-family}.ts
|
||||
*/
|
||||
|
||||
const STATE_COMMAND_ALIASES = [
|
||||
{ canonical: 'state.load', aliases: [], subcommand: 'load', mutation: false },
|
||||
{ canonical: 'state.json', aliases: ['state json'], subcommand: 'json', mutation: false },
|
||||
{ canonical: 'state.get', aliases: ['state get'], subcommand: 'get', mutation: false },
|
||||
{ canonical: 'state.update', aliases: ['state update'], subcommand: 'update', mutation: true },
|
||||
{ canonical: 'state.patch', aliases: ['state patch'], subcommand: 'patch', mutation: true },
|
||||
{ canonical: 'state.begin-phase', aliases: ['state begin-phase'], subcommand: 'begin-phase', mutation: true },
|
||||
{ canonical: 'state.advance-plan', aliases: ['state advance-plan'], subcommand: 'advance-plan', mutation: true },
|
||||
{ canonical: 'state.record-metric', aliases: ['state record-metric'], subcommand: 'record-metric', mutation: true },
|
||||
{ canonical: 'state.update-progress', aliases: ['state update-progress'], subcommand: 'update-progress', mutation: true },
|
||||
{ canonical: 'state.add-decision', aliases: ['state add-decision'], subcommand: 'add-decision', mutation: true },
|
||||
{ canonical: 'state.add-blocker', aliases: ['state add-blocker'], subcommand: 'add-blocker', mutation: true },
|
||||
{ canonical: 'state.resolve-blocker', aliases: ['state resolve-blocker'], subcommand: 'resolve-blocker', mutation: true },
|
||||
{ canonical: 'state.record-session', aliases: ['state record-session'], subcommand: 'record-session', mutation: true },
|
||||
{ canonical: 'state.signal-waiting', aliases: ['state signal-waiting'], subcommand: 'signal-waiting', mutation: true },
|
||||
{ canonical: 'state.signal-resume', aliases: ['state signal-resume'], subcommand: 'signal-resume', mutation: true },
|
||||
{ canonical: 'state.planned-phase', aliases: ['state planned-phase'], subcommand: 'planned-phase', mutation: true },
|
||||
{ canonical: 'state.validate', aliases: ['state validate'], subcommand: 'validate', mutation: false },
|
||||
{ canonical: 'state.sync', aliases: ['state sync'], subcommand: 'sync', mutation: true },
|
||||
{ canonical: 'state.prune', aliases: ['state prune'], subcommand: 'prune', mutation: true },
|
||||
{ canonical: 'state.milestone-switch', aliases: ['state milestone-switch'], subcommand: 'milestone-switch', mutation: true },
|
||||
{ canonical: 'state.add-roadmap-evolution', aliases: ['state add-roadmap-evolution'], subcommand: 'add-roadmap-evolution', mutation: true },
|
||||
{
|
||||
"canonical": "state.load",
|
||||
"aliases": [],
|
||||
"subcommand": "load",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "state.json",
|
||||
"aliases": [
|
||||
"state json"
|
||||
],
|
||||
"subcommand": "json",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "state.get",
|
||||
"aliases": [
|
||||
"state get"
|
||||
],
|
||||
"subcommand": "get",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "state.update",
|
||||
"aliases": [
|
||||
"state update"
|
||||
],
|
||||
"subcommand": "update",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "state.patch",
|
||||
"aliases": [
|
||||
"state patch"
|
||||
],
|
||||
"subcommand": "patch",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "state.begin-phase",
|
||||
"aliases": [
|
||||
"state begin-phase"
|
||||
],
|
||||
"subcommand": "begin-phase",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "state.advance-plan",
|
||||
"aliases": [
|
||||
"state advance-plan"
|
||||
],
|
||||
"subcommand": "advance-plan",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "state.record-metric",
|
||||
"aliases": [
|
||||
"state record-metric"
|
||||
],
|
||||
"subcommand": "record-metric",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "state.update-progress",
|
||||
"aliases": [
|
||||
"state update-progress"
|
||||
],
|
||||
"subcommand": "update-progress",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "state.add-decision",
|
||||
"aliases": [
|
||||
"state add-decision"
|
||||
],
|
||||
"subcommand": "add-decision",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "state.add-blocker",
|
||||
"aliases": [
|
||||
"state add-blocker"
|
||||
],
|
||||
"subcommand": "add-blocker",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "state.resolve-blocker",
|
||||
"aliases": [
|
||||
"state resolve-blocker"
|
||||
],
|
||||
"subcommand": "resolve-blocker",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "state.record-session",
|
||||
"aliases": [
|
||||
"state record-session"
|
||||
],
|
||||
"subcommand": "record-session",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "state.signal-waiting",
|
||||
"aliases": [
|
||||
"state signal-waiting"
|
||||
],
|
||||
"subcommand": "signal-waiting",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "state.signal-resume",
|
||||
"aliases": [
|
||||
"state signal-resume"
|
||||
],
|
||||
"subcommand": "signal-resume",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "state.planned-phase",
|
||||
"aliases": [
|
||||
"state planned-phase"
|
||||
],
|
||||
"subcommand": "planned-phase",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "state.validate",
|
||||
"aliases": [
|
||||
"state validate"
|
||||
],
|
||||
"subcommand": "validate",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "state.sync",
|
||||
"aliases": [
|
||||
"state sync"
|
||||
],
|
||||
"subcommand": "sync",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "state.prune",
|
||||
"aliases": [
|
||||
"state prune"
|
||||
],
|
||||
"subcommand": "prune",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "state.milestone-switch",
|
||||
"aliases": [
|
||||
"state milestone-switch"
|
||||
],
|
||||
"subcommand": "milestone-switch",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "state.add-roadmap-evolution",
|
||||
"aliases": [
|
||||
"state add-roadmap-evolution"
|
||||
],
|
||||
"subcommand": "add-roadmap-evolution",
|
||||
"mutation": true
|
||||
}
|
||||
];
|
||||
|
||||
const VERIFY_COMMAND_ALIASES = [
|
||||
{ canonical: 'verify.plan-structure', aliases: ['verify plan-structure'], subcommand: 'plan-structure', mutation: false },
|
||||
{ canonical: 'verify.phase-completeness', aliases: ['verify phase-completeness'], subcommand: 'phase-completeness', mutation: false },
|
||||
{ canonical: 'verify.references', aliases: ['verify references'], subcommand: 'references', mutation: false },
|
||||
{ canonical: 'verify.commits', aliases: ['verify commits'], subcommand: 'commits', mutation: false },
|
||||
{ canonical: 'verify.artifacts', aliases: ['verify artifacts'], subcommand: 'artifacts', mutation: false },
|
||||
{ canonical: 'verify.key-links', aliases: ['verify key-links'], subcommand: 'key-links', mutation: false },
|
||||
{ canonical: 'verify.schema-drift', aliases: ['verify schema-drift'], subcommand: 'schema-drift', mutation: false },
|
||||
{ canonical: 'verify.codebase-drift', aliases: ['verify codebase-drift'], subcommand: 'codebase-drift', mutation: false },
|
||||
{
|
||||
"canonical": "verify.plan-structure",
|
||||
"aliases": [
|
||||
"verify plan-structure"
|
||||
],
|
||||
"subcommand": "plan-structure",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "verify.phase-completeness",
|
||||
"aliases": [
|
||||
"verify phase-completeness"
|
||||
],
|
||||
"subcommand": "phase-completeness",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "verify.references",
|
||||
"aliases": [
|
||||
"verify references"
|
||||
],
|
||||
"subcommand": "references",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "verify.commits",
|
||||
"aliases": [
|
||||
"verify commits"
|
||||
],
|
||||
"subcommand": "commits",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "verify.artifacts",
|
||||
"aliases": [
|
||||
"verify artifacts"
|
||||
],
|
||||
"subcommand": "artifacts",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "verify.key-links",
|
||||
"aliases": [
|
||||
"verify key-links"
|
||||
],
|
||||
"subcommand": "key-links",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "verify.schema-drift",
|
||||
"aliases": [
|
||||
"verify schema-drift"
|
||||
],
|
||||
"subcommand": "schema-drift",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "verify.codebase-drift",
|
||||
"aliases": [
|
||||
"verify codebase-drift"
|
||||
],
|
||||
"subcommand": "codebase-drift",
|
||||
"mutation": false
|
||||
}
|
||||
];
|
||||
|
||||
const INIT_COMMAND_ALIASES = [
|
||||
{ canonical: 'init.execute-phase', aliases: ['init execute-phase'], subcommand: 'execute-phase', mutation: false },
|
||||
{ canonical: 'init.plan-phase', aliases: ['init plan-phase'], subcommand: 'plan-phase', mutation: false },
|
||||
{ canonical: 'init.new-project', aliases: ['init new-project'], subcommand: 'new-project', mutation: false },
|
||||
{ canonical: 'init.new-milestone', aliases: ['init new-milestone'], subcommand: 'new-milestone', mutation: false },
|
||||
{ canonical: 'init.quick', aliases: ['init quick'], subcommand: 'quick', mutation: false },
|
||||
{ canonical: 'init.ingest-docs', aliases: ['init ingest-docs'], subcommand: 'ingest-docs', mutation: false },
|
||||
{ canonical: 'init.resume', aliases: ['init resume'], subcommand: 'resume', mutation: false },
|
||||
{ canonical: 'init.verify-work', aliases: ['init verify-work'], subcommand: 'verify-work', mutation: false },
|
||||
{ canonical: 'init.phase-op', aliases: ['init phase-op'], subcommand: 'phase-op', mutation: false },
|
||||
{ canonical: 'init.todos', aliases: ['init todos'], subcommand: 'todos', mutation: false },
|
||||
{ canonical: 'init.milestone-op', aliases: ['init milestone-op'], subcommand: 'milestone-op', mutation: false },
|
||||
{ canonical: 'init.map-codebase', aliases: ['init map-codebase'], subcommand: 'map-codebase', mutation: false },
|
||||
{ canonical: 'init.progress', aliases: ['init progress'], subcommand: 'progress', mutation: false },
|
||||
{ canonical: 'init.manager', aliases: ['init manager'], subcommand: 'manager', mutation: false },
|
||||
{ canonical: 'init.new-workspace', aliases: ['init new-workspace'], subcommand: 'new-workspace', mutation: false },
|
||||
{ canonical: 'init.list-workspaces', aliases: ['init list-workspaces'], subcommand: 'list-workspaces', mutation: false },
|
||||
{ canonical: 'init.remove-workspace', aliases: ['init remove-workspace'], subcommand: 'remove-workspace', mutation: false },
|
||||
{
|
||||
"canonical": "init.execute-phase",
|
||||
"aliases": [
|
||||
"init execute-phase"
|
||||
],
|
||||
"subcommand": "execute-phase",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "init.plan-phase",
|
||||
"aliases": [
|
||||
"init plan-phase"
|
||||
],
|
||||
"subcommand": "plan-phase",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "init.new-project",
|
||||
"aliases": [
|
||||
"init new-project"
|
||||
],
|
||||
"subcommand": "new-project",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "init.new-milestone",
|
||||
"aliases": [
|
||||
"init new-milestone"
|
||||
],
|
||||
"subcommand": "new-milestone",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "init.quick",
|
||||
"aliases": [
|
||||
"init quick"
|
||||
],
|
||||
"subcommand": "quick",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "init.ingest-docs",
|
||||
"aliases": [
|
||||
"init ingest-docs"
|
||||
],
|
||||
"subcommand": "ingest-docs",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "init.resume",
|
||||
"aliases": [
|
||||
"init resume"
|
||||
],
|
||||
"subcommand": "resume",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "init.verify-work",
|
||||
"aliases": [
|
||||
"init verify-work"
|
||||
],
|
||||
"subcommand": "verify-work",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "init.phase-op",
|
||||
"aliases": [
|
||||
"init phase-op"
|
||||
],
|
||||
"subcommand": "phase-op",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "init.todos",
|
||||
"aliases": [
|
||||
"init todos"
|
||||
],
|
||||
"subcommand": "todos",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "init.milestone-op",
|
||||
"aliases": [
|
||||
"init milestone-op"
|
||||
],
|
||||
"subcommand": "milestone-op",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "init.map-codebase",
|
||||
"aliases": [
|
||||
"init map-codebase"
|
||||
],
|
||||
"subcommand": "map-codebase",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "init.progress",
|
||||
"aliases": [
|
||||
"init progress"
|
||||
],
|
||||
"subcommand": "progress",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "init.manager",
|
||||
"aliases": [
|
||||
"init manager"
|
||||
],
|
||||
"subcommand": "manager",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "init.new-workspace",
|
||||
"aliases": [
|
||||
"init new-workspace"
|
||||
],
|
||||
"subcommand": "new-workspace",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "init.list-workspaces",
|
||||
"aliases": [
|
||||
"init list-workspaces"
|
||||
],
|
||||
"subcommand": "list-workspaces",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "init.remove-workspace",
|
||||
"aliases": [
|
||||
"init remove-workspace"
|
||||
],
|
||||
"subcommand": "remove-workspace",
|
||||
"mutation": false
|
||||
}
|
||||
];
|
||||
|
||||
const PHASE_COMMAND_ALIASES = [
|
||||
{ canonical: 'phase.list-plans', aliases: ['phase list-plans'], subcommand: 'list-plans', mutation: false },
|
||||
{ canonical: 'phase.list-artifacts', aliases: ['phase list-artifacts'], subcommand: 'list-artifacts', mutation: false },
|
||||
{ canonical: 'phase.next-decimal', aliases: ['phase next-decimal'], subcommand: 'next-decimal', mutation: false },
|
||||
{ canonical: 'phase.add', aliases: ['phase add'], subcommand: 'add', mutation: true },
|
||||
{ canonical: 'phase.add-batch', aliases: ['phase add-batch'], subcommand: 'add-batch', mutation: true },
|
||||
{ canonical: 'phase.insert', aliases: ['phase insert'], subcommand: 'insert', mutation: true },
|
||||
{ canonical: 'phase.remove', aliases: ['phase remove'], subcommand: 'remove', mutation: true },
|
||||
{ canonical: 'phase.complete', aliases: ['phase complete'], subcommand: 'complete', mutation: true },
|
||||
{ canonical: 'phase.scaffold', aliases: ['phase scaffold'], subcommand: 'scaffold', mutation: true },
|
||||
{
|
||||
"canonical": "phase.list-plans",
|
||||
"aliases": [
|
||||
"phase list-plans"
|
||||
],
|
||||
"subcommand": "list-plans",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "phase.list-artifacts",
|
||||
"aliases": [
|
||||
"phase list-artifacts"
|
||||
],
|
||||
"subcommand": "list-artifacts",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "phase.next-decimal",
|
||||
"aliases": [
|
||||
"phase next-decimal"
|
||||
],
|
||||
"subcommand": "next-decimal",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "phase.add",
|
||||
"aliases": [
|
||||
"phase add"
|
||||
],
|
||||
"subcommand": "add",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "phase.add-batch",
|
||||
"aliases": [
|
||||
"phase add-batch"
|
||||
],
|
||||
"subcommand": "add-batch",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "phase.insert",
|
||||
"aliases": [
|
||||
"phase insert"
|
||||
],
|
||||
"subcommand": "insert",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "phase.remove",
|
||||
"aliases": [
|
||||
"phase remove"
|
||||
],
|
||||
"subcommand": "remove",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "phase.complete",
|
||||
"aliases": [
|
||||
"phase complete"
|
||||
],
|
||||
"subcommand": "complete",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "phase.scaffold",
|
||||
"aliases": [
|
||||
"phase scaffold"
|
||||
],
|
||||
"subcommand": "scaffold",
|
||||
"mutation": true
|
||||
}
|
||||
];
|
||||
|
||||
const PHASES_COMMAND_ALIASES = [
|
||||
{ canonical: 'phases.list', aliases: ['phases list'], subcommand: 'list', mutation: false },
|
||||
{ canonical: 'phases.clear', aliases: ['phases clear'], subcommand: 'clear', mutation: true },
|
||||
{ canonical: 'phases.archive', aliases: ['phases archive'], subcommand: 'archive', mutation: true },
|
||||
{
|
||||
"canonical": "phases.list",
|
||||
"aliases": [
|
||||
"phases list"
|
||||
],
|
||||
"subcommand": "list",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "phases.clear",
|
||||
"aliases": [
|
||||
"phases clear"
|
||||
],
|
||||
"subcommand": "clear",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "phases.archive",
|
||||
"aliases": [
|
||||
"phases archive"
|
||||
],
|
||||
"subcommand": "archive",
|
||||
"mutation": true
|
||||
}
|
||||
];
|
||||
|
||||
const VALIDATE_COMMAND_ALIASES = [
|
||||
{ canonical: 'validate.consistency', aliases: ['validate consistency'], subcommand: 'consistency', mutation: false },
|
||||
{ canonical: 'validate.health', aliases: ['validate health'], subcommand: 'health', mutation: false },
|
||||
{ canonical: 'validate.agents', aliases: ['validate agents'], subcommand: 'agents', mutation: false },
|
||||
{ canonical: 'validate.context', aliases: ['validate context'], subcommand: 'context', mutation: false },
|
||||
{
|
||||
"canonical": "validate.consistency",
|
||||
"aliases": [
|
||||
"validate consistency"
|
||||
],
|
||||
"subcommand": "consistency",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "validate.health",
|
||||
"aliases": [
|
||||
"validate health"
|
||||
],
|
||||
"subcommand": "health",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "validate.agents",
|
||||
"aliases": [
|
||||
"validate agents"
|
||||
],
|
||||
"subcommand": "agents",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "validate.context",
|
||||
"aliases": [
|
||||
"validate context"
|
||||
],
|
||||
"subcommand": "context",
|
||||
"mutation": false
|
||||
}
|
||||
];
|
||||
|
||||
const ROADMAP_COMMAND_ALIASES = [
|
||||
{ canonical: 'roadmap.analyze', aliases: ['roadmap analyze'], subcommand: 'analyze', mutation: false },
|
||||
{ canonical: 'roadmap.get-phase', aliases: ['roadmap get-phase'], subcommand: 'get-phase', mutation: false },
|
||||
{ canonical: 'roadmap.update-plan-progress', aliases: ['roadmap update-plan-progress'], subcommand: 'update-plan-progress', mutation: true },
|
||||
{ canonical: 'roadmap.annotate-dependencies', aliases: ['roadmap annotate-dependencies'], subcommand: 'annotate-dependencies', mutation: true },
|
||||
{
|
||||
"canonical": "roadmap.analyze",
|
||||
"aliases": [
|
||||
"roadmap analyze"
|
||||
],
|
||||
"subcommand": "analyze",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "roadmap.get-phase",
|
||||
"aliases": [
|
||||
"roadmap get-phase"
|
||||
],
|
||||
"subcommand": "get-phase",
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "roadmap.update-plan-progress",
|
||||
"aliases": [
|
||||
"roadmap update-plan-progress"
|
||||
],
|
||||
"subcommand": "update-plan-progress",
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "roadmap.annotate-dependencies",
|
||||
"aliases": [
|
||||
"roadmap annotate-dependencies"
|
||||
],
|
||||
"subcommand": "annotate-dependencies",
|
||||
"mutation": true
|
||||
}
|
||||
];
|
||||
|
||||
const NON_FAMILY_COMMAND_ALIASES = [
|
||||
{
|
||||
"canonical": "check-commit",
|
||||
"aliases": [],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "check.decision-coverage-plan",
|
||||
"aliases": [
|
||||
"check decision-coverage-plan"
|
||||
],
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "check.decision-coverage-verify",
|
||||
"aliases": [
|
||||
"check decision-coverage-verify"
|
||||
],
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "commit",
|
||||
"aliases": [],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "commit-to-subrepo",
|
||||
"aliases": [],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "config-ensure-section",
|
||||
"aliases": [],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "config-new-project",
|
||||
"aliases": [],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "config-set",
|
||||
"aliases": [],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "config-set-model-profile",
|
||||
"aliases": [],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "docs-init",
|
||||
"aliases": [],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "frontmatter.get",
|
||||
"aliases": [],
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "frontmatter.merge",
|
||||
"aliases": [],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "frontmatter.set",
|
||||
"aliases": [],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "frontmatter.validate",
|
||||
"aliases": [
|
||||
"frontmatter validate"
|
||||
],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "generate-claude-md",
|
||||
"aliases": [],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "generate-claude-profile",
|
||||
"aliases": [],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "generate-dev-preferences",
|
||||
"aliases": [],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "intel.patch-meta",
|
||||
"aliases": [
|
||||
"intel patch-meta"
|
||||
],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "intel.snapshot",
|
||||
"aliases": [
|
||||
"intel snapshot"
|
||||
],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "learnings.copy",
|
||||
"aliases": [
|
||||
"learnings copy"
|
||||
],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "learnings.delete",
|
||||
"aliases": [
|
||||
"learnings delete"
|
||||
],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "learnings.prune",
|
||||
"aliases": [
|
||||
"learnings prune"
|
||||
],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "milestone.complete",
|
||||
"aliases": [
|
||||
"milestone complete"
|
||||
],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "phase.mvp-mode",
|
||||
"aliases": [
|
||||
"phase mvp-mode"
|
||||
],
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "progress.bar",
|
||||
"aliases": [
|
||||
"progress bar"
|
||||
],
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "requirements.mark-complete",
|
||||
"aliases": [
|
||||
"requirements mark-complete"
|
||||
],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "stats.json",
|
||||
"aliases": [
|
||||
"stats json"
|
||||
],
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "task.is-behavior-adding",
|
||||
"aliases": [
|
||||
"task is-behavior-adding"
|
||||
],
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "template.fill",
|
||||
"aliases": [],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "template.select",
|
||||
"aliases": [
|
||||
"template select"
|
||||
],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "todo.complete",
|
||||
"aliases": [
|
||||
"todo complete"
|
||||
],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "todo.match-phase",
|
||||
"aliases": [
|
||||
"todo match-phase"
|
||||
],
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "uat.render-checkpoint",
|
||||
"aliases": [
|
||||
"uat render-checkpoint"
|
||||
],
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "verify-summary",
|
||||
"aliases": [
|
||||
"verify.summary",
|
||||
"verify summary"
|
||||
],
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "workstream.complete",
|
||||
"aliases": [
|
||||
"workstream complete"
|
||||
],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "workstream.create",
|
||||
"aliases": [
|
||||
"workstream create"
|
||||
],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "workstream.list",
|
||||
"aliases": [
|
||||
"workstream list"
|
||||
],
|
||||
"mutation": false
|
||||
},
|
||||
{
|
||||
"canonical": "workstream.progress",
|
||||
"aliases": [
|
||||
"workstream progress"
|
||||
],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "workstream.set",
|
||||
"aliases": [
|
||||
"workstream set"
|
||||
],
|
||||
"mutation": true
|
||||
},
|
||||
{
|
||||
"canonical": "write-profile",
|
||||
"aliases": [],
|
||||
"mutation": true
|
||||
}
|
||||
];
|
||||
|
||||
const STATE_SUBCOMMANDS = STATE_COMMAND_ALIASES.map((entry) => entry.subcommand);
|
||||
@@ -108,6 +820,7 @@ module.exports = {
|
||||
PHASES_COMMAND_ALIASES,
|
||||
VALIDATE_COMMAND_ALIASES,
|
||||
ROADMAP_COMMAND_ALIASES,
|
||||
NON_FAMILY_COMMAND_ALIASES,
|
||||
STATE_SUBCOMMANDS,
|
||||
VERIFY_SUBCOMMANDS,
|
||||
INIT_SUBCOMMANDS,
|
||||
@@ -115,4 +828,4 @@ module.exports = {
|
||||
PHASES_SUBCOMMANDS,
|
||||
VALIDATE_SUBCOMMANDS,
|
||||
ROADMAP_SUBCOMMANDS,
|
||||
};
|
||||
};
|
||||
@@ -36,8 +36,13 @@ const {
|
||||
PHASES_COMMAND_ALIASES,
|
||||
VALIDATE_COMMAND_ALIASES,
|
||||
ROADMAP_COMMAND_ALIASES,
|
||||
NON_FAMILY_COMMAND_ALIASES,
|
||||
} = await import('../dist/query/command-aliases.generated.js');
|
||||
|
||||
const {
|
||||
NON_FAMILY_COMMAND_MANIFEST,
|
||||
} = await import('../dist/query/command-manifest.non-family.js');
|
||||
|
||||
const cjsAliases = require(resolve(here, '..', '..', 'get-shit-done', 'bin', 'lib', 'command-aliases.generated.cjs'));
|
||||
|
||||
function toAliasEntries(manifest, family) {
|
||||
@@ -50,6 +55,16 @@ function toAliasEntries(manifest, family) {
|
||||
}));
|
||||
}
|
||||
|
||||
function toNonFamilyAliasEntries(manifest) {
|
||||
return [...manifest]
|
||||
.sort((a, b) => a.canonical.localeCompare(b.canonical))
|
||||
.map((entry) => ({
|
||||
canonical: entry.canonical,
|
||||
aliases: [...entry.aliases],
|
||||
mutation: entry.mutation,
|
||||
}));
|
||||
}
|
||||
|
||||
function assertEqual(label, actual, expected) {
|
||||
const a = JSON.stringify(actual);
|
||||
const e = JSON.stringify(expected);
|
||||
@@ -67,6 +82,7 @@ const expectedPhase = toAliasEntries(PHASE_COMMAND_MANIFEST, 'phase');
|
||||
const expectedPhases = toAliasEntries(PHASES_COMMAND_MANIFEST, 'phases');
|
||||
const expectedValidate = toAliasEntries(VALIDATE_COMMAND_MANIFEST, 'validate');
|
||||
const expectedRoadmap = toAliasEntries(ROADMAP_COMMAND_MANIFEST, 'roadmap');
|
||||
const expectedNonFamily = toNonFamilyAliasEntries(NON_FAMILY_COMMAND_MANIFEST);
|
||||
|
||||
assertEqual('TS STATE_COMMAND_ALIASES', STATE_COMMAND_ALIASES, expectedState);
|
||||
assertEqual('TS VERIFY_COMMAND_ALIASES', VERIFY_COMMAND_ALIASES, expectedVerify);
|
||||
@@ -75,6 +91,7 @@ assertEqual('TS PHASE_COMMAND_ALIASES', PHASE_COMMAND_ALIASES, expectedPhase);
|
||||
assertEqual('TS PHASES_COMMAND_ALIASES', PHASES_COMMAND_ALIASES, expectedPhases);
|
||||
assertEqual('TS VALIDATE_COMMAND_ALIASES', VALIDATE_COMMAND_ALIASES, expectedValidate);
|
||||
assertEqual('TS ROADMAP_COMMAND_ALIASES', ROADMAP_COMMAND_ALIASES, expectedRoadmap);
|
||||
assertEqual('TS NON_FAMILY_COMMAND_ALIASES', NON_FAMILY_COMMAND_ALIASES, expectedNonFamily);
|
||||
|
||||
assertEqual('CJS STATE_COMMAND_ALIASES', cjsAliases.STATE_COMMAND_ALIASES, expectedState);
|
||||
assertEqual('CJS VERIFY_COMMAND_ALIASES', cjsAliases.VERIFY_COMMAND_ALIASES, expectedVerify);
|
||||
@@ -83,5 +100,6 @@ assertEqual('CJS PHASE_COMMAND_ALIASES', cjsAliases.PHASE_COMMAND_ALIASES, expec
|
||||
assertEqual('CJS PHASES_COMMAND_ALIASES', cjsAliases.PHASES_COMMAND_ALIASES, expectedPhases);
|
||||
assertEqual('CJS VALIDATE_COMMAND_ALIASES', cjsAliases.VALIDATE_COMMAND_ALIASES, expectedValidate);
|
||||
assertEqual('CJS ROADMAP_COMMAND_ALIASES', cjsAliases.ROADMAP_COMMAND_ALIASES, expectedRoadmap);
|
||||
assertEqual('CJS NON_FAMILY_COMMAND_ALIASES', cjsAliases.NON_FAMILY_COMMAND_ALIASES, expectedNonFamily);
|
||||
|
||||
console.log('command alias artifacts are fresh');
|
||||
|
||||
@@ -11,6 +11,7 @@ import { writeFile } from 'node:fs/promises';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { COMMAND_DEFINITIONS_BY_FAMILY } from '../src/query/command-definition.js';
|
||||
import { NON_FAMILY_COMMAND_MANIFEST } from '../src/query/command-manifest.non-family.js';
|
||||
|
||||
function toSubcommand(canonical: string, family: 'state' | 'verify' | 'init' | 'phase' | 'phases' | 'validate' | 'roadmap'): string {
|
||||
const prefix = `${family}.`;
|
||||
@@ -67,22 +68,66 @@ async function main(): Promise<void> {
|
||||
mutation: entry.mutation,
|
||||
}));
|
||||
|
||||
const outPath = fileURLToPath(new URL('../src/query/command-aliases.generated.ts', import.meta.url));
|
||||
const header = `/**\n * GENERATED FILE — command alias expansion for state.*, verify.*, init.*, phase.*, phases.*, validate.*, and roadmap.* pilots.\n * Source: sdk/src/query/command-manifest.{state,verify,init,phase,phases,validate,roadmap}.ts\n */\n\n`;
|
||||
const body = [
|
||||
`export const STATE_COMMAND_ALIASES = ${JSON.stringify(stateEntries, null, 2)} as const;`,
|
||||
// Non-family entries — sorted by canonical for deterministic output.
|
||||
const nonFamilyEntries = [...NON_FAMILY_COMMAND_MANIFEST]
|
||||
.sort((a, b) => a.canonical.localeCompare(b.canonical))
|
||||
.map((entry) => ({
|
||||
canonical: entry.canonical,
|
||||
aliases: [...entry.aliases],
|
||||
mutation: entry.mutation,
|
||||
}));
|
||||
|
||||
// Serialise a FamilyCommandAlias entry as a single-line TS literal.
|
||||
function serializeFamily(e: { canonical: string; aliases: string[]; subcommand: string; mutation: boolean }): string {
|
||||
const aliases = `[${e.aliases.map((a) => `'${a}'`).join(', ')}]`;
|
||||
return `{ canonical: '${e.canonical}', aliases: ${aliases}, subcommand: '${e.subcommand}', mutation: ${e.mutation} }`;
|
||||
}
|
||||
|
||||
// Serialise a NonFamilyCommandAlias entry as a single-line TS literal.
|
||||
function serializeNonFamily(e: { canonical: string; aliases: string[]; mutation: boolean }): string {
|
||||
const aliases = `[${e.aliases.map((a) => `'${a}'`).join(', ')}]`;
|
||||
return `{ canonical: '${e.canonical}', aliases: ${aliases}, mutation: ${e.mutation} }`;
|
||||
}
|
||||
|
||||
function renderFamilyArray(entries: { canonical: string; aliases: string[]; subcommand: string; mutation: boolean }[]): string {
|
||||
return `[\n${entries.map((e) => ` ${serializeFamily(e)},`).join('\n')}\n]`;
|
||||
}
|
||||
|
||||
function renderNonFamilyArray(entries: { canonical: string; aliases: string[]; mutation: boolean }[]): string {
|
||||
return `[\n${entries.map((e) => ` ${serializeNonFamily(e)},`).join('\n')}\n]`;
|
||||
}
|
||||
|
||||
const tsOutPath = fileURLToPath(new URL('../src/query/command-aliases.generated.ts', import.meta.url));
|
||||
const tsHeader = `/**\n * GENERATED FILE — command alias expansion for state.*, verify.*, init.*, phase.*, phases.*, validate.*, roadmap.*, and non-family commands.\n * Source: sdk/src/query/command-manifest.{state,verify,init,phase,phases,validate,roadmap,non-family}.ts\n */\n\n`;
|
||||
const tsBody = [
|
||||
'export interface FamilyCommandAlias {',
|
||||
' canonical: string;',
|
||||
' aliases: string[];',
|
||||
' subcommand: string;',
|
||||
' mutation: boolean;',
|
||||
'}',
|
||||
'',
|
||||
`export const VERIFY_COMMAND_ALIASES = ${JSON.stringify(verifyEntries, null, 2)} as const;`,
|
||||
`export const STATE_COMMAND_ALIASES: readonly FamilyCommandAlias[] = ${renderFamilyArray(stateEntries)} as const;`,
|
||||
'',
|
||||
`export const INIT_COMMAND_ALIASES = ${JSON.stringify(initEntries, null, 2)} as const;`,
|
||||
`export const VERIFY_COMMAND_ALIASES: readonly FamilyCommandAlias[] = ${renderFamilyArray(verifyEntries)} as const;`,
|
||||
'',
|
||||
`export const PHASE_COMMAND_ALIASES = ${JSON.stringify(phaseEntries, null, 2)} as const;`,
|
||||
`export const INIT_COMMAND_ALIASES: readonly FamilyCommandAlias[] = ${renderFamilyArray(initEntries)} as const;`,
|
||||
'',
|
||||
`export const PHASES_COMMAND_ALIASES = ${JSON.stringify(phasesEntries, null, 2)} as const;`,
|
||||
`export const PHASE_COMMAND_ALIASES: readonly FamilyCommandAlias[] = ${renderFamilyArray(phaseEntries)} as const;`,
|
||||
'',
|
||||
`export const VALIDATE_COMMAND_ALIASES = ${JSON.stringify(validateEntries, null, 2)} as const;`,
|
||||
`export const PHASES_COMMAND_ALIASES: readonly FamilyCommandAlias[] = ${renderFamilyArray(phasesEntries)} as const;`,
|
||||
'',
|
||||
`export const ROADMAP_COMMAND_ALIASES = ${JSON.stringify(roadmapEntries, null, 2)} as const;`,
|
||||
`export const VALIDATE_COMMAND_ALIASES: readonly FamilyCommandAlias[] = ${renderFamilyArray(validateEntries)} as const;`,
|
||||
'',
|
||||
`export const ROADMAP_COMMAND_ALIASES: readonly FamilyCommandAlias[] = ${renderFamilyArray(roadmapEntries)} as const;`,
|
||||
'',
|
||||
'export interface NonFamilyCommandAlias {',
|
||||
' canonical: string;',
|
||||
' aliases: string[];',
|
||||
' mutation: boolean;',
|
||||
'}',
|
||||
'',
|
||||
`export const NON_FAMILY_COMMAND_ALIASES: readonly NonFamilyCommandAlias[] = ${renderNonFamilyArray(nonFamilyEntries)} as const;`,
|
||||
'',
|
||||
'export const STATE_SUBCOMMANDS = new Set<string>(STATE_COMMAND_ALIASES.map((entry) => entry.subcommand));',
|
||||
'export const VERIFY_SUBCOMMANDS = new Set<string>(VERIFY_COMMAND_ALIASES.map((entry) => entry.subcommand));',
|
||||
@@ -92,9 +137,57 @@ async function main(): Promise<void> {
|
||||
'export const VALIDATE_SUBCOMMANDS = new Set<string>(VALIDATE_COMMAND_ALIASES.map((entry) => entry.subcommand));',
|
||||
'export const ROADMAP_SUBCOMMANDS = new Set<string>(ROADMAP_COMMAND_ALIASES.map((entry) => entry.subcommand));',
|
||||
'',
|
||||
|
||||
].join('\n');
|
||||
await writeFile(outPath, header + body, 'utf-8');
|
||||
await writeFile(tsOutPath, tsHeader + tsBody, 'utf-8');
|
||||
|
||||
// Also generate the CJS mirror used by get-shit-done/bin/lib/ seams.
|
||||
// CJS is plain JavaScript — no type annotations.
|
||||
const cjsOutPath = fileURLToPath(new URL('../../get-shit-done/bin/lib/command-aliases.generated.cjs', import.meta.url));
|
||||
const cjsHeader = `'use strict';\n\n/**\n * GENERATED FILE — state.*, verify.*, init.*, phase.*, phases.*, validate.*, roadmap.*, and non-family alias/subcommand metadata for CJS routing.\n * Source: sdk/src/query/command-manifest.{state,verify,init,phase,phases,validate,roadmap,non-family}.ts\n */\n\n`;
|
||||
const cjsBody = [
|
||||
`const STATE_COMMAND_ALIASES = ${JSON.stringify(stateEntries, null, 2)};`,
|
||||
'',
|
||||
`const VERIFY_COMMAND_ALIASES = ${JSON.stringify(verifyEntries, null, 2)};`,
|
||||
'',
|
||||
`const INIT_COMMAND_ALIASES = ${JSON.stringify(initEntries, null, 2)};`,
|
||||
'',
|
||||
`const PHASE_COMMAND_ALIASES = ${JSON.stringify(phaseEntries, null, 2)};`,
|
||||
'',
|
||||
`const PHASES_COMMAND_ALIASES = ${JSON.stringify(phasesEntries, null, 2)};`,
|
||||
'',
|
||||
`const VALIDATE_COMMAND_ALIASES = ${JSON.stringify(validateEntries, null, 2)};`,
|
||||
'',
|
||||
`const ROADMAP_COMMAND_ALIASES = ${JSON.stringify(roadmapEntries, null, 2)};`,
|
||||
'',
|
||||
`const NON_FAMILY_COMMAND_ALIASES = ${JSON.stringify(nonFamilyEntries, null, 2)};`,
|
||||
'',
|
||||
`const STATE_SUBCOMMANDS = STATE_COMMAND_ALIASES.map((entry) => entry.subcommand);`,
|
||||
`const VERIFY_SUBCOMMANDS = VERIFY_COMMAND_ALIASES.map((entry) => entry.subcommand);`,
|
||||
`const INIT_SUBCOMMANDS = INIT_COMMAND_ALIASES.map((entry) => entry.subcommand);`,
|
||||
`const PHASE_SUBCOMMANDS = PHASE_COMMAND_ALIASES.map((entry) => entry.subcommand);`,
|
||||
`const PHASES_SUBCOMMANDS = PHASES_COMMAND_ALIASES.map((entry) => entry.subcommand);`,
|
||||
`const VALIDATE_SUBCOMMANDS = VALIDATE_COMMAND_ALIASES.map((entry) => entry.subcommand);`,
|
||||
`const ROADMAP_SUBCOMMANDS = ROADMAP_COMMAND_ALIASES.map((entry) => entry.subcommand);`,
|
||||
'',
|
||||
`module.exports = {`,
|
||||
` STATE_COMMAND_ALIASES,`,
|
||||
` VERIFY_COMMAND_ALIASES,`,
|
||||
` INIT_COMMAND_ALIASES,`,
|
||||
` PHASE_COMMAND_ALIASES,`,
|
||||
` PHASES_COMMAND_ALIASES,`,
|
||||
` VALIDATE_COMMAND_ALIASES,`,
|
||||
` ROADMAP_COMMAND_ALIASES,`,
|
||||
` NON_FAMILY_COMMAND_ALIASES,`,
|
||||
` STATE_SUBCOMMANDS,`,
|
||||
` VERIFY_SUBCOMMANDS,`,
|
||||
` INIT_SUBCOMMANDS,`,
|
||||
` PHASE_SUBCOMMANDS,`,
|
||||
` PHASES_SUBCOMMANDS,`,
|
||||
` VALIDATE_SUBCOMMANDS,`,
|
||||
` ROADMAP_SUBCOMMANDS,`,
|
||||
`};`,
|
||||
].join('\n');
|
||||
await writeFile(cjsOutPath, cjsHeader + cjsBody, 'utf-8');
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* GENERATED FILE — command alias expansion for state.*, verify.*, init.*, phase.*, phases.*, validate.*, and roadmap.* pilots.
|
||||
* Source: sdk/src/query/command-manifest.{state,verify,init,phase,phases,validate,roadmap}.ts
|
||||
* GENERATED FILE — command alias expansion for state.*, verify.*, init.*, phase.*, phases.*, validate.*, roadmap.*, and non-family commands.
|
||||
* Source: sdk/src/query/command-manifest.{state,verify,init,phase,phases,validate,roadmap,non-family}.ts
|
||||
*/
|
||||
|
||||
export interface FamilyCommandAlias {
|
||||
@@ -97,6 +97,55 @@ export const ROADMAP_COMMAND_ALIASES: readonly FamilyCommandAlias[] = [
|
||||
{ canonical: 'roadmap.annotate-dependencies', aliases: ['roadmap annotate-dependencies'], subcommand: 'annotate-dependencies', mutation: true },
|
||||
] as const;
|
||||
|
||||
export interface NonFamilyCommandAlias {
|
||||
canonical: string;
|
||||
aliases: string[];
|
||||
mutation: boolean;
|
||||
}
|
||||
|
||||
export const NON_FAMILY_COMMAND_ALIASES: readonly NonFamilyCommandAlias[] = [
|
||||
{ canonical: 'check-commit', aliases: [], mutation: true },
|
||||
{ canonical: 'check.decision-coverage-plan', aliases: ['check decision-coverage-plan'], mutation: false },
|
||||
{ canonical: 'check.decision-coverage-verify', aliases: ['check decision-coverage-verify'], mutation: false },
|
||||
{ canonical: 'commit', aliases: [], mutation: true },
|
||||
{ canonical: 'commit-to-subrepo', aliases: [], mutation: true },
|
||||
{ canonical: 'config-ensure-section', aliases: [], mutation: true },
|
||||
{ canonical: 'config-new-project', aliases: [], mutation: true },
|
||||
{ canonical: 'config-set', aliases: [], mutation: true },
|
||||
{ canonical: 'config-set-model-profile', aliases: [], mutation: true },
|
||||
{ canonical: 'docs-init', aliases: [], mutation: true },
|
||||
{ canonical: 'frontmatter.get', aliases: [], mutation: false },
|
||||
{ canonical: 'frontmatter.merge', aliases: [], mutation: true },
|
||||
{ canonical: 'frontmatter.set', aliases: [], mutation: true },
|
||||
{ canonical: 'frontmatter.validate', aliases: ['frontmatter validate'], mutation: true },
|
||||
{ canonical: 'generate-claude-md', aliases: [], mutation: true },
|
||||
{ canonical: 'generate-claude-profile', aliases: [], mutation: true },
|
||||
{ canonical: 'generate-dev-preferences', aliases: [], mutation: true },
|
||||
{ canonical: 'intel.patch-meta', aliases: ['intel patch-meta'], mutation: true },
|
||||
{ canonical: 'intel.snapshot', aliases: ['intel snapshot'], mutation: true },
|
||||
{ canonical: 'learnings.copy', aliases: ['learnings copy'], mutation: true },
|
||||
{ canonical: 'learnings.delete', aliases: ['learnings delete'], mutation: true },
|
||||
{ canonical: 'learnings.prune', aliases: ['learnings prune'], mutation: true },
|
||||
{ canonical: 'milestone.complete', aliases: ['milestone complete'], mutation: true },
|
||||
{ canonical: 'phase.mvp-mode', aliases: ['phase mvp-mode'], mutation: false },
|
||||
{ canonical: 'progress.bar', aliases: ['progress bar'], mutation: false },
|
||||
{ canonical: 'requirements.mark-complete', aliases: ['requirements mark-complete'], mutation: true },
|
||||
{ canonical: 'stats.json', aliases: ['stats json'], mutation: false },
|
||||
{ canonical: 'task.is-behavior-adding', aliases: ['task is-behavior-adding'], mutation: false },
|
||||
{ canonical: 'template.fill', aliases: [], mutation: true },
|
||||
{ canonical: 'template.select', aliases: ['template select'], mutation: true },
|
||||
{ canonical: 'todo.complete', aliases: ['todo complete'], mutation: true },
|
||||
{ canonical: 'todo.match-phase', aliases: ['todo match-phase'], mutation: false },
|
||||
{ canonical: 'uat.render-checkpoint', aliases: ['uat render-checkpoint'], mutation: false },
|
||||
{ canonical: 'verify-summary', aliases: ['verify.summary', 'verify summary'], mutation: false },
|
||||
{ canonical: 'workstream.complete', aliases: ['workstream complete'], mutation: true },
|
||||
{ canonical: 'workstream.create', aliases: ['workstream create'], mutation: true },
|
||||
{ canonical: 'workstream.list', aliases: ['workstream list'], mutation: false },
|
||||
{ canonical: 'workstream.progress', aliases: ['workstream progress'], mutation: true },
|
||||
{ canonical: 'workstream.set', aliases: ['workstream set'], mutation: true },
|
||||
{ canonical: 'write-profile', aliases: [], mutation: true },
|
||||
] as const;
|
||||
|
||||
export const STATE_SUBCOMMANDS = new Set<string>(STATE_COMMAND_ALIASES.map((entry) => entry.subcommand));
|
||||
export const VERIFY_SUBCOMMANDS = new Set<string>(VERIFY_COMMAND_ALIASES.map((entry) => entry.subcommand));
|
||||
export const INIT_SUBCOMMANDS = new Set<string>(INIT_COMMAND_ALIASES.map((entry) => entry.subcommand));
|
||||
@@ -104,4 +153,3 @@ export const PHASE_SUBCOMMANDS = new Set<string>(PHASE_COMMAND_ALIASES.map((entr
|
||||
export const PHASES_SUBCOMMANDS = new Set<string>(PHASES_COMMAND_ALIASES.map((entry) => entry.subcommand));
|
||||
export const VALIDATE_SUBCOMMANDS = new Set<string>(VALIDATE_COMMAND_ALIASES.map((entry) => entry.subcommand));
|
||||
export const ROADMAP_SUBCOMMANDS = new Set<string>(ROADMAP_COMMAND_ALIASES.map((entry) => entry.subcommand));
|
||||
|
||||
|
||||
@@ -8,6 +8,10 @@ export interface NonFamilyCommandManifestEntry {
|
||||
}
|
||||
|
||||
export const NON_FAMILY_COMMAND_MANIFEST: readonly NonFamilyCommandManifestEntry[] = [
|
||||
{ canonical: 'check.decision-coverage-plan', aliases: ['check decision-coverage-plan'], mutation: false, outputMode: 'json' },
|
||||
{ canonical: 'check.decision-coverage-verify', aliases: ['check decision-coverage-verify'], mutation: false, outputMode: 'json' },
|
||||
|
||||
{ canonical: 'frontmatter.get', aliases: [], mutation: false, outputMode: 'json' },
|
||||
{ canonical: 'frontmatter.set', aliases: [], mutation: true, outputMode: 'json' },
|
||||
{ canonical: 'frontmatter.merge', aliases: [], mutation: true, outputMode: 'json' },
|
||||
{ canonical: 'frontmatter.validate', aliases: ['frontmatter validate'], mutation: true, outputMode: 'json' },
|
||||
@@ -28,12 +32,25 @@ export const NON_FAMILY_COMMAND_MANIFEST: readonly NonFamilyCommandManifestEntry
|
||||
{ canonical: 'todo.complete', aliases: ['todo complete'], mutation: true, outputMode: 'json' },
|
||||
{ canonical: 'milestone.complete', aliases: ['milestone complete'], mutation: true, outputMode: 'json' },
|
||||
|
||||
{ canonical: 'phase.mvp-mode', aliases: ['phase mvp-mode'], mutation: false, outputMode: 'json' },
|
||||
|
||||
{ canonical: 'progress.bar', aliases: ['progress bar'], mutation: false, outputMode: 'json' },
|
||||
|
||||
{ canonical: 'stats.json', aliases: ['stats json'], mutation: false, outputMode: 'json' },
|
||||
|
||||
{ canonical: 'task.is-behavior-adding', aliases: ['task is-behavior-adding'], mutation: false, outputMode: 'json' },
|
||||
|
||||
{ canonical: 'todo.match-phase', aliases: ['todo match-phase'], mutation: false, outputMode: 'json' },
|
||||
|
||||
{ canonical: 'uat.render-checkpoint', aliases: ['uat render-checkpoint'], mutation: false, outputMode: 'json' },
|
||||
|
||||
{
|
||||
canonical: 'workstream.create',
|
||||
aliases: ['workstream create'],
|
||||
mutation: true,
|
||||
outputMode: 'json',
|
||||
},
|
||||
{ canonical: 'workstream.list', aliases: ['workstream list'], mutation: false, outputMode: 'json' },
|
||||
{ canonical: 'workstream.set', aliases: ['workstream set'], mutation: true, outputMode: 'json' },
|
||||
{
|
||||
canonical: 'workstream.complete',
|
||||
|
||||
128
tests/feat-3251-command-aliases-manifest-coverage.test.cjs
Normal file
128
tests/feat-3251-command-aliases-manifest-coverage.test.cjs
Normal file
@@ -0,0 +1,128 @@
|
||||
'use strict';
|
||||
/**
|
||||
* Regression guard for issue #3251:
|
||||
* 14 commands used in workflows must be present in command-aliases.generated.cjs.
|
||||
*
|
||||
* Asserts structurally by requiring the manifest and checking each canonical
|
||||
* command appears in either the family arrays or the non-family array.
|
||||
* Never greps the source file — see feedback_no_source_grep_tests.md.
|
||||
*/
|
||||
|
||||
const { describe, test } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const path = require('path');
|
||||
|
||||
const REPO_ROOT = path.join(__dirname, '..');
|
||||
const COMMAND_ALIASES_FILE = path.join(
|
||||
REPO_ROOT,
|
||||
'get-shit-done',
|
||||
'bin',
|
||||
'lib',
|
||||
'command-aliases.generated.cjs',
|
||||
);
|
||||
|
||||
const MISSING_14 = [
|
||||
'check.decision-coverage-plan',
|
||||
'check.decision-coverage-verify',
|
||||
'frontmatter.get',
|
||||
'frontmatter.set',
|
||||
'learnings.copy',
|
||||
'milestone.complete',
|
||||
'phase.mvp-mode',
|
||||
'progress.bar',
|
||||
'requirements.mark-complete',
|
||||
'stats.json',
|
||||
'task.is-behavior-adding',
|
||||
'todo.match-phase',
|
||||
'uat.render-checkpoint',
|
||||
'workstream.list',
|
||||
];
|
||||
|
||||
describe('feat-3251: command-aliases.generated.cjs manifest coverage', () => {
|
||||
let manifest;
|
||||
|
||||
test('manifest file can be required without error', () => {
|
||||
try {
|
||||
manifest = require(COMMAND_ALIASES_FILE);
|
||||
} catch (err) {
|
||||
assert.fail(`Failed to require manifest: ${err.message}`);
|
||||
}
|
||||
assert.ok(manifest, 'manifest should be truthy');
|
||||
});
|
||||
|
||||
test('manifest exports NON_FAMILY_COMMAND_ALIASES array', () => {
|
||||
manifest = manifest ?? require(COMMAND_ALIASES_FILE);
|
||||
assert.ok(
|
||||
Array.isArray(manifest.NON_FAMILY_COMMAND_ALIASES),
|
||||
'NON_FAMILY_COMMAND_ALIASES must be an exported array in command-aliases.generated.cjs',
|
||||
);
|
||||
});
|
||||
|
||||
test('all 14 missing commands are present in the manifest (family or non-family)', () => {
|
||||
manifest = manifest ?? require(COMMAND_ALIASES_FILE);
|
||||
|
||||
const allCanonicalsInManifest = new Set();
|
||||
|
||||
// Collect from all family arrays
|
||||
const familyArrayKeys = [
|
||||
'STATE_COMMAND_ALIASES',
|
||||
'VERIFY_COMMAND_ALIASES',
|
||||
'INIT_COMMAND_ALIASES',
|
||||
'PHASE_COMMAND_ALIASES',
|
||||
'PHASES_COMMAND_ALIASES',
|
||||
'VALIDATE_COMMAND_ALIASES',
|
||||
'ROADMAP_COMMAND_ALIASES',
|
||||
];
|
||||
for (const key of familyArrayKeys) {
|
||||
const arr = manifest[key];
|
||||
if (!Array.isArray(arr)) continue;
|
||||
for (const entry of arr) {
|
||||
if (entry && entry.canonical) allCanonicalsInManifest.add(entry.canonical);
|
||||
}
|
||||
}
|
||||
|
||||
// Collect from non-family array
|
||||
const nonFamily = manifest.NON_FAMILY_COMMAND_ALIASES;
|
||||
if (Array.isArray(nonFamily)) {
|
||||
for (const entry of nonFamily) {
|
||||
if (entry && entry.canonical) allCanonicalsInManifest.add(entry.canonical);
|
||||
}
|
||||
}
|
||||
|
||||
const missing = MISSING_14.filter((cmd) => !allCanonicalsInManifest.has(cmd));
|
||||
assert.deepStrictEqual(
|
||||
missing,
|
||||
[],
|
||||
`${missing.length} command(s) still missing from manifest: ${missing.join(', ')}`,
|
||||
);
|
||||
});
|
||||
|
||||
test('each non-family entry has required fields: canonical, aliases, mutation', () => {
|
||||
manifest = manifest ?? require(COMMAND_ALIASES_FILE);
|
||||
const nonFamily = manifest.NON_FAMILY_COMMAND_ALIASES;
|
||||
if (!Array.isArray(nonFamily)) return; // caught by earlier test
|
||||
|
||||
for (const entry of nonFamily) {
|
||||
assert.ok(typeof entry.canonical === 'string' && entry.canonical.length > 0,
|
||||
`entry missing canonical: ${JSON.stringify(entry)}`);
|
||||
assert.ok(Array.isArray(entry.aliases),
|
||||
`entry missing aliases array for canonical=${entry.canonical}`);
|
||||
assert.ok(typeof entry.mutation === 'boolean',
|
||||
`entry missing mutation boolean for canonical=${entry.canonical}`);
|
||||
}
|
||||
});
|
||||
|
||||
test('NON_FAMILY_COMMAND_ALIASES is sorted by canonical (deterministic output)', () => {
|
||||
manifest = manifest ?? require(COMMAND_ALIASES_FILE);
|
||||
const nonFamily = manifest.NON_FAMILY_COMMAND_ALIASES;
|
||||
if (!Array.isArray(nonFamily)) return; // caught by earlier test
|
||||
|
||||
const canonicals = nonFamily.map((e) => e.canonical);
|
||||
const sorted = [...canonicals].sort((a, b) => a.localeCompare(b));
|
||||
assert.deepStrictEqual(
|
||||
canonicals,
|
||||
sorted,
|
||||
'NON_FAMILY_COMMAND_ALIASES must be sorted by canonical for deterministic regeneration',
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user