create-quiver 0.10.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 (242) hide show
  1. package/BACKLOG.md +16 -17
  2. package/CHANGELOG.md +78 -0
  3. package/README.md +208 -41
  4. package/README_FOR_AI.md +50 -24
  5. package/ROADMAP.md +34 -11
  6. package/docs/AI_CONTEXT.md.template +2 -0
  7. package/docs/AI_ONBOARDING_PROMPT.md.template +31 -18
  8. package/docs/COMMANDS.md.template +90 -16
  9. package/docs/CONTEXTO.md.template +2 -0
  10. package/docs/DECISIONS.md.template +1 -0
  11. package/docs/INDEX.md.template +20 -18
  12. package/docs/STATUS.md.template +6 -1
  13. package/docs/SUPPORT_MATRIX.md.template +2 -2
  14. package/docs/TROUBLESHOOTING.md.template +50 -0
  15. package/docs/WORKFLOW.md.template +27 -17
  16. package/package.json +27 -4
  17. package/package.template.json +13 -1
  18. package/scripts/init-docs.sh +11 -4
  19. package/scripts/package-quiver.sh +18 -2
  20. package/specs/quiver-v22-guided-ai-workflow/EVIDENCE_REPORT.md +58 -0
  21. package/specs/quiver-v22-guided-ai-workflow/EXECUTION_PLAN.md +88 -0
  22. package/specs/quiver-v22-guided-ai-workflow/SPEC.md +228 -0
  23. package/specs/quiver-v22-guided-ai-workflow/STATUS.md +42 -0
  24. package/specs/quiver-v22-guided-ai-workflow/pr.md +104 -0
  25. package/specs/quiver-v22-guided-ai-workflow/slices/slice-00-spec-foundation/CLOSURE_BRIEF.md +35 -0
  26. package/specs/quiver-v22-guided-ai-workflow/slices/slice-00-spec-foundation/EXECUTION_BRIEF.md +61 -0
  27. package/specs/quiver-v22-guided-ai-workflow/slices/slice-00-spec-foundation/slice.json +51 -0
  28. package/specs/quiver-v22-guided-ai-workflow/slices/slice-01-docs-source-of-truth-sync/CLOSURE_BRIEF.md +31 -0
  29. package/specs/quiver-v22-guided-ai-workflow/slices/slice-01-docs-source-of-truth-sync/EXECUTION_BRIEF.md +58 -0
  30. package/specs/quiver-v22-guided-ai-workflow/slices/slice-01-docs-source-of-truth-sync/slice.json +55 -0
  31. package/specs/quiver-v22-guided-ai-workflow/slices/slice-02-prepare-command-diagnostics/CLOSURE_BRIEF.md +30 -0
  32. package/specs/quiver-v22-guided-ai-workflow/slices/slice-02-prepare-command-diagnostics/EXECUTION_BRIEF.md +57 -0
  33. package/specs/quiver-v22-guided-ai-workflow/slices/slice-02-prepare-command-diagnostics/slice.json +57 -0
  34. package/specs/quiver-v22-guided-ai-workflow/slices/slice-03-context-doc-refresh/CLOSURE_BRIEF.md +32 -0
  35. package/specs/quiver-v22-guided-ai-workflow/slices/slice-03-context-doc-refresh/EXECUTION_BRIEF.md +56 -0
  36. package/specs/quiver-v22-guided-ai-workflow/slices/slice-03-context-doc-refresh/slice.json +56 -0
  37. package/specs/quiver-v22-guided-ai-workflow/slices/slice-04-planner-approval-state/CLOSURE_BRIEF.md +33 -0
  38. package/specs/quiver-v22-guided-ai-workflow/slices/slice-04-planner-approval-state/EXECUTION_BRIEF.md +56 -0
  39. package/specs/quiver-v22-guided-ai-workflow/slices/slice-04-planner-approval-state/slice.json +58 -0
  40. package/specs/quiver-v22-guided-ai-workflow/slices/slice-05-spec-worktree-lifecycle/CLOSURE_BRIEF.md +32 -0
  41. package/specs/quiver-v22-guided-ai-workflow/slices/slice-05-spec-worktree-lifecycle/EXECUTION_BRIEF.md +56 -0
  42. package/specs/quiver-v22-guided-ai-workflow/slices/slice-05-spec-worktree-lifecycle/slice.json +54 -0
  43. package/specs/quiver-v22-guided-ai-workflow/slices/slice-06-executor-commit-recovery/CLOSURE_BRIEF.md +32 -0
  44. package/specs/quiver-v22-guided-ai-workflow/slices/slice-06-executor-commit-recovery/EXECUTION_BRIEF.md +58 -0
  45. package/specs/quiver-v22-guided-ai-workflow/slices/slice-06-executor-commit-recovery/slice.json +57 -0
  46. package/specs/quiver-v22-guided-ai-workflow/slices/slice-07-execution-waves-delegation/CLOSURE_BRIEF.md +32 -0
  47. package/specs/quiver-v22-guided-ai-workflow/slices/slice-07-execution-waves-delegation/EXECUTION_BRIEF.md +58 -0
  48. package/specs/quiver-v22-guided-ai-workflow/slices/slice-07-execution-waves-delegation/slice.json +55 -0
  49. package/specs/quiver-v22-guided-ai-workflow/slices/slice-08-pr-create-gh-ssh/CLOSURE_BRIEF.md +32 -0
  50. package/specs/quiver-v22-guided-ai-workflow/slices/slice-08-pr-create-gh-ssh/EXECUTION_BRIEF.md +58 -0
  51. package/specs/quiver-v22-guided-ai-workflow/slices/slice-08-pr-create-gh-ssh/slice.json +53 -0
  52. package/specs/quiver-v22-guided-ai-workflow/slices/slice-09-post-merge-cleanup-release-safety/CLOSURE_BRIEF.md +33 -0
  53. package/specs/quiver-v22-guided-ai-workflow/slices/slice-09-post-merge-cleanup-release-safety/EXECUTION_BRIEF.md +59 -0
  54. package/specs/quiver-v22-guided-ai-workflow/slices/slice-09-post-merge-cleanup-release-safety/slice.json +59 -0
  55. package/specs/quiver-v22-guided-ai-workflow/slices/slice-10-docs-smokes-release-readiness/CLOSURE_BRIEF.md +34 -0
  56. package/specs/quiver-v22-guided-ai-workflow/slices/slice-10-docs-smokes-release-readiness/EXECUTION_BRIEF.md +58 -0
  57. package/specs/quiver-v22-guided-ai-workflow/slices/slice-10-docs-smokes-release-readiness/slice.json +60 -0
  58. package/specs/quiver-v23-guided-flow-productization/EVIDENCE_REPORT.md +80 -0
  59. package/specs/quiver-v23-guided-flow-productization/EXECUTION_PLAN.md +80 -0
  60. package/specs/quiver-v23-guided-flow-productization/SPEC.md +203 -0
  61. package/specs/quiver-v23-guided-flow-productization/STATUS.md +39 -0
  62. package/specs/quiver-v23-guided-flow-productization/pr.md +119 -0
  63. package/specs/quiver-v23-guided-flow-productization/slices/slice-00-spec-foundation/CLOSURE_BRIEF.md +30 -0
  64. package/specs/quiver-v23-guided-flow-productization/slices/slice-00-spec-foundation/EXECUTION_BRIEF.md +61 -0
  65. package/specs/quiver-v23-guided-flow-productization/slices/slice-00-spec-foundation/slice.json +51 -0
  66. package/specs/quiver-v23-guided-flow-productization/slices/slice-01-short-command-and-flow-entrypoint/CLOSURE_BRIEF.md +33 -0
  67. package/specs/quiver-v23-guided-flow-productization/slices/slice-01-short-command-and-flow-entrypoint/EXECUTION_BRIEF.md +35 -0
  68. package/specs/quiver-v23-guided-flow-productization/slices/slice-01-short-command-and-flow-entrypoint/slice.json +56 -0
  69. package/specs/quiver-v23-guided-flow-productization/slices/slice-02-flow-status-wizard/CLOSURE_BRIEF.md +31 -0
  70. package/specs/quiver-v23-guided-flow-productization/slices/slice-02-flow-status-wizard/EXECUTION_BRIEF.md +29 -0
  71. package/specs/quiver-v23-guided-flow-productization/slices/slice-02-flow-status-wizard/slice.json +55 -0
  72. package/specs/quiver-v23-guided-flow-productization/slices/slice-03-agent-profiles/CLOSURE_BRIEF.md +33 -0
  73. package/specs/quiver-v23-guided-flow-productization/slices/slice-03-agent-profiles/EXECUTION_BRIEF.md +29 -0
  74. package/specs/quiver-v23-guided-flow-productization/slices/slice-03-agent-profiles/slice.json +54 -0
  75. package/specs/quiver-v23-guided-flow-productization/slices/slice-04-context-preparation-onboarding/CLOSURE_BRIEF.md +32 -0
  76. package/specs/quiver-v23-guided-flow-productization/slices/slice-04-context-preparation-onboarding/EXECUTION_BRIEF.md +30 -0
  77. package/specs/quiver-v23-guided-flow-productization/slices/slice-04-context-preparation-onboarding/slice.json +59 -0
  78. package/specs/quiver-v23-guided-flow-productization/slices/slice-05-planner-iteration-history/CLOSURE_BRIEF.md +31 -0
  79. package/specs/quiver-v23-guided-flow-productization/slices/slice-05-planner-iteration-history/EXECUTION_BRIEF.md +29 -0
  80. package/specs/quiver-v23-guided-flow-productization/slices/slice-05-planner-iteration-history/slice.json +53 -0
  81. package/specs/quiver-v23-guided-flow-productization/slices/slice-06-production-plan-review/CLOSURE_BRIEF.md +33 -0
  82. package/specs/quiver-v23-guided-flow-productization/slices/slice-06-production-plan-review/EXECUTION_BRIEF.md +30 -0
  83. package/specs/quiver-v23-guided-flow-productization/slices/slice-06-production-plan-review/slice.json +54 -0
  84. package/specs/quiver-v23-guided-flow-productization/slices/slice-07-spec-create-experience/CLOSURE_BRIEF.md +33 -0
  85. package/specs/quiver-v23-guided-flow-productization/slices/slice-07-spec-create-experience/EXECUTION_BRIEF.md +30 -0
  86. package/specs/quiver-v23-guided-flow-productization/slices/slice-07-spec-create-experience/slice.json +55 -0
  87. package/specs/quiver-v23-guided-flow-productization/slices/slice-08-executor-prompt-generation/CLOSURE_BRIEF.md +32 -0
  88. package/specs/quiver-v23-guided-flow-productization/slices/slice-08-executor-prompt-generation/EXECUTION_BRIEF.md +30 -0
  89. package/specs/quiver-v23-guided-flow-productization/slices/slice-08-executor-prompt-generation/slice.json +55 -0
  90. package/specs/quiver-v23-guided-flow-productization/slices/slice-09-delegated-slice-execution/CLOSURE_BRIEF.md +33 -0
  91. package/specs/quiver-v23-guided-flow-productization/slices/slice-09-delegated-slice-execution/EXECUTION_BRIEF.md +34 -0
  92. package/specs/quiver-v23-guided-flow-productization/slices/slice-09-delegated-slice-execution/slice.json +57 -0
  93. package/specs/quiver-v23-guided-flow-productization/slices/slice-10-docs-smokes-release-readiness/CLOSURE_BRIEF.md +33 -0
  94. package/specs/quiver-v23-guided-flow-productization/slices/slice-10-docs-smokes-release-readiness/EXECUTION_BRIEF.md +32 -0
  95. package/specs/quiver-v23-guided-flow-productization/slices/slice-10-docs-smokes-release-readiness/slice.json +63 -0
  96. package/specs/quiver-v24-dx-onboarding-hardening/EVIDENCE_REPORT.md +55 -0
  97. package/specs/quiver-v24-dx-onboarding-hardening/EXECUTION_PLAN.md +43 -0
  98. package/specs/quiver-v24-dx-onboarding-hardening/SPEC.md +149 -0
  99. package/specs/quiver-v24-dx-onboarding-hardening/STATUS.md +31 -0
  100. package/specs/quiver-v24-dx-onboarding-hardening/pr.md +76 -0
  101. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-00-spec-foundation/CLOSURE_BRIEF.md +31 -0
  102. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-00-spec-foundation/EXECUTION_BRIEF.md +52 -0
  103. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-00-spec-foundation/slice.json +51 -0
  104. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-01-init-template-hygiene/CLOSURE_BRIEF.md +38 -0
  105. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-01-init-template-hygiene/EXECUTION_BRIEF.md +53 -0
  106. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-01-init-template-hygiene/slice.json +55 -0
  107. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-02-cli-command-routing-version-errors/CLOSURE_BRIEF.md +33 -0
  108. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-02-cli-command-routing-version-errors/EXECUTION_BRIEF.md +50 -0
  109. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-02-cli-command-routing-version-errors/slice.json +52 -0
  110. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-03-doctor-fix-doc-link-checks/CLOSURE_BRIEF.md +33 -0
  111. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-03-doctor-fix-doc-link-checks/EXECUTION_BRIEF.md +50 -0
  112. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-03-doctor-fix-doc-link-checks/slice.json +53 -0
  113. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-04-prepare-output-ai-context-drafts/CLOSURE_BRIEF.md +33 -0
  114. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-04-prepare-output-ai-context-drafts/EXECUTION_BRIEF.md +50 -0
  115. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-04-prepare-output-ai-context-drafts/slice.json +70 -0
  116. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-05-local-slice-validation-base-guidance/CLOSURE_BRIEF.md +36 -0
  117. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-05-local-slice-validation-base-guidance/EXECUTION_BRIEF.md +49 -0
  118. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-05-local-slice-validation-base-guidance/slice.json +52 -0
  119. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-06-plan-graph-next-history-views/CLOSURE_BRIEF.md +43 -0
  120. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-06-plan-graph-next-history-views/EXECUTION_BRIEF.md +53 -0
  121. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-06-plan-graph-next-history-views/slice.json +60 -0
  122. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-07-analyzer-command-map-hardening/CLOSURE_BRIEF.md +32 -0
  123. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-07-analyzer-command-map-hardening/EXECUTION_BRIEF.md +50 -0
  124. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-07-analyzer-command-map-hardening/slice.json +51 -0
  125. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-08-evidence-run-command/CLOSURE_BRIEF.md +34 -0
  126. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-08-evidence-run-command/EXECUTION_BRIEF.md +52 -0
  127. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-08-evidence-run-command/slice.json +54 -0
  128. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-09-spec-viewer-demo-scaffolding/CLOSURE_BRIEF.md +34 -0
  129. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-09-spec-viewer-demo-scaffolding/EXECUTION_BRIEF.md +51 -0
  130. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-09-spec-viewer-demo-scaffolding/slice.json +59 -0
  131. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-10-docs-smokes-release-readiness/CLOSURE_BRIEF.md +33 -0
  132. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-10-docs-smokes-release-readiness/EXECUTION_BRIEF.md +54 -0
  133. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-10-docs-smokes-release-readiness/slice.json +76 -0
  134. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/EVIDENCE_REPORT.md +293 -0
  135. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/EXECUTION_PLAN.md +58 -0
  136. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/SPEC.md +242 -0
  137. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/STATUS.md +35 -0
  138. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/pr.md +77 -0
  139. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-00-spec-foundation/CLOSURE_BRIEF.md +34 -0
  140. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-00-spec-foundation/EXECUTION_BRIEF.md +52 -0
  141. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-00-spec-foundation/slice.json +52 -0
  142. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-01-cli-contract-compatibility/CLOSURE_BRIEF.md +36 -0
  143. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-01-cli-contract-compatibility/EXECUTION_BRIEF.md +52 -0
  144. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-01-cli-contract-compatibility/slice.json +56 -0
  145. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-02-run-state-phase-locks/CLOSURE_BRIEF.md +43 -0
  146. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-02-run-state-phase-locks/EXECUTION_BRIEF.md +54 -0
  147. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-02-run-state-phase-locks/slice.json +52 -0
  148. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-03-safe-ai-onboarding-docs/CLOSURE_BRIEF.md +35 -0
  149. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-03-safe-ai-onboarding-docs/EXECUTION_BRIEF.md +53 -0
  150. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-03-safe-ai-onboarding-docs/slice.json +54 -0
  151. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-04-agent-profiles-adapters/CLOSURE_BRIEF.md +34 -0
  152. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-04-agent-profiles-adapters/EXECUTION_BRIEF.md +54 -0
  153. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-04-agent-profiles-adapters/slice.json +52 -0
  154. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-05-approval-gates/CLOSURE_BRIEF.md +34 -0
  155. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-05-approval-gates/EXECUTION_BRIEF.md +54 -0
  156. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-05-approval-gates/slice.json +53 -0
  157. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-06-spec-slice-generator/CLOSURE_BRIEF.md +33 -0
  158. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-06-spec-slice-generator/EXECUTION_BRIEF.md +56 -0
  159. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-06-spec-slice-generator/slice.json +55 -0
  160. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-07-slice-execution-planner/CLOSURE_BRIEF.md +33 -0
  161. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-07-slice-execution-planner/EXECUTION_BRIEF.md +54 -0
  162. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-07-slice-execution-planner/slice.json +52 -0
  163. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-08-controlled-slice-execution/CLOSURE_BRIEF.md +39 -0
  164. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-08-controlled-slice-execution/EXECUTION_BRIEF.md +56 -0
  165. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-08-controlled-slice-execution/slice.json +53 -0
  166. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-09-git-worktree-pr-lifecycle/CLOSURE_BRIEF.md +38 -0
  167. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-09-git-worktree-pr-lifecycle/EXECUTION_BRIEF.md +57 -0
  168. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-09-git-worktree-pr-lifecycle/slice.json +52 -0
  169. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-10-validation-errors-fixtures/CLOSURE_BRIEF.md +39 -0
  170. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-10-validation-errors-fixtures/EXECUTION_BRIEF.md +55 -0
  171. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-10-validation-errors-fixtures/slice.json +56 -0
  172. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-11-export-dashboard-migration/CLOSURE_BRIEF.md +36 -0
  173. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-11-export-dashboard-migration/EXECUTION_BRIEF.md +54 -0
  174. package/specs/quiver-v25-ai-first-lifecycle-orchestrator/slices/slice-11-export-dashboard-migration/slice.json +53 -0
  175. package/specs/quiver-v26-0121-smoke-hardening/EVIDENCE_REPORT.md +208 -0
  176. package/specs/quiver-v26-0121-smoke-hardening/EXECUTION_PLAN.md +57 -0
  177. package/specs/quiver-v26-0121-smoke-hardening/SPEC.md +137 -0
  178. package/specs/quiver-v26-0121-smoke-hardening/STATUS.md +32 -0
  179. package/specs/quiver-v26-0121-smoke-hardening/pr.md +96 -0
  180. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-00-docs-foundation/CLOSURE_BRIEF.md +35 -0
  181. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-00-docs-foundation/EXECUTION_BRIEF.md +55 -0
  182. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-00-docs-foundation/slice.json +73 -0
  183. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-01-cli-help-version-contract/CLOSURE_BRIEF.md +38 -0
  184. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-01-cli-help-version-contract/EXECUTION_BRIEF.md +51 -0
  185. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-01-cli-help-version-contract/slice.json +76 -0
  186. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-02-init-doc-links-and-flow-guidance/CLOSURE_BRIEF.md +37 -0
  187. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-02-init-doc-links-and-flow-guidance/EXECUTION_BRIEF.md +52 -0
  188. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-02-init-doc-links-and-flow-guidance/slice.json +75 -0
  189. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-03-ai-approval-review-consistency/CLOSURE_BRIEF.md +37 -0
  190. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-03-ai-approval-review-consistency/EXECUTION_BRIEF.md +53 -0
  191. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-03-ai-approval-review-consistency/slice.json +77 -0
  192. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-04-local-validation-brief-contracts/CLOSURE_BRIEF.md +35 -0
  193. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-04-local-validation-brief-contracts/EXECUTION_BRIEF.md +52 -0
  194. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-04-local-validation-brief-contracts/slice.json +77 -0
  195. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-05-demo-scaffold-readiness/CLOSURE_BRIEF.md +34 -0
  196. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-05-demo-scaffold-readiness/EXECUTION_BRIEF.md +54 -0
  197. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-05-demo-scaffold-readiness/slice.json +84 -0
  198. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-06-plan-graph-scope-performance/CLOSURE_BRIEF.md +35 -0
  199. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-06-plan-graph-scope-performance/EXECUTION_BRIEF.md +53 -0
  200. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-06-plan-graph-scope-performance/slice.json +82 -0
  201. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-07-smoke-release-readiness/CLOSURE_BRIEF.md +35 -0
  202. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-07-smoke-release-readiness/EXECUTION_BRIEF.md +55 -0
  203. package/specs/quiver-v26-0121-smoke-hardening/slices/slice-07-smoke-release-readiness/slice.json +92 -0
  204. package/src/create-quiver/commands/ai.js +1060 -37
  205. package/src/create-quiver/commands/demo.js +22 -0
  206. package/src/create-quiver/commands/evidence.js +37 -0
  207. package/src/create-quiver/commands/flow.js +562 -0
  208. package/src/create-quiver/commands/graph.js +19 -4
  209. package/src/create-quiver/commands/next.js +28 -0
  210. package/src/create-quiver/commands/plan.js +9 -6
  211. package/src/create-quiver/commands/prepare.js +236 -0
  212. package/src/create-quiver/commands/spec.js +133 -0
  213. package/src/create-quiver/index.js +1010 -31
  214. package/src/create-quiver/lib/actionable-error.js +27 -0
  215. package/src/create-quiver/lib/agent-profiles.js +148 -0
  216. package/src/create-quiver/lib/ai/context-packs.js +16 -0
  217. package/src/create-quiver/lib/ai/execution-plan.js +377 -11
  218. package/src/create-quiver/lib/ai/executor.js +633 -24
  219. package/src/create-quiver/lib/ai/export-state.js +534 -0
  220. package/src/create-quiver/lib/ai/github.js +279 -0
  221. package/src/create-quiver/lib/ai/onboarding-template.js +578 -0
  222. package/src/create-quiver/lib/ai/plan-review.js +286 -0
  223. package/src/create-quiver/lib/ai/providers.js +5 -3
  224. package/src/create-quiver/lib/ai/run-state.js +414 -0
  225. package/src/create-quiver/lib/ai/safety.js +5 -0
  226. package/src/create-quiver/lib/ai/spec-generator.js +12 -0
  227. package/src/create-quiver/lib/ai/spec-templates.js +80 -11
  228. package/src/create-quiver/lib/approvals.js +369 -0
  229. package/src/create-quiver/lib/demo.js +832 -0
  230. package/src/create-quiver/lib/doctor.js +309 -0
  231. package/src/create-quiver/lib/evidence.js +115 -0
  232. package/src/create-quiver/lib/handoff.js +81 -12
  233. package/src/create-quiver/lib/init-docs.js +302 -17
  234. package/src/create-quiver/lib/init-layout.js +34 -1
  235. package/src/create-quiver/lib/json.js +53 -3
  236. package/src/create-quiver/lib/lifecycle.js +6 -0
  237. package/src/create-quiver/lib/package-safety.js +117 -0
  238. package/src/create-quiver/lib/readiness.js +103 -21
  239. package/src/create-quiver/lib/scope.js +50 -7
  240. package/src/create-quiver/lib/slice-graph.js +138 -37
  241. package/src/create-quiver/lib/slice.js +14 -9
  242. package/src/create-quiver/lib/spec-worktrees.js +363 -0
