create-quiver 0.12.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +49 -17
  3. package/README_FOR_AI.md +31 -29
  4. package/ROADMAP.md +15 -3
  5. package/docs/AI_ONBOARDING_PROMPT.md.template +7 -1
  6. package/docs/COMMANDS.md.template +44 -18
  7. package/docs/STATUS.md.template +5 -1
  8. package/docs/WORKFLOW.md.template +13 -11
  9. package/package.json +9 -3
  10. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/EVIDENCE_REPORT.md +293 -0
  11. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/EXECUTION_PLAN.md +58 -0
  12. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/SPEC.md +242 -0
  13. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/STATUS.md +35 -0
  14. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/pr.md +77 -0
  15. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-00-spec-foundation/CLOSURE_BRIEF.md +34 -0
  16. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-00-spec-foundation/EXECUTION_BRIEF.md +52 -0
  17. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-00-spec-foundation/slice.json +52 -0
  18. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-01-cli-contract-compatibility/CLOSURE_BRIEF.md +36 -0
  19. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-01-cli-contract-compatibility/EXECUTION_BRIEF.md +52 -0
  20. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-01-cli-contract-compatibility/slice.json +56 -0
  21. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-02-run-state-phase-locks/CLOSURE_BRIEF.md +43 -0
  22. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-02-run-state-phase-locks/EXECUTION_BRIEF.md +54 -0
  23. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-02-run-state-phase-locks/slice.json +52 -0
  24. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-03-safe-ai-onboarding-docs/CLOSURE_BRIEF.md +35 -0
  25. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-03-safe-ai-onboarding-docs/EXECUTION_BRIEF.md +53 -0
  26. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-03-safe-ai-onboarding-docs/slice.json +54 -0
  27. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-04-agent-profiles-adapters/CLOSURE_BRIEF.md +34 -0
  28. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-04-agent-profiles-adapters/EXECUTION_BRIEF.md +54 -0
  29. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-04-agent-profiles-adapters/slice.json +52 -0
  30. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-05-approval-gates/CLOSURE_BRIEF.md +34 -0
  31. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-05-approval-gates/EXECUTION_BRIEF.md +54 -0
  32. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-05-approval-gates/slice.json +53 -0
  33. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-06-spec-slice-generator/CLOSURE_BRIEF.md +33 -0
  34. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-06-spec-slice-generator/EXECUTION_BRIEF.md +56 -0
  35. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-06-spec-slice-generator/slice.json +55 -0
  36. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-07-slice-execution-planner/CLOSURE_BRIEF.md +33 -0
  37. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-07-slice-execution-planner/EXECUTION_BRIEF.md +54 -0
  38. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-07-slice-execution-planner/slice.json +52 -0
  39. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-08-controlled-slice-execution/CLOSURE_BRIEF.md +39 -0
  40. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-08-controlled-slice-execution/EXECUTION_BRIEF.md +56 -0
  41. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-08-controlled-slice-execution/slice.json +53 -0
  42. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-09-git-worktree-pr-lifecycle/CLOSURE_BRIEF.md +38 -0
  43. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-09-git-worktree-pr-lifecycle/EXECUTION_BRIEF.md +57 -0
  44. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-09-git-worktree-pr-lifecycle/slice.json +52 -0
  45. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-10-validation-errors-fixtures/CLOSURE_BRIEF.md +39 -0
  46. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-10-validation-errors-fixtures/EXECUTION_BRIEF.md +55 -0
  47. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-10-validation-errors-fixtures/slice.json +56 -0
  48. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-11-export-dashboard-migration/CLOSURE_BRIEF.md +36 -0
  49. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-11-export-dashboard-migration/EXECUTION_BRIEF.md +54 -0
  50. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-11-export-dashboard-migration/slice.json +53 -0
  51. package/specs/quiver-v26-0121-smoke-hardening/EVIDENCE_REPORT.md +208 -0
  52. package/specs/quiver-v26-0121-smoke-hardening/EXECUTION_PLAN.md +57 -0
  53. package/specs/quiver-v26-0121-smoke-hardening/SPEC.md +137 -0
  54. package/specs/quiver-v26-0121-smoke-hardening/STATUS.md +32 -0
  55. package/specs/quiver-v26-0121-smoke-hardening/pr.md +96 -0
  56. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-00-docs-foundation/CLOSURE_BRIEF.md +35 -0
  57. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-00-docs-foundation/EXECUTION_BRIEF.md +55 -0
  58. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-00-docs-foundation/slice.json +73 -0
  59. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-01-cli-help-version-contract/CLOSURE_BRIEF.md +38 -0
  60. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-01-cli-help-version-contract/EXECUTION_BRIEF.md +51 -0
  61. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-01-cli-help-version-contract/slice.json +76 -0
  62. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-02-init-doc-links-and-flow-guidance/CLOSURE_BRIEF.md +37 -0
  63. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-02-init-doc-links-and-flow-guidance/EXECUTION_BRIEF.md +52 -0
  64. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-02-init-doc-links-and-flow-guidance/slice.json +75 -0
  65. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-03-ai-approval-review-consistency/CLOSURE_BRIEF.md +37 -0
  66. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-03-ai-approval-review-consistency/EXECUTION_BRIEF.md +53 -0
  67. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-03-ai-approval-review-consistency/slice.json +77 -0
  68. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-04-local-validation-brief-contracts/CLOSURE_BRIEF.md +35 -0
  69. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-04-local-validation-brief-contracts/EXECUTION_BRIEF.md +52 -0
  70. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-04-local-validation-brief-contracts/slice.json +77 -0
  71. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-05-demo-scaffold-readiness/CLOSURE_BRIEF.md +34 -0
  72. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-05-demo-scaffold-readiness/EXECUTION_BRIEF.md +54 -0
  73. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-05-demo-scaffold-readiness/slice.json +84 -0
  74. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-06-plan-graph-scope-performance/CLOSURE_BRIEF.md +35 -0
  75. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-06-plan-graph-scope-performance/EXECUTION_BRIEF.md +53 -0
  76. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-06-plan-graph-scope-performance/slice.json +82 -0
  77. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-07-smoke-release-readiness/CLOSURE_BRIEF.md +35 -0
  78. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-07-smoke-release-readiness/EXECUTION_BRIEF.md +55 -0
  79. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-07-smoke-release-readiness/slice.json +92 -0
  80. package/src/create-quiver/commands/ai.js +577 -27
  81. package/src/create-quiver/commands/flow.js +6 -5
  82. package/src/create-quiver/commands/graph.js +6 -4
  83. package/src/create-quiver/commands/plan.js +3 -3
  84. package/src/create-quiver/index.js +328 -12
  85. package/src/create-quiver/lib/actionable-error.js +27 -0
  86. package/src/create-quiver/lib/agent-profiles.js +1 -1
  87. package/src/create-quiver/lib/ai/context-packs.js +4 -0
  88. package/src/create-quiver/lib/ai/execution-plan.js +7 -1
  89. package/src/create-quiver/lib/ai/executor.js +270 -20
  90. package/src/create-quiver/lib/ai/export-state.js +534 -0
  91. package/src/create-quiver/lib/ai/github.js +83 -0
  92. package/src/create-quiver/lib/ai/onboarding-template.js +215 -2
  93. package/src/create-quiver/lib/ai/plan-review.js +5 -2
  94. package/src/create-quiver/lib/ai/providers.js +4 -3
  95. package/src/create-quiver/lib/ai/run-state.js +414 -0
  96. package/src/create-quiver/lib/ai/spec-generator.js +12 -0
  97. package/src/create-quiver/lib/ai/spec-templates.js +78 -9
  98. package/src/create-quiver/lib/approvals.js +22 -3
  99. package/src/create-quiver/lib/demo.js +189 -14
  100. package/src/create-quiver/lib/doctor.js +75 -0
  101. package/src/create-quiver/lib/handoff.js +81 -12
  102. package/src/create-quiver/lib/init-docs.js +24 -6
  103. package/src/create-quiver/lib/init-layout.js +8 -0
  104. package/src/create-quiver/lib/json.js +53 -3
  105. package/src/create-quiver/lib/readiness.js +18 -3
  106. package/src/create-quiver/lib/scope.js +50 -7
  107. package/src/create-quiver/lib/slice-graph.js +138 -38
  108. package/src/create-quiver/lib/slice.js +6 -1
  109. package/src/create-quiver/lib/spec-worktrees.js +16 -2
