create-quiver 0.12.1 → 0.14.0

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 (110) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +24 -9
  3. package/README_FOR_AI.md +15 -6
  4. package/ROADMAP.md +15 -2
  5. package/docs/COMMANDS.md.template +12 -3
  6. package/docs/TROUBLESHOOTING.md.template +29 -0
  7. package/docs/WORKFLOW.md.template +13 -12
  8. package/package.json +2 -1
  9. package/specs/quiver-v26-0121-smoke-hardening/SPEC.md +2 -2
  10. package/specs/quiver-v26-0121-smoke-hardening/STATUS.md +5 -5
  11. package/specs/quiver-v27-reliability-ai-workflow-hardening/AUDIT_V24_V25_V26.md +67 -0
  12. package/specs/quiver-v27-reliability-ai-workflow-hardening/COMMAND_CONTRACTS.md +125 -0
  13. package/specs/quiver-v27-reliability-ai-workflow-hardening/COVERAGE_MATRIX.md +74 -0
  14. package/specs/quiver-v27-reliability-ai-workflow-hardening/EVIDENCE_REPORT.md +179 -0
  15. package/specs/quiver-v27-reliability-ai-workflow-hardening/EXECUTION_PLAN.md +71 -0
  16. package/specs/quiver-v27-reliability-ai-workflow-hardening/SPEC.md +176 -0
  17. package/specs/quiver-v27-reliability-ai-workflow-hardening/STATUS.md +37 -0
  18. package/specs/quiver-v27-reliability-ai-workflow-hardening/pr.md +132 -0
  19. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-00-docs-audit-coverage-and-contracts/CLOSURE_BRIEF.md +36 -0
  20. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-00-docs-audit-coverage-and-contracts/EXECUTION_BRIEF.md +56 -0
  21. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-00-docs-audit-coverage-and-contracts/slice.json +75 -0
  22. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-01-core-state-resolver-and-canonical-statuses/CLOSURE_BRIEF.md +37 -0
  23. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-01-core-state-resolver-and-canonical-statuses/EXECUTION_BRIEF.md +54 -0
  24. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-01-core-state-resolver-and-canonical-statuses/slice.json +79 -0
  25. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-02-json-export-contract-and-machine-output/CLOSURE_BRIEF.md +34 -0
  26. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-02-json-export-contract-and-machine-output/EXECUTION_BRIEF.md +54 -0
  27. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-02-json-export-contract-and-machine-output/slice.json +75 -0
  28. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-03-approved-plan-to-spec-create/CLOSURE_BRIEF.md +36 -0
  29. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-03-approved-plan-to-spec-create/EXECUTION_BRIEF.md +55 -0
  30. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-03-approved-plan-to-spec-create/slice.json +78 -0
  31. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-04-ai-artifact-storage-redaction-and-token-compaction/CLOSURE_BRIEF.md +31 -0
  32. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-04-ai-artifact-storage-redaction-and-token-compaction/EXECUTION_BRIEF.md +55 -0
  33. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-04-ai-artifact-storage-redaction-and-token-compaction/slice.json +77 -0
  34. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-05-worktree-lifecycle-locks-and-recovery/CLOSURE_BRIEF.md +31 -0
  35. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-05-worktree-lifecycle-locks-and-recovery/EXECUTION_BRIEF.md +55 -0
  36. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-05-worktree-lifecycle-locks-and-recovery/slice.json +84 -0
  37. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-06-validation-gates-and-scope-safety/CLOSURE_BRIEF.md +32 -0
  38. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-06-validation-gates-and-scope-safety/EXECUTION_BRIEF.md +57 -0
  39. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-06-validation-gates-and-scope-safety/slice.json +99 -0
  40. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-07-context-analysis-and-doctor-flow/CLOSURE_BRIEF.md +31 -0
  41. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-07-context-analysis-and-doctor-flow/EXECUTION_BRIEF.md +57 -0
  42. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-07-context-analysis-and-doctor-flow/slice.json +88 -0
  43. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-08-cross-platform-help-auth-and-dx/CLOSURE_BRIEF.md +31 -0
  44. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-08-cross-platform-help-auth-and-dx/EXECUTION_BRIEF.md +56 -0
  45. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-08-cross-platform-help-auth-and-dx/slice.json +85 -0
  46. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-09-fixtures-smoke-docs-and-release-readiness/CLOSURE_BRIEF.md +32 -0
  47. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-09-fixtures-smoke-docs-and-release-readiness/EXECUTION_BRIEF.md +56 -0
  48. package/specs/quiver-v27-reliability-ai-workflow-hardening/slices/slice-09-fixtures-smoke-docs-and-release-readiness/slice.json +91 -0
  49. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/COVERAGE_MATRIX.md +117 -0
  50. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/EVIDENCE_REPORT.md +200 -0
  51. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/EXECUTION_PLAN.md +60 -0
  52. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/SPEC.md +132 -0
  53. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/STATUS.md +36 -0
  54. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/pr.md +128 -0
  55. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-00-reconciliation-and-evidence-freeze/CLOSURE_BRIEF.md +44 -0
  56. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-00-reconciliation-and-evidence-freeze/EXECUTION_BRIEF.md +56 -0
  57. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-00-reconciliation-and-evidence-freeze/slice.json +71 -0
  58. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-01-ai-run-state-approvals-and-clean-output/CLOSURE_BRIEF.md +38 -0
  59. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-01-ai-run-state-approvals-and-clean-output/EXECUTION_BRIEF.md +53 -0
  60. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-01-ai-run-state-approvals-and-clean-output/slice.json +83 -0
  61. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-02-structured-technical-plan-contract-and-repair-flow/CLOSURE_BRIEF.md +33 -0
  62. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-02-structured-technical-plan-contract-and-repair-flow/EXECUTION_BRIEF.md +53 -0
  63. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-02-structured-technical-plan-contract-and-repair-flow/slice.json +85 -0
  64. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-03-active-slice-reconciliation-and-ai-inspect/CLOSURE_BRIEF.md +34 -0
  65. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-03-active-slice-reconciliation-and-ai-inspect/EXECUTION_BRIEF.md +52 -0
  66. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-03-active-slice-reconciliation-and-ai-inspect/slice.json +82 -0
  67. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-04-spec-validation-scope-and-worktree-reliability/CLOSURE_BRIEF.md +32 -0
  68. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-04-spec-validation-scope-and-worktree-reliability/EXECUTION_BRIEF.md +55 -0
  69. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-04-spec-validation-scope-and-worktree-reliability/slice.json +85 -0
  70. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-05-review-plan-closure-and-agent-dx/CLOSURE_BRIEF.md +35 -0
  71. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-05-review-plan-closure-and-agent-dx/EXECUTION_BRIEF.md +59 -0
  72. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-05-review-plan-closure-and-agent-dx/slice.json +94 -0
  73. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-06-backward-compatibility-docs-and-release-readiness/CLOSURE_BRIEF.md +40 -0
  74. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-06-backward-compatibility-docs-and-release-readiness/EXECUTION_BRIEF.md +56 -0
  75. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-06-backward-compatibility-docs-and-release-readiness/slice.json +98 -0
  76. package/src/create-quiver/commands/ai.js +563 -21
  77. package/src/create-quiver/commands/flow.js +52 -4
  78. package/src/create-quiver/commands/graph.js +7 -7
  79. package/src/create-quiver/commands/plan.js +6 -15
  80. package/src/create-quiver/commands/spec.js +292 -0
  81. package/src/create-quiver/index.js +125 -25
  82. package/src/create-quiver/lib/agent-profiles.js +15 -3
  83. package/src/create-quiver/lib/ai/artifacts.js +318 -0
  84. package/src/create-quiver/lib/ai/context-packs.js +2 -2
  85. package/src/create-quiver/lib/ai/execution-plan.js +9 -0
  86. package/src/create-quiver/lib/ai/executor.js +3 -2
  87. package/src/create-quiver/lib/ai/export-state.js +287 -95
  88. package/src/create-quiver/lib/ai/github.js +93 -4
  89. package/src/create-quiver/lib/ai/plan-review.js +161 -0
  90. package/src/create-quiver/lib/ai/run-state.js +17 -2
  91. package/src/create-quiver/lib/ai/spec-generator.js +87 -13
  92. package/src/create-quiver/lib/ai/spec-templates.js +72 -12
  93. package/src/create-quiver/lib/analyze.js +2 -2
  94. package/src/create-quiver/lib/approvals.js +14 -2
  95. package/src/create-quiver/lib/doctor.js +79 -0
  96. package/src/create-quiver/lib/git.js +40 -1
  97. package/src/create-quiver/lib/handoff.js +43 -1
  98. package/src/create-quiver/lib/init-docs.js +11 -7
  99. package/src/create-quiver/lib/init-layout.js +1 -0
  100. package/src/create-quiver/lib/lifecycle.js +52 -3
  101. package/src/create-quiver/lib/locks.js +134 -0
  102. package/src/create-quiver/lib/package-safety.js +7 -0
  103. package/src/create-quiver/lib/paths.js +74 -0
  104. package/src/create-quiver/lib/project-scan.js +74 -0
  105. package/src/create-quiver/lib/project-state-resolver.js +430 -0
  106. package/src/create-quiver/lib/readiness.js +48 -7
  107. package/src/create-quiver/lib/scope.js +2 -1
  108. package/src/create-quiver/lib/slice.js +8 -4
  109. package/src/create-quiver/lib/spec-worktrees.js +169 -38
  110. package/src/create-quiver/lib/statuses.js +115 -0
