create-quiver 0.9.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. package/BACKLOG.md +16 -17
  2. package/CHANGELOG.md +34 -0
  3. package/README.md +419 -330
  4. package/README_FOR_AI.md +93 -56
  5. package/ROADMAP.md +22 -11
  6. package/docs/AI_CONTEXT.md.template +2 -0
  7. package/docs/AI_ONBOARDING_PROMPT.md.template +36 -19
  8. package/docs/COMMANDS.md.template +73 -1
  9. package/docs/CONTEXTO.md.template +2 -0
  10. package/docs/DECISIONS.md.template +1 -0
  11. package/docs/GITFLOW_PR_GUIDE.md.template +11 -0
  12. package/docs/INDEX.md.template +20 -18
  13. package/docs/STANDARD.md.template +1 -1
  14. package/docs/STATUS.md.template +1 -0
  15. package/docs/SUPPORT_MATRIX.md.template +6 -2
  16. package/docs/TROUBLESHOOTING.md.template +79 -1
  17. package/docs/WORKFLOW.md.template +26 -18
  18. package/package.json +24 -2
  19. package/package.template.json +24 -7
  20. package/scripts/check-pr-readiness.sh +1 -1
  21. package/scripts/check-scope.sh +0 -1
  22. package/scripts/check-slice-readiness.sh +3 -4
  23. package/scripts/init-docs.sh +53 -6
  24. package/scripts/package-quiver.sh +18 -2
  25. package/specs/quiver-v20-ai-cli-orchestration/EVIDENCE_REPORT.md +23 -0
  26. package/specs/quiver-v20-ai-cli-orchestration/EXECUTION_PLAN.md +57 -0
  27. package/specs/quiver-v20-ai-cli-orchestration/SPEC.md +202 -0
  28. package/specs/quiver-v20-ai-cli-orchestration/STATUS.md +35 -0
  29. package/specs/quiver-v20-ai-cli-orchestration/pr.md +100 -0
  30. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-00-spec-foundation/CLOSURE_BRIEF.md +30 -0
  31. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-00-spec-foundation/EXECUTION_BRIEF.md +61 -0
  32. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-00-spec-foundation/slice.json +54 -0
  33. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-01-ai-provider-runner/CLOSURE_BRIEF.md +39 -0
  34. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-01-ai-provider-runner/EXECUTION_BRIEF.md +63 -0
  35. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-01-ai-provider-runner/slice.json +55 -0
  36. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-02-context-packs-token-budget/CLOSURE_BRIEF.md +40 -0
  37. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-02-context-packs-token-budget/EXECUTION_BRIEF.md +60 -0
  38. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-02-context-packs-token-budget/slice.json +54 -0
  39. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-03-ai-phase-gated-planner/CLOSURE_BRIEF.md +43 -0
  40. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-03-ai-phase-gated-planner/EXECUTION_BRIEF.md +62 -0
  41. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-03-ai-phase-gated-planner/slice.json +62 -0
  42. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-04-spec-slice-handoff-pr-generation/CLOSURE_BRIEF.md +36 -0
  43. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-04-spec-slice-handoff-pr-generation/EXECUTION_BRIEF.md +63 -0
  44. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-04-spec-slice-handoff-pr-generation/slice.json +59 -0
  45. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-05-execution-plan-parallel-worktrees/CLOSURE_BRIEF.md +32 -0
  46. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-05-execution-plan-parallel-worktrees/EXECUTION_BRIEF.md +61 -0
  47. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-05-execution-plan-parallel-worktrees/slice.json +59 -0
  48. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-06-ai-execute-slice-scope-enforcement/CLOSURE_BRIEF.md +36 -0
  49. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-06-ai-execute-slice-scope-enforcement/EXECUTION_BRIEF.md +64 -0
  50. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-06-ai-execute-slice-scope-enforcement/slice.json +65 -0
  51. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-07-github-pr-preflight/CLOSURE_BRIEF.md +36 -0
  52. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-07-github-pr-preflight/EXECUTION_BRIEF.md +66 -0
  53. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-07-github-pr-preflight/slice.json +63 -0
  54. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-08-docs-smokes-release-readiness/CLOSURE_BRIEF.md +35 -0
  55. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-08-docs-smokes-release-readiness/EXECUTION_BRIEF.md +64 -0
  56. package/specs/quiver-v20-ai-cli-orchestration/slices/slice-08-docs-smokes-release-readiness/slice.json +77 -0
  57. package/specs/quiver-v21-ai-first-layout/EVIDENCE_REPORT.md +31 -0
  58. package/specs/quiver-v21-ai-first-layout/EXECUTION_PLAN.md +185 -0
  59. package/specs/quiver-v21-ai-first-layout/SPEC.md +212 -0
  60. package/specs/quiver-v21-ai-first-layout/STATUS.md +37 -0
  61. package/specs/quiver-v21-ai-first-layout/pr.md +110 -0
  62. package/specs/quiver-v21-ai-first-layout/slices/slice-00-spec-foundation/CLOSURE_BRIEF.md +30 -0
  63. package/specs/quiver-v21-ai-first-layout/slices/slice-00-spec-foundation/EXECUTION_BRIEF.md +63 -0
  64. package/specs/quiver-v21-ai-first-layout/slices/slice-00-spec-foundation/slice.json +45 -0
  65. package/specs/quiver-v21-ai-first-layout/slices/slice-01-init-profiles-dry-run/CLOSURE_BRIEF.md +31 -0
  66. package/specs/quiver-v21-ai-first-layout/slices/slice-01-init-profiles-dry-run/EXECUTION_BRIEF.md +59 -0
  67. package/specs/quiver-v21-ai-first-layout/slices/slice-01-init-profiles-dry-run/slice.json +57 -0
  68. package/specs/quiver-v21-ai-first-layout/slices/slice-02-internal-layout-template-resolver/CLOSURE_BRIEF.md +32 -0
  69. package/specs/quiver-v21-ai-first-layout/slices/slice-02-internal-layout-template-resolver/EXECUTION_BRIEF.md +60 -0
  70. package/specs/quiver-v21-ai-first-layout/slices/slice-02-internal-layout-template-resolver/slice.json +58 -0
  71. package/specs/quiver-v21-ai-first-layout/slices/slice-03-generation-profiles-visible-contract/CLOSURE_BRIEF.md +34 -0
  72. package/specs/quiver-v21-ai-first-layout/slices/slice-03-generation-profiles-visible-contract/EXECUTION_BRIEF.md +61 -0
  73. package/specs/quiver-v21-ai-first-layout/slices/slice-03-generation-profiles-visible-contract/slice.json +64 -0
  74. package/specs/quiver-v21-ai-first-layout/slices/slice-04-analyze-scan-relocation/CLOSURE_BRIEF.md +32 -0
  75. package/specs/quiver-v21-ai-first-layout/slices/slice-04-analyze-scan-relocation/EXECUTION_BRIEF.md +58 -0
  76. package/specs/quiver-v21-ai-first-layout/slices/slice-04-analyze-scan-relocation/slice.json +64 -0
  77. package/specs/quiver-v21-ai-first-layout/slices/slice-05-empty-specs-layout-doctor/CLOSURE_BRIEF.md +32 -0
  78. package/specs/quiver-v21-ai-first-layout/slices/slice-05-empty-specs-layout-doctor/EXECUTION_BRIEF.md +60 -0
  79. package/specs/quiver-v21-ai-first-layout/slices/slice-05-empty-specs-layout-doctor/slice.json +65 -0
  80. package/specs/quiver-v21-ai-first-layout/slices/slice-06-legacy-migration-optional-assets/CLOSURE_BRIEF.md +31 -0
  81. package/specs/quiver-v21-ai-first-layout/slices/slice-06-legacy-migration-optional-assets/EXECUTION_BRIEF.md +62 -0
  82. package/specs/quiver-v21-ai-first-layout/slices/slice-06-legacy-migration-optional-assets/slice.json +66 -0
  83. package/specs/quiver-v21-ai-first-layout/slices/slice-07-docs-guidance-alignment/CLOSURE_BRIEF.md +33 -0
  84. package/specs/quiver-v21-ai-first-layout/slices/slice-07-docs-guidance-alignment/EXECUTION_BRIEF.md +61 -0
  85. package/specs/quiver-v21-ai-first-layout/slices/slice-07-docs-guidance-alignment/slice.json +67 -0
  86. package/specs/quiver-v21-ai-first-layout/slices/slice-08-smokes-release-readiness/CLOSURE_BRIEF.md +35 -0
  87. package/specs/quiver-v21-ai-first-layout/slices/slice-08-smokes-release-readiness/EXECUTION_BRIEF.md +66 -0
  88. package/specs/quiver-v21-ai-first-layout/slices/slice-08-smokes-release-readiness/slice.json +62 -0
  89. package/specs/quiver-v22-guided-ai-workflow/EVIDENCE_REPORT.md +58 -0
  90. package/specs/quiver-v22-guided-ai-workflow/EXECUTION_PLAN.md +88 -0
  91. package/specs/quiver-v22-guided-ai-workflow/SPEC.md +228 -0
  92. package/specs/quiver-v22-guided-ai-workflow/STATUS.md +42 -0
  93. package/specs/quiver-v22-guided-ai-workflow/pr.md +104 -0
  94. package/specs/quiver-v22-guided-ai-workflow/slices/slice-00-spec-foundation/CLOSURE_BRIEF.md +35 -0
  95. package/specs/quiver-v22-guided-ai-workflow/slices/slice-00-spec-foundation/EXECUTION_BRIEF.md +61 -0
  96. package/specs/quiver-v22-guided-ai-workflow/slices/slice-00-spec-foundation/slice.json +51 -0
  97. package/specs/quiver-v22-guided-ai-workflow/slices/slice-01-docs-source-of-truth-sync/CLOSURE_BRIEF.md +31 -0
  98. package/specs/quiver-v22-guided-ai-workflow/slices/slice-01-docs-source-of-truth-sync/EXECUTION_BRIEF.md +58 -0
  99. package/specs/quiver-v22-guided-ai-workflow/slices/slice-01-docs-source-of-truth-sync/slice.json +55 -0
  100. package/specs/quiver-v22-guided-ai-workflow/slices/slice-02-prepare-command-diagnostics/CLOSURE_BRIEF.md +30 -0
  101. package/specs/quiver-v22-guided-ai-workflow/slices/slice-02-prepare-command-diagnostics/EXECUTION_BRIEF.md +57 -0
  102. package/specs/quiver-v22-guided-ai-workflow/slices/slice-02-prepare-command-diagnostics/slice.json +57 -0
  103. package/specs/quiver-v22-guided-ai-workflow/slices/slice-03-context-doc-refresh/CLOSURE_BRIEF.md +32 -0
  104. package/specs/quiver-v22-guided-ai-workflow/slices/slice-03-context-doc-refresh/EXECUTION_BRIEF.md +56 -0
  105. package/specs/quiver-v22-guided-ai-workflow/slices/slice-03-context-doc-refresh/slice.json +56 -0
  106. package/specs/quiver-v22-guided-ai-workflow/slices/slice-04-planner-approval-state/CLOSURE_BRIEF.md +33 -0
  107. package/specs/quiver-v22-guided-ai-workflow/slices/slice-04-planner-approval-state/EXECUTION_BRIEF.md +56 -0
  108. package/specs/quiver-v22-guided-ai-workflow/slices/slice-04-planner-approval-state/slice.json +58 -0
  109. package/specs/quiver-v22-guided-ai-workflow/slices/slice-05-spec-worktree-lifecycle/CLOSURE_BRIEF.md +32 -0
  110. package/specs/quiver-v22-guided-ai-workflow/slices/slice-05-spec-worktree-lifecycle/EXECUTION_BRIEF.md +56 -0
  111. package/specs/quiver-v22-guided-ai-workflow/slices/slice-05-spec-worktree-lifecycle/slice.json +54 -0
  112. package/specs/quiver-v22-guided-ai-workflow/slices/slice-06-executor-commit-recovery/CLOSURE_BRIEF.md +32 -0
  113. package/specs/quiver-v22-guided-ai-workflow/slices/slice-06-executor-commit-recovery/EXECUTION_BRIEF.md +58 -0
  114. package/specs/quiver-v22-guided-ai-workflow/slices/slice-06-executor-commit-recovery/slice.json +57 -0
  115. package/specs/quiver-v22-guided-ai-workflow/slices/slice-07-execution-waves-delegation/CLOSURE_BRIEF.md +32 -0
  116. package/specs/quiver-v22-guided-ai-workflow/slices/slice-07-execution-waves-delegation/EXECUTION_BRIEF.md +58 -0
  117. package/specs/quiver-v22-guided-ai-workflow/slices/slice-07-execution-waves-delegation/slice.json +55 -0
  118. package/specs/quiver-v22-guided-ai-workflow/slices/slice-08-pr-create-gh-ssh/CLOSURE_BRIEF.md +32 -0
  119. package/specs/quiver-v22-guided-ai-workflow/slices/slice-08-pr-create-gh-ssh/EXECUTION_BRIEF.md +58 -0
  120. package/specs/quiver-v22-guided-ai-workflow/slices/slice-08-pr-create-gh-ssh/slice.json +53 -0
  121. package/specs/quiver-v22-guided-ai-workflow/slices/slice-09-post-merge-cleanup-release-safety/CLOSURE_BRIEF.md +33 -0
  122. package/specs/quiver-v22-guided-ai-workflow/slices/slice-09-post-merge-cleanup-release-safety/EXECUTION_BRIEF.md +59 -0
  123. package/specs/quiver-v22-guided-ai-workflow/slices/slice-09-post-merge-cleanup-release-safety/slice.json +59 -0
  124. package/specs/quiver-v22-guided-ai-workflow/slices/slice-10-docs-smokes-release-readiness/CLOSURE_BRIEF.md +34 -0
  125. package/specs/quiver-v22-guided-ai-workflow/slices/slice-10-docs-smokes-release-readiness/EXECUTION_BRIEF.md +58 -0
  126. package/specs/quiver-v22-guided-ai-workflow/slices/slice-10-docs-smokes-release-readiness/slice.json +60 -0
  127. package/specs/quiver-v23-guided-flow-productization/EVIDENCE_REPORT.md +80 -0
  128. package/specs/quiver-v23-guided-flow-productization/EXECUTION_PLAN.md +80 -0
  129. package/specs/quiver-v23-guided-flow-productization/SPEC.md +203 -0
  130. package/specs/quiver-v23-guided-flow-productization/STATUS.md +39 -0
  131. package/specs/quiver-v23-guided-flow-productization/pr.md +119 -0
  132. package/specs/quiver-v23-guided-flow-productization/slices/slice-00-spec-foundation/CLOSURE_BRIEF.md +30 -0
  133. package/specs/quiver-v23-guided-flow-productization/slices/slice-00-spec-foundation/EXECUTION_BRIEF.md +61 -0
  134. package/specs/quiver-v23-guided-flow-productization/slices/slice-00-spec-foundation/slice.json +51 -0
  135. package/specs/quiver-v23-guided-flow-productization/slices/slice-01-short-command-and-flow-entrypoint/CLOSURE_BRIEF.md +33 -0
  136. package/specs/quiver-v23-guided-flow-productization/slices/slice-01-short-command-and-flow-entrypoint/EXECUTION_BRIEF.md +35 -0
  137. package/specs/quiver-v23-guided-flow-productization/slices/slice-01-short-command-and-flow-entrypoint/slice.json +56 -0
  138. package/specs/quiver-v23-guided-flow-productization/slices/slice-02-flow-status-wizard/CLOSURE_BRIEF.md +31 -0
  139. package/specs/quiver-v23-guided-flow-productization/slices/slice-02-flow-status-wizard/EXECUTION_BRIEF.md +29 -0
  140. package/specs/quiver-v23-guided-flow-productization/slices/slice-02-flow-status-wizard/slice.json +55 -0
  141. package/specs/quiver-v23-guided-flow-productization/slices/slice-03-agent-profiles/CLOSURE_BRIEF.md +33 -0
  142. package/specs/quiver-v23-guided-flow-productization/slices/slice-03-agent-profiles/EXECUTION_BRIEF.md +29 -0
  143. package/specs/quiver-v23-guided-flow-productization/slices/slice-03-agent-profiles/slice.json +54 -0
  144. package/specs/quiver-v23-guided-flow-productization/slices/slice-04-context-preparation-onboarding/CLOSURE_BRIEF.md +32 -0
  145. package/specs/quiver-v23-guided-flow-productization/slices/slice-04-context-preparation-onboarding/EXECUTION_BRIEF.md +30 -0
  146. package/specs/quiver-v23-guided-flow-productization/slices/slice-04-context-preparation-onboarding/slice.json +59 -0
  147. package/specs/quiver-v23-guided-flow-productization/slices/slice-05-planner-iteration-history/CLOSURE_BRIEF.md +31 -0
  148. package/specs/quiver-v23-guided-flow-productization/slices/slice-05-planner-iteration-history/EXECUTION_BRIEF.md +29 -0
  149. package/specs/quiver-v23-guided-flow-productization/slices/slice-05-planner-iteration-history/slice.json +53 -0
  150. package/specs/quiver-v23-guided-flow-productization/slices/slice-06-production-plan-review/CLOSURE_BRIEF.md +33 -0
  151. package/specs/quiver-v23-guided-flow-productization/slices/slice-06-production-plan-review/EXECUTION_BRIEF.md +30 -0
  152. package/specs/quiver-v23-guided-flow-productization/slices/slice-06-production-plan-review/slice.json +54 -0
  153. package/specs/quiver-v23-guided-flow-productization/slices/slice-07-spec-create-experience/CLOSURE_BRIEF.md +33 -0
  154. package/specs/quiver-v23-guided-flow-productization/slices/slice-07-spec-create-experience/EXECUTION_BRIEF.md +30 -0
  155. package/specs/quiver-v23-guided-flow-productization/slices/slice-07-spec-create-experience/slice.json +55 -0
  156. package/specs/quiver-v23-guided-flow-productization/slices/slice-08-executor-prompt-generation/CLOSURE_BRIEF.md +32 -0
  157. package/specs/quiver-v23-guided-flow-productization/slices/slice-08-executor-prompt-generation/EXECUTION_BRIEF.md +30 -0
  158. package/specs/quiver-v23-guided-flow-productization/slices/slice-08-executor-prompt-generation/slice.json +55 -0
  159. package/specs/quiver-v23-guided-flow-productization/slices/slice-09-delegated-slice-execution/CLOSURE_BRIEF.md +33 -0
  160. package/specs/quiver-v23-guided-flow-productization/slices/slice-09-delegated-slice-execution/EXECUTION_BRIEF.md +34 -0
  161. package/specs/quiver-v23-guided-flow-productization/slices/slice-09-delegated-slice-execution/slice.json +57 -0
  162. package/specs/quiver-v23-guided-flow-productization/slices/slice-10-docs-smokes-release-readiness/CLOSURE_BRIEF.md +33 -0
  163. package/specs/quiver-v23-guided-flow-productization/slices/slice-10-docs-smokes-release-readiness/EXECUTION_BRIEF.md +32 -0
  164. package/specs/quiver-v23-guided-flow-productization/slices/slice-10-docs-smokes-release-readiness/slice.json +63 -0
  165. package/specs/quiver-v24-dx-onboarding-hardening/EVIDENCE_REPORT.md +55 -0
  166. package/specs/quiver-v24-dx-onboarding-hardening/EXECUTION_PLAN.md +43 -0
  167. package/specs/quiver-v24-dx-onboarding-hardening/SPEC.md +149 -0
  168. package/specs/quiver-v24-dx-onboarding-hardening/STATUS.md +31 -0
  169. package/specs/quiver-v24-dx-onboarding-hardening/pr.md +76 -0
  170. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-00-spec-foundation/CLOSURE_BRIEF.md +31 -0
  171. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-00-spec-foundation/EXECUTION_BRIEF.md +52 -0
  172. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-00-spec-foundation/slice.json +51 -0
  173. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-01-init-template-hygiene/CLOSURE_BRIEF.md +38 -0
  174. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-01-init-template-hygiene/EXECUTION_BRIEF.md +53 -0
  175. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-01-init-template-hygiene/slice.json +55 -0
  176. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-02-cli-command-routing-version-errors/CLOSURE_BRIEF.md +33 -0
  177. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-02-cli-command-routing-version-errors/EXECUTION_BRIEF.md +50 -0
  178. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-02-cli-command-routing-version-errors/slice.json +52 -0
  179. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-03-doctor-fix-doc-link-checks/CLOSURE_BRIEF.md +33 -0
  180. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-03-doctor-fix-doc-link-checks/EXECUTION_BRIEF.md +50 -0
  181. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-03-doctor-fix-doc-link-checks/slice.json +53 -0
  182. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-04-prepare-output-ai-context-drafts/CLOSURE_BRIEF.md +33 -0
  183. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-04-prepare-output-ai-context-drafts/EXECUTION_BRIEF.md +50 -0
  184. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-04-prepare-output-ai-context-drafts/slice.json +70 -0
  185. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-05-local-slice-validation-base-guidance/CLOSURE_BRIEF.md +36 -0
  186. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-05-local-slice-validation-base-guidance/EXECUTION_BRIEF.md +49 -0
  187. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-05-local-slice-validation-base-guidance/slice.json +52 -0
  188. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-06-plan-graph-next-history-views/CLOSURE_BRIEF.md +43 -0
  189. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-06-plan-graph-next-history-views/EXECUTION_BRIEF.md +53 -0
  190. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-06-plan-graph-next-history-views/slice.json +60 -0
  191. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-07-analyzer-command-map-hardening/CLOSURE_BRIEF.md +32 -0
  192. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-07-analyzer-command-map-hardening/EXECUTION_BRIEF.md +50 -0
  193. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-07-analyzer-command-map-hardening/slice.json +51 -0
  194. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-08-evidence-run-command/CLOSURE_BRIEF.md +34 -0
  195. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-08-evidence-run-command/EXECUTION_BRIEF.md +52 -0
  196. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-08-evidence-run-command/slice.json +54 -0
  197. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-09-spec-viewer-demo-scaffolding/CLOSURE_BRIEF.md +34 -0
  198. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-09-spec-viewer-demo-scaffolding/EXECUTION_BRIEF.md +51 -0
  199. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-09-spec-viewer-demo-scaffolding/slice.json +59 -0
  200. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-10-docs-smokes-release-readiness/CLOSURE_BRIEF.md +33 -0
  201. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-10-docs-smokes-release-readiness/EXECUTION_BRIEF.md +54 -0
  202. package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-10-docs-smokes-release-readiness/slice.json +76 -0
  203. package/src/create-quiver/commands/ai.js +915 -0
  204. package/src/create-quiver/commands/demo.js +22 -0
  205. package/src/create-quiver/commands/evidence.js +37 -0
  206. package/src/create-quiver/commands/flow.js +561 -0
  207. package/src/create-quiver/commands/graph.js +14 -1
  208. package/src/create-quiver/commands/next.js +28 -0
  209. package/src/create-quiver/commands/plan.js +6 -3
  210. package/src/create-quiver/commands/prepare.js +236 -0
  211. package/src/create-quiver/commands/spec.js +133 -0
  212. package/src/create-quiver/index.js +1096 -96
  213. package/src/create-quiver/lib/agent-profiles.js +148 -0
  214. package/src/create-quiver/lib/ai/context-packs.js +170 -0
  215. package/src/create-quiver/lib/ai/execution-plan.js +614 -0
  216. package/src/create-quiver/lib/ai/executor.js +682 -0
  217. package/src/create-quiver/lib/ai/github.js +525 -0
  218. package/src/create-quiver/lib/ai/onboarding-template.js +365 -0
  219. package/src/create-quiver/lib/ai/phase-gates.js +72 -0
  220. package/src/create-quiver/lib/ai/plan-review.js +283 -0
  221. package/src/create-quiver/lib/ai/preflight.js +58 -0
  222. package/src/create-quiver/lib/ai/prompt-transport.js +81 -0
  223. package/src/create-quiver/lib/ai/prompts.js +39 -0
  224. package/src/create-quiver/lib/ai/providers.js +315 -0
  225. package/src/create-quiver/lib/ai/safety.js +156 -0
  226. package/src/create-quiver/lib/ai/spec-generator.js +314 -0
  227. package/src/create-quiver/lib/ai/spec-templates.js +715 -0
  228. package/src/create-quiver/lib/approvals.js +350 -0
  229. package/src/create-quiver/lib/demo.js +657 -0
  230. package/src/create-quiver/lib/doctor.js +348 -0
  231. package/src/create-quiver/lib/evidence.js +115 -0
  232. package/src/create-quiver/lib/git.js +21 -0
  233. package/src/create-quiver/lib/init-docs.js +545 -23
  234. package/src/create-quiver/lib/init-layout.js +451 -0
  235. package/src/create-quiver/lib/lifecycle.js +8 -2
  236. package/src/create-quiver/lib/package-safety.js +117 -0
  237. package/src/create-quiver/lib/paths.js +63 -2
  238. package/src/create-quiver/lib/project-scan.js +66 -0
  239. package/src/create-quiver/lib/readiness.js +87 -18
  240. package/src/create-quiver/lib/scope.js +125 -0
  241. package/src/create-quiver/lib/slice-graph.js +7 -0
  242. package/src/create-quiver/lib/slice.js +59 -16
  243. package/src/create-quiver/lib/spec-worktrees.js +349 -0
  244. package/src/create-quiver/lib/state.js +18 -1
  245. package/src/create-quiver/lib/template-resolver.js +74 -0
