mustflow 1.15.97

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 (415) hide show
  1. package/LICENSE +16 -0
  2. package/README.md +422 -0
  3. package/dist/cli/commands/check.js +73 -0
  4. package/dist/cli/commands/classify.js +104 -0
  5. package/dist/cli/commands/context.js +95 -0
  6. package/dist/cli/commands/contract-lint.js +74 -0
  7. package/dist/cli/commands/dashboard.js +654 -0
  8. package/dist/cli/commands/docs.js +382 -0
  9. package/dist/cli/commands/doctor.js +232 -0
  10. package/dist/cli/commands/explain.js +293 -0
  11. package/dist/cli/commands/help.js +148 -0
  12. package/dist/cli/commands/impact.js +120 -0
  13. package/dist/cli/commands/index.js +70 -0
  14. package/dist/cli/commands/init.js +986 -0
  15. package/dist/cli/commands/line-endings.js +102 -0
  16. package/dist/cli/commands/map.js +95 -0
  17. package/dist/cli/commands/run.js +442 -0
  18. package/dist/cli/commands/search.js +166 -0
  19. package/dist/cli/commands/status.js +65 -0
  20. package/dist/cli/commands/update.js +443 -0
  21. package/dist/cli/commands/verify.js +448 -0
  22. package/dist/cli/commands/version-sources.js +79 -0
  23. package/dist/cli/commands/version.js +57 -0
  24. package/dist/cli/i18n/en.js +702 -0
  25. package/dist/cli/i18n/es.js +702 -0
  26. package/dist/cli/i18n/fr.js +702 -0
  27. package/dist/cli/i18n/hi.js +702 -0
  28. package/dist/cli/i18n/ko.js +702 -0
  29. package/dist/cli/i18n/zh.js +702 -0
  30. package/dist/cli/index.js +218 -0
  31. package/dist/cli/lib/agent-context.js +342 -0
  32. package/dist/cli/lib/browser-open.js +58 -0
  33. package/dist/cli/lib/cli-output.js +36 -0
  34. package/dist/cli/lib/command-contract.js +1 -0
  35. package/dist/cli/lib/command-registry.js +107 -0
  36. package/dist/cli/lib/dashboard-html.js +1866 -0
  37. package/dist/cli/lib/dashboard-locale.js +309 -0
  38. package/dist/cli/lib/dashboard-preferences.js +405 -0
  39. package/dist/cli/lib/doc-review-ledger.js +226 -0
  40. package/dist/cli/lib/filesystem.js +125 -0
  41. package/dist/cli/lib/git-changes.js +13 -0
  42. package/dist/cli/lib/i18n.js +55 -0
  43. package/dist/cli/lib/local-index.js +1014 -0
  44. package/dist/cli/lib/locale-tags.js +4 -0
  45. package/dist/cli/lib/manifest-lock.js +131 -0
  46. package/dist/cli/lib/npm-version-check.js +97 -0
  47. package/dist/cli/lib/package-info.js +13 -0
  48. package/dist/cli/lib/preferences-options.js +8 -0
  49. package/dist/cli/lib/project-root.js +23 -0
  50. package/dist/cli/lib/repo-map.js +635 -0
  51. package/dist/cli/lib/reporter.js +8 -0
  52. package/dist/cli/lib/run-receipt.js +1 -0
  53. package/dist/cli/lib/template-i18n.js +265 -0
  54. package/dist/cli/lib/templates.js +188 -0
  55. package/dist/cli/lib/toml.js +1 -0
  56. package/dist/cli/lib/validation.js +1639 -0
  57. package/dist/cli/lib/version-sources.js +1 -0
  58. package/dist/core/authority-resolution.js +155 -0
  59. package/dist/core/change-classification.js +122 -0
  60. package/dist/core/change-verification.js +80 -0
  61. package/dist/core/check-issues.js +67 -0
  62. package/dist/core/command-classification.js +22 -0
  63. package/dist/core/command-contract-rules.js +27 -0
  64. package/dist/core/command-contract-validation.js +197 -0
  65. package/dist/core/command-cwd.js +12 -0
  66. package/dist/core/command-effects.js +182 -0
  67. package/dist/core/command-explanation.js +135 -0
  68. package/dist/core/command-intent-eligibility.js +76 -0
  69. package/dist/core/config-loading.js +54 -0
  70. package/dist/core/contract-lint.js +110 -0
  71. package/dist/core/contract-models.js +53 -0
  72. package/dist/core/dashboard-verification.js +132 -0
  73. package/dist/core/doc-review-triage.js +92 -0
  74. package/dist/core/line-endings.js +144 -0
  75. package/dist/core/public-json-contracts.js +112 -0
  76. package/dist/core/public-surface-explanation.js +49 -0
  77. package/dist/core/release-version-validation.js +53 -0
  78. package/dist/core/retention-explanation.js +74 -0
  79. package/dist/core/retention-policy.js +57 -0
  80. package/dist/core/run-receipt.js +77 -0
  81. package/dist/core/skill-route-alignment.js +100 -0
  82. package/dist/core/skill-route-explanation.js +117 -0
  83. package/dist/core/source-anchor-explanation.js +33 -0
  84. package/dist/core/source-anchor-status.js +269 -0
  85. package/dist/core/source-anchor-symbols.js +181 -0
  86. package/dist/core/source-anchor-validation.js +158 -0
  87. package/dist/core/source-anchors.js +194 -0
  88. package/dist/core/surface-decision-model.js +18 -0
  89. package/dist/core/toml.js +11 -0
  90. package/dist/core/verification-plan.js +41 -0
  91. package/dist/core/verification-scheduler.js +92 -0
  92. package/dist/core/version-impact.js +54 -0
  93. package/dist/core/version-sources.js +235 -0
  94. package/dist/core/version-sync-policy.js +85 -0
  95. package/examples/README.md +13 -0
  96. package/examples/docs-only/README.md +72 -0
  97. package/examples/host-instruction-conflicts/README.md +47 -0
  98. package/examples/minimal-js/README.md +98 -0
  99. package/examples/missing-command-contracts/README.md +70 -0
  100. package/examples/nested-repos/README.md +62 -0
  101. package/package.json +80 -0
  102. package/schemas/README.md +32 -0
  103. package/schemas/change-verification-report.schema.json +319 -0
  104. package/schemas/classify-report.schema.json +113 -0
  105. package/schemas/commands.schema.json +116 -0
  106. package/schemas/context-report.schema.json +341 -0
  107. package/schemas/contract-lint-report.schema.json +61 -0
  108. package/schemas/docs-review-list.schema.json +72 -0
  109. package/schemas/doctor-report.schema.json +175 -0
  110. package/schemas/explain-report.schema.json +471 -0
  111. package/schemas/impact-report.schema.json +121 -0
  112. package/schemas/line-endings-report.schema.json +63 -0
  113. package/schemas/run-receipt.schema.json +75 -0
  114. package/schemas/verify-report.schema.json +67 -0
  115. package/schemas/version-sources-report.schema.json +42 -0
  116. package/templates/default/common/.mustflow/config/commands.toml +251 -0
  117. package/templates/default/common/.mustflow/config/mustflow.toml +424 -0
  118. package/templates/default/common/.mustflow/config/preferences.toml +125 -0
  119. package/templates/default/common/gitignore.mustflow +9 -0
  120. package/templates/default/i18n.toml +483 -0
  121. package/templates/default/locales/en/.mustflow/context/INDEX.md +39 -0
  122. package/templates/default/locales/en/.mustflow/context/PROJECT.md +66 -0
  123. package/templates/default/locales/en/.mustflow/docs/agent-workflow.md +345 -0
  124. package/templates/default/locales/en/.mustflow/skills/INDEX.md +78 -0
  125. package/templates/default/locales/en/.mustflow/skills/adapter-boundary/SKILL.md +193 -0
  126. package/templates/default/locales/en/.mustflow/skills/artifact-integrity-check/SKILL.md +121 -0
  127. package/templates/default/locales/en/.mustflow/skills/behavior-preserving-refactor/SKILL.md +182 -0
  128. package/templates/default/locales/en/.mustflow/skills/code-review/SKILL.md +115 -0
  129. package/templates/default/locales/en/.mustflow/skills/codebase-orientation/SKILL.md +115 -0
  130. package/templates/default/locales/en/.mustflow/skills/command-pattern/SKILL.md +247 -0
  131. package/templates/default/locales/en/.mustflow/skills/composition-over-inheritance/SKILL.md +176 -0
  132. package/templates/default/locales/en/.mustflow/skills/contract-sync-check/SKILL.md +116 -0
  133. package/templates/default/locales/en/.mustflow/skills/date-number-audit/SKILL.md +116 -0
  134. package/templates/default/locales/en/.mustflow/skills/dependency-injection/SKILL.md +161 -0
  135. package/templates/default/locales/en/.mustflow/skills/dependency-reality-check/SKILL.md +115 -0
  136. package/templates/default/locales/en/.mustflow/skills/diff-risk-review/SKILL.md +143 -0
  137. package/templates/default/locales/en/.mustflow/skills/docs-prose-review/SKILL.md +119 -0
  138. package/templates/default/locales/en/.mustflow/skills/docs-update/SKILL.md +100 -0
  139. package/templates/default/locales/en/.mustflow/skills/external-prompt-injection-defense/SKILL.md +124 -0
  140. package/templates/default/locales/en/.mustflow/skills/facade-pattern/SKILL.md +210 -0
  141. package/templates/default/locales/en/.mustflow/skills/failure-triage/SKILL.md +97 -0
  142. package/templates/default/locales/en/.mustflow/skills/instruction-conflict-scope-check/SKILL.md +118 -0
  143. package/templates/default/locales/en/.mustflow/skills/line-ending-hygiene/SKILL.md +111 -0
  144. package/templates/default/locales/en/.mustflow/skills/migration-safety-check/SKILL.md +117 -0
  145. package/templates/default/locales/en/.mustflow/skills/multi-agent-work-coordination/SKILL.md +260 -0
  146. package/templates/default/locales/en/.mustflow/skills/null-object-pattern/SKILL.md +196 -0
  147. package/templates/default/locales/en/.mustflow/skills/pattern-scout/SKILL.md +110 -0
  148. package/templates/default/locales/en/.mustflow/skills/performance-budget-check/SKILL.md +121 -0
  149. package/templates/default/locales/en/.mustflow/skills/project-context-authoring/SKILL.md +107 -0
  150. package/templates/default/locales/en/.mustflow/skills/pure-core-imperative-shell/SKILL.md +212 -0
  151. package/templates/default/locales/en/.mustflow/skills/readme-authoring/SKILL.md +115 -0
  152. package/templates/default/locales/en/.mustflow/skills/repo-improvement-loop/SKILL.md +150 -0
  153. package/templates/default/locales/en/.mustflow/skills/repro-first-debug/SKILL.md +112 -0
  154. package/templates/default/locales/en/.mustflow/skills/requirement-regression-guard/SKILL.md +152 -0
  155. package/templates/default/locales/en/.mustflow/skills/result-option/SKILL.md +186 -0
  156. package/templates/default/locales/en/.mustflow/skills/security-privacy-review/SKILL.md +130 -0
  157. package/templates/default/locales/en/.mustflow/skills/security-regression-tests/SKILL.md +157 -0
  158. package/templates/default/locales/en/.mustflow/skills/skill-authoring/SKILL.md +110 -0
  159. package/templates/default/locales/en/.mustflow/skills/source-freshness-check/SKILL.md +111 -0
  160. package/templates/default/locales/en/.mustflow/skills/state-machine-pattern/SKILL.md +214 -0
  161. package/templates/default/locales/en/.mustflow/skills/strategy-pattern/SKILL.md +215 -0
  162. package/templates/default/locales/en/.mustflow/skills/structure-discovery-gate/SKILL.md +159 -0
  163. package/templates/default/locales/en/.mustflow/skills/test-maintenance/SKILL.md +122 -0
  164. package/templates/default/locales/en/.mustflow/skills/ui-quality-gate/SKILL.md +119 -0
  165. package/templates/default/locales/en/.mustflow/skills/visual-review-artifact/SKILL.md +127 -0
  166. package/templates/default/locales/en/.mustflow/skills/visual-review-artifact/assets/review-template.html +286 -0
  167. package/templates/default/locales/en/.mustflow/skills/visual-review-artifact/resources.toml +7 -0
  168. package/templates/default/locales/en/.mustflow/skills/web-asset-optimization/SKILL.md +108 -0
  169. package/templates/default/locales/en/AGENTS.md +114 -0
  170. package/templates/default/locales/es/.mustflow/context/INDEX.md +39 -0
  171. package/templates/default/locales/es/.mustflow/context/PROJECT.md +63 -0
  172. package/templates/default/locales/es/.mustflow/docs/agent-workflow.md +365 -0
  173. package/templates/default/locales/es/.mustflow/skills/INDEX.md +78 -0
  174. package/templates/default/locales/es/.mustflow/skills/adapter-boundary/SKILL.md +193 -0
  175. package/templates/default/locales/es/.mustflow/skills/artifact-integrity-check/SKILL.md +114 -0
  176. package/templates/default/locales/es/.mustflow/skills/behavior-preserving-refactor/SKILL.md +182 -0
  177. package/templates/default/locales/es/.mustflow/skills/code-review/SKILL.md +115 -0
  178. package/templates/default/locales/es/.mustflow/skills/codebase-orientation/SKILL.md +115 -0
  179. package/templates/default/locales/es/.mustflow/skills/command-pattern/SKILL.md +247 -0
  180. package/templates/default/locales/es/.mustflow/skills/composition-over-inheritance/SKILL.md +176 -0
  181. package/templates/default/locales/es/.mustflow/skills/contract-sync-check/SKILL.md +116 -0
  182. package/templates/default/locales/es/.mustflow/skills/date-number-audit/SKILL.md +116 -0
  183. package/templates/default/locales/es/.mustflow/skills/dependency-injection/SKILL.md +161 -0
  184. package/templates/default/locales/es/.mustflow/skills/dependency-reality-check/SKILL.md +115 -0
  185. package/templates/default/locales/es/.mustflow/skills/diff-risk-review/SKILL.md +136 -0
  186. package/templates/default/locales/es/.mustflow/skills/docs-prose-review/SKILL.md +119 -0
  187. package/templates/default/locales/es/.mustflow/skills/docs-update/SKILL.md +97 -0
  188. package/templates/default/locales/es/.mustflow/skills/external-prompt-injection-defense/SKILL.md +116 -0
  189. package/templates/default/locales/es/.mustflow/skills/facade-pattern/SKILL.md +210 -0
  190. package/templates/default/locales/es/.mustflow/skills/failure-triage/SKILL.md +97 -0
  191. package/templates/default/locales/es/.mustflow/skills/instruction-conflict-scope-check/SKILL.md +118 -0
  192. package/templates/default/locales/es/.mustflow/skills/line-ending-hygiene/SKILL.md +111 -0
  193. package/templates/default/locales/es/.mustflow/skills/migration-safety-check/SKILL.md +117 -0
  194. package/templates/default/locales/es/.mustflow/skills/multi-agent-work-coordination/SKILL.md +260 -0
  195. package/templates/default/locales/es/.mustflow/skills/null-object-pattern/SKILL.md +196 -0
  196. package/templates/default/locales/es/.mustflow/skills/pattern-scout/SKILL.md +110 -0
  197. package/templates/default/locales/es/.mustflow/skills/performance-budget-check/SKILL.md +121 -0
  198. package/templates/default/locales/es/.mustflow/skills/project-context-authoring/SKILL.md +107 -0
  199. package/templates/default/locales/es/.mustflow/skills/pure-core-imperative-shell/SKILL.md +212 -0
  200. package/templates/default/locales/es/.mustflow/skills/readme-authoring/SKILL.md +115 -0
  201. package/templates/default/locales/es/.mustflow/skills/repo-improvement-loop/SKILL.md +150 -0
  202. package/templates/default/locales/es/.mustflow/skills/repro-first-debug/SKILL.md +112 -0
  203. package/templates/default/locales/es/.mustflow/skills/requirement-regression-guard/SKILL.md +152 -0
  204. package/templates/default/locales/es/.mustflow/skills/result-option/SKILL.md +186 -0
  205. package/templates/default/locales/es/.mustflow/skills/security-privacy-review/SKILL.md +116 -0
  206. package/templates/default/locales/es/.mustflow/skills/security-regression-tests/SKILL.md +131 -0
  207. package/templates/default/locales/es/.mustflow/skills/skill-authoring/SKILL.md +110 -0
  208. package/templates/default/locales/es/.mustflow/skills/source-freshness-check/SKILL.md +111 -0
  209. package/templates/default/locales/es/.mustflow/skills/state-machine-pattern/SKILL.md +214 -0
  210. package/templates/default/locales/es/.mustflow/skills/strategy-pattern/SKILL.md +215 -0
  211. package/templates/default/locales/es/.mustflow/skills/structure-discovery-gate/SKILL.md +159 -0
  212. package/templates/default/locales/es/.mustflow/skills/test-maintenance/SKILL.md +122 -0
  213. package/templates/default/locales/es/.mustflow/skills/ui-quality-gate/SKILL.md +117 -0
  214. package/templates/default/locales/es/.mustflow/skills/visual-review-artifact/SKILL.md +127 -0
  215. package/templates/default/locales/es/.mustflow/skills/visual-review-artifact/assets/review-template.html +286 -0
  216. package/templates/default/locales/es/.mustflow/skills/visual-review-artifact/resources.toml +7 -0
  217. package/templates/default/locales/es/.mustflow/skills/web-asset-optimization/SKILL.md +108 -0
  218. package/templates/default/locales/es/AGENTS.md +83 -0
  219. package/templates/default/locales/fr/.mustflow/context/INDEX.md +39 -0
  220. package/templates/default/locales/fr/.mustflow/context/PROJECT.md +63 -0
  221. package/templates/default/locales/fr/.mustflow/docs/agent-workflow.md +368 -0
  222. package/templates/default/locales/fr/.mustflow/skills/INDEX.md +78 -0
  223. package/templates/default/locales/fr/.mustflow/skills/adapter-boundary/SKILL.md +193 -0
  224. package/templates/default/locales/fr/.mustflow/skills/artifact-integrity-check/SKILL.md +114 -0
  225. package/templates/default/locales/fr/.mustflow/skills/behavior-preserving-refactor/SKILL.md +182 -0
  226. package/templates/default/locales/fr/.mustflow/skills/code-review/SKILL.md +115 -0
  227. package/templates/default/locales/fr/.mustflow/skills/codebase-orientation/SKILL.md +115 -0
  228. package/templates/default/locales/fr/.mustflow/skills/command-pattern/SKILL.md +247 -0
  229. package/templates/default/locales/fr/.mustflow/skills/composition-over-inheritance/SKILL.md +176 -0
  230. package/templates/default/locales/fr/.mustflow/skills/contract-sync-check/SKILL.md +116 -0
  231. package/templates/default/locales/fr/.mustflow/skills/date-number-audit/SKILL.md +116 -0
  232. package/templates/default/locales/fr/.mustflow/skills/dependency-injection/SKILL.md +161 -0
  233. package/templates/default/locales/fr/.mustflow/skills/dependency-reality-check/SKILL.md +115 -0
  234. package/templates/default/locales/fr/.mustflow/skills/diff-risk-review/SKILL.md +136 -0
  235. package/templates/default/locales/fr/.mustflow/skills/docs-prose-review/SKILL.md +119 -0
  236. package/templates/default/locales/fr/.mustflow/skills/docs-update/SKILL.md +97 -0
  237. package/templates/default/locales/fr/.mustflow/skills/external-prompt-injection-defense/SKILL.md +116 -0
  238. package/templates/default/locales/fr/.mustflow/skills/facade-pattern/SKILL.md +210 -0
  239. package/templates/default/locales/fr/.mustflow/skills/failure-triage/SKILL.md +97 -0
  240. package/templates/default/locales/fr/.mustflow/skills/instruction-conflict-scope-check/SKILL.md +118 -0
  241. package/templates/default/locales/fr/.mustflow/skills/line-ending-hygiene/SKILL.md +111 -0
  242. package/templates/default/locales/fr/.mustflow/skills/migration-safety-check/SKILL.md +117 -0
  243. package/templates/default/locales/fr/.mustflow/skills/multi-agent-work-coordination/SKILL.md +260 -0
  244. package/templates/default/locales/fr/.mustflow/skills/null-object-pattern/SKILL.md +196 -0
  245. package/templates/default/locales/fr/.mustflow/skills/pattern-scout/SKILL.md +110 -0
  246. package/templates/default/locales/fr/.mustflow/skills/performance-budget-check/SKILL.md +121 -0
  247. package/templates/default/locales/fr/.mustflow/skills/project-context-authoring/SKILL.md +107 -0
  248. package/templates/default/locales/fr/.mustflow/skills/pure-core-imperative-shell/SKILL.md +212 -0
  249. package/templates/default/locales/fr/.mustflow/skills/readme-authoring/SKILL.md +115 -0
  250. package/templates/default/locales/fr/.mustflow/skills/repo-improvement-loop/SKILL.md +150 -0
  251. package/templates/default/locales/fr/.mustflow/skills/repro-first-debug/SKILL.md +112 -0
  252. package/templates/default/locales/fr/.mustflow/skills/requirement-regression-guard/SKILL.md +152 -0
  253. package/templates/default/locales/fr/.mustflow/skills/result-option/SKILL.md +186 -0
  254. package/templates/default/locales/fr/.mustflow/skills/security-privacy-review/SKILL.md +116 -0
  255. package/templates/default/locales/fr/.mustflow/skills/security-regression-tests/SKILL.md +131 -0
  256. package/templates/default/locales/fr/.mustflow/skills/skill-authoring/SKILL.md +110 -0
  257. package/templates/default/locales/fr/.mustflow/skills/source-freshness-check/SKILL.md +111 -0
  258. package/templates/default/locales/fr/.mustflow/skills/state-machine-pattern/SKILL.md +214 -0
  259. package/templates/default/locales/fr/.mustflow/skills/strategy-pattern/SKILL.md +215 -0
  260. package/templates/default/locales/fr/.mustflow/skills/structure-discovery-gate/SKILL.md +159 -0
  261. package/templates/default/locales/fr/.mustflow/skills/test-maintenance/SKILL.md +122 -0
  262. package/templates/default/locales/fr/.mustflow/skills/ui-quality-gate/SKILL.md +117 -0
  263. package/templates/default/locales/fr/.mustflow/skills/visual-review-artifact/SKILL.md +127 -0
  264. package/templates/default/locales/fr/.mustflow/skills/visual-review-artifact/assets/review-template.html +286 -0
  265. package/templates/default/locales/fr/.mustflow/skills/visual-review-artifact/resources.toml +7 -0
  266. package/templates/default/locales/fr/.mustflow/skills/web-asset-optimization/SKILL.md +108 -0
  267. package/templates/default/locales/fr/AGENTS.md +84 -0
  268. package/templates/default/locales/hi/.mustflow/context/INDEX.md +39 -0
  269. package/templates/default/locales/hi/.mustflow/context/PROJECT.md +65 -0
  270. package/templates/default/locales/hi/.mustflow/docs/agent-workflow.md +359 -0
  271. package/templates/default/locales/hi/.mustflow/skills/INDEX.md +78 -0
  272. package/templates/default/locales/hi/.mustflow/skills/adapter-boundary/SKILL.md +193 -0
  273. package/templates/default/locales/hi/.mustflow/skills/artifact-integrity-check/SKILL.md +114 -0
  274. package/templates/default/locales/hi/.mustflow/skills/behavior-preserving-refactor/SKILL.md +182 -0
  275. package/templates/default/locales/hi/.mustflow/skills/code-review/SKILL.md +115 -0
  276. package/templates/default/locales/hi/.mustflow/skills/codebase-orientation/SKILL.md +115 -0
  277. package/templates/default/locales/hi/.mustflow/skills/command-pattern/SKILL.md +247 -0
  278. package/templates/default/locales/hi/.mustflow/skills/composition-over-inheritance/SKILL.md +176 -0
  279. package/templates/default/locales/hi/.mustflow/skills/contract-sync-check/SKILL.md +116 -0
  280. package/templates/default/locales/hi/.mustflow/skills/date-number-audit/SKILL.md +116 -0
  281. package/templates/default/locales/hi/.mustflow/skills/dependency-injection/SKILL.md +161 -0
  282. package/templates/default/locales/hi/.mustflow/skills/dependency-reality-check/SKILL.md +115 -0
  283. package/templates/default/locales/hi/.mustflow/skills/diff-risk-review/SKILL.md +136 -0
  284. package/templates/default/locales/hi/.mustflow/skills/docs-prose-review/SKILL.md +119 -0
  285. package/templates/default/locales/hi/.mustflow/skills/docs-update/SKILL.md +97 -0
  286. package/templates/default/locales/hi/.mustflow/skills/external-prompt-injection-defense/SKILL.md +116 -0
  287. package/templates/default/locales/hi/.mustflow/skills/facade-pattern/SKILL.md +210 -0
  288. package/templates/default/locales/hi/.mustflow/skills/failure-triage/SKILL.md +97 -0
  289. package/templates/default/locales/hi/.mustflow/skills/instruction-conflict-scope-check/SKILL.md +118 -0
  290. package/templates/default/locales/hi/.mustflow/skills/line-ending-hygiene/SKILL.md +111 -0
  291. package/templates/default/locales/hi/.mustflow/skills/migration-safety-check/SKILL.md +117 -0
  292. package/templates/default/locales/hi/.mustflow/skills/multi-agent-work-coordination/SKILL.md +260 -0
  293. package/templates/default/locales/hi/.mustflow/skills/null-object-pattern/SKILL.md +196 -0
  294. package/templates/default/locales/hi/.mustflow/skills/pattern-scout/SKILL.md +110 -0
  295. package/templates/default/locales/hi/.mustflow/skills/performance-budget-check/SKILL.md +121 -0
  296. package/templates/default/locales/hi/.mustflow/skills/project-context-authoring/SKILL.md +107 -0
  297. package/templates/default/locales/hi/.mustflow/skills/pure-core-imperative-shell/SKILL.md +212 -0
  298. package/templates/default/locales/hi/.mustflow/skills/readme-authoring/SKILL.md +115 -0
  299. package/templates/default/locales/hi/.mustflow/skills/repo-improvement-loop/SKILL.md +150 -0
  300. package/templates/default/locales/hi/.mustflow/skills/repro-first-debug/SKILL.md +112 -0
  301. package/templates/default/locales/hi/.mustflow/skills/requirement-regression-guard/SKILL.md +152 -0
  302. package/templates/default/locales/hi/.mustflow/skills/result-option/SKILL.md +186 -0
  303. package/templates/default/locales/hi/.mustflow/skills/security-privacy-review/SKILL.md +116 -0
  304. package/templates/default/locales/hi/.mustflow/skills/security-regression-tests/SKILL.md +131 -0
  305. package/templates/default/locales/hi/.mustflow/skills/skill-authoring/SKILL.md +110 -0
  306. package/templates/default/locales/hi/.mustflow/skills/source-freshness-check/SKILL.md +111 -0
  307. package/templates/default/locales/hi/.mustflow/skills/state-machine-pattern/SKILL.md +214 -0
  308. package/templates/default/locales/hi/.mustflow/skills/strategy-pattern/SKILL.md +215 -0
  309. package/templates/default/locales/hi/.mustflow/skills/structure-discovery-gate/SKILL.md +159 -0
  310. package/templates/default/locales/hi/.mustflow/skills/test-maintenance/SKILL.md +122 -0
  311. package/templates/default/locales/hi/.mustflow/skills/ui-quality-gate/SKILL.md +117 -0
  312. package/templates/default/locales/hi/.mustflow/skills/visual-review-artifact/SKILL.md +127 -0
  313. package/templates/default/locales/hi/.mustflow/skills/visual-review-artifact/assets/review-template.html +286 -0
  314. package/templates/default/locales/hi/.mustflow/skills/visual-review-artifact/resources.toml +7 -0
  315. package/templates/default/locales/hi/.mustflow/skills/web-asset-optimization/SKILL.md +108 -0
  316. package/templates/default/locales/hi/AGENTS.md +83 -0
  317. package/templates/default/locales/ko/.mustflow/context/INDEX.md +39 -0
  318. package/templates/default/locales/ko/.mustflow/context/PROJECT.md +66 -0
  319. package/templates/default/locales/ko/.mustflow/docs/agent-workflow.md +506 -0
  320. package/templates/default/locales/ko/.mustflow/skills/INDEX.md +78 -0
  321. package/templates/default/locales/ko/.mustflow/skills/adapter-boundary/SKILL.md +193 -0
  322. package/templates/default/locales/ko/.mustflow/skills/artifact-integrity-check/SKILL.md +114 -0
  323. package/templates/default/locales/ko/.mustflow/skills/behavior-preserving-refactor/SKILL.md +182 -0
  324. package/templates/default/locales/ko/.mustflow/skills/code-review/SKILL.md +118 -0
  325. package/templates/default/locales/ko/.mustflow/skills/codebase-orientation/SKILL.md +115 -0
  326. package/templates/default/locales/ko/.mustflow/skills/command-pattern/SKILL.md +247 -0
  327. package/templates/default/locales/ko/.mustflow/skills/composition-over-inheritance/SKILL.md +176 -0
  328. package/templates/default/locales/ko/.mustflow/skills/contract-sync-check/SKILL.md +116 -0
  329. package/templates/default/locales/ko/.mustflow/skills/date-number-audit/SKILL.md +116 -0
  330. package/templates/default/locales/ko/.mustflow/skills/dependency-injection/SKILL.md +161 -0
  331. package/templates/default/locales/ko/.mustflow/skills/dependency-reality-check/SKILL.md +115 -0
  332. package/templates/default/locales/ko/.mustflow/skills/diff-risk-review/SKILL.md +136 -0
  333. package/templates/default/locales/ko/.mustflow/skills/docs-prose-review/SKILL.md +119 -0
  334. package/templates/default/locales/ko/.mustflow/skills/docs-update/SKILL.md +107 -0
  335. package/templates/default/locales/ko/.mustflow/skills/external-prompt-injection-defense/SKILL.md +116 -0
  336. package/templates/default/locales/ko/.mustflow/skills/facade-pattern/SKILL.md +210 -0
  337. package/templates/default/locales/ko/.mustflow/skills/failure-triage/SKILL.md +119 -0
  338. package/templates/default/locales/ko/.mustflow/skills/instruction-conflict-scope-check/SKILL.md +118 -0
  339. package/templates/default/locales/ko/.mustflow/skills/line-ending-hygiene/SKILL.md +111 -0
  340. package/templates/default/locales/ko/.mustflow/skills/migration-safety-check/SKILL.md +117 -0
  341. package/templates/default/locales/ko/.mustflow/skills/multi-agent-work-coordination/SKILL.md +259 -0
  342. package/templates/default/locales/ko/.mustflow/skills/null-object-pattern/SKILL.md +196 -0
  343. package/templates/default/locales/ko/.mustflow/skills/pattern-scout/SKILL.md +110 -0
  344. package/templates/default/locales/ko/.mustflow/skills/performance-budget-check/SKILL.md +121 -0
  345. package/templates/default/locales/ko/.mustflow/skills/project-context-authoring/SKILL.md +107 -0
  346. package/templates/default/locales/ko/.mustflow/skills/pure-core-imperative-shell/SKILL.md +212 -0
  347. package/templates/default/locales/ko/.mustflow/skills/readme-authoring/SKILL.md +115 -0
  348. package/templates/default/locales/ko/.mustflow/skills/repo-improvement-loop/SKILL.md +150 -0
  349. package/templates/default/locales/ko/.mustflow/skills/repro-first-debug/SKILL.md +112 -0
  350. package/templates/default/locales/ko/.mustflow/skills/requirement-regression-guard/SKILL.md +152 -0
  351. package/templates/default/locales/ko/.mustflow/skills/result-option/SKILL.md +186 -0
  352. package/templates/default/locales/ko/.mustflow/skills/security-privacy-review/SKILL.md +116 -0
  353. package/templates/default/locales/ko/.mustflow/skills/security-regression-tests/SKILL.md +131 -0
  354. package/templates/default/locales/ko/.mustflow/skills/skill-authoring/SKILL.md +110 -0
  355. package/templates/default/locales/ko/.mustflow/skills/source-freshness-check/SKILL.md +111 -0
  356. package/templates/default/locales/ko/.mustflow/skills/state-machine-pattern/SKILL.md +214 -0
  357. package/templates/default/locales/ko/.mustflow/skills/strategy-pattern/SKILL.md +215 -0
  358. package/templates/default/locales/ko/.mustflow/skills/structure-discovery-gate/SKILL.md +159 -0
  359. package/templates/default/locales/ko/.mustflow/skills/test-maintenance/SKILL.md +130 -0
  360. package/templates/default/locales/ko/.mustflow/skills/ui-quality-gate/SKILL.md +117 -0
  361. package/templates/default/locales/ko/.mustflow/skills/visual-review-artifact/SKILL.md +127 -0
  362. package/templates/default/locales/ko/.mustflow/skills/visual-review-artifact/assets/review-template.html +286 -0
  363. package/templates/default/locales/ko/.mustflow/skills/visual-review-artifact/resources.toml +7 -0
  364. package/templates/default/locales/ko/.mustflow/skills/web-asset-optimization/SKILL.md +108 -0
  365. package/templates/default/locales/ko/AGENTS.md +85 -0
  366. package/templates/default/locales/zh/.mustflow/context/INDEX.md +39 -0
  367. package/templates/default/locales/zh/.mustflow/context/PROJECT.md +64 -0
  368. package/templates/default/locales/zh/.mustflow/docs/agent-workflow.md +310 -0
  369. package/templates/default/locales/zh/.mustflow/skills/INDEX.md +78 -0
  370. package/templates/default/locales/zh/.mustflow/skills/adapter-boundary/SKILL.md +193 -0
  371. package/templates/default/locales/zh/.mustflow/skills/artifact-integrity-check/SKILL.md +114 -0
  372. package/templates/default/locales/zh/.mustflow/skills/behavior-preserving-refactor/SKILL.md +182 -0
  373. package/templates/default/locales/zh/.mustflow/skills/code-review/SKILL.md +115 -0
  374. package/templates/default/locales/zh/.mustflow/skills/codebase-orientation/SKILL.md +115 -0
  375. package/templates/default/locales/zh/.mustflow/skills/command-pattern/SKILL.md +247 -0
  376. package/templates/default/locales/zh/.mustflow/skills/composition-over-inheritance/SKILL.md +176 -0
  377. package/templates/default/locales/zh/.mustflow/skills/contract-sync-check/SKILL.md +116 -0
  378. package/templates/default/locales/zh/.mustflow/skills/date-number-audit/SKILL.md +116 -0
  379. package/templates/default/locales/zh/.mustflow/skills/dependency-injection/SKILL.md +161 -0
  380. package/templates/default/locales/zh/.mustflow/skills/dependency-reality-check/SKILL.md +115 -0
  381. package/templates/default/locales/zh/.mustflow/skills/diff-risk-review/SKILL.md +136 -0
  382. package/templates/default/locales/zh/.mustflow/skills/docs-prose-review/SKILL.md +119 -0
  383. package/templates/default/locales/zh/.mustflow/skills/docs-update/SKILL.md +97 -0
  384. package/templates/default/locales/zh/.mustflow/skills/external-prompt-injection-defense/SKILL.md +116 -0
  385. package/templates/default/locales/zh/.mustflow/skills/facade-pattern/SKILL.md +210 -0
  386. package/templates/default/locales/zh/.mustflow/skills/failure-triage/SKILL.md +96 -0
  387. package/templates/default/locales/zh/.mustflow/skills/instruction-conflict-scope-check/SKILL.md +118 -0
  388. package/templates/default/locales/zh/.mustflow/skills/line-ending-hygiene/SKILL.md +111 -0
  389. package/templates/default/locales/zh/.mustflow/skills/migration-safety-check/SKILL.md +117 -0
  390. package/templates/default/locales/zh/.mustflow/skills/multi-agent-work-coordination/SKILL.md +260 -0
  391. package/templates/default/locales/zh/.mustflow/skills/null-object-pattern/SKILL.md +196 -0
  392. package/templates/default/locales/zh/.mustflow/skills/pattern-scout/SKILL.md +110 -0
  393. package/templates/default/locales/zh/.mustflow/skills/performance-budget-check/SKILL.md +121 -0
  394. package/templates/default/locales/zh/.mustflow/skills/project-context-authoring/SKILL.md +107 -0
  395. package/templates/default/locales/zh/.mustflow/skills/pure-core-imperative-shell/SKILL.md +212 -0
  396. package/templates/default/locales/zh/.mustflow/skills/readme-authoring/SKILL.md +115 -0
  397. package/templates/default/locales/zh/.mustflow/skills/repo-improvement-loop/SKILL.md +150 -0
  398. package/templates/default/locales/zh/.mustflow/skills/repro-first-debug/SKILL.md +112 -0
  399. package/templates/default/locales/zh/.mustflow/skills/requirement-regression-guard/SKILL.md +152 -0
  400. package/templates/default/locales/zh/.mustflow/skills/result-option/SKILL.md +186 -0
  401. package/templates/default/locales/zh/.mustflow/skills/security-privacy-review/SKILL.md +116 -0
  402. package/templates/default/locales/zh/.mustflow/skills/security-regression-tests/SKILL.md +131 -0
  403. package/templates/default/locales/zh/.mustflow/skills/skill-authoring/SKILL.md +110 -0
  404. package/templates/default/locales/zh/.mustflow/skills/source-freshness-check/SKILL.md +111 -0
  405. package/templates/default/locales/zh/.mustflow/skills/state-machine-pattern/SKILL.md +214 -0
  406. package/templates/default/locales/zh/.mustflow/skills/strategy-pattern/SKILL.md +215 -0
  407. package/templates/default/locales/zh/.mustflow/skills/structure-discovery-gate/SKILL.md +159 -0
  408. package/templates/default/locales/zh/.mustflow/skills/test-maintenance/SKILL.md +122 -0
  409. package/templates/default/locales/zh/.mustflow/skills/ui-quality-gate/SKILL.md +117 -0
  410. package/templates/default/locales/zh/.mustflow/skills/visual-review-artifact/SKILL.md +127 -0
  411. package/templates/default/locales/zh/.mustflow/skills/visual-review-artifact/assets/review-template.html +286 -0
  412. package/templates/default/locales/zh/.mustflow/skills/visual-review-artifact/resources.toml +7 -0
  413. package/templates/default/locales/zh/.mustflow/skills/web-asset-optimization/SKILL.md +108 -0
  414. package/templates/default/locales/zh/AGENTS.md +86 -0
  415. package/templates/default/manifest.toml +339 -0
