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
@@ -0,0 +1,27 @@
1
+ function formatActionableError({ failure, impact, fix, nextCommand } = {}) {
2
+ const lines = [`create-quiver: ${String(failure || 'operation failed').trim()}`];
3
+
4
+ if (impact) {
5
+ lines.push(`Impact: ${String(impact).trim()}`);
6
+ }
7
+ if (fix) {
8
+ lines.push(`Fix: ${String(fix).trim()}`);
9
+ }
10
+ if (nextCommand) {
11
+ lines.push(`Next command: ${String(nextCommand).trim()}`);
12
+ }
13
+
14
+ return lines.join('\n');
15
+ }
16
+
17
+ function createActionableError(code, fields = {}, details = {}) {
18
+ const error = new Error(formatActionableError(fields));
19
+ error.code = code;
20
+ error.details = details;
21
+ return error;
22
+ }
23
+
24
+ module.exports = {
25
+ createActionableError,
26
+ formatActionableError,
27
+ };
@@ -0,0 +1,148 @@
1
+ const fs = require('node:fs');
2
+ const path = require('node:path');
3
+
4
+ const { assertSupportedProvider, formatProviderList } = require('./ai/providers');
5
+ const { quiverInternalPaths } = require('./init-layout');
6
+
7
+ const AGENT_PROFILE_ROLES = Object.freeze(['planner', 'executor', 'reviewer', 'doctor']);
8
+ const PROFILE_STATE_VERSION = 1;
9
+
10
+ function formatError(message) {
11
+ return `create-quiver: ${message}`;
12
+ }
13
+
14
+ function agentProfilesPath(projectRoot) {
15
+ return path.join(quiverInternalPaths(projectRoot).root, 'agents', 'profiles.json');
16
+ }
17
+
18
+ function normalizeAgentProfileRole(role) {
19
+ const normalized = String(role || '').trim().toLowerCase();
20
+ if (!AGENT_PROFILE_ROLES.includes(normalized)) {
21
+ throw new Error(formatError(`unsupported agent profile role '${role}'. Expected one of: ${AGENT_PROFILE_ROLES.join(', ')}`));
22
+ }
23
+ return normalized;
24
+ }
25
+
26
+ function normalizeOptionalText(value, fieldName) {
27
+ if (value === undefined || value === null) {
28
+ return '';
29
+ }
30
+
31
+ const normalized = String(value).trim();
32
+ if (normalized.length > 160) {
33
+ throw new Error(formatError(`agent profile ${fieldName} is too long`));
34
+ }
35
+
36
+ assertNotSecretLike(normalized, fieldName);
37
+ return normalized;
38
+ }
39
+
40
+ function assertNotSecretLike(value, fieldName) {
41
+ const text = String(value || '');
42
+ const secretPatterns = [
43
+ /-----BEGIN [A-Z ]*PRIVATE KEY-----/,
44
+ /\bsk-[A-Za-z0-9_-]{16,}\b/,
45
+ /\bghp_[A-Za-z0-9_]{16,}\b/,
46
+ /\bgithub_pat_[A-Za-z0-9_]{16,}\b/,
47
+ /\bxox[baprs]-[A-Za-z0-9-]{16,}\b/,
48
+ ];
49
+
50
+ if (secretPatterns.some((pattern) => pattern.test(text))) {
51
+ throw new Error(formatError(`agent profile ${fieldName} looks like a secret; store provider credentials in the provider CLI, not in Quiver profiles`));
52
+ }
53
+ }
54
+
55
+ function emptyProfilesState() {
56
+ return {
57
+ version: PROFILE_STATE_VERSION,
58
+ profiles: {},
59
+ };
60
+ }
61
+
62
+ function readAgentProfiles(projectRoot) {
63
+ const filePath = agentProfilesPath(projectRoot);
64
+ if (!fs.existsSync(filePath)) {
65
+ return emptyProfilesState();
66
+ }
67
+
68
+ const state = JSON.parse(fs.readFileSync(filePath, 'utf8'));
69
+ return {
70
+ version: state.version || PROFILE_STATE_VERSION,
71
+ profiles: state.profiles && typeof state.profiles === 'object' ? state.profiles : {},
72
+ };
73
+ }
74
+
75
+ function writeAgentProfiles(projectRoot, state) {
76
+ const filePath = agentProfilesPath(projectRoot);
77
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
78
+ fs.writeFileSync(filePath, `${JSON.stringify(state, null, 2)}\n`);
79
+ return filePath;
80
+ }
81
+
82
+ function getAgentProfile(projectRoot, role) {
83
+ const normalizedRole = normalizeAgentProfileRole(role);
84
+ const state = readAgentProfiles(projectRoot);
85
+ return state.profiles[normalizedRole] || null;
86
+ }
87
+
88
+ function listAgentProfiles(projectRoot) {
89
+ const state = readAgentProfiles(projectRoot);
90
+ return AGENT_PROFILE_ROLES.map((role) => ({
91
+ role,
92
+ configured: Boolean(state.profiles[role]),
93
+ profile: state.profiles[role] || null,
94
+ }));
95
+ }
96
+
97
+ function setAgentProfile(projectRoot, role, options = {}) {
98
+ const normalizedRole = normalizeAgentProfileRole(role);
99
+ const provider = assertSupportedProvider(options.provider);
100
+ const model = normalizeOptionalText(options.model, 'model');
101
+ const label = normalizeOptionalText(options.label, 'label');
102
+ const context = normalizeOptionalText(options.context, 'context');
103
+ const state = readAgentProfiles(projectRoot);
104
+ const current = state.profiles[normalizedRole] || {};
105
+ const now = new Date().toISOString();
106
+ const profile = {
107
+ role: normalizedRole,
108
+ provider,
109
+ model: model || current.model || '',
110
+ label: label || current.label || '',
111
+ context: context || current.context || '',
112
+ updated_at: now,
113
+ };
114
+
115
+ state.version = PROFILE_STATE_VERSION;
116
+ state.profiles = {
117
+ ...state.profiles,
118
+ [normalizedRole]: profile,
119
+ };
120
+ state.updated_at = now;
121
+
122
+ const filePath = writeAgentProfiles(projectRoot, state);
123
+ return {
124
+ filePath,
125
+ profile,
126
+ };
127
+ }
128
+
129
+ function resolveProfileProvider(projectRoot, role, fallbackProvider) {
130
+ const profile = getAgentProfile(projectRoot, role);
131
+ if (profile?.provider) {
132
+ return assertSupportedProvider(profile.provider);
133
+ }
134
+ return assertSupportedProvider(fallbackProvider);
135
+ }
136
+
137
+ module.exports = {
138
+ AGENT_PROFILE_ROLES,
139
+ PROFILE_STATE_VERSION,
140
+ agentProfilesPath,
141
+ formatProviderList,
142
+ getAgentProfile,
143
+ listAgentProfiles,
144
+ normalizeAgentProfileRole,
145
+ readAgentProfiles,
146
+ resolveProfileProvider,
147
+ setAgentProfile,
148
+ };
@@ -44,6 +44,17 @@ const DEFAULT_CONTEXT_PACK_BY_ROLE = Object.freeze({
44
44
  });