@@ -3,15 +3,49 @@ const os = require('os');
3
3
  const path = require('path');
4
4
  const { execFileSync } = require('child_process');
5
5
  const { checkHandoff, scaffoldHandoff } = require('./lib/handoff');
6
- const { collectDoctorReport } = require('./lib/doctor');
7
- const { runDoctor: runAiDoctor, runExecuteSlice: runAiExecuteSlice, runOnboard, runPlan: runAiPlan, runPr: runAiPr } = require('./commands/ai');
6
+ const {
7
+ applyDoctorFixPlan,
8
+ buildDoctorFixPlan,
9
+ collectDoctorReport,
10
+ formatDoctorFixPlan,
11
+ } = require('./lib/doctor');
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');
35
+ const { runDemo } = require('./commands/demo');
36
+ const { runPrepare } = require('./commands/prepare');
37
+ const { runEvidence } = require('./commands/evidence');
38
+ const { runFlow } = require('./commands/flow');
8
39
  const { runGraph } = require('./commands/graph');
9
40
  const { runNext } = require('./commands/next');
10
41
  const { runPlan } = require('./commands/plan');
42
+ const { runCreateSpec } = require('./commands/spec');
11
43
  const { buildInitLayout, formatInitLayoutPlan } = require('./lib/init-layout');