@@ -289,10 +289,11 @@ function detectFlowState(projectRoot) {
289
289
  stage: 'criteria-draft',
290
290
  label: 'acceptance criteria need approval',
291
291
  blockers: ['Acceptance criteria draft exists but is not approved.'],
292
- nextCommand: 'npx create-quiver ai approve --phase acceptance --input acceptance-approved.md',
292
+ nextCommand: 'npx create-quiver ai approve --phase acceptance --version <n>',
293
293
  suggestedCommands: [
294
294
  'npx create-quiver ai approvals',
295
- 'npx create-quiver ai approve --phase acceptance --input acceptance-approved.md',
295
+ 'npx create-quiver ai revise --phase acceptance --input feedback.md --dry-run',
296
+ 'npx create-quiver ai approve --phase acceptance --version <n>',
296
297
  ],
297
298
  facts,
298
299
  });
@@ -303,10 +304,11 @@ function detectFlowState(projectRoot) {
303
304
  stage: 'criteria-stale',
304
305
  label: 'acceptance criteria approval is stale',
305
306
  blockers: ['Acceptance criteria changed after approval.'],
306
- nextCommand: 'npx create-quiver ai approve --phase acceptance --input acceptance-approved.md',
307
+ nextCommand: 'npx create-quiver ai approve --phase acceptance --version <n>',
307
308
  suggestedCommands: [
308
309
  'npx create-quiver ai approvals',
309
- 'npx create-quiver ai approve --phase acceptance --input acceptance-approved.md',
310
+ 'npx create-quiver ai revise --phase acceptance --input feedback.md --dry-run',
311
+ 'npx create-quiver ai approve --phase acceptance --version <n>',
310
312
  ],
311
313
  facts,
312
314
  });
@@ -407,7 +409,6 @@ function detectFlowState(projectRoot) {
407
409
  suggestedCommands: [
408
410
  'npx create-quiver ai review-plan --dry-run',
409
411
  'npx create-quiver ai review-plan',
410
- 'npx create-quiver ai approve --phase technical-plan --version <n>',
411
412
  ],
412
413
  facts,
413
414
  });
@@ -1,4 +1,4 @@
1
- const { buildGraph, computeLevels, detectFileConflicts, readAllSlices } = require('../lib/slice-graph');
1
+ const { buildGraph, computeLevels, detectFileConflicts, readAllSlices, readSlicesForSpec } = require('../lib/slice-graph');
2
2
  const { renderDotGraph } = require('../lib/renderers/dot');
3
3
  const { renderMermaidGraph } = require('../lib/renderers/mermaid');
4
4
  const { renderTreeGraph, isUnicodeEnabled } = require('../lib/renderers/tree');
@@ -28,11 +28,13 @@ function buildConflictPayload(levelIndex, groups) {
28
28
  }
29
29
 
