create-quiver 0.15.2 → 0.15.4
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/workflows/ci.yml +3 -0
- package/AGENTS.md.es.template +37 -0
- package/README.md +1 -0
- package/README_FOR_AI.md +6 -4
- package/docs/AI_CONTEXT.md.es.template +35 -0
- package/docs/AI_ONBOARDING_PROMPT.md.es.template +22 -0
- package/docs/CLI_UX_GUIDE.md +47 -1
- package/docs/COMMANDS.md.es.template +28 -0
- package/docs/COMMANDS.md.template +14 -3
- package/docs/CONTEXTO.md.es.template +33 -0
- package/docs/DECISIONS.md.es.template +17 -0
- package/docs/GITFLOW_PR_GUIDE.md.es.template +25 -0
- package/docs/INDEX.md +96 -0
- package/docs/INDEX.md.es.template +36 -0
- package/docs/STATUS.md.es.template +28 -0
- package/docs/SUPPORT_MATRIX.md.es.template +22 -0
- package/docs/TESTING_GUIDE_FOR_AI.md.es.template +19 -0
- package/docs/TROUBLESHOOTING.md.es.template +35 -0
- package/docs/WORKFLOW.md.es.template +29 -0
- package/docs/WORKFLOW.md.template +2 -2
- package/docs/ai/LESSONS.md.es.template +24 -0
- package/docs/getting-started/installation.md +19 -0
- package/docs/reference/commands.md +68 -2
- package/package.json +3 -1
- package/specs/quiver-v34-cli-dashboard-status/EVIDENCE_REPORT.md +119 -0
- package/specs/quiver-v34-cli-dashboard-status/EXECUTION_PLAN.md +77 -0
- package/specs/quiver-v34-cli-dashboard-status/SPEC.md +152 -0
- package/specs/quiver-v34-cli-dashboard-status/STATUS.md +29 -0
- package/specs/quiver-v34-cli-dashboard-status/pr.md +99 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-00-dashboard-foundation/CLOSURE_BRIEF.md +19 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-00-dashboard-foundation/EXECUTION_BRIEF.md +49 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-00-dashboard-foundation/slice.json +68 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-01-dashboard-report-contract/CLOSURE_BRIEF.md +19 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-01-dashboard-report-contract/EXECUTION_BRIEF.md +53 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-01-dashboard-report-contract/slice.json +78 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-02-dashboard-command-rendering/CLOSURE_BRIEF.md +19 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-02-dashboard-command-rendering/EXECUTION_BRIEF.md +53 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-02-dashboard-command-rendering/slice.json +82 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-03-dashboard-edge-cases-and-guardrails/CLOSURE_BRIEF.md +19 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-03-dashboard-edge-cases-and-guardrails/EXECUTION_BRIEF.md +54 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-03-dashboard-edge-cases-and-guardrails/slice.json +77 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-04-docs-templates-and-scripts/CLOSURE_BRIEF.md +19 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-04-docs-templates-and-scripts/EXECUTION_BRIEF.md +54 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-04-docs-templates-and-scripts/slice.json +88 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-05-tests-smokes-release-readiness/CLOSURE_BRIEF.md +26 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-05-tests-smokes-release-readiness/EXECUTION_BRIEF.md +57 -0
- package/specs/quiver-v34-cli-dashboard-status/slices/slice-05-tests-smokes-release-readiness/slice.json +85 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/EVIDENCE_REPORT.md +43 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/EXECUTION_PLAN.md +85 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/SPEC.md +147 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/STATUS.md +33 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/pr.md +106 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-00-foundation-and-doc-router/CLOSURE_BRIEF.md +19 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-00-foundation-and-doc-router/EXECUTION_BRIEF.md +38 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-00-foundation-and-doc-router/slice.json +64 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-01-dashboard-cli-contract/CLOSURE_BRIEF.md +19 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-01-dashboard-cli-contract/EXECUTION_BRIEF.md +49 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-01-dashboard-cli-contract/slice.json +80 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-02-dashboard-compact-renderer/CLOSURE_BRIEF.md +19 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-02-dashboard-compact-renderer/EXECUTION_BRIEF.md +48 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-02-dashboard-compact-renderer/slice.json +73 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-03-dashboard-details-sections/CLOSURE_BRIEF.md +19 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-03-dashboard-details-sections/EXECUTION_BRIEF.md +48 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-03-dashboard-details-sections/slice.json +72 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-04-version-command/CLOSURE_BRIEF.md +19 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-04-version-command/EXECUTION_BRIEF.md +49 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-04-version-command/slice.json +82 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-05-docs-help-generated-guidance/CLOSURE_BRIEF.md +19 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-05-docs-help-generated-guidance/EXECUTION_BRIEF.md +50 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-05-docs-help-generated-guidance/slice.json +90 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-06-tests-smokes-release-readiness/CLOSURE_BRIEF.md +21 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-06-tests-smokes-release-readiness/EXECUTION_BRIEF.md +51 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-06-tests-smokes-release-readiness/slice.json +85 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-07-package-and-cross-platform-smoke/CLOSURE_BRIEF.md +20 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-07-package-and-cross-platform-smoke/EXECUTION_BRIEF.md +49 -0
- package/specs/quiver-v35-compact-dashboard-version-ux/slices/slice-07-package-and-cross-platform-smoke/slice.json +79 -0
- package/specs/quiver-v36-ai-run-watch-portable/EVIDENCE_REPORT.md +33 -0
- package/specs/quiver-v36-ai-run-watch-portable/EXECUTION_PLAN.md +39 -0
- package/specs/quiver-v36-ai-run-watch-portable/SPEC.md +166 -0
- package/specs/quiver-v36-ai-run-watch-portable/STATUS.md +31 -0
- package/specs/quiver-v36-ai-run-watch-portable/pr.md +78 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-00-foundation-and-handoffs/CLOSURE_BRIEF.md +19 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-00-foundation-and-handoffs/EXECUTION_BRIEF.md +43 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-00-foundation-and-handoffs/slice.json +61 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-01-run-schema-path-safety/CLOSURE_BRIEF.md +18 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-01-run-schema-path-safety/EXECUTION_BRIEF.md +43 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-01-run-schema-path-safety/slice.json +65 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-02-event-writer-redacted-logs/CLOSURE_BRIEF.md +18 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-02-event-writer-redacted-logs/EXECUTION_BRIEF.md +43 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-02-event-writer-redacted-logs/slice.json +66 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-03-provider-streaming-integration/CLOSURE_BRIEF.md +18 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-03-provider-streaming-integration/EXECUTION_BRIEF.md +41 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-03-provider-streaming-integration/slice.json +71 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-04-ai-run-watch-command/CLOSURE_BRIEF.md +18 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-04-ai-run-watch-command/EXECUTION_BRIEF.md +44 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-04-ai-run-watch-command/slice.json +73 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-05-main-progress-user-guidance/CLOSURE_BRIEF.md +18 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-05-main-progress-user-guidance/EXECUTION_BRIEF.md +44 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-05-main-progress-user-guidance/slice.json +71 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-06-docs-generated-guidance/CLOSURE_BRIEF.md +19 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-06-docs-generated-guidance/EXECUTION_BRIEF.md +45 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-06-docs-generated-guidance/slice.json +77 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-07-tests-cross-platform-readiness/CLOSURE_BRIEF.md +22 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-07-tests-cross-platform-readiness/EXECUTION_BRIEF.md +46 -0
- package/specs/quiver-v36-ai-run-watch-portable/slices/slice-07-tests-cross-platform-readiness/slice.json +87 -0
- package/specs/quiver-v37-cli-i18n-foundation/EVIDENCE_REPORT.md +73 -0
- package/specs/quiver-v37-cli-i18n-foundation/EXECUTION_PLAN.md +34 -0
- package/specs/quiver-v37-cli-i18n-foundation/SPEC.md +91 -0
- package/specs/quiver-v37-cli-i18n-foundation/STATUS.md +29 -0
- package/specs/quiver-v37-cli-i18n-foundation/pr.md +97 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-00-foundation-and-program-roadmap/CLOSURE_BRIEF.md +10 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-00-foundation-and-program-roadmap/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-00-foundation-and-program-roadmap/slice.json +54 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-01-language-resolution-contract/CLOSURE_BRIEF.md +30 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-01-language-resolution-contract/EXECUTION_BRIEF.md +27 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-01-language-resolution-contract/slice.json +66 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-02-message-catalog-interpolation/CLOSURE_BRIEF.md +27 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-02-message-catalog-interpolation/EXECUTION_BRIEF.md +26 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-02-message-catalog-interpolation/slice.json +62 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-03-config-language-command/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-03-config-language-command/EXECUTION_BRIEF.md +25 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-03-config-language-command/slice.json +66 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-04-parser-help-error-foundation/CLOSURE_BRIEF.md +30 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-04-parser-help-error-foundation/EXECUTION_BRIEF.md +24 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-04-parser-help-error-foundation/slice.json +65 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-05-foundation-docs-tests-package-readiness/CLOSURE_BRIEF.md +27 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-05-foundation-docs-tests-package-readiness/EXECUTION_BRIEF.md +23 -0
- package/specs/quiver-v37-cli-i18n-foundation/slices/slice-05-foundation-docs-tests-package-readiness/slice.json +67 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/EVIDENCE_REPORT.md +69 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/EXECUTION_PLAN.md +25 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/SPEC.md +52 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/STATUS.md +24 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/pr.md +119 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-00-read-only-foundation/CLOSURE_BRIEF.md +10 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-00-read-only-foundation/EXECUTION_BRIEF.md +21 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-00-read-only-foundation/slice.json +53 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-01-version-dashboard-help/CLOSURE_BRIEF.md +17 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-01-version-dashboard-help/EXECUTION_BRIEF.md +23 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-01-version-dashboard-help/slice.json +69 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-02-flow-doctor-next-graph/CLOSURE_BRIEF.md +13 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-02-flow-doctor-next-graph/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-02-flow-doctor-next-graph/slice.json +77 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-03-ai-inspection-and-export/CLOSURE_BRIEF.md +12 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-03-ai-inspection-and-export/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-03-ai-inspection-and-export/slice.json +66 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-04-read-only-tests-smokes/CLOSURE_BRIEF.md +13 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-04-read-only-tests-smokes/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-04-read-only-tests-smokes/slice.json +61 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/EVIDENCE_REPORT.md +71 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/EXECUTION_PLAN.md +25 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/SPEC.md +53 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/STATUS.md +24 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/pr.md +104 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-00-setup-foundation/CLOSURE_BRIEF.md +10 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-00-setup-foundation/EXECUTION_BRIEF.md +21 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-00-setup-foundation/slice.json +53 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-01-init-interactive-language/CLOSURE_BRIEF.md +12 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-01-init-interactive-language/EXECUTION_BRIEF.md +23 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-01-init-interactive-language/slice.json +68 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-02-analyze-migrate-prepare/CLOSURE_BRIEF.md +12 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-02-analyze-migrate-prepare/EXECUTION_BRIEF.md +23 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-02-analyze-migrate-prepare/slice.json +62 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-03-demo-evidence-onboarding/CLOSURE_BRIEF.md +12 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-03-demo-evidence-onboarding/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-03-demo-evidence-onboarding/slice.json +72 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-04-setup-tests-smokes/CLOSURE_BRIEF.md +15 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-04-setup-tests-smokes/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-04-setup-tests-smokes/slice.json +61 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/EVIDENCE_REPORT.md +50 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/EXECUTION_PLAN.md +25 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/SPEC.md +52 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/STATUS.md +24 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/pr.md +94 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-00-spec-slice-foundation/CLOSURE_BRIEF.md +10 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-00-spec-slice-foundation/EXECUTION_BRIEF.md +21 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-00-spec-slice-foundation/slice.json +53 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-01-spec-create-start-status/CLOSURE_BRIEF.md +12 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-01-spec-create-start-status/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-01-spec-create-start-status/slice.json +63 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-02-spec-validate-close/CLOSURE_BRIEF.md +10 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-02-spec-validate-close/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-02-spec-validate-close/slice.json +63 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-03-slice-lifecycle-handoffs/CLOSURE_BRIEF.md +10 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-03-slice-lifecycle-handoffs/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-03-slice-lifecycle-handoffs/slice.json +72 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-04-spec-slice-tests-smokes/CLOSURE_BRIEF.md +15 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-04-spec-slice-tests-smokes/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-04-spec-slice-tests-smokes/slice.json +69 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/EVIDENCE_REPORT.md +90 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/EXECUTION_PLAN.md +33 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/SPEC.md +57 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/STATUS.md +26 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/pr.md +103 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-00-ai-i18n-foundation/CLOSURE_BRIEF.md +10 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-00-ai-i18n-foundation/EXECUTION_BRIEF.md +21 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-00-ai-i18n-foundation/slice.json +53 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-01-ai-run-status-resume/CLOSURE_BRIEF.md +13 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-01-ai-run-status-resume/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-01-ai-run-status-resume/slice.json +68 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-02-ai-agent-models/CLOSURE_BRIEF.md +12 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-02-ai-agent-models/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-02-ai-agent-models/slice.json +66 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-03-ai-planner-approval-review/CLOSURE_BRIEF.md +12 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-03-ai-planner-approval-review/EXECUTION_BRIEF.md +23 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-03-ai-planner-approval-review/slice.json +68 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-04-ai-execution-pr/CLOSURE_BRIEF.md +13 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-04-ai-execution-pr/EXECUTION_BRIEF.md +23 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-04-ai-execution-pr/slice.json +72 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-05-ai-tests-smokes/CLOSURE_BRIEF.md +15 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-05-ai-tests-smokes/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-05-ai-tests-smokes/slice.json +66 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-06-ai-prepare-context-progress-i18n-fix/CLOSURE_BRIEF.md +11 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-06-ai-prepare-context-progress-i18n-fix/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-06-ai-prepare-context-progress-i18n-fix/slice.json +70 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/EVIDENCE_REPORT.md +64 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/EXECUTION_PLAN.md +26 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/SPEC.md +52 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/STATUS.md +24 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/pr.md +125 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-00-generated-docs-foundation/CLOSURE_BRIEF.md +10 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-00-generated-docs-foundation/EXECUTION_BRIEF.md +21 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-00-generated-docs-foundation/slice.json +53 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-01-template-language-routing/CLOSURE_BRIEF.md +10 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-01-template-language-routing/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-01-template-language-routing/slice.json +62 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-02-init-docs-and-i18n-assets/CLOSURE_BRIEF.md +11 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-02-init-docs-and-i18n-assets/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-02-init-docs-and-i18n-assets/slice.json +72 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-03-docs-reference-guides/CLOSURE_BRIEF.md +12 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-03-docs-reference-guides/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-03-docs-reference-guides/slice.json +60 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-04-generated-docs-tests-smokes/CLOSURE_BRIEF.md +16 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-04-generated-docs-tests-smokes/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-04-generated-docs-tests-smokes/slice.json +62 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/EVIDENCE_REPORT.md +203 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/EXECUTION_PLAN.md +27 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/SPEC.md +54 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/STATUS.md +24 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/command-language-mode-matrix.json +545 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/cross-platform-smoke-matrix.md +35 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/pr.md +155 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-00-audit-foundation/CLOSURE_BRIEF.md +10 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-00-audit-foundation/EXECUTION_BRIEF.md +21 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-00-audit-foundation/slice.json +53 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-01-command-language-mode-matrix/CLOSURE_BRIEF.md +13 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-01-command-language-mode-matrix/EXECUTION_BRIEF.md +23 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-01-command-language-mode-matrix/slice.json +62 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-02-public-string-audit/CLOSURE_BRIEF.md +18 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-02-public-string-audit/EXECUTION_BRIEF.md +22 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-02-public-string-audit/slice.json +59 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-03-cross-platform-smokes/CLOSURE_BRIEF.md +15 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-03-cross-platform-smokes/EXECUTION_BRIEF.md +23 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-03-cross-platform-smokes/slice.json +62 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-04-package-release-readiness/CLOSURE_BRIEF.md +17 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-04-package-release-readiness/EXECUTION_BRIEF.md +24 -0
- package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-04-package-release-readiness/slice.json +66 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/EVIDENCE_REPORT.md +18 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/EXECUTION_PLAN.md +31 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/SPEC.md +118 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/STATUS.md +25 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/pr.md +92 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-00-tui-lite-contract-foundation/CLOSURE_BRIEF.md +11 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-00-tui-lite-contract-foundation/EXECUTION_BRIEF.md +23 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-00-tui-lite-contract-foundation/slice.json +64 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-01-provider-stream-hooks/CLOSURE_BRIEF.md +10 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-01-provider-stream-hooks/EXECUTION_BRIEF.md +24 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-01-provider-stream-hooks/slice.json +65 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-02-live-output-renderer/CLOSURE_BRIEF.md +10 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-02-live-output-renderer/EXECUTION_BRIEF.md +24 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-02-live-output-renderer/slice.json +70 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-03-prepare-context-integration/CLOSURE_BRIEF.md +10 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-03-prepare-context-integration/EXECUTION_BRIEF.md +25 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-03-prepare-context-integration/slice.json +70 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-04-planner-command-audit-adoption/CLOSURE_BRIEF.md +10 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-04-planner-command-audit-adoption/EXECUTION_BRIEF.md +26 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-04-planner-command-audit-adoption/slice.json +72 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-05-docs-tests-readiness/CLOSURE_BRIEF.md +15 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-05-docs-tests-readiness/EXECUTION_BRIEF.md +26 -0
- package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-05-docs-tests-readiness/slice.json +75 -0
- package/specs/quiver-v45-ci-actions-node24-readiness/EVIDENCE_REPORT.md +30 -0
- package/specs/quiver-v45-ci-actions-node24-readiness/EXECUTION_PLAN.md +22 -0
- package/specs/quiver-v45-ci-actions-node24-readiness/SPEC.md +49 -0
- package/specs/quiver-v45-ci-actions-node24-readiness/STATUS.md +21 -0
- package/specs/quiver-v45-ci-actions-node24-readiness/pr.md +67 -0
- package/specs/quiver-v45-ci-actions-node24-readiness/slices/slice-00-ci-actions-foundation/CLOSURE_BRIEF.md +10 -0
- package/specs/quiver-v45-ci-actions-node24-readiness/slices/slice-00-ci-actions-foundation/EXECUTION_BRIEF.md +21 -0
- package/specs/quiver-v45-ci-actions-node24-readiness/slices/slice-00-ci-actions-foundation/slice.json +48 -0
- package/specs/quiver-v45-ci-actions-node24-readiness/slices/slice-01-actions-node24-readiness/CLOSURE_BRIEF.md +14 -0
- package/specs/quiver-v45-ci-actions-node24-readiness/slices/slice-01-actions-node24-readiness/EXECUTION_BRIEF.md +23 -0
- package/specs/quiver-v45-ci-actions-node24-readiness/slices/slice-01-actions-node24-readiness/slice.json +65 -0
- package/src/create-quiver/commands/ai.js +485 -307
- package/src/create-quiver/commands/config.js +124 -0
- package/src/create-quiver/commands/dashboard.js +31 -0
- package/src/create-quiver/commands/demo.js +2 -2
- package/src/create-quiver/commands/evidence.js +6 -4
- package/src/create-quiver/commands/flow.js +108 -16
- package/src/create-quiver/commands/graph.js +1 -0
- package/src/create-quiver/commands/next.js +21 -18
- package/src/create-quiver/commands/plan.js +23 -6
- package/src/create-quiver/commands/spec.js +66 -57
- package/src/create-quiver/index.js +606 -136
- package/src/create-quiver/lib/ai/execution-plan.js +23 -20
- package/src/create-quiver/lib/ai/executor.js +60 -44
- package/src/create-quiver/lib/ai/export-state.js +75 -64
- package/src/create-quiver/lib/ai/github.js +24 -21
- package/src/create-quiver/lib/ai/run-state.js +28 -25
- package/src/create-quiver/lib/cli/ux-flags.js +6 -0
- package/src/create-quiver/lib/dashboard.js +939 -0
- package/src/create-quiver/lib/demo.js +14 -12
- package/src/create-quiver/lib/handoff.js +16 -7
- package/src/create-quiver/lib/i18n/catalog.js +152 -0
- package/src/create-quiver/lib/i18n/language.js +279 -0
- package/src/create-quiver/lib/i18n/messages/en.js +853 -0
- package/src/create-quiver/lib/i18n/messages/es.js +968 -0
- package/src/create-quiver/lib/i18n/read-only-format.js +26 -0
- package/src/create-quiver/lib/i18n/templates.js +172 -0
- package/src/create-quiver/lib/init-docs.js +24 -4
- package/src/create-quiver/lib/init-layout.js +8 -0
- package/src/create-quiver/lib/lifecycle.js +53 -46
- package/src/create-quiver/lib/project-state-resolver.js +22 -2
- package/src/create-quiver/lib/readiness.js +77 -67
- package/src/create-quiver/lib/renderers/tree.js +9 -6
- package/src/create-quiver/lib/spec-worktrees.js +34 -30
- package/src/create-quiver/lib/version.js +159 -0
|
@@ -15,6 +15,7 @@ const { parseContextProposalOutput } = require('../lib/ai/context-proposal');
|
|
|
15
15
|
const { openEditor } = require('../lib/cli/editor');
|
|
16
16
|
const { selectOption, promptText } = require('../lib/cli/selectors');
|
|
17
17
|
const { createUx } = require('../lib/cli/ux');
|
|
18
|
+
const { createTranslator } = require('../lib/i18n/catalog');
|
|
18
19
|
const { runExecuteSlice, runPromptSlice } = require('../lib/ai/executor');
|
|
19
20
|
const { runExecutePlan } = require('../lib/ai/execution-plan');
|
|
20
21
|
const { buildPrCreatePlan, formatPreflightReport, formatPrCreateReport, preflightGitHubPr, runGhPrCreate } = require('../lib/ai/github');
|
|
@@ -90,6 +91,7 @@ const {
|
|
|
90
91
|
formatApprovalDecisionLines,
|
|
91
92
|
} = require('../lib/ai/approval-candidates');
|
|
92
93
|
const { assertPlannerPhaseReady, getPlannerPhaseDetails, normalizePlannerPhase, PlannerPhaseError } = require('../lib/ai/phase-gates');
|
|
94
|
+
const { formatStatus, translatorForHuman } = require('../lib/i18n/read-only-format');
|
|
93
95
|
const { collectActiveSliceState, resolveProjectState } = require('../lib/project-state-resolver');
|
|
94
96
|
|
|
95
97
|
const DEFAULT_ONBOARD_PROVIDER = 'codex';
|
|
@@ -106,6 +108,23 @@ function formatError(message) {
|
|
|
106
108
|
return `create-quiver: ${message}`;
|
|
107
109
|
}
|
|
108
110
|
|
|
111
|
+
function formatLocalizedActionableError({ failure, impact, fix, nextCommand } = {}, options = {}) {
|
|
112
|
+
const translator = createTranslator(options.language);
|
|
113
|
+
const lines = [`create-quiver: ${String(failure || 'operation failed').trim()}`];
|
|
114
|
+
|
|
115
|
+
if (impact) {
|
|
116
|
+
lines.push(`${translator.t('ai.actionable.impact')}: ${String(impact).trim()}`);
|
|
117
|
+
}
|
|
118
|
+
if (fix) {
|
|
119
|
+
lines.push(`${translator.t('ai.actionable.fix')}: ${String(fix).trim()}`);
|
|
120
|
+
}
|
|
121
|
+
if (nextCommand) {
|
|
122
|
+
lines.push(`${translator.t('ai.actionable.next_command')}: ${String(nextCommand).trim()}`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return lines.join('\n');
|
|
126
|
+
}
|
|
127
|
+
|
|
109
128
|
function readTextFile(filePath, repoRoot) {
|
|
110
129
|
if (!filePath) {
|
|
111
130
|
return '';
|
|
@@ -226,8 +245,12 @@ function shouldShowHumanProgress(ux, options = {}) {
|
|
|
226
245
|
&& ux?.mode?.decoration === true;
|
|
227
246
|
}
|
|
228
247
|
|
|
229
|
-
function plannerProgressTitle(action, runtimeProfile) {
|
|
230
|
-
|
|
248
|
+
function plannerProgressTitle(action, runtimeProfile, options = {}) {
|
|
249
|
+
const translator = createTranslator(options.language);
|
|
250
|
+
return translator.t('ai.planner.progress.title', {
|
|
251
|
+
action,
|
|
252
|
+
profile: runtimeProfile.displayName || runtimeProfile.model || runtimeProfile.provider,
|
|
253
|
+
});
|
|
231
254
|
}
|
|
232
255
|
|
|
233
256
|
function writeProgressChecks(ux, enabled, title, checks = []) {
|
|
@@ -240,7 +263,7 @@ function writeProgressChecks(ux, enabled, title, checks = []) {
|
|
|
240
263
|
}
|
|
241
264
|
}
|
|
242
265
|
|
|
243
|
-
async function runProviderWithProgress({ ux, enabled, message = '
|
|
266
|
+
async function runProviderWithProgress({ ux, enabled, message = 'Running agent...', successMessage = 'Agent finished', failureMessage = 'Agent failed', run }) {
|
|
244
267
|
async function runAndFailOnProviderResult() {
|
|
245
268
|
const result = await run();
|
|
246
269
|
if (result && result.ok === false) {
|
|
@@ -327,77 +350,85 @@ function buildOnboardContext({ role, context, inputText, inputPath, repoRoot })
|
|
|
327
350
|
};
|
|
328
351
|
}
|
|
329
352
|
|
|
330
|
-
function formatDryRunReport({ task, provider, role, contextPack, phase, invocation, onboardingPlan }) {
|
|
353
|
+
function formatDryRunReport({ task, provider, role, contextPack, phase, invocation, onboardingPlan, language = 'en' }) {
|
|
354
|
+
const translator = createTranslator(language);
|
|
355
|
+
const modelStatus = invocation.modelSelection?.supported
|
|
356
|
+
? translator.t('ai_task.model_supported')
|
|
357
|
+
: translator.t('ai_task.model_unsupported');
|
|
331
358
|
const lines = [
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
359
|
+
translator.t('ai_task.title.dry_run', { task }),
|
|
360
|
+
translator.t('ai_task.provider', { provider }),
|
|
361
|
+
translator.t('ai_task.role', { role }),
|
|
362
|
+
translator.t('ai_task.context_pack', { context: contextPack }),
|
|
336
363
|
];
|
|
337
364
|
|
|
338
365
|
if (phase) {
|
|
339
|
-
lines.push(
|
|
366
|
+
lines.push(translator.t('ai_task.phase', { phase }));
|
|
340
367
|
}
|
|
341
368
|
|
|
342
|
-
lines.push(
|
|
343
|
-
lines.push(
|
|
344
|
-
lines.push(
|
|
345
|
-
lines.push(
|
|
369
|
+
lines.push(translator.t('ai_task.command', { command: `${invocation.command} ${invocation.args.join(' ')}`.trim() }));
|
|
370
|
+
lines.push(translator.t('ai_task.timeout', { timeout: invocation.timeoutMs }));
|
|
371
|
+
lines.push(translator.t('ai_task.prompt_transport', { mode: invocation.promptTransport.mode }));
|
|
372
|
+
lines.push(translator.t('ai_task.prompt_length', { bytes: invocation.promptLength }));
|
|
346
373
|
if (invocation.modelSelection && invocation.modelSelection.model) {
|
|
347
|
-
lines.push(
|
|
348
|
-
lines.push(
|
|
374
|
+
lines.push(translator.t('ai_task.model', { model: invocation.modelSelection.model }));
|
|
375
|
+
lines.push(translator.t('ai_task.model_support', { status: modelStatus, reason: invocation.modelSelection.reason }));
|
|
349
376
|
}
|
|
350
377
|
|
|
351
378
|
if (onboardingPlan) {
|
|
352
|
-
lines.push(
|
|
353
|
-
lines.push(
|
|
354
|
-
lines.push(
|
|
379
|
+
lines.push(translator.t('ai_task.prompt_source', { source: onboardingPlan.promptSource }));
|
|
380
|
+
lines.push(translator.t('ai_task.selected_docs', { count: onboardingPlan.selectedDocs.length }));
|
|
381
|
+
lines.push(translator.t('ai_task.documentation_debt', { count: onboardingPlan.missingDocs.length }));
|
|
355
382
|
}
|
|
356
383
|
|
|
357
384
|
return `${lines.join('\n')}\n`;
|
|
358
385
|
}
|
|
359
386
|
|
|
360
|
-
function formatPromptOnlyReport({ task, provider, role, contextPack, phase, invocation, prompt, onboardingPlan, promptSource, inputPath, inputKind, inputVersion }) {
|
|
387
|
+
function formatPromptOnlyReport({ task, provider, role, contextPack, phase, invocation, prompt, onboardingPlan, promptSource, inputPath, inputKind, inputVersion, language = 'en' }) {
|
|
388
|
+
const translator = createTranslator(language);
|
|
389
|
+
const modelStatus = invocation.modelSelection?.supported
|
|
390
|
+
? translator.t('ai_task.model_supported')
|
|
391
|
+
: translator.t('ai_task.model_unsupported');
|
|
361
392
|
const lines = [
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
393
|
+
translator.t('ai_task.title.prompt_only', { task }),
|
|
394
|
+
translator.t('ai_task.provider', { provider }),
|
|
395
|
+
translator.t('ai_task.role', { role }),
|
|
396
|
+
translator.t('ai_task.context_pack', { context: contextPack }),
|
|
366
397
|
];
|
|
367
398
|
|
|
368
399
|
if (phase) {
|
|
369
|
-
lines.push(
|
|
400
|
+
lines.push(translator.t('ai_task.phase', { phase }));
|
|
370
401
|
}
|
|
371
402
|
|
|
372
|
-
lines.push(
|
|
373
|
-
lines.push(
|
|
374
|
-
lines.push(
|
|
375
|
-
lines.push(
|
|
403
|
+
lines.push(translator.t('ai_task.command', { command: `${invocation.command} ${invocation.args.join(' ')}`.trim() }));
|
|
404
|
+
lines.push(translator.t('ai_task.timeout', { timeout: invocation.timeoutMs }));
|
|
405
|
+
lines.push(translator.t('ai_task.prompt_transport', { mode: invocation.promptTransport.mode }));
|
|
406
|
+
lines.push(translator.t('ai_task.prompt_length', { bytes: invocation.promptLength }));
|
|
376
407
|
if (invocation.modelSelection && invocation.modelSelection.model) {
|
|
377
|
-
lines.push(
|
|
378
|
-
lines.push(
|
|
408
|
+
lines.push(translator.t('ai_task.model', { model: invocation.modelSelection.model }));
|
|
409
|
+
lines.push(translator.t('ai_task.model_support', { status: modelStatus, reason: invocation.modelSelection.reason }));
|
|
379
410
|
}
|
|
380
411
|
|
|
381
412
|
if (onboardingPlan) {
|
|
382
|
-
lines.push(
|
|
383
|
-
lines.push(
|
|
384
|
-
lines.push(
|
|
413
|
+
lines.push(translator.t('ai_task.prompt_source', { source: onboardingPlan.promptSource }));
|
|
414
|
+
lines.push(translator.t('ai_task.selected_docs', { count: onboardingPlan.selectedDocs.length }));
|
|
415
|
+
lines.push(translator.t('ai_task.documentation_debt', { count: onboardingPlan.missingDocs.length }));
|
|
385
416
|
}
|
|
386
417
|
|
|
387
418
|
if (promptSource) {
|
|
388
|
-
lines.push(
|
|
419
|
+
lines.push(translator.t('ai_task.prompt_source', { source: promptSource }));
|
|
389
420
|
}
|
|
390
421
|
|
|
391
422
|
if (inputPath) {
|
|
392
|
-
lines.push(
|
|
423
|
+
lines.push(translator.t('ai_task.input_file', { path: inputPath }));
|
|
393
424
|
}
|
|
394
425
|
|
|
395
426
|
if (inputKind) {
|
|
396
|
-
lines.push(
|
|
427
|
+
lines.push(translator.t('ai_task.input_kind', { kind: inputKind }));
|
|
397
428
|
}
|
|
398
429
|
|
|
399
430
|
if (inputVersion) {
|
|
400
|
-
lines.push(
|
|
431
|
+
lines.push(translator.t('ai_task.input_version', { version: inputVersion }));
|
|
401
432
|
}
|
|
402
433
|
|
|
403
434
|
lines.push('--- PROMPT START ---');
|
|
@@ -415,21 +446,22 @@ function formatPathList(items, emptyLabel = 'none') {
|
|
|
415
446
|
return items.map((item) => `- ${item}`);
|
|
416
447
|
}
|
|
417
448
|
|
|
418
|
-
function formatContextPreparationReport({ dryRun, plan, writePlan, writtenDocs, snapshot, completed = false }) {
|
|
449
|
+
function formatContextPreparationReport({ dryRun, plan, writePlan, writtenDocs, snapshot, completed = false, language = 'en' }) {
|
|
450
|
+
const translator = createTranslator(language);
|
|
419
451
|
const lines = [
|
|
420
|
-
dryRun ? '
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
'
|
|
425
|
-
'
|
|
426
|
-
|
|
452
|
+
dryRun ? translator.t('prepare_context.title.dry_run') : completed ? translator.t('prepare_context.title.completed') : translator.t('prepare_context.title.write_plan'),
|
|
453
|
+
translator.t('prepare_context.mode', { mode: dryRun ? 'dry-run' : 'live' }),
|
|
454
|
+
translator.t('prepare_context.project', { project: plan.projectName }),
|
|
455
|
+
translator.t('prepare_context.project_slug', { slug: plan.projectSlug }),
|
|
456
|
+
translator.t('prepare_context.writes_docs_only'),
|
|
457
|
+
translator.t('prepare_context.product_code_untouched'),
|
|
458
|
+
translator.t('prepare_context.proposed_docs', { docs: writePlan.length > 0 ? writePlan.map((item) => item.path).join(', ') : translator.t('common.none') }),
|
|
427
459
|
];
|
|
428
460
|
|
|
429
461
|
if (!dryRun) {
|
|
430
|
-
lines.push(
|
|
462
|
+
lines.push(translator.t(completed ? 'prepare_context.written_docs' : 'prepare_context.planned_writes', { docs: writtenDocs.length > 0 ? writtenDocs.join(', ') : translator.t('common.none') }));
|
|
431
463
|
if (snapshot) {
|
|
432
|
-
lines.push(
|
|
464
|
+
lines.push(translator.t('prepare_context.snapshot', { path: snapshot.root }));
|
|
433
465
|
}
|
|
434
466
|
}
|
|
435
467
|
|
|
@@ -438,21 +470,21 @@ function formatContextPreparationReport({ dryRun, plan, writePlan, writtenDocs,
|
|
|
438
470
|
}
|
|
439
471
|
|
|
440
472
|
lines.push(
|
|
441
|
-
'
|
|
473
|
+
translator.t('prepare_context.proposed_changes'),
|
|
442
474
|
...writePlan.map((item) => `- ${item.path}: ${item.action}${item.reason ? ` (${item.reason})` : ''}`),
|
|
443
|
-
'
|
|
475
|
+
translator.t('prepare_context.diff_preview'),
|
|
444
476
|
...formatDiffPreview(writePlan),
|
|
445
|
-
'
|
|
446
|
-
...plan.filesConsidered.map((item) => `- ${item.path}: ${item.present ? 'present' : 'absent'}${item.reason ? ` (${item.reason})` : ''}`),
|
|
447
|
-
'
|
|
448
|
-
...formatPathList(plan.assumptions),
|
|
449
|
-
'
|
|
450
|
-
...formatPathList(plan.risks),
|
|
451
|
-
'
|
|
452
|
-
...formatPathList(plan.contradictions),
|
|
453
|
-
'
|
|
454
|
-
...formatPathList(plan.omittedPaths),
|
|
455
|
-
'
|
|
477
|
+
translator.t('prepare_context.files_considered'),
|
|
478
|
+
...plan.filesConsidered.map((item) => `- ${item.path}: ${item.present ? translator.t('prepare_context.present') : translator.t('prepare_context.absent')}${item.reason ? ` (${item.reason})` : ''}`),
|
|
479
|
+
translator.t('prepare_context.assumptions'),
|
|
480
|
+
...formatPathList(plan.assumptions, translator.t('common.none')),
|
|
481
|
+
translator.t('prepare_context.risks'),
|
|
482
|
+
...formatPathList(plan.risks, translator.t('common.none')),
|
|
483
|
+
translator.t('prepare_context.contradictions'),
|
|
484
|
+
...formatPathList(plan.contradictions, translator.t('common.none')),
|
|
485
|
+
translator.t('prepare_context.omitted_paths'),
|
|
486
|
+
...formatPathList(plan.omittedPaths, translator.t('common.none')),
|
|
487
|
+
translator.t('prepare_context.uncertainty_markers'),
|
|
456
488
|
);
|
|
457
489
|
|
|
458
490
|
return `${lines.join('\n')}\n`;
|
|
@@ -537,12 +569,13 @@ function buildPrepareContextPlannerPrompt({ pack, draftPack }) {
|
|
|
537
569
|
};
|
|
538
570
|
}
|
|
539
571
|
|
|
540
|
-
function formatPrepareContextPlannerDryRunReport({ provider, role, context, invocation, promptInfo, review, interactive }) {
|
|
572
|
+
function formatPrepareContextPlannerDryRunReport({ provider, role, context, invocation, promptInfo, review, interactive, language = 'en' }) {
|
|
573
|
+
const translator = createTranslator(language);
|
|
541
574
|
const plan = promptInfo.plan;
|
|
542
575
|
const lines = [
|
|
543
|
-
'
|
|
544
|
-
'
|
|
545
|
-
'
|
|
576
|
+
translator.t('prepare_context_planner.title.dry_run'),
|
|
577
|
+
translator.t('prepare_context.mode', { mode: 'dry-run' }),
|
|
578
|
+
translator.t('prepare_context_planner.enabled'),
|
|
546
579
|
`Provider: ${provider}`,
|
|
547
580
|
`Role: ${role}`,
|
|
548
581
|
`Context pack: ${context}`,
|
|
@@ -554,18 +587,18 @@ function formatPrepareContextPlannerDryRunReport({ provider, role, context, invo
|
|
|
554
587
|
invocation.modelSelection && invocation.modelSelection.model
|
|
555
588
|
? `Model support: ${invocation.modelSelection.supported ? 'supported' : 'unsupported'} (${invocation.modelSelection.reason})`
|
|
556
589
|
: '',
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
'
|
|
561
|
-
'
|
|
562
|
-
'
|
|
563
|
-
|
|
564
|
-
'
|
|
565
|
-
...plan.filesConsidered.map((item) => `- ${item.path}: ${item.present ? 'present' : 'absent'}`),
|
|
566
|
-
'
|
|
590
|
+
translator.t('prepare_context.prompt_source', { source: promptInfo.promptSource }),
|
|
591
|
+
translator.t('prepare_context_planner.review_requested', { value: review ? translator.t('common.yes') : translator.t('common.no') }),
|
|
592
|
+
translator.t('prepare_context_planner.interactive_requested', { value: interactive ? translator.t('common.yes') : translator.t('common.no') }),
|
|
593
|
+
translator.t('prepare_context_planner.provider_execution_skipped'),
|
|
594
|
+
translator.t('prepare_context.writes_none'),
|
|
595
|
+
translator.t('prepare_context.product_code_untouched'),
|
|
596
|
+
translator.t('prepare_context_planner.candidate_docs', { docs: promptInfo.allowedPaths.join(', ') }),
|
|
597
|
+
translator.t('prepare_context.files_considered'),
|
|
598
|
+
...plan.filesConsidered.map((item) => `- ${item.path}: ${item.present ? translator.t('prepare_context.present') : translator.t('prepare_context.absent')}`),
|
|
599
|
+
translator.t('prepare_context_planner.allowed_docs_only_paths'),
|
|
567
600
|
...promptInfo.allowedPaths.map((item) => `- ${item}`),
|
|
568
|
-
'
|
|
601
|
+
translator.t('prepare_context_planner.next_safe_commands'),
|
|
569
602
|
'- npx create-quiver ai prepare-context --with-planner --print-prompt',
|
|
570
603
|
'- npx create-quiver ai prepare-context --with-planner --dry-run --review',
|
|
571
604
|
'- npx create-quiver ai prepare-context --with-planner',
|
|
@@ -909,17 +942,18 @@ function writeDraftDocs(writePlan) {
|
|
|
909
942
|
return writtenDocs;
|
|
910
943
|
}
|
|
911
944
|
|
|
912
|
-
function formatSpecDryRunReport({ manifest, repoRoot }) {
|
|
945
|
+
function formatSpecDryRunReport({ manifest, repoRoot, language }) {
|
|
946
|
+
const translator = createTranslator(language);
|
|
913
947
|
const preview = describeSpecGeneration(manifest, repoRoot);
|
|
914
948
|
const relativeSpecDir = path.relative(repoRoot, preview.specDir).split(path.sep).join('/');
|
|
915
949
|
const lines = [
|
|
916
|
-
'
|
|
917
|
-
'
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
950
|
+
translator.t('ai.plan.spec.dry_run.title'),
|
|
951
|
+
translator.t('ai_task.phase', { phase: 'spec' }),
|
|
952
|
+
translator.t('ai.plan.spec.slug', { slug: manifest.slug }),
|
|
953
|
+
translator.t('ai.plan.spec.title', { title: manifest.title }),
|
|
954
|
+
translator.t('ai_task.input_file', { path: manifest.sourcePath }),
|
|
955
|
+
translator.t('ai.plan.spec.target', { target: relativeSpecDir }),
|
|
956
|
+
translator.t('ai.plan.spec.planned_files', { count: preview.files.length }),
|
|
923
957
|
];
|
|
924
958
|
|
|
925
959
|
for (const file of preview.files) {
|
|
@@ -929,13 +963,14 @@ function formatSpecDryRunReport({ manifest, repoRoot }) {
|
|
|
929
963
|
return `${lines.join('\n')}\n`;
|
|
930
964
|
}
|
|
931
965
|
|
|
932
|
-
function formatSpecGenerationResult(result, repoRoot) {
|
|
966
|
+
function formatSpecGenerationResult(result, repoRoot, options = {}) {
|
|
967
|
+
const translator = createTranslator(options.language);
|
|
933
968
|
const relativeSpecDir = path.relative(repoRoot, result.specDir).split(path.sep).join('/');
|
|
934
969
|
const lines = [
|
|
935
|
-
'
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
970
|
+
translator.t('ai.plan.spec.completed'),
|
|
971
|
+
translator.t('ai.plan.spec.slug', { slug: result.manifest.slug }),
|
|
972
|
+
translator.t('ai.plan.spec.target', { target: relativeSpecDir }),
|
|
973
|
+
translator.t('ai.plan.spec.files_written', { count: result.files.length }),
|
|
939
974
|
];
|
|
940
975
|
|
|
941
976
|
for (const filePath of result.files) {
|
|
@@ -945,30 +980,32 @@ function formatSpecGenerationResult(result, repoRoot) {
|
|
|
945
980
|
return `${lines.join('\n')}\n`;
|
|
946
981
|
}
|
|
947
982
|
|
|
948
|
-
function formatApprovalResult(result, repoRoot) {
|
|
983
|
+
function formatApprovalResult(result, repoRoot, options = {}) {
|
|
984
|
+
const translator = createTranslator(options.language);
|
|
949
985
|
const relativePath = path.relative(repoRoot, result.filePath).split(path.sep).join('/');
|
|
950
986
|
const lines = [
|
|
951
|
-
'
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
987
|
+
translator.t('ai.approve.saved'),
|
|
988
|
+
translator.t('ai_task.phase', { phase: result.phase }),
|
|
989
|
+
`${translator.t('ai.table.status')}: ${translator.t('ai.approve.status.approved')}`,
|
|
990
|
+
`${translator.t('ai.approve.artifact')}: ${relativePath}`,
|
|
991
|
+
`${translator.t('ai.approvals.source_file')}: ${result.sourceFile}`,
|
|
992
|
+
`${translator.t('ai.approve.timestamp')}: ${result.createdAt}`,
|
|
957
993
|
];
|
|
958
994
|
if (result.version) {
|
|
959
|
-
lines.push(
|
|
995
|
+
lines.push(`${translator.t('ai.approve.version')}: v${result.version}`);
|
|
960
996
|
}
|
|
961
997
|
|
|
962
998
|
return `${lines.join('\n')}\n`;
|
|
963
999
|
}
|
|
964
1000
|
|
|
965
|
-
function formatApprovalDryRunResult({ phase, input, version }) {
|
|
966
|
-
const
|
|
1001
|
+
function formatApprovalDryRunResult({ phase, input, version, language }) {
|
|
1002
|
+
const translator = createTranslator(language);
|
|
1003
|
+
const lines = [translator.t('ai.approve.dry_run.title'), translator.t('ai_task.phase', { phase })];
|
|
967
1004
|
if (version) {
|
|
968
|
-
lines.push(
|
|
1005
|
+
lines.push(`${translator.t('ai.approve.version')}: v${version}`);
|
|
969
1006
|
}
|
|
970
1007
|
if (input) {
|
|
971
|
-
lines.push(
|
|
1008
|
+
lines.push(translator.t('ai_task.input_file', { path: input }));
|
|
972
1009
|
}
|
|
973
1010
|
return `${lines.join('\n')}\n`;
|
|
974
1011
|
}
|
|
@@ -1076,15 +1113,16 @@ function buildRepairPlanContext({ context, inputText, inputPath, repoRoot, role,
|
|
|
1076
1113
|
};
|
|
1077
1114
|
}
|
|
1078
1115
|
|
|
1079
|
-
function formatRepairPlanResult(result, repoRoot) {
|
|
1116
|
+
function formatRepairPlanResult(result, repoRoot, options = {}) {
|
|
1117
|
+
const translator = createTranslator(options.language);
|
|
1080
1118
|
const relativePath = path.relative(repoRoot, result.filePath).split(path.sep).join('/');
|
|
1081
1119
|
return [
|
|
1082
|
-
'
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
'
|
|
1087
|
-
'
|
|
1120
|
+
translator.t('ai.repair_plan.saved'),
|
|
1121
|
+
`${translator.t('ai.approvals.draft')}: ${relativePath}`,
|
|
1122
|
+
`${translator.t('ai.approve.version')}: v${result.version}`,
|
|
1123
|
+
`${translator.t('ai.repair_plan.source_approved_artifact')}: ${result.sourcePath}`,
|
|
1124
|
+
translator.t('ai.repair_plan.original_preserved'),
|
|
1125
|
+
`${translator.t('ai.label.next_safe_commands')}:`,
|
|
1088
1126
|
'- npx create-quiver ai review-plan --dry-run',
|
|
1089
1127
|
'- npx create-quiver ai review-plan',
|
|
1090
1128
|
`- npx create-quiver ai approve --phase technical-plan --version ${result.version}`,
|
|
@@ -1188,16 +1226,17 @@ function classifyGlobalApprovalRelation(report, runApprovalRows) {
|
|
|
1188
1226
|
return 'orphaned';
|
|
1189
1227
|
}
|
|
1190
1228
|
|
|
1191
|
-
function formatRunScopedApprovals(repoRoot, runApprovalRows) {
|
|
1229
|
+
function formatRunScopedApprovals(repoRoot, runApprovalRows, options = {}) {
|
|
1230
|
+
const translator = translatorForHuman(options);
|
|
1192
1231
|
const runs = listAiRuns(repoRoot);
|
|
1193
1232
|
const activeRun = resolveAiRun(repoRoot, '');
|
|
1194
1233
|
const lines = [
|
|
1195
|
-
'
|
|
1196
|
-
|
|
1234
|
+
translator.t('ai.approvals.run_scoped'),
|
|
1235
|
+
`${translator.t('ai.approvals.active_run')}: ${activeRun ? activeRun.run_id : translator.t('ai.approvals.none_value')}`,
|
|
1197
1236
|
];
|
|
1198
1237
|
|
|
1199
1238
|
if (runs.length === 0) {
|
|
1200
|
-
lines.push(
|
|
1239
|
+
lines.push(`- ${translator.t('ai.approvals.no_ai_runs')}`);
|
|
1201
1240
|
return `${lines.join('\n')}\n`;
|
|
1202
1241
|
}
|
|
1203
1242
|
|
|
@@ -1208,9 +1247,9 @@ function formatRunScopedApprovals(repoRoot, runApprovalRows) {
|
|
|
1208
1247
|
? 'historical'
|
|
1209
1248
|
: 'other-open';
|
|
1210
1249
|
const approvals = runApprovalRows.filter((row) => row.run.run_id === run.run_id);
|
|
1211
|
-
lines.push(
|
|
1250
|
+
lines.push(`${translator.t('ai.run.run')}: ${run.run_id} (${translator.t(`ai.approvals.relation.${relation}`)}, ${translator.t('ai.run.phase').toLowerCase()}: ${run.phase}, ${translator.t('ai.run.status').toLowerCase()}: ${formatStatus(run.status, translator)})`);
|
|
1212
1251
|
if (approvals.length === 0) {
|
|
1213
|
-
lines.push('
|
|
1252
|
+
lines.push(`- ${translator.t('ai.approvals.no_run_scoped')}`);
|
|
1214
1253
|
continue;
|
|
1215
1254
|
}
|
|
1216
1255
|
for (const row of approvals) {
|
|
@@ -1223,18 +1262,76 @@ function formatRunScopedApprovals(repoRoot, runApprovalRows) {
|
|
|
1223
1262
|
}
|
|
1224
1263
|
|
|
1225
1264
|
function formatApprovalStatusReport(repoRoot) {
|
|
1265
|
+
return formatApprovalStatusReportWithOptions(repoRoot);
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
function localizeApprovalSummary(text, translator) {
|
|
1269
|
+
if (translator.language === 'en') {
|
|
1270
|
+
return text;
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
return String(text || '')
|
|
1274
|
+
.split('\n')
|
|
1275
|
+
.map((line) => {
|
|
1276
|
+
let match = line.match(/^Phase: (.+)$/);
|
|
1277
|
+
if (match) return `${translator.t('ai.run.phase')}: ${match[1]}`;
|
|
1278
|
+
match = line.match(/^Status: (.+)$/);
|
|
1279
|
+
if (match) return `${translator.t('ai.run.status')}: ${formatStatus(match[1], translator)}`;
|
|
1280
|
+
match = line.match(/^Draft( v\d+)?: (.+)$/);
|
|
1281
|
+
if (match) return `${translator.t('ai.approvals.draft')}${match[1] || ''}: ${match[2]}`;
|
|
1282
|
+
if (line === 'Draft history:') return `${translator.t('ai.approvals.draft_history')}:`;
|
|
1283
|
+
match = line.match(/^Approved( v\d+)?: (.+)$/);
|
|
1284
|
+
if (match) return `${translator.t('ai.approvals.approved')}${match[1] || ''}: ${match[2]}`;
|
|
1285
|
+
match = line.match(/^Source file: (.+)$/);
|
|
1286
|
+
if (match) return `${translator.t('ai.approvals.source_file')}: ${match[1]}`;
|
|
1287
|
+
match = line.match(/^Review: (.+)$/);
|
|
1288
|
+
if (match) return `${translator.t('ai.approvals.review')}: ${match[1]}`;
|
|
1289
|
+
match = line.match(/^Approval recommendation: (.+)$/);
|
|
1290
|
+
if (match) return `${translator.t('ai.approvals.approval_recommendation')}: ${match[1]}`;
|
|
1291
|
+
match = line.match(/^Blocking: (yes|no)$/);
|
|
1292
|
+
if (match) return `${translator.t('ai.approvals.blocking')}: ${translator.t(match[1] === 'yes' ? 'common.yes' : 'common.no')}`;
|
|
1293
|
+
match = line.match(/^Required fixes: (.+)$/);
|
|
1294
|
+
if (match) return `${translator.t('ai.approvals.required_fixes')}: ${match[1]}`;
|
|
1295
|
+
match = line.match(/^Optional hardening: (.+)$/);
|
|
1296
|
+
if (match) return `${translator.t('ai.approvals.optional_hardening')}: ${match[1]}`;
|
|
1297
|
+
match = line.match(/^Next command: (.+)$/);
|
|
1298
|
+
if (match) return `${translator.t('ai.approvals.next_command')}: ${match[1]}`;
|
|
1299
|
+
return line;
|
|
1300
|
+
})
|
|
1301
|
+
.join('\n');
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
function localizeApprovalDecisionLine(line, translator) {
|
|
1305
|
+
if (translator.language === 'en') {
|
|
1306
|
+
return line;
|
|
1307
|
+
}
|
|
1308
|
+
return String(line || '')
|
|
1309
|
+
.replace(/^Candidates:/, translator.t('ai.approvals.candidates') + ':')
|
|
1310
|
+
.replace(/^Latest draft:/, translator.t('ai.approvals.latest_draft') + ':')
|
|
1311
|
+
.replace(/^Current candidate:/, translator.t('ai.approvals.current_candidate') + ':')
|
|
1312
|
+
.replace(/^Recommended approval:/, translator.t('ai.approvals.recommended_approval') + ':')
|
|
1313
|
+
.replace(/^Recommended next command:/, translator.t('ai.approvals.recommended_next_command') + ':')
|
|
1314
|
+
.replace(/^Review status:/, translator.t('ai.approvals.review_status') + ':');
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
function formatApprovalStatusReportWithOptions(repoRoot, options = {}) {
|
|
1318
|
+
const translator = translatorForHuman(options);
|
|
1226
1319
|
const runApprovalRows = collectRunApprovalRows(repoRoot);
|
|
1227
|
-
const sections = [
|
|
1320
|
+
const sections = [
|
|
1321
|
+
translator.t('ai.approvals.title'),
|
|
1322
|
+
formatRunScopedApprovals(repoRoot, runApprovalRows, options).trimEnd(),
|
|
1323
|
+
translator.t('ai.approvals.global_planner'),
|
|
1324
|
+
];
|
|
1228
1325
|
for (const phase of PLANNER_APPROVAL_PHASES) {
|
|
1229
|
-
const summary = summarizePlannerApproval(repoRoot, phase).trimEnd();
|
|
1326
|
+
const summary = localizeApprovalSummary(summarizePlannerApproval(repoRoot, phase).trimEnd(), translator);
|
|
1230
1327
|
const relation = classifyGlobalApprovalRelation(readPhaseApproval(repoRoot, phase), runApprovalRows);
|
|
1231
1328
|
const candidates = buildApprovalCandidateReport(repoRoot, phase);
|
|
1232
1329
|
const decisionLines = formatApprovalDecisionLines(candidates)
|
|
1233
|
-
.map((line) => `- ${line}`)
|
|
1330
|
+
.map((line) => `- ${localizeApprovalDecisionLine(line, translator)}`)
|
|
1234
1331
|
.join('\n');
|
|
1235
|
-
sections.push(`${summary}\
|
|
1332
|
+
sections.push(`${summary}\n${translator.t('ai.approvals.run_relation')}: ${translator.t(`ai.approvals.relation.${relation}`)}${decisionLines ? `\n${translator.t('ai.approvals.approval_candidates')}:\n${decisionLines}` : ''}`);
|
|
1236
1333
|
}
|
|
1237
|
-
sections.push(summarizePlanReview(repoRoot).trimEnd());
|
|
1334
|
+
sections.push(localizeApprovalSummary(summarizePlanReview(repoRoot).trimEnd(), translator));
|
|
1238
1335
|
return `${sections.join('\n\n')}\n`;
|
|
1239
1336
|
}
|
|
1240
1337
|
|
|
@@ -1291,6 +1388,7 @@ async function runOnboard(repoRoot, options = {}) {
|
|
|
1291
1388
|
role,
|
|
1292
1389
|
contextPack: context,
|
|
1293
1390
|
invocation,
|
|
1391
|
+
language: options.language,
|
|
1294
1392
|
onboardingPlan: contextInfo.plan,
|
|
1295
1393
|
profile: runtimeProfile,
|
|
1296
1394
|
};
|
|
@@ -1305,6 +1403,7 @@ async function runOnboard(repoRoot, options = {}) {
|
|
|
1305
1403
|
role,
|
|
1306
1404
|
contextPack: context,
|
|
1307
1405
|
invocation,
|
|
1406
|
+
language: options.language,
|
|
1308
1407
|
onboardingPlan: contextInfo.plan,
|
|
1309
1408
|
prompt,
|
|
1310
1409
|
profile: runtimeProfile,
|
|
@@ -1315,11 +1414,16 @@ async function runOnboard(repoRoot, options = {}) {
|
|
|
1315
1414
|
|
|
1316
1415
|
const ux = createCommandUx(options);
|
|
1317
1416
|
const showProgress = shouldShowHumanProgress(ux, options);
|
|
1417
|
+
const progressTranslator = createTranslator(options.language);
|
|
1318
1418
|
writeProgressChecks(
|
|
1319
1419
|
ux,
|
|
1320
1420
|
showProgress,
|
|
1321
|
-
plannerProgressTitle('
|
|
1322
|
-
[
|
|
1421
|
+
plannerProgressTitle(progressTranslator.t('ai.planner.progress.onboarding'), runtimeProfile, options),
|
|
1422
|
+
[
|
|
1423
|
+
progressTranslator.t('ai.planner.progress.reading_base_docs'),
|
|
1424
|
+
progressTranslator.t('ai.planner.progress.detecting_structure'),
|
|
1425
|
+
progressTranslator.t('ai.planner.progress.preparing_prompt'),
|
|
1426
|
+
],
|
|
1323
1427
|
);
|
|
1324
1428
|
|
|
1325
1429
|
let result;
|
|
@@ -1327,6 +1431,9 @@ async function runOnboard(repoRoot, options = {}) {
|
|
|
1327
1431
|
result = await runProviderWithProgress({
|
|
1328
1432
|
ux,
|
|
1329
1433
|
enabled: showProgress,
|
|
1434
|
+
message: progressTranslator.t('ai.planner.progress.running_agent'),
|
|
1435
|
+
successMessage: progressTranslator.t('ai.planner.progress.agent_finished'),
|
|
1436
|
+
failureMessage: progressTranslator.t('ai.planner.progress.agent_failed'),
|
|
1330
1437
|
run: () => (options.runProviderFn || runProvider)(provider, {
|
|
1331
1438
|
prompt,
|
|
1332
1439
|
cwd: repoRoot,
|
|
@@ -1390,6 +1497,7 @@ async function runPrepareContext(repoRoot, options = {}) {
|
|
|
1390
1497
|
plan: draftPack.plan,
|
|
1391
1498
|
writePlan,
|
|
1392
1499
|
writtenDocs: [],
|
|
1500
|
+
language: options.language,
|
|
1393
1501
|
}));
|
|
1394
1502
|
return report;
|
|
1395
1503
|
}
|
|
@@ -1408,6 +1516,7 @@ async function runPrepareContext(repoRoot, options = {}) {
|
|
|
1408
1516
|
writePlan,
|
|
1409
1517
|
writtenDocs: plannedDocs,
|
|
1410
1518
|
snapshot,
|
|
1519
|
+
language: options.language,
|
|
1411
1520
|
}));
|
|
1412
1521
|
const writtenDocs = writeDraftDocs(writePlan);
|
|
1413
1522
|
updateAiRunPhase(repoRoot, lifecycleRun.run_id, 'onboarding-ready', {
|
|
@@ -1421,6 +1530,7 @@ async function runPrepareContext(repoRoot, options = {}) {
|
|
|
1421
1530
|
writtenDocs,
|
|
1422
1531
|
snapshot,
|
|
1423
1532
|
completed: true,
|
|
1533
|
+
language: options.language,
|
|
1424
1534
|
}));
|
|
1425
1535
|
|
|
1426
1536
|
return {
|
|
@@ -1485,6 +1595,7 @@ async function runPrepareContextWithPlanner(repoRoot, options = {}) {
|
|
|
1485
1595
|
promptInfo,
|
|
1486
1596
|
review: options.review === true,
|
|
1487
1597
|
interactive: options.interactive === true,
|
|
1598
|
+
language: options.language,
|
|
1488
1599
|
}));
|
|
1489
1600
|
return report;
|
|
1490
1601
|
}
|
|
@@ -1506,11 +1617,16 @@ async function runPrepareContextWithPlanner(repoRoot, options = {}) {
|
|
|
1506
1617
|
|
|
1507
1618
|
const ux = createCommandUx(options);
|
|
1508
1619
|
const showProgress = shouldShowHumanProgress(ux, options);
|
|
1620
|
+
const progressTranslator = createTranslator(options.language);
|
|
1509
1621
|
writeProgressChecks(
|
|
1510
1622
|
ux,
|
|
1511
1623
|
showProgress,
|
|
1512
|
-
plannerProgressTitle('
|
|
1513
|
-
[
|
|
1624
|
+
plannerProgressTitle(progressTranslator.t('ai.planner.progress.onboarding'), runtimeProfile, options),
|
|
1625
|
+
[
|
|
1626
|
+
progressTranslator.t('ai.planner.progress.reading_base_docs'),
|
|
1627
|
+
progressTranslator.t('ai.planner.progress.detecting_structure'),
|
|
1628
|
+
progressTranslator.t('ai.planner.progress.preparing_prompt'),
|
|
1629
|
+
],
|
|
1514
1630
|
);
|
|
1515
1631
|
|
|
1516
1632
|
let result;
|
|
@@ -1518,6 +1634,9 @@ async function runPrepareContextWithPlanner(repoRoot, options = {}) {
|
|
|
1518
1634
|
result = await runProviderWithProgress({
|
|
1519
1635
|
ux,
|
|
1520
1636
|
enabled: showProgress,
|
|
1637
|
+
message: progressTranslator.t('ai.planner.progress.running_agent'),
|
|
1638
|
+
successMessage: progressTranslator.t('ai.planner.progress.agent_finished'),
|
|
1639
|
+
failureMessage: progressTranslator.t('ai.planner.progress.agent_failed'),
|
|
1521
1640
|
run: () => (options.runProviderFn || runProvider)(provider, {
|
|
1522
1641
|
prompt,
|
|
1523
1642
|
cwd: repoRoot,
|
|
@@ -1569,6 +1688,7 @@ async function runPrepareContextWithPlanner(repoRoot, options = {}) {
|
|
|
1569
1688
|
writePlan,
|
|
1570
1689
|
writtenDocs: plannedDocs,
|
|
1571
1690
|
snapshot,
|
|
1691
|
+
language: options.language,
|
|
1572
1692
|
}));
|
|
1573
1693
|
|
|
1574
1694
|
const writtenDocs = writeDraftDocs(writePlan);
|
|
@@ -1583,6 +1703,7 @@ async function runPrepareContextWithPlanner(repoRoot, options = {}) {
|
|
|
1583
1703
|
writtenDocs,
|
|
1584
1704
|
snapshot,
|
|
1585
1705
|
completed: true,
|
|
1706
|
+
language: options.language,
|
|
1586
1707
|
}));
|
|
1587
1708
|
|
|
1588
1709
|
return {
|
|
@@ -1628,8 +1749,9 @@ async function runPlan(repoRoot, options = {}) {
|
|
|
1628
1749
|
phase,
|
|
1629
1750
|
manifest,
|
|
1630
1751
|
};
|
|
1631
|
-
|
|
1632
|
-
process.stdout.write(
|
|
1752
|
+
const translator = createTranslator(options.language);
|
|
1753
|
+
process.stdout.write(`${translator.t('ai_task.title.prompt_only', { task: 'plan' })}\n${translator.t('ai_task.phase', { phase: 'spec' })}\n${translator.t('ai.plan.spec.prompt_only_no_provider')}\n`);
|
|
1754
|
+
process.stdout.write(formatSpecDryRunReport({ manifest, repoRoot, language: options.language }));
|
|
1633
1755
|
return report;
|
|
1634
1756
|
}
|
|
1635
1757
|
|
|
@@ -1639,7 +1761,7 @@ async function runPlan(repoRoot, options = {}) {
|
|
|
1639
1761
|
phase,
|
|
1640
1762
|
manifest,
|
|
1641
1763
|
};
|
|
1642
|
-
process.stdout.write(formatSpecDryRunReport({ manifest, repoRoot }));
|
|
1764
|
+
process.stdout.write(formatSpecDryRunReport({ manifest, repoRoot, language: options.language }));
|
|
1643
1765
|
return report;
|
|
1644
1766
|
}
|
|
1645
1767
|
|
|
@@ -1647,7 +1769,7 @@ async function runPlan(repoRoot, options = {}) {
|
|
|
1647
1769
|
input: inputPath,
|
|
1648
1770
|
specSlug: options.specSlug,
|
|
1649
1771
|
});
|
|
1650
|
-
process.stdout.write(formatSpecGenerationResult(result, repoRoot));
|
|
1772
|
+
process.stdout.write(formatSpecGenerationResult(result, repoRoot, options));
|
|
1651
1773
|
|
|
1652
1774
|
return {
|
|
1653
1775
|
task: 'plan',
|
|
@@ -1728,15 +1850,15 @@ async function runPlan(repoRoot, options = {}) {
|
|
|
1728
1850
|
invocation,
|
|
1729
1851
|
profile: runtimeProfile,
|
|
1730
1852
|
};
|
|
1731
|
-
process.stdout.write(formatDryRunReport(report));
|
|
1853
|
+
process.stdout.write(formatDryRunReport({ ...report, language: options.language }));
|
|
1732
1854
|
if (options.withPlanner === true) {
|
|
1733
|
-
process.stdout.write('
|
|
1855
|
+
process.stdout.write(`${createTranslator(options.language).t('ai.plan.with_planner_already_active')}\n`);
|
|
1734
1856
|
}
|
|
1735
1857
|
if (options.review === true) {
|
|
1736
|
-
process.stdout.write('
|
|
1858
|
+
process.stdout.write(`${createTranslator(options.language).t('ai.plan.review_requested')}\n`);
|
|
1737
1859
|
}
|
|
1738
1860
|
if (options.interactive === true) {
|
|
1739
|
-
process.stdout.write('
|
|
1861
|
+
process.stdout.write(`${createTranslator(options.language).t('ai.plan.interactive_requested')}\n`);
|
|
1740
1862
|
}
|
|
1741
1863
|
return report;
|
|
1742
1864
|
}
|
|
@@ -1752,7 +1874,7 @@ async function runPlan(repoRoot, options = {}) {
|
|
|
1752
1874
|
prompt,
|
|
1753
1875
|
profile: runtimeProfile,
|
|
1754
1876
|
};
|
|
1755
|
-
process.stdout.write(formatPromptOnlyReport(report));
|
|
1877
|
+
process.stdout.write(formatPromptOnlyReport({ ...report, language: options.language }));
|
|
1756
1878
|
return report;
|
|
1757
1879
|
}
|
|
1758
1880
|
|
|
@@ -1761,8 +1883,12 @@ async function runPlan(repoRoot, options = {}) {
|
|
|
1761
1883
|
writeProgressChecks(
|
|
1762
1884
|
ux,
|
|
1763
1885
|
showProgress,
|
|
1764
|
-
plannerProgressTitle(
|
|
1765
|
-
[
|
|
1886
|
+
plannerProgressTitle(createTranslator(options.language).t('ai.planner.progress.plan', { phase }), runtimeProfile, options),
|
|
1887
|
+
[
|
|
1888
|
+
createTranslator(options.language).t('ai.planner.progress.reading_input'),
|
|
1889
|
+
createTranslator(options.language).t('ai.planner.progress.preparing_context'),
|
|
1890
|
+
createTranslator(options.language).t('ai.planner.progress.preparing_prompt'),
|
|
1891
|
+
],
|
|
1766
1892
|
);
|
|
1767
1893
|
|
|
1768
1894
|
let result;
|
|
@@ -1905,12 +2031,14 @@ async function runReviewPlan(repoRoot, options = {}) {
|
|
|
1905
2031
|
contextPack: pack.packName,
|
|
1906
2032
|
phase: 'plan-review',
|
|
1907
2033
|
invocation,
|
|
2034
|
+
language: options.language,
|
|
1908
2035
|
}));
|
|
1909
|
-
|
|
1910
|
-
process.stdout.write(
|
|
1911
|
-
process.stdout.write(
|
|
2036
|
+
const translator = createTranslator(options.language);
|
|
2037
|
+
process.stdout.write(`${translator.t('ai_task.prompt_source', { source: built.promptSource })}\n`);
|
|
2038
|
+
process.stdout.write(`${translator.t('ai_task.input_file', { path: inputPath })}\n`);
|
|
2039
|
+
process.stdout.write(`${translator.t('ai_task.input_kind', { kind: resolved.kind })}\n`);
|
|
1912
2040
|
if (resolved.version) {
|
|
1913
|
-
process.stdout.write(
|
|
2041
|
+
process.stdout.write(`${translator.t('ai_task.input_version', { version: resolved.version })}\n`);
|
|
1914
2042
|
}
|
|
1915
2043
|
return report;
|
|
1916
2044
|
}
|
|
@@ -1930,7 +2058,7 @@ async function runReviewPlan(repoRoot, options = {}) {
|
|
|
1930
2058
|
inputVersion: resolved.version,
|
|
1931
2059
|
profile: runtimeProfile,
|
|
1932
2060
|
};
|
|
1933
|
-
process.stdout.write(formatPromptOnlyReport(report));
|
|
2061
|
+
process.stdout.write(formatPromptOnlyReport({ ...report, language: options.language }));
|
|
1934
2062
|
return report;
|
|
1935
2063
|
}
|
|
1936
2064
|
|
|
@@ -1939,8 +2067,12 @@ async function runReviewPlan(repoRoot, options = {}) {
|
|
|
1939
2067
|
writeProgressChecks(
|
|
1940
2068
|
ux,
|
|
1941
2069
|
showProgress,
|
|
1942
|
-
plannerProgressTitle('
|
|
1943
|
-
[
|
|
2070
|
+
plannerProgressTitle(createTranslator(options.language).t('ai.planner.progress.review_plan'), runtimeProfile, options),
|
|
2071
|
+
[
|
|
2072
|
+
createTranslator(options.language).t('ai.planner.progress.reading_technical_plan'),
|
|
2073
|
+
createTranslator(options.language).t('ai.planner.progress.preparing_context'),
|
|
2074
|
+
createTranslator(options.language).t('ai.planner.progress.preparing_prompt'),
|
|
2075
|
+
],
|
|
1944
2076
|
);
|
|
1945
2077
|
|
|
1946
2078
|
let result;
|
|
@@ -1999,8 +2131,9 @@ async function runReviewPlan(repoRoot, options = {}) {
|
|
|
1999
2131
|
rawArtifactPath: rawArtifact.path,
|
|
2000
2132
|
});
|
|
2001
2133
|
const relativePath = path.relative(repoRoot, saved.filePath).split(path.sep).join('/');
|
|
2002
|
-
const summary = summarizePlanReview(repoRoot).trimEnd();
|
|
2003
|
-
|
|
2134
|
+
const summary = localizeApprovalSummary(summarizePlanReview(repoRoot), createTranslator(options.language)).trimEnd();
|
|
2135
|
+
const translator = createTranslator(options.language);
|
|
2136
|
+
process.stdout.write(`${translator.t('ai.review_plan.saved')}\n${translator.t('ai.approve.artifact')}: ${relativePath}\n${translator.t('ai_task.prompt_source', { source: PLAN_REVIEW_PROMPT_SOURCE })}\n${summary}\n`);
|
|
2004
2137
|
|
|
2005
2138
|
return {
|
|
2006
2139
|
task: 'review-plan',
|
|
@@ -2060,9 +2193,10 @@ async function runRepairPlan(repoRoot, options = {}) {
|
|
|
2060
2193
|
invocation,
|
|
2061
2194
|
profile: runtimeProfile,
|
|
2062
2195
|
};
|
|
2063
|
-
process.stdout.write(formatDryRunReport(report));
|
|
2064
|
-
|
|
2065
|
-
process.stdout.write(
|
|
2196
|
+
process.stdout.write(formatDryRunReport({ ...report, language: options.language }));
|
|
2197
|
+
const translator = createTranslator(options.language);
|
|
2198
|
+
process.stdout.write(`${translator.t('ai.repair_plan.source_approved_artifact')}: ${source.path}\n`);
|
|
2199
|
+
process.stdout.write(`${translator.t('ai.repair_plan.validation_failure')}: ${source.validationError}\n`);
|
|
2066
2200
|
return report;
|
|
2067
2201
|
}
|
|
2068
2202
|
|
|
@@ -2080,7 +2214,7 @@ async function runRepairPlan(repoRoot, options = {}) {
|
|
|
2080
2214
|
inputVersion: source.approval.meta?.approved?.version || null,
|
|
2081
2215
|
profile: runtimeProfile,
|
|
2082
2216
|
};
|
|
2083
|
-
process.stdout.write(formatPromptOnlyReport(report));
|
|
2217
|
+
process.stdout.write(formatPromptOnlyReport({ ...report, language: options.language }));
|
|
2084
2218
|
return report;
|
|
2085
2219
|
}
|
|
2086
2220
|
|
|
@@ -2089,15 +2223,23 @@ async function runRepairPlan(repoRoot, options = {}) {
|
|
|
2089
2223
|
writeProgressChecks(
|
|
2090
2224
|
ux,
|
|
2091
2225
|
showProgress,
|
|
2092
|
-
plannerProgressTitle('
|
|
2093
|
-
[
|
|
2226
|
+
plannerProgressTitle(createTranslator(options.language).t('ai.planner.progress.repair_plan'), runtimeProfile, options),
|
|
2227
|
+
[
|
|
2228
|
+
createTranslator(options.language).t('ai.planner.progress.reading_approved_plan'),
|
|
2229
|
+
createTranslator(options.language).t('ai.planner.progress.preparing_context'),
|
|
2230
|
+
createTranslator(options.language).t('ai.planner.progress.preparing_prompt'),
|
|
2231
|
+
],
|
|
2094
2232
|
);
|
|
2095
2233
|
|
|
2096
2234
|
let providerResult;
|
|
2097
2235
|
try {
|
|
2236
|
+
const progressTranslator = createTranslator(options.language);
|
|
2098
2237
|
providerResult = await runProviderWithProgress({
|
|
2099
2238
|
ux,
|
|
2100
2239
|
enabled: showProgress,
|
|
2240
|
+
message: progressTranslator.t('ai.planner.progress.running_agent'),
|
|
2241
|
+
successMessage: progressTranslator.t('ai.planner.progress.agent_finished'),
|
|
2242
|
+
failureMessage: progressTranslator.t('ai.planner.progress.agent_failed'),
|
|
2101
2243
|
run: () => (options.runProviderFn || runProvider)(provider, {
|
|
2102
2244
|
prompt: built.prompt,
|
|
2103
2245
|
cwd: repoRoot,
|
|
@@ -2164,7 +2306,7 @@ async function runRepairPlan(repoRoot, options = {}) {
|
|
|
2164
2306
|
process.stdout.write(formatRepairPlanResult({
|
|
2165
2307
|
...draft,
|
|
2166
2308
|
sourcePath: source.path,
|
|
2167
|
-
}, repoRoot));
|
|
2309
|
+
}, repoRoot, options));
|
|
2168
2310
|
|
|
2169
2311
|
return {
|
|
2170
2312
|
task: 'repair-plan',
|
|
@@ -2181,14 +2323,18 @@ async function runRepairPlan(repoRoot, options = {}) {
|
|
|
2181
2323
|
}
|
|
2182
2324
|
|
|
2183
2325
|
async function runRevise(repoRoot, options = {}) {
|
|
2326
|
+
const translator = createTranslator(options.language);
|
|
2184
2327
|
const phase = normalizePlannerPhase(options.phase || DEFAULT_PLAN_PHASE);
|
|
2185
2328
|
if (phase === 'spec') {
|
|
2186
|
-
throw new Error(formatError(
|
|
2329
|
+
throw new Error(formatError(translator.t('ai.revise.error.unsupported_phase', { phase })));
|
|
2187
2330
|
}
|
|
2188
2331
|
|
|
2189
2332
|
const approval = readPhaseApproval(repoRoot, phase);
|
|
2190
2333
|
if (approval.status !== 'draft' && approval.status !== 'stale') {
|
|
2191
|
-
throw new Error(formatError(
|
|
2334
|
+
throw new Error(formatError(translator.t('ai.revise.error.requires_draft', {
|
|
2335
|
+
phase,
|
|
2336
|
+
status: approval.status,
|
|
2337
|
+
})));
|
|
2192
2338
|
}
|
|
2193
2339
|
|
|
2194
2340
|
return runPlan(repoRoot, {
|
|
@@ -2198,10 +2344,11 @@ async function runRevise(repoRoot, options = {}) {
|
|
|
2198
2344
|
});
|
|
2199
2345
|
}
|
|
2200
2346
|
|
|
2201
|
-
function formatApprovalCandidateHint(candidate) {
|
|
2347
|
+
function formatApprovalCandidateHint(candidate, options = {}) {
|
|
2348
|
+
const translator = createTranslator(options.language);
|
|
2202
2349
|
const parts = [];
|
|
2203
2350
|
if (candidate.current) {
|
|
2204
|
-
parts.push('
|
|
2351
|
+
parts.push(translator.t('ai.approvals.current_candidate').toLowerCase());
|
|
2205
2352
|
}
|
|
2206
2353
|
if (candidate.created_at) {
|
|
2207
2354
|
parts.push(candidate.created_at);
|
|
@@ -2210,10 +2357,10 @@ function formatApprovalCandidateHint(candidate) {
|
|
|
2210
2357
|
parts.push(`review=${candidate.review.recommendation}`);
|
|
2211
2358
|
}
|
|
2212
2359
|
if (candidate.review?.required_fixes_count) {
|
|
2213
|
-
parts.push(
|
|
2360
|
+
parts.push(`${translator.t('ai.approvals.required_fixes').toLowerCase()}=${candidate.review.required_fixes_count}`);
|
|
2214
2361
|
}
|
|
2215
2362
|
if (candidate.review?.optional_hardening_count) {
|
|
2216
|
-
parts.push(
|
|
2363
|
+
parts.push(`${translator.t('ai.approvals.optional_hardening').toLowerCase()}=${candidate.review.optional_hardening_count}`);
|
|
2217
2364
|
}
|
|
2218
2365
|
if (candidate.review?.risks_count) {
|
|
2219
2366
|
parts.push(`risks=${candidate.review.risks_count}`);
|
|
@@ -2222,17 +2369,19 @@ function formatApprovalCandidateHint(candidate) {
|
|
|
2222
2369
|
return parts.filter(Boolean).join(', ');
|
|
2223
2370
|
}
|
|
2224
2371
|
|
|
2225
|
-
function approvalSelectionOptions(report) {
|
|
2372
|
+
function approvalSelectionOptions(report, options = {}) {
|
|
2373
|
+
const translator = createTranslator(options.language);
|
|
2226
2374
|
return report.candidates.map((candidate) => ({
|
|
2227
|
-
label: `${candidate.label}${candidate.recommended ?
|
|
2375
|
+
label: `${candidate.label}${candidate.recommended ? ` (${translator.t('ai.approvals.recommended_approval').toLowerCase()})` : candidate.current ? ` (${translator.t('ai.approvals.current_candidate').toLowerCase()})` : ` (${translator.t('ai.approvals.draft_history').toLowerCase()})`}`,
|
|
2228
2376
|
value: String(candidate.version || ''),
|
|
2229
|
-
hint: formatApprovalCandidateHint(candidate),
|
|
2377
|
+
hint: formatApprovalCandidateHint(candidate, options),
|
|
2230
2378
|
default: candidate.recommended === true,
|
|
2231
2379
|
raw: candidate,
|
|
2232
2380
|
}));
|
|
2233
2381
|
}
|
|
2234
2382
|
|
|
2235
2383
|
async function resolveApprovalVersion(repoRoot, phase, options = {}) {
|
|
2384
|
+
const translator = createTranslator(options.language);
|
|
2236
2385
|
if (options.version) {
|
|
2237
2386
|
return options.version;
|
|
2238
2387
|
}
|
|
@@ -2243,24 +2392,24 @@ async function resolveApprovalVersion(repoRoot, phase, options = {}) {
|
|
|
2243
2392
|
|
|
2244
2393
|
if (!shouldPrompt || !canPrompt) {
|
|
2245
2394
|
const recommended = report.recommended?.version || report.latest_version || '<n>';
|
|
2246
|
-
throw new Error(
|
|
2247
|
-
failure:
|
|
2248
|
-
impact: '
|
|
2249
|
-
fix: '
|
|
2395
|
+
throw new Error(formatLocalizedActionableError({
|
|
2396
|
+
failure: translator.t('ai.approve.error.no_prompt.failure', { phase }),
|
|
2397
|
+
impact: translator.t('ai.approve.error.no_prompt.impact'),
|
|
2398
|
+
fix: translator.t('ai.approve.error.no_prompt.fix'),
|
|
2250
2399
|
nextCommand: `npx create-quiver ai approve --phase ${phase} --version ${recommended}`,
|
|
2251
|
-
}));
|
|
2400
|
+
}, options));
|
|
2252
2401
|
}
|
|
2253
2402
|
|
|
2254
2403
|
if (report.candidates.length === 0) {
|
|
2255
|
-
throw new Error(
|
|
2256
|
-
failure:
|
|
2257
|
-
impact: '
|
|
2258
|
-
fix:
|
|
2404
|
+
throw new Error(formatLocalizedActionableError({
|
|
2405
|
+
failure: translator.t('ai.approve.error.no_drafts.failure', { phase }),
|
|
2406
|
+
impact: translator.t('ai.approve.error.no_drafts.impact'),
|
|
2407
|
+
fix: translator.t('ai.approve.error.no_drafts.fix', { phase }),
|
|
2259
2408
|
nextCommand: `npx create-quiver ai plan --phase ${phase}${phase === 'acceptance' ? ' --input <requirements.md>' : ''} --dry-run`,
|
|
2260
|
-
}));
|
|
2409
|
+
}, options));
|
|
2261
2410
|
}
|
|
2262
2411
|
|
|
2263
|
-
const selected = await selectOption(
|
|
2412
|
+
const selected = await selectOption(translator.t('ai.approve.prompt.version', { phase }), approvalSelectionOptions(report, options), {
|
|
2264
2413
|
env: options.env,
|
|
2265
2414
|
error: options.error,
|
|
2266
2415
|
input: options.input,
|
|
@@ -2279,27 +2428,28 @@ async function resolveApprovalVersion(repoRoot, phase, options = {}) {
|
|
|
2279
2428
|
|
|
2280
2429
|
const candidate = selected.raw;
|
|
2281
2430
|
if (!candidate?.approvable) {
|
|
2282
|
-
throw new Error(
|
|
2283
|
-
failure:
|
|
2431
|
+
throw new Error(formatLocalizedActionableError({
|
|
2432
|
+
failure: translator.t('ai.approve.error.not_approvable.failure', { phase, label: selected.label }),
|
|
2284
2433
|
impact: candidate?.review?.blocking
|
|
2285
|
-
? '
|
|
2286
|
-
: '
|
|
2287
|
-
fix: candidate?.reason || '
|
|
2434
|
+
? translator.t('ai.approve.error.not_approvable.impact_blocked')
|
|
2435
|
+
: translator.t('ai.approve.error.not_approvable.impact'),
|
|
2436
|
+
fix: candidate?.reason || translator.t('ai.approve.error.not_approvable.fix'),
|
|
2288
2437
|
nextCommand: candidate?.next_command || `npx create-quiver ai approvals`,
|
|
2289
|
-
}));
|
|
2438
|
+
}, options));
|
|
2290
2439
|
}
|
|
2291
2440
|
|
|
2292
2441
|
return selected.value;
|
|
2293
2442
|
}
|
|
2294
2443
|
|
|
2295
2444
|
async function runApprove(repoRoot, options = {}) {
|
|
2445
|
+
const translator = createTranslator(options.language);
|
|
2296
2446
|
const phase = normalizePlannerPhase(options.phase || DEFAULT_PLAN_PHASE);
|
|
2297
2447
|
if (phase === 'spec') {
|
|
2298
|
-
throw new Error(formatError(
|
|
2448
|
+
throw new Error(formatError(translator.t('ai.approve.error.unsupported_phase', { phase })));
|
|
2299
2449
|
}
|
|
2300
2450
|
|
|
2301
2451
|
if (options.input) {
|
|
2302
|
-
throw new Error(formatError(
|
|
2452
|
+
throw new Error(formatError(translator.t('ai.approve.error.input_not_supported', { phase, input: options.input })));
|
|
2303
2453
|
}
|
|
2304
2454
|
|
|
2305
2455
|
const version = await resolveApprovalVersion(repoRoot, phase, options);
|
|
@@ -2307,12 +2457,16 @@ async function runApprove(repoRoot, options = {}) {
|
|
|
2307
2457
|
if (phase === 'technical-plan') {
|
|
2308
2458
|
const review = readPlanReview(repoRoot);
|
|
2309
2459
|
if (review.status !== 'unapproved' && review.status !== 'reviewed') {
|
|
2310
|
-
throw new Error(formatError(
|
|
2460
|
+
throw new Error(formatError(translator.t('ai.approve.error.review_required', { status: review.status })));
|
|
2311
2461
|
}
|
|
2312
2462
|
if (reviewBlocksApproval(review)) {
|
|
2313
2463
|
const result = review.meta.review_result;
|
|
2314
2464
|
const requiredFixes = Array.isArray(result.required_fixes) ? result.required_fixes.length : 0;
|
|
2315
|
-
throw new Error(formatError(
|
|
2465
|
+
throw new Error(formatError(translator.t('ai.approve.error.review_blocked', {
|
|
2466
|
+
recommendation: result.approval_recommendation,
|
|
2467
|
+
fixes: requiredFixes,
|
|
2468
|
+
command: result.next_command,
|
|
2469
|
+
})));
|
|
2316
2470
|
}
|
|
2317
2471
|
assertTechnicalPlanDraftHasSpecContract(repoRoot, version);
|
|
2318
2472
|
}
|
|
@@ -2320,7 +2474,7 @@ async function runApprove(repoRoot, options = {}) {
|
|
|
2320
2474
|
const inputText = '';
|
|
2321
2475
|
|
|
2322
2476
|
if (options.dryRun) {
|
|
2323
|
-
process.stdout.write(formatApprovalDryRunResult({ phase, input: options.input, version }));
|
|
2477
|
+
process.stdout.write(formatApprovalDryRunResult({ phase, input: options.input, version, language: options.language }));
|
|
2324
2478
|
return {
|
|
2325
2479
|
task: 'approve',
|
|
2326
2480
|
phase,
|
|
@@ -2351,7 +2505,7 @@ async function runApprove(repoRoot, options = {}) {
|
|
|
2351
2505
|
process.stdout.write(formatApprovalResult({
|
|
2352
2506
|
...result,
|
|
2353
2507
|
sourceFile: options.input || `draft version ${version}`,
|
|
2354
|
-
}, repoRoot));
|
|
2508
|
+
}, repoRoot, options));
|
|
2355
2509
|
|
|
2356
2510
|
return {
|
|
2357
2511
|
task: 'approve',
|
|
@@ -2363,8 +2517,8 @@ async function runApprove(repoRoot, options = {}) {
|
|
|
2363
2517
|
};
|
|
2364
2518
|
}
|
|
2365
2519
|
|
|
2366
|
-
async function runApprovalStatus(repoRoot) {
|
|
2367
|
-
const report =
|
|
2520
|
+
async function runApprovalStatus(repoRoot, options = {}) {
|
|
2521
|
+
const report = formatApprovalStatusReportWithOptions(repoRoot, options);
|
|
2368
2522
|
process.stdout.write(report);
|
|
2369
2523
|
return {
|
|
2370
2524
|
task: 'approval-status',
|
|
@@ -2374,7 +2528,7 @@ async function runApprovalStatus(repoRoot) {
|
|
|
2374
2528
|
|
|
2375
2529
|
function runLifecycleStatus(repoRoot, options = {}) {
|
|
2376
2530
|
const run = resolveAiRun(repoRoot, options.runId || '');
|
|
2377
|
-
const report = formatAiRunStatus(repoRoot, run);
|
|
2531
|
+
const report = formatAiRunStatus(repoRoot, run, options);
|
|
2378
2532
|
process.stdout.write(report);
|
|
2379
2533
|
return {
|
|
2380
2534
|
task: 'status',
|
|
@@ -2385,7 +2539,7 @@ function runLifecycleStatus(repoRoot, options = {}) {
|
|
|
2385
2539
|
|
|
2386
2540
|
function runLifecycleResume(repoRoot, options = {}) {
|
|
2387
2541
|
const run = resolveAiRun(repoRoot, options.runId || '');
|
|
2388
|
-
const report = formatAiRunResume(repoRoot, run);
|
|
2542
|
+
const report = formatAiRunResume(repoRoot, run, options);
|
|
2389
2543
|
process.stdout.write(report);
|
|
2390
2544
|
return {
|
|
2391
2545
|
task: 'resume',
|
|
@@ -2398,7 +2552,7 @@ function runInspect(repoRoot, options = {}) {
|
|
|
2398
2552
|
const report = collectLifecycleExport(repoRoot, {
|
|
2399
2553
|
includeCompleted: options.includeCompleted === true,
|
|
2400
2554
|
});
|
|
2401
|
-
process.stdout.write(formatLifecycleInspect(report));
|
|
2555
|
+
process.stdout.write(formatLifecycleInspect(report, options));
|
|
2402
2556
|
return {
|
|
2403
2557
|
task: 'inspect',
|
|
2404
2558
|
report,
|
|
@@ -2421,7 +2575,7 @@ function runExport(repoRoot, options = {}) {
|
|
|
2421
2575
|
}
|
|
2422
2576
|
|
|
2423
2577
|
if (format === 'markdown' || format === 'md') {
|
|
2424
|
-
process.stdout.write(formatLifecycleExportMarkdown(report));
|
|
2578
|
+
process.stdout.write(formatLifecycleExportMarkdown(report, options));
|
|
2425
2579
|
return {
|
|
2426
2580
|
task: 'export',
|
|
2427
2581
|
format: 'markdown',
|
|
@@ -2439,7 +2593,7 @@ function runSpecsList(repoRoot, options = {}) {
|
|
|
2439
2593
|
if (options.json === true) {
|
|
2440
2594
|
process.stdout.write(`${JSON.stringify({ specs: report.specs }, null, 2)}\n`);
|
|
2441
2595
|
} else {
|
|
2442
|
-
process.stdout.write(formatSpecsList(report));
|
|
2596
|
+
process.stdout.write(formatSpecsList(report, options));
|
|
2443
2597
|
}
|
|
2444
2598
|
return {
|
|
2445
2599
|
task: 'specs',
|
|
@@ -2454,7 +2608,7 @@ function runSlicesList(repoRoot, options = {}) {
|
|
|
2454
2608
|
if (options.json === true) {
|
|
2455
2609
|
process.stdout.write(`${JSON.stringify({ slices: report.slices }, null, 2)}\n`);
|
|
2456
2610
|
} else {
|
|
2457
|
-
process.stdout.write(formatSlicesList(report));
|
|
2611
|
+
process.stdout.write(formatSlicesList(report, options));
|
|
2458
2612
|
}
|
|
2459
2613
|
return {
|
|
2460
2614
|
task: 'slices',
|
|
@@ -2466,7 +2620,7 @@ function runTraceReport(repoRoot, options = {}) {
|
|
|
2466
2620
|
const report = collectLifecycleExport(repoRoot, {
|
|
2467
2621
|
includeCompleted: options.includeCompleted === true,
|
|
2468
2622
|
});
|
|
2469
|
-
process.stdout.write(formatTraceReport(report));
|
|
2623
|
+
process.stdout.write(formatTraceReport(report, options));
|
|
2470
2624
|
return {
|
|
2471
2625
|
task: 'trace',
|
|
2472
2626
|
report,
|
|
@@ -2496,22 +2650,23 @@ function runActiveSlice(repoRoot, options = {}) {
|
|
|
2496
2650
|
}
|
|
2497
2651
|
|
|
2498
2652
|
function runLifecycleRun(repoRoot, options = {}) {
|
|
2653
|
+
const translator = createTranslator(options.language);
|
|
2499
2654
|
const command = String(options.command || '').trim().toLowerCase();
|
|
2500
2655
|
if (command !== 'create' && command !== 'close') {
|
|
2501
|
-
throw new Error(formatError(
|
|
2656
|
+
throw new Error(formatError(translator.t('ai.run.error.unsupported_subcommand', { command })));
|
|
2502
2657
|
}
|
|
2503
2658
|
if (command === 'create' && !options.input) {
|
|
2504
|
-
throw new Error(formatError('ai
|
|
2659
|
+
throw new Error(formatError(translator.t('ai.run.error.create_requires_input')));
|
|
2505
2660
|
}
|
|
2506
2661
|
if (command === 'close') {
|
|
2507
2662
|
const current = resolveAiRun(repoRoot, options.runId || '');
|
|
2508
2663
|
if (!current) {
|
|
2509
|
-
throw new Error(formatError('ai
|
|
2664
|
+
throw new Error(formatError(translator.t('ai.run.error.close_requires_run')));
|
|
2510
2665
|
}
|
|
2511
2666
|
const run = updateAiRunPhase(repoRoot, current.run_id, 'closed', {
|
|
2512
2667
|
command: 'ai run close',
|
|
2513
2668
|
});
|
|
2514
|
-
const report =
|
|
2669
|
+
const report = `${translator.t('ai.run.closed.title')}\n${formatAiRunStatus(repoRoot, run, options)}`;
|
|
2515
2670
|
process.stdout.write(report);
|
|
2516
2671
|
return {
|
|
2517
2672
|
task: 'run',
|
|
@@ -2526,7 +2681,7 @@ function runLifecycleRun(repoRoot, options = {}) {
|
|
|
2526
2681
|
runId: options.runId,
|
|
2527
2682
|
specSlug: options.specSlug,
|
|
2528
2683
|
});
|
|
2529
|
-
const report = formatAiRunStatus(repoRoot, run);
|
|
2684
|
+
const report = formatAiRunStatus(repoRoot, run, options);
|
|
2530
2685
|
process.stdout.write(report);
|
|
2531
2686
|
return {
|
|
2532
2687
|
task: 'run',
|
|
@@ -2543,7 +2698,7 @@ function isInteractiveAgentPromptAvailable(options = {}) {
|
|
|
2543
2698
|
return stdinIsTTY && stdoutIsTTY && ci !== '1' && ci !== 'true';
|
|
2544
2699
|
}
|
|
2545
2700
|
|
|
2546
|
-
function
|
|
2701
|
+
function providerInstallStatus(repoRoot, providerId, options = {}) {
|
|
2547
2702
|
const probe = options.preflightProvider || preflightProvider;
|
|
2548
2703
|
try {
|
|
2549
2704
|
probe(providerId, {
|
|
@@ -2554,19 +2709,23 @@ function providerInstallHint(repoRoot, providerId, options = {}) {
|
|
|
2554
2709
|
return 'installed';
|
|
2555
2710
|
} catch (error) {
|
|
2556
2711
|
if (error && error.code === 'MISSING_PROVIDER_CLI') {
|
|
2557
|
-
return '
|
|
2712
|
+
return 'not_installed';
|
|
2558
2713
|
}
|
|
2559
|
-
return '
|
|
2714
|
+
return 'not_verified';
|
|
2560
2715
|
}
|
|
2561
2716
|
}
|
|
2562
2717
|
|
|
2563
2718
|
function buildAgentProviderChoices(repoRoot, options = {}) {
|
|
2719
|
+
const translator = createTranslator(options.language);
|
|
2564
2720
|
return listCatalogProviders().map((provider) => {
|
|
2565
|
-
const status =
|
|
2721
|
+
const status = providerInstallStatus(repoRoot, provider.id, options);
|
|
2566
2722
|
return {
|
|
2567
2723
|
label: provider.displayName,
|
|
2568
2724
|
value: provider.id,
|
|
2569
|
-
hint:
|
|
2725
|
+
hint: translator.t('ai.agent.choice.provider_hint', {
|
|
2726
|
+
count: provider.modelCount,
|
|
2727
|
+
status: translator.t(`ai.agent.install_status.${status}`),
|
|
2728
|
+
}),
|
|
2570
2729
|
raw: {
|
|
2571
2730
|
...provider,
|
|
2572
2731
|
installStatus: status,
|
|
@@ -2575,12 +2734,15 @@ function buildAgentProviderChoices(repoRoot, options = {}) {
|
|
|
2575
2734
|
});
|
|
2576
2735
|
}
|
|
2577
2736
|
|
|
2578
|
-
function buildAgentModelChoices(provider, role) {
|
|
2737
|
+
function buildAgentModelChoices(provider, role, options = {}) {
|
|
2738
|
+
const translator = createTranslator(options.language);
|
|
2579
2739
|
return getKnownModelsForProvider(provider, { role }).map((model) => {
|
|
2580
|
-
const recommended = model.recommendedFor.includes(role)
|
|
2740
|
+
const recommended = model.recommendedFor.includes(role)
|
|
2741
|
+
? translator.t('ai.agent.choice.model_recommended')
|
|
2742
|
+
: translator.t('ai.agent.choice.model_available');
|
|
2581
2743
|
const tier = [model.costTier, model.qualityTier, model.stability].filter(Boolean).join('/');
|
|
2582
2744
|
return {
|
|
2583
|
-
label: model.displayName,
|
|
2745
|
+
label: model.id === 'custom' ? translator.t('ai.agent.choice.model_custom') : model.displayName,
|
|
2584
2746
|
value: model.id,
|
|
2585
2747
|
hint: [recommended, tier].filter(Boolean).join(', '),
|
|
2586
2748
|
default: model.recommendedFor.includes(role),
|
|
@@ -2590,6 +2752,7 @@ function buildAgentModelChoices(provider, role) {
|
|
|
2590
2752
|
}
|
|
2591
2753
|
|
|
2592
2754
|
async function resolveInteractiveAgentSetOptions(repoRoot, options = {}) {
|
|
2755
|
+
const translator = createTranslator(options.language);
|
|
2593
2756
|
const role = normalizeAgentProfileRole(options.role);
|
|
2594
2757
|
const hasProvider = Boolean(String(options.provider || '').trim());
|
|
2595
2758
|
const hasModel = Boolean(String(options.model || '').trim());
|
|
@@ -2603,12 +2766,12 @@ async function resolveInteractiveAgentSetOptions(repoRoot, options = {}) {
|
|
|
2603
2766
|
const canPrompt = isInteractiveAgentPromptAvailable(options);
|
|
2604
2767
|
const shouldPrompt = options.interactive === true || canPrompt;
|
|
2605
2768
|
if (!shouldPrompt || !canPrompt) {
|
|
2606
|
-
throw new Error(
|
|
2607
|
-
failure:
|
|
2608
|
-
impact: '
|
|
2609
|
-
fix: '
|
|
2769
|
+
throw new Error(formatLocalizedActionableError({
|
|
2770
|
+
failure: translator.t('ai.agent.error.no_prompt.failure', { role }),
|
|
2771
|
+
impact: translator.t('ai.agent.error.no_prompt.impact'),
|
|
2772
|
+
fix: translator.t('ai.agent.error.no_prompt.fix'),
|
|
2610
2773
|
nextCommand: `npx create-quiver ai agent set ${role} --provider codex --model gpt-5.5`,
|
|
2611
|
-
}));
|
|
2774
|
+
}, options));
|
|
2612
2775
|
}
|
|
2613
2776
|
|
|
2614
2777
|
const promptOptions = {
|
|
@@ -2633,16 +2796,16 @@ async function resolveInteractiveAgentSetOptions(repoRoot, options = {}) {
|
|
|
2633
2796
|
const ux = createCommandUx(promptOptions);
|
|
2634
2797
|
ux.summary(existingProfiles.map((profile) => ({
|
|
2635
2798
|
label: profile.id,
|
|
2636
|
-
value: `${profile.provider} ${profile.model || '
|
|
2799
|
+
value: `${profile.provider} ${profile.model || translator.t('ai.agent.value.no_model')}${profile.default ? ` ${translator.t('ai.agent.value.default')}` : ''}`,
|
|
2637
2800
|
})), {
|
|
2638
|
-
title:
|
|
2801
|
+
title: translator.t('ai.agent.prompt.existing_title', { role }),
|
|
2639
2802
|
});
|
|
2640
2803
|
|
|
2641
|
-
const action = await selectOption(
|
|
2642
|
-
{ label: '
|
|
2643
|
-
{ label: '
|
|
2644
|
-
{ label: '
|
|
2645
|
-
{ label: '
|
|
2804
|
+
const action = await selectOption(translator.t('ai.agent.prompt.existing_action', { role }), [
|
|
2805
|
+
{ label: translator.t('ai.agent.prompt.action.update_current.label'), value: 'update-current', hint: translator.t('ai.agent.prompt.action.update_current.hint'), default: true },
|
|
2806
|
+
{ label: translator.t('ai.agent.prompt.action.create_new.label'), value: 'create-new', hint: translator.t('ai.agent.prompt.action.create_new.hint') },
|
|
2807
|
+
{ label: translator.t('ai.agent.prompt.action.change_default.label'), value: 'change-default', hint: translator.t('ai.agent.prompt.action.change_default.hint') },
|
|
2808
|
+
{ label: translator.t('ai.agent.prompt.action.cancel.label'), value: 'cancel', hint: translator.t('ai.agent.prompt.action.cancel.hint') },
|
|
2646
2809
|
], {
|
|
2647
2810
|
...promptOptions,
|
|
2648
2811
|
name: 'agent profile action',
|
|
@@ -2650,14 +2813,14 @@ async function resolveInteractiveAgentSetOptions(repoRoot, options = {}) {
|
|
|
2650
2813
|
});
|
|
2651
2814
|
|
|
2652
2815
|
if (action.value === 'cancel') {
|
|
2653
|
-
throw new Error(formatError('ai
|
|
2816
|
+
throw new Error(formatError(translator.t('ai.agent.error.canceled')));
|
|
2654
2817
|
}
|
|
2655
2818
|
|
|
2656
2819
|
if (action.value === 'change-default') {
|
|
2657
|
-
const profile = await selectOption(
|
|
2820
|
+
const profile = await selectOption(translator.t('ai.agent.prompt.default_profile', { role }), existingProfiles.map((item) => ({
|
|
2658
2821
|
label: resolveAgentProfileDisplayName(item),
|
|
2659
2822
|
value: item.id,
|
|
2660
|
-
hint: `${item.provider} ${item.model || '
|
|
2823
|
+
hint: `${item.provider} ${item.model || translator.t('ai.agent.value.no_model')}`,
|
|
2661
2824
|
default: item.default === true,
|
|
2662
2825
|
raw: item,
|
|
2663
2826
|
})), {
|
|
@@ -2688,7 +2851,7 @@ async function resolveInteractiveAgentSetOptions(repoRoot, options = {}) {
|
|
|
2688
2851
|
}
|
|
2689
2852
|
|
|
2690
2853
|
if (action.value === 'create-new') {
|
|
2691
|
-
const id = await promptText(
|
|
2854
|
+
const id = await promptText(translator.t('ai.agent.prompt.new_id', { role }), {
|
|
2692
2855
|
...promptOptions,
|
|
2693
2856
|
name: 'agent profile id',
|
|
2694
2857
|
flag: '--id',
|
|
@@ -2700,7 +2863,7 @@ async function resolveInteractiveAgentSetOptions(repoRoot, options = {}) {
|
|
|
2700
2863
|
}
|
|
2701
2864
|
|
|
2702
2865
|
if (!next.provider) {
|
|
2703
|
-
const selectedProvider = await selectOption(
|
|
2866
|
+
const selectedProvider = await selectOption(translator.t('ai.agent.prompt.provider', { role }), buildAgentProviderChoices(repoRoot, options), {
|
|
2704
2867
|
...promptOptions,
|
|
2705
2868
|
name: 'agent provider',
|
|
2706
2869
|
flag: '--provider',
|
|
@@ -2709,19 +2872,19 @@ async function resolveInteractiveAgentSetOptions(repoRoot, options = {}) {
|
|
|
2709
2872
|
}
|
|
2710
2873
|
|
|
2711
2874
|
if (!next.model) {
|
|
2712
|
-
const selectedModel = await selectOption(
|
|
2875
|
+
const selectedModel = await selectOption(translator.t('ai.agent.prompt.model', { role }), buildAgentModelChoices(next.provider, role, options), {
|
|
2713
2876
|
...promptOptions,
|
|
2714
2877
|
name: 'agent model',
|
|
2715
2878
|
flag: '--model',
|
|
2716
2879
|
});
|
|
2717
2880
|
if (selectedModel.value === 'custom') {
|
|
2718
|
-
const model = await promptText(
|
|
2881
|
+
const model = await promptText(translator.t('ai.agent.prompt.custom_model', { provider: next.provider }), {
|
|
2719
2882
|
...promptOptions,
|
|
2720
2883
|
name: 'agent model',
|
|
2721
2884
|
flag: '--model',
|
|
2722
2885
|
placeholder: `${next.provider}-model-id`,
|
|
2723
2886
|
});
|
|
2724
|
-
const displayName = await promptText('
|
|
2887
|
+
const displayName = await promptText(translator.t('ai.agent.prompt.custom_model_display'), {
|
|
2725
2888
|
...promptOptions,
|
|
2726
2889
|
name: 'agent model display name',
|
|
2727
2890
|
flag: '--display-name',
|
|
@@ -2742,48 +2905,53 @@ async function resolveInteractiveAgentSetOptions(repoRoot, options = {}) {
|
|
|
2742
2905
|
};
|
|
2743
2906
|
}
|
|
2744
2907
|
|
|
2745
|
-
function formatAgentProfile(profile) {
|
|
2908
|
+
function formatAgentProfile(profile, options = {}) {
|
|
2909
|
+
const translator = createTranslator(options.language);
|
|
2746
2910
|
const lines = [
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2911
|
+
`${translator.t('ai.agent.field.id')}: ${profile.id || translator.t('ai.agent.value.default')}`,
|
|
2912
|
+
`${translator.t('ai.agent.field.role')}: ${profile.role}`,
|
|
2913
|
+
`${translator.t('ai.agent.field.provider')}: ${profile.provider}`,
|
|
2914
|
+
`${translator.t('ai.agent.field.model')}: ${profile.model || translator.t('ai.agent.value.not_set')}`,
|
|
2915
|
+
`${translator.t('ai.agent.field.label')}: ${profile.label || translator.t('ai.agent.value.not_set')}`,
|
|
2916
|
+
`${translator.t('ai.agent.field.display_name')}: ${resolveAgentProfileDisplayName(profile) || translator.t('ai.agent.value.not_set')}`,
|
|
2917
|
+
`${translator.t('ai.agent.field.default')}: ${profile.default === true ? translator.t('ai.agent.value.yes') : translator.t('ai.agent.value.no')}`,
|
|
2918
|
+
`${translator.t('ai.agent.field.context')}: ${profile.context || translator.t('ai.agent.value.not_set')}`,
|
|
2919
|
+
`${translator.t('ai.agent.field.updated')}: ${profile.updated_at}`,
|
|
2756
2920
|
];
|
|
2757
2921
|
return `${lines.join('\n')}\n`;
|
|
2758
2922
|
}
|
|
2759
2923
|
|
|
2760
|
-
function formatAgentProfileList(profiles) {
|
|
2761
|
-
const
|
|
2924
|
+
function formatAgentProfileList(profiles, options = {}) {
|
|
2925
|
+
const translator = createTranslator(options.language);
|
|
2926
|
+
const lines = [translator.t('ai.agent.list.title')];
|
|
2762
2927
|
for (const item of profiles) {
|
|
2763
2928
|
if (!item.configured) {
|
|
2764
|
-
lines.push(`- ${item.role}:
|
|
2929
|
+
lines.push(`- ${item.role}: ${translator.t('ai.agent.list.not_configured')}`);
|
|
2765
2930
|
continue;
|
|
2766
2931
|
}
|
|
2767
2932
|
const model = item.profile.model ? ` model=${item.profile.model}` : '';
|
|
2768
2933
|
const label = item.profile.label ? ` label=${item.profile.label}` : '';
|
|
2769
2934
|
const displayName = resolveAgentProfileDisplayName(item.profile);
|
|
2770
|
-
const alternatives = item.profiles.length > 1 ? ` options=${item.profiles.length}` : '';
|
|
2771
|
-
lines.push(`- ${item.role}: provider=${item.profile.provider}${model}${label}
|
|
2935
|
+
const alternatives = item.profiles.length > 1 ? ` ${translator.t('ai.agent.list.options')}=${item.profiles.length}` : '';
|
|
2936
|
+
lines.push(`- ${item.role}: provider=${item.profile.provider}${model}${label} ${translator.t('ai.agent.list.display_name')}=${displayName}${alternatives}`);
|
|
2772
2937
|
}
|
|
2773
2938
|
return `${lines.join('\n')}\n`;
|
|
2774
2939
|
}
|
|
2775
2940
|
|
|
2776
|
-
function formatAgentProfileDryRun(repoRoot, result) {
|
|
2941
|
+
function formatAgentProfileDryRun(repoRoot, result, options = {}) {
|
|
2942
|
+
const translator = createTranslator(options.language);
|
|
2777
2943
|
const relativePath = path.relative(repoRoot, result.filePath).split(path.sep).join('/');
|
|
2778
|
-
const verb = result.action === 'update'
|
|
2944
|
+
const verb = result.action === 'update'
|
|
2945
|
+
? translator.t('ai.agent.dry_run.verb_update')
|
|
2946
|
+
: translator.t('ai.agent.dry_run.verb_create');
|
|
2779
2947
|
return [
|
|
2780
|
-
'
|
|
2781
|
-
'
|
|
2782
|
-
`-
|
|
2948
|
+
translator.t('ai.agent.dry_run.title'),
|
|
2949
|
+
`- ${translator.t('ai.agent.dry_run.writes')}: ${translator.t('ai.agent.value.none')}`,
|
|
2950
|
+
`- ${translator.t('ai.agent.dry_run.would', { verb, path: relativePath })}`,
|
|
2783
2951
|
'',
|
|
2784
|
-
formatAgentProfile(result.profile).trimEnd(),
|
|
2952
|
+
formatAgentProfile(result.profile, options).trimEnd(),
|
|
2785
2953
|
'',
|
|
2786
|
-
'
|
|
2954
|
+
translator.t('ai.agent.dry_run.no_secrets'),
|
|
2787
2955
|
'',
|
|
2788
2956
|
].join('\n');
|
|
2789
2957
|
}
|
|
@@ -2794,58 +2962,60 @@ function agentDoctorSymbol(status) {
|
|
|
2794
2962
|
return 'OK';
|
|
2795
2963
|
}
|
|
2796
2964
|
|
|
2797
|
-
function formatAgentDoctorReport(report) {
|
|
2965
|
+
function formatAgentDoctorReport(report, options = {}) {
|
|
2966
|
+
const translator = createTranslator(options.language);
|
|
2798
2967
|
const lines = [
|
|
2799
|
-
'
|
|
2968
|
+
translator.t('ai.agent.doctor.title'),
|
|
2800
2969
|
'',
|
|
2801
|
-
'
|
|
2970
|
+
translator.t('ai.agent.doctor.checks'),
|
|
2802
2971
|
];
|
|
2803
2972
|
|
|
2804
2973
|
if (report.checks.length === 0) {
|
|
2805
|
-
lines.push(
|
|
2974
|
+
lines.push(` ! ${translator.t('ai.agent.doctor.no_profiles')}`);
|
|
2806
2975
|
}
|
|
2807
2976
|
|
|
2808
2977
|
for (const check of report.checks) {
|
|
2809
2978
|
const target = `${check.role}/${check.id}`;
|
|
2810
|
-
const model = check.model || '
|
|
2811
|
-
const provider = check.provider || '
|
|
2812
|
-
const defaultText = check.default ? '
|
|
2979
|
+
const model = check.model || translator.t('ai.agent.value.no_model');
|
|
2980
|
+
const provider = check.provider || translator.t('ai.agent.value.no_provider');
|
|
2981
|
+
const defaultText = check.default ? ` ${translator.t('ai.agent.value.default')}` : '';
|
|
2813
2982
|
lines.push(` ${agentDoctorSymbol(check.status)} ${target}: provider=${provider} model=${model}${defaultText}`);
|
|
2814
2983
|
for (const finding of check.findings.filter((item) => item.severity !== 'info')) {
|
|
2815
2984
|
lines.push(` - ${finding.severity}: ${finding.message}`);
|
|
2816
2985
|
}
|
|
2817
2986
|
}
|
|
2818
2987
|
|
|
2819
|
-
lines.push('', '
|
|
2988
|
+
lines.push('', translator.t('ai.agent.doctor.suggested_fixes'));
|
|
2820
2989
|
if (report.suggestedFixes.length === 0) {
|
|
2821
|
-
lines.push(
|
|
2990
|
+
lines.push(` OK ${translator.t('ai.agent.doctor.no_fixes')}`);
|
|
2822
2991
|
} else {
|
|
2823
2992
|
for (const fix of report.suggestedFixes) {
|
|
2824
2993
|
lines.push(` - ${fix}`);
|
|
2825
2994
|
}
|
|
2826
2995
|
}
|
|
2827
2996
|
lines.push('');
|
|
2828
|
-
lines.push(
|
|
2997
|
+
lines.push(`${translator.t('ai.agent.doctor.summary')}: profiles=${report.summary.profiles} errors=${report.summary.errors} warnings=${report.summary.warnings} info=${report.summary.info}`);
|
|
2829
2998
|
lines.push('');
|
|
2830
2999
|
return `${lines.join('\n')}\n`;
|
|
2831
3000
|
}
|
|
2832
3001
|
|
|
2833
|
-
function formatAgentRepairPlan(plan) {
|
|
3002
|
+
function formatAgentRepairPlan(plan, options = {}) {
|
|
3003
|
+
const translator = createTranslator(options.language);
|
|
2834
3004
|
const lines = [
|
|
2835
|
-
'
|
|
2836
|
-
'
|
|
3005
|
+
translator.t('ai.agent.repair.title'),
|
|
3006
|
+
`- ${translator.t('ai.agent.dry_run.writes')}: ${translator.t('ai.agent.value.none')}`,
|
|
2837
3007
|
'',
|
|
2838
|
-
'
|
|
3008
|
+
translator.t('ai.agent.repair.proposed_changes'),
|
|
2839
3009
|
];
|
|
2840
3010
|
|
|
2841
3011
|
if (plan.changes.length === 0) {
|
|
2842
|
-
lines.push(
|
|
3012
|
+
lines.push(` OK ${translator.t('ai.agent.repair.no_repairs')}`);
|
|
2843
3013
|
}
|
|
2844
3014
|
|
|
2845
3015
|
for (const change of plan.changes) {
|
|
2846
3016
|
lines.push(` - ${change.role}/${change.profileId}: ${change.reason}`);
|
|
2847
|
-
lines.push(`
|
|
2848
|
-
lines.push(`
|
|
3017
|
+
lines.push(` ${translator.t('ai.agent.repair.before')}: model=${change.before.model || translator.t('ai.agent.value.not_set')} displayName=${change.before.displayName || translator.t('ai.agent.value.not_set')}`);
|
|
3018
|
+
lines.push(` ${translator.t('ai.agent.repair.after')}: model=${change.after.model || translator.t('ai.agent.value.not_set')} displayName=${change.after.displayName || translator.t('ai.agent.value.not_set')}`);
|
|
2849
3019
|
}
|
|
2850
3020
|
|
|
2851
3021
|
lines.push('');
|
|
@@ -2853,13 +3023,17 @@ function formatAgentRepairPlan(plan) {
|
|
|
2853
3023
|
}
|
|
2854
3024
|
|
|
2855
3025
|
function buildModelsListReport(options = {}) {
|
|
3026
|
+
const translator = createTranslator(options.language);
|
|
2856
3027
|
const providerFilter = String(options.provider || '').trim().toLowerCase();
|
|
2857
3028
|
const providers = providerFilter
|
|
2858
3029
|
? [listCatalogProviders().find((provider) => provider.id === providerFilter)].filter(Boolean)
|
|
2859
3030
|
: listCatalogProviders();
|
|
2860
3031
|
|
|
2861
3032
|
if (providerFilter && providers.length === 0) {
|
|
2862
|
-
throw new Error(formatError(
|
|
3033
|
+
throw new Error(formatError(translator.t('ai.models.error.unsupported_provider_filter', {
|
|
3034
|
+
provider: options.provider,
|
|
3035
|
+
providers: listCatalogProviders().map((provider) => provider.id).join(', '),
|
|
3036
|
+
})));
|
|
2863
3037
|
}
|
|
2864
3038
|
|
|
2865
3039
|
return {
|
|
@@ -2882,21 +3056,22 @@ function buildModelsListReport(options = {}) {
|
|
|
2882
3056
|
};
|
|
2883
3057
|
}
|
|
2884
3058
|
|
|
2885
|
-
function formatModelsListReport(report) {
|
|
3059
|
+
function formatModelsListReport(report, options = {}) {
|
|
3060
|
+
const translator = createTranslator(options.language);
|
|
2886
3061
|
const lines = [
|
|
2887
|
-
'
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
'
|
|
3062
|
+
translator.t('ai.models.title'),
|
|
3063
|
+
`${translator.t('ai.models.catalog_version')}: ${report.catalogVersion}`,
|
|
3064
|
+
`${translator.t('ai.models.last_updated')}: ${report.lastUpdated}`,
|
|
3065
|
+
`${translator.t('ai.models.note')}`,
|
|
2891
3066
|
'',
|
|
2892
3067
|
];
|
|
2893
3068
|
|
|
2894
3069
|
for (const provider of report.providers) {
|
|
2895
3070
|
lines.push(`${provider.displayName} (${provider.id})`);
|
|
2896
3071
|
for (const model of provider.models) {
|
|
2897
|
-
const roles = model.recommendedFor.length > 0 ? model.recommendedFor.join(', ') : '
|
|
3072
|
+
const roles = model.recommendedFor.length > 0 ? model.recommendedFor.join(', ') : translator.t('ai.models.roles.custom_manual');
|
|
2898
3073
|
lines.push(` - ${model.id} (${model.displayName})`);
|
|
2899
|
-
lines.push(` roles: ${roles}`);
|
|
3074
|
+
lines.push(` ${translator.t('ai.models.roles')}: ${roles}`);
|
|
2900
3075
|
lines.push(` cost=${model.costTier} quality=${model.qualityTier} stability=${model.stability}`);
|
|
2901
3076
|
}
|
|
2902
3077
|
lines.push('');
|
|
@@ -2907,12 +3082,13 @@ function formatModelsListReport(report) {
|
|
|
2907
3082
|
|
|
2908
3083
|
function runModelsList(options = {}) {
|
|
2909
3084
|
const report = buildModelsListReport({
|
|
3085
|
+
language: options.language,
|
|
2910
3086
|
provider: options.provider,
|
|
2911
3087
|
});
|
|
2912
3088
|
if (options.json) {
|
|
2913
3089
|
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
2914
3090
|
} else {
|
|
2915
|
-
process.stdout.write(formatModelsListReport(report));
|
|
3091
|
+
process.stdout.write(formatModelsListReport(report, options));
|
|
2916
3092
|
}
|
|
2917
3093
|
return {
|
|
2918
3094
|
task: 'models',
|
|
@@ -2922,11 +3098,12 @@ function runModelsList(options = {}) {
|
|
|
2922
3098
|
}
|
|
2923
3099
|
|
|
2924
3100
|
async function runAgent(repoRoot, options = {}) {
|
|
3101
|
+
const translator = createTranslator(options.language);
|
|
2925
3102
|
const command = String(options.command || '').trim().toLowerCase();
|
|
2926
3103
|
|
|
2927
3104
|
if (command === 'set') {
|
|
2928
3105
|
if (!options.role) {
|
|
2929
|
-
throw new Error(formatError('
|
|
3106
|
+
throw new Error(formatError(translator.t('ai.agent.error.missing_set_role')));
|
|
2930
3107
|
}
|
|
2931
3108
|
const profileOptions = await resolveInteractiveAgentSetOptions(repoRoot, options);
|
|
2932
3109
|
if (options.dryRun) {
|
|
@@ -2939,7 +3116,7 @@ async function runAgent(repoRoot, options = {}) {
|
|
|
2939
3116
|
model: profileOptions.model,
|
|
2940
3117
|
provider: profileOptions.provider,
|
|
2941
3118
|
});
|
|
2942
|
-
process.stdout.write(formatAgentProfileDryRun(repoRoot, preview));
|
|
3119
|
+
process.stdout.write(formatAgentProfileDryRun(repoRoot, preview, options));
|
|
2943
3120
|
return {
|
|
2944
3121
|
task: 'agent',
|
|
2945
3122
|
command,
|
|
@@ -2960,13 +3137,13 @@ async function runAgent(repoRoot, options = {}) {
|
|
|
2960
3137
|
});
|
|
2961
3138
|
const ux = createCommandUx(profileOptions);
|
|
2962
3139
|
ux.summary([
|
|
2963
|
-
{ label: '
|
|
2964
|
-
{ label: '
|
|
2965
|
-
{ label: '
|
|
2966
|
-
{ label: '
|
|
2967
|
-
{ label: '
|
|
3140
|
+
{ label: translator.t('ai.agent.field.role'), value: preview.profile.role },
|
|
3141
|
+
{ label: translator.t('ai.agent.field.provider'), value: preview.profile.provider },
|
|
3142
|
+
{ label: translator.t('ai.agent.field.model'), value: preview.profile.model || translator.t('ai.agent.value.not_set') },
|
|
3143
|
+
{ label: translator.t('ai.agent.field.display_name'), value: resolveAgentProfileDisplayName(preview.profile) || translator.t('ai.agent.value.not_set') },
|
|
3144
|
+
{ label: translator.t('ai.agent.field.default'), value: preview.profile.default === true ? translator.t('ai.agent.value.yes') : translator.t('ai.agent.value.no') },
|
|
2968
3145
|
], {
|
|
2969
|
-
title: '
|
|
3146
|
+
title: translator.t('ai.agent.profile_to_save.title'),
|
|
2970
3147
|
});
|
|
2971
3148
|
}
|
|
2972
3149
|
const result = setAgentProfile(repoRoot, profileOptions.role, {
|
|
@@ -2978,9 +3155,9 @@ async function runAgent(repoRoot, options = {}) {
|
|
|
2978
3155
|
model: profileOptions.model,
|
|
2979
3156
|
provider: profileOptions.provider,
|
|
2980
3157
|
});
|
|
2981
|
-
process.stdout.write('
|
|
2982
|
-
process.stdout.write(formatAgentProfile(result.profile));
|
|
2983
|
-
process.stdout.write(
|
|
3158
|
+
process.stdout.write(`${translator.t('ai.agent.saved.title')}\n`);
|
|
3159
|
+
process.stdout.write(formatAgentProfile(result.profile, options));
|
|
3160
|
+
process.stdout.write(`${translator.t('ai.agent.field.state')}: ${path.relative(repoRoot, result.filePath).split(path.sep).join('/')}\n`);
|
|
2984
3161
|
return {
|
|
2985
3162
|
task: 'agent',
|
|
2986
3163
|
command,
|
|
@@ -2991,22 +3168,22 @@ async function runAgent(repoRoot, options = {}) {
|
|
|
2991
3168
|
|
|
2992
3169
|
if (command === 'show') {
|
|
2993
3170
|
if (!options.role) {
|
|
2994
|
-
throw new Error(formatError('
|
|
3171
|
+
throw new Error(formatError(translator.t('ai.agent.error.missing_show_role')));
|
|
2995
3172
|
}
|
|
2996
3173
|
const profile = options.id
|
|
2997
3174
|
? getAgentProfileById(repoRoot, options.role, options.id)
|
|
2998
3175
|
: getAgentProfile(repoRoot, options.role);
|
|
2999
3176
|
if (!profile) {
|
|
3000
|
-
throw new Error(
|
|
3177
|
+
throw new Error(formatLocalizedActionableError({
|
|
3001
3178
|
failure: options.id
|
|
3002
|
-
?
|
|
3003
|
-
:
|
|
3004
|
-
impact: '
|
|
3005
|
-
fix:
|
|
3179
|
+
? translator.t('ai.agent.error.missing_profile_id.failure', { role: options.role, id: options.id })
|
|
3180
|
+
: translator.t('ai.agent.error.missing_profile.failure', { role: options.role }),
|
|
3181
|
+
impact: translator.t('ai.agent.error.missing_profile.impact'),
|
|
3182
|
+
fix: translator.t('ai.agent.error.missing_profile.fix', { role: options.role }),
|
|
3006
3183
|
nextCommand: `npx create-quiver ai agent set ${options.role} --provider <provider> --model <model-id>`,
|
|
3007
|
-
}));
|
|
3184
|
+
}, options));
|
|
3008
3185
|
}
|
|
3009
|
-
process.stdout.write(formatAgentProfile(profile));
|
|
3186
|
+
process.stdout.write(formatAgentProfile(profile, options));
|
|
3010
3187
|
return {
|
|
3011
3188
|
task: 'agent',
|
|
3012
3189
|
command,
|
|
@@ -3016,8 +3193,8 @@ async function runAgent(repoRoot, options = {}) {
|
|
|
3016
3193
|
|
|
3017
3194
|
if (command === 'list' || command === 'ls' || command === '') {
|
|
3018
3195
|
const profiles = listAgentProfiles(repoRoot);
|
|
3019
|
-
process.stdout.write(formatAgentProfileList(profiles));
|
|
3020
|
-
process.stdout.write(
|
|
3196
|
+
process.stdout.write(formatAgentProfileList(profiles, options));
|
|
3197
|
+
process.stdout.write(`${translator.t('ai.agent.field.state')}: ${path.relative(repoRoot, agentProfilesPath(repoRoot)).split(path.sep).join('/')}\n`);
|
|
3021
3198
|
return {
|
|
3022
3199
|
task: 'agent',
|
|
3023
3200
|
command: 'list',
|
|
@@ -3030,7 +3207,7 @@ async function runAgent(repoRoot, options = {}) {
|
|
|
3030
3207
|
if (options.json) {
|
|
3031
3208
|
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
3032
3209
|
} else {
|
|
3033
|
-
process.stdout.write(formatAgentDoctorReport(report));
|
|
3210
|
+
process.stdout.write(formatAgentDoctorReport(report, options));
|
|
3034
3211
|
}
|
|
3035
3212
|
if (report.summary.errors > 0) {
|
|
3036
3213
|
process.exitCode = 1;
|
|
@@ -3044,7 +3221,7 @@ async function runAgent(repoRoot, options = {}) {
|
|
|
3044
3221
|
|
|
3045
3222
|
if (command === 'repair') {
|
|
3046
3223
|
if (options.dryRun !== true) {
|
|
3047
|
-
throw new Error(formatError('ai
|
|
3224
|
+
throw new Error(formatError(translator.t('ai.agent.error.repair_requires_dry_run')));
|
|
3048
3225
|
}
|
|
3049
3226
|
const plan = buildAgentProfileRepairPlan(repoRoot, {
|
|
3050
3227
|
includeState: options.json === true,
|
|
@@ -3052,7 +3229,7 @@ async function runAgent(repoRoot, options = {}) {
|
|
|
3052
3229
|
if (options.json) {
|
|
3053
3230
|
process.stdout.write(`${JSON.stringify(plan, null, 2)}\n`);
|
|
3054
3231
|
} else {
|
|
3055
|
-
process.stdout.write(formatAgentRepairPlan(plan));
|
|
3232
|
+
process.stdout.write(formatAgentRepairPlan(plan, options));
|
|
3056
3233
|
}
|
|
3057
3234
|
return {
|
|
3058
3235
|
task: 'agent',
|
|
@@ -3062,7 +3239,7 @@ async function runAgent(repoRoot, options = {}) {
|
|
|
3062
3239
|
};
|
|
3063
3240
|
}
|
|
3064
3241
|
|
|
3065
|
-
throw new Error(formatError(
|
|
3242
|
+
throw new Error(formatError(translator.t('ai.agent.error.unsupported_subcommand', { command })));
|
|
3066
3243
|
}
|
|
3067
3244
|
|
|
3068
3245
|
async function runGitHubTask(repoRoot, options = {}, mode = 'pr') {
|
|
@@ -3086,7 +3263,7 @@ async function runGitHubTask(repoRoot, options = {}, mode = 'pr') {
|
|
|
3086
3263
|
throw annotateGitHubError(error, mode);
|
|
3087
3264
|
}
|
|
3088
3265
|
|
|
3089
|
-
process.stdout.write(formatPreflightReport(report, { mode, dryRun }));
|
|
3266
|
+
process.stdout.write(formatPreflightReport(report, { mode, dryRun, language: options.language }));
|
|
3090
3267
|
|
|
3091
3268
|
return {
|
|
3092
3269
|
task: mode,
|
|
@@ -3098,10 +3275,11 @@ async function runGitHubTask(repoRoot, options = {}, mode = 'pr') {
|
|
|
3098
3275
|
async function runPr(repoRoot, options = {}) {
|
|
3099
3276
|
const dryRun = options.dryRun === true;
|
|
3100
3277
|
const create = options.create === true;
|
|
3278
|
+
const translator = createTranslator(options.language);
|
|
3101
3279
|
const ux = createCommandUx(options);
|
|
3102
3280
|
const showProgress = create && !dryRun && shouldShowHumanProgress(ux, options);
|
|
3103
3281
|
if (showProgress) {
|
|
3104
|
-
ux.heading('
|
|
3282
|
+
ux.heading(translator.t('ai.github.progress.heading'));
|
|
3105
3283
|
}
|
|
3106
3284
|
let preflight;
|
|
3107
3285
|
|
|
@@ -3109,9 +3287,9 @@ async function runPr(repoRoot, options = {}) {
|
|
|
3109
3287
|
preflight = await runProviderWithProgress({
|
|
3110
3288
|
ux,
|
|
3111
3289
|
enabled: showProgress,
|
|
3112
|
-
message: '
|
|
3113
|
-
successMessage: '
|
|
3114
|
-
failureMessage: '
|
|
3290
|
+
message: translator.t('ai.github.progress.preflight.running'),
|
|
3291
|
+
successMessage: translator.t('ai.github.progress.preflight.done'),
|
|
3292
|
+
failureMessage: translator.t('ai.github.progress.preflight.failed'),
|
|
3115
3293
|
run: () => (options.preflightFn || preflightGitHubPr)(repoRoot, {
|
|
3116
3294
|
remote: options.remote,
|
|
3117
3295
|
sshHostAlias: options.sshHostAlias,
|
|
@@ -3139,7 +3317,7 @@ async function runPr(repoRoot, options = {}) {
|
|
|
3139
3317
|
title: options.title,
|
|
3140
3318
|
});
|
|
3141
3319
|
if (showProgress) {
|
|
3142
|
-
ux.check('
|
|
3320
|
+
ux.check(translator.t('ai.github.progress.body_ready'));
|
|
3143
3321
|
}
|
|
3144
3322
|
} catch (error) {
|
|
3145
3323
|
throw annotateGitHubError(error, 'pr');
|
|
@@ -3171,7 +3349,7 @@ async function runPr(repoRoot, options = {}) {
|
|
|
3171
3349
|
}
|
|
3172
3350
|
|
|
3173
3351
|
if (dryRun || !create) {
|
|
3174
|
-
process.stdout.write(formatPrCreateReport({ preflight, plan }, { dryRun, create }));
|
|
3352
|
+
process.stdout.write(formatPrCreateReport({ preflight, plan }, { dryRun, create, language: options.language }));
|
|
3175
3353
|
return {
|
|
3176
3354
|
task: 'pr',
|
|
3177
3355
|
dryRun,
|
|
@@ -3188,9 +3366,9 @@ async function runPr(repoRoot, options = {}) {
|
|
|
3188
3366
|
result = await runProviderWithProgress({
|
|
3189
3367
|
ux,
|
|
3190
3368
|
enabled: showProgress,
|
|
3191
|
-
message: '
|
|
3192
|
-
successMessage: '
|
|
3193
|
-
failureMessage: '
|
|
3369
|
+
message: translator.t('ai.github.progress.create.running'),
|
|
3370
|
+
successMessage: translator.t('ai.github.progress.create.done'),
|
|
3371
|
+
failureMessage: translator.t('ai.github.progress.create.failed'),
|
|
3194
3372
|
run: () => runGhPrCreate(plan, {
|
|
3195
3373
|
ghCreateRunner: options.ghCreateRunner,
|
|
3196
3374
|
}),
|
|
@@ -3199,7 +3377,7 @@ async function runPr(repoRoot, options = {}) {
|
|
|
3199
3377
|
throw annotateGitHubError(error, 'pr');
|
|
3200
3378
|
}
|
|
3201
3379
|
|
|
3202
|
-
process.stdout.write(formatPrCreateReport({ preflight, plan, result }, { dryRun: false, create: true }));
|
|
3380
|
+
process.stdout.write(formatPrCreateReport({ preflight, plan, result }, { dryRun: false, create: true, language: options.language }));
|
|
3203
3381
|
return {
|
|
3204
3382
|
task: 'pr',
|
|
3205
3383
|
dryRun: false,
|