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