30
30
  function collectGraph(repoRoot, options = {}) {
31
- const graph = buildGraph(readAllSlices(repoRoot));
32
- computeLevels(graph);
31
+ const specSlug = options.specSlug ? String(options.specSlug).trim() : '';
32
+ const graph = buildGraph(specSlug ? readSlicesForSpec(repoRoot, specSlug) : readAllSlices(repoRoot));
33
+ if (!specSlug) {
34
+ computeLevels(graph);
35
+ }
33
36
  const includeCompleted = options.includeCompleted === true;
34
37
  const excluded = includeCompleted ? HISTORY_EXCLUDED_STATUSES : EXCLUDED_STATUSES;
35
- const specSlug = options.specSlug ? String(options.specSlug).trim() : '';
36
38
  const pendingNodes = graph.nodes.filter((node) => {
37
39
  if (excluded.has(String(node.status || '').toLowerCase())) {
38
40
  return false;
@@ -1,7 +1,7 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
  const { relativePosixPath } = require('../lib/paths');
4
- const { buildGraph, readAllSlices, topoSort } = require('../lib/slice-graph');
4
+ const { buildGraph, readAllSlices, readSlicesForSpec, topoSort } = require('../lib/slice-graph');
5
5
 
6
6
  const EXCLUDED_STATUSES = new Set(['completed', 'skipped', 'cancelled']);
7
7
  const HISTORY_EXCLUDED_STATUSES = new Set(['skipped', 'cancelled']);
@@ -116,12 +116,12 @@ function buildCriticalPath(graph, refs) {
116
116
  }
117
117
 
118
118
  function collectPlan(repoRoot, options = {}) {
119
- const allSlices = readAllSlices(repoRoot);
119
+ const specSlug = options.specSlug ? String(options.specSlug).trim() : '';
120
+ const allSlices = specSlug ? readSlicesForSpec(repoRoot, specSlug) : readAllSlices(repoRoot);
120
121
  const graph = buildGraph(allSlices);
121
122
  const topo = topoSort(graph);
122
123
  const includeCompleted = options.includeCompleted === true;
123
124
  const excluded = includeCompleted ? HISTORY_EXCLUDED_STATUSES : EXCLUDED_STATUSES;
124
- const specSlug = options.specSlug ? String(options.specSlug).trim() : '';
125
125
 
126
126
  const pendingRefs = new Set(
127
127
  graph.nodes
@@ -9,7 +9,29 @@ const {
9
9
  collectDoctorReport,
10
10
  formatDoctorFixPlan,
11
11
  } = require('./lib/doctor');
12
- const { runAgent: runAiAgent, runApprovalStatus: runAiApprovalStatus, runApprove: runAiApprove, runDoctor: runAiDoctor, runExecutePlan: runAiExecutePlan, runExecuteSlice: runAiExecuteSlice, runOnboard, runPlan: runAiPlan, runPrepareContext: runAiPrepareContext, runPr: runAiPr, runPromptSlice: runAiPromptSlice, runReviewPlan: runAiReviewPlan } = require('./commands/ai');
12
+ const {
13
+ runAgent: runAiAgent,
14
+ runApprovalStatus: runAiApprovalStatus,
15
+ runApprove: runAiApprove,
16
+ runDoctor: runAiDoctor,
17
+ runExecutePlan: runAiExecutePlan,
18
+ runExecuteSlice: runAiExecuteSlice,
19
+ runExport: runAiExport,
20
+ runInspect: runAiInspect,
21
+ runLifecycleResume: runAiLifecycleResume,
22
+ runLifecycleRun: runAiLifecycleRun,
23
+ runLifecycleStatus: runAiLifecycleStatus,
24
+ runOnboard,
25
+ runPlan: runAiPlan,
26
+ runPrepareContext: runAiPrepareContext,
27
+ runPr: runAiPr,
28
+ runPromptSlice: runAiPromptSlice,
29
+ runReviewPlan: runAiReviewPlan,
30
+ runRevise: runAiRevise,
31
+ runSlicesList: runAiSlicesList,
32
+ runSpecsList: runAiSpecsList,
33
+ runTraceReport: runAiTraceReport,
34
+ } = require('./commands/ai');
13
35
  const { runDemo } = require('./commands/demo');
14
36
  const { runPrepare } = require('./commands/prepare');
15
37
  const { runEvidence } = require('./commands/evidence');
@@ -80,12 +102,21 @@ const SUPPORTED_AI_COMMANDS = new Set([
80
102
  'execute-plan',
81
103
  'execute-slice',
82
104
  'executor-prompt',
105
+ 'export',
106
+ 'inspect',
83
107
  'onboard',
84
108
  'plan',
85
109
  'prepare-context',
86
110
  'pr',
87
111
  'prompt-slice',
88
112
  'review-plan',
113
+ 'revise',
114
+ 'resume',
115
+ 'run',
116
+ 'slices',
117
+ 'specs',
118
+ 'status',
119
+ 'trace',
89
120
  ]);
90
121
 
91
122
  const SUPPORTED_SPEC_COMMANDS = new Set(['close', 'create', 'start', 'status']);
@@ -100,6 +131,103 @@ function unsupportedCommandMessage(commandName) {
100
131
  ].join('\n');
101
132
  }
102
133
 
134
+ const COMMAND_HELP_GROUPS = [
135
+ {
136
+ title: 'Bootstrap and project context',
137
+ commands: [
138
+ ['init', 'Create the default AI-first Quiver contract in the current project.'],
139
+ ['analyze', 'Scan the project and write docs/PROJECT_MAP.md plus .quiver scan data.'],
140
+ ['doctor', 'Validate the Quiver layout, generated docs, environment, and next safe steps.'],
141
+ ['flow', 'Show the read-only guided workflow stage, blockers, and next safe command.'],
142
+ ['prepare', 'Run setup diagnostics for providers, GitHub, SSH, and project readiness.'],
143
+ ['migrate', 'Upgrade an already initialized Quiver project to the current contract.'],
144
+ ],
145
+ },
146
+ {
147
+ title: 'Planning and slice navigation',
148
+ commands: [
149
+ ['plan', 'List slices in execution order with critical path and optional JSON output.'],
150
+ ['graph', 'Render slice dependencies as tree, Mermaid, DOT, or JSON-ready graph output.'],
151
+ ['next', 'Print the next ready slice or every ready slice with --all-ready.'],
152
+ ],
153
+ },
154
+ {
155
+ title: 'AI lifecycle',
156
+ commands: [
157
+ ['ai run create', 'Create a durable AI lifecycle run from a requirements file.'],
158
+ ['ai status', 'Show current AI lifecycle phase, approved versions, blockers, and next command.'],
159
+ ['ai resume', 'Resume guidance from the last valid lifecycle phase without chat memory.'],
160
+ ['ai onboard', 'Run or print the planner onboarding prompt with a token-aware context pack.'],
161
+ ['ai prepare-context', 'Preview or write docs-only AI context updates with assumptions and risks.'],
162
+ ['ai agent set|list|show', 'Manage planner, executor, reviewer, and doctor provider profiles without secrets.'],
163
+ ['ai plan', 'Generate versioned planner drafts for acceptance criteria, technical plan, or spec phase.'],
164
+ ['ai revise', 'Create a new planner draft from human feedback without approving it.'],
165
+ ['ai review-plan', 'Review the technical-plan draft for production readiness before approval.'],
166
+ ['ai approve', 'Approve a concrete saved draft version for the next planner phase.'],
167
+ ['ai approvals', 'Inspect approval status and saved planner drafts.'],
168
+ ['ai prompt-slice', 'Print a minimal executor prompt for one slice without provider execution.'],
169
+ ['ai execute-slice', 'Execute one slice with scope checks, redacted evidence, closure updates, and optional commit.'],
170
+ ['ai execute-plan', 'Print or execute dependency-safe waves in manual or delegated mode.'],
171
+ ['ai doctor', 'Run GitHub, SSH, and PR readiness preflight checks.'],
172
+ ['ai pr', 'Validate and optionally create a GitHub PR from the generated PR body.'],
173
+ ],
174
+ },
175
+ {
176
+ title: 'Inspection and export',
177
+ commands: [
178
+ ['ai inspect', 'Show dashboard-friendly lifecycle state for specs, slices, runs, agents, and blockers.'],
179
+ ['ai export', 'Export lifecycle state as JSON or Markdown for dashboards, PRs, or other agents.'],
180
+ ['ai specs list', 'List specs with status, progress, slice counts, and paths.'],
181
+ ['ai slices list', 'List slices with status, dependencies, blockers, and optional JSON.'],
182
+ ['ai trace report', 'Report AI runs, execution waves, and migration guidance.'],
183
+ ],
184
+ },
185
+ {
186
+ title: 'Specs, slices, and validation',
187
+ commands: [
188
+ ['spec create', 'Create the real spec tree from a reviewed approved technical plan.'],
189
+ ['spec start', 'Create or reuse the dedicated worktree and branch for one spec.'],
190
+ ['spec status', 'Show spec worktree, branch, slice-00 state, and pending slices.'],
191
+ ['spec close', 'Close a merged clean spec worktree and guide local sync.'],
192
+ ['start-slice', 'Start work on one slice and mark it active.'],
193
+ ['check-slice', 'Validate slice structure, dependencies, scope, and readiness.'],
194
+ ['check-pr', 'Validate PR readiness for a slice/spec workflow.'],
195
+ ['check-scope', 'Compare changed files against a slice scope.'],
196
+ ['cleanup-slice', 'Clean active-slice state after a slice finishes or is discarded.'],
197
+ ['refresh-active-slices', 'Refresh generated active-slice boards.'],
198
+ ['check-handoff', 'Validate a transfer handoff or per-slice execution/closure brief.'],
199
+ ['new-handoff', 'Create a handoff scaffold for exceptional context transfer.'],
200
+ ],
201
+ },
202
+ {
203
+ title: 'Evidence and demos',
204
+ commands: [
205
+ ['evidence run', 'Run a command and record exit code, duration, redacted output, and Markdown evidence.'],
206
+ ['demo create spec-viewer', 'Create or preview the optional static Quiver Spec Viewer demo scaffold.'],
207
+ ],
208
+ },
209
+ {
210
+ title: 'Shortcuts and compatibility',
211
+ commands: [
212
+ ['--name "<project>"', 'Compatibility alias for init when bootstrapping a project.'],
213
+ ['--version / -V', 'Print the installed create-quiver package version.'],
214
+ ['--help / help', 'Show this command reference.'],
215
+ ['quiver', 'Local installed alias to the same CLI; use npx create-quiver for bootstrap.'],
216
+ ],
217
+ },
218
+ ];
219
+
220
+ function formatCommandHelpGroups() {
221
+ const lines = ['Commands:'];
222
+ for (const group of COMMAND_HELP_GROUPS) {
223
+ lines.push('', `${group.title}:`);
224
+ for (const [command, description] of group.commands) {
225
+ lines.push(` ${command.padEnd(24)} ${description}`);
226
+ }
227
+ }
228
+ return lines.join('\n');
229
+ }
230
+
103
231
  function printUsage() {
104
232
  console.log(`Usage:
105
233
  npx create-quiver [options]
@@ -108,8 +236,17 @@ function printUsage() {
108
236
  npx create-quiver flow [options]
109
237
  npx create-quiver plan [options]
110
238
  npx create-quiver ai <task> [options]
239
+ npx create-quiver ai run create --input <requirements.md>
240
+ npx create-quiver ai status [options]
241
+ npx create-quiver ai resume [options]
242
+ npx create-quiver ai inspect [options]
243
+ npx create-quiver ai export [--format json|markdown]
244
+ npx create-quiver ai specs list [--json]
245
+ npx create-quiver ai slices list [--json]
246
+ npx create-quiver ai trace report [options]
111
247
  npx create-quiver ai agent <set|list|show> [role] [options]
112
248
  npx create-quiver ai prepare-context [options]
249
+ npx create-quiver ai revise [options]
113
250
  npx create-quiver graph [options]
114
251
  npx create-quiver next [options]
115
252
  npx create-quiver migrate [options]
@@ -118,7 +255,7 @@ function printUsage() {
118
255
  npx create-quiver start-slice [options] <slice.json>
119
256
  npx create-quiver check-slice [options] <slice.json>
120
257
  npx create-quiver check-pr <slice.json>
121
- npx create-quiver check-handoff <handoff.md>
258
+ npx create-quiver check-handoff <handoff-or-brief.md>
122
259
  npx create-quiver new-handoff <spec-slug>
123
260
  npx create-quiver cleanup-slice [options] <slice.json>
124
261
  npx create-quiver check-scope [options] <slice.json>
@@ -130,11 +267,13 @@ function printUsage() {
130
267
  npx create-quiver evidence run [options] -- <command>
131
268
  npx create-quiver demo create spec-viewer [options]
132
269
 
270
+ ${formatCommandHelpGroups()}
271
+
133
272
  Options:
134
273
  -n, --name <project-name> Project name to generate
135
274
  -d, --dir <target-dir> Target directory to scaffold into or inspect
136
275
  --spec <slug> Restrict plan output to one spec
137
- --format <name> Graph output format (tree, mermaid, dot)
276
+ --format <name> Graph or AI export output format (tree, mermaid, dot, json, markdown)
138
277
  --show-conflicts Show shared file paths in graph output
139
278
  --level <n> Restrict graph output to one level
140
279
  --json Emit machine-readable JSON
@@ -148,7 +287,8 @@ Options:
148
287
  --full Plan or run the full compatibility init profile
149
288
  --legacy-scripts Include legacy Bash wrappers in init profile
150
289
  --include-templates Export packaged templates in init profile
151
- --dry-run Preview init, prepare, spec create, demo, or AI work without executing writes/providers
290
+ --dry-run Preview init, migrate, prepare, spec create/start/close, demo, or AI work without executing writes/providers
291
+ --print-prompt Print the exact AI prompt and exit without executing provider CLIs
152
292
  --fix For doctor, apply safe non-destructive repairs
153
293
  --execute For ai execute-plan, run the planned slices instead of printing commands
154
294
  --create For ai pr, create the PR after preflight instead of printing the plan only
@@ -158,6 +298,7 @@ Options:
158
298
  --provider <name> Provider CLI to preflight for prepare or AI commands
159
299
  --model <label> Free-form model label for AI agent profiles
160
300
  --version <n> Draft version to approve for AI planner phases
301
+ --run <id> AI lifecycle run id
161
302
  --ssh-host-alias <name> SSH host alias to validate for prepare or AI commands
162
303
  --identity-file <path> SSH identity file to validate for prepare or AI commands
163
304
  --remote <name> Git remote name for check-slice or AI PR checks
@@ -166,6 +307,7 @@ Options:
166
307
  --max-output <n> Maximum stdout/stderr chars per evidence section
167
308
  --title <text> Override PR title for ai pr create
168
309
  -y, --yes Skip prompts and use the provided inputs
310
+ -V, --version Show the installed create-quiver version
169
311
  -h, --help Show this help message
170
312
 
171
313
  Examples:
@@ -177,15 +319,27 @@ Examples:
177
319
  cd ./my-project && npx create-quiver analyze
178
320
  cd ./my-project && npx create-quiver plan --json
179
321
  cd ./my-project && npx create-quiver ai onboard --dry-run
322
+ cd ./my-project && npx create-quiver ai onboard --print-prompt
180
323
  cd ./my-project && npx create-quiver ai prepare-context --dry-run
324
+ cd ./my-project && npx create-quiver ai run create --input requirements.md
325
+ cd ./my-project && npx create-quiver ai status
326
+ cd ./my-project && npx create-quiver ai resume
327
+ cd ./my-project && npx create-quiver ai inspect
328
+ cd ./my-project && npx create-quiver ai export --format json
329
+ cd ./my-project && npx create-quiver ai export --format markdown
330
+ cd ./my-project && npx create-quiver ai specs list
331
+ cd ./my-project && npx create-quiver ai slices list --json
332
+ cd ./my-project && npx create-quiver ai trace report
181
333
  cd ./my-project && npx create-quiver ai agent set planner --provider codex --model gpt-5.5
182
334
  cd ./my-project && npx create-quiver ai agent list
183
335
  cd ./my-project && npx create-quiver ai plan --phase acceptance --input requirements.md --dry-run
184
- cd ./my-project && npx create-quiver ai approve --phase acceptance --input acceptance.md
336
+ cd ./my-project && npx create-quiver ai revise --phase acceptance --input feedback.md --dry-run
337
+ cd ./my-project && npx create-quiver ai approve --phase acceptance --version 1
185
338
  cd ./my-project && npx create-quiver ai plan --phase technical-plan --dry-run
186
339
  cd ./my-project && npx create-quiver ai review-plan --dry-run
187
340
  cd ./my-project && npx create-quiver ai approve --phase technical-plan --version 1
188
341
  cd ./my-project && npx create-quiver spec create --dry-run
342
+ cd ./my-project && npx create-quiver spec start specs/my-project --dry-run
189
343
  cd ./my-project && npx create-quiver ai approvals
190
344
  cd ./my-project && npx create-quiver ai prompt-slice --slice specs/my-project/slices/slice-01/slice.json --dry-run
191
345
  cd ./my-project && npx create-quiver ai execute-slice --slice specs/my-project/slices/slice-01/slice.json --dry-run
@@ -207,6 +361,7 @@ Examples:
207
361
  cd ./my-project && npx create-quiver check-slice specs/my-project/slices/slice-01/slice.json
208
362
  cd ./my-project && npx create-quiver check-pr specs/my-project/slices/slice-01/slice.json
209
363
  cd ./my-project && npx create-quiver check-handoff specs/my-project/HANDOFF.md
364
+ cd ./my-project && npx create-quiver check-handoff specs/my-project/slices/slice-01/EXECUTION_BRIEF.md
210
365
  cd ./my-project && npx create-quiver new-handoff my-spec
211
366
  cd ./my-project && npx create-quiver cleanup-slice specs/my-project/slices/slice-01/slice.json
212
367
  cd ./my-project && npx create-quiver check-scope specs/my-project/slices/slice-01/slice.json
@@ -232,6 +387,7 @@ function parseArgs(argv) {
232
387
  discard: false,
233
388
  doctorFix: false,
234
389
  dryRun: false,
390
+ aiPrintPrompt: false,
235
391
  gate: 'execution',
236
392
  projectName: '',
237
393
  targetDir: '.',
@@ -245,12 +401,16 @@ function parseArgs(argv) {
245
401
  autoStart: false,
246
402
  specSlug: '',
247
403
  format: 'tree',
404
+ formatExplicit: false,
248
405
  showConflicts: false,
249
406
  level: null,
250
407
  unicode: false,
251
408
  aiCommand: '',
409
+ aiSecondaryCommand: '',
252
410
  aiAgentCommand: '',
253
411
  aiAgentRole: '',
412
+ aiRunCommand: '',
413
+ aiRunId: '',
254
414
  aiPhase: 'acceptance',
255
415
  aiProvider: 'codex',
256
416
  aiProviderExplicit: false,
@@ -396,6 +556,11 @@ function parseArgs(argv) {
396
556
  continue;
397
557
  }
398
558
 
559
+ if (arg === '--print-prompt') {
560
+ result.aiPrintPrompt = true;
561
+ continue;
562
+ }
563
+
399
564
  if (arg === '--commit') {
400
565
  result.aiCommit = true;
401
566
  continue;
@@ -476,6 +641,7 @@ function parseArgs(argv) {
476
641
  throw new Error(formatError('missing value for --format'));
477
642
  }
478
643
  result.format = value;
644
+ result.formatExplicit = true;
479
645
  continue;
480
646
  }
481
647
 
@@ -550,6 +716,15 @@ function parseArgs(argv) {
550
716
  continue;
551
717
  }
552
718
 
719
+ if (arg === '--run') {
720
+ const value = args[++index];
721
+ if (!value) {
722
+ throw new Error(formatError('missing value for --run'));
723
+ }
724
+ result.aiRunId = value;
725
+ continue;
726
+ }
727
+
553
728
  if (arg === '--role') {
554
729
  const value = args[++index];
555
730
  if (!value) {
@@ -748,6 +923,18 @@ function parseArgs(argv) {
748
923
  result.aiAgentRole = positional.shift();
749
924
  }
750
925
  }
926
+ if (result.aiCommand === 'run' && !result.aiRunCommand && positional.length > 0) {
927
+ result.aiRunCommand = positional.shift();
928
+ }
929
+ if ((result.aiCommand === 'specs' || result.aiCommand === 'slices' || result.aiCommand === 'trace') && !result.aiSecondaryCommand && positional.length > 0) {
930
+ result.aiSecondaryCommand = positional.shift();
931
+ }
932
+ if ((result.aiCommand === 'specs' || result.aiCommand === 'slices') && result.aiSecondaryCommand && result.aiSecondaryCommand !== 'list') {
933
+ throw new Error(formatError(`unsupported ai ${result.aiCommand} subcommand: ${result.aiSecondaryCommand}. Supported tasks: list`));
934
+ }
935
+ if (result.aiCommand === 'trace' && result.aiSecondaryCommand && result.aiSecondaryCommand !== 'report') {
936
+ throw new Error(formatError(`unsupported ai trace subcommand: ${result.aiSecondaryCommand}. Supported tasks: report`));
937
+ }
751
938
  if (positional.length > 0) {
752
939
  throw new Error(formatError('ai does not accept extra positional arguments'));
753
940
  }
@@ -1845,9 +2032,34 @@ function runMigrate(targetDir, options = {}) {
1845
2032
  const packageJson = loadPackageJson(projectRoot);
1846
2033
  const projectName = packageJson.name || path.basename(projectRoot) || 'Quiver Project';
1847
2034
  const packageRoot = path.resolve(__dirname, '../..');
1848
- const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'quiver-migrate-'));
1849
2035
  const legacyLayout = inspectLegacyMigrationLayout(projectRoot);
1850
2036
 
2037
+ if (options.dryRun) {
2038
+ const migrationPlan = buildInitLayout(projectRoot, {
2039
+ dryRun: true,
2040
+ full: true,
2041
+ legacyScripts: true,
2042
+ projectName,
2043
+ skipInstall: options.skipInstall === true,
2044
+ });
2045
+ console.log('Quiver migration dry-run');
2046
+ console.log(`- Project: ${projectName}`);
2047
+ console.log(`- Target: ${projectRoot}`);
2048
+ console.log('- Writes: none');
2049
+ console.log(`- Planned create: ${migrationPlan.summary.create}`);
2050
+ console.log(`- Planned update: ${migrationPlan.summary.update}`);
2051
+ console.log(`- Planned preserve: ${migrationPlan.summary.preserve}`);
2052
+ if (legacyLayout.hasLegacyLayout) {
2053
+ console.log(`- Legacy layout detected and preserved: ${legacyLayout.legacyPaths.join(', ')}`);
2054
+ }
2055
+ console.log('- Next command: npx create-quiver migrate --skip-install');
2056
+ console.log('');
2057
+ console.log(formatInitLayoutPlan(migrationPlan));
2058
+ return;
2059
+ }
2060
+
2061
+ const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'quiver-migrate-'));
2062
+
1851
2063
  try {
1852
2064
  const templateRoot = packTemplate(packageRoot, tempRoot);
1853
2065
  mergeDirectoryTree(templateRoot, path.join(projectRoot, 'docs-template'));
@@ -1958,6 +2170,11 @@ function runDoctor(targetDir, options = {}) {
1958
2170
  .filter((name) => typeof pkg.scripts?.[name] !== 'string');
1959
2171
  const missingAiScripts = [
1960
2172
  'quiver:ai:agent',
2173
+ 'quiver:ai:inspect',
2174
+ 'quiver:ai:export',
2175
+ 'quiver:ai:specs',
2176
+ 'quiver:ai:slices',
2177
+ 'quiver:ai:trace',
1961
2178
  'quiver:ai:onboard',
1962
2179
  'quiver:ai:plan',
1963
2180
  'quiver:ai:review-plan',
@@ -2045,6 +2262,16 @@ function printInitNextSteps(targetDir, projectName) {
2045
2262
  }
2046
2263
 
2047
2264
  async function run(argv) {
2265
+ if (argv.length === 1 && argv[0] === 'help') {
2266
+ printUsage();
2267
+ return;
2268
+ }
2269
+
2270
+ if (argv.length === 1 && (argv[0] === '-V' || argv[0] === '--version')) {
2271
+ console.log(CLI_VERSION);
2272
+ return;
2273
+ }
2274
+
2048
2275
  const args = parseArgs(argv);
2049
2276
 
2050
2277
  if (args.help) {
@@ -2087,7 +2314,69 @@ async function run(argv) {
2087
2314
 
2088
2315
  if (args.mode === 'ai') {
2089
2316
  if (!args.aiCommand) {
2090
- throw new Error(formatError('missing ai subcommand. Use: npx create-quiver ai onboard | prepare-context | plan | review-plan | approve | approvals | agent | prompt-slice | execute-slice | execute-plan | doctor | pr'));
2317
+ throw new Error(formatError('missing ai subcommand. Use: npx create-quiver ai onboard | prepare-context | run | status | resume | inspect | export | specs | slices | trace | plan | revise | review-plan | approve | approvals | agent | prompt-slice | execute-slice | execute-plan | doctor | pr'));
2318
+ }
2319
+
2320
+ if (args.aiCommand === 'run') {
2321
+ runAiLifecycleRun(process.cwd(), {
2322
+ command: args.aiRunCommand,
2323
+ input: args.aiInput || undefined,
2324
+ runId: args.aiRunId || undefined,
2325
+ specSlug: args.specSlug || undefined,
2326
+ });
2327
+ return;
2328
+ }
2329
+
2330
+ if (args.aiCommand === 'status') {
2331
+ runAiLifecycleStatus(process.cwd(), {
2332
+ runId: args.aiRunId || undefined,
2333
+ });
2334
+ return;
2335
+ }
2336
+
2337
+ if (args.aiCommand === 'resume') {
2338
+ runAiLifecycleResume(process.cwd(), {
2339
+ runId: args.aiRunId || undefined,
2340
+ });
2341
+ return;
2342
+ }
2343
+
2344
+ if (args.aiCommand === 'inspect') {
2345
+ runAiInspect(process.cwd(), {
2346
+ includeCompleted: args.includeCompleted,
2347
+ });
2348
+ return;
2349
+ }
2350
+
2351
+ if (args.aiCommand === 'export') {
2352
+ runAiExport(process.cwd(), {
2353
+ format: args.formatExplicit ? args.format : 'json',
2354
+ includeCompleted: args.includeCompleted,
2355
+ });
2356
+ return;
2357
+ }
2358
+
2359
+ if (args.aiCommand === 'specs') {
2360
+ runAiSpecsList(process.cwd(), {
2361
+ includeCompleted: args.includeCompleted,
2362
+ json: args.json,
2363
+ });
2364
+ return;
2365
+ }
2366
+
2367
+ if (args.aiCommand === 'slices') {
2368
+ runAiSlicesList(process.cwd(), {
2369
+ includeCompleted: args.includeCompleted,
2370
+ json: args.json,
2371
+ });
2372
+ return;
2373
+ }
2374
+
2375
+ if (args.aiCommand === 'trace') {
2376
+ runAiTraceReport(process.cwd(), {
2377
+ includeCompleted: args.includeCompleted,
2378
+ });
2379
+ return;
2091
2380
  }
2092
2381
 
2093
2382
  if (args.aiCommand === 'agent') {
@@ -2107,6 +2396,7 @@ async function run(argv) {
2107
2396
  context: args.aiContext || undefined,
2108
2397
  dryRun: args.dryRun,
2109
2398
  input: args.aiInput || undefined,
2399
+ printPrompt: args.aiPrintPrompt,
2110
2400
  provider: args.aiProvider,
2111
2401
  providerExplicit: args.aiProviderExplicit,
2112
2402
  role: args.aiRole,
@@ -2118,6 +2408,7 @@ async function run(argv) {
2118
2408
  if (args.aiCommand === 'prepare-context') {
2119
2409
  await runAiPrepareContext(process.cwd(), {
2120
2410
  dryRun: args.dryRun,
2411
+ runId: args.aiRunId || undefined,
2121
2412
  });
2122
2413
  return;
2123
2414
  }
@@ -2128,9 +2419,11 @@ async function run(argv) {
2128
2419
  dryRun: args.dryRun,
2129
2420
  input: args.aiInput || undefined,
2130
2421
  phase: args.aiPhase,
2422
+ printPrompt: args.aiPrintPrompt,
2131
2423
  provider: args.aiProvider,
2132
2424
  providerExplicit: args.aiProviderExplicit,
2133
2425
  role: args.aiRole,
2426
+ runId: args.aiRunId || undefined,
2134
2427
  specSlug: args.specSlug || undefined,
2135
2428
  timeout: args.aiTimeout,
2136
2429
  });
@@ -2142,8 +2435,25 @@ async function run(argv) {
2142
2435
  context: args.aiContext || undefined,
2143
2436
  dryRun: args.dryRun,
2144
2437
  input: args.aiInput || undefined,
2438
+ printPrompt: args.aiPrintPrompt,
2439
+ provider: args.aiProvider,
2440
+ providerExplicit: args.aiProviderExplicit,
2441
+ timeout: args.aiTimeout,
2442
+ });
2443
+ return;
2444
+ }
2445
+
2446
+ if (args.aiCommand === 'revise') {
2447
+ await runAiRevise(process.cwd(), {
2448
+ context: args.aiContext || undefined,
2449
+ dryRun: args.dryRun,
2450
+ input: args.aiInput || undefined,
2451
+ phase: args.aiPhase,
2452
+ printPrompt: args.aiPrintPrompt,
2145
2453
  provider: args.aiProvider,
2146
2454
  providerExplicit: args.aiProviderExplicit,
2455
+ role: args.aiRole,
2456
+ runId: args.aiRunId || undefined,
2147
2457
  timeout: args.aiTimeout,
2148
2458
  });
2149
2459
  return;
@@ -2154,6 +2464,7 @@ async function run(argv) {
2154
2464
  dryRun: args.dryRun,
2155
2465
  input: args.aiInput || undefined,
2156
2466
  phase: args.aiPhase,
2467
+ runId: args.aiRunId || undefined,
2157
2468
  version: args.aiVersion || undefined,
2158
2469
  });
2159
2470
  return;
@@ -2228,7 +2539,7 @@ async function run(argv) {
2228
2539
  return;
2229
2540
  }
2230
2541
 
2231
- throw new Error(formatError(`unsupported ai subcommand: ${args.aiCommand}. Supported tasks: onboard, plan, review-plan, approve, approvals, agent, prompt-slice, execute-slice, execute-plan, doctor, pr`));
2542
+ throw new Error(formatError(`unsupported ai subcommand: ${args.aiCommand}. Supported tasks: onboard, prepare-context, run, status, resume, inspect, export, specs, slices, trace, plan, revise, review-plan, approve, approvals, agent, prompt-slice, execute-slice, execute-plan, doctor, pr`));
2232
2543
  }
2233
2544
 
2234
2545
  if (args.mode === 'graph') {
@@ -2278,7 +2589,10 @@ async function run(argv) {
2278
2589
  }
2279
2590
 
2280
2591
  if (args.mode === 'migrate') {
2281
- runMigrate(args.targetDir, { skipInstall: args.skipInstall });
2592
+ runMigrate(args.targetDir, {
2593
+ dryRun: args.dryRun,
2594
+ skipInstall: args.skipInstall,
2595
+ });
2282
2596
  return;
2283
2597
  }
2284
2598
 
@@ -2315,10 +2629,10 @@ async function run(argv) {
2315
2629
  const repoRoot = process.cwd();
2316
2630
  const handoffInput = args.targetDir;
2317
2631
  if (!handoffInput || handoffInput === '.') {
2318
- throw new Error(formatError('missing handoff path. Use: npx create-quiver check-handoff specs/<spec-slug>/HANDOFF.md'));
2632
+ throw new Error(formatError('missing handoff or brief path. Use: npx create-quiver check-handoff specs/<spec-slug>/HANDOFF.md or specs/<spec-slug>/slices/<slice-id>/EXECUTION_BRIEF.md'));
2319
2633
  }
2320
2634
  const resolved = checkHandoff(handoffInput, repoRoot);
2321
- console.log(`PASS: Handoff validated at ${resolved.relativePath}`);
2635
+ console.log(`PASS: ${resolved.label} validated at ${resolved.relativePath}`);
2322
2636
  return;
2323
2637
  }
2324
2638
 
@@ -2366,7 +2680,9 @@ async function run(argv) {
2366
2680
  }
2367
2681
 
2368
2682
  if (args.specCommand === 'start') {
2369
- const report = startSpecWorktree(process.cwd(), args.targetDir);
2683
+ const report = startSpecWorktree(process.cwd(), args.targetDir, {
2684
+ dryRun: args.dryRun,
2685
+ });
2370
2686
  process.stdout.write(formatSpecStartResult(report));
2371
2687
  return;
2372
2688
  }