create-quiver 0.15.3 → 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.
Files changed (236) hide show
  1. package/.github/workflows/ci.yml +3 -0
  2. package/AGENTS.md.es.template +37 -0
  3. package/docs/AI_CONTEXT.md.es.template +35 -0
  4. package/docs/AI_ONBOARDING_PROMPT.md.es.template +22 -0
  5. package/docs/CLI_UX_GUIDE.md +46 -0
  6. package/docs/COMMANDS.md.es.template +28 -0
  7. package/docs/CONTEXTO.md.es.template +33 -0
  8. package/docs/DECISIONS.md.es.template +17 -0
  9. package/docs/GITFLOW_PR_GUIDE.md.es.template +25 -0
  10. package/docs/INDEX.md +10 -1
  11. package/docs/INDEX.md.es.template +36 -0
  12. package/docs/STATUS.md.es.template +28 -0
  13. package/docs/SUPPORT_MATRIX.md.es.template +22 -0
  14. package/docs/TESTING_GUIDE_FOR_AI.md.es.template +19 -0
  15. package/docs/TROUBLESHOOTING.md.es.template +35 -0
  16. package/docs/WORKFLOW.md.es.template +29 -0
  17. package/docs/ai/LESSONS.md.es.template +24 -0
  18. package/docs/getting-started/installation.md +19 -0
  19. package/docs/reference/commands.md +55 -1
  20. package/package.json +1 -1
  21. package/specs/quiver-v37-cli-i18n-foundation/EVIDENCE_REPORT.md +73 -0
  22. package/specs/quiver-v37-cli-i18n-foundation/EXECUTION_PLAN.md +34 -0
  23. package/specs/quiver-v37-cli-i18n-foundation/SPEC.md +91 -0
  24. package/specs/quiver-v37-cli-i18n-foundation/STATUS.md +29 -0
  25. package/specs/quiver-v37-cli-i18n-foundation/pr.md +97 -0
  26. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-00-foundation-and-program-roadmap/CLOSURE_BRIEF.md +10 -0
  27. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-00-foundation-and-program-roadmap/EXECUTION_BRIEF.md +22 -0
  28. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-00-foundation-and-program-roadmap/slice.json +54 -0
  29. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-01-language-resolution-contract/CLOSURE_BRIEF.md +30 -0
  30. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-01-language-resolution-contract/EXECUTION_BRIEF.md +27 -0
  31. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-01-language-resolution-contract/slice.json +66 -0
  32. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-02-message-catalog-interpolation/CLOSURE_BRIEF.md +27 -0
  33. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-02-message-catalog-interpolation/EXECUTION_BRIEF.md +26 -0
  34. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-02-message-catalog-interpolation/slice.json +62 -0
  35. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-03-config-language-command/CLOSURE_BRIEF.md +32 -0
  36. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-03-config-language-command/EXECUTION_BRIEF.md +25 -0
  37. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-03-config-language-command/slice.json +66 -0
  38. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-04-parser-help-error-foundation/CLOSURE_BRIEF.md +30 -0
  39. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-04-parser-help-error-foundation/EXECUTION_BRIEF.md +24 -0
  40. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-04-parser-help-error-foundation/slice.json +65 -0
  41. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-05-foundation-docs-tests-package-readiness/CLOSURE_BRIEF.md +27 -0
  42. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-05-foundation-docs-tests-package-readiness/EXECUTION_BRIEF.md +23 -0
  43. package/specs/quiver-v37-cli-i18n-foundation/slices/slice-05-foundation-docs-tests-package-readiness/slice.json +67 -0
  44. package/specs/quiver-v38-cli-i18n-read-only-commands/EVIDENCE_REPORT.md +69 -0
  45. package/specs/quiver-v38-cli-i18n-read-only-commands/EXECUTION_PLAN.md +25 -0
  46. package/specs/quiver-v38-cli-i18n-read-only-commands/SPEC.md +52 -0
  47. package/specs/quiver-v38-cli-i18n-read-only-commands/STATUS.md +24 -0
  48. package/specs/quiver-v38-cli-i18n-read-only-commands/pr.md +119 -0
  49. package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-00-read-only-foundation/CLOSURE_BRIEF.md +10 -0
  50. package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-00-read-only-foundation/EXECUTION_BRIEF.md +21 -0
  51. package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-00-read-only-foundation/slice.json +53 -0
  52. package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-01-version-dashboard-help/CLOSURE_BRIEF.md +17 -0
  53. package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-01-version-dashboard-help/EXECUTION_BRIEF.md +23 -0
  54. package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-01-version-dashboard-help/slice.json +69 -0
  55. package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-02-flow-doctor-next-graph/CLOSURE_BRIEF.md +13 -0
  56. package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-02-flow-doctor-next-graph/EXECUTION_BRIEF.md +22 -0
  57. package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-02-flow-doctor-next-graph/slice.json +77 -0
  58. package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-03-ai-inspection-and-export/CLOSURE_BRIEF.md +12 -0
  59. package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-03-ai-inspection-and-export/EXECUTION_BRIEF.md +22 -0
  60. package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-03-ai-inspection-and-export/slice.json +66 -0
  61. package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-04-read-only-tests-smokes/CLOSURE_BRIEF.md +13 -0
  62. package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-04-read-only-tests-smokes/EXECUTION_BRIEF.md +22 -0
  63. package/specs/quiver-v38-cli-i18n-read-only-commands/slices/slice-04-read-only-tests-smokes/slice.json +61 -0
  64. package/specs/quiver-v39-cli-i18n-setup-onboarding/EVIDENCE_REPORT.md +71 -0
  65. package/specs/quiver-v39-cli-i18n-setup-onboarding/EXECUTION_PLAN.md +25 -0
  66. package/specs/quiver-v39-cli-i18n-setup-onboarding/SPEC.md +53 -0
  67. package/specs/quiver-v39-cli-i18n-setup-onboarding/STATUS.md +24 -0
  68. package/specs/quiver-v39-cli-i18n-setup-onboarding/pr.md +104 -0
  69. package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-00-setup-foundation/CLOSURE_BRIEF.md +10 -0
  70. package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-00-setup-foundation/EXECUTION_BRIEF.md +21 -0
  71. package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-00-setup-foundation/slice.json +53 -0
  72. package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-01-init-interactive-language/CLOSURE_BRIEF.md +12 -0
  73. package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-01-init-interactive-language/EXECUTION_BRIEF.md +23 -0
  74. package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-01-init-interactive-language/slice.json +68 -0
  75. package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-02-analyze-migrate-prepare/CLOSURE_BRIEF.md +12 -0
  76. package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-02-analyze-migrate-prepare/EXECUTION_BRIEF.md +23 -0
  77. package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-02-analyze-migrate-prepare/slice.json +62 -0
  78. package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-03-demo-evidence-onboarding/CLOSURE_BRIEF.md +12 -0
  79. package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-03-demo-evidence-onboarding/EXECUTION_BRIEF.md +22 -0
  80. package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-03-demo-evidence-onboarding/slice.json +72 -0
  81. package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-04-setup-tests-smokes/CLOSURE_BRIEF.md +15 -0
  82. package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-04-setup-tests-smokes/EXECUTION_BRIEF.md +22 -0
  83. package/specs/quiver-v39-cli-i18n-setup-onboarding/slices/slice-04-setup-tests-smokes/slice.json +61 -0
  84. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/EVIDENCE_REPORT.md +50 -0
  85. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/EXECUTION_PLAN.md +25 -0
  86. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/SPEC.md +52 -0
  87. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/STATUS.md +24 -0
  88. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/pr.md +94 -0
  89. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-00-spec-slice-foundation/CLOSURE_BRIEF.md +10 -0
  90. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-00-spec-slice-foundation/EXECUTION_BRIEF.md +21 -0
  91. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-00-spec-slice-foundation/slice.json +53 -0
  92. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-01-spec-create-start-status/CLOSURE_BRIEF.md +12 -0
  93. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-01-spec-create-start-status/EXECUTION_BRIEF.md +22 -0
  94. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-01-spec-create-start-status/slice.json +63 -0
  95. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-02-spec-validate-close/CLOSURE_BRIEF.md +10 -0
  96. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-02-spec-validate-close/EXECUTION_BRIEF.md +22 -0
  97. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-02-spec-validate-close/slice.json +63 -0
  98. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-03-slice-lifecycle-handoffs/CLOSURE_BRIEF.md +10 -0
  99. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-03-slice-lifecycle-handoffs/EXECUTION_BRIEF.md +22 -0
  100. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-03-slice-lifecycle-handoffs/slice.json +72 -0
  101. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-04-spec-slice-tests-smokes/CLOSURE_BRIEF.md +15 -0
  102. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-04-spec-slice-tests-smokes/EXECUTION_BRIEF.md +22 -0
  103. package/specs/quiver-v40-cli-i18n-spec-slice-workflows/slices/slice-04-spec-slice-tests-smokes/slice.json +69 -0
  104. package/specs/quiver-v41-cli-i18n-ai-lifecycle/EVIDENCE_REPORT.md +90 -0
  105. package/specs/quiver-v41-cli-i18n-ai-lifecycle/EXECUTION_PLAN.md +33 -0
  106. package/specs/quiver-v41-cli-i18n-ai-lifecycle/SPEC.md +57 -0
  107. package/specs/quiver-v41-cli-i18n-ai-lifecycle/STATUS.md +26 -0
  108. package/specs/quiver-v41-cli-i18n-ai-lifecycle/pr.md +103 -0
  109. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-00-ai-i18n-foundation/CLOSURE_BRIEF.md +10 -0
  110. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-00-ai-i18n-foundation/EXECUTION_BRIEF.md +21 -0
  111. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-00-ai-i18n-foundation/slice.json +53 -0
  112. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-01-ai-run-status-resume/CLOSURE_BRIEF.md +13 -0
  113. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-01-ai-run-status-resume/EXECUTION_BRIEF.md +22 -0
  114. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-01-ai-run-status-resume/slice.json +68 -0
  115. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-02-ai-agent-models/CLOSURE_BRIEF.md +12 -0
  116. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-02-ai-agent-models/EXECUTION_BRIEF.md +22 -0
  117. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-02-ai-agent-models/slice.json +66 -0
  118. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-03-ai-planner-approval-review/CLOSURE_BRIEF.md +12 -0
  119. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-03-ai-planner-approval-review/EXECUTION_BRIEF.md +23 -0
  120. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-03-ai-planner-approval-review/slice.json +68 -0
  121. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-04-ai-execution-pr/CLOSURE_BRIEF.md +13 -0
  122. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-04-ai-execution-pr/EXECUTION_BRIEF.md +23 -0
  123. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-04-ai-execution-pr/slice.json +72 -0
  124. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-05-ai-tests-smokes/CLOSURE_BRIEF.md +15 -0
  125. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-05-ai-tests-smokes/EXECUTION_BRIEF.md +22 -0
  126. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-05-ai-tests-smokes/slice.json +66 -0
  127. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-06-ai-prepare-context-progress-i18n-fix/CLOSURE_BRIEF.md +11 -0
  128. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-06-ai-prepare-context-progress-i18n-fix/EXECUTION_BRIEF.md +22 -0
  129. package/specs/quiver-v41-cli-i18n-ai-lifecycle/slices/slice-06-ai-prepare-context-progress-i18n-fix/slice.json +70 -0
  130. package/specs/quiver-v42-cli-i18n-generated-docs/EVIDENCE_REPORT.md +64 -0
  131. package/specs/quiver-v42-cli-i18n-generated-docs/EXECUTION_PLAN.md +26 -0
  132. package/specs/quiver-v42-cli-i18n-generated-docs/SPEC.md +52 -0
  133. package/specs/quiver-v42-cli-i18n-generated-docs/STATUS.md +24 -0
  134. package/specs/quiver-v42-cli-i18n-generated-docs/pr.md +125 -0
  135. package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-00-generated-docs-foundation/CLOSURE_BRIEF.md +10 -0
  136. package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-00-generated-docs-foundation/EXECUTION_BRIEF.md +21 -0
  137. package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-00-generated-docs-foundation/slice.json +53 -0
  138. package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-01-template-language-routing/CLOSURE_BRIEF.md +10 -0
  139. package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-01-template-language-routing/EXECUTION_BRIEF.md +22 -0
  140. package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-01-template-language-routing/slice.json +62 -0
  141. package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-02-init-docs-and-i18n-assets/CLOSURE_BRIEF.md +11 -0
  142. package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-02-init-docs-and-i18n-assets/EXECUTION_BRIEF.md +22 -0
  143. package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-02-init-docs-and-i18n-assets/slice.json +72 -0
  144. package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-03-docs-reference-guides/CLOSURE_BRIEF.md +12 -0
  145. package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-03-docs-reference-guides/EXECUTION_BRIEF.md +22 -0
  146. package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-03-docs-reference-guides/slice.json +60 -0
  147. package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-04-generated-docs-tests-smokes/CLOSURE_BRIEF.md +16 -0
  148. package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-04-generated-docs-tests-smokes/EXECUTION_BRIEF.md +22 -0
  149. package/specs/quiver-v42-cli-i18n-generated-docs/slices/slice-04-generated-docs-tests-smokes/slice.json +62 -0
  150. package/specs/quiver-v43-cli-i18n-audit-release-readiness/EVIDENCE_REPORT.md +203 -0
  151. package/specs/quiver-v43-cli-i18n-audit-release-readiness/EXECUTION_PLAN.md +27 -0
  152. package/specs/quiver-v43-cli-i18n-audit-release-readiness/SPEC.md +54 -0
  153. package/specs/quiver-v43-cli-i18n-audit-release-readiness/STATUS.md +24 -0
  154. package/specs/quiver-v43-cli-i18n-audit-release-readiness/command-language-mode-matrix.json +545 -0
  155. package/specs/quiver-v43-cli-i18n-audit-release-readiness/cross-platform-smoke-matrix.md +35 -0
  156. package/specs/quiver-v43-cli-i18n-audit-release-readiness/pr.md +155 -0
  157. package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-00-audit-foundation/CLOSURE_BRIEF.md +10 -0
  158. package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-00-audit-foundation/EXECUTION_BRIEF.md +21 -0
  159. package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-00-audit-foundation/slice.json +53 -0
  160. package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-01-command-language-mode-matrix/CLOSURE_BRIEF.md +13 -0
  161. package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-01-command-language-mode-matrix/EXECUTION_BRIEF.md +23 -0
  162. package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-01-command-language-mode-matrix/slice.json +62 -0
  163. package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-02-public-string-audit/CLOSURE_BRIEF.md +18 -0
  164. package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-02-public-string-audit/EXECUTION_BRIEF.md +22 -0
  165. package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-02-public-string-audit/slice.json +59 -0
  166. package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-03-cross-platform-smokes/CLOSURE_BRIEF.md +15 -0
  167. package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-03-cross-platform-smokes/EXECUTION_BRIEF.md +23 -0
  168. package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-03-cross-platform-smokes/slice.json +62 -0
  169. package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-04-package-release-readiness/CLOSURE_BRIEF.md +17 -0
  170. package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-04-package-release-readiness/EXECUTION_BRIEF.md +24 -0
  171. package/specs/quiver-v43-cli-i18n-audit-release-readiness/slices/slice-04-package-release-readiness/slice.json +66 -0
  172. package/specs/quiver-v44-provider-live-output-tui-lite/EVIDENCE_REPORT.md +18 -0
  173. package/specs/quiver-v44-provider-live-output-tui-lite/EXECUTION_PLAN.md +31 -0
  174. package/specs/quiver-v44-provider-live-output-tui-lite/SPEC.md +118 -0
  175. package/specs/quiver-v44-provider-live-output-tui-lite/STATUS.md +25 -0
  176. package/specs/quiver-v44-provider-live-output-tui-lite/pr.md +92 -0
  177. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-00-tui-lite-contract-foundation/CLOSURE_BRIEF.md +11 -0
  178. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-00-tui-lite-contract-foundation/EXECUTION_BRIEF.md +23 -0
  179. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-00-tui-lite-contract-foundation/slice.json +64 -0
  180. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-01-provider-stream-hooks/CLOSURE_BRIEF.md +10 -0
  181. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-01-provider-stream-hooks/EXECUTION_BRIEF.md +24 -0
  182. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-01-provider-stream-hooks/slice.json +65 -0
  183. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-02-live-output-renderer/CLOSURE_BRIEF.md +10 -0
  184. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-02-live-output-renderer/EXECUTION_BRIEF.md +24 -0
  185. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-02-live-output-renderer/slice.json +70 -0
  186. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-03-prepare-context-integration/CLOSURE_BRIEF.md +10 -0
  187. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-03-prepare-context-integration/EXECUTION_BRIEF.md +25 -0
  188. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-03-prepare-context-integration/slice.json +70 -0
  189. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-04-planner-command-audit-adoption/CLOSURE_BRIEF.md +10 -0
  190. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-04-planner-command-audit-adoption/EXECUTION_BRIEF.md +26 -0
  191. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-04-planner-command-audit-adoption/slice.json +72 -0
  192. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-05-docs-tests-readiness/CLOSURE_BRIEF.md +15 -0
  193. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-05-docs-tests-readiness/EXECUTION_BRIEF.md +26 -0
  194. package/specs/quiver-v44-provider-live-output-tui-lite/slices/slice-05-docs-tests-readiness/slice.json +75 -0
  195. package/specs/quiver-v45-ci-actions-node24-readiness/EVIDENCE_REPORT.md +30 -0
  196. package/specs/quiver-v45-ci-actions-node24-readiness/EXECUTION_PLAN.md +22 -0
  197. package/specs/quiver-v45-ci-actions-node24-readiness/SPEC.md +49 -0
  198. package/specs/quiver-v45-ci-actions-node24-readiness/STATUS.md +21 -0
  199. package/specs/quiver-v45-ci-actions-node24-readiness/pr.md +67 -0
  200. package/specs/quiver-v45-ci-actions-node24-readiness/slices/slice-00-ci-actions-foundation/CLOSURE_BRIEF.md +10 -0
  201. package/specs/quiver-v45-ci-actions-node24-readiness/slices/slice-00-ci-actions-foundation/EXECUTION_BRIEF.md +21 -0
  202. package/specs/quiver-v45-ci-actions-node24-readiness/slices/slice-00-ci-actions-foundation/slice.json +48 -0
  203. package/specs/quiver-v45-ci-actions-node24-readiness/slices/slice-01-actions-node24-readiness/CLOSURE_BRIEF.md +14 -0
  204. package/specs/quiver-v45-ci-actions-node24-readiness/slices/slice-01-actions-node24-readiness/EXECUTION_BRIEF.md +23 -0
  205. package/specs/quiver-v45-ci-actions-node24-readiness/slices/slice-01-actions-node24-readiness/slice.json +65 -0
  206. package/src/create-quiver/commands/ai.js +485 -307
  207. package/src/create-quiver/commands/config.js +124 -0
  208. package/src/create-quiver/commands/demo.js +2 -2
  209. package/src/create-quiver/commands/evidence.js +6 -4
  210. package/src/create-quiver/commands/flow.js +108 -16
  211. package/src/create-quiver/commands/graph.js +1 -0
  212. package/src/create-quiver/commands/next.js +21 -18
  213. package/src/create-quiver/commands/plan.js +23 -6
  214. package/src/create-quiver/commands/spec.js +66 -57
  215. package/src/create-quiver/index.js +514 -139
  216. package/src/create-quiver/lib/ai/execution-plan.js +23 -20
  217. package/src/create-quiver/lib/ai/executor.js +60 -44
  218. package/src/create-quiver/lib/ai/export-state.js +75 -64
  219. package/src/create-quiver/lib/ai/github.js +24 -21
  220. package/src/create-quiver/lib/ai/run-state.js +28 -25
  221. package/src/create-quiver/lib/dashboard.js +154 -111
  222. package/src/create-quiver/lib/demo.js +14 -12
  223. package/src/create-quiver/lib/handoff.js +16 -7
  224. package/src/create-quiver/lib/i18n/catalog.js +152 -0
  225. package/src/create-quiver/lib/i18n/language.js +279 -0
  226. package/src/create-quiver/lib/i18n/messages/en.js +853 -0
  227. package/src/create-quiver/lib/i18n/messages/es.js +968 -0
  228. package/src/create-quiver/lib/i18n/read-only-format.js +26 -0
  229. package/src/create-quiver/lib/i18n/templates.js +172 -0
  230. package/src/create-quiver/lib/init-docs.js +18 -4
  231. package/src/create-quiver/lib/init-layout.js +6 -0
  232. package/src/create-quiver/lib/lifecycle.js +53 -46
  233. package/src/create-quiver/lib/readiness.js +77 -67
  234. package/src/create-quiver/lib/renderers/tree.js +9 -6
  235. package/src/create-quiver/lib/spec-worktrees.js +34 -30
  236. package/src/create-quiver/lib/version.js +11 -9