@@ -10,6 +10,7 @@ const {
10
10
  formatDoctorFixPlan,
11
11
  } = require('./lib/doctor');
12
12
  const {
13
+ runActiveSlice: runAiActiveSlice,
13
14
  runAgent: runAiAgent,
14
15
  runApprovalStatus: runAiApprovalStatus,
15
16
  runApprove: runAiApprove,
@@ -25,6 +26,7 @@ const {
25
26
  runPlan: runAiPlan,
26
27
  runPrepareContext: runAiPrepareContext,
27
28
  runPr: runAiPr,
29
+ runRepairPlan: runAiRepairPlan,
28
30
  runPromptSlice: runAiPromptSlice,
29
31
  runReviewPlan: runAiReviewPlan,
30
32
  runRevise: runAiRevise,
@@ -39,9 +41,14 @@ const { runFlow } = require('./commands/flow');
39
41
  const { runGraph } = require('./commands/graph');
40
42
  const { runNext } = require('./commands/next');
41
43
  const { runPlan } = require('./commands/plan');
42
- const { runCreateSpec } = require('./commands/spec');
44
+ const { runCreateSpec, runValidateSpec } = require('./commands/spec');
43
45
  const { buildInitLayout, formatInitLayoutPlan } = require('./lib/init-layout');
44
- const { initializeProjectDocs, installSelfAsDevDep, refreshAiContextDoc } = require('./lib/init-docs');
46
+ const {
47
+ formatInstallSelfCommand,
48
+ initializeProjectDocs,
49
+ installSelfAsDevDep,
50
+ refreshAiContextDoc,
51
+ } = require('./lib/init-docs');
45
52
  const { checkPrReadiness, checkScope, checkSliceReadiness } = require('./lib/readiness');
46
53
  const { cleanupSlice, refreshActiveSlicesBoard, startSlice } = require('./lib/lifecycle');
47
54
  const { buildSpecStatus, closeSpecWorktree, formatSpecCloseResult, formatSpecStartResult, formatSpecStatus, startSpecWorktree } = require('./lib/spec-worktrees');
@@ -94,6 +101,7 @@ const SUPPORTED_COMMAND_MODES = new Set([
94
101
  ]);
95
102
 
96
103
  const SUPPORTED_AI_COMMANDS = new Set([
104
+ 'active-slice',
97
105
  'agent',
98
106
  'approve',
99
107
  'approval-status',
@@ -109,6 +117,7 @@ const SUPPORTED_AI_COMMANDS = new Set([
109
117
  'prepare-context',
110
118
  'pr',
111
119
  'prompt-slice',
120
+ 'repair-plan',
112
121
  'review-plan',
113
122
  'revise',
114
123
  'resume',
@@ -119,7 +128,7 @@ const SUPPORTED_AI_COMMANDS = new Set([
119
128
  'trace',
120
129
  ]);
121
130
 
122
- const SUPPORTED_SPEC_COMMANDS = new Set(['close', 'create', 'start', 'status']);
131
+ const SUPPORTED_SPEC_COMMANDS = new Set(['close', 'create', 'start', 'status', 'validate']);
123
132
  const SUPPORTED_DEMO_COMMANDS = new Set(['create']);
124
133
 
125
134
  function unsupportedCommandMessage(commandName) {
@@ -154,14 +163,16 @@ const COMMAND_HELP_GROUPS = [
154
163
  {
155
164
  title: 'AI lifecycle',
156
165
  commands: [
157
- ['ai run create', 'Create a durable AI lifecycle run from a requirements file.'],
166
+ ['ai run create|close', 'Create a durable AI lifecycle run or close/archive a completed or stale run without deleting evidence.'],
167
+ ['ai active-slice status|reconcile', 'Inspect or dry-run reconcile local active-slice state from every supported source.'],
158
168
  ['ai status', 'Show current AI lifecycle phase, approved versions, blockers, and next command.'],
159
169
  ['ai resume', 'Resume guidance from the last valid lifecycle phase without chat memory.'],
160
170
  ['ai onboard', 'Run or print the planner onboarding prompt with a token-aware context pack.'],
161
171
  ['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.'],
172
+ ['ai agent set|list|show', 'Manage planner, executor, reviewer, and doctor provider profiles without secrets; use set --dry-run to preview.'],
163
173
  ['ai plan', 'Generate versioned planner drafts for acceptance criteria, technical plan, or spec phase.'],
164
174
  ['ai revise', 'Create a new planner draft from human feedback without approving it.'],
175
+ ['ai repair-plan', 'Repair an approved technical plan into a new structured draft without mutating the approved artifact.'],
165
176
  ['ai review-plan', 'Review the technical-plan draft for production readiness before approval.'],
166
177
  ['ai approve', 'Approve a concrete saved draft version for the next planner phase.'],
167
178
  ['ai approvals', 'Inspect approval status and saved planner drafts.'],
@@ -188,6 +199,7 @@ const COMMAND_HELP_GROUPS = [
188
199
  ['spec create', 'Create the real spec tree from a reviewed approved technical plan.'],
189
200
  ['spec start', 'Create or reuse the dedicated worktree and branch for one spec.'],
190
201
  ['spec status', 'Show spec worktree, branch, slice-00 state, and pending slices.'],
202
+ ['spec validate', 'Validate spec docs, slices, briefs, evidence, status, dependencies, and safe paths.'],
191
203
  ['spec close', 'Close a merged clean spec worktree and guide local sync.'],
192
204
  ['start-slice', 'Start work on one slice and mark it active.'],
193
205
  ['check-slice', 'Validate slice structure, dependencies, scope, and readiness.'],
@@ -237,6 +249,8 @@ function printUsage() {
237
249
  npx create-quiver plan [options]
238
250
  npx create-quiver ai <task> [options]
239
251
  npx create-quiver ai run create --input <requirements.md>
252
+ npx create-quiver ai run close --run <id>
253
+ npx create-quiver ai active-slice reconcile --dry-run
240
254
  npx create-quiver ai status [options]
241
255
  npx create-quiver ai resume [options]
242
256
  npx create-quiver ai inspect [options]
@@ -247,6 +261,7 @@ function printUsage() {
247
261
  npx create-quiver ai agent <set|list|show> [role] [options]
248
262
  npx create-quiver ai prepare-context [options]
249
263
  npx create-quiver ai revise [options]
264
+ npx create-quiver ai repair-plan [options]
250
265
  npx create-quiver graph [options]
251
266
  npx create-quiver next [options]
252
267
  npx create-quiver migrate [options]
@@ -263,6 +278,7 @@ function printUsage() {
263
278
  npx create-quiver spec create [options]
264
279
  npx create-quiver spec start <spec-dir>
265
280
  npx create-quiver spec status <spec-dir>
281
+ npx create-quiver spec validate <spec-dir>
266
282
  npx create-quiver spec close <spec-dir>
267
283
  npx create-quiver evidence run [options] -- <command>
268
284
  npx create-quiver demo create spec-viewer [options]
@@ -282,12 +298,13 @@ Options:
282
298
  --all-ready List every ready slice returned by next
283
299
  --auto-start Prompt for confirmation and run start-slice on next
284
300
  --local For check-slice, run structural validation without remote/base checks
301
+ --strict Treat supported validation warnings as failures
285
302
  --unicode Prefer Unicode output when supported
286
303
  --minimal Plan or run the minimal init profile
287
304
  --full Plan or run the full compatibility init profile
288
305
  --legacy-scripts Include legacy Bash wrappers in init profile
289
306
  --include-templates Export packaged templates in init profile
290
- --dry-run Preview init, migrate, prepare, spec create/start/close, demo, or AI work without executing writes/providers
307
+ --dry-run Preview init, analyze, migrate, prepare, spec create/start/close, demo, ai agent set, or AI work without executing writes/providers
291
308
  --print-prompt Print the exact AI prompt and exit without executing provider CLIs
292
309
  --fix For doctor, apply safe non-destructive repairs
293
310
  --execute For ai execute-plan, run the planned slices instead of printing commands
@@ -302,7 +319,7 @@ Options:
302
319
  --ssh-host-alias <name> SSH host alias to validate for prepare or AI commands
303
320
  --identity-file <path> SSH identity file to validate for prepare or AI commands
304
321
  --remote <name> Git remote name for check-slice or AI PR checks
305
- --base <branch> Base branch for check-slice, ai pr, or spec close (default: main)
322
+ --base <branch> Base branch for check-slice, check-scope, ai pr, or spec close (default: main)
306
323
  --output <file> Output file for evidence run
307
324
  --max-output <n> Maximum stdout/stderr chars per evidence section
308
325
  --title <text> Override PR title for ai pr create
@@ -322,6 +339,7 @@ Examples:
322
339
  cd ./my-project && npx create-quiver ai onboard --print-prompt
323
340
  cd ./my-project && npx create-quiver ai prepare-context --dry-run
324
341
  cd ./my-project && npx create-quiver ai run create --input requirements.md
342
+ cd ./my-project && npx create-quiver ai active-slice reconcile --dry-run
325
343
  cd ./my-project && npx create-quiver ai status
326
344
  cd ./my-project && npx create-quiver ai resume
327
345
  cd ./my-project && npx create-quiver ai inspect
@@ -330,18 +348,21 @@ Examples:
330
348
  cd ./my-project && npx create-quiver ai specs list
331
349
  cd ./my-project && npx create-quiver ai slices list --json
332
350
  cd ./my-project && npx create-quiver ai trace report
351
+ cd ./my-project && npx create-quiver ai agent set planner --provider codex --model gpt-5.5 --dry-run
333
352
  cd ./my-project && npx create-quiver ai agent set planner --provider codex --model gpt-5.5
334
353
  cd ./my-project && npx create-quiver ai agent list
335
354
  cd ./my-project && npx create-quiver ai plan --phase acceptance --input requirements.md --dry-run
336
355
  cd ./my-project && npx create-quiver ai revise --phase acceptance --input feedback.md --dry-run
337
356
  cd ./my-project && npx create-quiver ai approve --phase acceptance --version 1
338
357
  cd ./my-project && npx create-quiver ai plan --phase technical-plan --dry-run
358
+ cd ./my-project && npx create-quiver ai repair-plan --dry-run
339
359
  cd ./my-project && npx create-quiver ai review-plan --dry-run
340
360
  cd ./my-project && npx create-quiver ai approve --phase technical-plan --version 1
341
361
  cd ./my-project && npx create-quiver spec create --dry-run
342
362
  cd ./my-project && npx create-quiver spec start specs/my-project --dry-run
343
363
  cd ./my-project && npx create-quiver ai approvals
344
364
  cd ./my-project && npx create-quiver ai prompt-slice --slice specs/my-project/slices/slice-01/slice.json --dry-run
365
+ cd ./my-project && npx --yes create-quiver@${CLI_VERSION} ai prompt-slice --slice specs/my-project/slices/slice-01/slice.json --dry-run
345
366
  cd ./my-project && npx create-quiver ai execute-slice --slice specs/my-project/slices/slice-01/slice.json --dry-run
346
367
  cd ./my-project && npx create-quiver ai execute-slice --slice specs/my-project/slices/slice-01/slice.json --commit
347
368
  cd ./my-project && npx create-quiver ai execute-plan --dry-run --commit
@@ -368,6 +389,7 @@ Examples:
368
389
  cd ./my-project && npx create-quiver refresh-active-slices
369
390
  cd ./my-project && npx create-quiver spec start specs/my-project
370
391
  cd ./my-project && npx create-quiver spec status specs/my-project
392
+ cd ./my-project && npx create-quiver spec validate specs/my-project
371
393
  cd ./my-project && npx create-quiver spec close specs/my-project --dry-run
372
394
  cd ./my-project && npx create-quiver evidence run -- npm test
373
395
  cd ./my-project && npx create-quiver demo create spec-viewer --dry-run
@@ -926,7 +948,7 @@ function parseArgs(argv) {
926
948
  if (result.aiCommand === 'run' && !result.aiRunCommand && positional.length > 0) {
927
949
  result.aiRunCommand = positional.shift();
928
950
  }
929
- if ((result.aiCommand === 'specs' || result.aiCommand === 'slices' || result.aiCommand === 'trace') && !result.aiSecondaryCommand && positional.length > 0) {
951
+ if ((result.aiCommand === 'specs' || result.aiCommand === 'slices' || result.aiCommand === 'trace' || result.aiCommand === 'active-slice') && !result.aiSecondaryCommand && positional.length > 0) {
930
952
  result.aiSecondaryCommand = positional.shift();
931
953
  }
932
954
  if ((result.aiCommand === 'specs' || result.aiCommand === 'slices') && result.aiSecondaryCommand && result.aiSecondaryCommand !== 'list') {
@@ -935,6 +957,9 @@ function parseArgs(argv) {
935
957
  if (result.aiCommand === 'trace' && result.aiSecondaryCommand && result.aiSecondaryCommand !== 'report') {
936
958
  throw new Error(formatError(`unsupported ai trace subcommand: ${result.aiSecondaryCommand}. Supported tasks: report`));
937
959
  }
960
+ if (result.aiCommand === 'active-slice' && result.aiSecondaryCommand && result.aiSecondaryCommand !== 'status' && result.aiSecondaryCommand !== 'reconcile') {
961
+ throw new Error(formatError(`unsupported ai active-slice subcommand: ${result.aiSecondaryCommand}. Supported tasks: status, reconcile`));
962
+ }
938
963
  if (positional.length > 0) {
939
964
  throw new Error(formatError('ai does not accept extra positional arguments'));
940
965
  }
@@ -951,7 +976,7 @@ function parseArgs(argv) {
951
976
  result.specCommand = positional.shift();
952
977
  }
953
978
  if (!result.specCommand) {
954
- throw new Error(formatError('missing spec subcommand. Use: npx create-quiver spec <create|start|status|close>'));
979
+ throw new Error(formatError('missing spec subcommand. Use: npx create-quiver spec <create|start|status|validate|close>'));
955
980
  }
956
981
  if (result.specCommand !== 'create' && positional.length > 0) {
957
982
  result.targetDir = positional.shift();
@@ -1574,8 +1599,8 @@ function detectFrameworks(projectRoot, files, rootEntries, packageJson) {
1574
1599
  },
1575
1600
  {
1576
1601
  name: 'vue',
1577
- matches: () => dependencies.has('vue') || rootFileSet.has('vue.config.js') || rootFileSet.has('vite.config.js') || rootFileSet.has('vite.config.ts'),
1578
- signals: ['vue', 'vue.config.*', 'vite.config.*'],
1602
+ matches: () => dependencies.has('vue') || rootFileSet.has('vue.config.js'),
1603
+ signals: ['vue', 'vue.config.*'],
1579
1604
  },
1580
1605
  {
1581
1606
  name: 'react',
@@ -1998,7 +2023,7 @@ function writeProjectScanArtifacts(projectRoot, scan) {
1998
2023
  return { jsonPath, mdPath: scanPaths.projectMapPath };
1999
2024
  }
2000
2025
 
2001
- function runAnalyze(targetDir) {
2026
+ function runAnalyze(targetDir, options = {}) {
2002
2027
  const projectRoot = resolveTargetRoot(process.cwd(), targetDir);
2003
2028
 
2004
2029
  if (!fs.existsSync(projectRoot)) {
@@ -2006,6 +2031,26 @@ function runAnalyze(targetDir) {
2006
2031
  }
2007
2032
 
2008
2033
  const scan = buildProjectScan(projectRoot);
2034
+
2035
+ if (options.dryRun) {
2036
+ console.log(`Project analysis dry-run for ${projectRoot}`);
2037
+ console.log('Writes: none');
2038
+ console.log(`Would write ${CURRENT_SCAN_RELATIVE_PATH}`);
2039
+ console.log(`Would write ${PROJECT_MAP_RELATIVE_PATH}`);
2040
+ console.log('Would refresh docs/AI_CONTEXT.md');
2041
+ console.log(`Detected primary stack: ${scan.stack.primary}`);
2042
+ console.log(`Detected frameworks: ${scan.stack.frameworks.length > 0 ? scan.stack.frameworks.join(', ') : 'none detected'}`);
2043
+ console.log(`Detected package manager: ${scan.project.package_manager}`);
2044
+ return {
2045
+ artifacts: {
2046
+ jsonPath: path.join(projectRoot, CURRENT_SCAN_RELATIVE_PATH),
2047
+ mdPath: path.join(projectRoot, PROJECT_MAP_RELATIVE_PATH),
2048
+ },
2049
+ dryRun: true,
2050
+ scan,
2051
+ };
2052
+ }
2053
+
2009
2054
  const artifacts = writeProjectScanArtifacts(projectRoot, scan);
2010
2055
  const aiContextPath = refreshAiContextDoc(projectRoot, scan);
2011
2056
  updateStateForAnalyze(projectRoot, CLI_VERSION);
@@ -2016,6 +2061,13 @@ function runAnalyze(targetDir) {
2016
2061
  console.log(`Wrote ${relativePosixPath(projectRoot, aiContextPath)}`);
2017
2062
  console.log(`Detected primary stack: ${scan.stack.primary}`);
2018
2063
  console.log(`Detected package manager: ${scan.project.package_manager}`);
2064
+
2065
+ return {
2066
+ artifacts,
2067
+ aiContextPath,
2068
+ dryRun: false,
2069
+ scan,
2070
+ };
2019
2071
  }
2020
2072
 
2021
2073
  function runMigrate(targetDir, options = {}) {
@@ -2079,7 +2131,7 @@ function runMigrate(targetDir, options = {}) {
2079
2131
  if (installResult === 'installed') {
2080
2132
  console.log(`Added create-quiver@${CLI_VERSION} as dev dependency`);
2081
2133
  } else if (installResult === 'failed') {
2082
- console.warn(`Warning: could not install create-quiver automatically. Run: npm install -D create-quiver@${CLI_VERSION}`);
2134
+ console.warn(`Warning: could not install create-quiver automatically. Run: ${formatInstallSelfCommand(projectRoot, CLI_VERSION)}`);
2083
2135
  }
2084
2136
  }
2085
2137
 
@@ -2117,6 +2169,11 @@ function runDoctor(targetDir, options = {}) {
2117
2169
 
2118
2170
  const doctorReport = collectDoctorReport(projectRoot);
2119
2171
  const specSlugs = doctorReport.specSlugs;
2172
+ const doctorExampleTarget = doctorReport.exampleTarget || {
2173
+ sliceId: '<slice-id>',
2174
+ source: 'generic',
2175
+ specSlug: '<spec-slug>',
2176
+ };
2120
2177
  const specRequiredFiles = specSlugs.flatMap((projectSlug) => [
2121
2178
  `specs/${projectSlug}/SPEC.md`,
2122
2179
  `specs/${projectSlug}/STATUS.md`,
@@ -2237,16 +2294,22 @@ function runDoctor(targetDir, options = {}) {
2237
2294
  if (!hasQuiverState) {
2238
2295
  console.log('- Run migration first: npx create-quiver migrate');
2239
2296
  } else if (!hasScanArtifacts) {
2240
- console.log('- Analyze the project first: npx create-quiver analyze');
2297
+ console.log('- Analyze the project first: npx create-quiver analyze');
2241
2298
  } else {
2242
2299
  console.log('- Ask your AI agent: Read AGENTS.md, then docs/AI_ONBOARDING_PROMPT.md and execute it.');
2243
2300
  }
2244
2301
  console.log('- Check the next ready slice: npx create-quiver next');
2245
2302
  if (specSlugs.length > 0) {
2246
- const projectSlug = specSlugs[0];
2247
- console.log(`- Start a slice: npx create-quiver start-slice specs/${projectSlug}/slices/<slice-id>/slice.json`);
2248
- console.log(`- Validate a slice: npx create-quiver check-slice specs/${projectSlug}/slices/<slice-id>/slice.json`);
2249
- console.log(`- Validate the PR gate: npx create-quiver check-pr specs/${projectSlug}/slices/<slice-id>/slice.json`);
2303
+ const projectSlug = doctorExampleTarget.specSlug;
2304
+ const sliceId = doctorExampleTarget.sliceId || '<slice-id>';
2305
+ if (doctorExampleTarget.source === 'active-slice') {
2306
+ console.log(`- Example target: ${projectSlug}/${sliceId} (${doctorExampleTarget.status})`);
2307
+ } else if (doctorExampleTarget.source === 'generic-multiple-specs') {
2308
+ console.log('- Example target: specs/<spec-slug>/slices/<slice-id>/slice.json (generic because no active slice is obvious)');
2309
+ }
2310
+ console.log(`- Start a slice: npx create-quiver start-slice specs/${projectSlug}/slices/${sliceId}/slice.json`);
2311
+ console.log(`- Validate a slice: npx create-quiver check-slice specs/${projectSlug}/slices/${sliceId}/slice.json`);
2312
+ console.log(`- Validate the PR gate: npx create-quiver check-pr specs/${projectSlug}/slices/${sliceId}/slice.json`);
2250
2313
  } else {
2251
2314
  console.log('- Create real specs and slices only after acceptance criteria are approved and the technical plan is reviewed and approved.');
2252
2315
  }
@@ -2280,7 +2343,9 @@ async function run(argv) {
2280
2343
  }
2281
2344
 
2282
2345
  if (args.mode === 'analyze') {
2283
- runAnalyze(args.targetDir);
2346
+ runAnalyze(args.targetDir, {
2347
+ dryRun: args.dryRun,
2348
+ });
2284
2349
  return;
2285
2350
  }
2286
2351
 
@@ -2314,7 +2379,7 @@ async function run(argv) {
2314
2379
 
2315
2380
  if (args.mode === 'ai') {
2316
2381
  if (!args.aiCommand) {
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'));
2382
+ throw new Error(formatError('missing ai subcommand. Use: npx create-quiver ai onboard | prepare-context | run | active-slice | status | resume | inspect | export | specs | slices | trace | plan | revise | repair-plan | review-plan | approve | approvals | agent | prompt-slice | execute-slice | execute-plan | doctor | pr'));
2318
2383
  }
2319
2384
 
2320
2385
  if (args.aiCommand === 'run') {
@@ -2327,6 +2392,14 @@ async function run(argv) {
2327
2392
  return;
2328
2393
  }
2329
2394
 
2395
+ if (args.aiCommand === 'active-slice') {
2396
+ runAiActiveSlice(process.cwd(), {
2397
+ command: args.aiSecondaryCommand || 'status',
2398
+ dryRun: args.dryRun,
2399
+ });
2400
+ return;
2401
+ }
2402
+
2330
2403
  if (args.aiCommand === 'status') {
2331
2404
  runAiLifecycleStatus(process.cwd(), {
2332
2405
  runId: args.aiRunId || undefined,
@@ -2387,6 +2460,7 @@ async function run(argv) {
2387
2460
  model: args.aiModel || undefined,
2388
2461
  provider: args.aiProviderExplicit ? args.aiProvider : undefined,
2389
2462
  role: args.aiAgentRole || undefined,
2463
+ dryRun: args.dryRun,
2390
2464
  });
2391
2465
  return;
2392
2466
  }
@@ -2443,6 +2517,21 @@ async function run(argv) {
2443
2517
  return;
2444
2518
  }
2445
2519
 
2520
+ if (args.aiCommand === 'repair-plan') {
2521
+ await runAiRepairPlan(process.cwd(), {
2522
+ context: args.aiContext || undefined,
2523
+ dryRun: args.dryRun,
2524
+ input: args.aiInput || undefined,
2525
+ printPrompt: args.aiPrintPrompt,
2526
+ provider: args.aiProvider,
2527
+ providerExplicit: args.aiProviderExplicit,
2528
+ role: args.aiRole,
2529
+ runId: args.aiRunId || undefined,
2530
+ timeout: args.aiTimeout,
2531
+ });
2532
+ return;
2533
+ }
2534
+
2446
2535
  if (args.aiCommand === 'revise') {
2447
2536
  await runAiRevise(process.cwd(), {
2448
2537
  context: args.aiContext || undefined,
@@ -2539,7 +2628,7 @@ async function run(argv) {
2539
2628
  return;
2540
2629
  }
2541
2630
 
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`));
2631
+ throw new Error(formatError(`unsupported ai subcommand: ${args.aiCommand}. Supported tasks: onboard, prepare-context, run, active-slice, status, resume, inspect, export, specs, slices, trace, plan, revise, repair-plan, review-plan, approve, approvals, agent, prompt-slice, execute-slice, execute-plan, doctor, pr`));
2543
2632
  }
2544
2633
 
2545
2634
  if (args.mode === 'graph') {
@@ -2655,7 +2744,11 @@ async function run(argv) {
2655
2744
  }
2656
2745
 
2657
2746
  if (args.mode === 'check-scope') {
2658
- checkScope(args.targetDir, { strict: args.strict });
2747
+ checkScope(args.targetDir, {
2748
+ baseBranch: args.baseBranchExplicit ? args.aiBaseBranch : '',
2749
+ remote: args.aiRemote,
2750
+ strict: args.strict,
2751
+ });
2659
2752
  return;
2660
2753
  }
2661
2754
 
@@ -2676,7 +2769,7 @@ async function run(argv) {
2676
2769
  }
2677
2770
 
2678
2771
  if (!args.targetDir || args.targetDir === '.') {
2679
- throw new Error(formatError('missing spec directory. Use: npx create-quiver spec <start|status|close> <spec-dir>'));
2772
+ throw new Error(formatError('missing spec directory. Use: npx create-quiver spec <start|status|validate|close> <spec-dir>'));
2680
2773
  }
2681
2774
 
2682
2775
  if (args.specCommand === 'start') {
@@ -2693,6 +2786,13 @@ async function run(argv) {
2693
2786
  return;
2694
2787
  }
2695
2788
 
2789
+ if (args.specCommand === 'validate') {
2790
+ runValidateSpec(process.cwd(), args.targetDir, {
2791
+ strict: args.strict,
2792
+ });
2793
+ return;
2794
+ }
2795
+
2696
2796
  if (args.specCommand === 'close') {
2697
2797
  const report = closeSpecWorktree(process.cwd(), args.targetDir, {
2698
2798
  baseBranch: args.aiBaseBranch,
@@ -2705,7 +2805,7 @@ async function run(argv) {
2705
2805
  return;
2706
2806
  }
2707
2807
 
2708
- throw new Error(formatError(`unsupported spec subcommand: ${args.specCommand}. Supported tasks: create, start, status, close`));
2808
+ throw new Error(formatError(`unsupported spec subcommand: ${args.specCommand}. Supported tasks: create, start, status, validate, close`));
2709
2809
  }
2710
2810
 
2711
2811
  const packageRoot = path.resolve(__dirname, '../..');
@@ -2748,7 +2848,7 @@ async function run(argv) {
2748
2848
  if (installResult === 'installed') {
2749
2849
  console.log(`Added create-quiver@${CLI_VERSION} as dev dependency`);
2750
2850
  } else if (installResult === 'failed') {
2751
- console.warn(`Warning: could not install create-quiver automatically. Run: npm install -D create-quiver@${CLI_VERSION}`);
2851
+ console.warn(`Warning: could not install create-quiver automatically. Run: ${formatInstallSelfCommand(targetDir, CLI_VERSION)}`);
2752
2852
  }
2753
2853
  }
2754
2854
 
@@ -95,6 +95,16 @@ function listAgentProfiles(projectRoot) {
95
95
  }
96
96
 
97
97
  function setAgentProfile(projectRoot, role, options = {}) {
98
+ const next = buildAgentProfileState(projectRoot, role, options);
99
+
100
+ const filePath = writeAgentProfiles(projectRoot, next.state);
101
+ return {
102
+ filePath,
103
+ profile: next.profile,
104
+ };
105
+ }
106
+
107
+ function buildAgentProfileState(projectRoot, role, options = {}) {
98
108
  const normalizedRole = normalizeAgentProfileRole(role);
99
109
  const provider = assertSupportedProvider(options.provider);
100
110
  const model = normalizeOptionalText(options.model, 'model');
@@ -102,7 +112,7 @@ function setAgentProfile(projectRoot, role, options = {}) {
102
112
  const context = normalizeOptionalText(options.context, 'context');
103
113
  const state = readAgentProfiles(projectRoot);
104
114
  const current = state.profiles[normalizedRole] || {};
105
- const now = new Date().toISOString();
115
+ const now = options.now instanceof Date ? options.now.toISOString() : new Date().toISOString();
106
116
  const profile = {
107
117
  role: normalizedRole,
108
118
  provider,
@@ -119,10 +129,11 @@ function setAgentProfile(projectRoot, role, options = {}) {
119
129
  };
120
130
  state.updated_at = now;
121
131
 
122
- const filePath = writeAgentProfiles(projectRoot, state);
123
132
  return {
124
- filePath,
133
+ action: current.provider ? 'update' : 'create',
134
+ filePath: agentProfilesPath(projectRoot),
125
135
  profile,
136
+ state,
126
137
  };
127
138
  }
128
139
 
@@ -139,6 +150,7 @@ module.exports = {
139
150
  PROFILE_STATE_VERSION,
140
151
  agentProfilesPath,
141
152
  formatProviderList,
153
+ buildAgentProfileState,
142
154
  getAgentProfile,
143
155
  listAgentProfiles,
144
156
  normalizeAgentProfileRole,