@@ -0,0 +1,986 @@
1
+ import { copyFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { stdin as processStdin, stdout as processStdout } from 'node:process';
4
+ import { createInterface } from 'node:readline/promises';
5
+ import { printUsageError, renderHelp } from '../lib/cli-output.js';
6
+ import { ensureFileTargetInsideWithoutSymlinks, ensureInside, readUtf8FileInsideWithoutSymlinks, writeUtf8FileInsideWithoutSymlinks, } from '../lib/filesystem.js';
7
+ import { localeMessage, t } from '../lib/i18n.js';
8
+ import { isLocaleTag } from '../lib/locale-tags.js';
9
+ import { MANIFEST_LOCK_RELATIVE_PATH, sha256File } from '../lib/manifest-lock.js';
10
+ import { isCommitMessageStyle, isTestAuthoringPolicy } from '../lib/preferences-options.js';
11
+ import { getDefaultTemplate, getTemplateFiles } from '../lib/templates.js';
12
+ const MUSTFLOW_BLOCK_START = '<!-- mustflow:start schema=1 -->';
13
+ const MUSTFLOW_BLOCK_END = '<!-- mustflow:end -->';
14
+ const GITIGNORE_RELATIVE_PATH = '.gitignore';
15
+ const GITIGNORE_FRAGMENT_RELATIVE_PATH = 'gitignore.mustflow';
16
+ const LOCALE_LABELS = {
17
+ en: 'English',
18
+ ko: 'Korean',
19
+ zh: 'Chinese',
20
+ es: 'Spanish',
21
+ fr: 'French',
22
+ hi: 'Hindi',
23
+ };
24
+ function getMustflowRouterBlock(locale) {
25
+ return localeMessage(locale, 'init.routerBlock');
26
+ }
27
+ export function getInitHelp(lang = 'en') {
28
+ return renderHelp({
29
+ usage: 'mf init [options]',
30
+ summary: t(lang, 'init.help.summary'),
31
+ options: [
32
+ { label: '-h, --help', description: t(lang, 'cli.option.help') },
33
+ { label: '--yes', description: t(lang, 'init.help.option.yes') },
34
+ {
35
+ label: '--dry-run',
36
+ description: t(lang, 'init.help.option.dryRun'),
37
+ },
38
+ {
39
+ label: '--interactive',
40
+ description: t(lang, 'init.help.option.interactive'),
41
+ },
42
+ {
43
+ label: '--merge',
44
+ description: t(lang, 'init.help.option.merge'),
45
+ },
46
+ {
47
+ label: '--force',
48
+ description: t(lang, 'init.help.option.force'),
49
+ },
50
+ {
51
+ label: '--profile <name>',
52
+ description: t(lang, 'init.help.option.profile'),
53
+ },
54
+ {
55
+ label: '--locale <locale>',
56
+ description: t(lang, 'init.help.option.locale'),
57
+ },
58
+ {
59
+ label: '--agent-lang <locale>',
60
+ description: t(lang, 'init.help.option.agentLang'),
61
+ },
62
+ {
63
+ label: '--set <key=value>',
64
+ description: t(lang, 'init.help.option.set'),
65
+ },
66
+ {
67
+ label: '--product-source-locale <locale>',
68
+ description: t(lang, 'init.help.option.productSourceLocale'),
69
+ },
70
+ {
71
+ label: '--product-locale <locale>',
72
+ description: t(lang, 'init.help.option.productLocale'),
73
+ },
74
+ ],
75
+ examples: [
76
+ 'mf init --dry-run',
77
+ 'mf init --interactive',
78
+ 'mf init --set git.auto_commit=true',
79
+ 'mf init --profile oss --locale ko',
80
+ 'mf init --profile product --product-source-locale en --product-locale ko-KR',
81
+ ],
82
+ exitCodes: [
83
+ { label: '0', description: t(lang, 'init.help.exit.ok') },
84
+ {
85
+ label: '1',
86
+ description: t(lang, 'init.help.exit.fail'),
87
+ },
88
+ ],
89
+ }, lang);
90
+ }
91
+ function splitLongOption(arg) {
92
+ const equalsIndex = arg.indexOf('=');
93
+ if (equalsIndex === -1) {
94
+ return { name: arg };
95
+ }
96
+ return {
97
+ name: arg.slice(0, equalsIndex),
98
+ value: arg.slice(equalsIndex + 1),
99
+ };
100
+ }
101
+ function readRequiredOptionValue(args, index, parsed, reporter, lang) {
102
+ if (parsed.value !== undefined) {
103
+ if (parsed.value.trim().length === 0) {
104
+ printUsageError(reporter, t(lang, 'cli.error.missingValue', { option: parsed.name }), 'mf init --help', getInitHelp(lang), lang);
105
+ return undefined;
106
+ }
107
+ return parsed.value;
108
+ }
109
+ const next = args[index + 1];
110
+ if (!next || next.startsWith('-')) {
111
+ printUsageError(reporter, t(lang, 'cli.error.missingValue', { option: parsed.name }), 'mf init --help', getInitHelp(lang), lang);
112
+ return undefined;
113
+ }
114
+ return next;
115
+ }
116
+ function parseBoolean(value) {
117
+ if (value === 'true') {
118
+ return true;
119
+ }
120
+ if (value === 'false') {
121
+ return false;
122
+ }
123
+ return undefined;
124
+ }
125
+ function parsePositiveInteger(value) {
126
+ const parsed = Number.parseInt(value, 10);
127
+ if (String(parsed) !== value || parsed <= 0) {
128
+ return undefined;
129
+ }
130
+ return parsed;
131
+ }
132
+ function isSupportedLanguagePreference(value) {
133
+ return ['agent_response', 'docs', 'preserve_existing'].includes(value) || isLocaleTag(value);
134
+ }
135
+ function isSupportedMemorySummaryPreference(value) {
136
+ return ['agent_response', 'docs', 'preserve_existing'].includes(value) || isLocaleTag(value);
137
+ }
138
+ const RELEASE_VERSIONING_PREFERENCE_FIELDS = new Set([
139
+ 'impact_check',
140
+ 'suggest_bump',
141
+ 'auto_bump',
142
+ 'require_user_confirmation',
143
+ 'sync_template_version',
144
+ 'sync_docs_examples',
145
+ 'sync_tests',
146
+ ]);
147
+ const VERIFICATION_SELECTION_STRATEGIES = new Set(['risk_based', 'targeted', 'full']);
148
+ const VERIFICATION_SELECTION_BOOLEAN_FIELDS = new Set([
149
+ 'prefer_related_tests',
150
+ 'skip_docs_only_full_test',
151
+ 'skip_low_risk_code_full_test',
152
+ 'skip_translation_only_full_test',
153
+ 'skip_copy_only_full_test',
154
+ 'report_skipped',
155
+ ]);
156
+ const TEST_AUTHORING_BOOLEAN_FIELDS = new Set(['prefer_existing_tests', 'require_new_test_rationale']);
157
+ function createPreferenceOverride(key, value, reporter, lang) {
158
+ if (key === 'git.auto_stage' || key === 'git.auto_commit') {
159
+ const parsed = parseBoolean(value);
160
+ if (parsed === undefined) {
161
+ reporter.stderr(t(lang, 'init.error.invalidPreferenceValue', { key, value }));
162
+ return undefined;
163
+ }
164
+ return {
165
+ key,
166
+ section: 'git',
167
+ field: key.slice('git.'.length),
168
+ renderedValue: String(parsed),
169
+ };
170
+ }
171
+ if (key === 'git.auto_push') {
172
+ if (value !== 'false') {
173
+ reporter.stderr(t(lang, 'init.error.invalidPreferenceValue', { key, value }));
174
+ return undefined;
175
+ }
176
+ return {
177
+ key,
178
+ section: 'git',
179
+ field: 'auto_push',
180
+ renderedValue: 'false',
181
+ };
182
+ }
183
+ if (key === 'git.commit_message.language') {
184
+ if (!isSupportedLanguagePreference(value)) {
185
+ reporter.stderr(t(lang, 'init.error.invalidPreferenceValue', { key, value }));
186
+ return undefined;
187
+ }
188
+ return {
189
+ key,
190
+ section: 'git.commit_message',
191
+ field: 'language',
192
+ renderedValue: tomlString(value),
193
+ };
194
+ }
195
+ if (key === 'git.commit_message.style') {
196
+ if (!isCommitMessageStyle(value)) {
197
+ reporter.stderr(t(lang, 'init.error.invalidPreferenceValue', { key, value }));
198
+ return undefined;
199
+ }
200
+ return {
201
+ key,
202
+ section: 'git.commit_message',
203
+ field: 'style',
204
+ renderedValue: tomlString(value),
205
+ };
206
+ }
207
+ if (key === 'git.commit_message.max_suggestions') {
208
+ const parsed = parsePositiveInteger(value);
209
+ if (parsed === undefined || parsed > 5) {
210
+ reporter.stderr(t(lang, 'init.error.invalidPreferenceValue', { key, value }));
211
+ return undefined;
212
+ }
213
+ return {
214
+ key,
215
+ section: 'git.commit_message',
216
+ field: 'max_suggestions',
217
+ renderedValue: String(parsed),
218
+ };
219
+ }
220
+ if (key === 'git.commit_message.include_body') {
221
+ if (!['when_non_trivial', 'never', 'always'].includes(value)) {
222
+ reporter.stderr(t(lang, 'init.error.invalidPreferenceValue', { key, value }));
223
+ return undefined;
224
+ }
225
+ return {
226
+ key,
227
+ section: 'git.commit_message',
228
+ field: 'include_body',
229
+ renderedValue: tomlString(value),
230
+ };
231
+ }
232
+ if (key === 'git.commit_message.split_when_multiple_concerns') {
233
+ const parsed = parseBoolean(value);
234
+ if (parsed === undefined) {
235
+ reporter.stderr(t(lang, 'init.error.invalidPreferenceValue', { key, value }));
236
+ return undefined;
237
+ }
238
+ return {
239
+ key,
240
+ section: 'git.commit_message',
241
+ field: 'split_when_multiple_concerns',
242
+ renderedValue: String(parsed),
243
+ };
244
+ }
245
+ if (key === 'reporting.commit_suggestion.enabled') {
246
+ const parsed = parseBoolean(value);
247
+ if (parsed === undefined) {
248
+ reporter.stderr(t(lang, 'init.error.invalidPreferenceValue', { key, value }));
249
+ return undefined;
250
+ }
251
+ return {
252
+ key,
253
+ section: 'reporting.commit_suggestion',
254
+ field: 'enabled',
255
+ renderedValue: String(parsed),
256
+ };
257
+ }
258
+ if (key.startsWith('release.versioning.')) {
259
+ const field = key.slice('release.versioning.'.length);
260
+ if (!RELEASE_VERSIONING_PREFERENCE_FIELDS.has(field)) {
261
+ reporter.stderr(t(lang, 'init.error.unsupportedPreference', { key }));
262
+ return undefined;
263
+ }
264
+ const parsed = parseBoolean(value);
265
+ if (parsed === undefined) {
266
+ reporter.stderr(t(lang, 'init.error.invalidPreferenceValue', { key, value }));
267
+ return undefined;
268
+ }
269
+ return {
270
+ key,
271
+ section: 'release.versioning',
272
+ field,
273
+ renderedValue: String(parsed),
274
+ };
275
+ }
276
+ if (key === 'verification.selection.strategy') {
277
+ if (!VERIFICATION_SELECTION_STRATEGIES.has(value)) {
278
+ reporter.stderr(t(lang, 'init.error.invalidPreferenceValue', { key, value }));
279
+ return undefined;
280
+ }
281
+ return {
282
+ key,
283
+ section: 'verification.selection',
284
+ field: 'strategy',
285
+ renderedValue: tomlString(value),
286
+ };
287
+ }
288
+ if (key.startsWith('verification.selection.')) {
289
+ const field = key.slice('verification.selection.'.length);
290
+ if (!VERIFICATION_SELECTION_BOOLEAN_FIELDS.has(field)) {
291
+ reporter.stderr(t(lang, 'init.error.unsupportedPreference', { key }));
292
+ return undefined;
293
+ }
294
+ const parsed = parseBoolean(value);
295
+ if (parsed === undefined) {
296
+ reporter.stderr(t(lang, 'init.error.invalidPreferenceValue', { key, value }));
297
+ return undefined;
298
+ }
299
+ return {
300
+ key,
301
+ section: 'verification.selection',
302
+ field,
303
+ renderedValue: String(parsed),
304
+ };
305
+ }
306
+ if (key === 'testing.authoring.new_test_policy') {
307
+ if (!isTestAuthoringPolicy(value)) {
308
+ reporter.stderr(t(lang, 'init.error.invalidPreferenceValue', { key, value }));
309
+ return undefined;
310
+ }
311
+ return {
312
+ key,
313
+ section: 'testing.authoring',
314
+ field: 'new_test_policy',
315
+ renderedValue: tomlString(value),
316
+ };
317
+ }
318
+ if (key.startsWith('testing.authoring.')) {
319
+ const field = key.slice('testing.authoring.'.length);
320
+ if (!TEST_AUTHORING_BOOLEAN_FIELDS.has(field)) {
321
+ reporter.stderr(t(lang, 'init.error.unsupportedPreference', { key }));
322
+ return undefined;
323
+ }
324
+ const parsed = parseBoolean(value);
325
+ if (parsed === undefined) {
326
+ reporter.stderr(t(lang, 'init.error.invalidPreferenceValue', { key, value }));
327
+ return undefined;
328
+ }
329
+ return {
330
+ key,
331
+ section: 'testing.authoring',
332
+ field,
333
+ renderedValue: String(parsed),
334
+ };
335
+ }
336
+ if (key === 'language.memory.summary') {
337
+ if (!isSupportedMemorySummaryPreference(value)) {
338
+ reporter.stderr(t(lang, 'init.error.invalidPreferenceValue', { key, value }));
339
+ return undefined;
340
+ }
341
+ return {
342
+ key,
343
+ section: 'language.memory',
344
+ field: 'summary',
345
+ renderedValue: tomlString(value),
346
+ };
347
+ }
348
+ reporter.stderr(t(lang, 'init.error.unsupportedPreference', { key }));
349
+ return undefined;
350
+ }
351
+ function parsePreferenceOverride(raw, reporter, lang) {
352
+ const equalsIndex = raw.indexOf('=');
353
+ if (equalsIndex <= 0 || equalsIndex === raw.length - 1) {
354
+ reporter.stderr(t(lang, 'init.error.invalidPreference', { value: raw }));
355
+ return undefined;
356
+ }
357
+ return createPreferenceOverride(raw.slice(0, equalsIndex), raw.slice(equalsIndex + 1), reporter, lang);
358
+ }
359
+ function parseOptions(args, reporter, lang) {
360
+ let yes = false;
361
+ let dryRun = false;
362
+ let merge = false;
363
+ let force = false;
364
+ let interactive = false;
365
+ let profile;
366
+ let locale;
367
+ let agentLang;
368
+ let productSourceLocale;
369
+ const productLocales = [];
370
+ const preferenceOverrides = [];
371
+ for (let index = 0; index < args.length; index += 1) {
372
+ const arg = args[index];
373
+ if (!arg) {
374
+ continue;
375
+ }
376
+ const parsed = splitLongOption(arg);
377
+ if (['--yes', '--dry-run', '--merge', '--force', '--interactive'].includes(parsed.name) && parsed.value !== undefined) {
378
+ printUsageError(reporter, t(lang, 'cli.error.unexpectedValue', { option: parsed.name }), 'mf init --help', getInitHelp(lang), lang);
379
+ return undefined;
380
+ }
381
+ if (parsed.name === '--yes') {
382
+ yes = true;
383
+ continue;
384
+ }
385
+ if (parsed.name === '--dry-run') {
386
+ dryRun = true;
387
+ continue;
388
+ }
389
+ if (parsed.name === '--merge') {
390
+ merge = true;
391
+ continue;
392
+ }
393
+ if (parsed.name === '--force') {
394
+ force = true;
395
+ continue;
396
+ }
397
+ if (parsed.name === '--interactive') {
398
+ interactive = true;
399
+ continue;
400
+ }
401
+ if (parsed.name === '--set') {
402
+ const value = readRequiredOptionValue(args, index, parsed, reporter, lang);
403
+ if (value === undefined) {
404
+ return undefined;
405
+ }
406
+ if (parsed.value === undefined) {
407
+ index += 1;
408
+ }
409
+ const override = parsePreferenceOverride(value, reporter, lang);
410
+ if (!override) {
411
+ return undefined;
412
+ }
413
+ preferenceOverrides.push(override);
414
+ continue;
415
+ }
416
+ if (['--profile', '--locale', '--agent-lang', '--product-source-locale', '--product-locale'].includes(parsed.name)) {
417
+ const value = readRequiredOptionValue(args, index, parsed, reporter, lang);
418
+ if (value === undefined) {
419
+ return undefined;
420
+ }
421
+ if (parsed.value === undefined) {
422
+ index += 1;
423
+ }
424
+ if (parsed.name === '--profile') {
425
+ profile = value;
426
+ }
427
+ else if (parsed.name === '--locale') {
428
+ locale = value;
429
+ }
430
+ else if (parsed.name === '--agent-lang') {
431
+ agentLang = value;
432
+ }
433
+ else if (parsed.name === '--product-source-locale') {
434
+ productSourceLocale = value;
435
+ }
436
+ else {
437
+ productLocales.push(value);
438
+ }
439
+ continue;
440
+ }
441
+ printUsageError(reporter, t(lang, 'cli.error.unknownOption', { option: arg }), 'mf init --help', getInitHelp(lang), lang);
442
+ return undefined;
443
+ }
444
+ if (merge && force) {
445
+ printUsageError(reporter, t(lang, 'init.error.cannotCombineMergeForce'), 'mf init --help', getInitHelp(lang), lang);
446
+ return undefined;
447
+ }
448
+ if (interactive && yes) {
449
+ printUsageError(reporter, t(lang, 'init.error.cannotCombineInteractiveYes'), 'mf init --help', getInitHelp(lang), lang);
450
+ return undefined;
451
+ }
452
+ return {
453
+ yes,
454
+ dryRun,
455
+ merge,
456
+ force,
457
+ interactive,
458
+ profile,
459
+ locale,
460
+ agentLang,
461
+ productSourceLocale,
462
+ productLocales,
463
+ preferenceOverrides,
464
+ };
465
+ }
466
+ function sameTemplateFileContent(projectRoot, source, targetPath) {
467
+ return (source.content ?? readFileSync(source.sourcePath, 'utf8')) === readUtf8FileInsideWithoutSymlinks(projectRoot, targetPath);
468
+ }
469
+ function formatLocaleChoice(locale) {
470
+ const label = LOCALE_LABELS[locale] ?? locale;
471
+ return `${label} (${locale})`;
472
+ }
473
+ function createPromptReader(reporter) {
474
+ if (!processStdin.isTTY) {
475
+ const lines = readFileSync(0, 'utf8').split(/\r?\n/u);
476
+ return {
477
+ async question(prompt) {
478
+ reporter.stdout(prompt.trimEnd());
479
+ return lines.shift() ?? '';
480
+ },
481
+ close() {
482
+ // No resources are held when stdin is pre-read from a pipe.
483
+ },
484
+ };
485
+ }
486
+ const readline = createInterface({
487
+ input: processStdin,
488
+ output: processStdout,
489
+ });
490
+ return {
491
+ question(prompt) {
492
+ return readline.question(prompt);
493
+ },
494
+ close() {
495
+ readline.close();
496
+ },
497
+ };
498
+ }
499
+ function shouldPromptForInit(args, options) {
500
+ if (options.interactive) {
501
+ return true;
502
+ }
503
+ if (options.yes || args.length > 0) {
504
+ return false;
505
+ }
506
+ return Boolean(processStdin.isTTY && processStdout.isTTY);
507
+ }
508
+ async function promptChoice(reader, reporter, lang, question, choices, defaultValue) {
509
+ const defaultIndex = Math.max(0, choices.findIndex((choice) => choice.value === defaultValue));
510
+ reporter.stdout('');
511
+ reporter.stdout(question);
512
+ for (const [index, choice] of choices.entries()) {
513
+ reporter.stdout(` ${index + 1}. ${choice.label}`);
514
+ }
515
+ for (;;) {
516
+ const answer = (await reader.question(t(lang, 'init.prompt.select', { defaultChoice: defaultIndex + 1 }))).trim();
517
+ if (answer.length === 0) {
518
+ return choices[defaultIndex]?.value ?? defaultValue;
519
+ }
520
+ const selectedIndex = Number.parseInt(answer, 10);
521
+ if (String(selectedIndex) === answer && selectedIndex >= 1 && selectedIndex <= choices.length) {
522
+ return choices[selectedIndex - 1]?.value ?? defaultValue;
523
+ }
524
+ reporter.stderr(t(lang, 'init.prompt.invalidChoice', { count: choices.length }));
525
+ }
526
+ }
527
+ async function promptBoolean(reader, reporter, lang, question, defaultValue) {
528
+ const defaultLabel = defaultValue ? 'Y/n' : 'y/N';
529
+ for (;;) {
530
+ const answer = (await reader.question(`${question} [${defaultLabel}]: `)).trim().toLowerCase();
531
+ if (answer.length === 0) {
532
+ return defaultValue;
533
+ }
534
+ if (answer === 'y' || answer === 'yes' || answer === 'true') {
535
+ return true;
536
+ }
537
+ if (answer === 'n' || answer === 'no' || answer === 'false') {
538
+ return false;
539
+ }
540
+ reporter.stderr(t(lang, 'init.prompt.invalidBoolean'));
541
+ }
542
+ }
543
+ function hasPreferenceOverride(overrides, key) {
544
+ return overrides.some((override) => override.key === key);
545
+ }
546
+ function addPromptedPreferenceOverride(overrides, key, value, reporter, lang) {
547
+ const override = createPreferenceOverride(key, value, reporter, lang);
548
+ if (override) {
549
+ overrides.push(override);
550
+ }
551
+ }
552
+ async function promptInitOptions(template, options, reporter, lang) {
553
+ const reader = createPromptReader(reporter);
554
+ try {
555
+ const preferenceOverrides = [...options.preferenceOverrides];
556
+ const localeChoices = template.manifest.locales.map((locale) => ({
557
+ value: locale,
558
+ label: formatLocaleChoice(locale),
559
+ }));
560
+ const profileChoices = template.manifest.profiles.map((profile) => ({
561
+ value: profile,
562
+ label: profile,
563
+ }));
564
+ const locale = options.locale ?? (await promptChoice(reader, reporter, lang, t(lang, 'init.prompt.locale'), localeChoices, template.manifest.defaultLocale));
565
+ const profile = options.profile ?? (await promptChoice(reader, reporter, lang, t(lang, 'init.prompt.profile'), profileChoices, template.manifest.defaultProfile));
566
+ const agentLanguageChoices = [
567
+ { value: 'same-as-docs', label: t(lang, 'init.prompt.sameAsDocuments') },
568
+ ...localeChoices,
569
+ ];
570
+ const selectedAgentLang = options.agentLang ?? (await promptChoice(reader, reporter, lang, t(lang, 'init.prompt.agentLang'), agentLanguageChoices, 'same-as-docs'));
571
+ const agentLang = selectedAgentLang === 'same-as-docs' ? locale : selectedAgentLang;
572
+ const customizeAdvanced = await promptBoolean(reader, reporter, lang, t(lang, 'init.prompt.advanced'), false);
573
+ if (customizeAdvanced) {
574
+ if (!hasPreferenceOverride(preferenceOverrides, 'git.auto_stage')) {
575
+ addPromptedPreferenceOverride(preferenceOverrides, 'git.auto_stage', String(await promptBoolean(reader, reporter, lang, t(lang, 'init.prompt.autoStage'), false)), reporter, lang);
576
+ }
577
+ if (!hasPreferenceOverride(preferenceOverrides, 'git.auto_commit')) {
578
+ addPromptedPreferenceOverride(preferenceOverrides, 'git.auto_commit', String(await promptBoolean(reader, reporter, lang, t(lang, 'init.prompt.autoCommit'), false)), reporter, lang);
579
+ }
580
+ if (!hasPreferenceOverride(preferenceOverrides, 'git.commit_message.language')) {
581
+ const commitLanguageChoices = [
582
+ { value: 'preserve_existing', label: t(lang, 'init.prompt.preserveExisting') },
583
+ { value: 'same-as-agent', label: t(lang, 'init.prompt.sameAsAgentReports') },
584
+ ...localeChoices,
585
+ ];
586
+ const commitLanguage = await promptChoice(reader, reporter, lang, t(lang, 'init.prompt.commitMessageLanguage'), commitLanguageChoices, 'preserve_existing');
587
+ addPromptedPreferenceOverride(preferenceOverrides, 'git.commit_message.language', commitLanguage === 'same-as-agent' ? agentLang : commitLanguage, reporter, lang);
588
+ }
589
+ if (!hasPreferenceOverride(preferenceOverrides, 'reporting.commit_suggestion.enabled')) {
590
+ addPromptedPreferenceOverride(preferenceOverrides, 'reporting.commit_suggestion.enabled', String(await promptBoolean(reader, reporter, lang, t(lang, 'init.prompt.commitSuggestions'), true)), reporter, lang);
591
+ }
592
+ }
593
+ return {
594
+ ...options,
595
+ profile,
596
+ locale,
597
+ agentLang,
598
+ preferenceOverrides,
599
+ };
600
+ }
601
+ finally {
602
+ reader.close();
603
+ }
604
+ }
605
+ function escapeRegExp(value) {
606
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
607
+ }
608
+ function planStatus(projectRoot, source, targetPath, options) {
609
+ if (!existsSync(targetPath)) {
610
+ return 'create';
611
+ }
612
+ if (sameTemplateFileContent(projectRoot, source, targetPath)) {
613
+ return 'unchanged';
614
+ }
615
+ if (options.force) {
616
+ return 'overwrite';
617
+ }
618
+ if (options.merge && source.relativePath === 'AGENTS.md') {
619
+ return 'merge';
620
+ }
621
+ return 'conflict';
622
+ }
623
+ function writeTemplateFile(projectRoot, source, targetPath) {
624
+ if (source.content !== undefined) {
625
+ writeUtf8FileInsideWithoutSymlinks(projectRoot, targetPath, source.content);
626
+ return;
627
+ }
628
+ ensureFileTargetInsideWithoutSymlinks(projectRoot, targetPath, { allowMissingLeaf: true });
629
+ mkdirSync(path.dirname(targetPath), { recursive: true });
630
+ copyFileSync(source.sourcePath, targetPath);
631
+ }
632
+ function writePlannedFile(projectRoot, file) {
633
+ writeTemplateFile(projectRoot, file, file.targetPath);
634
+ }
635
+ function gitignoreFragmentPath(template) {
636
+ return path.join(template.templateRoot, template.manifest.commonRoot, GITIGNORE_FRAGMENT_RELATIVE_PATH);
637
+ }
638
+ function mergeGitignoreContent(existingContent, fragmentContent) {
639
+ const normalizedFragment = fragmentContent.trim();
640
+ const blockPattern = new RegExp(`${escapeRegExp('# mustflow:start schema=1')}[\\s\\S]*?${escapeRegExp('# mustflow:end')}`, 'u');
641
+ if (blockPattern.test(existingContent)) {
642
+ return `${existingContent.replace(blockPattern, normalizedFragment).trimEnd()}\n`;
643
+ }
644
+ if (existingContent.trim().length === 0) {
645
+ return `${normalizedFragment}\n`;
646
+ }
647
+ return `${existingContent.trimEnd()}\n\n${normalizedFragment}\n`;
648
+ }
649
+ function planGitignoreStatus(projectRoot, sourcePath, targetPath) {
650
+ if (!existsSync(targetPath)) {
651
+ return 'create';
652
+ }
653
+ const mergedContent = mergeGitignoreContent(readUtf8FileInsideWithoutSymlinks(projectRoot, targetPath), readFileSync(sourcePath, 'utf8'));
654
+ return mergedContent === readUtf8FileInsideWithoutSymlinks(projectRoot, targetPath) ? 'unchanged' : 'merge';
655
+ }
656
+ function renderPlanVerb(status) {
657
+ if (status === 'create') {
658
+ return 'create';
659
+ }
660
+ if (status === 'unchanged') {
661
+ return 'leave unchanged';
662
+ }
663
+ if (status === 'merge') {
664
+ return 'merge';
665
+ }
666
+ if (status === 'overwrite') {
667
+ return 'overwrite';
668
+ }
669
+ return 'conflict';
670
+ }
671
+ function printDryRunPlan(plannedFiles, reporter, lang) {
672
+ for (const file of plannedFiles) {
673
+ reporter.stdout(t(lang, 'init.plan.would', { action: renderPlanVerb(file.status), path: file.relativePath }));
674
+ }
675
+ reporter.stdout(t(lang, 'init.plan.noFilesWritten'));
676
+ }
677
+ function printConflictReport(conflicts, reporter, lang) {
678
+ for (const conflict of conflicts) {
679
+ reporter.stderr(t(lang, 'init.conflict', { path: conflict.relativePath }));
680
+ }
681
+ reporter.stderr(t(lang, 'init.plan.noFilesWritten'));
682
+ reporter.stderr(t(lang, 'init.conflictGuidance'));
683
+ }
684
+ function mergeAgentsContent(existingContent, locale) {
685
+ const routerBlock = getMustflowRouterBlock(locale);
686
+ const blockPattern = new RegExp(`${escapeRegExp(MUSTFLOW_BLOCK_START)}[\\s\\S]*?${escapeRegExp(MUSTFLOW_BLOCK_END)}`);
687
+ if (blockPattern.test(existingContent)) {
688
+ return existingContent.replace(blockPattern, routerBlock);
689
+ }
690
+ return `${routerBlock}\n\n${existingContent}`;
691
+ }
692
+ function buildPlannedFiles(template, selectedLocale, targetRoot, options) {
693
+ const selectedProfile = options.profile ?? template.manifest.defaultProfile;
694
+ const plannedFiles = getTemplateFiles(template, selectedLocale, selectedProfile).map((source) => {
695
+ const targetPath = path.join(targetRoot, source.relativePath);
696
+ ensureInside(template.templateRoot, source.sourcePath);
697
+ ensureInside(targetRoot, targetPath);
698
+ ensureFileTargetInsideWithoutSymlinks(targetRoot, targetPath, { allowMissingLeaf: true });
699
+ return {
700
+ relativePath: source.relativePath,
701
+ sourcePath: source.sourcePath,
702
+ sourceKind: source.sourceKind,
703
+ content: source.content,
704
+ targetPath,
705
+ status: planStatus(targetRoot, source, targetPath, options),
706
+ lock: true,
707
+ };
708
+ });
709
+ const sourcePath = gitignoreFragmentPath(template);
710
+ const targetPath = path.join(targetRoot, GITIGNORE_RELATIVE_PATH);
711
+ ensureInside(template.templateRoot, sourcePath);
712
+ ensureInside(targetRoot, targetPath);
713
+ ensureFileTargetInsideWithoutSymlinks(targetRoot, targetPath, { allowMissingLeaf: true });
714
+ plannedFiles.push({
715
+ relativePath: GITIGNORE_RELATIVE_PATH,
716
+ sourcePath,
717
+ sourceKind: 'common',
718
+ targetPath,
719
+ status: planGitignoreStatus(targetRoot, sourcePath, targetPath),
720
+ lock: false,
721
+ });
722
+ return plannedFiles;
723
+ }
724
+ function backupConflictingFiles(projectRoot, conflicts) {
725
+ if (conflicts.length === 0) {
726
+ return undefined;
727
+ }
728
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
729
+ const backupRoot = path.join(projectRoot, '.mustflow', 'backups', timestamp);
730
+ for (const conflict of conflicts) {
731
+ const backupPath = path.join(backupRoot, conflict.relativePath);
732
+ ensureInside(backupRoot, backupPath);
733
+ ensureFileTargetInsideWithoutSymlinks(projectRoot, conflict.targetPath);
734
+ ensureFileTargetInsideWithoutSymlinks(projectRoot, backupPath, { allowMissingLeaf: true });
735
+ mkdirSync(path.dirname(backupPath), { recursive: true });
736
+ copyFileSync(conflict.targetPath, backupPath);
737
+ }
738
+ return backupRoot;
739
+ }
740
+ function tomlString(value) {
741
+ return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
742
+ }
743
+ function tomlArray(values) {
744
+ return `[${values.map(tomlString).join(', ')}]`;
745
+ }
746
+ function validateInitSelection(template, options, reporter, lang) {
747
+ if (options.profile && !template.manifest.profiles.includes(options.profile)) {
748
+ reporter.stderr(t(lang, 'init.error.unsupportedProfile', { profile: options.profile }));
749
+ reporter.stderr(t(lang, 'init.error.supportedProfiles', { profiles: template.manifest.profiles.join(', ') }));
750
+ return false;
751
+ }
752
+ if (options.locale && !template.manifest.locales.includes(options.locale)) {
753
+ reporter.stderr(t(lang, 'init.error.unsupportedLocale', { locale: options.locale }));
754
+ reporter.stderr(t(lang, 'init.error.supportedLocales', { locales: template.manifest.locales.join(', ') }));
755
+ return false;
756
+ }
757
+ for (const [label, value] of [
758
+ ['--agent-lang', options.agentLang],
759
+ ['--product-source-locale', options.productSourceLocale],
760
+ ]) {
761
+ if (value && !isLocaleTag(value)) {
762
+ reporter.stderr(t(lang, 'init.error.invalidLocaleTag', { label, value }));
763
+ return false;
764
+ }
765
+ }
766
+ for (const productLocale of options.productLocales) {
767
+ if (!isLocaleTag(productLocale)) {
768
+ reporter.stderr(t(lang, 'init.error.invalidLocaleTag', { label: '--product-locale', value: productLocale }));
769
+ return false;
770
+ }
771
+ }
772
+ return true;
773
+ }
774
+ function replaceLine(content, pattern, replacement) {
775
+ return pattern.test(content) ? content.replace(pattern, replacement) : `${content.trimEnd()}\n${replacement}\n`;
776
+ }
777
+ function replaceTomlSetting(content, section, field, renderedValue) {
778
+ const sectionPattern = new RegExp(`(^\\[${escapeRegExp(section)}\\]\\n)([\\s\\S]*?)(?=^\\[[^\\]]+\\]\\n|\\s*$)`, 'mu');
779
+ const replacement = `${field} = ${renderedValue}`;
780
+ if (!sectionPattern.test(content)) {
781
+ return `${content.trimEnd()}\n\n[${section}]\n${replacement}\n`;
782
+ }
783
+ return content.replace(sectionPattern, (_match, header, body) => {
784
+ const fieldPattern = new RegExp(`^${escapeRegExp(field)}\\s*=.*$`, 'mu');
785
+ const nextBody = fieldPattern.test(body)
786
+ ? body.replace(fieldPattern, replacement)
787
+ : `${body.trimEnd()}\n${replacement}\n`;
788
+ return `${header}${nextBody}`;
789
+ });
790
+ }
791
+ function removeProductI18nBlock(content) {
792
+ return content.replace(/\n\[product_i18n\]\n[\s\S]*?(?=\n\[[^\]]+\]\n|$)/u, '').trimEnd();
793
+ }
794
+ function renderProductI18nBlock(sourceLocale, targetLocales) {
795
+ return [
796
+ '',
797
+ '[product_i18n]',
798
+ 'enabled = true',
799
+ `source_locale = ${tomlString(sourceLocale)}`,
800
+ `target_locales = ${tomlArray(targetLocales)}`,
801
+ `fallback_locale = ${tomlString(sourceLocale)}`,
802
+ 'locale_tag_format = "bcp47"',
803
+ 'user_facing_text_policy = "externalize"',
804
+ 'hardcoded_user_facing_strings = "avoid"',
805
+ 'translation_policy = "update_source_mark_targets_stale"',
806
+ 'do_not_translate = ["identifiers", "log_keys", "error_codes", "metric_names", "api_field_names"]',
807
+ ].join('\n');
808
+ }
809
+ function applyInitPreferences(projectRoot, preferencesPath, template, options) {
810
+ if (!existsSync(preferencesPath)) {
811
+ return false;
812
+ }
813
+ ensureFileTargetInsideWithoutSymlinks(projectRoot, preferencesPath);
814
+ const original = readUtf8FileInsideWithoutSymlinks(projectRoot, preferencesPath);
815
+ let next = original;
816
+ if (options.profile) {
817
+ next = replaceLine(next, /^profile = ".*"$/mu, `profile = ${tomlString(options.profile)}`);
818
+ }
819
+ if (options.locale) {
820
+ next = replaceLine(next, /^docs = ".*"$/mu, `docs = ${tomlString(options.locale)}`);
821
+ }
822
+ if (options.agentLang) {
823
+ next = replaceLine(next, /^agent_response = ".*"$/mu, `agent_response = ${tomlString(options.agentLang)}`);
824
+ }
825
+ if (options.productSourceLocale || options.productLocales.length > 0) {
826
+ const sourceLocale = options.productSourceLocale ?? options.locale ?? template.manifest.defaultLocale;
827
+ const targetLocales = options.productLocales.length > 0 ? options.productLocales : [sourceLocale];
828
+ next = `${removeProductI18nBlock(next)}\n${renderProductI18nBlock(sourceLocale, targetLocales)}\n`;
829
+ }
830
+ for (const override of options.preferenceOverrides) {
831
+ next = replaceTomlSetting(next, override.section, override.field, override.renderedValue);
832
+ }
833
+ if (next === original) {
834
+ return false;
835
+ }
836
+ writeUtf8FileInsideWithoutSymlinks(projectRoot, preferencesPath, next);
837
+ return true;
838
+ }
839
+ function printInitSelection(template, options, reporter, lang) {
840
+ reporter.stdout(t(lang, 'init.selection.profile', { profile: options.profile ?? template.manifest.defaultProfile }));
841
+ reporter.stdout(t(lang, 'init.selection.locale', { locale: options.locale ?? template.manifest.defaultLocale }));
842
+ if (options.agentLang) {
843
+ reporter.stdout(t(lang, 'init.selection.agentLang', { locale: options.agentLang }));
844
+ }
845
+ if (options.productSourceLocale || options.productLocales.length > 0) {
846
+ reporter.stdout(t(lang, 'init.selection.productSourceLocale', { locale: options.productSourceLocale ?? options.locale ?? template.manifest.defaultLocale }));
847
+ reporter.stdout(t(lang, 'init.selection.productLocales', {
848
+ locales: options.productLocales.length > 0 ? options.productLocales.join(', ') : t(lang, 'init.selection.sourceLocaleOnly'),
849
+ }));
850
+ }
851
+ }
852
+ function lockAction(status) {
853
+ if (status === 'create') {
854
+ return 'created';
855
+ }
856
+ if (status === 'merge') {
857
+ return 'merged';
858
+ }
859
+ if (status === 'overwrite') {
860
+ return 'overwritten';
861
+ }
862
+ return 'unchanged';
863
+ }
864
+ function lockSource(file) {
865
+ if (file.relativePath === 'AGENTS.md' && file.status === 'merge') {
866
+ return 'managed_block';
867
+ }
868
+ return file.sourceKind === 'locale' ? 'template_locale' : 'template_common';
869
+ }
870
+ function renderManifestLock(template, plannedFiles, options, customizedFiles) {
871
+ const lines = [
872
+ 'schema_version = "1"',
873
+ 'generated_by = "mustflow"',
874
+ '',
875
+ '[template]',
876
+ `id = ${tomlString(template.manifest.id)}`,
877
+ `version = ${tomlString(template.manifest.version)}`,
878
+ `profile = ${tomlString(options.profile ?? template.manifest.defaultProfile)}`,
879
+ `locale = ${tomlString(options.locale ?? template.manifest.defaultLocale)}`,
880
+ ];
881
+ if (options.agentLang) {
882
+ lines.push(`agent_lang = ${tomlString(options.agentLang)}`);
883
+ }
884
+ if (options.productSourceLocale || options.productLocales.length > 0) {
885
+ lines.push('', '[product_i18n]');
886
+ lines.push(`source_locale = ${tomlString(options.productSourceLocale ?? options.locale ?? template.manifest.defaultLocale)}`);
887
+ lines.push(`target_locales = ${tomlArray(options.productLocales.length > 0
888
+ ? options.productLocales
889
+ : [options.productSourceLocale ?? options.locale ?? template.manifest.defaultLocale])}`);
890
+ }
891
+ for (const file of plannedFiles.filter((plannedFile) => plannedFile.lock)) {
892
+ lines.push('', `[files.${tomlString(file.relativePath)}]`, `source = ${tomlString(lockSource(file))}`, `last_action = ${tomlString(customizedFiles.has(file.relativePath) ? 'customized' : lockAction(file.status))}`, `content_hash = ${tomlString(sha256File(file.targetPath))}`);
893
+ }
894
+ return `${lines.join('\n')}\n`;
895
+ }
896
+ function writeManifestLock(projectRoot, template, plannedFiles, options, customizedFiles) {
897
+ const lockPath = path.join(projectRoot, MANIFEST_LOCK_RELATIVE_PATH);
898
+ ensureInside(projectRoot, lockPath);
899
+ writeUtf8FileInsideWithoutSymlinks(projectRoot, lockPath, renderManifestLock(template, plannedFiles, options, customizedFiles));
900
+ }
901
+ export async function runInit(args, reporter, lang = 'en') {
902
+ if (args.includes('--help') || args.includes('-h')) {
903
+ reporter.stdout(getInitHelp(lang));
904
+ return 0;
905
+ }
906
+ const parsedOptions = parseOptions(args, reporter, lang);
907
+ if (!parsedOptions) {
908
+ return 1;
909
+ }
910
+ const targetRoot = process.cwd();
911
+ let template;
912
+ try {
913
+ template = getDefaultTemplate();
914
+ }
915
+ catch (error) {
916
+ reporter.stderr(error instanceof Error ? error.message : String(error));
917
+ return 1;
918
+ }
919
+ const options = shouldPromptForInit(args, parsedOptions) ? await promptInitOptions(template, parsedOptions, reporter, lang) : parsedOptions;
920
+ const selectedLocale = options.locale ?? template.manifest.defaultLocale;
921
+ if (!validateInitSelection(template, options, reporter, lang)) {
922
+ return 1;
923
+ }
924
+ let created = 0;
925
+ let unchanged = 0;
926
+ let merged = 0;
927
+ let overwritten = 0;
928
+ const plannedFiles = buildPlannedFiles(template, selectedLocale, targetRoot, options);
929
+ const conflicts = plannedFiles.filter((file) => file.status === 'conflict');
930
+ const forceConflicts = plannedFiles.filter((file) => file.status === 'overwrite');
931
+ if (options.dryRun) {
932
+ printInitSelection(template, options, reporter, lang);
933
+ printDryRunPlan(plannedFiles, reporter, lang);
934
+ return 0;
935
+ }
936
+ if (conflicts.length > 0) {
937
+ printConflictReport(conflicts, reporter, lang);
938
+ return 1;
939
+ }
940
+ const backupRoot = options.force ? backupConflictingFiles(targetRoot, forceConflicts) : undefined;
941
+ if (backupRoot) {
942
+ reporter.stdout(t(lang, 'init.backup.conflicts', {
943
+ count: forceConflicts.length,
944
+ fileWord: t(lang, forceConflicts.length === 1 ? 'init.fileWord.singular' : 'init.fileWord.plural'),
945
+ path: backupRoot,
946
+ }));
947
+ }
948
+ for (const file of plannedFiles) {
949
+ if (file.status === 'create') {
950
+ writePlannedFile(targetRoot, file);
951
+ created += 1;
952
+ reporter.stdout(t(lang, 'init.action.created', { path: file.relativePath }));
953
+ continue;
954
+ }
955
+ if (file.status === 'unchanged') {
956
+ unchanged += 1;
957
+ reporter.stdout(t(lang, 'init.action.unchanged', { path: file.relativePath }));
958
+ continue;
959
+ }
960
+ if (file.status === 'merge') {
961
+ ensureFileTargetInsideWithoutSymlinks(targetRoot, file.targetPath);
962
+ const mergedContent = file.relativePath === GITIGNORE_RELATIVE_PATH
963
+ ? mergeGitignoreContent(readUtf8FileInsideWithoutSymlinks(targetRoot, file.targetPath), readFileSync(file.sourcePath, 'utf8'))
964
+ : mergeAgentsContent(readUtf8FileInsideWithoutSymlinks(targetRoot, file.targetPath), selectedLocale);
965
+ writeUtf8FileInsideWithoutSymlinks(targetRoot, file.targetPath, mergedContent);
966
+ merged += 1;
967
+ reporter.stdout(t(lang, 'init.action.merged', { path: file.relativePath }));
968
+ continue;
969
+ }
970
+ if (file.status === 'overwrite') {
971
+ writePlannedFile(targetRoot, file);
972
+ overwritten += 1;
973
+ reporter.stdout(t(lang, 'init.action.overwrote', { path: file.relativePath }));
974
+ }
975
+ }
976
+ const customizedFiles = new Set();
977
+ const preferencesPath = path.join(targetRoot, '.mustflow', 'config', 'preferences.toml');
978
+ if (applyInitPreferences(targetRoot, preferencesPath, template, options)) {
979
+ customizedFiles.add('.mustflow/config/preferences.toml');
980
+ reporter.stdout(t(lang, 'init.action.customizedPreferences'));
981
+ }
982
+ writeManifestLock(targetRoot, template, plannedFiles, options, customizedFiles);
983
+ reporter.stdout(t(lang, 'init.action.wrote', { path: MANIFEST_LOCK_RELATIVE_PATH }));
984
+ reporter.stdout(t(lang, 'init.complete', { created, merged, overwritten, unchanged }));
985
+ return 0;
986
+ }