@@ -0,0 +1,525 @@
1
+ const fs = require('node:fs');
2
+ const os = require('node:os');
3
+ const path = require('node:path');
4
+ const { spawnSync } = require('node:child_process');
5
+
6
+ const { currentBranch, hasRemote, isCleanWorktree } = require('../git');
7
+
8
+ const DEFAULT_GH_COMMAND = 'gh';
9
+ const DEFAULT_REMOTE = 'origin';
10
+ const DEFAULT_GITFLOW_GUIDE_PATH = 'docs/GITFLOW_PR_GUIDE.md';
11
+
12
+ class GitHubPreflightError extends Error {
13
+ constructor(code, message, details = {}) {
14
+ super(message);
15
+ this.name = 'GitHubPreflightError';
16
+ this.code = code;
17
+ this.details = details;
18
+ }
19
+ }
20
+
21
+ function formatError(message) {
22
+ return `create-quiver: ${message}`;
23
+ }
24
+
25
+ function normalizeOptionalPath(filePath) {
26
+ const value = String(filePath || '').trim();
27
+ if (!value) {
28
+ return '';
29
+ }
30
+
31
+ if (value === '~') {
32
+ return os.homedir();
33
+ }
34
+
35
+ if (value.startsWith('~/') || value.startsWith('~\\')) {
36
+ return path.join(os.homedir(), value.slice(2));
37
+ }
38
+
39
+ return value;
40
+ }
41
+
42
+ function resolveConfiguredPath(repoRoot, filePath) {
43
+ const normalized = normalizeOptionalPath(filePath);
44
+ if (!normalized) {
45
+ return '';
46
+ }
47
+
48
+ if (path.isAbsolute(normalized)) {
49
+ return path.normalize(normalized);
50
+ }
51
+
52
+ return path.resolve(repoRoot, normalized);
53
+ }
54
+
55
+ function formatGhInstallGuidance() {
56
+ return [
57
+ 'GitHub CLI is not installed.',
58
+ 'macOS: brew install gh',
59
+ 'Linux: follow https://github.com/cli/cli/blob/trunk/docs/install_linux.md or use your distro package manager',
60
+ 'Windows: winget install GitHub.cli',
61
+ ].join('\n');
62
+ }
63
+
64
+ function createError(code, message, details = {}) {
65
+ return new GitHubPreflightError(code, message, details);
66
+ }
67
+
68
+ function runCommand(command, args, options = {}) {
69
+ const runner = options.runner || spawnSync;
70
+ return runner(command, args, {
71
+ cwd: options.cwd,
72
+ encoding: 'utf8',
73
+ shell: false,
74
+ stdio: ['ignore', 'pipe', 'pipe'],
75
+ });
76
+ }
77
+
78
+ function ensureGhInstalled(options = {}) {
79
+ const command = options.ghCommand || DEFAULT_GH_COMMAND;
80
+ const probeArgs = Array.isArray(options.ghProbeArgs) ? options.ghProbeArgs : ['--version'];
81
+ const result = runCommand(command, probeArgs, {
82
+ cwd: options.cwd,
83
+ runner: options.ghProbe || spawnSync,
84
+ });
85
+
86
+ if (result && result.error && result.error.code === 'ENOENT') {
87
+ throw createError('MISSING_GH_CLI', `${formatGhInstallGuidance()}\nRun gh auth login after installation.`, {
88
+ command,
89
+ probeArgs,
90
+ errorCode: result.error.code,
91
+ });
92
+ }
93
+
94
+ if (result && result.error) {
95
+ throw createError('GH_CLI_UNAVAILABLE', formatError(`GitHub CLI could not be executed. Check '${command}' and then run gh auth login.`), {
96
+ command,
97
+ probeArgs,
98
+ errorCode: result.error.code,
99
+ errorMessage: result.error.message,
100
+ });
101
+ }
102
+
103
+ if (!result || typeof result.status !== 'number' || result.status !== 0) {
104
+ const stderr = result && typeof result.stderr === 'string' ? result.stderr.trim() : '';
105
+ const stdout = result && typeof result.stdout === 'string' ? result.stdout.trim() : '';
106
+ const details = [stderr, stdout].filter(Boolean).join('\n');
107
+ throw createError(
108
+ 'GH_CLI_UNAVAILABLE',
109
+ `${formatError(`GitHub CLI probe failed for '${command} ${probeArgs.join(' ')}'. Check your gh installation and then run gh auth login.`)}${details ? `\n${details}` : ''}`,
110
+ {
111
+ command,
112
+ probeArgs,
113
+ status: result && result.status,
114
+ stderr,
115
+ stdout,
116
+ },
117
+ );
118
+ }
119
+
120
+ return {
121
+ command,
122
+ probeArgs,
123
+ stdout: result && typeof result.stdout === 'string' ? result.stdout : '',
124
+ stderr: result && typeof result.stderr === 'string' ? result.stderr : '',
125
+ status: result && typeof result.status === 'number' ? result.status : 0,
126
+ };
127
+ }
128
+
129
+ function ensureGhAuthenticated(options = {}) {
130
+ const command = options.ghCommand || DEFAULT_GH_COMMAND;
131
+ const authArgs = Array.isArray(options.ghAuthArgs) ? options.ghAuthArgs : ['auth', 'status'];
132
+ const result = runCommand(command, authArgs, {
133
+ cwd: options.cwd,
134
+ runner: options.ghAuthProbe || options.ghProbe || spawnSync,
135
+ });
136
+
137
+ if (result && result.error && result.error.code === 'ENOENT') {
138
+ throw createError('MISSING_GH_CLI', `${formatGhInstallGuidance()}\nRun gh auth login after installation.`, {
139
+ command,
140
+ authArgs,
141
+ errorCode: result.error.code,
142
+ });
143
+ }
144
+
145
+ if (typeof result.status !== 'number' || result.status !== 0) {
146
+ const stderr = typeof result.stderr === 'string' ? result.stderr.trim() : '';
147
+ const stdout = typeof result.stdout === 'string' ? result.stdout.trim() : '';
148
+ const details = [stderr, stdout].filter(Boolean).join('\n');
149
+ throw createError(
150
+ 'GH_NOT_AUTHENTICATED',
151
+ `${formatError('gh auth status failed. Run gh auth login and then re-run the preflight.')}${details ? `\n${details}` : ''}`,
152
+ {
153
+ command,
154
+ authArgs,
155
+ status: result.status,
156
+ stderr,
157
+ stdout,
158
+ },
159
+ );
160
+ }
161
+
162
+ return {
163
+ command,
164
+ authArgs,
165
+ stdout: typeof result.stdout === 'string' ? result.stdout : '',
166
+ stderr: typeof result.stderr === 'string' ? result.stderr : '',
167
+ status: result.status,
168
+ };
169
+ }
170
+
171
+ function ensureGitFlowGuide(repoRoot, guidePath) {
172
+ const resolved = resolveConfiguredPath(repoRoot, guidePath || DEFAULT_GITFLOW_GUIDE_PATH);
173
+ if (!resolved || !fs.existsSync(resolved)) {
174
+ throw createError(
175
+ 'MISSING_GITFLOW_GUIDE',
176
+ formatError(`missing GitFlow PR guide at ${resolved || guidePath || DEFAULT_GITFLOW_GUIDE_PATH}. Create docs/GITFLOW_PR_GUIDE.md before opening the PR.`),
177
+ {
178
+ guidePath: resolved || guidePath || DEFAULT_GITFLOW_GUIDE_PATH,
179
+ },
180
+ );
181
+ }
182
+
183
+ return resolved;
184
+ }
185
+
186
+ function ensureRemote(repoRoot, remoteName = DEFAULT_REMOTE) {
187
+ if (!hasRemote(repoRoot, remoteName)) {
188
+ throw createError(
189
+ 'MISSING_GIT_REMOTE',
190
+ formatError(`missing Git remote '${remoteName}'. Configure a remote before preparing the PR.`),
191
+ { remoteName },
192
+ );
193
+ }
194
+
195
+ return remoteName;
196
+ }
197
+
198
+ function ensureWorktreeReady(repoRoot, options = {}) {
199
+ const branchName = currentBranch(repoRoot);
200
+ if (!branchName) {
201
+ throw createError(
202
+ 'DETACHED_HEAD',
203
+ formatError('current HEAD is detached. Check out the spec branch before preparing the PR.'),
204
+ { repoRoot },
205
+ );
206
+ }
207
+
208
+ const blockedBranches = Array.isArray(options.blockedBranches) && options.blockedBranches.length > 0
209
+ ? options.blockedBranches
210
+ : ['main', 'master', 'develop'];
211
+
212
+ if (blockedBranches.includes(branchName)) {
213
+ throw createError(
214
+ 'UNSAFE_PR_BRANCH',
215
+ formatError(`current branch '${branchName}' is not a PR branch. Create or switch to the feature branch before continuing.`),
216
+ { branchName, blockedBranches },
217
+ );
218
+ }
219
+
220
+ if (!isCleanWorktree(repoRoot)) {
221
+ throw createError(
222
+ 'DIRTY_WORKTREE',
223
+ formatError(`worktree has uncommitted changes on branch '${branchName}'. Commit or stash them before preparing the PR.`),
224
+ { branchName },
225
+ );
226
+ }
227
+
228
+ return branchName;
229
+ }
230
+
231
+ function ensureIdentityFile(repoRoot, identityFile) {
232
+ const normalized = String(identityFile || '').trim();
233
+ if (!normalized) {
234
+ return '';
235
+ }
236
+
237
+ const resolved = resolveConfiguredPath(repoRoot, normalized);
238
+ if (!fs.existsSync(resolved)) {
239
+ throw createError(
240
+ 'MISSING_IDENTITY_FILE',
241
+ formatError(`missing SSH identity file at ${resolved}. Check the path you passed as identityFile.`),
242
+ {
243
+ identityFile: normalized,
244
+ resolvedIdentityFile: resolved,
245
+ },
246
+ );
247
+ }
248
+
249
+ return resolved;
250
+ }
251
+
252
+ function findPrBodyCandidates(repoRoot) {
253
+ const candidates = [];
254
+ const rootPr = path.join(repoRoot, 'pr.md');
255
+ if (fs.existsSync(rootPr)) {
256
+ candidates.push(rootPr);
257
+ }
258
+
259
+ const specsDir = path.join(repoRoot, 'specs');
260
+ if (fs.existsSync(specsDir)) {
261
+ for (const entry of fs.readdirSync(specsDir, { withFileTypes: true })) {
262
+ if (!entry.isDirectory()) {
263
+ continue;
264
+ }
265
+ const candidate = path.join(specsDir, entry.name, 'pr.md');
266
+ if (fs.existsSync(candidate)) {
267
+ candidates.push(candidate);
268
+ }
269
+ }
270
+ }
271
+
272
+ return candidates.sort((left, right) => left.localeCompare(right));
273
+ }
274
+
275
+ function resolvePrBodyPath(repoRoot, prBodyPath) {
276
+ const configured = String(prBodyPath || '').trim();
277
+ if (configured) {
278
+ const resolved = resolveConfiguredPath(repoRoot, configured);
279
+ if (!fs.existsSync(resolved)) {
280
+ throw createError('MISSING_PR_BODY', formatError(`missing PR body file at ${resolved}. Pass --input specs/<spec-slug>/pr.md or generate pr.md first.`), {
281
+ prBodyPath: configured,
282
+ resolvedPrBodyPath: resolved,
283
+ });
284
+ }
285
+ return resolved;
286
+ }
287
+
288
+ const candidates = findPrBodyCandidates(repoRoot);
289
+ if (candidates.length === 1) {
290
+ return candidates[0];
291
+ }
292
+ if (candidates.length === 0) {
293
+ throw createError('MISSING_PR_BODY', formatError('missing PR body file. Pass --input specs/<spec-slug>/pr.md or generate pr.md first.'), {
294
+ candidates,
295
+ });
296
+ }
297
+
298
+ throw createError('AMBIGUOUS_PR_BODY', formatError(`multiple pr.md files found: ${candidates.map((item) => path.relative(repoRoot, item).split(path.sep).join('/')).join(', ')}. Pass --input with the intended PR body.`), {
299
+ candidates,
300
+ });
301
+ }
302
+
303
+ function readPrBody(repoRoot, prBodyPath) {
304
+ const resolved = resolvePrBodyPath(repoRoot, prBodyPath);
305
+ const body = fs.readFileSync(resolved, 'utf8');
306
+ if (!body.trim()) {
307
+ throw createError('EMPTY_PR_BODY', formatError(`PR body file is empty: ${path.relative(repoRoot, resolved).split(path.sep).join('/')}`), {
308
+ prBodyPath: resolved,
309
+ });
310
+ }
311
+ return {
312
+ body,
313
+ path: resolved,
314
+ };
315
+ }
316
+
317
+ function extractPrTitle(prBody, fallbackTitle) {
318
+ const lines = String(prBody || '').split(/\r?\n/);
319
+ const titleIndex = lines.findIndex((line) => /^##\s+Title\s*$/i.test(line.trim()));
320
+ if (titleIndex !== -1) {
321
+ for (const line of lines.slice(titleIndex + 1)) {
322
+ const value = line.trim().replace(/^#+\s*/, '');
323
+ if (value) {
324
+ return value;
325
+ }
326
+ }
327
+ }
328
+
329
+ const firstHeading = lines.find((line) => /^#\s+\S/.test(line.trim()));
330
+ if (firstHeading) {
331
+ return firstHeading.trim().replace(/^#\s+/, '');
332
+ }
333
+
334
+ return fallbackTitle || 'Quiver PR';
335
+ }
336
+
337
+ function buildPrCreateArgs(plan) {
338
+ const args = [
339
+ 'pr',
340
+ 'create',
341
+ '--base',
342
+ plan.baseBranch,
343
+ '--head',
344
+ plan.branchName,
345
+ '--title',
346
+ plan.title,
347
+ '--body-file',
348
+ plan.prBodyPath,
349
+ ];
350
+ return args;
351
+ }
352
+
353
+ function buildPrCreatePlan(repoRoot, preflightReport, options = {}) {
354
+ const prBody = readPrBody(repoRoot, options.prBodyPath || options.input);
355
+ const baseBranch = String(options.baseBranch || 'main').trim() || 'main';
356
+ const title = String(options.title || '').trim() || extractPrTitle(prBody.body, preflightReport.branchName);
357
+ const plan = {
358
+ baseBranch,
359
+ branchName: preflightReport.branchName,
360
+ ghCommand: options.ghCommand || DEFAULT_GH_COMMAND,
361
+ prBodyPath: prBody.path,
362
+ prBodyRelativePath: path.relative(repoRoot, prBody.path).split(path.sep).join('/'),
363
+ remote: preflightReport.remote,
364
+ repoRoot,
365
+ title,
366
+ };
367
+ plan.args = buildPrCreateArgs(plan);
368
+ return plan;
369
+ }
370
+
371
+ function runGhPrCreate(plan, options = {}) {
372
+ const result = runCommand(plan.ghCommand, plan.args, {
373
+ cwd: plan.repoRoot,
374
+ runner: options.runner || options.ghCreateRunner || spawnSync,
375
+ });
376
+
377
+ if (result && result.error) {
378
+ throw createError('GH_PR_CREATE_FAILED', formatError(`gh pr create could not be executed. ${result.error.message}`), {
379
+ args: plan.args,
380
+ errorCode: result.error.code,
381
+ errorMessage: result.error.message,
382
+ });
383
+ }
384
+
385
+ if (!result || typeof result.status !== 'number' || result.status !== 0) {
386
+ const stderr = result && typeof result.stderr === 'string' ? result.stderr.trim() : '';
387
+ const stdout = result && typeof result.stdout === 'string' ? result.stdout.trim() : '';
388
+ throw createError('GH_PR_CREATE_FAILED', `${formatError('gh pr create failed.')}${[stderr, stdout].filter(Boolean).length > 0 ? `\n${[stderr, stdout].filter(Boolean).join('\n')}` : ''}`, {
389
+ args: plan.args,
390
+ status: result && result.status,
391
+ stderr,
392
+ stdout,
393
+ });
394
+ }
395
+
396
+ return {
397
+ status: result.status,
398
+ stdout: typeof result.stdout === 'string' ? result.stdout : '',
399
+ stderr: typeof result.stderr === 'string' ? result.stderr : '',
400
+ };
401
+ }
402
+
403
+ function buildPreflightReport(repoRoot, options = {}, checks = {}) {
404
+ return {
405
+ ok: true,
406
+ repoRoot,
407
+ remote: checks.remote || options.remote || DEFAULT_REMOTE,
408
+ branchName: checks.branchName || '',
409
+ guidePath: checks.guidePath || '',
410
+ sshHostAlias: options.sshHostAlias || '',
411
+ identityFile: checks.identityFile || '',
412
+ gh: checks.gh || null,
413
+ auth: checks.auth || null,
414
+ };
415
+ }
416
+
417
+ function preflightGitHubPr(repoRoot, options = {}) {
418
+ const gh = ensureGhInstalled(options);
419
+ const auth = ensureGhAuthenticated(options);
420
+ const guidePath = ensureGitFlowGuide(repoRoot, options.gitFlowGuidePath);
421
+ const remote = ensureRemote(repoRoot, options.remote || DEFAULT_REMOTE);
422
+ const branchName = ensureWorktreeReady(repoRoot, options);
423
+ const identityFile = ensureIdentityFile(repoRoot, options.identityFile);
424
+
425
+ return buildPreflightReport(repoRoot, options, {
426
+ gh,
427
+ auth,
428
+ guidePath,
429
+ remote,
430
+ branchName,
431
+ identityFile,
432
+ });
433
+ }
434
+
435
+ function formatPreflightReport(report, options = {}) {
436
+ const mode = options.mode || 'pr';
437
+ const dryRun = options.dryRun === true;
438
+ const lines = [
439
+ `GitHub ${mode} ${dryRun ? 'dry-run' : 'preflight'}`,
440
+ `Remote: ${report.remote}`,
441
+ `Branch: ${report.branchName}`,
442
+ `GitFlow guide: ${path.relative(report.repoRoot, report.guidePath).split(path.sep).join('/')}`,
443
+ ];
444
+
445
+ if (report.sshHostAlias) {
446
+ lines.push(`SSH host alias: ${report.sshHostAlias}`);
447
+ }
448
+
449
+ if (report.identityFile) {
450
+ lines.push(`Identity file: ${report.identityFile}`);
451
+ }
452
+
453
+ lines.push('Checks: gh, gh auth status, git remote, worktree branch, GitFlow guide, SSH identity file');
454
+
455
+ if (dryRun) {
456
+ lines.push('No PR will be created in dry-run mode.');
457
+ } else {
458
+ lines.push('PR creation is not performed in this slice.');
459
+ }
460
+
461
+ return `${lines.join('\n')}\n`;
462
+ }
463
+
464
+ function quoteCommandArg(arg) {
465
+ const value = String(arg);
466
+ return /^[A-Za-z0-9_./:=@-]+$/.test(value) ? value : JSON.stringify(value);
467
+ }
468
+
469
+ function formatPrCreateReport({ preflight, plan, result }, options = {}) {
470
+ const dryRun = options.dryRun === true;
471
+ const create = options.create === true;
472
+ const lines = [
473
+ `GitHub pr ${dryRun ? 'dry-run' : create ? 'created' : 'preflight'}`,
474
+ `Remote: ${preflight.remote}`,
475
+ `Branch: ${preflight.branchName}`,
476
+ `Base: ${plan.baseBranch}`,
477
+ `PR body: ${plan.prBodyRelativePath}`,
478
+ `Title: ${plan.title}`,
479
+ `Command: ${plan.ghCommand} ${plan.args.map(quoteCommandArg).join(' ')}`,
480
+ ];
481
+
482
+ if (preflight.sshHostAlias) {
483
+ lines.push(`SSH host alias: ${preflight.sshHostAlias}`);
484
+ }
485
+
486
+ if (preflight.identityFile) {
487
+ lines.push(`Identity file: ${preflight.identityFile}`);
488
+ }
489
+
490
+ if (dryRun) {
491
+ lines.push('No PR will be created in dry-run mode.');
492
+ } else if (!create) {
493
+ lines.push('No PR was created. Re-run with --create after reviewing the plan.');
494
+ } else if (result && result.stdout) {
495
+ lines.push(result.stdout.trimEnd());
496
+ }
497
+
498
+ return `${lines.join('\n')}\n`;
499
+ }
500
+
501
+ module.exports = {
502
+ DEFAULT_GH_COMMAND,
503
+ DEFAULT_GITFLOW_GUIDE_PATH,
504
+ DEFAULT_REMOTE,
505
+ GitHubPreflightError,
506
+ buildPrCreateArgs,
507
+ buildPrCreatePlan,
508
+ buildPreflightReport,
509
+ extractPrTitle,
510
+ ensureGhAuthenticated,
511
+ ensureGhInstalled,
512
+ ensureGitFlowGuide,
513
+ ensureIdentityFile,
514
+ ensureRemote,
515
+ ensureWorktreeReady,
516
+ findPrBodyCandidates,
517
+ formatGhInstallGuidance,
518
+ formatPreflightReport,
519
+ formatPrCreateReport,
520
+ preflightGitHubPr,
521
+ readPrBody,
522
+ resolveConfiguredPath,
523
+ resolvePrBodyPath,
524
+ runGhPrCreate,
525
+ };