45
45
 
46
46
  const PACK_ORDER = ['full', 'planning', 'slice', 'minimal'];
47
+ const CONTEXT_PREPARED_DOC_PATHS = Object.freeze([
48
+ 'docs/INDEX.md',
49
+ 'docs/PROJECT_MAP.md',
50
+ 'docs/AI_CONTEXT.md',
51
+ 'docs/AI_ONBOARDING_PROMPT.md',
52
+ 'docs/CONTEXTO.md',
53
+ 'docs/WORKFLOW.md',
54
+ 'docs/ARCHITECTURE.md',
55
+ 'docs/STATUS.md',
56
+ 'docs/DECISIONS.md',
57
+ ]);
47
58
 
48
59
  function normalizeRole(role) {
49
60
  const value = String(role || '').trim().toLowerCase();
@@ -66,6 +77,10 @@ function getDefaultContextPack(role) {
66
77
  return DEFAULT_CONTEXT_PACK_BY_ROLE[normalizedRole];
67
78
  }
68
79
 
80
+ function getPreparedContextDocPaths() {
81
+ return CONTEXT_PREPARED_DOC_PATHS.slice();
82
+ }
83
+
69
84
  function resolveContextPack({ role, packName } = {}) {
70
85
  const normalizedRole = normalizeRole(role);
71
86
  const defaultPack = getDefaultContextPack(normalizedRole);
@@ -148,6 +163,7 @@ module.exports = {
148
163
  ROLES,
149
164
  buildContextPackMetadata,
150
165
  buildPackSelection,
166
+ getPreparedContextDocPaths,
151
167
  getDefaultContextPack,
152
168
  normalizePackName,
153
169
  normalizeRole,
@@ -1,19 +1,43 @@
1
+ const fs = require('node:fs');
2
+ const path = require('node:path');
3
+
4
+ const { resolveProfileProvider } = require('../agent-profiles');
5
+ const { branchDelete, runGit, statusPorcelain, worktreeAdd, worktreePrune, worktreeRemove } = require('../git');
6
+ const { safeBranchName, worktreesRootForRepo } = require('../slice');
1
7
  const { buildGraph, computeLevels, detectFileConflicts, isFoundationSliceId, readAllSlices, topoSort, SliceGraphError } = require('../slice-graph');
8
+ const { runExecuteSlice } = require('./executor');
2
9
 
3
10
  const EXCLUDED_STATUSES = new Set(['completed', 'skipped', 'cancelled']);
11
+ const EXECUTION_MODES = new Set(['auto', 'manual', 'delegated']);
4
12
 
5
13
  function formatError(message) {
6
14
  return `create-quiver: ${message}`;
7
15
  }
8
16
 
9
- function summarizeSlice(node) {
17
+ function toRelativePath(repoRoot, filePath) {
18
+ return path.relative(repoRoot, filePath).split(path.sep).join('/');
19
+ }
20
+
21
+ function normalizeExecutionMode(mode) {
22
+ const value = String(mode || 'auto').trim().toLowerCase() || 'auto';
23
+ if (!EXECUTION_MODES.has(value)) {
24
+ throw new Error(formatError(`unsupported execution mode: ${mode}. Use auto, manual, or delegated.`));
25
+ }
26
+ return value;
27
+ }
28
+
29
+ function summarizeSlice(node, repoRoot) {
10
30
  return {
11
31
  ref: node.ref,
12
32
  spec_slug: node.specSlug,
13
33
  slice_id: node.sliceId,
34
+ slice_path: node.slicePath ? toRelativePath(repoRoot, node.slicePath) : '',
14
35
  title: node.title || node.sliceId,
15
36
  status: node.status || 'draft',
16
37
  files: Array.isArray(node.files) ? node.files : [],
38
+ expected_read_paths: Array.isArray(node.expected_read_paths) ? node.expected_read_paths : [],
39
+ allowed_write_paths: Array.isArray(node.allowed_write_paths) ? node.allowed_write_paths : [],
40
+ validation_hints: Array.isArray(node.validation_hints) ? node.validation_hints : [],
17
41
  depends_on: Array.isArray(node.depends_on) ? node.depends_on : [],
18
42
  parallel_safe: node.parallel_safe || null,
19
43
  parallel_safe_reason: node.parallel_safe_reason || null,
@@ -92,8 +116,18 @@ function buildPendingGraph(graph, options = {}) {
92
116
  };
93
117
  }
94
118
 
95
- function buildLevelStrategy(levelNodes) {
96
- if (levelNodes.length > 1) {
119
+ function buildFallbackReason({ conflicts, unknownScopeSlices }) {
120
+ if (unknownScopeSlices.length > 0) {
121
+ return `Unknown file scope: ${unknownScopeSlices.join(', ')}`;
122
+ }
123
+ if (conflicts.length > 0) {
124
+ return `File conflicts: ${conflicts.map((conflict) => conflict.slices.join(', ')).join('; ')}`;
125
+ }
126
+ return '';
127
+ }
128
+
129
+ function buildLevelStrategy(levelNodes, { parallelReady, conflicts, unknownScopeSlices }) {
130
+ if (parallelReady) {
97
131
  return {
98
132
  mode: 'temporary-per-slice',
99
133
  temporary_worktrees: true,
@@ -101,6 +135,14 @@ function buildLevelStrategy(levelNodes) {
101
135
  };
102
136
  }
103
137
 
138
+ if (levelNodes.length > 1) {
139
+ return {
140
+ mode: 'sequential-fallback',
141
+ temporary_worktrees: false,
142
+ reason: buildFallbackReason({ conflicts, unknownScopeSlices }) || 'Run sequentially because this level is not parallel-ready.',
143
+ };
144
+ }
145
+
104
146
  return {
105
147
  mode: 'shared-worktree',
106
148
  temporary_worktrees: false,
@@ -108,21 +150,45 @@ function buildLevelStrategy(levelNodes) {
108
150
  };
109
151
  }
110
152
 
111
- function summarizeLevel(levelNodes, index) {
112
- const slices = levelNodes.map(summarizeSlice);
153
+ function buildExecutionGroups(slices, parallelReady, fallbackReason) {
154
+ if (parallelReady) {
155
+ return [{
156
+ mode: 'parallel',
157
+ reason: 'No file-scope conflicts detected.',
158
+ slice_refs: slices.map((slice) => slice.ref),
159
+ }];
160
+ }
161
+
162
+ return slices.map((slice) => ({
163
+ mode: 'sequential',
164
+ reason: fallbackReason || 'Sequential execution is the safe default.',
165
+ slice_refs: [slice.ref],
166
+ }));
167
+ }
168
+
169
+ function summarizeLevel(levelNodes, index, repoRoot) {
170
+ const slices = levelNodes.map((node) => summarizeSlice(node, repoRoot));
113
171
  const sliceRefs = slices.map((slice) => slice.ref);
114
172
  const conflicts = detectFileConflicts(levelNodes).map((group) => ({
115
173
  files: group.files,
116
174
  slices: group.slices,
117
175
  }));
176
+ const unknownScopeSlices = slices
177
+ .filter((slice) => !Array.isArray(slice.files) || slice.files.length === 0)
178
+ .map((slice) => slice.ref);
179
+ const fallbackReason = buildFallbackReason({ conflicts, unknownScopeSlices });
180
+ const parallelReady = levelNodes.length > 1 && conflicts.length === 0 && unknownScopeSlices.length === 0;
118
181
 
119
182
  return {
120
183
  index,
121
184
  slice_refs: sliceRefs,
122
- parallel_ready: levelNodes.length > 1,
123
- requires_temporary_worktrees: levelNodes.length > 1,
124
- worktree_strategy: buildLevelStrategy(levelNodes),
185
+ parallel_ready: parallelReady,
186
+ requires_temporary_worktrees: parallelReady,
187
+ worktree_strategy: buildLevelStrategy(levelNodes, { parallelReady, conflicts, unknownScopeSlices }),
125
188
  conflicts,
189
+ unknown_scope_slices: unknownScopeSlices,
190
+ fallback_reason: fallbackReason || null,
191
+ execution_groups: buildExecutionGroups(slices, parallelReady, fallbackReason),
126
192
  slices,
127
193
  };
128
194
  }
@@ -153,7 +219,7 @@ function collectExecutionPlan(repoRoot, options = {}) {
153
219
  }
154
220
 
155
221
  const readyLevels = computeLevels(pendingGraph);
156
- const readyLevelReports = readyLevels.map((levelNodes, index) => summarizeLevel(levelNodes, index));
222
+ const readyLevelReports = readyLevels.map((levelNodes, index) => summarizeLevel(levelNodes, index, repoRoot));
157
223
  const executionOrder = topoSort(pendingGraph).map((node) => node.ref);
158
224
  const integrationOrder = readyLevelReports.flatMap((level) => level.slice_refs);
159
225
  const foundationRefs = pendingGraph.foundationRefs;
@@ -210,12 +276,16 @@ function formatHumanExecutionPlan(report) {
210
276
  }
211
277
 
212
278
  for (const level of report.ready_levels) {
213
- const modeLabel = level.parallel_ready ? 'parallel' : 'sequential';
214
- lines.push(`Level ${level.index} (${modeLabel})`);
279
+ const modeLabel = level.parallel_ready ? 'parallel-ready' : 'sequential';
280
+ lines.push(`Wave ${level.index} (${modeLabel})`);
215
281
  lines.push(`Worktree strategy: ${level.worktree_strategy.mode}`);
282
+ if (level.fallback_reason) {
283
+ lines.push(`Fallback: ${level.fallback_reason}`);
284
+ }
216
285
 
217
286
  for (const slice of level.slices) {
218
287
  lines.push(`- ${slice.ref} [${slice.status}]`);
288
+ lines.push(` parallel_safe: ${slice.parallel_safe || 'unspecified'}${slice.parallel_safe_reason ? ` (${slice.parallel_safe_reason})` : ''}`);
219
289
  }
220
290
 
221
291
  if (level.conflicts.length > 0) {
@@ -225,6 +295,13 @@ function formatHumanExecutionPlan(report) {
225
295
  }
226
296
  }
227
297
 
298
+ if (level.unknown_scope_slices.length > 0) {
299
+ lines.push('Unknown scope:');
300
+ for (const ref of level.unknown_scope_slices) {
301
+ lines.push(`- ${ref}`);
302
+ }
303
+ }
304
+
228
305
  lines.push('');
229
306
  }
230
307
 
@@ -236,6 +313,292 @@ function formatHumanExecutionPlan(report) {
236
313
  return `${lines.join('\n')}\n`;
237
314
  }
238
315
 
316
+ function formatExecutePlanDryRun(report, options = {}) {
317
+ const provider = options.resolvedProvider || options.provider || 'codex';
318
+ const commitEnabled = options.commit === true;
319
+ const executionMode = normalizeExecutionMode(options.mode || options.executionMode);
320
+ const lines = [
321
+ 'AI execute-plan dry-run',
322
+ `Execution mode: ${executionMode}`,
323
+ `Provider: ${provider}`,
324
+ `Commit after each slice: ${commitEnabled ? 'enabled' : 'disabled'}`,
325
+ `Total slices: ${report.summary.total_slices}`,
326
+ '',
327
+ 'Waves',
328
+ ];
329
+
330
+ const commandForSlice = (slice) => {
331
+ const parts = [
332
+ 'npx create-quiver ai execute-slice',
333
+ `--slice ${JSON.stringify(slice.slice_path)}`,
334
+ `--provider ${provider}`,
335
+ ];
336
+ if (commitEnabled) {
337
+ parts.push('--commit');
338
+ }
339
+ return parts.join(' ');
340
+ };
341
+ const promptCommandForSlice = (slice) => [
342
+ 'npx create-quiver ai prompt-slice',
343
+ `--slice ${JSON.stringify(slice.slice_path)}`,
344
+ '--dry-run',
345
+ ].join(' ');
346
+
347
+ for (const level of report.ready_levels) {
348
+ lines.push(`Wave ${level.index}: ${level.parallel_ready ? 'parallel-ready' : 'sequential'}`);
349
+ lines.push(`Workspace strategy: ${level.worktree_strategy.mode}`);
350
+ if (level.fallback_reason) {
351
+ lines.push(`Fallback: ${level.fallback_reason}`);
352
+ }
353
+ for (const group of level.execution_groups) {
354
+ lines.push(`Group: ${group.mode}`);
355
+ for (const ref of group.slice_refs) {
356
+ const slice = level.slices.find((item) => item.ref === ref);
357
+ lines.push(`- Prompt: ${promptCommandForSlice(slice)}`);
358
+ if (executionMode !== 'manual') {
359
+ lines.push(` Execute: ${commandForSlice(slice)}`);
360
+ }
361
+ }
362
+ }
363
+ }
364
+
365
+ return `${lines.join('\n')}\n`;
366
+ }
367
+
368
+ function buildRecoveryGuidance(ref, workspaces = []) {
369
+ const lines = [
370
+ 'Recovery:',
371
+ `- Retry slice: npx create-quiver ai prompt-slice --slice <slice.json> --dry-run, then rerun only ${ref}.`,
372
+ '- Abort: inspect the active checkout and temporary worktrees before reverting, stashing, or removing anything.',
373
+ ];
374
+
375
+ if (workspaces.length > 0) {
376
+ lines.push('- Temporary worktrees left for inspection:');
377
+ for (const workspace of workspaces) {
378
+ lines.push(` - ${workspace.worktreePath}`);
379
+ }
380
+ }
381
+
382
+ return lines.join('\n');
383
+ }
384
+
385
+ function appendRecovery(error, ref, workspaces = []) {
386
+ const message = error && error.message ? error.message : String(error);
387
+ if (message.includes('Recovery:')) {
388
+ return error;
389
+ }
390
+
391
+ const wrapped = new Error(`${message}\n\n${buildRecoveryGuidance(ref, workspaces)}`);
392
+ wrapped.cause = error;
393
+ wrapped.code = error && error.code ? error.code : undefined;
394
+ wrapped.details = error && error.details ? error.details : undefined;
395
+ return wrapped;
396
+ }
397
+
398
+ function ensureCleanIntegrationWorktree(repoRoot) {
399
+ const status = statusPorcelain(repoRoot);
400
+ if (status !== '') {
401
+ throw new Error(formatError(`delegated parallel execution requires a clean active worktree before integration. Dirty files: ${status.split('\n').join(', ')}`));
402
+ }
403
+ }
404
+
405
+ function buildDelegatedRunId() {
406
+ return new Date().toISOString().replace(/[^0-9A-Za-z]/g, '');
407
+ }
408
+
409
+ function buildDelegatedWorkspace(repoRoot, slice, runId, index, options = {}) {
410
+ const safeRef = safeBranchName(slice.ref).slice(0, 80);
411
+ const branchName = `quiver-exec-${runId}-${index + 1}-${safeRef}`;
412
+ const worktreesRoot = options.worktreesRoot || path.join(worktreesRootForRepo(repoRoot, branchName), 'execute-plan');
413
+ const worktreePath = path.join(worktreesRoot, runId, safeRef);
414
+
415
+ return {
416
+ branchName,
417
+ ref: slice.ref,
418
+ slice,
419
+ worktreePath,
420
+ };
421
+ }
422
+
423
+ function createDelegatedWorkspace(repoRoot, workspace, baseRef) {
424
+ if (fs.existsSync(workspace.worktreePath)) {
425
+ throw new Error(formatError(`temporary worktree path already exists: ${workspace.worktreePath}`));
426
+ }
427
+
428
+ fs.mkdirSync(path.dirname(workspace.worktreePath), { recursive: true });
429
+ worktreeAdd(repoRoot, workspace.worktreePath, baseRef, { branch: workspace.branchName });
430
+ }
431
+
432
+ function cleanupDelegatedWorkspace(repoRoot, workspace) {
433
+ try {
434
+ worktreeRemove(repoRoot, workspace.worktreePath);
435
+ } catch {
436
+ // Keep cleanup best-effort after successful integration.
437
+ }
438
+ try {
439
+ branchDelete(repoRoot, workspace.branchName, true);
440
+ } catch {
441
+ // The committed changes were already integrated; a leftover temp branch is non-blocking.
442
+ }
443
+ }
444
+
445
+ async function runSequentialGroup(repoRoot, level, group, options = {}) {
446
+ const runSlice = options.runExecuteSliceFn || runExecuteSlice;
447
+ const results = [];
448
+
449
+ for (const ref of group.slice_refs) {
450
+ const slice = level.slices.find((item) => item.ref === ref);
451
+ try {
452
+ const result = await runSlice(repoRoot, {
453
+ allowDirty: options.allowDirty === true,
454
+ commit: true,
455
+ context: options.context,
456
+ dryRun: false,
457
+ provider: options.provider,
458
+ providerExplicit: options.providerExplicit,
459
+ role: options.role,
460
+ slice: slice.slice_path,
461
+ skipWorktreeBranchCheck: true,
462
+ timeout: options.timeout,
463
+ });
464
+ results.push({
465
+ level: level.index,
466
+ mode: 'sequential',
467
+ ref,
468
+ ok: true,
469
+ result,
470
+ workspace: repoRoot,
471
+ });
472
+ } catch (error) {
473
+ throw appendRecovery(error, ref);
474
+ }
475
+ }
476
+
477
+ return results;
478
+ }
479
+
480
+ async function runParallelGroupInWorktrees(repoRoot, level, group, options = {}) {
481
+ ensureCleanIntegrationWorktree(repoRoot);
482
+
483
+ const runSlice = options.runExecuteSliceFn || runExecuteSlice;
484
+ const baseRef = runGit(['rev-parse', 'HEAD'], repoRoot);
485
+ const runId = options.runId || buildDelegatedRunId();
486
+ const slices = group.slice_refs.map((ref) => level.slices.find((item) => item.ref === ref));
487
+ const workspaces = slices.map((slice, index) => buildDelegatedWorkspace(repoRoot, slice, runId, index, options));
488
+
489
+ let runResults;
490
+ try {
491
+ worktreePrune(repoRoot);
492
+ for (const workspace of workspaces) {
493
+ createDelegatedWorkspace(repoRoot, workspace, baseRef);
494
+ }
495
+
496
+ runResults = await Promise.all(workspaces.map(async (workspace) => {
497
+ const result = await runSlice(workspace.worktreePath, {
498
+ allowDirty: false,
499
+ commit: true,
500
+ context: options.context,
501
+ dryRun: false,
502
+ provider: options.provider,
503
+ providerExplicit: options.providerExplicit,
504
+ role: options.role,
505
+ slice: workspace.slice.slice_path,
506
+ skipWorktreeBranchCheck: true,
507
+ timeout: options.timeout,
508
+ });
509
+ const commit = runGit(['rev-parse', 'HEAD'], workspace.worktreePath);
510
+ if (commit === baseRef) {
511
+ throw new Error(formatError(`delegated slice ${workspace.ref} finished without creating a slice commit.`));
512
+ }
513
+ return {
514
+ commit,
515
+ level: level.index,
516
+ mode: 'parallel-worktree',
517
+ ok: true,
518
+ ref: workspace.ref,
519
+ result,
520
+ workspace,
521
+ };
522
+ }));
523
+
524
+ ensureCleanIntegrationWorktree(repoRoot);
525
+ for (const item of runResults) {
526
+ runGit(['cherry-pick', item.commit], repoRoot);
527
+ }
528
+
529
+ for (const workspace of workspaces) {
530
+ cleanupDelegatedWorkspace(repoRoot, workspace);
531
+ }
532
+ } catch (error) {
533
+ throw appendRecovery(error, group.slice_refs.join(', '), workspaces);
534
+ }
535
+
536
+ return runResults.map((item) => ({
537
+ level: item.level,
538
+ mode: item.mode,
539
+ ref: item.ref,
540
+ ok: item.ok,
541
+ result: item.result,
542
+ workspace: item.workspace.worktreePath,
543
+ integratedCommit: item.commit,
544
+ }));
545
+ }
546
+
547
+ async function runExecutePlan(repoRoot, options = {}) {
548
+ const report = collectExecutionPlan(repoRoot, options);
549
+ const execute = options.execute === true;
550
+ const executionMode = normalizeExecutionMode(options.mode || options.executionMode);
551
+ const provider = options.providerExplicit === true || (options.provider && options.providerExplicit !== false)
552
+ ? options.provider
553
+ : resolveProfileProvider(repoRoot, options.role || 'executor', 'codex');
554
+ const resolvedOptions = {
555
+ ...options,
556
+ mode: executionMode,
557
+ provider,
558
+ resolvedProvider: provider,
559
+ };
560
+
561
+ if (options.json && !execute) {
562
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
563
+ return { task: 'execute-plan', dryRun: true, report };
564
+ }
565
+
566
+ if (!execute || options.dryRun === true) {
567
+ process.stdout.write(formatExecutePlanDryRun(report, resolvedOptions));
568
+ return { task: 'execute-plan', dryRun: true, report };
569
+ }
570
+
571
+ if (executionMode === 'manual') {
572
+ throw new Error(formatError('ai execute-plan --execute does not support --mode manual. Use the printed prompt-slice commands, or choose --mode delegated.'));
573
+ }
574
+
575
+ if (options.commit !== true) {
576
+ throw new Error(formatError('ai execute-plan --execute requires --commit so each successful slice creates one commit.'));
577
+ }
578
+
579
+ const results = [];
580
+
581
+ for (const level of report.ready_levels) {
582
+ for (const group of level.execution_groups) {
583
+ try {
584
+ const groupResults = executionMode === 'delegated' && group.mode === 'parallel' && group.slice_refs.length > 1
585
+ ? await runParallelGroupInWorktrees(repoRoot, level, group, resolvedOptions)
586
+ : await runSequentialGroup(repoRoot, level, group, resolvedOptions);
587
+ results.push(...groupResults);
588
+ } catch (error) {
589
+ const wrapped = new Error(formatError(`ai execute-plan stopped at wave ${level.index} group ${group.slice_refs.join(', ')}: ${error.message || error}`));
590
+ wrapped.cause = error;
591
+ wrapped.code = error.code || 'AI_EXECUTE_PLAN_FAILED';
592
+ wrapped.details = { level: level.index, group, results };
593
+ throw wrapped;
594
+ }
595
+ }
596
+ }
597
+
598
+ process.stdout.write(`AI execute-plan completed\nSlices executed: ${results.length}\n`);
599
+ return { task: 'execute-plan', dryRun: false, report, results };
600
+ }
601
+
239
602
  function runExecutionPlan(repoRoot, options = {}) {
240
603
  const report = collectExecutionPlan(repoRoot, options);
241
604
  if (options.json) {
@@ -249,6 +612,9 @@ function runExecutionPlan(repoRoot, options = {}) {
249
612
 
250
613
  module.exports = {
251
614
  collectExecutionPlan,
615
+ formatExecutePlanDryRun,
252
616
  formatHumanExecutionPlan,
617
+ normalizeExecutionMode,
618
+ runExecutePlan,
253
619
  runExecutionPlan,
254
620
  };