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,66 @@
1
+ const fs = require('node:fs');
2
+ const path = require('node:path');
3
+
4
+ const CURRENT_SCAN_RELATIVE_PATH = '.quiver/scans/PROJECT_SCAN.json';
5
+ const LEGACY_SCAN_RELATIVE_PATH = 'docs/PROJECT_SCAN.json';
6
+ const PROJECT_MAP_RELATIVE_PATH = 'docs/PROJECT_MAP.md';
7
+
8
+ function projectScanPaths(projectRoot) {
9
+ return {
10
+ currentScanPath: path.join(projectRoot, '.quiver', 'scans', 'PROJECT_SCAN.json'),
11
+ legacyScanPath: path.join(projectRoot, 'docs', 'PROJECT_SCAN.json'),
12
+ projectMapPath: path.join(projectRoot, 'docs', 'PROJECT_MAP.md'),
13
+ scanDir: path.join(projectRoot, '.quiver', 'scans'),
14
+ };
15
+ }
16
+
17
+ function toRelativeScanPath(projectRoot, filePath) {
18
+ return path.relative(projectRoot, filePath).split(path.sep).join('/');
19
+ }
20
+
21
+ function writeProjectScanJson(projectRoot, scan) {
22
+ const { currentScanPath, scanDir } = projectScanPaths(projectRoot);
23
+ fs.mkdirSync(scanDir, { recursive: true });
24
+ fs.writeFileSync(currentScanPath, `${JSON.stringify(scan, null, 2)}\n`);
25
+ return currentScanPath;
26
+ }
27
+
28
+ function readProjectScanArtifact(projectRoot) {
29
+ const { currentScanPath, legacyScanPath } = projectScanPaths(projectRoot);
30
+
31
+ if (fs.existsSync(currentScanPath)) {
32
+ return {
33
+ path: currentScanPath,
34
+ relativePath: toRelativeScanPath(projectRoot, currentScanPath),
35
+ source: 'current',
36
+ scan: JSON.parse(fs.readFileSync(currentScanPath, 'utf8')),
37
+ };
38
+ }
39
+
40
+ if (fs.existsSync(legacyScanPath)) {
41
+ return {
42
+ path: legacyScanPath,
43
+ relativePath: toRelativeScanPath(projectRoot, legacyScanPath),
44
+ source: 'legacy',
45
+ scan: JSON.parse(fs.readFileSync(legacyScanPath, 'utf8')),
46
+ };
47
+ }
48
+
49
+ return null;
50
+ }
51
+
52
+ function hasProjectScanArtifact(projectRoot) {
53
+ const { currentScanPath, legacyScanPath } = projectScanPaths(projectRoot);
54
+ return fs.existsSync(currentScanPath) || fs.existsSync(legacyScanPath);
55
+ }
56
+
57
+ module.exports = {
58
+ CURRENT_SCAN_RELATIVE_PATH,
59
+ LEGACY_SCAN_RELATIVE_PATH,
60
+ PROJECT_MAP_RELATIVE_PATH,
61
+ hasProjectScanArtifact,
62
+ projectScanPaths,
63
+ readProjectScanArtifact,
64
+ toRelativeScanPath,
65
+ writeProjectScanJson,
66
+ };
@@ -56,7 +56,7 @@ function parseWorktrees(text) {
56
56
  return entries;
57
57
  }
58
58
 