@@ -35,6 +35,7 @@ const {
35
35
  runSpecsList: runAiSpecsList,
36
36
  runTraceReport: runAiTraceReport,
37
37
  } = require('./commands/ai');
38
+ const { runConfig } = require('./commands/config');
38
39
  const { runDashboard } = require('./commands/dashboard');
39
40
  const { runDemo } = require('./commands/demo');
40
41
  const { runPrepare } = require('./commands/prepare');
@@ -59,6 +60,16 @@ const { getContextPathExclusionReason } = require('./lib/ai/safety');
59
60
  const { selectOption } = require('./lib/cli/selectors');
60
61
  const { createUx } = require('./lib/cli/ux');
61
62
  const { validateUxFlags } = require('./lib/cli/ux-flags');
63
+ const {
64
+ DEFAULT_LANGUAGE,
65
+ extractCliLanguageFlag,
66
+ normalizeLanguage,
67
+ readProjectLanguageConfig,
68
+ resolveLanguage,
69
+ writeProjectLanguageConfig,
70
+ } = require('./lib/i18n/language');
71
+ const { createTranslator, getCatalog, translate } = require('./lib/i18n/catalog');
72
+ const { formatWarningPrefix } = require('./lib/i18n/read-only-format');
62
73
  const { relativePosixPath, resolveTargetRoot } = require('./lib/paths');