12
- const { initializeProjectDocs, installSelfAsDevDep } = require('./lib/init-docs');
44
+ const { initializeProjectDocs, installSelfAsDevDep, refreshAiContextDoc } = require('./lib/init-docs');
13
45
  const { checkPrReadiness, checkScope, checkSliceReadiness } = require('./lib/readiness');
14
46
  const { cleanupSlice, refreshActiveSlicesBoard, startSlice } = require('./lib/lifecycle');
47
+ const { buildSpecStatus, closeSpecWorktree, formatSpecCloseResult, formatSpecStartResult, formatSpecStatus, startSpecWorktree } = require('./lib/spec-worktrees');
48
+ const { getContextPathExclusionReason } = require('./lib/ai/safety');
15
49
  const { relativePosixPath, resolveTargetRoot } = require('./lib/paths');
16
50
  const {
17
51
  CURRENT_SCAN_RELATIVE_PATH,
@@ -35,44 +69,245 @@ function formatError(message) {
35
69
  return `create-quiver: ${message}`;
36
70
  }
37
71
 
72
+ const SUPPORTED_COMMAND_MODES = new Set([
73
+ 'init',
74
+ 'flow',
75
+ 'plan',
76
+ 'graph',
77
+ 'next',
78
+ 'doctor',
79
+ 'prepare',
80
+ 'analyze',
81
+ 'migrate',
82
+ 'start-slice',
83
+ 'check-slice',
84
+ 'check-pr',
85
+ 'check-handoff',
86
+ 'new-handoff',
87
+ 'cleanup-slice',
88
+ 'check-scope',
89
+ 'refresh-active-slices',
90
+ 'spec',
91
+ 'evidence',
92
+ 'demo',
93
+ 'ai',
94
+ ]);
95
+
96
+ const SUPPORTED_AI_COMMANDS = new Set([
97
+ 'agent',
98
+ 'approve',
99
+ 'approval-status',
100
+ 'approvals',
101
+ 'doctor',
102
+ 'execute-plan',
103
+ 'execute-slice',
104
+ 'executor-prompt',
105
+ 'export',
106
+ 'inspect',
107
+ 'onboard',
108
+ 'plan',
109
+ 'prepare-context',
110
+ 'pr',
111
+ 'prompt-slice',
112
+ 'review-plan',
113
+ 'revise',
114
+ 'resume',
115
+ 'run',
116
+ 'slices',
117
+ 'specs',
118
+ 'status',
119
+ 'trace',
120
+ ]);
121
+
122
+ const SUPPORTED_SPEC_COMMANDS = new Set(['close', 'create', 'start', 'status']);
123
+ const SUPPORTED_DEMO_COMMANDS = new Set(['create']);
124
+
125
+ function unsupportedCommandMessage(commandName) {
126
+ return [
127
+ `unsupported command: ${commandName}`,
128
+ 'Run: npx create-quiver --help',
129
+ `If you meant to initialize a project, use: npx create-quiver init --name "${commandName}"`,
130
+ 'If this command exists in newer docs, update create-quiver and rerun the command.',
131
+ ].join('\n');
132
+ }
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
+
38
231
  function printUsage() {
39
232
  console.log(`Usage:
40
233
  npx create-quiver [options]
41
234
  npx create-quiver init [options]
42
235
  npx create-quiver analyze [options]
236
+ npx create-quiver flow [options]
43
237
  npx create-quiver plan [options]
44
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]
247
+ npx create-quiver ai agent <set|list|show> [role] [options]
248
+ npx create-quiver ai prepare-context [options]
249
+ npx create-quiver ai revise [options]
45
250
  npx create-quiver graph [options]
46
251
  npx create-quiver next [options]
47
252
  npx create-quiver migrate [options]
48
253
  npx create-quiver doctor [options]
254
+ npx create-quiver prepare [options]
49
255
  npx create-quiver start-slice [options] <slice.json>
50
256
  npx create-quiver check-slice [options] <slice.json>
51
257
  npx create-quiver check-pr <slice.json>
52
- npx create-quiver check-handoff <handoff.md>
258
+ npx create-quiver check-handoff <handoff-or-brief.md>
53
259
  npx create-quiver new-handoff <spec-slug>
54
260
  npx create-quiver cleanup-slice [options] <slice.json>
55
261
  npx create-quiver check-scope [options] <slice.json>
56
262
  npx create-quiver refresh-active-slices
263
+ npx create-quiver spec create [options]
264
+ npx create-quiver spec start <spec-dir>
265
+ npx create-quiver spec status <spec-dir>
266
+ npx create-quiver spec close <spec-dir>
267
+ npx create-quiver evidence run [options] -- <command>
268
+ npx create-quiver demo create spec-viewer [options]
269
+
270
+ ${formatCommandHelpGroups()}
57
271
 
58
272
  Options:
59
273
  -n, --name <project-name> Project name to generate
60
274
  -d, --dir <target-dir> Target directory to scaffold into or inspect
61
275
  --spec <slug> Restrict plan output to one spec
62
- --format <name> Graph output format (tree, mermaid, dot)
276
+ --format <name> Graph or AI export output format (tree, mermaid, dot, json, markdown)
63
277
  --show-conflicts Show shared file paths in graph output
64
278
  --level <n> Restrict graph output to one level
65
279
  --json Emit machine-readable JSON
280
+ --include-completed Include completed slices in plan, graph, or next history output
66
281
  --only-ready Show only slices with no pending dependencies
67
282
  --all-ready List every ready slice returned by next
68
283
  --auto-start Prompt for confirmation and run start-slice on next
284
+ --local For check-slice, run structural validation without remote/base checks
69
285
  --unicode Prefer Unicode output when supported
70
286
  --minimal Plan or run the minimal init profile
71
287
  --full Plan or run the full compatibility init profile
72
288
  --legacy-scripts Include legacy Bash wrappers in init profile
73
289
  --include-templates Export packaged templates in init profile
74
- --dry-run Preview init 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
292
+ --fix For doctor, apply safe non-destructive repairs
293
+ --execute For ai execute-plan, run the planned slices instead of printing commands
294
+ --create For ai pr, create the PR after preflight instead of printing the plan only
295
+ --commit For ai execute-slice, commit validated slice changes after provider, scope, and tests pass
296
+ --allow-dirty For ai execute-slice, allow pre-existing dirty files and ignore them for scope diff
297
+ --mode <name> Execution mode for ai execute-plan (auto, manual, delegated)
298
+ --provider <name> Provider CLI to preflight for prepare or AI commands
299
+ --model <label> Free-form model label for AI agent profiles
300
+ --version <n> Draft version to approve for AI planner phases
301
+ --run <id> AI lifecycle run id
302
+ --ssh-host-alias <name> SSH host alias to validate for prepare or AI commands
303
+ --identity-file <path> SSH identity file to validate for prepare or AI commands
304
+ --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)
306
+ --output <file> Output file for evidence run
307
+ --max-output <n> Maximum stdout/stderr chars per evidence section
308
+ --title <text> Override PR title for ai pr create
75
309
  -y, --yes Skip prompts and use the provided inputs
310
+ -V, --version Show the installed create-quiver version
76
311
  -h, --help Show this help message
77
312
 
78
313
  Examples:
@@ -80,13 +315,40 @@ Examples:
80
315
  npx create-quiver init --name "My Project" --dry-run
81
316
  npx create-quiver --name "My Project"
82
317
  npx create-quiver --name "My Project" --dir ./my-project
318
+ cd ./my-project && npx create-quiver flow
83
319
  cd ./my-project && npx create-quiver analyze
84
320
  cd ./my-project && npx create-quiver plan --json
85
321
  cd ./my-project && npx create-quiver ai onboard --dry-run
322
+ cd ./my-project && npx create-quiver ai onboard --print-prompt
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
333
+ cd ./my-project && npx create-quiver ai agent set planner --provider codex --model gpt-5.5
334
+ cd ./my-project && npx create-quiver ai agent list
86
335
  cd ./my-project && npx create-quiver ai plan --phase acceptance --input requirements.md --dry-run
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
338
+ cd ./my-project && npx create-quiver ai plan --phase technical-plan --dry-run
339
+ cd ./my-project && npx create-quiver ai review-plan --dry-run
340
+ cd ./my-project && npx create-quiver ai approve --phase technical-plan --version 1
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
343
+ cd ./my-project && npx create-quiver ai approvals
344
+ cd ./my-project && npx create-quiver ai prompt-slice --slice specs/my-project/slices/slice-01/slice.json --dry-run
87
345
  cd ./my-project && npx create-quiver ai execute-slice --slice specs/my-project/slices/slice-01/slice.json --dry-run
346
+ cd ./my-project && npx create-quiver ai execute-slice --slice specs/my-project/slices/slice-01/slice.json --commit
347
+ cd ./my-project && npx create-quiver ai execute-plan --dry-run --commit
88
348
  cd ./my-project && npx create-quiver ai doctor --dry-run --ssh-host-alias github-work --identity-file ~/.ssh/github-work
89
349
  cd ./my-project && npx create-quiver ai pr --dry-run --ssh-host-alias github-work --identity-file ~/.ssh/github-work
350
+ cd ./my-project && npx create-quiver ai pr --create --input specs/my-project/pr.md --ssh-host-alias github-work --identity-file ~/.ssh/github-work
351
+ cd ./my-project && npx create-quiver prepare --dry-run --provider codex --ssh-host-alias github-work --identity-file ~/.ssh/github-work
90
352
  cd ./my-project && npx create-quiver graph --show-conflicts
91
353
  cd ./my-project && npx create-quiver graph --format mermaid
92
354
  cd ./my-project && npx create-quiver graph --format dot
@@ -99,10 +361,16 @@ Examples:
99
361
  cd ./my-project && npx create-quiver check-slice specs/my-project/slices/slice-01/slice.json
100
362
  cd ./my-project && npx create-quiver check-pr specs/my-project/slices/slice-01/slice.json
101
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
102
365
  cd ./my-project && npx create-quiver new-handoff my-spec
103
366
  cd ./my-project && npx create-quiver cleanup-slice specs/my-project/slices/slice-01/slice.json
104
367
  cd ./my-project && npx create-quiver check-scope specs/my-project/slices/slice-01/slice.json
105
368
  cd ./my-project && npx create-quiver refresh-active-slices
369
+ cd ./my-project && npx create-quiver spec start specs/my-project
370
+ cd ./my-project && npx create-quiver spec status specs/my-project
371
+ cd ./my-project && npx create-quiver spec close specs/my-project --dry-run
372
+ cd ./my-project && npx create-quiver evidence run -- npm test
373
+ cd ./my-project && npx create-quiver demo create spec-viewer --dry-run
106
374
  node bin/create-quiver.js doctor --dir ./my-project
107
375
  `);
108
376
  }
@@ -114,31 +382,55 @@ function parseArgs(argv) {
114
382
  explicitInit: false,
115
383
  mode: 'init',
116
384
  allowDraft: false,
385
+ checkSliceLocal: false,
117
386
  closeBaseline: false,
118
387
  discard: false,
388
+ doctorFix: false,
119
389
  dryRun: false,
390
+ aiPrintPrompt: false,
120
391
  gate: 'execution',
121
392
  projectName: '',
122
393
  targetDir: '.',
394
+ targetDirExplicit: false,
123
395
  strict: false,
124
396
  strictOverlap: false,
125
397
  json: false,
398
+ includeCompleted: false,
126
399
  onlyReady: false,
127
400
  allReady: false,
128
401
  autoStart: false,
129
402
  specSlug: '',
130
403
  format: 'tree',
404
+ formatExplicit: false,
131
405
  showConflicts: false,
132
406
  level: null,
133
407
  unicode: false,
134
408
  aiCommand: '',
409
+ aiSecondaryCommand: '',
410
+ aiAgentCommand: '',
411
+ aiAgentRole: '',
412
+ aiRunCommand: '',
413
+ aiRunId: '',
135
414
  aiPhase: 'acceptance',
136
415
  aiProvider: 'codex',
416
+ aiProviderExplicit: false,
417
+ aiModel: '',
418
+ aiLabel: '',
419
+ aiVersion: '',
420
+ prepareProvider: '',
137
421
  aiRole: '',
138
422
  aiContext: '',
139
423
  aiInput: '',
140
424
  aiSlice: '',
141
425
  aiTimeout: null,
426
+ aiCommit: false,
427
+ aiAllowDirty: false,
428
+ aiExecute: false,
429
+ aiExecutionMode: 'auto',
430
+ aiCreate: false,
431
+ aiBaseBranch: 'main',
432
+ baseBranchExplicit: false,
433
+ aiTitle: '',
142
434
  aiSshHostAlias: '',
143
435
  aiIdentityFile: '',
144
436
  aiRemote: 'origin',
@@ -146,14 +438,30 @@ function parseArgs(argv) {
146
438
  initIncludeTemplates: false,
147
439
  initLegacyScripts: false,
148
440
  initMinimal: false,
441
+ specCommand: '',
442
+ demoCommand: '',
443
+ demoName: '',
444
+ evidenceCommand: '',
445
+ evidenceArgs: [],
446
+ evidenceOutput: '',
447
+ evidenceMaxOutput: null,
149
448
  };
150
449
 
151
450
  const args = [...argv];
152
- const commandModes = new Set(['init', 'plan', 'graph', 'next', 'doctor', 'analyze', 'migrate', 'start-slice', 'check-slice', 'check-pr', 'check-handoff', 'new-handoff', 'cleanup-slice', 'check-scope', 'refresh-active-slices', 'ai']);
153
- if (commandModes.has(args[0])) {
451
+ if (SUPPORTED_COMMAND_MODES.has(args[0])) {
154
452
  result.mode = args[0];
155
453
  result.explicitInit = args[0] === 'init';
156
454
  args.shift();
455
+ if (result.mode === 'spec') {
456
+ result.specCommand = args.shift() || '';
457
+ }
458
+ if (result.mode === 'evidence') {
459
+ result.evidenceCommand = args.shift() || '';
460
+ }
461
+ if (result.mode === 'demo') {
462
+ result.demoCommand = args.shift() || '';
463
+ result.demoName = args.shift() || '';
464
+ }
157
465
  } else if (args[0] === '--analyze') {
158
466
  result.mode = 'analyze';
159
467
  args.shift();
@@ -169,6 +477,8 @@ function parseArgs(argv) {
169
477
  } else if (args[0] === '--new-handoff') {
170
478
  result.mode = 'new-handoff';
171
479
  args.shift();
480
+ } else if (args[0] && !args[0].startsWith('-')) {
481
+ throw new Error(formatError(unsupportedCommandMessage(args[0])));
172
482
  }
173
483
 
174
484
  const positional = [];
@@ -176,6 +486,11 @@ function parseArgs(argv) {
176
486
  for (let index = 0; index < args.length; index += 1) {
177
487
  const arg = args[index];
178
488
 
489
+ if (arg === '--') {
490
+ result.evidenceArgs = args.slice(index + 1);
491
+ break;
492
+ }
493
+
179
494
  if (arg === '-h' || arg === '--help') {
180
495
  result.help = true;
181
496
  continue;
@@ -216,6 +531,11 @@ function parseArgs(argv) {
216
531
  continue;
217
532
  }
218
533
 
534
+ if (arg === '--local') {
535
+ result.checkSliceLocal = true;
536
+ continue;
537
+ }
538
+
219
539
  if (arg === '--close-baseline') {
220
540
  result.closeBaseline = true;
221
541
  continue;
@@ -226,11 +546,50 @@ function parseArgs(argv) {
226
546
  continue;
227
547
  }
228
548
 
549
+ if (arg === '--fix') {
550
+ result.doctorFix = true;
551
+ continue;
552
+ }
553
+
229
554
  if (arg === '--dry-run') {
230
555
  result.dryRun = true;
231
556
  continue;
232
557
  }
233
558
 
559
+ if (arg === '--print-prompt') {
560
+ result.aiPrintPrompt = true;
561
+ continue;
562
+ }
563
+
564
+ if (arg === '--commit') {
565
+ result.aiCommit = true;
566
+ continue;
567
+ }
568
+
569
+ if (arg === '--execute') {
570
+ result.aiExecute = true;
571
+ continue;
572
+ }
573
+
574
+ if (arg === '--create') {
575
+ result.aiCreate = true;
576
+ continue;
577
+ }
578
+
579
+ if (arg === '--mode') {
580
+ const value = args[++index];
581
+ if (!value) {
582
+ throw new Error(formatError('missing value for --mode'));
583
+ }
584
+ result.aiExecutionMode = value;
585
+ continue;
586
+ }
587
+
588
+ if (arg === '--allow-dirty') {
589
+ result.aiAllowDirty = true;
590
+ continue;
591
+ }
592
+
234
593
  if (arg === '--minimal') {
235
594
  result.initMinimal = true;
236
595
  continue;
@@ -266,6 +625,11 @@ function parseArgs(argv) {
266
625
  continue;
267
626
  }
268
627
 
628
+ if (arg === '--include-completed') {
629
+ result.includeCompleted = true;
630
+ continue;
631
+ }
632
+
269
633
  if (arg === '--show-conflicts') {
270
634
  result.showConflicts = true;
271
635
  continue;
@@ -277,6 +641,7 @@ function parseArgs(argv) {
277
641
  throw new Error(formatError('missing value for --format'));
278
642
  }
279
643
  result.format = value;
644
+ result.formatExplicit = true;
280
645
  continue;
281
646
  }
282
647
 
@@ -319,6 +684,44 @@ function parseArgs(argv) {
319
684
  throw new Error(formatError('missing value for --provider'));
320
685
  }
321
686
  result.aiProvider = value;
687
+ result.prepareProvider = value;
688
+ result.aiProviderExplicit = true;
689
+ continue;
690
+ }
691
+
692
+ if (arg === '--model') {
693
+ const value = args[++index];
694
+ if (!value) {
695
+ throw new Error(formatError('missing value for --model'));
696
+ }
697
+ result.aiModel = value;
698
+ continue;
699
+ }
700
+
701
+ if (arg === '--label') {
702
+ const value = args[++index];
703
+ if (!value) {
704
+ throw new Error(formatError('missing value for --label'));
705
+ }
706
+ result.aiLabel = value;
707
+ continue;
708
+ }
709
+
710
+ if (arg === '--version') {
711
+ const value = args[++index];
712
+ if (!value) {
713
+ throw new Error(formatError('missing value for --version'));
714
+ }
715
+ result.aiVersion = value;
716
+ continue;
717
+ }
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;
322
725
  continue;
323
726
  }
324
727
 
@@ -398,6 +801,47 @@ function parseArgs(argv) {
398
801
  continue;
399
802
  }
400
803
 
804
+ if (arg === '--base') {
805
+ const value = args[++index];
806
+ if (!value) {
807
+ throw new Error(formatError('missing value for --base'));
808
+ }
809
+ result.aiBaseBranch = value;
810
+ result.baseBranchExplicit = true;
811
+ continue;
812
+ }
813
+
814
+ if (arg === '--output') {
815
+ const value = args[++index];
816
+ if (!value) {
817
+ throw new Error(formatError('missing value for --output'));
818
+ }
819
+ result.evidenceOutput = value;
820
+ continue;
821
+ }
822
+
823
+ if (arg === '--max-output') {
824
+ const value = args[++index];
825
+ if (typeof value === 'undefined') {
826
+ throw new Error(formatError('missing value for --max-output'));
827
+ }
828
+ const parsed = Number.parseInt(value, 10);
829
+ if (!Number.isInteger(parsed) || parsed <= 0) {
830
+ throw new Error(formatError('invalid value for --max-output'));
831
+ }
832
+ result.evidenceMaxOutput = parsed;
833
+ continue;
834
+ }
835
+
836
+ if (arg === '--title') {
837
+ const value = args[++index];
838
+ if (!value) {
839
+ throw new Error(formatError('missing value for --title'));
840
+ }
841
+ result.aiTitle = value;
842
+ continue;
843
+ }
844
+
401
845
  if (arg === '--phase') {
402
846
  const value = args[++index];
403
847
  if (!value) {
@@ -440,6 +884,7 @@ function parseArgs(argv) {
440
884
  throw new Error(formatError('missing value for --dir'));
441
885
  }
442
886
  result.targetDir = value;
887
+ result.targetDirExplicit = true;
443
888
  continue;
444
889
  }
445
890
 
@@ -462,17 +907,90 @@ function parseArgs(argv) {
462
907
  if (positional.length > 0) {
463
908
  throw new Error(formatError('plan does not accept positional arguments; use --spec <slug>'));
464
909
  }
910
+ } else if (result.mode === 'flow') {
911
+ if (positional.length > 0) {
912
+ throw new Error(formatError('flow does not accept positional arguments'));
913
+ }
465
914
  } else if (result.mode === 'ai') {
466
915
  if (!result.aiCommand && positional.length > 0) {
467
916
  result.aiCommand = positional.shift();
468
917
  }
918
+ if (result.aiCommand === 'agent') {
919
+ if (!result.aiAgentCommand && positional.length > 0) {
920
+ result.aiAgentCommand = positional.shift();
921
+ }
922
+ if (!result.aiAgentRole && positional.length > 0) {
923
+ result.aiAgentRole = positional.shift();
924
+ }
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
+ }
469
938
  if (positional.length > 0) {
470
939
  throw new Error(formatError('ai does not accept extra positional arguments'));
471
940
  }
941
+ } else if (result.mode === 'prepare') {
942
+ if (positional.length > 0) {
943
+ throw new Error(formatError('prepare does not accept positional arguments'));
944
+ }
472
945
  } else if (result.mode === 'refresh-active-slices') {
473
946
  if (positional.length > 0) {
474
947
  throw new Error(formatError('refresh-active-slices does not accept positional arguments'));
475
948
  }
949
+ } else if (result.mode === 'spec') {
950
+ if (!result.specCommand && positional.length > 0) {
951
+ result.specCommand = positional.shift();
952
+ }
953
+ if (!result.specCommand) {
954
+ throw new Error(formatError('missing spec subcommand. Use: npx create-quiver spec <create|start|status|close>'));
955
+ }
956
+ if (result.specCommand !== 'create' && positional.length > 0) {
957
+ result.targetDir = positional.shift();
958
+ }
959
+ if (result.specCommand === 'create' && positional.length > 0) {
960
+ throw new Error(formatError('spec create does not accept positional arguments; use --input <file> or --spec <slug>'));
961
+ }
962
+ } else if (result.mode === 'evidence') {
963
+ if (!result.evidenceCommand && positional.length > 0) {
964
+ result.evidenceCommand = positional.shift();
965
+ }
966
+ if (!result.evidenceCommand) {
967
+ throw new Error(formatError('missing evidence subcommand. Use: npx create-quiver evidence run -- <command>'));
968
+ }
969
+ if (result.evidenceCommand !== 'run') {
970
+ throw new Error(formatError(`unsupported evidence subcommand: ${result.evidenceCommand}. Supported tasks: run`));
971
+ }
972
+ if (positional.length > 0) {
973
+ throw new Error(formatError('evidence run does not accept positional arguments before --'));
974
+ }
975
+ } else if (result.mode === 'demo') {
976
+ if (!result.demoCommand && positional.length > 0) {
977
+ result.demoCommand = positional.shift();
978
+ }
979
+ if (!result.demoName && positional.length > 0) {
980
+ result.demoName = positional.shift();
981
+ }
982
+ if (!result.demoCommand) {
983
+ throw new Error(formatError('missing demo subcommand. Use: npx create-quiver demo create spec-viewer'));
984
+ }
985
+ if (!SUPPORTED_DEMO_COMMANDS.has(result.demoCommand)) {
986
+ throw new Error(formatError(`unsupported demo subcommand: ${result.demoCommand}. Supported tasks: create`));
987
+ }
988
+ if (result.demoName !== 'spec-viewer') {
989
+ throw new Error(formatError(`unsupported demo: ${result.demoName || '(missing)'}. Supported demos: spec-viewer`));
990
+ }
991
+ if (positional.length > 0) {
992
+ throw new Error(formatError('demo create spec-viewer does not accept positional target paths; use --dir <target-dir>'));
993
+ }
476
994
  } else {
477
995
  if (positional.length > 0) {
478
996
  result.targetDir = positional.shift();
@@ -698,6 +1216,43 @@ function escapeMarkdownCell(value) {
698
1216
  return String(value).replace(/\|/g, '\\|');
699
1217
  }
700
1218
 
1219
+ function summarizeSkippedPaths(scan) {
1220
+ const details = Array.isArray(scan.skipped_path_details) && scan.skipped_path_details.length > 0
1221
+ ? scan.skipped_path_details
1222
+ : (Array.isArray(scan.skipped_paths) ? scan.skipped_paths.map((item) => ({ reason: 'excluded path', path: item })) : []);
1223
+ const counts = new Map();
1224
+ const dependencySegments = new Set(['node_modules', '.pnpm-store', '.npm', '.yarn']);
1225
+ const outputSegments = new Set(['dist', 'build', 'coverage', 'out', 'tmp', 'temp', 'cache', '.cache', '.turbo', '.next', '.nuxt', '.parcel-cache', 'generated', 'gen', 'artifacts', 'reports', 'vendor', 'target']);
1226
+
1227
+ for (const item of details) {
1228
+ const reason = item.reason || 'excluded path';
1229
+ let label = reason;
1230
+ if (reason === 'env-file') {
1231
+ label = 'env files';
1232
+ } else if (reason === 'git-metadata') {
1233
+ label = 'git metadata';
1234
+ } else if (reason === 'hidden-directory') {
1235
+ label = 'hidden directories';
1236
+ } else if (reason.startsWith('secret-file:')) {
1237
+ label = 'secret files';
1238
+ } else if (reason.startsWith('unsafe-segment:')) {
1239
+ const segment = reason.slice('unsafe-segment:'.length);
1240
+ if (segment === '.quiver') {
1241
+ label = 'local AI state';
1242
+ } else if (dependencySegments.has(segment)) {
1243
+ label = 'dependency folders';
1244
+ } else if (outputSegments.has(segment)) {
1245
+ label = 'generated/output/cache folders';
1246
+ } else {
1247
+ label = segment;
1248
+ }
1249
+ }
1250
+ counts.set(label, (counts.get(label) || 0) + 1);
1251
+ }
1252
+
1253
+ return Array.from(counts.entries()).map(([reason, count]) => ({ reason, count }));
1254
+ }
1255
+
701
1256
  function collectPackageManagers(projectRoot) {
702
1257
  const packageManagerField = readJsonIfExists(path.join(projectRoot, 'package.json'))?.packageManager;
703
1258
 
@@ -725,6 +1280,7 @@ function collectPackageManagers(projectRoot) {
725
1280
  function collectProjectFiles(projectRoot, maxDepth = 2) {
726
1281
  const files = [];
727
1282
  const skippedPaths = [];
1283
+ const skippedPathDetails = [];
728
1284
  const ignoredDirs = new Set([
729
1285
  '.git',
730
1286
  'node_modules',
@@ -741,6 +1297,12 @@ function collectProjectFiles(projectRoot, maxDepth = 2) {
741
1297
  ]);
742
1298
  const allowedHiddenDirs = new Set(['.github', '.vscode', '.devcontainer']);
743
1299
 
1300
+ function skipPath(relativePath, reason) {
1301
+ const normalized = relativePath.split(path.sep).join('/');
1302
+ skippedPaths.push(normalized);
1303
+ skippedPathDetails.push({ path: normalized, reason });
1304
+ }
1305
+
744
1306
  function walk(currentDir, depth, relativeDir = '') {
745
1307
  const entries = fs.readdirSync(currentDir, { withFileTypes: true });
746
1308
 
@@ -750,12 +1312,18 @@ function collectProjectFiles(projectRoot, maxDepth = 2) {
750
1312
 
751
1313
  if (entry.isDirectory()) {
752
1314
  if (ignoredDirs.has(entry.name)) {
753
- skippedPaths.push(entryRelativePath);
1315
+ skipPath(entryRelativePath, `unsafe-segment:${entry.name}`);
1316
+ continue;
1317
+ }
1318
+
1319
+ const directoryReason = getContextPathExclusionReason(entryRelativePath);
1320
+ if (directoryReason) {
1321
+ skipPath(entryRelativePath, directoryReason);
754
1322
  continue;
755
1323
  }
756
1324
 
757
1325
  if (entry.name.startsWith('.') && !allowedHiddenDirs.has(entry.name)) {
758
- skippedPaths.push(entryRelativePath);
1326
+ skipPath(entryRelativePath, 'hidden-directory');
759
1327
  continue;
760
1328
  }
761
1329
 
@@ -766,13 +1334,19 @@ function collectProjectFiles(projectRoot, maxDepth = 2) {
766
1334
  continue;
767
1335
  }
768
1336
 
1337
+ const fileReason = getContextPathExclusionReason(entryRelativePath);
1338
+ if (fileReason) {
1339
+ skipPath(entryRelativePath, fileReason);
1340
+ continue;
1341
+ }
1342
+
769
1343
  files.push(entryRelativePath);
770
1344
  }
771
1345
  }
772
1346
 
773
1347
  walk(projectRoot, 0);
774
1348
 
775
- return { files, skippedPaths };
1349
+ return { files, skipped_path_details: skippedPathDetails, skippedPaths };
776
1350
  }
777
1351
 
778
1352
  function collectRootEntries(projectRoot) {
@@ -820,6 +1394,7 @@ function collectLanguageSignals(files) {
820
1394
  }
821
1395
 
822
1396
  const languages = [];
1397
+ const seenLanguages = new Set();
823
1398
  const extToLanguage = new Map([
824
1399
  ['.ts', 'typescript'],
825
1400
  ['.tsx', 'typescript'],
@@ -845,14 +1420,90 @@ function collectLanguageSignals(files) {
845
1420
  ]);
846
1421
 
847
1422
  for (const [ext, language] of extToLanguage.entries()) {
848
- if (extensions.has(ext)) {
1423
+ if (extensions.has(ext) && !seenLanguages.has(language)) {
849
1424
  languages.push(language);
1425
+ seenLanguages.add(language);
850
1426
  }
851
1427
  }
852
1428
 
853
1429
  return languages;
854
1430
  }
855
1431
 
1432
+ function parseCreateQuiverScriptCommand(command) {
1433
+ const normalized = String(command || '').trim();
1434
+ const match = normalized.match(/^npx\s+create-quiver(?:@[^\s]+)?\s+(.+)$/);
1435
+ if (!match) {
1436
+ return null;
1437
+ }
1438
+
1439
+ const tokens = match[1].split(/\s+/).filter(Boolean);
1440
+ if (tokens.length === 0) {
1441
+ return null;
1442
+ }
1443
+
1444
+ return {
1445
+ commandName: tokens[0],
1446
+ subcommand: tokens[1] || '',
1447
+ };
1448
+ }
1449
+
1450
+ function findUnsupportedCreateQuiverScripts(scripts = {}) {
1451
+ const unsupported = [];
1452
+
1453
+ for (const [scriptName, command] of Object.entries(scripts)) {
1454
+ const parsed = parseCreateQuiverScriptCommand(command);
1455
+ if (!parsed) {
1456
+ continue;
1457
+ }
1458
+
1459
+ if (!SUPPORTED_COMMAND_MODES.has(parsed.commandName)) {
1460
+ unsupported.push({
1461
+ command,
1462
+ reason: `unsupported command "${parsed.commandName}"`,
1463
+ scriptName,
1464
+ });
1465
+ continue;
1466
+ }
1467
+
1468
+ if (parsed.commandName === 'ai' && !SUPPORTED_AI_COMMANDS.has(parsed.subcommand)) {
1469
+ unsupported.push({
1470
+ command,
1471
+ reason: `unsupported ai subcommand "${parsed.subcommand || '(missing)'}"`,
1472
+ scriptName,
1473
+ });
1474
+ continue;
1475
+ }
1476
+
1477
+ if (parsed.commandName === 'spec' && !SUPPORTED_SPEC_COMMANDS.has(parsed.subcommand)) {
1478
+ unsupported.push({
1479
+ command,
1480
+ reason: `unsupported spec subcommand "${parsed.subcommand || '(missing)'}"`,
1481
+ scriptName,
1482
+ });
1483
+ continue;
1484
+ }
1485
+
1486
+ if (parsed.commandName === 'demo' && !SUPPORTED_DEMO_COMMANDS.has(parsed.subcommand)) {
1487
+ unsupported.push({
1488
+ command,
1489
+ reason: `unsupported demo subcommand "${parsed.subcommand || '(missing)'}"`,
1490
+ scriptName,
1491
+ });
1492
+ }
1493
+ }
1494
+
1495
+ return unsupported;
1496
+ }
1497
+
1498
+ function detectNodeProject(files, rootEntries, packageJson, languages) {
1499
+ const hasPackageJson = Boolean(packageJson);
1500
+ const hasJavaScriptSignals = languages.some((language) => language === 'javascript' || language === 'typescript');
1501
+ const hasSourceDirectories = detectSourceDirectories(rootEntries).length > 0;
1502
+ const hasSourceFiles = files.some((file) => /\.(?:c|m)?jsx?$/i.test(file) || /\.(?:c|m)?tsx?$/i.test(file));
1503
+
1504
+ return hasJavaScriptSignals && (hasPackageJson || hasSourceDirectories || hasSourceFiles);
1505
+ }
1506
+
856
1507
  function collectWorkspaces(packageJson) {
857
1508
  if (!packageJson) {
858
1509
  return [];
@@ -982,6 +1633,11 @@ function detectFrameworks(projectRoot, files, rootEntries, packageJson) {
982
1633
  evidence.push({ framework: 'react', signals: ['react', 'typescript files'] });
983
1634
  }
984
1635
 
1636
+ if (frameworks.length === 0 && detectNodeProject(files, rootEntries, packageJson, languages)) {
1637
+ frameworks.push('node');
1638
+ evidence.push({ framework: 'node', signals: ['package.json', 'javascript or typescript source files'] });
1639
+ }
1640
+
985
1641
  const primary = frameworks[0] || 'unknown';
986
1642
 
987
1643
  return {
@@ -1076,7 +1732,7 @@ function detectRisks(projectRoot, scan) {
1076
1732
  function buildProjectScan(projectRoot) {
1077
1733
  const packageJson = readJsonIfExists(path.join(projectRoot, 'package.json'));
1078
1734
  const rootEntries = collectRootEntries(projectRoot);
1079
- const { files, skippedPaths } = collectProjectFiles(projectRoot);
1735
+ const { files, skippedPaths, skipped_path_details } = collectProjectFiles(projectRoot);
1080
1736
  const topLevelDirectories = rootEntries.filter((entry) => entry.type === 'directory' && !entry.name.startsWith('.')).map((entry) => entry.name);
1081
1737
  const sourceDirectories = detectSourceDirectories(rootEntries);
1082
1738
  const configFiles = detectConfigFiles(rootEntries);
@@ -1134,6 +1790,7 @@ function buildProjectScan(projectRoot) {
1134
1790
  },
1135
1791
  risks: [],
1136
1792
  skipped_paths: skippedPaths,
1793
+ skipped_path_details,
1137
1794
  };
1138
1795
 
1139
1796
  scan.risks = detectRisks(projectRoot, scan);
@@ -1250,7 +1907,7 @@ function renderProjectMap(scan) {
1250
1907
  }
1251
1908
 
1252
1909
  const relevantScripts = Object.entries(scan.commands.scripts)
1253
- .filter(([name]) => /(^|:)(analyze|doctor|migrate|test|build|lint|dev|start|check)(:|$)|analyze|doctor|migrate|test|build|lint|dev|start|check/i.test(name))
1910
+ .filter(([name]) => /(^|:)(analyze|doctor|migrate|validate|test|build|lint|dev|start|check)(:|$)|analyze|doctor|migrate|validate|test|build|lint|dev|start|check/i.test(name))
1254
1911
  .slice(0, 12);
1255
1912
 
1256
1913
  if (relevantScripts.length > 0) {
@@ -1310,9 +1967,10 @@ function renderProjectMap(scan) {
1310
1967
 
1311
1968
  lines.push('');
1312
1969
  lines.push('## Skipped Paths');
1313
- if (scan.skipped_paths.length > 0) {
1314
- for (const skippedPath of scan.skipped_paths) {
1315
- lines.push(`- ${skippedPath}`);
1970
+ const skippedSummaries = summarizeSkippedPaths(scan);
1971
+ if (skippedSummaries.length > 0) {
1972
+ for (const skippedPath of skippedSummaries) {
1973
+ lines.push(`- ${skippedPath.reason}: ${skippedPath.count}`);
1316
1974
  }
1317
1975
  } else {
1318
1976
  lines.push('- None');
@@ -1320,10 +1978,8 @@ function renderProjectMap(scan) {
1320
1978
 
1321
1979
  lines.push('');
1322
1980
  lines.push('## Do Not Read First');
1323
- if (scan.skipped_paths.length > 0) {
1324
- for (const skippedPath of scan.skipped_paths) {
1325
- lines.push(`- ${skippedPath}`);
1326
- }
1981
+ if (skippedSummaries.length > 0) {
1982
+ lines.push('- Hidden, generated, secret, and cache paths are excluded from the analysis scan.');
1327
1983
  } else {
1328
1984
  lines.push('- None detected, but still prioritize docs and config files before source trees.');
1329
1985
  }
@@ -1351,11 +2007,13 @@ function runAnalyze(targetDir) {
1351
2007
 
1352
2008
  const scan = buildProjectScan(projectRoot);
1353
2009
  const artifacts = writeProjectScanArtifacts(projectRoot, scan);
2010
+ const aiContextPath = refreshAiContextDoc(projectRoot, scan);
1354
2011
  updateStateForAnalyze(projectRoot, CLI_VERSION);
1355
2012
 
1356
2013
  console.log(`Project analysis completed for ${projectRoot}`);
1357
2014
  console.log(`Wrote ${relativePosixPath(projectRoot, artifacts.jsonPath)}`);
1358
2015
  console.log(`Wrote ${relativePosixPath(projectRoot, artifacts.mdPath)}`);
2016
+ console.log(`Wrote ${relativePosixPath(projectRoot, aiContextPath)}`);
1359
2017
  console.log(`Detected primary stack: ${scan.stack.primary}`);
1360
2018
  console.log(`Detected package manager: ${scan.project.package_manager}`);
1361
2019
  }
@@ -1374,9 +2032,34 @@ function runMigrate(targetDir, options = {}) {
1374
2032
  const packageJson = loadPackageJson(projectRoot);
1375
2033
  const projectName = packageJson.name || path.basename(projectRoot) || 'Quiver Project';
1376
2034
  const packageRoot = path.resolve(__dirname, '../..');
1377
- const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'quiver-migrate-'));
1378
2035
  const legacyLayout = inspectLegacyMigrationLayout(projectRoot);
1379
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
+
1380
2063
  try {
1381
2064
  const templateRoot = packTemplate(packageRoot, tempRoot);
1382
2065
  mergeDirectoryTree(templateRoot, path.join(projectRoot, 'docs-template'));
@@ -1410,7 +2093,7 @@ function runMigrate(targetDir, options = {}) {
1410
2093
  }
1411
2094
  }
1412
2095
 
1413
- function runDoctor(targetDir) {
2096
+ function runDoctor(targetDir, options = {}) {
1414
2097
  const projectRoot = resolveTargetRoot(process.cwd(), targetDir);
1415
2098
 
1416
2099
  if (!fs.existsSync(projectRoot)) {
@@ -1421,6 +2104,17 @@ function runDoctor(targetDir) {
1421
2104
  throw new Error(formatError('doctor requires a project previously initialized by Quiver.\nRun init first: npx create-quiver --name "Project Name"'));
1422
2105
  }
1423
2106
 
2107
+ const fixPlan = buildDoctorFixPlan(projectRoot);
2108
+ if (options.fix) {
2109
+ if (options.dryRun) {
2110
+ console.log(formatDoctorFixPlan(fixPlan, { dryRun: true }));
2111
+ return;
2112
+ }
2113
+
2114
+ applyDoctorFixPlan(projectRoot, fixPlan);
2115
+ console.log(formatDoctorFixPlan(fixPlan));
2116
+ }
2117
+
1424
2118
  const doctorReport = collectDoctorReport(projectRoot);
1425
2119
  const specSlugs = doctorReport.specSlugs;
1426
2120
  const specRequiredFiles = specSlugs.flatMap((projectSlug) => [
@@ -1475,12 +2169,23 @@ function runDoctor(targetDir) {
1475
2169
  const missingNodeNativeScripts = ['quiver:migrate', 'quiver:analyze', 'quiver:doctor']
1476
2170
  .filter((name) => typeof pkg.scripts?.[name] !== 'string');
1477
2171
  const missingAiScripts = [
2172
+ 'quiver:ai:agent',
2173
+ 'quiver:ai:inspect',
2174
+ 'quiver:ai:export',
2175
+ 'quiver:ai:specs',
2176
+ 'quiver:ai:slices',
2177
+ 'quiver:ai:trace',
1478
2178
  'quiver:ai:onboard',
1479
2179
  'quiver:ai:plan',
2180
+ 'quiver:ai:review-plan',
2181
+ 'quiver:ai:approve',
2182
+ 'quiver:ai:prompt-slice',
1480
2183
  'quiver:ai:execute-slice',
2184
+ 'quiver:ai:execute-plan',
1481
2185
  'quiver:ai:pr',
1482
2186
  'quiver:ai:doctor',
1483
2187
  ].filter((name) => typeof pkg.scripts?.[name] !== 'string');
2188
+ const unsupportedCreateQuiverScripts = findUnsupportedCreateQuiverScripts(pkg.scripts || {});
1484
2189
  const hasScanArtifacts = hasProjectScanArtifact(projectRoot)
1485
2190
  && fs.existsSync(path.join(projectRoot, PROJECT_MAP_RELATIVE_PATH));
1486
2191
  const quiverState = readState(projectRoot);
@@ -1523,6 +2228,9 @@ function runDoctor(targetDir) {
1523
2228
  if (legacyOnlyScripts.length > 0) {
1524
2229
  console.log(`- Warning: legacy Bash workflow scripts detected for ${legacyOnlyScripts.join(', ')}. Run npx create-quiver migrate to add quiver:* npm scripts.`);
1525
2230
  }
2231
+ for (const script of unsupportedCreateQuiverScripts) {
2232
+ console.log(`- Warning: package.json script ${script.scriptName} targets ${script.reason}: \`${script.command}\`. Update create-quiver or regenerate scripts with npx create-quiver migrate.`);
2233
+ }
1526
2234
  for (const warning of softWarnings) {
1527
2235
  console.log(`- Warning: ${warning}`);
1528
2236
  }
@@ -1540,7 +2248,7 @@ function runDoctor(targetDir) {
1540
2248
  console.log(`- Validate a slice: npx create-quiver check-slice specs/${projectSlug}/slices/<slice-id>/slice.json`);
1541
2249
  console.log(`- Validate the PR gate: npx create-quiver check-pr specs/${projectSlug}/slices/<slice-id>/slice.json`);
1542
2250
  } else {
1543
- console.log('- Create real specs and slices only after acceptance criteria and the technical plan are approved.');
2251
+ console.log('- Create real specs and slices only after acceptance criteria are approved and the technical plan is reviewed and approved.');
1544
2252
  }
1545
2253
  }
1546
2254
 
@@ -1550,10 +2258,20 @@ function printInitNextSteps(targetDir, projectName) {
1550
2258
  console.log(`- Review AGENTS.md, then ${path.join(targetDir, 'docs', 'AI_ONBOARDING_PROMPT.md')}`);
1551
2259
  console.log(`- Review ${path.join(targetDir, 'docs', 'WORKFLOW.md')}`);
1552
2260
  console.log('- Analyze the project with npx create-quiver analyze');
1553
- console.log('- Create real specs and slices after acceptance criteria and the technical plan are approved.');
2261
+ console.log('- Create real specs and slices after acceptance criteria are approved and the technical plan is reviewed and approved.');
1554
2262
  }
1555
2263
 
1556
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
+
1557
2275
  const args = parseArgs(argv);
1558
2276
 
1559
2277
  if (args.help) {
@@ -1566,8 +2284,16 @@ async function run(argv) {
1566
2284
  return;
1567
2285
  }
1568
2286
 
2287
+ if (args.mode === 'flow') {
2288
+ await runFlow(process.cwd(), {
2289
+ json: args.json,
2290
+ });
2291
+ return;
2292
+ }
2293
+
1569
2294
  if (args.mode === 'plan') {
1570
2295
  runPlan(process.cwd(), {
2296
+ includeCompleted: args.includeCompleted,
1571
2297
  json: args.json,
1572
2298
  onlyReady: args.onlyReady,
1573
2299
  specSlug: args.specSlug,
@@ -1576,9 +2302,93 @@ async function run(argv) {
1576
2302
  return;
1577
2303
  }
1578
2304
 
2305
+ if (args.mode === 'prepare') {
2306
+ await runPrepare(process.cwd(), {
2307
+ dryRun: args.dryRun,
2308
+ identityFile: args.aiIdentityFile || undefined,
2309
+ provider: args.prepareProvider || undefined,
2310
+ sshHostAlias: args.aiSshHostAlias || undefined,
2311
+ });
2312
+ return;
2313
+ }
2314
+
1579
2315
  if (args.mode === 'ai') {
1580
2316
  if (!args.aiCommand) {
1581
- throw new Error(formatError('missing ai subcommand. Use: npx create-quiver ai onboard | plan | execute-slice | 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;
2380
+ }
2381
+
2382
+ if (args.aiCommand === 'agent') {
2383
+ runAiAgent(process.cwd(), {
2384
+ command: args.aiAgentCommand,
2385
+ context: args.aiContext || undefined,
2386
+ label: args.aiLabel || undefined,
2387
+ model: args.aiModel || undefined,
2388
+ provider: args.aiProviderExplicit ? args.aiProvider : undefined,
2389
+ role: args.aiAgentRole || undefined,
2390
+ });
2391
+ return;
1582
2392
  }
1583
2393
 
1584
2394
  if (args.aiCommand === 'onboard') {
@@ -1586,32 +2396,93 @@ async function run(argv) {
1586
2396
  context: args.aiContext || undefined,
1587
2397
  dryRun: args.dryRun,
1588
2398
  input: args.aiInput || undefined,
2399
+ printPrompt: args.aiPrintPrompt,
1589
2400
  provider: args.aiProvider,
2401
+ providerExplicit: args.aiProviderExplicit,
1590
2402
  role: args.aiRole,
1591
2403
  timeout: args.aiTimeout,
1592
2404
  });
1593
2405
  return;
1594
2406
  }
1595
2407
 
2408
+ if (args.aiCommand === 'prepare-context') {
2409
+ await runAiPrepareContext(process.cwd(), {
2410
+ dryRun: args.dryRun,
2411
+ runId: args.aiRunId || undefined,
2412
+ });
2413
+ return;
2414
+ }
2415
+
1596
2416
  if (args.aiCommand === 'plan') {
1597
2417
  await runAiPlan(process.cwd(), {
1598
2418
  context: args.aiContext || undefined,
1599
2419
  dryRun: args.dryRun,
1600
2420
  input: args.aiInput || undefined,
1601
2421
  phase: args.aiPhase,
2422
+ printPrompt: args.aiPrintPrompt,
1602
2423
  provider: args.aiProvider,
2424
+ providerExplicit: args.aiProviderExplicit,
1603
2425
  role: args.aiRole,
2426
+ runId: args.aiRunId || undefined,
1604
2427
  specSlug: args.specSlug || undefined,
1605
2428
  timeout: args.aiTimeout,
1606
2429
  });
1607
2430
  return;
1608
2431
  }
1609
2432
 
2433
+ if (args.aiCommand === 'review-plan') {
2434
+ await runAiReviewPlan(process.cwd(), {
2435
+ context: args.aiContext || undefined,
2436
+ dryRun: args.dryRun,
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,
2453
+ provider: args.aiProvider,
2454
+ providerExplicit: args.aiProviderExplicit,
2455
+ role: args.aiRole,
2456
+ runId: args.aiRunId || undefined,
2457
+ timeout: args.aiTimeout,
2458
+ });
2459
+ return;
2460
+ }
2461
+
2462
+ if (args.aiCommand === 'approve') {
2463
+ await runAiApprove(process.cwd(), {
2464
+ dryRun: args.dryRun,
2465
+ input: args.aiInput || undefined,
2466
+ phase: args.aiPhase,
2467
+ runId: args.aiRunId || undefined,
2468
+ version: args.aiVersion || undefined,
2469
+ });
2470
+ return;
2471
+ }
2472
+
2473
+ if (args.aiCommand === 'approvals' || args.aiCommand === 'approval-status') {
2474
+ await runAiApprovalStatus(process.cwd());
2475
+ return;
2476
+ }
2477
+
1610
2478
  if (args.aiCommand === 'execute-slice') {
1611
2479
  await runAiExecuteSlice(process.cwd(), {
2480
+ allowDirty: args.aiAllowDirty,
2481
+ commit: args.aiCommit,
1612
2482
  context: args.aiContext || undefined,
1613
2483
  dryRun: args.dryRun,
1614
2484
  provider: args.aiProvider,
2485
+ providerExplicit: args.aiProviderExplicit,
1615
2486
  role: args.aiRole,
1616
2487
  slice: args.aiSlice || undefined,
1617
2488
  timeout: args.aiTimeout,
@@ -1619,6 +2490,31 @@ async function run(argv) {
1619
2490
  return;
1620
2491
  }
1621
2492
 
2493
+ if (args.aiCommand === 'prompt-slice' || args.aiCommand === 'executor-prompt') {
2494
+ runAiPromptSlice(process.cwd(), {
2495
+ slice: args.aiSlice || undefined,
2496
+ });
2497
+ return;
2498
+ }
2499
+
2500
+ if (args.aiCommand === 'execute-plan') {
2501
+ await runAiExecutePlan(process.cwd(), {
2502
+ allowDirty: args.aiAllowDirty,
2503
+ commit: args.aiCommit,
2504
+ context: args.aiContext || undefined,
2505
+ dryRun: args.dryRun,
2506
+ execute: args.aiExecute,
2507
+ json: args.json,
2508
+ mode: args.aiExecutionMode,
2509
+ provider: args.aiProvider,
2510
+ providerExplicit: args.aiProviderExplicit,
2511
+ role: args.aiRole,
2512
+ specSlug: args.specSlug || undefined,
2513
+ timeout: args.aiTimeout,
2514
+ });
2515
+ return;
2516
+ }
2517
+
1622
2518
  if (args.aiCommand === 'doctor') {
1623
2519
  await runAiDoctor(process.cwd(), {
1624
2520
  dryRun: args.dryRun,
@@ -1631,23 +2527,29 @@ async function run(argv) {
1631
2527
 
1632
2528
  if (args.aiCommand === 'pr') {
1633
2529
  await runAiPr(process.cwd(), {
2530
+ baseBranch: args.aiBaseBranch,
2531
+ create: args.aiCreate,
1634
2532
  dryRun: args.dryRun,
2533
+ input: args.aiInput || undefined,
1635
2534
  remote: args.aiRemote || undefined,
1636
2535
  sshHostAlias: args.aiSshHostAlias || undefined,
1637
2536
  identityFile: args.aiIdentityFile || undefined,
2537
+ title: args.aiTitle || undefined,
1638
2538
  });
1639
2539
  return;
1640
2540
  }
1641
2541
 
1642
- throw new Error(formatError(`unsupported ai subcommand: ${args.aiCommand}. Supported tasks: onboard, plan, execute-slice, 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`));
1643
2543
  }
1644
2544
 
1645
2545
  if (args.mode === 'graph') {
1646
2546
  runGraph(process.cwd(), {
1647
2547
  format: args.format,
2548
+ includeCompleted: args.includeCompleted,
1648
2549
  json: args.json,
1649
2550
  level: args.level,
1650
2551
  showConflicts: args.showConflicts,
2552
+ specSlug: args.specSlug,
1651
2553
  unicode: args.unicode,
1652
2554
  });
1653
2555
  return;
@@ -1657,19 +2559,48 @@ async function run(argv) {
1657
2559
  await runNext(process.cwd(), {
1658
2560
  allReady: args.allReady,
1659
2561
  autoStart: args.autoStart,
2562
+ includeCompleted: args.includeCompleted,
1660
2563
  json: args.json,
1661
2564
  specSlug: args.specSlug,
1662
2565
  });
1663
2566
  return;
1664
2567
  }
1665
2568
 
2569
+ if (args.mode === 'evidence') {
2570
+ const result = runEvidence(process.cwd(), {
2571
+ command: args.evidenceArgs,
2572
+ maxOutput: args.evidenceMaxOutput || undefined,
2573
+ output: args.evidenceOutput || undefined,
2574
+ subcommand: args.evidenceCommand,
2575
+ });
2576
+ process.exitCode = result.exitCode;
2577
+ return;
2578
+ }
2579
+
2580
+ if (args.mode === 'demo') {
2581
+ const demoTarget = resolveTargetRoot(process.cwd(), args.targetDirExplicit ? args.targetDir : 'quiver-spec-viewer');
2582
+ runDemo({
2583
+ command: args.demoCommand,
2584
+ demo: args.demoName,
2585
+ dryRun: args.dryRun,
2586
+ targetRoot: demoTarget,
2587
+ });
2588
+ return;
2589
+ }
2590
+
1666
2591
  if (args.mode === 'migrate') {
1667
- runMigrate(args.targetDir, { skipInstall: args.skipInstall });
2592
+ runMigrate(args.targetDir, {
2593
+ dryRun: args.dryRun,
2594
+ skipInstall: args.skipInstall,
2595
+ });
1668
2596
  return;
1669
2597
  }
1670
2598
 
1671
2599
  if (args.mode === 'doctor') {
1672
- runDoctor(args.targetDir);
2600
+ runDoctor(args.targetDir, {
2601
+ dryRun: args.dryRun,
2602
+ fix: args.doctorFix,
2603
+ });
1673
2604
  return;
1674
2605
  }
1675
2606
 
@@ -1680,7 +2611,10 @@ async function run(argv) {
1680
2611
 
1681
2612
  if (args.mode === 'check-slice') {
1682
2613
  checkSliceReadiness(args.targetDir, {
2614
+ baseBranch: args.baseBranchExplicit ? args.aiBaseBranch : '',
1683
2615
  gate: args.gate,
2616
+ local: args.checkSliceLocal,
2617
+ remote: args.aiRemote,
1684
2618
  strictOverlap: args.strictOverlap,
1685
2619
  });
1686
2620
  return;
@@ -1695,10 +2629,10 @@ async function run(argv) {
1695
2629
  const repoRoot = process.cwd();
1696
2630
  const handoffInput = args.targetDir;
1697
2631
  if (!handoffInput || handoffInput === '.') {
1698
- 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'));
1699
2633
  }
1700
2634
  const resolved = checkHandoff(handoffInput, repoRoot);
1701
- console.log(`PASS: Handoff validated at ${resolved.relativePath}`);
2635
+ console.log(`PASS: ${resolved.label} validated at ${resolved.relativePath}`);
1702
2636
  return;
1703
2637
  }
1704
2638
 
@@ -1731,6 +2665,49 @@ async function run(argv) {
1731
2665
  return;
1732
2666
  }
1733
2667
 
2668
+ if (args.mode === 'spec') {
2669
+ if (args.specCommand === 'create') {
2670
+ runCreateSpec(process.cwd(), {
2671
+ dryRun: args.dryRun,
2672
+ input: args.aiInput || undefined,
2673
+ specSlug: args.specSlug || undefined,
2674
+ });
2675
+ return;
2676
+ }
2677
+
2678
+ if (!args.targetDir || args.targetDir === '.') {
2679
+ throw new Error(formatError('missing spec directory. Use: npx create-quiver spec <start|status|close> <spec-dir>'));
2680
+ }
2681
+
2682
+ if (args.specCommand === 'start') {
2683
+ const report = startSpecWorktree(process.cwd(), args.targetDir, {
2684
+ dryRun: args.dryRun,
2685
+ });
2686
+ process.stdout.write(formatSpecStartResult(report));
2687
+ return;
2688
+ }
2689
+
2690
+ if (args.specCommand === 'status') {
2691
+ const report = buildSpecStatus(process.cwd(), args.targetDir);
2692
+ process.stdout.write(formatSpecStatus(report));
2693
+ return;
2694
+ }
2695
+
2696
+ if (args.specCommand === 'close') {
2697
+ const report = closeSpecWorktree(process.cwd(), args.targetDir, {
2698
+ baseBranch: args.aiBaseBranch,
2699
+ discard: args.discard,
2700
+ dryRun: args.dryRun,
2701
+ force: args.force,
2702
+ remote: args.aiRemote,
2703
+ });
2704
+ process.stdout.write(formatSpecCloseResult(report));
2705
+ return;
2706
+ }
2707
+
2708
+ throw new Error(formatError(`unsupported spec subcommand: ${args.specCommand}. Supported tasks: create, start, status, close`));
2709
+ }
2710
+
1734
2711
  const packageRoot = path.resolve(__dirname, '../..');
1735
2712
  const targetDir = resolveTargetRoot(process.cwd(), args.targetDir);
1736
2713
  const projectName = args.projectName || path.basename(targetDir) || 'Quiver Project';
@@ -1785,6 +2762,8 @@ async function run(argv) {
1785
2762
  module.exports = {
1786
2763
  runAnalyze,
1787
2764
  runDoctor,
2765
+ runFlow,
1788
2766
  runMigrate,
2767
+ runPrepare,
1789
2768
  run,
1790
2769
  };