create-quiver 0.15.4 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/pull_request_template.md +17 -0
- package/.github/workflows/ci.yml +76 -0
- package/.markdown-link-check.json +15 -0
- package/.markdownlint.json +11 -0
- package/ARCHITECTURE.md +133 -0
- package/CHANGELOG.md +16 -0
- package/CONTRIBUTING.md +174 -9
- package/README.md +17 -2
- package/README_FOR_AI.md +4 -1
- package/ROADMAP.md +4 -0
- package/SECURITY.md +9 -2
- package/docs/AI_CONTEXT.md.es.template +3 -1
- package/docs/AI_CONTEXT.md.template +3 -1
- package/docs/CLI_UX_GUIDE.md +20 -1
- package/docs/COMMANDS.md.template +20 -6
- package/docs/GITFLOW_PR_GUIDE.md +73 -11
- package/docs/GITFLOW_PR_GUIDE.md.es.template +61 -2
- package/docs/GITFLOW_PR_GUIDE.md.template +72 -10
- package/docs/INDEX.md +6 -1
- package/docs/QUICK.md.template +2 -1
- package/docs/STANDARD.md.template +2 -1
- package/docs/WORKFLOW.md.es.template +3 -1
- package/docs/WORKFLOW.md.template +6 -4
- package/docs/getting-started/installation.md +7 -0
- package/docs/reference/commands.md +138 -6
- package/docs/reference/slice-schema.md +37 -0
- package/docs/schema/slice.schema.json +221 -0
- package/docs/specs/01-spec/01-slice/01-slice.json +36 -0
- package/docs/specs/01-spec/01-slice/01-slice.md +106 -0
- package/docs/specs/01-spec/01-slice/CLOSURE_BRIEF.md +80 -0
- package/docs/specs/01-spec/01-slice/EXECUTION_BRIEF.md +39 -0
- package/docs/specs/01-spec/02-slice/02-slice.json +36 -0
- package/docs/specs/01-spec/02-slice/02-slice.md +108 -0
- package/docs/specs/01-spec/02-slice/CLOSURE_BRIEF.md +88 -0
- package/docs/specs/01-spec/02-slice/EXECUTION_BRIEF.md +40 -0
- package/docs/specs/01-spec/03-slice/03-slice.json +36 -0
- package/docs/specs/01-spec/03-slice/03-slice.md +103 -0
- package/docs/specs/01-spec/03-slice/CLOSURE_BRIEF.md +54 -0
- package/docs/specs/01-spec/03-slice/EXECUTION_BRIEF.md +39 -0
- package/docs/specs/01-spec/04-slice/04-slice.json +36 -0
- package/docs/specs/01-spec/04-slice/04-slice.md +107 -0
- package/docs/specs/01-spec/04-slice/CLOSURE_BRIEF.md +46 -0
- package/docs/specs/01-spec/04-slice/EXECUTION_BRIEF.md +39 -0
- package/docs/specs/01-spec/05-slice/05-slice.json +36 -0
- package/docs/specs/01-spec/05-slice/05-slice.md +106 -0
- package/docs/specs/01-spec/05-slice/CLOSURE_BRIEF.md +84 -0
- package/docs/specs/01-spec/05-slice/EXECUTION_BRIEF.md +109 -0
- package/docs/specs/01-spec/06-slice/06-slice.json +36 -0
- package/docs/specs/01-spec/06-slice/06-slice.md +107 -0
- package/docs/specs/01-spec/06-slice/CLOSURE_BRIEF.md +67 -0
- package/docs/specs/01-spec/06-slice/EXECUTION_BRIEF.md +39 -0
- package/docs/specs/01-spec/07-slice/07-slice.json +36 -0
- package/docs/specs/01-spec/07-slice/07-slice.md +105 -0
- package/docs/specs/01-spec/07-slice/CLOSURE_BRIEF.md +71 -0
- package/docs/specs/01-spec/07-slice/EXECUTION_BRIEF.md +39 -0
- package/docs/specs/01-spec/08-slice/08-slice.json +36 -0
- package/docs/specs/01-spec/08-slice/08-slice.md +105 -0
- package/docs/specs/01-spec/08-slice/CLOSURE_BRIEF.md +114 -0
- package/docs/specs/01-spec/08-slice/EXECUTION_BRIEF.md +39 -0
- package/docs/specs/01-spec/CLOSURE_BRIEF.md +87 -0
- package/docs/specs/01-spec/spec.md +197 -0
- package/docs/workflows/full-ai-spec-to-pr.md +46 -3
- package/i18n/es/docs/GITFLOW_PR_GUIDE.md.template +38 -1
- package/package.json +27 -1
- package/scripts/package-quiver.sh +82 -2
- package/scripts/release-quiver.sh +14 -3
- package/specs/[project-name]/slices/pr.md.template +19 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/command-language-mode-matrix.json +122 -1
- package/specs/quiver-v46-deep-project-analysis/EVIDENCE_REPORT.md +94 -0
- package/specs/quiver-v46-deep-project-analysis/EXECUTION_PLAN.md +26 -0
- package/specs/quiver-v46-deep-project-analysis/SPEC.md +157 -0
- package/specs/quiver-v46-deep-project-analysis/STATUS.md +26 -0
- package/specs/quiver-v46-deep-project-analysis/pr.md +131 -0
- package/specs/quiver-v46-deep-project-analysis/slices/slice-00-analysis-contract-foundation/CLOSURE_BRIEF.md +14 -0
- package/specs/quiver-v46-deep-project-analysis/slices/slice-00-analysis-contract-foundation/EXECUTION_BRIEF.md +41 -0
- package/specs/quiver-v46-deep-project-analysis/slices/slice-00-analysis-contract-foundation/slice.json +61 -0
- package/specs/quiver-v46-deep-project-analysis/slices/slice-01-stack-agnostic-discovery-sampling/CLOSURE_BRIEF.md +22 -0
- package/specs/quiver-v46-deep-project-analysis/slices/slice-01-stack-agnostic-discovery-sampling/EXECUTION_BRIEF.md +33 -0
- package/specs/quiver-v46-deep-project-analysis/slices/slice-01-stack-agnostic-discovery-sampling/slice.json +80 -0
- package/specs/quiver-v46-deep-project-analysis/slices/slice-02-provider-analysis-json-contract/CLOSURE_BRIEF.md +21 -0
- package/specs/quiver-v46-deep-project-analysis/slices/slice-02-provider-analysis-json-contract/EXECUTION_BRIEF.md +34 -0
- package/specs/quiver-v46-deep-project-analysis/slices/slice-02-provider-analysis-json-contract/slice.json +79 -0
- package/specs/quiver-v46-deep-project-analysis/slices/slice-03-doc-proposal-review-safe-writes/CLOSURE_BRIEF.md +19 -0
- package/specs/quiver-v46-deep-project-analysis/slices/slice-03-doc-proposal-review-safe-writes/EXECUTION_BRIEF.md +33 -0
- package/specs/quiver-v46-deep-project-analysis/slices/slice-03-doc-proposal-review-safe-writes/slice.json +79 -0
- package/specs/quiver-v46-deep-project-analysis/slices/slice-04-validation-docs-release-readiness/CLOSURE_BRIEF.md +20 -0
- package/specs/quiver-v46-deep-project-analysis/slices/slice-04-validation-docs-release-readiness/EXECUTION_BRIEF.md +32 -0
- package/specs/quiver-v46-deep-project-analysis/slices/slice-04-validation-docs-release-readiness/slice.json +85 -0
- package/specs/quiver-v50-audit-trust-foundation/EVIDENCE_REPORT.md +151 -0
- package/specs/quiver-v50-audit-trust-foundation/EXECUTION_PLAN.md +34 -0
- package/specs/quiver-v50-audit-trust-foundation/SPEC.md +113 -0
- package/specs/quiver-v50-audit-trust-foundation/STATUS.md +26 -0
- package/specs/quiver-v50-audit-trust-foundation/pr.md +120 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-00-audit-baseline-and-resolved-findings/CLOSURE_BRIEF.md +20 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-00-audit-baseline-and-resolved-findings/EXECUTION_BRIEF.md +58 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-00-audit-baseline-and-resolved-findings/slice.json +57 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-01-runtime-minimum-and-package-metadata/CLOSURE_BRIEF.md +24 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-01-runtime-minimum-and-package-metadata/EXECUTION_BRIEF.md +67 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-01-runtime-minimum-and-package-metadata/slice.json +71 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-02-migrate-write-safety-contract/CLOSURE_BRIEF.md +24 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-02-migrate-write-safety-contract/EXECUTION_BRIEF.md +71 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-02-migrate-write-safety-contract/slice.json +81 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-03-security-reporting-channel/CLOSURE_BRIEF.md +22 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-03-security-reporting-channel/EXECUTION_BRIEF.md +57 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-03-security-reporting-channel/slice.json +56 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-04-user-facing-i18n-error-coverage/CLOSURE_BRIEF.md +23 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-04-user-facing-i18n-error-coverage/EXECUTION_BRIEF.md +68 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-04-user-facing-i18n-error-coverage/slice.json +84 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-05-init-analyze-progress-and-summaries/CLOSURE_BRIEF.md +25 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-05-init-analyze-progress-and-summaries/EXECUTION_BRIEF.md +73 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-05-init-analyze-progress-and-summaries/slice.json +72 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-06-contributor-and-architecture-docs/CLOSURE_BRIEF.md +22 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-06-contributor-and-architecture-docs/EXECUTION_BRIEF.md +66 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-06-contributor-and-architecture-docs/slice.json +74 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-07-ci-and-documentation-lint-baseline/CLOSURE_BRIEF.md +29 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-07-ci-and-documentation-lint-baseline/EXECUTION_BRIEF.md +74 -0
- package/specs/quiver-v50-audit-trust-foundation/slices/slice-07-ci-and-documentation-lint-baseline/slice.json +81 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/EVIDENCE_REPORT.md +145 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/EXECUTION_PLAN.md +32 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/SPEC.md +109 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/STATUS.md +25 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/pr.md +69 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-00-cli-contract-baseline/CLOSURE_BRIEF.md +20 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-00-cli-contract-baseline/EXECUTION_BRIEF.md +58 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-00-cli-contract-baseline/slice.json +56 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-01-flow-json-compatibility/CLOSURE_BRIEF.md +21 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-01-flow-json-compatibility/EXECUTION_BRIEF.md +61 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-01-flow-json-compatibility/slice.json +68 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-02-dashboard-section-validation-i18n/CLOSURE_BRIEF.md +25 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-02-dashboard-section-validation-i18n/EXECUTION_BRIEF.md +65 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-02-dashboard-section-validation-i18n/pr.md +134 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-02-dashboard-section-validation-i18n/slice.json +80 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-03-base-branch-resolution-policy/CLOSURE_BRIEF.md +31 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-03-base-branch-resolution-policy/EXECUTION_BRIEF.md +80 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-03-base-branch-resolution-policy/pr.md +159 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-03-base-branch-resolution-policy/slice.json +102 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-04-next-plan-graph-ux-edge-cases/CLOSURE_BRIEF.md +25 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-04-next-plan-graph-ux-edge-cases/EXECUTION_BRIEF.md +74 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-04-next-plan-graph-ux-edge-cases/pr.md +147 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-04-next-plan-graph-ux-edge-cases/slice.json +91 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-05-evidence-robustness-path-safety/CLOSURE_BRIEF.md +28 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-05-evidence-robustness-path-safety/EXECUTION_BRIEF.md +73 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-05-evidence-robustness-path-safety/pr.md +146 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-05-evidence-robustness-path-safety/slice.json +100 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-06-namespace-compatibility-windows-scripts/CLOSURE_BRIEF.md +36 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-06-namespace-compatibility-windows-scripts/EXECUTION_BRIEF.md +76 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-06-namespace-compatibility-windows-scripts/pr.md +155 -0
- package/specs/quiver-v51-cli-ergonomics-automation-contracts/slices/slice-06-namespace-compatibility-windows-scripts/slice.json +111 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/EVIDENCE_REPORT.md +95 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/EXECUTION_PLAN.md +31 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/SPEC.md +107 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/STATUS.md +22 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/pr.md +69 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/slices/slice-00-schema-docs-release-baseline/CLOSURE_BRIEF.md +21 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/slices/slice-00-schema-docs-release-baseline/EXECUTION_BRIEF.md +60 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/slices/slice-00-schema-docs-release-baseline/slice.json +62 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/slices/slice-01-json-schema-for-slice-json/CLOSURE_BRIEF.md +34 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/slices/slice-01-json-schema-for-slice-json/EXECUTION_BRIEF.md +71 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/slices/slice-01-json-schema-for-slice-json/pr.md +146 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/slices/slice-01-json-schema-for-slice-json/slice.json +106 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/slices/slice-02-generated-cli-reference/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/slices/slice-02-generated-cli-reference/EXECUTION_BRIEF.md +67 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/slices/slice-02-generated-cli-reference/pr.md +144 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/slices/slice-02-generated-cli-reference/slice.json +86 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/slices/slice-03-changelog-package-release-smoke-hygiene/CLOSURE_BRIEF.md +38 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/slices/slice-03-changelog-package-release-smoke-hygiene/EXECUTION_BRIEF.md +75 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/slices/slice-03-changelog-package-release-smoke-hygiene/pr.md +159 -0
- package/specs/quiver-v52-schema-docs-release-hygiene/slices/slice-03-changelog-package-release-smoke-hygiene/slice.json +105 -0
- package/src/create-quiver/commands/ai.js +521 -0
- package/src/create-quiver/commands/changelog.js +93 -0
- package/src/create-quiver/commands/config.js +16 -5
- package/src/create-quiver/commands/evidence.js +33 -2
- package/src/create-quiver/commands/flow.js +1 -0
- package/src/create-quiver/commands/graph.js +8 -2
- package/src/create-quiver/commands/plan.js +6 -0
- package/src/create-quiver/commands/spec.js +28 -13
- package/src/create-quiver/index.js +408 -98
- package/src/create-quiver/lib/ai/analyze-project-discovery.js +387 -0
- package/src/create-quiver/lib/ai/analyze-project-docs.js +364 -0
- package/src/create-quiver/lib/ai/analyze-project-parser.js +277 -0
- package/src/create-quiver/lib/ai/analyze-project-prompts.js +214 -0
- package/src/create-quiver/lib/ai/analyze-project-review.js +99 -0
- package/src/create-quiver/lib/ai/analyze-project-sampling.js +402 -0
- package/src/create-quiver/lib/ai/analyze-project-schema.js +92 -0
- package/src/create-quiver/lib/ai/analyze-project-validation.js +309 -0
- package/src/create-quiver/lib/ai/artifacts.js +4 -1
- package/src/create-quiver/lib/ai/github.js +5 -2
- package/src/create-quiver/lib/ai/spec-templates.js +19 -0
- package/src/create-quiver/lib/cli/command-registry.js +72 -0
- package/src/create-quiver/lib/cli/parser.js +14 -0
- package/src/create-quiver/lib/evidence.js +161 -6
- package/src/create-quiver/lib/git.js +99 -0
- package/src/create-quiver/lib/i18n/messages/en.js +52 -7
- package/src/create-quiver/lib/i18n/messages/es.js +54 -9
- package/src/create-quiver/lib/init-docs.js +1 -1
- package/src/create-quiver/lib/init-layout.js +9 -8
- package/src/create-quiver/lib/lifecycle.js +24 -26
- package/src/create-quiver/lib/readiness.js +67 -56
- package/src/create-quiver/lib/spec-worktrees.js +16 -34
|
@@ -62,6 +62,8 @@ module.exports = {
|
|
|
62
62
|
'spec status': 'Muestra worktree, branch, estado de slice-00 y slices pendientes de una spec.',
|
|
63
63
|
'spec validate': 'Valida docs de spec, slices, briefs, evidencia, estado, dependencias y rutas seguras.',
|
|
64
64
|
'spec close': 'Cierra un worktree de spec mergeado y limpio, y guia la sincronizacion local.',
|
|
65
|
+
'slice start|check|pr|scope|cleanup|refresh-active': 'Namespace canonico para ciclo de vida, validacion, scope y tableros de slices.',
|
|
66
|
+
'handoff check|new': 'Namespace canonico para validar o crear artefactos de handoff.',
|
|
65
67
|
'start-slice': 'Inicia trabajo en un slice y lo marca activo.',
|
|
66
68
|
'check-slice': 'Valida estructura, dependencias, scope y preparacion de un slice.',
|
|
67
69
|
'check-pr': 'Valida preparacion de PR para un workflow de slice/spec.',
|
|
@@ -89,7 +91,7 @@ module.exports = {
|
|
|
89
91
|
'For config language set, write the global user config': 'En config language set, escribe la configuracion global del usuario',
|
|
90
92
|
'Include completed slices in dashboard, plan, graph, or next history output': 'Incluye slices completados en dashboard, plan, graph o historial de next',
|
|
91
93
|
'Show the full human dashboard report': 'Muestra el reporte humano completo de dashboard',
|
|
92
|
-
'Show one human dashboard section': 'Muestra una seccion humana de dashboard',
|
|
94
|
+
'Show one human dashboard section': 'Muestra una seccion humana de dashboard (overview, specs, slices, blockers, warnings, agents, approvals, runs, active-slice, next-steps)',
|
|
93
95
|
'Limit dashboard human lists (1-100)': 'Limita listas humanas de dashboard (1-100)',
|
|
94
96
|
'Show only slices with no pending dependencies': 'Muestra solo slices sin dependencias pendientes',
|
|
95
97
|
'List every ready slice returned by next': 'Lista todos los slices listos devueltos por next',
|
|
@@ -121,11 +123,11 @@ module.exports = {
|
|
|
121
123
|
'SSH host alias to validate for prepare or AI commands': 'Alias de host SSH a validar para prepare o comandos de IA',
|
|
122
124
|
'SSH identity file to validate for prepare or AI commands': 'Archivo de identidad SSH a validar para prepare o comandos de IA',
|
|
123
125
|
'Git remote name for check-slice or AI PR checks': 'Nombre del remote Git para check-slice o checks de PR de IA',
|
|
124
|
-
'Base branch for check-slice, check-scope, ai pr, or spec close
|
|
126
|
+
'Base branch override for check-slice, check-scope, check-pr, ai pr, spec start, or spec close': 'Override de branch base para check-slice, check-scope, check-pr, ai pr, spec start o spec close',
|
|
125
127
|
'Output file for evidence run': 'Archivo de salida para evidence run',
|
|
126
128
|
'Maximum stdout/stderr chars per evidence section': 'Maximo de caracteres stdout/stderr por seccion de evidencia',
|
|
127
129
|
'Override PR title for ai pr create': 'Anula el titulo del PR para ai pr create',
|
|
128
|
-
'Skip prompts and
|
|
130
|
+
'Skip prompts and confirm write prompts such as migrate': 'Omite prompts y confirma escrituras como migrate',
|
|
129
131
|
'Show the installed create-quiver version': 'Muestra la version instalada de create-quiver',
|
|
130
132
|
'Show this help message': 'Muestra este mensaje de ayuda',
|
|
131
133
|
},
|
|
@@ -143,6 +145,9 @@ module.exports = {
|
|
|
143
145
|
'common.unknown': 'desconocido',
|
|
144
146
|
'common.warning': 'Advertencia: {message}',
|
|
145
147
|
'common.yes': 'si',
|
|
148
|
+
'config.error.unsupported_language': 'idioma no compatible: {language}. Idiomas soportados: {supported}. Ejecuta: npx create-quiver config language set {fallback}',
|
|
149
|
+
'config.error.unsupported_language_command': 'comando de idioma de config no compatible: {command}. Comandos soportados: show, set',
|
|
150
|
+
'config.error.unsupported_section': 'seccion de config no compatible: {section}. Secciones soportadas: language',
|
|
146
151
|
'ai_task.command': 'Comando: {command}',
|
|
147
152
|
'ai_task.context_pack': 'Pack de contexto: {context}',
|
|
148
153
|
'ai_task.documentation_debt': 'Deuda documental: {count}',
|
|
@@ -435,6 +440,14 @@ module.exports = {
|
|
|
435
440
|
'analyze.detected_package_manager': 'Package manager detectado: {manager}',
|
|
436
441
|
'analyze.detected_primary_stack': 'Stack principal detectado: {stack}',
|
|
437
442
|
'analyze.dry_run_for': 'Dry-run de analisis del proyecto para {path}',
|
|
443
|
+
'analyze.progress.artifacts_written': 'Artefactos de analisis escritos',
|
|
444
|
+
'analyze.progress.context_refreshed': 'Contexto de IA actualizado',
|
|
445
|
+
'analyze.progress.refreshing_context': 'Actualizando contexto de IA...',
|
|
446
|
+
'analyze.progress.scanned': 'Escaneo del proyecto completado',
|
|
447
|
+
'analyze.progress.scanning': 'Escaneando proyecto...',
|
|
448
|
+
'analyze.progress.state_updated': 'Estado de analisis actualizado',
|
|
449
|
+
'analyze.progress.updating_state': 'Actualizando estado de Quiver...',
|
|
450
|
+
'analyze.progress.writing_artifacts': 'Escribiendo artefactos de analisis...',
|
|
438
451
|
'analyze.would_refresh': 'Actualizaria {path}',
|
|
439
452
|
'analyze.would_write': 'Escribiria {path}',
|
|
440
453
|
'analyze.writes_none': 'Escrituras: ninguna',
|
|
@@ -467,7 +480,11 @@ module.exports = {
|
|
|
467
480
|
'demo.title.created': 'Demo de Quiver creado',
|
|
468
481
|
'demo.title.dry_run': 'Dry-run de demo Quiver',
|
|
469
482
|
'evidence.command': 'Comando: {command}',
|
|
483
|
+
'evidence.error.missing_command': 'evidence run requiere un comando despues de --',
|
|
484
|
+
'evidence.error.missing_subcommand': 'falta el subcomando de evidence. Usa: npx create-quiver evidence <run|list|show>',
|
|
470
485
|
'evidence.exit_code': 'Codigo de salida: {code}',
|
|
486
|
+
'evidence.list.empty': 'No se encontraron archivos de evidencia.',
|
|
487
|
+
'evidence.list.title': 'Archivos de evidencia de Quiver',
|
|
471
488
|
'evidence.output': 'Salida: {path}',
|
|
472
489
|
'evidence.recorded': 'Evidencia de Quiver registrada',
|
|
473
490
|
'init.agent_guidance.show.hint': 'No guarda credenciales ni ejecuta providers',
|
|
@@ -494,6 +511,14 @@ module.exports = {
|
|
|
494
511
|
'init.next_steps.review_agents': 'Revisa AGENTS.md y despues {path}',
|
|
495
512
|
'init.next_steps.review_workflow': 'Revisa {path}',
|
|
496
513
|
'init.next_steps.title': 'Proximos pasos:',
|
|
514
|
+
'init.progress.docs_written': 'Docs de init escritos',
|
|
515
|
+
'init.progress.exporting_templates': 'Exportando templates de compatibilidad...',
|
|
516
|
+
'init.progress.install_checked': 'Instalacion del paquete verificada',
|
|
517
|
+
'init.progress.installing_package': 'Verificando instalacion de create-quiver...',
|
|
518
|
+
'init.progress.preparing_templates': 'Preparando templates empaquetados...',
|
|
519
|
+
'init.progress.templates_exported': 'Templates de compatibilidad exportados',
|
|
520
|
+
'init.progress.templates_ready': 'Templates empaquetados listos',
|
|
521
|
+
'init.progress.writing_docs': 'Escribiendo docs de init...',
|
|
497
522
|
'init.profile.default.hint': 'Contrato AI-first recomendado',
|
|
498
523
|
'init.profile.full.hint': 'Incluye compatibilidad historica y templates visibles',
|
|
499
524
|
'init.profile.minimal.hint': 'Solo documentos esenciales',
|
|
@@ -511,6 +536,9 @@ module.exports = {
|
|
|
511
536
|
'init.summary.project': 'Proyecto',
|
|
512
537
|
'init.summary.title': 'Configuracion elegida',
|
|
513
538
|
'migrate.completed_for': 'Migracion de Quiver completada para {path}',
|
|
539
|
+
'migrate.confirm.declined': 'migrate cancelado. No se escribieron archivos.',
|
|
540
|
+
'migrate.confirm.prompt': 'Este comando modificara archivos del proyecto en {path}. Ejecuta `npx create-quiver migrate --dry-run` para previsualizar. Continuar?',
|
|
541
|
+
'migrate.confirm.required': 'migrate requiere confirmacion antes de modificar archivos del proyecto. Ejecuta `npx create-quiver migrate --dry-run` para previsualizar, o pasa `--yes` para continuar en automatizacion.',
|
|
514
542
|
'migrate.dry_run_title': 'Dry-run de migracion de Quiver',
|
|
515
543
|
'migrate.legacy_preserved': 'Layout legacy detectado y preservado: {paths}',
|
|
516
544
|
'migrate.next_command': 'Proximo comando: {command}',
|
|
@@ -577,7 +605,9 @@ module.exports = {
|
|
|
577
605
|
'flow.stage.technical-plan-stale': 'el plan tecnico necesita revision',
|
|
578
606
|
'flow.suggested_sequence': 'Secuencia sugerida',
|
|
579
607
|
'flow.title': 'Flujo guiado de Quiver',
|
|
608
|
+
'graph.empty.level': 'No se encontraron slices para el nivel de graph {level}.',
|
|
580
609
|
'graph.empty.pending': 'No se encontraron slices pendientes.',
|
|
610
|
+
'graph.error.unsupported_format': 'formato de graph no compatible: {format}',
|
|
581
611
|
'graph.level': 'Nivel {level}',
|
|
582
612
|
'graph.lots_count': {
|
|
583
613
|
one: '{count} lote',
|
|
@@ -609,6 +639,10 @@ module.exports = {
|
|
|
609
639
|
'plan.header.status': 'ESTADO',
|
|
610
640
|
'plan.header.ticket': 'TICKET',
|
|
611
641
|
'plan.header.title': 'TITULO',
|
|
642
|
+
'plan.missing_estimates_note': {
|
|
643
|
+
one: 'Nota: {count} slice no tiene estimated_hours positivo y cuenta como 0h.',
|
|
644
|
+
other: 'Nota: {count} slices no tienen estimated_hours positivo y cuentan como 0h.',
|
|
645
|
+
},
|
|
612
646
|
'plan.title': 'Plan de Quiver',
|
|
613
647
|
'plan.title.including_completed': 'Plan de Quiver (incluye completados)',
|
|
614
648
|
'plan.title.ready': 'Slices listos',
|
|
@@ -780,11 +814,11 @@ module.exports = {
|
|
|
780
814
|
'lifecycle.cleanup.dry_run.branch': 'DRY RUN: git branch {flag} {branch}',
|
|
781
815
|
'lifecycle.cleanup.dry_run.slice': 'DRY RUN: slice={slice} branch={branch}',
|
|
782
816
|
'lifecycle.cleanup.dry_run.worktree': 'DRY RUN: git worktree remove {force}{path}',
|
|
783
|
-
'lifecycle.cleanup.error.branch': 'el cleanup normal debe correrse desde
|
|
784
|
-
'lifecycle.cleanup.error.
|
|
817
|
+
'lifecycle.cleanup.error.branch': 'el cleanup normal debe correrse desde {base}. Rama actual: {branch}',
|
|
818
|
+
'lifecycle.cleanup.error.base_stale': '{base} local no esta actualizado respecto de {ref}. Ejecuta git pull --ff-only antes del cleanup.',
|
|
785
819
|
'lifecycle.cleanup.error.dirty': 'el checkout actual no esta limpio. Limpialo antes del cleanup.',
|
|
786
820
|
'lifecycle.cleanup.error.missing': "no existe worktree ni rama local para '{slice}'.",
|
|
787
|
-
'lifecycle.cleanup.error.unmerged': "la rama '{branch}' no esta mergeada en
|
|
821
|
+
'lifecycle.cleanup.error.unmerged': "la rama '{branch}' no esta mergeada en {ref}. Usa --discard si el slice se descarta.",
|
|
788
822
|
'lifecycle.cleanup.finished': "PASS: Cleanup finalizado para '{slice}'.",
|
|
789
823
|
'lifecycle.cleanup.removed_active_slice': 'PASS: ACTIVE_SLICE.md eliminado',
|
|
790
824
|
'lifecycle.cleanup.removed_branch': 'PASS: Rama local eliminada: {branch}',
|
|
@@ -839,15 +873,15 @@ module.exports = {
|
|
|
839
873
|
'readiness.pr.branch.pass': 'PASS: La rama actual coincide con la rama declarada por el slice.',
|
|
840
874
|
'readiness.pr.case.pass': 'PASS: Al menos un caso de uso documentado.',
|
|
841
875
|
'readiness.pr.clean.pass': 'PASS: El worktree esta limpio.',
|
|
842
|
-
'readiness.pr.commits.pass': 'PASS: La rama tiene commits propios contra
|
|
843
|
-
'readiness.pr.error.absorbed': 'La rama ya fue absorbida por
|
|
876
|
+
'readiness.pr.commits.pass': 'PASS: La rama tiene commits propios contra {ref}.',
|
|
877
|
+
'readiness.pr.error.absorbed': 'La rama ya fue absorbida por {ref}. Este gate aplica antes del merge.',
|
|
844
878
|
'readiness.pr.error.dirty': 'El worktree no esta limpio. Cerra la implementacion antes de abrir el PR.',
|
|
845
879
|
'readiness.pr.error.missing_branch': 'Falta git.branch_name en el slice.',
|
|
846
880
|
'readiness.pr.error.missing_pr': 'Falta pr.md junto al slice.',
|
|
847
881
|
'readiness.pr.error.missing_section': "Falta la seccion obligatoria '{heading}' en pr.md.",
|
|
848
882
|
'readiness.pr.error.missing_subsection': "Falta la subseccion '{subheading}' dentro de How to Test.",
|
|
849
883
|
'readiness.pr.error.no_case': 'How to Test debe tener al menos un caso de uso documentado (#### Case 1: ...).',
|
|
850
|
-
'readiness.pr.error.no_commits': 'La rama no tiene commits propios respecto de
|
|
884
|
+
'readiness.pr.error.no_commits': 'La rama no tiene commits propios respecto de {ref}.',
|
|
851
885
|
'readiness.pr.error.rollback': 'Rollback debe incluir al menos un comando git revert.',
|
|
852
886
|
'readiness.pr.error.wrong_branch': 'Debes ejecutar este check desde la rama del slice. Actual: {actual} Esperada: {expected}',
|
|
853
887
|
'readiness.pr.how_to_test.pass': 'PASS: How to Test incluye entorno, acceso al worktree, arranque, casos de uso y verificacion tecnica.',
|
|
@@ -865,6 +899,11 @@ module.exports = {
|
|
|
865
899
|
'readiness.spec_docs.pass': 'PASS: El spec local tiene SPEC.md, STATUS.md y EVIDENCE_REPORT.md.',
|
|
866
900
|
'readiness.warn': 'WARN: {message}',
|
|
867
901
|
'spec_create.confirm_create': 'Crear spec "{slug}"?',
|
|
902
|
+
'spec_create.error.approval_declined': 'aprobacion interactiva de spec create rechazada. No se escribieron archivos.',
|
|
903
|
+
'spec_create.error.interactive_tty_required': 'spec create --interactive requiere una TTY interactiva. Usa --input, --spec, --review y --dry-run para automatizacion no interactiva.',
|
|
904
|
+
'spec_create.error.review_canceled': '{reason}\nArtefacto de revision: {path}',
|
|
905
|
+
'spec_create.error.review_canceled.default_reason': 'la revision de spec create fue cancelada.',
|
|
906
|
+
'spec_create.error.review_tty_required': 'spec create --review requiere una terminal interactiva o un editor inyectado.\nArtefacto de revision: {path}',
|
|
868
907
|
'spec_create.input.approved_plan_hint': 'Plan tecnico revisado y aprobado',
|
|
869
908
|
'spec_create.label.files_written': 'Archivos escritos: {count}',
|
|
870
909
|
'spec_create.label.input_file': 'Archivo de entrada: {path}',
|
|
@@ -932,6 +971,12 @@ module.exports = {
|
|
|
932
971
|
'spec_validate.strict': 'Estricto: {value}',
|
|
933
972
|
'spec_validate.title': 'Validacion de spec de Quiver',
|
|
934
973
|
'spec_validate.warnings': 'Advertencias:',
|
|
974
|
+
'spec.error.directory_not_found': 'directorio de spec no encontrado: {path}',
|
|
975
|
+
'spec.error.directory_already_exists': 'el directorio de spec ya existe: {path}',
|
|
976
|
+
'spec.error.missing_approved_plan_input': 'falta el input de plan revisado y aprobado: {path}',
|
|
977
|
+
'spec.error.missing_directory_command': 'falta el directorio de spec. Usa: npx create-quiver spec <start|status|validate|close> <spec-dir>',
|
|
978
|
+
'spec.error.missing_directory_validate': 'falta el directorio de spec. Usa: npx create-quiver spec validate specs/<spec-slug>',
|
|
979
|
+
'spec.error.validate_failed': 'fallo spec validate para {path}',
|
|
935
980
|
'status.blocked': 'bloqueado',
|
|
936
981
|
'status.cancelled': 'cancelado',
|
|
937
982
|
'status.active': 'activo',
|
|
@@ -645,7 +645,7 @@ Use this section only for projects generated with the full compatibility layout.
|
|
|
645
645
|
5. Check the next ready slice with \`{{NEXT_COMMAND}}\` or \`npm run quiver:next\`.
|
|
646
646
|
6. Start work with \`{{START_SLICE_COMMAND}}\` or \`npm run quiver:start-slice -- <slice.json>\`.
|
|
647
647
|
7. Make one commit per slice.
|
|
648
|
-
8. Open one PR per
|
|
648
|
+
8. Open one PR per slice by default; group slices only when \`docs/GITFLOW_PR_GUIDE.md\` allows it.
|
|
649
649
|
|
|
650
650
|
## Verification Checklist
|
|
651
651
|
|
|
@@ -214,14 +214,15 @@ function resolveInitPackageScripts(profile, options = {}) {
|
|
|
214
214
|
'quiver:spec:status': 'npx create-quiver spec status',
|
|
215
215
|
'quiver:spec:validate': 'npx create-quiver spec validate',
|
|
216
216
|
'quiver:spec:close': 'npx create-quiver spec close',
|
|
217
|
-
'quiver:start-slice': 'npx create-quiver start
|
|
218
|
-
'quiver:check-slice': 'npx create-quiver check
|
|
219
|
-
'quiver:check-pr': 'npx create-quiver
|
|
220
|
-
'quiver:check-handoff': 'npx create-quiver check
|
|
221
|
-
'check-handoff': 'npx create-quiver check
|
|
222
|
-
'quiver:
|
|
223
|
-
'quiver:
|
|
224
|
-
'quiver:
|
|
217
|
+
'quiver:start-slice': 'npx create-quiver slice start',
|
|
218
|
+
'quiver:check-slice': 'npx create-quiver slice check',
|
|
219
|
+
'quiver:check-pr': 'npx create-quiver slice pr',
|
|
220
|
+
'quiver:check-handoff': 'npx create-quiver handoff check',
|
|
221
|
+
'check-handoff': 'npx create-quiver handoff check',
|
|
222
|
+
'quiver:new-handoff': 'npx create-quiver handoff new',
|
|
223
|
+
'quiver:cleanup-slice': 'npx create-quiver slice cleanup',
|
|
224
|
+
'quiver:check-scope': 'npx create-quiver slice scope',
|
|
225
|
+
'quiver:refresh-active-slices': 'npx create-quiver slice refresh-active',
|
|
225
226
|
};
|
|
226
227
|
|
|
227
228
|
if (profile === 'full' || options.legacyScripts === true) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const { branchDelete, catFileExists, currentBranch, fetchBranch, fetchRemote, hasLocalBranch,
|
|
3
|
+
const { branchDelete, catFileExists, currentBranch, fetchBranch, fetchRemote, hasLocalBranch, isGitWorktree, isLinkedWorktree, lsRemoteHeads, mergeBaseIsAncestor, resolveBaseRef: resolveGitBaseRef, revListCount, runGit, statusPorcelain, worktreeAdd, worktreeList, worktreePrune, worktreeRemove } = require('./git');
|
|
4
4
|
const { parseJsonWithComments } = require('./json');
|
|
5
5
|
const { createTranslator } = require('./i18n/catalog');
|
|
6
6
|
const { writeFrontMatter } = require('./init-docs');
|
|
@@ -273,21 +273,14 @@ function refreshActiveSlicesBoard(repoRoot) {
|
|
|
273
273
|
}
|
|
274
274
|
|
|
275
275
|
function resolveBaseRef(repoRoot, baseBranch, translator = lifecycleTranslator()) {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
if (lsRemoteHeads(repoRoot, baseBranch)) {
|
|
283
|
-
try {
|
|
284
|
-
fetchBranch(repoRoot, baseBranch);
|
|
285
|
-
return `origin/${baseBranch}`;
|
|
286
|
-
} catch {
|
|
287
|
-
throw new Error(`create-quiver: ${translator.t('lifecycle.base_ref.fetch_failed', { base: baseBranch })}`);
|
|
288
|
-
}
|
|
276
|
+
const resolution = resolveGitBaseRef(repoRoot, {
|
|
277
|
+
explicitBaseBranch: baseBranch,
|
|
278
|
+
missingOk: true,
|
|
279
|
+
});
|
|
280
|
+
if (resolution.baseRef) {
|
|
281
|
+
return resolution.baseRef;
|
|
289
282
|
}
|
|
290
|
-
throw new Error(`create-quiver: ${translator.t('lifecycle.base_ref.missing', { base: baseBranch, remoteRef: `origin/${baseBranch}` })}`);
|
|
283
|
+
throw new Error(`create-quiver: ${translator.t('lifecycle.base_ref.missing', { base: resolution.baseBranch || baseBranch, remoteRef: `origin/${resolution.baseBranch || baseBranch}` })}`);
|
|
291
284
|
}
|
|
292
285
|
|
|
293
286
|
function findExistingWorktreeForBranch(repoRoot, branchName) {
|
|
@@ -470,29 +463,34 @@ function cleanupSlice(sliceInput, options = {}) {
|
|
|
470
463
|
}
|
|
471
464
|
|
|
472
465
|
if (!discard) {
|
|
466
|
+
const base = resolveGitBaseRef(repoRoot, {
|
|
467
|
+
preferredBaseBranch: slice.baseBranch,
|
|
468
|
+
});
|
|
473
469
|
const branch = currentBranch(repoRoot);
|
|
474
|
-
if (branch !==
|
|
475
|
-
throw new Error(`create-quiver: ${translator.t('lifecycle.cleanup.error.branch', { branch })}`);
|
|
470
|
+
if (branch !== base.baseBranch) {
|
|
471
|
+
throw new Error(`create-quiver: ${translator.t('lifecycle.cleanup.error.branch', { branch, base: base.baseBranch })}`);
|
|
476
472
|
}
|
|
477
473
|
if (statusPorcelain(repoRoot) !== '') {
|
|
478
474
|
throw new Error(`create-quiver: ${translator.t('lifecycle.cleanup.error.dirty')}`);
|
|
479
475
|
}
|
|
480
476
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
477
|
+
if (base.remote) {
|
|
478
|
+
try {
|
|
479
|
+
fetchRemote(repoRoot, base.remote, [base.baseBranch]);
|
|
480
|
+
} catch {
|
|
481
|
+
// Local-only test repos and offline environments can still validate against the current remote ref.
|
|
482
|
+
}
|
|
485
483
|
}
|
|
486
484
|
|
|
487
485
|
const localDevelopSha = runGit(['rev-parse', 'HEAD'], repoRoot);
|
|
488
|
-
const remoteDevelopSha = runGit(['rev-parse',
|
|
489
|
-
if (localDevelopSha !== remoteDevelopSha) {
|
|
490
|
-
throw new Error(`create-quiver: ${translator.t('lifecycle.cleanup.error.
|
|
486
|
+
const remoteDevelopSha = runGit(['rev-parse', base.baseRef], repoRoot);
|
|
487
|
+
if (base.remote && localDevelopSha !== remoteDevelopSha) {
|
|
488
|
+
throw new Error(`create-quiver: ${translator.t('lifecycle.cleanup.error.base_stale', { base: base.baseBranch, ref: base.baseRef })}`);
|
|
491
489
|
}
|
|
492
490
|
|
|
493
491
|
if (hasLocalBranch(repoRoot, slice.branchName)) {
|
|
494
|
-
if (!mergeBaseIsAncestor(repoRoot, slice.branchName,
|
|
495
|
-
throw new Error(`create-quiver: ${translator.t('lifecycle.cleanup.error.unmerged', { branch: slice.branchName })}`);
|
|
492
|
+
if (!mergeBaseIsAncestor(repoRoot, slice.branchName, base.baseRef)) {
|
|
493
|
+
throw new Error(`create-quiver: ${translator.t('lifecycle.cleanup.error.unmerged', { branch: slice.branchName, ref: base.baseRef })}`);
|
|
496
494
|
}
|
|
497
495
|
}
|
|
498
496
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const { catFileExists, currentBranch,
|
|
3
|
+
const { catFileExists, currentBranch, mergeBaseIsAncestor, resolveBaseRef, revListCount, runGit, statusPorcelain, worktreeList } = require('./git');
|
|
4
4
|
const { parseJsonWithComments } = require('./json');
|
|
5
5
|
const { createTranslator } = require('./i18n/catalog');
|
|
6
6
|
const { buildGraph, normalizeDeclaredDependencies, readAllSlices, SliceGraphError, topoSort } = require('./slice-graph');
|
|
@@ -62,7 +62,7 @@ function parseWorktrees(text) {
|
|
|
62
62
|
return entries;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
function collectOverlapWarnings(repoRoot, currentBranchName, currentFiles, baseRef
|
|
65
|
+
function collectOverlapWarnings(repoRoot, currentBranchName, currentFiles, baseRef) {
|
|
66
66
|
const sliceMap = new Map();
|
|
67
67
|
walkSlices(path.join(repoRoot, 'specs'), sliceMap, repoRoot);
|
|
68
68
|
walkSlices(path.join(repoRoot, 'specs-fix'), sliceMap, repoRoot);
|
|
@@ -130,6 +130,15 @@ function baseRecoveryMessage(remote, baseBranch, translator) {
|
|
|
130
130
|
return translator.t('readiness.base.recovery', { base: baseBranch, remote, remoteRef: `${remote}/${baseBranch}` });
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
+
function resolveReadinessBase(repoRoot, slice, options = {}) {
|
|
134
|
+
return resolveBaseRef(repoRoot, {
|
|
135
|
+
explicitBaseBranch: options.baseBranch,
|
|
136
|
+
missingOk: true,
|
|
137
|
+
preferredBaseBranch: slice.baseBranch,
|
|
138
|
+
remote: options.remote || 'origin',
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
133
142
|
function resolveReadinessRoot(localMode) {
|
|
134
143
|
try {
|
|
135
144
|
return runGit(['rev-parse', '--show-toplevel'], process.cwd());
|
|
@@ -145,23 +154,23 @@ function validateSliceDocumentedOnBase(repoRoot, slice, options = {}) {
|
|
|
145
154
|
const translator = readinessTranslator(options);
|
|
146
155
|
const gate = options.gate || 'execution';
|
|
147
156
|
const remote = options.remote || 'origin';
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
157
|
+
const base = resolveReadinessBase(repoRoot, slice, {
|
|
158
|
+
baseBranch: options.baseBranch,
|
|
159
|
+
remote,
|
|
160
|
+
});
|
|
152
161
|
|
|
153
|
-
if (
|
|
154
|
-
console.log(translator.t('readiness.documented.remote.pass', { ref:
|
|
155
|
-
return
|
|
162
|
+
if (base.baseRef && base.remote && catFileExists(repoRoot, `${base.baseRef}:${slice.sliceRel}`)) {
|
|
163
|
+
console.log(translator.t('readiness.documented.remote.pass', { ref: base.baseRef }));
|
|
164
|
+
return base.baseRef;
|
|
156
165
|
}
|
|
157
166
|
|
|
158
|
-
if (
|
|
159
|
-
console.log(translator.t('readiness.documented.local.pass', { branch:
|
|
160
|
-
return
|
|
167
|
+
if (base.baseRef && !base.remote && catFileExists(repoRoot, `${base.baseRef}:${slice.sliceRel}`)) {
|
|
168
|
+
console.log(translator.t('readiness.documented.local.pass', { branch: base.baseRef }));
|
|
169
|
+
return base.baseRef;
|
|
161
170
|
}
|
|
162
171
|
|
|
163
|
-
if (!
|
|
164
|
-
const guidance = baseRecoveryMessage(remote, baseBranch, translator);
|
|
172
|
+
if (!base.baseRef) {
|
|
173
|
+
const guidance = baseRecoveryMessage(remote, base.baseBranch || base.candidates.map((candidate) => candidate.branch).join(', '), translator);
|
|
165
174
|
if (gate === 'validation') {
|
|
166
175
|
console.log(translator.t('readiness.warn', { message: guidance }));
|
|
167
176
|
return null;
|
|
@@ -170,13 +179,12 @@ function validateSliceDocumentedOnBase(repoRoot, slice, options = {}) {
|
|
|
170
179
|
throw new Error(`create-quiver: ${guidance}`);
|
|
171
180
|
}
|
|
172
181
|
|
|
173
|
-
const expectedBase = hasRemoteBase ? remoteRef : baseBranch;
|
|
174
182
|
if (gate === 'validation') {
|
|
175
|
-
console.log(translator.t('readiness.documented.missing_validation.warn', { ref:
|
|
176
|
-
return
|
|
183
|
+
console.log(translator.t('readiness.documented.missing_validation.warn', { ref: base.baseRef }));
|
|
184
|
+
return base.baseRef;
|
|
177
185
|
}
|
|
178
186
|
|
|
179
|
-
throw new Error(`create-quiver: ${translator.t('readiness.documented.missing.error', { ref:
|
|
187
|
+
throw new Error(`create-quiver: ${translator.t('readiness.documented.missing.error', { ref: base.baseRef })}`);
|
|
180
188
|
}
|
|
181
189
|
|
|
182
190
|
function validateDeclaredDependencyContract(repoRoot, slice) {
|
|
@@ -246,7 +254,11 @@ function checkSliceReadiness(sliceInput, options = {}) {
|
|
|
246
254
|
const remote = options.remote || 'origin';
|
|
247
255
|
const repoRoot = resolveReadinessRoot(localMode);
|
|
248
256
|
const slice = resolveSliceContext(repoRoot, sliceInput);
|
|
249
|
-
const
|
|
257
|
+
const base = resolveReadinessBase(repoRoot, slice, {
|
|
258
|
+
baseBranch: options.baseBranch,
|
|
259
|
+
remote,
|
|
260
|
+
});
|
|
261
|
+
const baseBranch = base.baseBranch || options.baseBranch || slice.baseBranch || 'main';
|
|
250
262
|
|
|
251
263
|
for (const specFile of ['SPEC.md', 'STATUS.md', 'EVIDENCE_REPORT.md']) {
|
|
252
264
|
ensureExists(path.join(repoRoot, slice.specDirRel, specFile), `create-quiver: falta '${slice.specDirRel}/${specFile}'.`);
|
|
@@ -268,7 +280,7 @@ function checkSliceReadiness(sliceInput, options = {}) {
|
|
|
268
280
|
}
|
|
269
281
|
|
|
270
282
|
if (!localMode) {
|
|
271
|
-
const overlapWarnings = collectOverlapWarnings(repoRoot, currentBranch(repoRoot), slice.files, baseRef ||
|
|
283
|
+
const overlapWarnings = collectOverlapWarnings(repoRoot, currentBranch(repoRoot), slice.files, baseRef || base.baseRef);
|
|
272
284
|
if (overlapWarnings.length === 0) {
|
|
273
285
|
console.log(translator.t('readiness.overlap.none.pass'));
|
|
274
286
|
} else {
|
|
@@ -330,13 +342,31 @@ function checkSliceReadiness(sliceInput, options = {}) {
|
|
|
330
342
|
function checkPrReadiness(sliceInput, options = {}) {
|
|
331
343
|
const translator = readinessTranslator(options);
|
|
332
344
|
const repoRoot = runGit(['rev-parse', '--show-toplevel'], process.cwd());
|
|
333
|
-
const scriptDir = path.dirname(__filename);
|
|
334
345
|
const slice = resolveSliceContext(repoRoot, sliceInput);
|
|
335
346
|
const current = currentBranch(repoRoot);
|
|
336
347
|
const prPath = path.join(path.dirname(slice.sliceAbs), 'pr.md');
|
|
348
|
+
const remote = options.remote || 'origin';
|
|
349
|
+
const base = resolveReadinessBase(repoRoot, slice, {
|
|
350
|
+
baseBranch: options.baseBranch,
|
|
351
|
+
remote,
|
|
352
|
+
});
|
|
337
353
|
|
|
338
|
-
|
|
339
|
-
|
|
354
|
+
if (!base.baseRef) {
|
|
355
|
+
throw new Error(`create-quiver: ${baseRecoveryMessage(remote, base.baseBranch || base.candidates.map((candidate) => candidate.branch).join(', '), translator)}`);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
checkSliceReadiness(slice.sliceRel, {
|
|
359
|
+
baseBranch: base.baseBranch,
|
|
360
|
+
gate: 'validation',
|
|
361
|
+
language: options.language,
|
|
362
|
+
remote,
|
|
363
|
+
});
|
|
364
|
+
checkScope(slice.sliceRel, {
|
|
365
|
+
baseBranch: base.baseBranch,
|
|
366
|
+
language: options.language,
|
|
367
|
+
remote,
|
|
368
|
+
strict: true,
|
|
369
|
+
});
|
|
340
370
|
|
|
341
371
|
if (!slice.branchName) {
|
|
342
372
|
throw new Error(`create-quiver: ${translator.t('readiness.pr.error.missing_branch')}`);
|
|
@@ -353,14 +383,14 @@ function checkPrReadiness(sliceInput, options = {}) {
|
|
|
353
383
|
}
|
|
354
384
|
console.log(translator.t('readiness.pr.clean.pass'));
|
|
355
385
|
|
|
356
|
-
const aheadCount = revListCount(repoRoot,
|
|
386
|
+
const aheadCount = revListCount(repoRoot, `${base.baseRef}..HEAD`);
|
|
357
387
|
if (aheadCount <= 0) {
|
|
358
|
-
if (mergeBaseIsAncestor(repoRoot, 'HEAD',
|
|
359
|
-
throw new Error(`create-quiver: ${translator.t('readiness.pr.error.absorbed')}`);
|
|
388
|
+
if (mergeBaseIsAncestor(repoRoot, 'HEAD', base.baseRef)) {
|
|
389
|
+
throw new Error(`create-quiver: ${translator.t('readiness.pr.error.absorbed', { ref: base.baseRef })}`);
|
|
360
390
|
}
|
|
361
|
-
throw new Error(`create-quiver: ${translator.t('readiness.pr.error.no_commits')}`);
|
|
391
|
+
throw new Error(`create-quiver: ${translator.t('readiness.pr.error.no_commits', { ref: base.baseRef })}`);
|
|
362
392
|
}
|
|
363
|
-
console.log(translator.t('readiness.pr.commits.pass'));
|
|
393
|
+
console.log(translator.t('readiness.pr.commits.pass', { ref: base.baseRef }));
|
|
364
394
|
|
|
365
395
|
const prText = fs.readFileSync(prPath, 'utf8');
|
|
366
396
|
for (const heading of ['## Title', '## Summary', '## Scope', '## Files', '## How to Test (DETAILED - REQUIRED)', '## Evidence', '## Rollback', '## Risks / Notes']) {
|
|
@@ -403,41 +433,22 @@ function checkScope(sliceInput, options = {}) {
|
|
|
403
433
|
const declared = slice.files;
|
|
404
434
|
validateProjectRelativePaths(declared, 'slice scope path');
|
|
405
435
|
|
|
406
|
-
const
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
'main',
|
|
411
|
-
'develop',
|
|
412
|
-
'master',
|
|
413
|
-
].filter(Boolean)));
|
|
414
|
-
|
|
415
|
-
let baseRef = '';
|
|
416
|
-
let baseSource = '';
|
|
417
|
-
for (const candidate of candidateBaseBranches) {
|
|
418
|
-
if (hasRemoteBranch(repoRoot, candidate, remote)) {
|
|
419
|
-
baseRef = `${remote}/${candidate}`;
|
|
420
|
-
baseSource = explicitBaseBranch === candidate ? '--base' : candidate === slice.baseBranch ? 'slice.git.base_branch' : 'fallback';
|
|
421
|
-
break;
|
|
422
|
-
}
|
|
423
|
-
if (hasLocalBranch(repoRoot, candidate)) {
|
|
424
|
-
baseRef = candidate;
|
|
425
|
-
baseSource = explicitBaseBranch === candidate ? '--base' : candidate === slice.baseBranch ? 'slice.git.base_branch' : 'fallback';
|
|
426
|
-
break;
|
|
427
|
-
}
|
|
428
|
-
}
|
|
436
|
+
const base = resolveReadinessBase(repoRoot, slice, {
|
|
437
|
+
baseBranch: options.baseBranch,
|
|
438
|
+
remote,
|
|
439
|
+
});
|
|
429
440
|
|
|
430
441
|
let touchedRaw = '';
|
|
431
|
-
if (baseRef) {
|
|
432
|
-
touchedRaw = runGit(['diff', '--name-only', `${baseRef}...HEAD`], repoRoot);
|
|
433
|
-
console.log(translator.t('readiness.scope.base.info', { ref: baseRef, source:
|
|
442
|
+
if (base.baseRef) {
|
|
443
|
+
touchedRaw = runGit(['diff', '--name-only', `${base.baseRef}...HEAD`], repoRoot);
|
|
444
|
+
console.log(translator.t('readiness.scope.base.info', { ref: base.baseRef, source: base.source }));
|
|
434
445
|
} else {
|
|
435
|
-
console.log(translator.t('readiness.scope.base.warn', { branches:
|
|
446
|
+
console.log(translator.t('readiness.scope.base.warn', { branches: base.candidates.map((candidate) => candidate.branch).join(', ') }));
|
|
436
447
|
return;
|
|
437
448
|
}
|
|
438
449
|
|
|
439
450
|
if (!touchedRaw) {
|
|
440
|
-
console.log(translator.t('readiness.scope.empty.warn', { ref: baseRef }));
|
|
451
|
+
console.log(translator.t('readiness.scope.empty.warn', { ref: base.baseRef }));
|
|
441
452
|
return;
|
|
442
453
|
}
|
|
443
454
|
|
|
@@ -5,12 +5,11 @@ const {
|
|
|
5
5
|
currentBranch,
|
|
6
6
|
fetchRemote,
|
|
7
7
|
hasLocalBranch,
|
|
8
|
-
hasRemoteBranch,
|
|
9
8
|
isGitWorktree,
|
|
10
9
|
isLinkedWorktree,
|
|
11
10
|
isCleanWorktree,
|
|
12
|
-
lsRemoteHeads,
|
|
13
11
|
mergeBaseIsAncestor,
|
|
12
|
+
resolveBaseRef: resolveGitBaseRef,
|
|
14
13
|
runGit,
|
|
15
14
|
statusPorcelain,
|
|
16
15
|
worktreeAdd,
|
|
@@ -175,41 +174,24 @@ function formatDirtyCheckoutRecovery(repoRoot) {
|
|
|
175
174
|
return lines.filter((line) => line !== '').join('\n');
|
|
176
175
|
}
|
|
177
176
|
|
|
178
|
-
function resolveBaseRef(repoRoot, preferred = '') {
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
if (hasRemoteBranch(repoRoot, candidate)) {
|
|
185
|
-
return `origin/${candidate}`;
|
|
186
|
-
}
|
|
187
|
-
if (lsRemoteHeads(repoRoot, candidate)) {
|
|
188
|
-
return `origin/${candidate}`;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
throw new Error(formatError('missing base branch. Expected local or remote main/develop.'));
|
|
177
|
+
function resolveBaseRef(repoRoot, preferred = '', remote = 'origin') {
|
|
178
|
+
const resolution = resolveGitBaseRef(repoRoot, {
|
|
179
|
+
explicitBaseBranch: preferred,
|
|
180
|
+
remote,
|
|
181
|
+
});
|
|
182
|
+
return resolution.baseRef;
|
|
192
183
|
}
|
|
193
184
|
|
|
194
185
|
function resolveMergedBaseRef(repoRoot, preferred = '', remote = 'origin') {
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (hasLocalBranch(repoRoot, candidate)) {
|
|
205
|
-
return {
|
|
206
|
-
baseBranch: candidate,
|
|
207
|
-
baseRef: candidate,
|
|
208
|
-
remote: '',
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
throw new Error(formatError('missing merge base branch. Expected local or remote main/develop.'));
|
|
186
|
+
const resolution = resolveGitBaseRef(repoRoot, {
|
|
187
|
+
explicitBaseBranch: preferred,
|
|
188
|
+
remote,
|
|
189
|
+
});
|
|
190
|
+
return {
|
|
191
|
+
baseBranch: resolution.baseBranch,
|
|
192
|
+
baseRef: resolution.baseRef,
|
|
193
|
+
remote: resolution.remote,
|
|
194
|
+
};
|
|
213
195
|
}
|
|
214
196
|
|
|
215
197
|
function buildSpecStatus(repoRoot, specInput) {
|