63
74
  const {
64
75
  CURRENT_SCAN_RELATIVE_PATH,
@@ -78,8 +89,60 @@ const {
78
89
  const cliPackageJson = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../..', 'package.json'), 'utf8'));
79
90
  const CLI_VERSION = cliPackageJson.version || '0.0.0';
80
91
 
92
+ let currentErrorLanguage = DEFAULT_LANGUAGE;
93
+
94
+ function setCurrentErrorLanguage(language) {
95
+ currentErrorLanguage = language || DEFAULT_LANGUAGE;
96
+ }
97
+
98
+ function localizeParserMessage(message, language = currentErrorLanguage) {
99
+ const raw = String(message || '');
100
+ const missingValue = raw.match(/^missing value for (--[a-z0-9-]+)$/i);
101
+ if (missingValue) {
102
+ return translate(language, 'error.flag.missing_value', { flag: missingValue[1] });
103
+ }
104
+
105
+ const invalidValue = raw.match(/^invalid value for (--[a-z0-9-]+)$/i);
106
+ if (invalidValue) {
107
+ return translate(language, 'error.flag.invalid_value', { flag: invalidValue[1] });
108
+ }
109
+
110
+ const unknownFlag = raw.match(/^unknown flag: (.+)$/);
111
+ if (unknownFlag) {
112
+ return translate(language, 'error.flag.unknown', { flag: unknownFlag[1] });
113
+ }
114
+
115
+ return raw;
116
+ }
117
+
81
118
  function formatError(message) {
82
- return `create-quiver: ${message}`;
119
+ return `create-quiver: ${localizeParserMessage(message)}`;
120
+ }
121
+
122
+ function helpCatalog(language = DEFAULT_LANGUAGE) {
123
+ const catalog = getCatalog(language);
124
+ return catalog.messages['cli.help'] || getCatalog(DEFAULT_LANGUAGE).messages['cli.help'] || {};
125
+ }
126
+
127
+ function helpText(help, section, key, fallback) {
128
+ return help?.[section]?.[key] || fallback;
129
+ }
130
+
131
+ function optionDescription(help, fallback) {
132
+ return helpText(help, 'optionDescriptions', fallback, fallback);
133
+ }
134
+
135
+ function formatLanguageWarningForCli(warning, language = DEFAULT_LANGUAGE) {
136
+ if (!warning || warning.code !== 'UNSUPPORTED_LANGUAGE') {
137
+ return '';
138
+ }
139
+
140
+ return formatError(translate(language, 'warning.language.unsupported_source', {
141
+ fallback: warning.fallbackLanguage,
142
+ language: warning.requestedLanguage,
143
+ source: warning.source,
144
+ supported: warning.supportedLanguages.join(', '),
145
+ }));
83
146
  }
84
147
 
85
148
  const SUPPORTED_COMMAND_MODES = new Set([
@@ -101,6 +164,7 @@ const SUPPORTED_COMMAND_MODES = new Set([
101
164
  'new-handoff',
102
165
  'cleanup-slice',
103
166
  'check-scope',
167
+ 'config',
104
168
  'refresh-active-slices',
105
169
  'spec',
106
170
  'evidence',
@@ -138,13 +202,16 @@ const SUPPORTED_AI_COMMANDS = new Set([
138
202
 
139
203
  const SUPPORTED_SPEC_COMMANDS = new Set(['close', 'create', 'start', 'status', 'validate']);
140
204
  const SUPPORTED_DEMO_COMMANDS = new Set(['create']);
205
+ const SUPPORTED_CONFIG_SECTIONS = new Set(['language']);
206
+ const SUPPORTED_CONFIG_LANGUAGE_COMMANDS = new Set(['show', 'set']);
141
207
 
142
208
  function unsupportedCommandMessage(commandName) {
209
+ const translator = createTranslator(currentErrorLanguage);
143
210
  return [
144
- `unsupported command: ${commandName}`,
145
- 'Run: npx create-quiver --help',
146
- `If you meant to initialize a project, use: npx create-quiver init --name "${commandName}"`,
147
- 'If this command exists in newer docs, update create-quiver and rerun the command.',
211
+ translator.t('error.command.unsupported', { commandName }),
212
+ translator.t('error.command.help'),
213
+ translator.t('error.command.init_hint', { commandName }),
214
+ translator.t('error.command.update_hint'),
148
215
  ].join('\n');
149
216
  }
150
217
 
@@ -158,6 +225,7 @@ const COMMAND_HELP_GROUPS = [
158
225
  ['flow', 'Show the read-only guided workflow stage, blockers, and next safe command.'],
159
226
  ['dashboard', 'Show compact read-only project, spec, slice, run, approval, and agent status.'],
160
227
  ['version', 'Show a Quiver-branded version report; use --json for metadata.'],
228
+ ['config language show|set', 'Inspect or update the effective Quiver language without editing JSON by hand.'],
161
229
  ['prepare', 'Run setup diagnostics for providers, GitHub, SSH, and project readiness.'],
162
230
  ['migrate', 'Upgrade an already initialized Quiver project to the current contract.'],
163
231
  ],
@@ -240,25 +308,29 @@ const COMMAND_HELP_GROUPS = [
240
308
  },
241
309
  ];
242
310
 
243
- function formatCommandHelpGroups() {
244
- const lines = ['Commands:'];
311
+ function formatCommandHelpGroups(language = DEFAULT_LANGUAGE) {
312
+ const help = helpCatalog(language);
313
+ const lines = [helpText(help, 'headings', 'commands', 'Commands:')];
245
314
  for (const group of COMMAND_HELP_GROUPS) {
246
- lines.push('', `${group.title}:`);
315
+ lines.push('', `${helpText(help, 'groupTitles', group.title, group.title)}:`);
247
316
  for (const [command, description] of group.commands) {
248
- lines.push(` ${command.padEnd(24)} ${description}`);
317
+ lines.push(` ${command.padEnd(24)} ${helpText(help, 'commandDescriptions', command, description)}`);
249
318
  }
250
319
  }
251
320
  return lines.join('\n');
252
321
  }
253
322
 
254
- function printUsage() {
255
- console.log(`Usage:
323
+ function printUsage(language = DEFAULT_LANGUAGE) {
324
+ const help = helpCatalog(language);
325
+ console.log(`${helpText(help, 'headings', 'usage', 'Usage:')}
256
326
  npx create-quiver [options]
257
327
  npx create-quiver init [options]
258
328
  npx create-quiver analyze [options]
259
329
  npx create-quiver flow [options]
260
330
  npx create-quiver dashboard [options]
261
331
  npx create-quiver version [--json]
332
+ npx create-quiver config language show [--json]
333
+ npx create-quiver config language set <en|es> [--global]
262
334
  npx create-quiver plan [options]
263
335
  npx create-quiver ai <task> [options]
264
336
  npx create-quiver ai run create --input <requirements.md>
@@ -297,59 +369,61 @@ function printUsage() {
297
369
  npx create-quiver evidence run [options] -- <command>
298
370
  npx create-quiver demo create spec-viewer [options]
299
371
 
300
- ${formatCommandHelpGroups()}
301
-
302
- Options:
303
- -n, --name <project-name> Project name to generate
304
- -d, --dir <target-dir> Target directory to scaffold into or inspect
305
- --spec <slug> Restrict plan, graph, next, or dashboard output to one spec
306
- --format <name> Graph or AI export output format (tree, mermaid, dot, json, markdown)
307
- --show-conflicts Show shared file paths in graph output
308
- --level <n> Restrict graph output to one level
309
- --json Emit machine-readable JSON
310
- --include-completed Include completed slices in dashboard, plan, graph, or next history output
311
- --details Show the full human dashboard report
312
- --section <name> Show one human dashboard section
313
- --limit <n> Limit dashboard human lists (1-100)
314
- --only-ready Show only slices with no pending dependencies
315
- --all-ready List every ready slice returned by next
316
- --auto-start Prompt for confirmation and run start-slice on next
317
- --local For check-slice, run structural validation without remote/base checks
318
- --strict Treat supported validation warnings as failures
319
- --unicode Prefer Unicode output when supported
320
- --minimal Plan or run the minimal init profile
321
- --full Plan or run the full compatibility init profile
322
- --legacy-scripts Include legacy Bash wrappers in init profile
323
- --include-templates Export packaged templates in init profile
324
- --dry-run Preview init, analyze, migrate, prepare, spec create/start/close, demo, ai agent set, or AI work without executing writes/providers
325
- --print-prompt Print the exact AI prompt and exit without executing provider CLIs
326
- --with-planner Enable planner-assisted behavior on commands that explicitly support it
327
- --interactive Enable prompts on commands that explicitly support interactive choices
328
- --review Open or prepare human review before persistent writes where supported
329
- --methodology <name> Select methodology where supported (currently wdd-sdd)
330
- --no-color Disable ANSI colors in human output
331
- --fix For doctor, apply safe non-destructive repairs
332
- --execute For ai execute-plan, run the planned slices instead of printing commands
333
- --create For ai pr, create the PR after preflight instead of printing the plan only
334
- --commit For ai execute-slice, commit validated slice changes after provider, scope, and tests pass
335
- --allow-dirty For ai execute-slice, allow pre-existing dirty files and ignore them for scope diff
336
- --mode <name> Execution mode for ai execute-plan (auto, manual, delegated)
337
- --provider <name> Provider CLI to preflight for prepare or AI commands
338
- --model <model-id> Technical model id for AI agent profiles or provider-backed AI commands
339
- --version <n> Draft version to approve for AI planner phases
340
- --run <id> AI lifecycle run id
341
- --ssh-host-alias <name> SSH host alias to validate for prepare or AI commands
342
- --identity-file <path> SSH identity file to validate for prepare or AI commands
343
- --remote <name> Git remote name for check-slice or AI PR checks
344
- --base <branch> Base branch for check-slice, check-scope, ai pr, or spec close (default: main)
345
- --output <file> Output file for evidence run
346
- --max-output <n> Maximum stdout/stderr chars per evidence section
347
- --title <text> Override PR title for ai pr create
348
- -y, --yes Skip prompts and use the provided inputs
349
- -V, --version Show the installed create-quiver version
350
- -h, --help Show this help message
351
-
352
- Examples:
372
+ ${formatCommandHelpGroups(language)}
373
+
374
+ ${helpText(help, 'headings', 'options', 'Options:')}
375
+ -n, --name <project-name> ${optionDescription(help, 'Project name to generate')}
376
+ -d, --dir <target-dir> ${optionDescription(help, 'Target directory to scaffold into or inspect')}
377
+ --spec <slug> ${optionDescription(help, 'Restrict plan, graph, next, or dashboard output to one spec')}
378
+ --format <name> ${optionDescription(help, 'Graph or AI export output format (tree, mermaid, dot, json, markdown)')}
379
+ --show-conflicts ${optionDescription(help, 'Show shared file paths in graph output')}
380
+ --level <n> ${optionDescription(help, 'Restrict graph output to one level')}
381
+ --json ${optionDescription(help, 'Emit machine-readable JSON')}
382
+ --lang <en|es> ${optionDescription(help, 'Override CLI human output language')}
383
+ --global ${optionDescription(help, 'For config language set, write the global user config')}
384
+ --include-completed ${optionDescription(help, 'Include completed slices in dashboard, plan, graph, or next history output')}
385
+ --details ${optionDescription(help, 'Show the full human dashboard report')}
386
+ --section <name> ${optionDescription(help, 'Show one human dashboard section')}
387
+ --limit <n> ${optionDescription(help, 'Limit dashboard human lists (1-100)')}
388
+ --only-ready ${optionDescription(help, 'Show only slices with no pending dependencies')}
389
+ --all-ready ${optionDescription(help, 'List every ready slice returned by next')}
390
+ --auto-start ${optionDescription(help, 'Prompt for confirmation and run start-slice on next')}
391
+ --local ${optionDescription(help, 'For check-slice, run structural validation without remote/base checks')}
392
+ --strict ${optionDescription(help, 'Treat supported validation warnings as failures')}
393
+ --unicode ${optionDescription(help, 'Prefer Unicode output when supported')}
394
+ --minimal ${optionDescription(help, 'Plan or run the minimal init profile')}
395
+ --full ${optionDescription(help, 'Plan or run the full compatibility init profile')}
396
+ --legacy-scripts ${optionDescription(help, 'Include legacy Bash wrappers in init profile')}
397
+ --include-templates ${optionDescription(help, 'Export packaged templates in init profile')}
398
+ --dry-run ${optionDescription(help, 'Preview init, analyze, migrate, prepare, spec create/start/close, demo, ai agent set, or AI work without executing writes/providers')}
399
+ --print-prompt ${optionDescription(help, 'Print the exact AI prompt and exit without executing provider CLIs')}
400
+ --with-planner ${optionDescription(help, 'Enable planner-assisted behavior on commands that explicitly support it')}
401
+ --interactive ${optionDescription(help, 'Enable prompts on commands that explicitly support interactive choices')}
402
+ --review ${optionDescription(help, 'Open or prepare human review before persistent writes where supported')}
403
+ --methodology <name> ${optionDescription(help, 'Select methodology where supported (currently wdd-sdd)')}
404
+ --no-color ${optionDescription(help, 'Disable ANSI colors in human output')}
405
+ --fix ${optionDescription(help, 'For doctor, apply safe non-destructive repairs')}
406
+ --execute ${optionDescription(help, 'For ai execute-plan, run the planned slices instead of printing commands')}
407
+ --create ${optionDescription(help, 'For ai pr, create the PR after preflight instead of printing the plan only')}
408
+ --commit ${optionDescription(help, 'For ai execute-slice, commit validated slice changes after provider, scope, and tests pass')}
409
+ --allow-dirty ${optionDescription(help, 'For ai execute-slice, allow pre-existing dirty files and ignore them for scope diff')}
410
+ --mode <name> ${optionDescription(help, 'Execution mode for ai execute-plan (auto, manual, delegated)')}
411
+ --provider <name> ${optionDescription(help, 'Provider CLI to preflight for prepare or AI commands')}
412
+ --model <model-id> ${optionDescription(help, 'Technical model id for AI agent profiles or provider-backed AI commands')}
413
+ --version <n> ${optionDescription(help, 'Draft version to approve for AI planner phases')}
414
+ --run <id> ${optionDescription(help, 'AI lifecycle run id')}
415
+ --ssh-host-alias <name> ${optionDescription(help, 'SSH host alias to validate for prepare or AI commands')}
416
+ --identity-file <path> ${optionDescription(help, 'SSH identity file to validate for prepare or AI commands')}
417
+ --remote <name> ${optionDescription(help, 'Git remote name for check-slice or AI PR checks')}
418
+ --base <branch> ${optionDescription(help, 'Base branch for check-slice, check-scope, ai pr, or spec close (default: main)')}
419
+ --output <file> ${optionDescription(help, 'Output file for evidence run')}
420
+ --max-output <n> ${optionDescription(help, 'Maximum stdout/stderr chars per evidence section')}
421
+ --title <text> ${optionDescription(help, 'Override PR title for ai pr create')}
422
+ -y, --yes ${optionDescription(help, 'Skip prompts and use the provided inputs')}
423
+ -V, --version ${optionDescription(help, 'Show the installed create-quiver version')}
424
+ -h, --help ${optionDescription(help, 'Show this help message')}
425
+
426
+ ${helpText(help, 'headings', 'examples', 'Examples:')}
353
427
  npx create-quiver init --name "My Project"
354
428
  npx create-quiver init --interactive
355
429
  npx create-quiver init --name "My Project" --dry-run
@@ -361,6 +435,9 @@ Examples:
361
435
  cd ./my-project && npx create-quiver dashboard --json
362
436
  cd ./my-project && npx create-quiver version
363
437
  cd ./my-project && npx create-quiver version --json
438
+ cd ./my-project && npx create-quiver config language show
439
+ cd ./my-project && npx create-quiver config language set es
440
+ npx create-quiver config language set en --global
364
441
  cd ./my-project && npx create-quiver analyze
365
442
  cd ./my-project && npx create-quiver plan --json
366
443
  cd ./my-project && npx create-quiver ai onboard --dry-run
@@ -428,7 +505,7 @@ Examples:
428
505
  `);
429
506
  }
430
507
 
431
- function parseArgs(argv) {
508
+ function parseArgs(argv, options = {}) {
432
509
  const result = {
433
510
  help: false,
434
511
  force: false,
@@ -448,8 +525,14 @@ function parseArgs(argv) {
448
525
  strict: false,
449
526
  strictOverlap: false,
450
527
  json: false,
528
+ language: options.language || '',
529
+ languageResolution: null,
451
530
  noColor: false,
452
531
  withPlanner: false,
532
+ configGlobal: false,
533
+ configSection: '',
534
+ configCommand: '',
535
+ configValue: '',
453
536
  interactive: false,
454
537
  review: false,
455
538
  includeCompleted: false,
@@ -700,6 +783,11 @@ function parseArgs(argv) {
700
783
  continue;
701
784
  }
702
785
 
786
+ if (arg === '--global') {
787
+ result.configGlobal = true;
788
+ continue;
789
+ }
790
+
703
791
  if (arg === '--with-planner') {
704
792
  result.withPlanner = true;
705
793
  continue;
@@ -1104,6 +1192,28 @@ function parseArgs(argv) {
1104
1192
  if (positional.length > 0) {
1105
1193
  throw new Error(formatError('dashboard does not accept positional arguments; use --spec <slug>'));
1106
1194
  }
1195
+ } else if (result.mode === 'config') {
1196
+ if (!result.configSection && positional.length > 0) {
1197
+ result.configSection = positional.shift();
1198
+ }
1199
+ if (!SUPPORTED_CONFIG_SECTIONS.has(result.configSection)) {
1200
+ throw new Error(formatError(`unsupported config section: ${result.configSection || '(missing)'}. Supported sections: language`));
1201
+ }
1202
+ if (!result.configCommand && positional.length > 0) {
1203
+ result.configCommand = positional.shift();
1204
+ }
1205
+ if (!SUPPORTED_CONFIG_LANGUAGE_COMMANDS.has(result.configCommand)) {
1206
+ throw new Error(formatError(`unsupported config language command: ${result.configCommand || '(missing)'}. Supported commands: show, set`));
1207
+ }
1208
+ if (result.configCommand === 'set') {
1209
+ if (positional.length === 0) {
1210
+ throw new Error(formatError('missing language for config language set. Use: npx create-quiver config language set <en|es>'));
1211
+ }
1212
+ result.configValue = positional.shift();
1213
+ }
1214
+ if (result.configCommand === 'show' && positional.length > 0) {
1215
+ throw new Error(formatError('config language show does not accept a language value'));
1216
+ }
1107
1217
  } else if (result.mode === 'ai') {
1108
1218
  if (!result.aiCommand && positional.length > 0) {
1109
1219
  result.aiCommand = positional.shift();
@@ -1205,6 +1315,14 @@ function parseArgs(argv) {
1205
1315
  throw new Error(formatError(`${requestedDashboardFlags.join(', ')} ${requestedDashboardFlags.length === 1 ? 'is' : 'are'} only supported by dashboard. Use: npx create-quiver dashboard ${requestedDashboardFlags[0]}${requestedDashboardFlags[0] === '--section' ? ' <name>' : requestedDashboardFlags[0] === '--limit' ? ' <n>' : ''}`));
1206
1316
  }
1207
1317
 
1318
+ if (result.mode !== 'config' && result.configGlobal) {
1319
+ throw new Error(formatError('--global is only supported by config language set. Use: npx create-quiver config language set <en|es> --global'));
1320
+ }
1321
+
1322
+ if (result.mode === 'config' && result.configGlobal && result.configCommand !== 'set') {
1323
+ throw new Error(formatError('--global is only supported by config language set. Use: npx create-quiver config language set <en|es> --global'));
1324
+ }
1325
+
1208
1326
  return result;
1209
1327
  }
1210
1328
 
@@ -1349,6 +1467,7 @@ function runInitDocs(repoRoot, projectName, options = {}) {
1349
1467
  migrateMode: false,
1350
1468
  profile: options.profile || 'default',
1351
1469
  templateRoot: templateRoot.path,
1470
+ language: options.language || '',
1352
1471
  });
1353
1472
  }
1354
1473
 
@@ -2204,6 +2323,7 @@ function writeProjectScanArtifacts(projectRoot, scan) {
2204
2323
 
2205
2324
  function runAnalyze(targetDir, options = {}) {
2206
2325
  const projectRoot = resolveTargetRoot(process.cwd(), targetDir);
2326
+ const translator = createTranslator(options.language);
2207
2327
 
2208
2328
  if (!fs.existsSync(projectRoot)) {
2209
2329
  throw new Error(formatError(`target directory does not exist: ${projectRoot}`));
@@ -2212,14 +2332,14 @@ function runAnalyze(targetDir, options = {}) {
2212
2332
  const scan = buildProjectScan(projectRoot);
2213
2333
 
2214
2334
  if (options.dryRun) {
2215
- console.log(`Project analysis dry-run for ${projectRoot}`);
2216
- console.log('Writes: none');
2217
- console.log(`Would write ${CURRENT_SCAN_RELATIVE_PATH}`);
2218
- console.log(`Would write ${PROJECT_MAP_RELATIVE_PATH}`);
2219
- console.log('Would refresh docs/AI_CONTEXT.md');
2220
- console.log(`Detected primary stack: ${scan.stack.primary}`);
2221
- console.log(`Detected frameworks: ${scan.stack.frameworks.length > 0 ? scan.stack.frameworks.join(', ') : 'none detected'}`);
2222
- console.log(`Detected package manager: ${scan.project.package_manager}`);
2335
+ console.log(translator.t('analyze.dry_run_for', { path: projectRoot }));
2336
+ console.log(translator.t('analyze.writes_none'));
2337
+ console.log(translator.t('analyze.would_write', { path: CURRENT_SCAN_RELATIVE_PATH }));
2338
+ console.log(translator.t('analyze.would_write', { path: PROJECT_MAP_RELATIVE_PATH }));
2339
+ console.log(translator.t('analyze.would_refresh', { path: 'docs/AI_CONTEXT.md' }));
2340
+ console.log(translator.t('analyze.detected_primary_stack', { stack: scan.stack.primary }));
2341
+ console.log(translator.t('analyze.detected_frameworks', { frameworks: scan.stack.frameworks.length > 0 ? scan.stack.frameworks.join(', ') : translator.t('common.none_detected') }));
2342
+ console.log(translator.t('analyze.detected_package_manager', { manager: scan.project.package_manager }));
2223
2343
  return {
2224
2344
  artifacts: {
2225
2345
  jsonPath: path.join(projectRoot, CURRENT_SCAN_RELATIVE_PATH),
@@ -2234,12 +2354,12 @@ function runAnalyze(targetDir, options = {}) {
2234
2354
  const aiContextPath = refreshAiContextDoc(projectRoot, scan);
2235
2355
  updateStateForAnalyze(projectRoot, CLI_VERSION);
2236
2356
 
2237
- console.log(`Project analysis completed for ${projectRoot}`);
2238
- console.log(`Wrote ${relativePosixPath(projectRoot, artifacts.jsonPath)}`);
2239
- console.log(`Wrote ${relativePosixPath(projectRoot, artifacts.mdPath)}`);
2240
- console.log(`Wrote ${relativePosixPath(projectRoot, aiContextPath)}`);
2241
- console.log(`Detected primary stack: ${scan.stack.primary}`);
2242
- console.log(`Detected package manager: ${scan.project.package_manager}`);
2357
+ console.log(translator.t('analyze.completed_for', { path: projectRoot }));
2358
+ console.log(translator.t('analyze.wrote', { path: relativePosixPath(projectRoot, artifacts.jsonPath) }));
2359
+ console.log(translator.t('analyze.wrote', { path: relativePosixPath(projectRoot, artifacts.mdPath) }));
2360
+ console.log(translator.t('analyze.wrote', { path: relativePosixPath(projectRoot, aiContextPath) }));
2361
+ console.log(translator.t('analyze.detected_primary_stack', { stack: scan.stack.primary }));
2362
+ console.log(translator.t('analyze.detected_package_manager', { manager: scan.project.package_manager }));
2243
2363
 
2244
2364
  return {
2245
2365
  artifacts,
@@ -2251,6 +2371,7 @@ function runAnalyze(targetDir, options = {}) {
2251
2371
 
2252
2372
  function runMigrate(targetDir, options = {}) {
2253
2373
  const projectRoot = resolveTargetRoot(process.cwd(), targetDir);
2374
+ const translator = createTranslator(options.language);
2254
2375
 
2255
2376
  if (!fs.existsSync(projectRoot)) {
2256
2377
  throw new Error(formatError(`target directory does not exist: ${projectRoot}`));
@@ -2273,17 +2394,17 @@ function runMigrate(targetDir, options = {}) {
2273
2394
  projectName,
2274
2395
  skipInstall: options.skipInstall === true,
2275
2396
  });
2276
- console.log('Quiver migration dry-run');
2277
- console.log(`- Project: ${projectName}`);
2278
- console.log(`- Target: ${projectRoot}`);
2279
- console.log('- Writes: none');
2280
- console.log(`- Planned create: ${migrationPlan.summary.create}`);
2281
- console.log(`- Planned update: ${migrationPlan.summary.update}`);
2282
- console.log(`- Planned preserve: ${migrationPlan.summary.preserve}`);
2397
+ console.log(translator.t('migrate.dry_run_title'));
2398
+ console.log(`- ${translator.t('migrate.project', { project: projectName })}`);
2399
+ console.log(`- ${translator.t('migrate.target', { path: projectRoot })}`);
2400
+ console.log(`- ${translator.t('migrate.writes_none')}`);
2401
+ console.log(`- ${translator.t('migrate.planned_create', { count: migrationPlan.summary.create })}`);
2402
+ console.log(`- ${translator.t('migrate.planned_update', { count: migrationPlan.summary.update })}`);
2403
+ console.log(`- ${translator.t('migrate.planned_preserve', { count: migrationPlan.summary.preserve })}`);
2283
2404
  if (legacyLayout.hasLegacyLayout) {
2284
- console.log(`- Legacy layout detected and preserved: ${legacyLayout.legacyPaths.join(', ')}`);
2405
+ console.log(`- ${translator.t('migrate.legacy_preserved', { paths: legacyLayout.legacyPaths.join(', ') })}`);
2285
2406
  }
2286
- console.log('- Next command: npx create-quiver migrate --skip-install');
2407
+ console.log(`- ${translator.t('migrate.next_command', { command: 'npx create-quiver migrate --skip-install' })}`);
2287
2408
  console.log('');
2288
2409
  console.log(formatInitLayoutPlan(migrationPlan));
2289
2410
  return;
@@ -2314,10 +2435,10 @@ function runMigrate(targetDir, options = {}) {
2314
2435
  }
2315
2436
  }
2316
2437
 
2317
- console.log(`Quiver migration completed for ${projectRoot}`);
2318
- console.log('Missing workflow files were restored without overwriting existing project files.');
2438
+ console.log(translator.t('migrate.completed_for', { path: projectRoot }));
2439
+ console.log(translator.t('migrate.restored_missing'));
2319
2440
  if (legacyLayout.hasLegacyLayout) {
2320
- console.log(`Legacy layout detected and preserved: ${legacyLayout.legacyPaths.join(', ')}`);
2441
+ console.log(translator.t('migrate.legacy_preserved', { paths: legacyLayout.legacyPaths.join(', ') }));
2321
2442
  }
2322
2443
  } finally {
2323
2444
  fs.rmSync(tempRoot, { recursive: true, force: true });
@@ -2558,6 +2679,7 @@ function buildDoctorCommandReport(projectRoot) {
2558
2679
  }
2559
2680
 
2560
2681
  function formatDoctorHumanReport(report, options = {}) {
2682
+ const translator = createTranslator(options.language);
2561
2683
  const lines = [];
2562
2684
  const ux = createUx({
2563
2685
  ...options,
@@ -2574,19 +2696,39 @@ function formatDoctorHumanReport(report, options = {}) {
2574
2696
  if (status === 'error') return 'error';
2575
2697
  return 'warning';
2576
2698
  };
2699
+ const localizeDoctorText = (message) => {
2700
+ const text = String(message || '');
2701
+ let match = text.match(/^Quiver doctor passed for (.+)$/);
2702
+ if (match) return translator.t('doctor.check.passed_for', { path: match[1] });
2703
+ match = text.match(/^Layout: (.+)$/);
2704
+ if (match) return translator.t('doctor.check.layout', { layout: match[1] });
2705
+ if (text === 'Specs: none yet') return translator.t('doctor.check.specs_none');
2706
+ match = text.match(/^Specs: (.+)$/);
2707
+ if (match) return translator.t('doctor.check.specs_found', { specs: match[1] });
2708
+ if (text === 'Required files found') return translator.t('doctor.check.required_files_found');
2709
+ if (text === 'Workflow scripts available') return translator.t('doctor.check.workflow_scripts_available');
2710
+ if (text === 'Quiver state metadata found') return translator.t('doctor.check.state_found');
2711
+ if (text === 'Project analysis artifacts found') return translator.t('doctor.check.project_analysis_found');
2712
+ if (text === 'No specs yet. That is valid after the AI-first init flow.') return translator.t('doctor.fix.no_specs_yet');
2713
+ if (text === 'Run `npx create-quiver analyze` to generate docs/PROJECT_MAP.md when you want the visible project map.') return translator.t('doctor.fix.generate_project_map');
2714
+ if (text === 'Analyze the project first: npx create-quiver analyze') return translator.t('doctor.fix.analyze_first');
2715
+ if (text === 'Check the next ready slice: npx create-quiver next') return translator.t('doctor.fix.check_next');
2716
+ if (text === 'Create real specs and slices only after acceptance criteria are approved and the technical plan is reviewed and approved.') return translator.t('doctor.fix.create_specs_after_approval');
2717
+ return formatWarningPrefix(text, translator);
2718
+ };
2577
2719
 
2578
- ux.section('Quiver Doctor');
2720
+ ux.section(translator.t('doctor.title'));
2579
2721
  ux.line('');
2580
- ux.line('Checks');
2722
+ ux.line(translator.t('doctor.checks'));
2581
2723
  for (const check of report.checks) {
2582
- const line = ` ${symbolForStatus(check.status)} ${check.message}`;
2724
+ const line = ` ${symbolForStatus(check.status)} ${localizeDoctorText(check.message)}`;
2583
2725
  ux.line(ux.mode.decoration ? ux.theme.status(colorForStatus(check.status), line) : line);
2584
2726
  }
2585
2727
 
2586
2728
  ux.line('');
2587
- ux.line('Suggested fixes');
2729
+ ux.line(translator.t('doctor.suggested_fixes'));
2588
2730
  for (const fix of report.suggested_fixes) {
2589
- const line = ` ${ux.theme.symbols.bullet} ${fix}`;
2731
+ const line = ` ${ux.theme.symbols.bullet} ${localizeDoctorText(fix)}`;
2590
2732
  ux.line(ux.mode.decoration ? ux.theme.status('command', line) : line);
2591
2733
  }
2592
2734
 
@@ -2640,6 +2782,74 @@ const INIT_PROFILE_OPTIONS = Object.freeze([
2640
2782
  },
2641
2783
  ]);
2642
2784
 
2785
+ function initModeOptions(translator) {
2786
+ return [
2787
+ {
2788
+ label: translator.t('init.mode.existing.label'),
2789
+ value: 'existing',
2790
+ hint: translator.t('init.mode.existing.hint'),
2791
+ default: true,
2792
+ },
2793
+ {
2794
+ label: translator.t('init.mode.new.label'),
2795
+ value: 'new',
2796
+ hint: translator.t('init.mode.new.hint'),
2797
+ },
2798
+ {
2799
+ label: translator.t('init.mode.validate.label'),
2800
+ value: 'validate',
2801
+ hint: translator.t('init.mode.validate.hint'),
2802
+ },
2803
+ ];
2804
+ }
2805
+
2806
+ function methodologyOptions(translator) {
2807
+ return [
2808
+ {
2809
+ label: translator.t('init.methodology.wdd_sdd.label'),
2810
+ value: 'wdd-sdd',
2811
+ hint: translator.t('init.methodology.wdd_sdd.hint'),
2812
+ default: true,
2813
+ },
2814
+ ];
2815
+ }
2816
+
2817
+ function initProfileOptions(translator) {
2818
+ return [
2819
+ {
2820
+ label: 'Default',
2821
+ value: 'default',
2822
+ hint: translator.t('init.profile.default.hint'),
2823
+ default: true,
2824
+ },
2825
+ {
2826
+ label: 'Minimal',
2827
+ value: 'minimal',
2828
+ hint: translator.t('init.profile.minimal.hint'),
2829
+ },
2830
+ {
2831
+ label: 'Full compatibility',
2832
+ value: 'full',
2833
+ hint: translator.t('init.profile.full.hint'),
2834
+ },
2835
+ ];
2836
+ }
2837
+
2838
+ function initLanguageOptions() {
2839
+ return [
2840
+ {
2841
+ label: 'English',
2842
+ value: 'en',
2843
+ hint: 'en',
2844
+ },
2845
+ {
2846
+ label: 'Español',
2847
+ value: 'es',
2848
+ hint: 'es',
2849
+ },
2850
+ ];
2851
+ }
2852
+
2643
2853
  function hasDirectoryContent(dirPath) {
2644
2854
  return fs.existsSync(dirPath)
2645
2855
  && fs.statSync(dirPath).isDirectory()
@@ -2657,8 +2867,16 @@ function assertSupportedMethodology(value) {
2657
2867
  return normalized;
2658
2868
  }
2659
2869
 
2870
+ function resolveExistingProjectLanguage(targetDir) {
2871
+ const config = readProjectLanguageConfig(targetDir);
2872
+ return normalizeLanguage(config.language);
2873
+ }
2874
+
2660
2875
  async function resolveInteractiveInitOptions(args, targetDir, projectName, options = {}) {
2661
2876
  const explicitMethodology = assertSupportedMethodology(args.methodology);
2877
+ const language = normalizeLanguage(options.language || args.language) || DEFAULT_LANGUAGE;
2878
+ const translator = createTranslator(language);
2879
+ const existingProjectLanguage = resolveExistingProjectLanguage(targetDir);
2662
2880
 
2663
2881
  if (args.interactive !== true) {
2664
2882
  return {
@@ -2669,6 +2887,7 @@ async function resolveInteractiveInitOptions(args, targetDir, projectName, optio
2669
2887
  methodology: explicitMethodology,
2670
2888
  minimal: args.initMinimal,
2671
2889
  projectName,
2890
+ language: '',
2672
2891
  };
2673
2892
  }
2674
2893
 
@@ -2702,58 +2921,66 @@ async function resolveInteractiveInitOptions(args, targetDir, projectName, optio
2702
2921
  stdoutIsTTY: options.stdoutIsTTY,
2703
2922
  };
2704
2923
 
2705
- ux.heading('Bienvenido a Quiver');
2706
- const selectedMode = await selectOption('¿Qué querés configurar?', INIT_MODE_OPTIONS, {
2924
+ ux.heading(translator.t('init.heading'));
2925
+ const selectedMode = await selectOption(translator.t('init.prompt.mode'), initModeOptions(translator), {
2707
2926
  ...selectorOptions,
2708
2927
  defaultValue: hasDirectoryContent(targetDir) ? 'existing' : 'new',
2709
2928
  flag: 'init|doctor',
2710
2929
  name: 'init mode',
2711
2930
  });
2712
- const selectedMethodology = await selectOption('¿Qué metodología vas a usar?', METHODOLOGY_OPTIONS, {
2931
+ const selectedMethodology = await selectOption(translator.t('init.prompt.methodology'), methodologyOptions(translator), {
2713
2932
  ...selectorOptions,
2714
2933
  defaultValue: explicitMethodology,
2715
2934
  flag: '--methodology',
2716
2935
  name: 'methodology',
2717
2936
  value: args.methodology || '',
2718
2937
  });
2938
+ const selectedLanguage = await selectOption(translator.t('init.prompt.language'), initLanguageOptions(), {
2939
+ ...selectorOptions,
2940
+ defaultValue: existingProjectLanguage || language,
2941
+ flag: '--lang|config language set',
2942
+ name: 'project language',
2943
+ });
2719
2944
 
2720
2945
  assertSupportedMethodology(selectedMethodology.value);
2721
2946
 
2722
2947
  if (selectedMode.value === 'validate') {
2723
2948
  ux.summary([
2724
- { label: 'Modo', value: 'Solo validar estructura' },
2725
- { label: 'Metodologia', value: selectedMethodology.label },
2726
- { label: 'Comando equivalente', value: 'npx create-quiver doctor' },
2727
- ], { title: 'Configuracion elegida' });
2949
+ { label: translator.t('init.summary.mode'), value: selectedMode.label },
2950
+ { label: translator.t('init.summary.methodology'), value: selectedMethodology.label },
2951
+ { label: translator.t('init.summary.language'), value: selectedLanguage.value },
2952
+ { label: translator.t('init.summary.equivalent_command'), value: 'npx create-quiver doctor' },
2953
+ ], { title: translator.t('init.summary.title') });
2728
2954
  if (!args.force && !args.dryRun) {
2729
- const confirmed = await ux.promptConfirm('Ejecutar Doctor ahora?', { initialValue: true });
2955
+ const confirmed = await ux.promptConfirm(translator.t('init.confirm.doctor'), { initialValue: true });
2730
2956
  if (!confirmed) {
2731
2957
  throw new Error(formatError('init interactive validation declined. No files were written.'));
2732
2958
  }
2733
2959
  }
2734
2960
  return {
2735
2961
  action: 'doctor',
2962
+ language: selectedLanguage.value,
2736
2963
  methodology: selectedMethodology.value,
2737
2964
  projectName,
2738
2965
  };
2739
2966
  }
2740
2967
 
2741
2968
  const defaultProfile = args.initFull ? 'full' : args.initMinimal ? 'minimal' : 'default';
2742
- const selectedProfile = await selectOption('¿Qué contrato inicial querés crear?', INIT_PROFILE_OPTIONS, {
2969
+ const selectedProfile = await selectOption(translator.t('init.prompt.profile'), initProfileOptions(translator), {
2743
2970
  ...selectorOptions,
2744
2971
  defaultValue: defaultProfile,
2745
2972
  flag: '--minimal|--full',
2746
2973
  name: 'init profile',
2747
2974
  });
2748
- const agentGuidance = await selectOption('¿Querés ver el próximo paso para perfiles de agentes?', [
2975
+ const agentGuidance = await selectOption(translator.t('init.prompt.agent_guidance'), [
2749
2976
  {
2750
- label: 'Mostrar comandos sugeridos',
2977
+ label: translator.t('init.agent_guidance.show.label'),
2751
2978
  value: 'show',
2752
- hint: 'No guarda credenciales ni ejecuta proveedores',
2979
+ hint: translator.t('init.agent_guidance.show.hint'),
2753
2980
  default: true,
2754
2981
  },
2755
2982
  {
2756
- label: 'Omitir por ahora',
2983
+ label: translator.t('init.agent_guidance.skip.label'),
2757
2984
  value: 'skip',
2758
2985
  },
2759
2986
  ], {
@@ -2766,28 +2993,30 @@ async function resolveInteractiveInitOptions(args, targetDir, projectName, optio
2766
2993
  full: selectedProfile.value === 'full',
2767
2994
  includeTemplates: args.initIncludeTemplates || selectedProfile.value === 'full',
2768
2995
  legacyScripts: args.initLegacyScripts,
2996
+ language: selectedLanguage.value,
2769
2997
  methodology: selectedMethodology.value,
2770
2998
  minimal: selectedProfile.value === 'minimal',
2771
2999
  projectName,
2772
3000
  };
2773
3001
 
2774
3002
  ux.summary([
2775
- { label: 'Proyecto', value: projectName },
2776
- { label: 'Modo', value: selectedMode.label },
2777
- { label: 'Metodologia', value: selectedMethodology.label },
2778
- { label: 'Perfil', value: selectedProfile.label },
2779
- { label: 'Perfiles de agentes', value: agentGuidance.value === 'show' ? 'mostrar proximo paso' : 'omitir' },
2780
- ], { title: 'Configuracion elegida' });
3003
+ { label: translator.t('init.summary.project'), value: projectName },
3004
+ { label: translator.t('init.summary.mode'), value: selectedMode.label },
3005
+ { label: translator.t('init.summary.methodology'), value: selectedMethodology.label },
3006
+ { label: translator.t('init.summary.language'), value: selectedLanguage.value },
3007
+ { label: translator.t('init.summary.profile'), value: selectedProfile.label },
3008
+ { label: translator.t('init.summary.agent_profiles'), value: agentGuidance.value === 'show' ? translator.t('init.agent_guidance.show.summary') : translator.t('init.agent_guidance.skip.summary') },
3009
+ ], { title: translator.t('init.summary.title') });
2781
3010
 
2782
3011
  if (agentGuidance.value === 'show') {
2783
3012
  ux.nextSteps([
2784
3013
  'npx create-quiver ai agent set planner --provider codex --model gpt-5.5 --dry-run',
2785
3014
  'npx create-quiver ai agent set executor --provider claude --model claude-sonnet-4-6 --dry-run',
2786
- ], { title: 'Despues de inicializar' });
3015
+ ], { title: translator.t('init.next_steps.after_init') });
2787
3016
  }
2788
3017
 
2789
3018
  if (!args.force && !args.dryRun) {
2790
- const confirmed = await ux.promptConfirm(`Inicializar Quiver en ${targetDir}?`, { initialValue: true });
3019
+ const confirmed = await ux.promptConfirm(translator.t('init.confirm.initialize', { path: targetDir }), { initialValue: true });
2791
3020
  if (!confirmed) {
2792
3021
  throw new Error(formatError('init interactive approval declined. No files were written.'));
2793
3022
  }
@@ -2799,6 +3028,46 @@ async function resolveInteractiveInitOptions(args, targetDir, projectName, optio
2799
3028
  };
2800
3029
  }
2801
3030
 
3031
+ function persistInitLanguage(targetDir, initOptions = {}) {
3032
+ if (!initOptions.language) {
3033
+ return null;
3034
+ }
3035
+ writeProjectLanguageConfig(targetDir, initOptions.language);
3036
+ return {
3037
+ language: initOptions.language,
3038
+ path: path.join(targetDir, '.quiver', 'config.json'),
3039
+ };
3040
+ }
3041
+
3042
+ function resolveInitGeneratedLanguage(args, targetDir, initOptions = {}) {
3043
+ if (initOptions.language) {
3044
+ return {
3045
+ configLanguage: initOptions.language,
3046
+ docsLanguage: initOptions.language,
3047
+ };
3048
+ }
3049
+
3050
+ if (args.languageResolution?.source === '--lang') {
3051
+ return {
3052
+ configLanguage: args.language,
3053
+ docsLanguage: args.language,
3054
+ };
3055
+ }
3056
+
3057
+ const existingProjectLanguage = resolveExistingProjectLanguage(targetDir);
3058
+ if (existingProjectLanguage) {
3059
+ return {
3060
+ configLanguage: existingProjectLanguage,
3061
+ docsLanguage: existingProjectLanguage,
3062
+ };
3063
+ }
3064
+
3065
+ return {
3066
+ configLanguage: '',
3067
+ docsLanguage: args.language || DEFAULT_LANGUAGE,
3068
+ };
3069
+ }
3070
+
2802
3071
  function runDoctor(targetDir, options = {}) {
2803
3072
  const projectRoot = resolveTargetRoot(process.cwd(), targetDir);
2804
3073
 
@@ -2837,6 +3106,7 @@ function runDoctor(targetDir, options = {}) {
2837
3106
  console.log(JSON.stringify(commandReport, null, 2));
2838
3107
  } else {
2839
3108
  process.stdout.write(formatDoctorHumanReport(commandReport, {
3109
+ language: options.language,
2840
3110
  noColor: options.noColor,
2841
3111
  unicode: options.unicode,
2842
3112
  }));
@@ -2847,38 +3117,75 @@ function runDoctor(targetDir, options = {}) {
2847
3117
  }
2848
3118
  }
2849
3119
 
2850
- function printInitNextSteps(targetDir, projectName) {
3120
+ function printInitNextSteps(targetDir, projectName, options = {}) {
3121
+ const translator = createTranslator(options.language);
2851
3122
  console.log('');
2852
- console.log('Next steps:');
2853
- console.log(`- Review AGENTS.md, then ${path.join(targetDir, 'docs', 'AI_ONBOARDING_PROMPT.md')}`);
2854
- console.log(`- Review ${path.join(targetDir, 'docs', 'WORKFLOW.md')}`);
2855
- console.log('- Analyze the project with npx create-quiver analyze');
2856
- console.log('- Create real specs and slices after acceptance criteria are approved and the technical plan is reviewed and approved.');
3123
+ console.log(translator.t('init.next_steps.title'));
3124
+ console.log(`- ${translator.t('init.next_steps.review_agents', { path: path.join(targetDir, 'docs', 'AI_ONBOARDING_PROMPT.md') })}`);
3125
+ console.log(`- ${translator.t('init.next_steps.review_workflow', { path: path.join(targetDir, 'docs', 'WORKFLOW.md') })}`);
3126
+ console.log(`- ${translator.t('init.next_steps.analyze')}`);
3127
+ console.log(`- ${translator.t('init.next_steps.create_specs')}`);
2857
3128
  }
2858
3129
 
2859
3130
  async function run(argv) {
2860
- if (argv.length === 1 && argv[0] === 'help') {
2861
- printUsage();
3131
+ let languageArgs;
3132
+ try {
3133
+ languageArgs = extractCliLanguageFlag(argv);
3134
+ } catch (error) {
3135
+ const languageResolution = resolveLanguage({
3136
+ env: process.env,
3137
+ projectRoot: process.cwd(),
3138
+ });
3139
+ setCurrentErrorLanguage(languageResolution.language);
3140
+ throw new Error(formatError(error.message));
3141
+ }
3142
+
3143
+ const normalizedArgv = languageArgs.argv;
3144
+ const languageResolution = resolveLanguage({
3145
+ cliLanguage: languageArgs.language,
3146
+ env: process.env,
3147
+ projectRoot: process.cwd(),
3148
+ });
3149
+ setCurrentErrorLanguage(languageResolution.language);
3150
+
3151
+ if (normalizedArgv.length === 1 && normalizedArgv[0] === 'help') {
3152
+ printUsage(languageResolution.language);
2862
3153
  return;
2863
3154
  }
2864
3155
 
2865
- if (argv.length === 1 && (argv[0] === '-V' || argv[0] === '--version')) {
3156
+ if (normalizedArgv.length === 1 && (normalizedArgv[0] === '-V' || normalizedArgv[0] === '--version')) {
2866
3157
  console.log(CLI_VERSION);
2867
3158
  return;
2868
3159
  }
2869
3160
 
2870
- const args = parseArgs(argv);
3161
+ const args = parseArgs(normalizedArgv, {
3162
+ language: languageArgs.language,
3163
+ });
3164
+ args.languageResolution = languageResolution;
3165
+ args.language = args.languageResolution.language;
2871
3166
 
2872
3167
  if (args.help) {
2873
- printUsage();
3168
+ if (!args.json) {
3169
+ for (const warning of args.languageResolution.warnings || []) {
3170
+ process.stderr.write(`${formatLanguageWarningForCli(warning, args.language)}\n`);
3171
+ }
3172
+ }
3173
+ printUsage(args.language);
2874
3174
  return;
2875
3175
  }
2876
3176
 
2877
3177
  validateUxFlags(args);
2878
3178
 
3179
+ if (!args.json) {
3180
+ for (const warning of args.languageResolution.warnings || []) {
3181
+ process.stderr.write(`${formatLanguageWarningForCli(warning, args.language)}\n`);
3182
+ }
3183
+ }
3184
+
2879
3185
  if (args.mode === 'analyze') {
2880
3186
  runAnalyze(args.targetDir, {
2881
3187
  dryRun: args.dryRun,
3188
+ language: args.language,
2882
3189
  });
2883
3190
  return;
2884
3191
  }
@@ -2886,6 +3193,7 @@ async function run(argv) {
2886
3193
  if (args.mode === 'flow') {
2887
3194
  await runFlow(process.cwd(), {
2888
3195
  json: args.json,
3196
+ language: args.language,
2889
3197
  });
2890
3198
  return;
2891
3199
  }
@@ -2895,6 +3203,7 @@ async function run(argv) {
2895
3203
  details: args.dashboardDetails,
2896
3204
  includeCompleted: args.includeCompleted,
2897
3205
  json: args.json,
3206
+ language: args.language,
2898
3207
  limit: args.dashboardLimit,
2899
3208
  noColor: args.noColor,
2900
3209
  optionErrors: args.dashboardOptionErrors,
@@ -2914,6 +3223,7 @@ async function run(argv) {
2914
3223
  } else {
2915
3224
  process.stdout.write(formatHumanVersionReport(report, {
2916
3225
  env: process.env,
3226
+ language: args.language,
2917
3227
  noColor: args.noColor,
2918
3228
  stdoutIsTTY: Boolean(process.stdout.isTTY),
2919
3229
  }));
@@ -2921,10 +3231,23 @@ async function run(argv) {
2921
3231
  return;
2922
3232
  }
2923
3233
 
3234
+ if (args.mode === 'config') {
3235
+ runConfig(process.cwd(), {
3236
+ command: args.configCommand,
3237
+ global: args.configGlobal,
3238
+ json: args.json,
3239
+ languageResolution: args.languageResolution,
3240
+ section: args.configSection,
3241
+ value: args.configValue,
3242
+ });
3243
+ return;
3244
+ }
3245
+
2924
3246
  if (args.mode === 'plan') {
2925
3247
  runPlan(process.cwd(), {
2926
3248
  includeCompleted: args.includeCompleted,
2927
3249
  json: args.json,
3250
+ language: args.language,
2928
3251
  onlyReady: args.onlyReady,
2929
3252
  specSlug: args.specSlug,
2930
3253
  unicode: args.unicode,
@@ -2951,6 +3274,7 @@ async function run(argv) {
2951
3274
  runAiLifecycleRun(process.cwd(), {
2952
3275
  command: args.aiRunCommand,
2953
3276
  input: args.aiInput || undefined,
3277
+ language: args.language,
2954
3278
  runId: args.aiRunId || undefined,
2955
3279
  specSlug: args.specSlug || undefined,
2956
3280
  });
@@ -2961,12 +3285,14 @@ async function run(argv) {
2961
3285
  runAiActiveSlice(process.cwd(), {
2962
3286
  command: args.aiSecondaryCommand || 'status',
2963
3287
  dryRun: args.dryRun,
3288
+ language: args.language,
2964
3289
  });
2965
3290
  return;
2966
3291
  }
2967
3292
 
2968
3293
  if (args.aiCommand === 'status') {
2969
3294
  runAiLifecycleStatus(process.cwd(), {
3295
+ language: args.language,
2970
3296
  runId: args.aiRunId || undefined,
2971
3297
  });
2972
3298
  return;
@@ -2974,6 +3300,7 @@ async function run(argv) {
2974
3300
 
2975
3301
  if (args.aiCommand === 'resume') {
2976
3302
  runAiLifecycleResume(process.cwd(), {
3303
+ language: args.language,
2977
3304
  runId: args.aiRunId || undefined,
2978
3305
  });
2979
3306
  return;
@@ -2982,6 +3309,7 @@ async function run(argv) {
2982
3309
  if (args.aiCommand === 'inspect') {
2983
3310
  runAiInspect(process.cwd(), {
2984
3311
  includeCompleted: args.includeCompleted,
3312
+ language: args.language,
2985
3313
  });
2986
3314
  return;
2987
3315
  }
@@ -2990,6 +3318,7 @@ async function run(argv) {
2990
3318
  runAiExport(process.cwd(), {
2991
3319
  format: args.formatExplicit ? args.format : 'json',
2992
3320
  includeCompleted: args.includeCompleted,
3321
+ language: args.language,
2993
3322
  });
2994
3323
  return;
2995
3324
  }
@@ -2998,6 +3327,7 @@ async function run(argv) {
2998
3327
  runAiSpecsList(process.cwd(), {
2999
3328
  includeCompleted: args.includeCompleted,
3000
3329
  json: args.json,
3330
+ language: args.language,
3001
3331
  });
3002
3332
  return;
3003
3333
  }
@@ -3006,6 +3336,7 @@ async function run(argv) {
3006
3336
  runAiSlicesList(process.cwd(), {
3007
3337
  includeCompleted: args.includeCompleted,
3008
3338
  json: args.json,
3339
+ language: args.language,
3009
3340
  });
3010
3341
  return;
3011
3342
  }
@@ -3013,6 +3344,7 @@ async function run(argv) {
3013
3344
  if (args.aiCommand === 'trace') {
3014
3345
  runAiTraceReport(process.cwd(), {
3015
3346
  includeCompleted: args.includeCompleted,
3347
+ language: args.language,
3016
3348
  });
3017
3349
  return;
3018
3350
  }
@@ -3020,6 +3352,7 @@ async function run(argv) {
3020
3352
  if (args.aiCommand === 'models') {
3021
3353
  runAiModelsList({
3022
3354
  json: args.json,
3355
+ language: args.language,
3023
3356
  provider: args.aiProviderExplicit ? args.aiProvider : undefined,
3024
3357
  });
3025
3358
  return;
@@ -3034,6 +3367,7 @@ async function run(argv) {
3034
3367
  id: args.aiProfileId || undefined,
3035
3368
  interactive: args.interactive,
3036
3369
  json: args.json,
3370
+ language: args.language,
3037
3371
  label: args.aiLabel || undefined,
3038
3372
  model: args.aiModel || undefined,
3039
3373
  provider: args.aiProviderExplicit ? args.aiProvider : undefined,
@@ -3052,6 +3386,7 @@ async function run(argv) {
3052
3386
  provider: args.aiProvider,
3053
3387
  providerExplicit: args.aiProviderExplicit,
3054
3388
  model: args.aiModel || undefined,
3389
+ language: args.language,
3055
3390
  plannerProfile: args.aiPlannerProfile || undefined,
3056
3391
  role: args.aiRole,
3057
3392
  timeout: args.aiTimeout,
@@ -3064,6 +3399,7 @@ async function run(argv) {
3064
3399
  context: args.aiContext || undefined,
3065
3400
  dryRun: args.dryRun,
3066
3401
  interactive: args.interactive,
3402
+ language: args.language,
3067
3403
  printPrompt: args.aiPrintPrompt,
3068
3404
  provider: args.aiProvider,
3069
3405
  providerExplicit: args.aiProviderExplicit,
@@ -3084,6 +3420,7 @@ async function run(argv) {
3084
3420
  dryRun: args.dryRun,
3085
3421
  input: args.aiInput || undefined,
3086
3422
  phase: args.aiPhase,
3423
+ language: args.language,
3087
3424
  printPrompt: args.aiPrintPrompt,
3088
3425
  provider: args.aiProvider,
3089
3426
  providerExplicit: args.aiProviderExplicit,
@@ -3105,6 +3442,7 @@ async function run(argv) {
3105
3442
  context: args.aiContext || undefined,
3106
3443
  dryRun: args.dryRun,
3107
3444
  input: args.aiInput || undefined,
3445
+ language: args.language,
3108
3446
  printPrompt: args.aiPrintPrompt,
3109
3447
  provider: args.aiProvider,
3110
3448
  providerExplicit: args.aiProviderExplicit,
@@ -3120,6 +3458,7 @@ async function run(argv) {
3120
3458
  context: args.aiContext || undefined,
3121
3459
  dryRun: args.dryRun,
3122
3460
  input: args.aiInput || undefined,
3461
+ language: args.language,
3123
3462
  printPrompt: args.aiPrintPrompt,
3124
3463
  provider: args.aiProvider,
3125
3464
  providerExplicit: args.aiProviderExplicit,
@@ -3138,6 +3477,7 @@ async function run(argv) {
3138
3477
  dryRun: args.dryRun,
3139
3478
  input: args.aiInput || undefined,
3140
3479
  phase: args.aiPhase,
3480
+ language: args.language,
3141
3481
  printPrompt: args.aiPrintPrompt,
3142
3482
  provider: args.aiProvider,
3143
3483
  providerExplicit: args.aiProviderExplicit,
@@ -3154,6 +3494,7 @@ async function run(argv) {
3154
3494
  await runAiApprove(process.cwd(), {
3155
3495
  dryRun: args.dryRun,
3156
3496
  input: args.aiInput || undefined,
3497
+ language: args.language,
3157
3498
  phase: args.aiPhase,
3158
3499
  runId: args.aiRunId || undefined,
3159
3500
  version: args.aiVersion || undefined,
@@ -3162,7 +3503,9 @@ async function run(argv) {
3162
3503
  }
3163
3504
 
3164
3505
  if (args.aiCommand === 'approvals' || args.aiCommand === 'approval-status') {
3165
- await runAiApprovalStatus(process.cwd());
3506
+ await runAiApprovalStatus(process.cwd(), {
3507
+ language: args.language,
3508
+ });
3166
3509
  return;
3167
3510
  }
3168
3511
 
@@ -3174,6 +3517,7 @@ async function run(argv) {
3174
3517
  dryRun: args.dryRun,
3175
3518
  executorProfile: args.aiExecutorProfile || undefined,
3176
3519
  interactive: args.interactive,
3520
+ language: args.language,
3177
3521
  model: args.aiModel || undefined,
3178
3522
  provider: args.aiProvider,
3179
3523
  providerExplicit: args.aiProviderExplicit,
@@ -3186,6 +3530,7 @@ async function run(argv) {
3186
3530
 
3187
3531
  if (args.aiCommand === 'prompt-slice' || args.aiCommand === 'executor-prompt') {
3188
3532
  runAiPromptSlice(process.cwd(), {
3533
+ language: args.language,
3189
3534
  slice: args.aiSlice || undefined,
3190
3535
  });
3191
3536
  return;
@@ -3201,6 +3546,7 @@ async function run(argv) {
3201
3546
  executorProfile: args.aiExecutorProfile || undefined,
3202
3547
  interactive: args.interactive,
3203
3548
  json: args.json,
3549
+ language: args.language,
3204
3550
  model: args.aiModel || undefined,
3205
3551
  mode: args.aiExecutionMode,
3206
3552
  provider: args.aiProvider,
@@ -3229,6 +3575,7 @@ async function run(argv) {
3229
3575
  dryRun: args.dryRun,
3230
3576
  input: args.aiInput || undefined,
3231
3577
  interactive: args.interactive,
3578
+ language: args.language,
3232
3579
  remote: args.aiRemote || undefined,
3233
3580
  review: args.review,
3234
3581
  sshHostAlias: args.aiSshHostAlias || undefined,
@@ -3246,6 +3593,7 @@ async function run(argv) {
3246
3593
  format: args.format,
3247
3594
  includeCompleted: args.includeCompleted,
3248
3595
  json: args.json,
3596
+ language: args.language,
3249
3597
  level: args.level,
3250
3598
  showConflicts: args.showConflicts,
3251
3599
  specSlug: args.specSlug,
@@ -3260,6 +3608,7 @@ async function run(argv) {
3260
3608
  autoStart: args.autoStart,
3261
3609
  includeCompleted: args.includeCompleted,
3262
3610
  json: args.json,
3611
+ language: args.language,
3263
3612
  specSlug: args.specSlug,
3264
3613
  });
3265
3614
  return;
@@ -3268,6 +3617,7 @@ async function run(argv) {
3268
3617
  if (args.mode === 'evidence') {
3269
3618
  const result = runEvidence(process.cwd(), {
3270
3619
  command: args.evidenceArgs,
3620
+ language: args.language,
3271
3621
  maxOutput: args.evidenceMaxOutput || undefined,
3272
3622
  output: args.evidenceOutput || undefined,
3273
3623
  subcommand: args.evidenceCommand,
@@ -3282,6 +3632,7 @@ async function run(argv) {
3282
3632
  command: args.demoCommand,
3283
3633
  demo: args.demoName,
3284
3634
  dryRun: args.dryRun,
3635
+ language: args.language,
3285
3636
  targetRoot: demoTarget,
3286
3637
  });
3287
3638
  return;
@@ -3290,6 +3641,7 @@ async function run(argv) {
3290
3641
  if (args.mode === 'migrate') {
3291
3642
  runMigrate(args.targetDir, {
3292
3643
  dryRun: args.dryRun,
3644
+ language: args.language,
3293
3645
  skipInstall: args.skipInstall,
3294
3646
  });
3295
3647
  return;
@@ -3300,6 +3652,7 @@ async function run(argv) {
3300
3652
  dryRun: args.dryRun,
3301
3653
  fix: args.doctorFix,
3302
3654
  json: args.json,
3655
+ language: args.language,
3303
3656
  noColor: args.noColor,
3304
3657
  unicode: args.unicode,
3305
3658
  });
@@ -3307,7 +3660,10 @@ async function run(argv) {
3307
3660
  }
3308
3661
 
3309
3662
  if (args.mode === 'start-slice') {
3310
- startSlice(args.targetDir, { allowDraft: args.allowDraft });
3663
+ startSlice(args.targetDir, {
3664
+ allowDraft: args.allowDraft,
3665
+ language: args.language,
3666
+ });
3311
3667
  return;
3312
3668
  }
3313
3669
 
@@ -3315,6 +3671,7 @@ async function run(argv) {
3315
3671
  checkSliceReadiness(args.targetDir, {
3316
3672
  baseBranch: args.baseBranchExplicit ? args.aiBaseBranch : '',
3317
3673
  gate: args.gate,
3674
+ language: args.language,
3318
3675
  local: args.checkSliceLocal,
3319
3676
  remote: args.aiRemote,
3320
3677
  strictOverlap: args.strictOverlap,
@@ -3323,7 +3680,7 @@ async function run(argv) {
3323
3680
  }
3324
3681
 
3325
3682
  if (args.mode === 'check-pr') {
3326
- checkPrReadiness(args.targetDir);
3683
+ checkPrReadiness(args.targetDir, { language: args.language });
3327
3684
  return;
3328
3685
  }
3329
3686
 
@@ -3333,16 +3690,21 @@ async function run(argv) {
3333
3690
  if (!handoffInput || handoffInput === '.') {
3334
3691
  throw new Error(formatError('missing handoff or brief path. Use: npx create-quiver check-handoff specs/<spec-slug>/HANDOFF.md or specs/<spec-slug>/slices/<slice-id>/EXECUTION_BRIEF.md'));
3335
3692
  }
3336
- const resolved = checkHandoff(handoffInput, repoRoot);
3337
- console.log(`PASS: ${resolved.label} validated at ${resolved.relativePath}`);
3693
+ const translator = createTranslator(args.language);
3694
+ const resolved = checkHandoff(handoffInput, repoRoot, { language: args.language });
3695
+ console.log(translator.t('handoff.validated', {
3696
+ path: resolved.relativePath,
3697
+ subject: translator.t(`handoff.label.${resolved.kind}`),
3698
+ }));
3338
3699
  return;
3339
3700
  }
3340
3701
 
3341
3702
  if (args.mode === 'new-handoff') {
3342
3703
  const repoRoot = process.cwd();
3343
3704
  const handoffSlug = args.targetDir;
3705
+ const translator = createTranslator(args.language);
3344
3706
  const resolved = scaffoldHandoff(handoffSlug, repoRoot);
3345
- console.log(`PASS: Handoff scaffolded at ${resolved.relativePath}`);
3707
+ console.log(translator.t('handoff.scaffolded', { path: resolved.relativePath }));
3346
3708
  return;
3347
3709
  }
3348
3710
 
@@ -3352,6 +3714,7 @@ async function run(argv) {
3352
3714
  discard: args.discard,
3353
3715
  dryRun: args.dryRun,
3354
3716
  force: args.force,
3717
+ language: args.language,
3355
3718
  });
3356
3719
  return;
3357
3720
  }
@@ -3359,6 +3722,7 @@ async function run(argv) {
3359
3722
  if (args.mode === 'check-scope') {
3360
3723
  checkScope(args.targetDir, {
3361
3724
  baseBranch: args.baseBranchExplicit ? args.aiBaseBranch : '',
3725
+ language: args.language,
3362
3726
  remote: args.aiRemote,
3363
3727
  strict: args.strict,
3364
3728
  });
@@ -3377,6 +3741,7 @@ async function run(argv) {
3377
3741
  dryRun: args.dryRun,
3378
3742
  input: args.aiInput || undefined,
3379
3743
  interactive: args.interactive,
3744
+ language: args.language,
3380
3745
  methodology: args.methodology || undefined,
3381
3746
  review: args.review,
3382
3747
  specSlug: args.specSlug || undefined,
@@ -3393,18 +3758,19 @@ async function run(argv) {
3393
3758
  const report = startSpecWorktree(process.cwd(), args.targetDir, {
3394
3759
  dryRun: args.dryRun,
3395
3760
  });
3396
- process.stdout.write(formatSpecStartResult(report));
3761
+ process.stdout.write(formatSpecStartResult(report, { language: args.language }));
3397
3762
  return;
3398
3763
  }
3399
3764
 
3400
3765
  if (args.specCommand === 'status') {
3401
3766
  const report = buildSpecStatus(process.cwd(), args.targetDir);
3402
- process.stdout.write(formatSpecStatus(report));
3767
+ process.stdout.write(formatSpecStatus(report, { language: args.language }));
3403
3768
  return;
3404
3769
  }
3405
3770
 
3406
3771
  if (args.specCommand === 'validate') {
3407
3772
  runValidateSpec(process.cwd(), args.targetDir, {
3773
+ language: args.language,
3408
3774
  strict: args.strict,
3409
3775
  });
3410
3776
  return;
@@ -3418,7 +3784,7 @@ async function run(argv) {
3418
3784
  force: args.force,
3419
3785
  remote: args.aiRemote,
3420
3786
  });
3421
- process.stdout.write(formatSpecCloseResult(report));
3787
+ process.stdout.write(formatSpecCloseResult(report, { language: args.language }));
3422
3788
  return;
3423
3789
  }
3424
3790
 
@@ -3439,11 +3805,13 @@ async function run(argv) {
3439
3805
  });
3440
3806
  return;
3441
3807
  }
3808
+ const initLanguage = resolveInitGeneratedLanguage(args, targetDir, initOptions);
3442
3809
  const initLayout = buildInitLayout(targetDir, {
3443
3810
  compatibilityAlias: !args.explicitInit,
3444
3811
  dryRun: args.dryRun,
3445
3812
  full: initOptions.full,
3446
3813
  includeTemplates: initOptions.includeTemplates,
3814
+ language: initLanguage.configLanguage,
3447
3815
  legacyScripts: initOptions.legacyScripts,
3448
3816
  minimal: initOptions.minimal,
3449
3817
  projectName: initOptions.projectName,
@@ -3466,10 +3834,12 @@ async function run(argv) {
3466
3834
  }
3467
3835
  runInitDocs(targetDir, initOptions.projectName, {
3468
3836
  includeTemplates: initOptions.includeTemplates,
3837
+ language: initLanguage.docsLanguage,
3469
3838
  legacyScripts: initOptions.legacyScripts,
3470
3839
  profile: initLayout.profile,
3471
3840
  templateRoot,
3472
3841
  });
3842
+ const languageWrite = persistInitLanguage(targetDir, { language: initLanguage.configLanguage });
3473
3843
 
3474
3844
  if (!args.skipInstall) {
3475
3845
  const installResult = installSelfAsDevDep(targetDir, CLI_VERSION);
@@ -3480,14 +3850,19 @@ async function run(argv) {
3480
3850
  }
3481
3851
  }
3482
3852
 
3483
- console.log(`Installed Quiver into ${targetDir}`);
3484
- printInitNextSteps(targetDir, initOptions.projectName);
3853
+ const translator = createTranslator(args.language);
3854
+ console.log(translator.t('init.installed', { path: targetDir }));
3855
+ if (languageWrite) {
3856
+ console.log(translator.t('init.language.saved', { language: languageWrite.language }));
3857
+ }
3858
+ printInitNextSteps(targetDir, initOptions.projectName, { language: args.language });
3485
3859
  } finally {
3486
3860
  fs.rmSync(tempRoot, { recursive: true, force: true });
3487
3861
  }
3488
3862
  }
3489
3863
 
3490
3864
  module.exports = {
3865
+ persistInitLanguage,
3491
3866
  resolveInteractiveInitOptions,
3492
3867
  runAnalyze,
3493
3868
  runDashboard,