59
- function collectOverlapWarnings(repoRoot, currentBranchName, currentFiles) {
59
+ function collectOverlapWarnings(repoRoot, currentBranchName, currentFiles, baseRef = 'origin/develop') {
60
60
  const sliceMap = new Map();
61
61
  walkSlices(path.join(repoRoot, 'specs'), sliceMap, repoRoot);
62
62
  walkSlices(path.join(repoRoot, 'specs-fix'), sliceMap, repoRoot);
@@ -79,7 +79,7 @@ function collectOverlapWarnings(repoRoot, currentBranchName, currentFiles) {
79
79
  }
80
80
 
81
81
  const dirty = statusPorcelain(worktreePath) !== '';
82
- const aheadCount = revListCount(worktreePath, 'origin/develop..HEAD');
82
+ const aheadCount = revListCount(worktreePath, `${baseRef}..HEAD`);
83
83
  const active = dirty || aheadCount > 0;
84
84
 
85
85
  if (!active) {
@@ -95,6 +95,65 @@ function collectOverlapWarnings(repoRoot, currentBranchName, currentFiles) {
95
95
  return warnings;
96
96
  }
97
97
 
98
+ function validateLocalSliceArtifacts(repoRoot, slice) {
99
+ const sliceDir = path.dirname(slice.sliceAbs);
100
+ for (const file of ['EXECUTION_BRIEF.md', 'CLOSURE_BRIEF.md']) {
101
+ ensureExists(path.join(sliceDir, file), `create-quiver: falta '${path.posix.join(path.dirname(slice.sliceRel), file)}'.`);
102
+ }
103
+ console.log('PASS: El slice local tiene EXECUTION_BRIEF.md y CLOSURE_BRIEF.md.');
104
+
105
+ if (!Array.isArray(slice.json.files) || slice.json.files.length === 0) {
106
+ throw new Error('create-quiver: slice.json debe declarar al menos un archivo en files para validacion local.');
107
+ }
108
+
109
+ const invalidFiles = slice.json.files.filter((file) => typeof file !== 'string' || file.trim().length === 0);
110
+ if (invalidFiles.length > 0) {
111
+ throw new Error('create-quiver: slice.json.files contiene entradas invalidas.');
112
+ }
113
+ console.log('PASS: slice.json declara archivos de alcance.');
114
+ }
115
+
116
+ function baseRecoveryMessage(remote, baseBranch) {
117
+ return `No se encontro la base '${baseBranch}' como rama local ni como '${remote}/${baseBranch}'. Para validacion estructural usa --local; para validacion contra otra base usa --base <branch>; o configura/fetchea el remoto '${remote}'.`;
118
+ }
119
+
120
+ function validateSliceDocumentedOnBase(repoRoot, slice, options = {}) {
121
+ const gate = options.gate || 'execution';
122
+ const remote = options.remote || 'origin';
123
+ const baseBranch = options.baseBranch || slice.baseBranch || 'develop';
124
+ const remoteRef = `${remote}/${baseBranch}`;
125
+ const hasRemoteBase = hasRemoteBranch(repoRoot, baseBranch, remote);
126
+ const hasLocalBase = hasLocalBranch(repoRoot, baseBranch);
127
+
128
+ if (hasRemoteBase && catFileExists(repoRoot, `${remoteRef}:${slice.sliceRel}`)) {
129
+ console.log(`PASS: El slice ya existe en ${remoteRef} (PR base documental mergeado).`);
130
+ return remoteRef;
131
+ }
132
+
133
+ if (hasLocalBase && catFileExists(repoRoot, `${baseBranch}:${slice.sliceRel}`)) {
134
+ console.log(`PASS: El slice ya existe en ${baseBranch} local (modo sin remote).`);
135
+ return baseBranch;
136
+ }
137
+
138
+ if (!hasRemoteBase && !hasLocalBase) {
139
+ const guidance = baseRecoveryMessage(remote, baseBranch);
140
+ if (gate === 'validation') {
141
+ console.log(`WARN: ${guidance}`);
142
+ return null;
143
+ }
144
+
145
+ throw new Error(`create-quiver: ${guidance}`);
146
+ }
147
+
148
+ const expectedBase = hasRemoteBase ? remoteRef : baseBranch;
149
+ if (gate === 'validation') {
150
+ console.log(`WARN: El slice no existe todavia en ${expectedBase}. El PR base documental sigue pendiente de merge. Podes abrir el PR del slice igual si el humano mergea en orden.`);
151
+ return expectedBase;
152
+ }
153
+
154
+ throw new Error(`create-quiver: el slice no existe en ${expectedBase}. Mergea primero el PR base documental o usa --local para validar solo estructura local.`);
155
+ }
156
+
98
157
  function validateDeclaredDependencyContract(repoRoot, slice) {
99
158
  const declaredDependsOn = Array.isArray(slice.json.depends_on) ? slice.json.depends_on : null;
100
159
  const declaredParallelSafe = typeof slice.json.parallel_safe === 'string' ? slice.json.parallel_safe.trim() : '';
@@ -147,33 +206,43 @@ function validateDeclaredDependencyContract(repoRoot, slice) {
147
206
 
148
207
  function checkSliceReadiness(sliceInput, options = {}) {
149
208
  const gate = options.gate || 'execution';
209
+ const localMode = options.local === true;
150
210
  const strictOverlap = options.strictOverlap === true;
211
+ const remote = options.remote || 'origin';
151
212
  const repoRoot = runGit(['rev-parse', '--show-toplevel'], process.cwd());
152
213
  const slice = resolveSliceContext(repoRoot, sliceInput);
214
+ const baseBranch = options.baseBranch || slice.baseBranch || 'develop';
153
215
 
154
216
  for (const specFile of ['SPEC.md', 'STATUS.md', 'EVIDENCE_REPORT.md']) {
155
217
  ensureExists(path.join(repoRoot, slice.specDirRel, specFile), `create-quiver: falta '${slice.specDirRel}/${specFile}'.`);
156
218
  }
157
219
  console.log('PASS: El spec local tiene SPEC.md, STATUS.md y EVIDENCE_REPORT.md.');
158
220
 
159
- if (catFileExists(repoRoot, `origin/develop:${slice.sliceRel}`)) {
160
- console.log('PASS: El slice ya existe en origin/develop (PR base documental mergeado).');
161
- } else if (gate === 'validation') {
162
- console.log('WARN: El slice no existe todavia en origin/develop. El PR base documental sigue pendiente de merge. Podes abrir el PR del slice igual el humano mergea en orden.');
221
+ let baseRef = null;
222
+ if (localMode) {
223
+ validateLocalSliceArtifacts(repoRoot, slice);
224
+ console.log(`INFO: Modo local: se omite validacion de existencia del slice en ${remote}/${baseBranch} o ${baseBranch}.`);
225
+ console.log('INFO: Modo local: se omite validacion de overlap contra worktrees activos basada en rama remota/base.');
163
226
  } else {
164
- throw new Error('create-quiver: el slice no existe en origin/develop. Mergea primero el PR base documental.');
227
+ baseRef = validateSliceDocumentedOnBase(repoRoot, slice, {
228
+ baseBranch,
229
+ gate,
230
+ remote,
231
+ });
165
232
  }
166
233
 
167
- const overlapWarnings = collectOverlapWarnings(repoRoot, currentBranch(repoRoot), slice.files);
168
- if (overlapWarnings.length === 0) {
169
- console.log('PASS: No se detecto overlap con worktrees activos.');
170
- } else {
171
- for (const warning of overlapWarnings) {
172
- const [overlapBranch, overlapFiles] = warning.split('|');
173
- if (strictOverlap) {
174
- throw new Error(`create-quiver: Overlap con worktree activo '${overlapBranch}': ${overlapFiles}`);
234
+ if (!localMode) {
235
+ const overlapWarnings = collectOverlapWarnings(repoRoot, currentBranch(repoRoot), slice.files, baseRef || `${remote}/${baseBranch}`);
236
+ if (overlapWarnings.length === 0) {
237
+ console.log('PASS: No se detecto overlap con worktrees activos.');
238
+ } else {
239
+ for (const warning of overlapWarnings) {
240
+ const [overlapBranch, overlapFiles] = warning.split('|');
241
+ if (strictOverlap) {
242
+ throw new Error(`create-quiver: Overlap con worktree activo '${overlapBranch}': ${overlapFiles}`);
243
+ }
244
+ console.log(`WARN: Overlap con worktree activo '${overlapBranch}': ${overlapFiles}`);
175
245
  }
176
- console.log(`WARN: Overlap con worktree activo '${overlapBranch}': ${overlapFiles}`);
177
246
  }
178
247
  }
179
248
 
@@ -226,8 +295,8 @@ function checkPrReadiness(sliceInput) {
226
295
  const current = currentBranch(repoRoot);
227
296
  const prPath = path.join(path.dirname(slice.sliceAbs), 'pr.md');
228
297
 
229
- checkSliceReadiness(slice.sliceAbs, { gate: 'validation' });
230
- checkScope(slice.sliceAbs, { strict: true });
298
+ checkSliceReadiness(slice.sliceRel, { gate: 'validation' });
299
+ checkScope(slice.sliceRel, { strict: true });
231
300
 
232
301
  if (!slice.branchName) {
233
302
  throw new Error('create-quiver: Falta git.branch_name en el slice.');
@@ -1,5 +1,130 @@
1
+ const { statusPorcelain } = require('./git');
2
+ const { normalizeContextPath } = require('./ai/safety');
1
3
  const { checkScope } = require('./readiness');
2
4
 
5
+ class ScopeValidationError extends Error {
6
+ constructor(code, message, details = {}) {
7
+ super(message);
8
+ this.name = 'ScopeValidationError';
9
+ this.code = code;
10
+ this.details = details;
11
+ }
12
+ }
13
+
14
+ function formatError(message) {
15
+ return `create-quiver: ${message}`;
16
+ }
17
+
18
+ function normalizeScopePath(filePath) {
19
+ return normalizeContextPath(filePath);
20
+ }
21
+
22
+ function parseStatusPorcelain(text) {
23
+ if (!text) {
24
+ return [];
25
+ }
26
+
27
+ return String(text)
28
+ .split('\n')
29
+ .map((line) => line.trimEnd())
30
+ .filter(Boolean)
31
+ .map((line) => {
32
+ if (line.startsWith('?? ')) {
33
+ return normalizeScopePath(line.slice(3));
34
+ }
35
+
36
+ const entry = (line[2] === ' ' ? line.slice(3) : line[1] === ' ' ? line.slice(2) : line.slice(3)).trim();
37
+ if (!entry) {
38
+ return '';
39
+ }
40
+
41
+ const renamedTarget = entry.includes(' -> ') ? entry.split(' -> ').pop() : entry;
42
+ return normalizeScopePath(renamedTarget);
43
+ })
44
+ .filter(Boolean);
45
+ }
46
+
47
+ function captureWorktreeSnapshot(repoRoot, options = {}) {
48
+ const raw = typeof options.rawStatus === 'string' ? options.rawStatus : statusPorcelain(repoRoot);
49
+ const files = parseStatusPorcelain(raw);
50
+
51
+ return {
52
+ repoRoot,
53
+ raw,
54
+ files,
55
+ };
56
+ }
57
+
58
+ function diffWorktreeSnapshots(beforeSnapshot, afterSnapshot) {
59
+ const beforeFiles = new Set((beforeSnapshot && Array.isArray(beforeSnapshot.files) ? beforeSnapshot.files : []).map(normalizeScopePath));
60
+ const seen = new Set();
61
+ const changedFiles = [];
62
+
63
+ for (const file of afterSnapshot && Array.isArray(afterSnapshot.files) ? afterSnapshot.files : []) {
64
+ const normalized = normalizeScopePath(file);
65
+ if (!normalized || beforeFiles.has(normalized) || seen.has(normalized)) {
66
+ continue;
67
+ }
68
+
69
+ seen.add(normalized);
70
+ changedFiles.push(normalized);
71
+ }
72
+
73
+ return changedFiles;
74
+ }
75
+
76
+ function validateScopeSnapshot({ allowedFiles = [], beforeSnapshot, afterSnapshot, strict = true } = {}) {
77
+ const normalizedAllowedFiles = new Set(
78
+ Array.isArray(allowedFiles)
79
+ ? allowedFiles.map(normalizeScopePath).filter(Boolean)
80
+ : [],
81
+ );
82
+ const changedFiles = diffWorktreeSnapshots(beforeSnapshot, afterSnapshot);
83
+ const outOfScopeFiles = changedFiles.filter((file) => !normalizedAllowedFiles.has(file));
84
+
85
+ if (outOfScopeFiles.length === 0) {
86
+ return {
87
+ ok: true,
88
+ changedFiles,
89
+ outOfScopeFiles,
90
+ allowedFiles: Array.from(normalizedAllowedFiles),
91
+ beforeSnapshot,
92
+ afterSnapshot,
93
+ };
94
+ }
95
+
96
+ const message = formatError(
97
+ `scope violation detected: changed files outside slice.json.files: ${outOfScopeFiles.join(', ')}`,
98
+ );
99
+ const error = new ScopeValidationError('SCOPE_VIOLATION', message, {
100
+ allowedFiles: Array.from(normalizedAllowedFiles),
101
+ beforeSnapshot,
102
+ afterSnapshot,
103
+ changedFiles,
104
+ outOfScopeFiles,
105
+ });
106
+
107
+ if (strict) {
108
+ throw error;
109
+ }
110
+
111
+ return {
112
+ ok: false,
113
+ changedFiles,
114
+ outOfScopeFiles,
115
+ allowedFiles: Array.from(normalizedAllowedFiles),
116
+ beforeSnapshot,
117
+ afterSnapshot,
118
+ error,
119
+ };
120
+ }
121
+
3
122
  module.exports = {
123
+ ScopeValidationError,
124
+ captureWorktreeSnapshot,
125
+ diffWorktreeSnapshots,
4
126
  checkScope,
127
+ normalizeScopePath,
128
+ parseStatusPorcelain,
129
+ validateScopeSnapshot,
5
130
  };
@@ -34,6 +34,10 @@ function naturalNumberFromSliceId(sliceId) {
34
34
  return match ? Number.parseInt(match[1], 10) : Number.POSITIVE_INFINITY;
35
35
  }
36
36
 
37
+ function isFoundationSliceId(sliceId) {
38
+ return naturalNumberFromSliceId(sliceId) === 0;
39
+ }
40
+
37
41
  function compareSliceRefs(a, b) {
38
42
  const left = String(a || '');
39
43
  const right = String(b || '');
@@ -139,6 +143,7 @@ function readAllSlices(rootDir) {
139
143
  parallel_safe: typeof json.parallel_safe === 'string' ? json.parallel_safe : null,
140
144
  parallel_safe_reason: typeof json.parallel_safe_reason === 'string' ? json.parallel_safe_reason : null,
141
145
  status: typeof json.status === 'string' ? json.status : 'draft',
146
+ ticket: typeof json.ticket === 'string' ? json.ticket : '',
142
147
  title: typeof json.title === 'string' ? json.title : sliceId,
143
148
  json,
144
149
  });
@@ -448,6 +453,8 @@ module.exports = {
448
453
  computeLevels,
449
454
  detectFileConflicts,
450
455
  inferDependencies,
456
+ isFoundationSliceId,
451
457
  readAllSlices,
458
+ naturalNumberFromSliceId,
452
459
  topoSort,
453
460
  };
@@ -1,17 +1,18 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
  const { parseJsonWithComments } = require('./json');
4
- const { resolveTargetRoot, toPosixPath } = require('./paths');
4
+ const { normalizeGitBashDrivePath, relativePosixPath, resolveTargetRoot, specRelativePathFromPath, toPosixPath } = require('./paths');
5
5
 
6
6
  function readJson(filePath) {
7
7
  return JSON.parse(fs.readFileSync(filePath, 'utf8'));
8
8
  }
9
9
 
10
10
  function canonicalizePath(dirPath) {
11
+ const normalizedPath = normalizeGitBashDrivePath(dirPath);
11
12
  try {
12
- return fs.realpathSync(dirPath);
13
+ return normalizeGitBashDrivePath(fs.realpathSync(normalizedPath));
13
14
  } catch {
14
- return path.resolve(dirPath);
15
+ return path.resolve(normalizedPath);
15
16
  }
16
17
  }
17
18
 
@@ -73,19 +74,19 @@ function validateSliceMetaForStart(slice) {
73
74
  throw new Error('create-quiver: el bloque "git" debe incluir "branch_type", "base_branch", "branch_slug" y "branch_name".');
74
75
  }
75
76
 
76
- const expectedBaseByType = {
77
- feature: 'develop',
78
- bugfix: 'develop',
79
- hotfix: 'main',
77
+ const allowedBaseByType = {
78
+ feature: ['main', 'develop'],
79
+ bugfix: ['main', 'develop'],
80
+ hotfix: ['main'],
80
81
  };
81
82
 
82
- if (!expectedBaseByType[slice.branchType]) {
83
+ if (!allowedBaseByType[slice.branchType]) {
83
84
  throw new Error(`create-quiver: git.branch_type invalido: "${slice.branchType}". Usa "feature", "bugfix" o "hotfix".`);
84
85
  }
85
86
 
86
- const expectedBaseBranch = expectedBaseByType[slice.branchType];
87
- if (slice.baseBranch !== expectedBaseBranch) {
88
- throw new Error(`create-quiver: git.base_branch invalido para ${slice.branchType}. Esperado: "${expectedBaseBranch}".`);
87
+ const allowedBaseBranches = allowedBaseByType[slice.branchType];
88
+ if (!allowedBaseBranches.includes(slice.baseBranch)) {
89
+ throw new Error(`create-quiver: git.base_branch invalido para ${slice.branchType}. Usa "${allowedBaseBranches.join('" o "')}".`);
89
90
  }
90
91
 
91
92
  const expectedBranchName = `${slice.branchType}/${slice.ticket}-${slice.branchSlug}`;
@@ -94,19 +95,61 @@ function validateSliceMetaForStart(slice) {
94
95
  }
95
96
  }
96
97
 
98
+ function isSpecRelativePath(parts) {
99
+ return parts[0] === 'specs' || parts[0] === 'specs-fix';
100
+ }
101
+
102
+ function resolveRepoSlicePath(repoRoot, relSlicePath) {
103
+ const candidate = path.join(repoRoot, relSlicePath);
104
+ if (!fs.existsSync(candidate)) {
105
+ return '';
106
+ }
107
+
108
+ return canonicalizePath(candidate);
109
+ }
110
+
97
111
  function resolveSliceContext(repoRoot, slicePath) {
98
- const absSlicePath = resolveSlicePath(slicePath);
99
- const relSlicePath = toPosixPath(path.relative(repoRoot, absSlicePath));
100
- const parts = relSlicePath.split('/');
112
+ const canonicalRepoRoot = canonicalizePath(repoRoot);
113
+ let absSlicePath = resolveSlicePath(slicePath);
114
+ let relSlicePath = relativePosixPath(canonicalRepoRoot, absSlicePath);
115
+ let parts = relSlicePath.split('/');
116
+
117
+ if (!isSpecRelativePath(parts)) {
118
+ const cwdRelSlicePath = relativePosixPath(canonicalizePath(process.cwd()), absSlicePath);
119
+ const cwdParts = cwdRelSlicePath.split('/');
120
+ if (isSpecRelativePath(cwdParts)) {
121
+ relSlicePath = cwdRelSlicePath;
122
+ parts = cwdParts;
123
+ }
124
+ }
125
+
126
+ if (!isSpecRelativePath(parts) && !path.isAbsolute(slicePath)) {
127
+ const inputRelSlicePath = toPosixPath(slicePath).replace(/^\.\/+/, '');
128
+ const inputParts = inputRelSlicePath.split('/');
129
+ if (isSpecRelativePath(inputParts)) {
130
+ relSlicePath = inputRelSlicePath;
131
+ parts = inputParts;
132
+ }
133
+ }
134
+
135
+ if (!isSpecRelativePath(parts)) {
136
+ const candidateRelSlicePath = specRelativePathFromPath(absSlicePath) || specRelativePathFromPath(slicePath);
137
+ const candidateAbsSlicePath = candidateRelSlicePath ? resolveRepoSlicePath(canonicalRepoRoot, candidateRelSlicePath) : '';
138
+ if (candidateAbsSlicePath) {
139
+ relSlicePath = candidateRelSlicePath;
140
+ parts = relSlicePath.split('/');
141
+ absSlicePath = candidateAbsSlicePath;
142
+ }
143
+ }
101
144
 
102
- if (parts[0] !== 'specs' && parts[0] !== 'specs-fix') {
145
+ if (!isSpecRelativePath(parts)) {
103
146
  throw new Error('create-quiver: el slice debe vivir dentro de specs/ o specs-fix/.');
104
147
  }
105
148
 
106
149
  const specFamily = parts[0];
107
150
  const specSlug = parts[1];
108
151
  const specDirRel = `${specFamily}/${specSlug}`;
109
- const specDirAbs = path.join(repoRoot, specDirRel);
152
+ const specDirAbs = path.join(canonicalRepoRoot, specDirRel);
110
153
  const slice = readSliceMeta(absSlicePath);
111
154
  slice.specFamily = specFamily;
112
155
  slice.specSlug = specSlug;