@orkastery/cli 0.5.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (502) hide show
  1. package/adapters/README.md +18 -0
  2. package/adapters/claude-code/.claude-plugin/plugin.json +1 -0
  3. package/adapters/claude-code/README.md +195 -5
  4. package/adapters/claude-code/agents/ork-check.md +1 -0
  5. package/adapters/claude-code/agents/ork-go.md +1 -0
  6. package/adapters/claude-code/agents/ork-goal.md +1 -0
  7. package/adapters/claude-code/agents/ork-master.md +1 -0
  8. package/adapters/claude-code/agents/ork-plan.md +1 -0
  9. package/adapters/claude-code/agents/ork-ship.md +1 -0
  10. package/adapters/claude-code/hooks/hooks.json +2 -1
  11. package/adapters/claude-code/hooks/ork-guard.js +15 -1
  12. package/adapters/claude-code/hooks/ork-resposta.js +91 -0
  13. package/adapters/claude-code/hooks/ork-sensor.js +18 -2
  14. package/adapters/claude-code/hooks/quota-signal.js +14 -0
  15. package/adapters/claude-code/mods/autoridade.json +56 -0
  16. package/adapters/claude-code/mods/ork-clima/.claude-plugin/plugin.json +14 -0
  17. package/adapters/claude-code/mods/ork-clima/hooks/contas.ts +283 -0
  18. package/adapters/claude-code/mods/ork-clima/hooks/hooks.json +3 -0
  19. package/adapters/claude-code/mods/ork-clima/hooks/previsao.ts +393 -0
  20. package/adapters/claude-code/mods/ork-clima/hooks/register.ts +205 -0
  21. package/adapters/claude-code/mods/ork-clima/orkastery-mod.json +5 -0
  22. package/adapters/claude-code/mods/ork-clima/types/index.d.ts +80 -0
  23. package/adapters/claude-code/mods/ork-freio/.claude-plugin/plugin.json +14 -0
  24. package/adapters/claude-code/mods/ork-freio/hooks/carga.ts +160 -0
  25. package/adapters/claude-code/mods/ork-freio/hooks/conferencia.ts +309 -0
  26. package/adapters/claude-code/mods/ork-freio/hooks/hooks.json +3 -0
  27. package/adapters/claude-code/mods/ork-freio/hooks/lote.ts +270 -0
  28. package/adapters/claude-code/mods/ork-freio/hooks/register.ts +285 -0
  29. package/adapters/claude-code/mods/ork-freio/orkastery-mod.json +5 -0
  30. package/adapters/claude-code/mods/ork-freio/types/index.d.ts +127 -0
  31. package/adapters/claude-code/mods/ork-mensageiro/.claude-plugin/plugin.json +14 -0
  32. package/adapters/claude-code/mods/ork-mensageiro/hooks/caixa.ts +215 -0
  33. package/adapters/claude-code/mods/ork-mensageiro/hooks/hooks.json +3 -0
  34. package/adapters/claude-code/mods/ork-mensageiro/hooks/painel.tsx +165 -0
  35. package/adapters/claude-code/mods/ork-mensageiro/hooks/recepcao.ts +256 -0
  36. package/adapters/claude-code/mods/ork-mensageiro/hooks/register.tsx +481 -0
  37. package/adapters/claude-code/mods/ork-mensageiro/orkastery-mod.json +5 -0
  38. package/adapters/claude-code/mods/ork-mensageiro/types/index.d.ts +85 -0
  39. package/adapters/claude-code/mods/ork-mesa/.claude-plugin/plugin.json +14 -0
  40. package/adapters/claude-code/mods/ork-mesa/hooks/cartoes.tsx +246 -0
  41. package/adapters/claude-code/mods/ork-mesa/hooks/decidir.ts +110 -0
  42. package/adapters/claude-code/mods/ork-mesa/hooks/fila.ts +253 -0
  43. package/adapters/claude-code/mods/ork-mesa/hooks/hooks.json +3 -0
  44. package/adapters/claude-code/mods/ork-mesa/hooks/obvia.ts +98 -0
  45. package/adapters/claude-code/mods/ork-mesa/hooks/register.tsx +493 -0
  46. package/adapters/claude-code/mods/ork-mesa/orkastery-mod.json +5 -0
  47. package/adapters/claude-code/mods/ork-mesa/types/index.d.ts +131 -0
  48. package/adapters/claude-code/mods/ork-pista/.claude-plugin/plugin.json +14 -0
  49. package/adapters/claude-code/mods/ork-pista/hooks/acoes.ts +71 -0
  50. package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +121 -0
  51. package/adapters/claude-code/mods/ork-pista/hooks/hooks.json +3 -0
  52. package/adapters/claude-code/mods/ork-pista/hooks/pista.tsx +356 -0
  53. package/adapters/claude-code/mods/ork-pista/hooks/register.tsx +439 -0
  54. package/adapters/claude-code/mods/ork-pista/orkastery-mod.json +5 -0
  55. package/adapters/claude-code/mods/ork-pista/types/index.d.ts +85 -0
  56. package/adapters/claude-code/mods/ork-ponte/.claude-plugin/plugin.json +13 -0
  57. package/adapters/claude-code/mods/ork-ponte/hooks/faixa.tsx +57 -0
  58. package/adapters/claude-code/mods/ork-ponte/hooks/guarda.ts +410 -0
  59. package/adapters/claude-code/mods/ork-ponte/hooks/hooks.json +3 -0
  60. package/adapters/claude-code/mods/ork-ponte/hooks/mostrado.ts +55 -0
  61. package/adapters/claude-code/mods/ork-ponte/hooks/nucleo.ts +157 -0
  62. package/adapters/claude-code/mods/ork-ponte/hooks/papel.ts +42 -0
  63. package/adapters/claude-code/mods/ork-ponte/hooks/register.ts +331 -0
  64. package/adapters/claude-code/mods/ork-ponte/hooks/vigia.ts +76 -0
  65. package/adapters/claude-code/mods/ork-ponte/orkastery-mod.json +5 -0
  66. package/adapters/claude-code/mods/ork-ponte/types/index.d.ts +178 -0
  67. package/adapters/claude-code/mods/ork-portao/.claude-plugin/plugin.json +14 -0
  68. package/adapters/claude-code/mods/ork-portao/hooks/hooks.json +3 -0
  69. package/adapters/claude-code/mods/ork-portao/hooks/lease.ts +201 -0
  70. package/adapters/claude-code/mods/ork-portao/hooks/plano.ts +304 -0
  71. package/adapters/claude-code/mods/ork-portao/hooks/register.ts +339 -0
  72. package/adapters/claude-code/mods/ork-portao/hooks/verify.ts +152 -0
  73. package/adapters/claude-code/mods/ork-portao/orkastery-mod.json +5 -0
  74. package/adapters/claude-code/mods/ork-portao/types/index.d.ts +60 -0
  75. package/adapters/claude-code/mods/ork-radar/.claude-plugin/plugin.json +14 -0
  76. package/adapters/claude-code/mods/ork-radar/hooks/colisao.ts +420 -0
  77. package/adapters/claude-code/mods/ork-radar/hooks/hooks.json +3 -0
  78. package/adapters/claude-code/mods/ork-radar/hooks/mapa.tsx +322 -0
  79. package/adapters/claude-code/mods/ork-radar/hooks/register.tsx +470 -0
  80. package/adapters/claude-code/mods/ork-radar/orkastery-mod.json +5 -0
  81. package/adapters/claude-code/mods/ork-radar/types/index.d.ts +72 -0
  82. package/adapters/claude-code/mods/ork-ritual/.claude-plugin/plugin.json +14 -0
  83. package/adapters/claude-code/mods/ork-ritual/hooks/hooks.json +3 -0
  84. package/adapters/claude-code/mods/ork-ritual/hooks/nota.ts +88 -0
  85. package/adapters/claude-code/mods/ork-ritual/hooks/register.tsx +494 -0
  86. package/adapters/claude-code/mods/ork-ritual/hooks/replay.tsx +271 -0
  87. package/adapters/claude-code/mods/ork-ritual/hooks/ritual.ts +218 -0
  88. package/adapters/claude-code/mods/ork-ritual/orkastery-mod.json +5 -0
  89. package/adapters/claude-code/mods/ork-ritual/types/index.d.ts +106 -0
  90. package/adapters/claude-code/mods/ork-sentinela/.claude-plugin/plugin.json +14 -0
  91. package/adapters/claude-code/mods/ork-sentinela/hooks/alertas.ts +85 -0
  92. package/adapters/claude-code/mods/ork-sentinela/hooks/despacho.ts +156 -0
  93. package/adapters/claude-code/mods/ork-sentinela/hooks/hooks.json +3 -0
  94. package/adapters/claude-code/mods/ork-sentinela/hooks/register.ts +511 -0
  95. package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +186 -0
  96. package/adapters/claude-code/mods/ork-sentinela/orkastery-mod.json +5 -0
  97. package/adapters/claude-code/mods/ork-sentinela/types/index.d.ts +65 -0
  98. package/adapters/claude-code/mods/ork-torre/.claude-plugin/plugin.json +14 -0
  99. package/adapters/claude-code/mods/ork-torre/hooks/agenda.ts +60 -0
  100. package/adapters/claude-code/mods/ork-torre/hooks/detalhe.tsx +236 -0
  101. package/adapters/claude-code/mods/ork-torre/hooks/frases.ts +42 -0
  102. package/adapters/claude-code/mods/ork-torre/hooks/hooks.json +3 -0
  103. package/adapters/claude-code/mods/ork-torre/hooks/painel.tsx +344 -0
  104. package/adapters/claude-code/mods/ork-torre/hooks/rede.ts +97 -0
  105. package/adapters/claude-code/mods/ork-torre/hooks/register.tsx +437 -0
  106. package/adapters/claude-code/mods/ork-torre/orkastery-mod.json +5 -0
  107. package/adapters/claude-code/mods/ork-torre/types/index.d.ts +108 -0
  108. package/adapters/codex/skills/ork/SKILL.md +2 -0
  109. package/adapters/hermes/README.md +64 -1
  110. package/adapters/hermes/bin/ork-conhecimento-colecoes.sh +14 -0
  111. package/adapters/hermes/bin/ork-conhecimento-listar.sh +15 -0
  112. package/adapters/hermes/bin/ork-conhecimento-mostrar.sh +16 -0
  113. package/adapters/hermes/bin/ork-conhecimento-verificar.sh +15 -0
  114. package/adapters/hermes/bin/ork-vigia-batida.py +127 -0
  115. package/adapters/hermes/hermes.plugin.json +4 -0
  116. package/adapters/hermes/hitl-ingress/__init__.py +101 -8
  117. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +3 -3
  118. package/adapters/openclaw/README.md +83 -10
  119. package/adapters/openclaw/bin/ork-vigia-batida.js +86 -0
  120. package/adapters/openclaw/dist/hitl-ingress.js +106 -9
  121. package/adapters/openclaw/dist/index.js +86 -0
  122. package/adapters/openclaw/openclaw.plugin.json +34 -4
  123. package/adapters/openclaw/package.json +2 -2
  124. package/adapters/openclaw/src/hitl-ingress.ts +103 -9
  125. package/adapters/openclaw/src/index.ts +94 -0
  126. package/assets/adapters-en/claude-code/README.md +403 -0
  127. package/assets/adapters-en/claude-code/agents/ork-check.md +33 -0
  128. package/assets/adapters-en/claude-code/agents/ork-go.md +33 -0
  129. package/assets/adapters-en/claude-code/agents/ork-goal.md +34 -0
  130. package/assets/adapters-en/claude-code/agents/ork-master.md +35 -0
  131. package/assets/adapters-en/claude-code/agents/ork-plan.md +33 -0
  132. package/assets/adapters-en/claude-code/agents/ork-ship.md +33 -0
  133. package/assets/adapters-en/claude-code/commands/check.md +46 -0
  134. package/assets/adapters-en/claude-code/commands/go.md +46 -0
  135. package/assets/adapters-en/claude-code/commands/goal.md +55 -0
  136. package/assets/adapters-en/claude-code/commands/master.md +54 -0
  137. package/assets/adapters-en/claude-code/commands/onboarding.md +22 -0
  138. package/assets/adapters-en/claude-code/commands/ork.md +126 -0
  139. package/assets/adapters-en/claude-code/commands/plan.md +47 -0
  140. package/assets/adapters-en/claude-code/commands/ship.md +45 -0
  141. package/assets/adapters-en/codex/skills/ork/SKILL.md +85 -0
  142. package/assets/adapters-en/hermes/README.md +273 -0
  143. package/assets/adapters-en/hermes/skills/orkastery-devmaster/SKILL.md +169 -0
  144. package/assets/docs-en/markdownlint-cli2.jsonc +22 -0
  145. package/assets/docs-en/padroes/documentacao-de-produto.md +135 -0
  146. package/assets/docs-en/padroes/roadmap-de-produto.md +100 -0
  147. package/assets/docs-en/produto/README.md +14 -0
  148. package/assets/docs-en/produto/_modelo-feature.md +62 -0
  149. package/assets/docs-en/roadmap/README.md +14 -0
  150. package/assets/docs-en/roadmap/_modelo-item.md +75 -0
  151. package/assets/references-en/README.md +25 -0
  152. package/assets/references-en/code-review-axes.md +82 -0
  153. package/assets/references-en/definition-of-done.md +74 -0
  154. package/assets/references-en/performance-checklist.md +53 -0
  155. package/assets/references-en/security-checklist.md +101 -0
  156. package/assets/references-en/testing-patterns.md +51 -0
  157. package/assets/security-scan/defaults/.golangci.yml +2 -0
  158. package/assets/security-scan/defaults/eslint.config.mjs +11 -0
  159. package/assets/security-scan/defaults/gitleaks.toml +3 -0
  160. package/assets/security-scan/defaults/ruff.toml +1 -0
  161. package/assets/security-scan/tools-agil.json +87 -0
  162. package/assets/security-scan/tools.json +625 -0
  163. package/assets/skills-en/core/onboarding/SKILL.md +58 -0
  164. package/assets/skills-en/core/orkastery-bootstrap/SKILL.md +119 -0
  165. package/assets/skills-en/core/thread-state/SKILL.md +88 -0
  166. package/assets/skills-en/governance/decision-triage/SKILL.md +65 -0
  167. package/assets/skills-en/governance/narrative-guardian/SKILL.md +66 -0
  168. package/assets/skills-en/governance/roadmap-keeper/SKILL.md +60 -0
  169. package/assets/skills-en/governance/scope-check-capability-map/SKILL.md +71 -0
  170. package/assets/skills-en/observability/thread-tracing/SKILL.md +63 -0
  171. package/assets/skills-en/phases/check-quality/SKILL.md +103 -0
  172. package/assets/skills-en/phases/go-implementation/SKILL.md +78 -0
  173. package/assets/skills-en/phases/goal-definition/SKILL.md +69 -0
  174. package/assets/skills-en/phases/master-metrics/SKILL.md +72 -0
  175. package/assets/skills-en/phases/plan-specification/SKILL.md +67 -0
  176. package/assets/skills-en/phases/security-remediation/SKILL.md +70 -0
  177. package/assets/skills-en/phases/ship-release/SKILL.md +71 -0
  178. package/assets/skills-en/reviewers/code-reviewer/SKILL.md +61 -0
  179. package/assets/skills-en/reviewers/security-auditor/SKILL.md +93 -0
  180. package/assets/skills-en/reviewers/test-engineer/SKILL.md +66 -0
  181. package/assets/skills-en/reviewers/web-performance-auditor/SKILL.md +63 -0
  182. package/dist/adapters/claude-bg.js +193 -15
  183. package/dist/adapters/codex-controller-worker.js +12 -5
  184. package/dist/adapters/codex-events.js +16 -4
  185. package/dist/adapters/codex.js +13 -2
  186. package/dist/agents-md.js +24 -15
  187. package/dist/atualizar-branch.js +245 -0
  188. package/dist/auditoria.js +13 -11
  189. package/dist/auditrun.js +68 -48
  190. package/dist/autorizacao-duravel.js +327 -0
  191. package/dist/board.js +98 -43
  192. package/dist/branch-de-estado.js +39 -9
  193. package/dist/busca-semantica.js +7 -5
  194. package/dist/catalogo.js +35 -1
  195. package/dist/changelog-reconciliacao.js +290 -0
  196. package/dist/check-agil.js +500 -0
  197. package/dist/check-modo.js +41 -0
  198. package/dist/check-paralelo.js +183 -0
  199. package/dist/ci.js +255 -46
  200. package/dist/ciclos.js +8 -6
  201. package/dist/claim-lint.js +12 -8
  202. package/dist/claims-conferir.js +350 -0
  203. package/dist/claims.js +13 -10
  204. package/dist/company-brain-client.js +45 -3
  205. package/dist/company-brain-journal.js +2 -1
  206. package/dist/company-brain-migration.js +47 -6
  207. package/dist/conducao-batida.js +759 -0
  208. package/dist/conducao-sentinela.js +405 -0
  209. package/dist/conducao-texto.js +12 -18
  210. package/dist/conducao.js +206 -59
  211. package/dist/conhecimento-consulta.js +270 -0
  212. package/dist/conhecimento.js +514 -0
  213. package/dist/conta-esgotada.js +127 -0
  214. package/dist/dado-privado.js +816 -0
  215. package/dist/decisao-autonoma.js +5 -4
  216. package/dist/demo.js +14 -12
  217. package/dist/dependencias-da-worktree.js +25 -0
  218. package/dist/divida.js +38 -36
  219. package/dist/docs.js +103 -82
  220. package/dist/doctor-forja.js +345 -0
  221. package/dist/doctor-pulse-cron.js +294 -27
  222. package/dist/doctor-rede.js +18 -17
  223. package/dist/doctor.js +278 -116
  224. package/dist/dsn-da-memoria.js +417 -0
  225. package/dist/entrega-por-mod.js +503 -0
  226. package/dist/entrega-pr.js +158 -57
  227. package/dist/escopo-escrita.js +10 -1
  228. package/dist/esgotamentos.js +13 -11
  229. package/dist/estado-thread.js +42 -17
  230. package/dist/evalrunner.js +35 -32
  231. package/dist/experiencia-instalacao.js +45 -25
  232. package/dist/fabrica-batida.js +323 -0
  233. package/dist/fabrica-estado.js +49 -16
  234. package/dist/fabrica-publicar.js +3 -1
  235. package/dist/fila-pesada.js +444 -0
  236. package/dist/fix.js +24 -21
  237. package/dist/forja/adaptador.js +6 -0
  238. package/dist/forja/ambiente-de-ci.js +27 -0
  239. package/dist/forja/api.js +256 -0
  240. package/dist/forja/cache.js +89 -0
  241. package/dist/forja/cli.js +60 -0
  242. package/dist/forja/contrato.js +9 -0
  243. package/dist/forja/endereco.js +43 -0
  244. package/dist/forja/estado.js +22 -0
  245. package/dist/forja/executor.js +73 -0
  246. package/dist/forja/github/ci.js +95 -0
  247. package/dist/forja/github/dono-da-rede.js +18 -0
  248. package/dist/forja/github/metadados.js +15 -0
  249. package/dist/forja/github/pedidos.js +200 -0
  250. package/dist/forja/gitlab/ci.js +141 -0
  251. package/dist/forja/gitlab/consultas.js +59 -0
  252. package/dist/forja/gitlab/dono-da-rede.js +43 -0
  253. package/dist/forja/gitlab/metadados.js +15 -0
  254. package/dist/forja/gitlab/pedidos-abertos.js +158 -0
  255. package/dist/forja/gitlab/pedidos.js +141 -0
  256. package/dist/forja/produtor.js +32 -0
  257. package/dist/forja/registro.js +31 -0
  258. package/dist/forja/resolver.js +121 -0
  259. package/dist/forja/texto.js +13 -0
  260. package/dist/forja/versao.js +71 -0
  261. package/dist/forja.js +124 -81
  262. package/dist/gates.js +3 -28
  263. package/dist/handoff.js +33 -19
  264. package/dist/hitl-contract.js +46 -43
  265. package/dist/hitl-curto.js +37 -25
  266. package/dist/hitl-gates.js +13 -11
  267. package/dist/hitl-local-receipt.js +53 -0
  268. package/dist/hitl-local.js +11 -2
  269. package/dist/hitl-lock.js +5 -11
  270. package/dist/hitl-public-receipt.js +11 -0
  271. package/dist/hitl-resumo.js +72 -3
  272. package/dist/hitl-sessions.js +62 -9
  273. package/dist/hitl-tempo-parado.js +4 -4
  274. package/dist/hitl-texto-livre.js +7 -4
  275. package/dist/hitl.js +63 -64
  276. package/dist/horario.js +30 -7
  277. package/dist/hosts.js +155 -134
  278. package/dist/impedimento.js +108 -14
  279. package/dist/index.js +1421 -1019
  280. package/dist/indice-vetorial.js +14 -12
  281. package/dist/indice.js +7 -1
  282. package/dist/init.js +54 -49
  283. package/dist/instabilidade.js +144 -0
  284. package/dist/integracoes-locais.js +4 -0
  285. package/dist/intelligence-graph-cli.js +213 -88
  286. package/dist/intelligence-graph-contexto.js +56 -17
  287. package/dist/intelligence-graph-contract.js +2 -1
  288. package/dist/intelligence-graph-extract-md.js +56 -4
  289. package/dist/intelligence-graph-extract-ts.js +71 -3
  290. package/dist/intelligence-graph-query.js +96 -34
  291. package/dist/leases.js +19 -18
  292. package/dist/ledger-stats.js +17 -16
  293. package/dist/ledger.js +46 -2
  294. package/dist/licoes.js +12 -11
  295. package/dist/liveness.js +6 -3
  296. package/dist/locale-accounts.js +220 -0
  297. package/dist/locale-adapter.js +291 -0
  298. package/dist/locale-ajuda.js +833 -0
  299. package/dist/locale-audit.js +199 -0
  300. package/dist/locale-claims.js +213 -0
  301. package/dist/locale-conducao.js +138 -0
  302. package/dist/locale-conhecimento.js +181 -0
  303. package/dist/locale-decisao.js +205 -0
  304. package/dist/locale-docs.js +230 -0
  305. package/dist/locale-estado.js +101 -0
  306. package/dist/locale-forja.js +290 -0
  307. package/dist/locale-gerados.js +165 -0
  308. package/dist/locale-grafo.js +129 -0
  309. package/dist/locale-master.js +182 -0
  310. package/dist/locale-network.js +524 -0
  311. package/dist/locale-onboarding.js +92 -0
  312. package/dist/locale-operacao-restante.js +931 -0
  313. package/dist/locale-phase.js +151 -0
  314. package/dist/locale-projetos.js +100 -0
  315. package/dist/locale-prompts.js +194 -0
  316. package/dist/locale-pulse.js +349 -0
  317. package/dist/locale-reservas.js +87 -0
  318. package/dist/locale-retry.js +524 -0
  319. package/dist/locale-roadmap.js +102 -0
  320. package/dist/locale-security-scan.js +69 -0
  321. package/dist/locale-setup.js +192 -0
  322. package/dist/locale-ship.js +597 -0
  323. package/dist/locale-thread.js +421 -0
  324. package/dist/locale-verify.js +201 -0
  325. package/dist/locale-worktree.js +246 -0
  326. package/dist/locale.js +1258 -0
  327. package/dist/maestro-runtime.js +22 -3
  328. package/dist/manifest.js +415 -13
  329. package/dist/maquina-ociosa.js +211 -0
  330. package/dist/maquina.js +31 -7
  331. package/dist/master-digest.js +6 -1
  332. package/dist/master-nota-local.js +200 -0
  333. package/dist/master-nota.js +14 -8
  334. package/dist/master.js +139 -65
  335. package/dist/mcp-artifacts.js +11 -2
  336. package/dist/mcp-conhecimento.js +52 -0
  337. package/dist/mcp-experiencia.js +26 -5
  338. package/dist/mcp-git.js +23 -6
  339. package/dist/mcp-grafo.js +7 -4
  340. package/dist/mcp-install.js +73 -8
  341. package/dist/mcp-noctum.js +101 -0
  342. package/dist/mcp-server.js +90 -16
  343. package/dist/mcp-ship-transporte.js +977 -0
  344. package/dist/mcp-ship.js +71 -25
  345. package/dist/mcp-transportes.js +17 -0
  346. package/dist/mcp-verify.js +6 -1
  347. package/dist/memoria.js +63 -58
  348. package/dist/modos-migracao.js +8 -6
  349. package/dist/modos.js +20 -24
  350. package/dist/network-roadmap.js +90 -51
  351. package/dist/noctum-aceite.js +789 -0
  352. package/dist/noctum-arco.js +1418 -0
  353. package/dist/noctum-capacidade.js +141 -0
  354. package/dist/noctum-changelog.js +399 -0
  355. package/dist/noctum-cli.js +482 -0
  356. package/dist/noctum-coordenacao.js +1225 -0
  357. package/dist/noctum-entrega.js +1169 -0
  358. package/dist/noctum-envelope.js +1046 -0
  359. package/dist/noctum-execucao.js +376 -0
  360. package/dist/noctum-fechamento.js +405 -0
  361. package/dist/noctum-fila.js +314 -0
  362. package/dist/noctum-guarda.js +256 -0
  363. package/dist/noctum-integracao.js +507 -0
  364. package/dist/noctum-maquinas.js +383 -0
  365. package/dist/noctum-medicao.js +450 -0
  366. package/dist/noctum-modo.js +362 -0
  367. package/dist/noctum-pergunta-canal.js +96 -0
  368. package/dist/noctum-pergunta.js +115 -0
  369. package/dist/noctum-provas.js +838 -0
  370. package/dist/noctum-reconciliacao.js +591 -0
  371. package/dist/noctum-registro.js +215 -0
  372. package/dist/noctum-relatorio.js +827 -0
  373. package/dist/noctum-resposta.js +207 -0
  374. package/dist/noctum-sessoes-em-voo.js +93 -0
  375. package/dist/noctum-supervisao.js +649 -0
  376. package/dist/noctum-terminal.js +459 -0
  377. package/dist/noctum-transporte.js +655 -0
  378. package/dist/noctum-vigia.js +639 -0
  379. package/dist/ocupacao.js +32 -3
  380. package/dist/onboarding.js +56 -26
  381. package/dist/orkmind.js +48 -25
  382. package/dist/orquestracao.js +44 -47
  383. package/dist/parado-no-condutor.js +174 -127
  384. package/dist/phase.js +144 -63
  385. package/dist/policies.js +37 -4
  386. package/dist/portfolio.js +4 -2
  387. package/dist/postura-local.js +235 -0
  388. package/dist/preflight.js +11 -10
  389. package/dist/procedencia.js +220 -0
  390. package/dist/projeto-alvo.js +186 -24
  391. package/dist/prompts.js +140 -42
  392. package/dist/prova-minima.js +5 -6
  393. package/dist/pulse-cadencia.js +5 -4
  394. package/dist/pulse-consentimento.js +53 -1
  395. package/dist/pulse-delivery.js +151 -24
  396. package/dist/pulse-resposta.js +368 -4
  397. package/dist/pulse.js +188 -22
  398. package/dist/ratelimit.js +16 -6
  399. package/dist/recall.js +14 -13
  400. package/dist/redacao-saida.js +63 -0
  401. package/dist/rede-adesao.js +13 -8
  402. package/dist/rede-forja.js +108 -24
  403. package/dist/rede-status.js +66 -47
  404. package/dist/rede.js +86 -46
  405. package/dist/retomada-checkpoint.js +101 -0
  406. package/dist/retry.js +451 -212
  407. package/dist/roadmap-reservas.js +45 -28
  408. package/dist/roadmap-status.js +129 -33
  409. package/dist/runtime-ambiente.js +5 -0
  410. package/dist/runtime-context.js +284 -32
  411. package/dist/runtime-escada.js +423 -0
  412. package/dist/runtime-profiles.js +103 -46
  413. package/dist/runtimes.js +2 -1
  414. package/dist/saida-segura.js +3 -2
  415. package/dist/security-scan/agil.js +355 -0
  416. package/dist/security-scan/cli.js +76 -0
  417. package/dist/security-scan/compare.js +149 -0
  418. package/dist/security-scan/config.js +93 -0
  419. package/dist/security-scan/detect.js +97 -0
  420. package/dist/security-scan/executor.js +188 -0
  421. package/dist/security-scan/guard.js +180 -0
  422. package/dist/security-scan/imagem-de-lint.js +96 -0
  423. package/dist/security-scan/normalize/actionlint.js +12 -0
  424. package/dist/security-scan/normalize/eslint.js +12 -0
  425. package/dist/security-scan/normalize/gitleaks.js +13 -0
  426. package/dist/security-scan/normalize/golangci-lint.js +13 -0
  427. package/dist/security-scan/normalize/govulncheck.js +36 -0
  428. package/dist/security-scan/normalize/index.js +25 -0
  429. package/dist/security-scan/normalize/npm-audit.js +30 -0
  430. package/dist/security-scan/normalize/osv-scanner.js +32 -0
  431. package/dist/security-scan/normalize/oxlint.js +51 -0
  432. package/dist/security-scan/normalize/pip-audit.js +16 -0
  433. package/dist/security-scan/normalize/ruff.js +12 -0
  434. package/dist/security-scan/normalize/semgrep.js +20 -0
  435. package/dist/security-scan/normalize/trivy.js +33 -0
  436. package/dist/security-scan/normalize/util.js +204 -0
  437. package/dist/security-scan/normalize/zizmor.js +19 -0
  438. package/dist/security-scan/report.js +156 -0
  439. package/dist/security-scan/run.js +448 -0
  440. package/dist/security-scan/tools.js +62 -0
  441. package/dist/security-scan/trabalhador.js +74 -0
  442. package/dist/security-scan/types.js +15 -0
  443. package/dist/session-events.js +26 -5
  444. package/dist/session-watcher-claude.js +81 -20
  445. package/dist/session-watcher.js +340 -42
  446. package/dist/sessoes-contas.js +10 -1
  447. package/dist/sessoes-inventario.js +1 -1
  448. package/dist/sessoes.js +25 -23
  449. package/dist/setup.js +59 -58
  450. package/dist/ship-publicar.js +971 -0
  451. package/dist/ship.js +243 -97
  452. package/dist/steal.js +77 -0
  453. package/dist/superficie.js +14 -11
  454. package/dist/thread-close.js +12 -11
  455. package/dist/thread.js +274 -100
  456. package/dist/tokens.js +15 -11
  457. package/dist/trabalho-thread.js +297 -0
  458. package/dist/transporte-do-canal.js +189 -0
  459. package/dist/types.js +12 -1
  460. package/dist/util.js +13 -3
  461. package/dist/varredura-acoes.js +507 -0
  462. package/dist/verify.js +608 -76
  463. package/dist/vida-da-thread.js +254 -0
  464. package/dist/worktree-local.js +167 -0
  465. package/dist/worktree.js +99 -83
  466. package/dist/yaml.js +27 -8
  467. package/eval/casos/check-quality.json +77 -0
  468. package/eval/casos/security-auditor.json +148 -0
  469. package/eval/casos/security-remediation.json +161 -0
  470. package/eval/fixtures/security-scan/README.md +8 -0
  471. package/eval/fixtures/security-scan/go/.github/workflows/ci.yml +12 -0
  472. package/eval/fixtures/security-scan/go/Dockerfile +4 -0
  473. package/eval/fixtures/security-scan/go/README.md +4 -0
  474. package/eval/fixtures/security-scan/go/config.go +4 -0
  475. package/eval/fixtures/security-scan/go/go.mod +5 -0
  476. package/eval/fixtures/security-scan/go/go.sum +2 -0
  477. package/eval/fixtures/security-scan/go/main.go +31 -0
  478. package/eval/fixtures/security-scan/js/.github/workflows/ci.yml +12 -0
  479. package/eval/fixtures/security-scan/js/Dockerfile +3 -0
  480. package/eval/fixtures/security-scan/js/README.md +4 -0
  481. package/eval/fixtures/security-scan/js/package-lock.json +844 -0
  482. package/eval/fixtures/security-scan/js/package.json +10 -0
  483. package/eval/fixtures/security-scan/js/src/config.js +4 -0
  484. package/eval/fixtures/security-scan/js/src/server.js +17 -0
  485. package/eval/fixtures/security-scan/js/src/util.ts +4 -0
  486. package/eval/fixtures/security-scan/js/tsconfig.json +4 -0
  487. package/eval/fixtures/security-scan/python/.github/workflows/ci.yml +12 -0
  488. package/eval/fixtures/security-scan/python/Dockerfile +3 -0
  489. package/eval/fixtures/security-scan/python/README.md +4 -0
  490. package/eval/fixtures/security-scan/python/app/__init__.py +0 -0
  491. package/eval/fixtures/security-scan/python/app/config.py +2 -0
  492. package/eval/fixtures/security-scan/python/app/main.py +19 -0
  493. package/eval/fixtures/security-scan/python/requirements.txt +1 -0
  494. package/package.json +9 -4
  495. package/references/security-checklist.md +3 -3
  496. package/schemas/code-artifact-graph.v1.schema.json +2 -1
  497. package/skills/README.md +1 -0
  498. package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
  499. package/skills/phases/check-quality/SKILL.md +16 -0
  500. package/skills/phases/go-implementation/SKILL.md +6 -0
  501. package/skills/phases/security-remediation/SKILL.md +70 -0
  502. package/skills/reviewers/security-auditor/SKILL.md +25 -0
package/dist/docs.js CHANGED
@@ -79,6 +79,8 @@ const node_child_process_1 = require("node:child_process");
79
79
  const yaml_1 = require("./yaml");
80
80
  const thread_1 = require("./thread");
81
81
  const ledger_1 = require("./ledger");
82
+ const branch_de_estado_1 = require("./branch-de-estado");
83
+ const locale_1 = require("./locale");
82
84
  exports.DIR_PRODUTO = 'docs/produto';
83
85
  exports.DIR_ROADMAP = 'docs/roadmap';
84
86
  exports.DIR_PADROES = 'docs/padroes';
@@ -161,17 +163,18 @@ function paginas(raiz, dir) {
161
163
  function documentoDeTexto(arquivo, texto) {
162
164
  const { bruto, corpo } = separarFrontmatter(texto);
163
165
  if (bruto === null) {
164
- return { achado: erro(arquivo, undefined, 'docs.frontmatter.ausente', 'página sem frontmatter YAML', 'comece o arquivo com as chaves do modelo entre duas linhas ---') };
166
+ return { achado: erro(arquivo, undefined, 'docs.frontmatter.ausente', (m) => m.semFrontmatter, (m) => m.semFrontmatterCorrecao) };
165
167
  }
166
168
  let dados;
167
169
  try {
168
170
  dados = (0, yaml_1.lerYaml)(bruto);
169
171
  }
170
172
  catch (e) {
171
- return { achado: erro(arquivo, undefined, 'docs.frontmatter.invalido', `frontmatter inválido: ${e.message}`) };
173
+ const detalhe = e.message;
174
+ return { achado: erro(arquivo, undefined, 'docs.frontmatter.invalido', (m) => m.frontmatterInvalido(detalhe)) };
172
175
  }
173
176
  if (!ehMapa(dados)) {
174
- return { achado: erro(arquivo, undefined, 'docs.frontmatter.invalido', 'o frontmatter precisa ser um mapa de chaves') };
177
+ return { achado: erro(arquivo, undefined, 'docs.frontmatter.invalido', (m) => m.frontmatterNaoMapa) };
175
178
  }
176
179
  return { doc: { arquivo, tipo: dados.tipo, id: String(dados.id ?? ''), dados, corpo } };
177
180
  }
@@ -187,11 +190,15 @@ function carregarDocs(raiz) {
187
190
  }
188
191
  return { docs, achados };
189
192
  }
193
+ function achado(gravidade, arquivo, id, regra, mensagem, correcao) {
194
+ const texto = (montar) => (0, locale_1.textoDoCatalogo)((m) => montar(m.docs));
195
+ return { arquivo, ...(id ? { id } : {}), regra, gravidade, mensagem: texto(mensagem), ...(correcao ? { correcao: texto(correcao) } : {}) };
196
+ }
190
197
  function erro(arquivo, id, regra, mensagem, correcao) {
191
- return { arquivo, ...(id ? { id } : {}), regra, gravidade: 'erro', mensagem, ...(correcao ? { correcao } : {}) };
198
+ return achado('erro', arquivo, id, regra, mensagem, correcao);
192
199
  }
193
200
  function aviso(arquivo, id, regra, mensagem, correcao) {
194
- return { arquivo, ...(id ? { id } : {}), regra, gravidade: 'aviso', mensagem, ...(correcao ? { correcao } : {}) };
201
+ return achado('aviso', arquivo, id, regra, mensagem, correcao);
195
202
  }
196
203
  function git(raiz, args) {
197
204
  const r = (0, node_child_process_1.spawnSync)('git', args, { cwd: raiz, encoding: 'utf8' });
@@ -199,6 +206,9 @@ function git(raiz, args) {
199
206
  }
200
207
  /** Resolve a branch base: local, depois `origin/`, porque o CI faz checkout destacado. */
201
208
  function resolverBase(raiz, preferida = 'main') {
209
+ // RM-047 (fronteira de confiança): `preferida` vem do `worktree.base_branch` do clone.
210
+ if (!(0, branch_de_estado_1.branchValida)(preferida))
211
+ return null;
202
212
  for (const ref of [preferida, `origin/${preferida}`]) {
203
213
  if (git(raiz, ['rev-parse', '--verify', '--quiet', `${ref}^{commit}`]).ok)
204
214
  return ref;
@@ -228,23 +238,23 @@ function verificarDocs(raiz, opcoes = {}) {
228
238
  const porId = new Map();
229
239
  for (const d of docs) {
230
240
  if (!TIPOS.includes(d.tipo)) {
231
- achados.push(erro(d.arquivo, d.id || undefined, 'docs.tipo', `tipo "${String(d.dados.tipo)}" desconhecido`, `use um de: ${TIPOS.join(', ')}`));
241
+ achados.push(erro(d.arquivo, d.id || undefined, 'docs.tipo', (m) => m.tipoDesconhecido(String(d.dados.tipo)), (m) => m.useUmDe(TIPOS.join(', '))));
232
242
  continue;
233
243
  }
234
244
  if (!PADRAO_ID[d.tipo].test(d.id)) {
235
- achados.push(erro(d.arquivo, d.id || undefined, 'docs.id.formato', `ID "${d.id}" fora do padrão de ${d.tipo}`, `formato esperado: ${PADRAO_ID[d.tipo].source.replace(/[\^$\\]/g, '')}`));
245
+ achados.push(erro(d.arquivo, d.id || undefined, 'docs.id.formato', (m) => m.idForaDoPadrao(d.id, d.tipo), (m) => m.formatoEsperado(PADRAO_ID[d.tipo].source.replace(/[\^$\\]/g, ''))));
236
246
  }
237
247
  const nome = path.posix.basename(d.arquivo);
238
248
  if (!(nome === `${d.id}.md` || nome.startsWith(`${d.id}-`))) {
239
- achados.push(erro(d.arquivo, d.id, 'docs.id.arquivo', 'o nome do arquivo não começa pelo ID', `renomeie para ${d.id}-<assunto>.md`));
249
+ achados.push(erro(d.arquivo, d.id, 'docs.id.arquivo', (m) => m.arquivoSemId, (m) => m.renomeie(d.id)));
240
250
  }
241
251
  const pastaCerta = d.tipo === 'roadmap' ? exports.DIR_ROADMAP : exports.DIR_PRODUTO;
242
252
  if (path.posix.dirname(d.arquivo) !== pastaCerta) {
243
- achados.push(erro(d.arquivo, d.id, 'docs.pasta', `${d.tipo} mora em ${pastaCerta}`));
253
+ achados.push(erro(d.arquivo, d.id, 'docs.pasta', (m) => m.pastaErrada(d.tipo, pastaCerta)));
244
254
  }
245
255
  const anterior = porId.get(d.id);
246
256
  if (anterior) {
247
- achados.push(erro(d.arquivo, d.id, 'docs.id.duplicado', `ID repetido: também em ${anterior.arquivo}`, 'IDs são estáveis e únicos; renumere o novo, nunca o antigo'));
257
+ achados.push(erro(d.arquivo, d.id, 'docs.id.duplicado', (m) => m.idRepetido(anterior.arquivo), (m) => m.idRepetidoCorrecao));
248
258
  }
249
259
  else {
250
260
  porId.set(d.id, d);
@@ -252,7 +262,7 @@ function verificarDocs(raiz, opcoes = {}) {
252
262
  }
253
263
  const base = opcoes.semGit ? null : resolverBase(raiz, opcoes.baseBranch);
254
264
  if (!opcoes.semGit && !base) {
255
- achados.push(aviso('.', undefined, 'docs.git.base', `branch base "${opcoes.baseBranch ?? 'main'}" não encontrada: a paridade com o git ficou de fora`, 'rode com o histórico do git disponível (fetch-depth: 0 no CI)'));
265
+ achados.push(aviso('.', undefined, 'docs.git.base', (m) => m.baseAusente(opcoes.baseBranch ?? 'main'), (m) => m.baseAusenteCorrecao));
256
266
  }
257
267
  const comandos = opcoes.ajudaDoCli ? comandosDaAjuda(opcoes.ajudaDoCli) : null;
258
268
  for (const d of docs) {
@@ -275,50 +285,53 @@ function verificarDocs(raiz, opcoes = {}) {
275
285
  function verificarChaves(d, achados) {
276
286
  for (const k of CHAVES[d.tipo]) {
277
287
  if (!(k in d.dados)) {
278
- achados.push(erro(d.arquivo, d.id, 'docs.frontmatter.chave', `falta a chave "${k}"`, 'copie a chave do modelo; lacuna é "A definir — responsável, prazo"'));
288
+ achados.push(erro(d.arquivo, d.id, 'docs.frontmatter.chave', (m) => m.faltaChave(k), (m) => m.faltaChaveCorrecao));
279
289
  }
280
290
  }
281
291
  if (d.tipo !== 'roadmap' && 'estado' in d.dados) {
282
292
  const e = String(d.dados.estado);
283
293
  if (!exports.ESTADOS_DA_ESPECIFICACAO.includes(e)) {
284
- achados.push(erro(d.arquivo, d.id, 'docs.frontmatter.valor', `estado "${e}" fora do padrão`, `use um de: ${exports.ESTADOS_DA_ESPECIFICACAO.join(', ')}`));
294
+ achados.push(erro(d.arquivo, d.id, 'docs.frontmatter.valor', (m) => m.estadoForaDoPadrao(e), (m) => m.useUmDe(exports.ESTADOS_DA_ESPECIFICACAO.join(', '))));
285
295
  }
286
296
  }
287
297
  if (d.tipo === 'roadmap') {
288
298
  const cat = String(d.dados.categoria ?? '');
289
299
  if ('categoria' in d.dados && !exports.CATEGORIAS.includes(cat)) {
290
- achados.push(erro(d.arquivo, d.id, 'docs.frontmatter.valor', `categoria "${cat}" fora do padrão`, `use uma de: ${exports.CATEGORIAS.join(', ')}`));
300
+ achados.push(erro(d.arquivo, d.id, 'docs.frontmatter.valor', (m) => m.categoriaForaDoPadrao(cat), (m) => m.useUmaDe(exports.CATEGORIAS.join(', '))));
291
301
  }
292
302
  const estado = d.dados.estado;
293
303
  if ('estado' in d.dados && !ehMapa(estado)) {
294
- achados.push(erro(d.arquivo, d.id, 'docs.frontmatter.valor', 'estado do roadmap é um mapa de dimensões', `dimensões: ${Object.keys(exports.DIMENSOES).join(', ')}`));
304
+ achados.push(erro(d.arquivo, d.id, 'docs.frontmatter.valor', (m) => m.estadoNaoMapa, (m) => m.dimensoes(Object.keys(exports.DIMENSOES).join(', '))));
295
305
  }
296
306
  else if (ehMapa(estado)) {
297
307
  for (const [dim, valores] of Object.entries(exports.DIMENSOES)) {
298
308
  if (!(dim in estado)) {
299
- achados.push(erro(d.arquivo, d.id, 'docs.frontmatter.chave', `falta a dimensão estado.${dim}`, 'o padrão atualiza cada dimensão separadamente'));
309
+ achados.push(erro(d.arquivo, d.id, 'docs.frontmatter.chave', (m) => m.faltaDimensao(dim), (m) => m.faltaDimensaoCorrecao));
300
310
  }
301
311
  else if (!valores.includes(String(estado[dim]))) {
302
- achados.push(erro(d.arquivo, d.id, 'docs.frontmatter.valor', `estado.${dim} "${String(estado[dim])}" fora do padrão`, `use um de: ${valores.join(', ')}`));
312
+ const valor = String(estado[dim]);
313
+ achados.push(erro(d.arquivo, d.id, 'docs.frontmatter.valor', (m) => m.dimensaoForaDoPadrao(dim, valor), (m) => m.useUmDe(valores.join(', '))));
303
314
  }
304
315
  }
305
316
  for (const dim of Object.keys(estado)) {
306
317
  if (!(dim in exports.DIMENSOES)) {
307
- achados.push(erro(d.arquivo, d.id, 'docs.frontmatter.chave', `dimensão desconhecida estado.${dim}`));
318
+ achados.push(erro(d.arquivo, d.id, 'docs.frontmatter.chave', (m) => m.dimensaoDesconhecida(dim)));
308
319
  }
309
320
  }
310
321
  }
311
322
  }
312
323
  for (const k of ['verificado_em', 'atualizado_em']) {
313
324
  if (k in d.dados && !ISO_COM_FUSO.test(String(d.dados[k]))) {
314
- achados.push(erro(d.arquivo, d.id, 'docs.data', `${k} "${String(d.dados[k])}" não é ISO 8601 com fuso`, 'exemplo: 2026-09-24T20:00:00-03:00'));
325
+ const valor = String(d.dados[k]);
326
+ achados.push(erro(d.arquivo, d.id, 'docs.data', (m) => m.dataSemFuso(k, valor), (m) => m.dataExemplo));
315
327
  }
316
328
  }
317
329
  // Valor de modelo esquecido no frontmatter: `<...>` ou ID zerado (FEAT-000, MOD-00, RM-000).
318
330
  const visitar = (v, onde) => {
319
331
  if (typeof v === 'string') {
320
332
  if (/^<[^>]*>$/.test(v.trim()) || /^(PLAT|SYS|MOD|FEAT|RM)-0+$/.test(v.trim()) || /@0{7}$/.test(v.trim())) {
321
- achados.push(erro(d.arquivo, d.id, 'docs.modelo', `valor do modelo não preenchido em ${onde}: ${v}`));
333
+ const valor = v;
334
+ achados.push(erro(d.arquivo, d.id, 'docs.modelo', (m) => m.valorDoModelo(onde, valor)));
322
335
  }
323
336
  }
324
337
  else if (Array.isArray(v))
@@ -392,15 +405,15 @@ function substituirBloco(corpo, ini, fim, conteudo) {
392
405
  }
393
406
  function verificarTabelasDeEstado(d, achados) {
394
407
  for (const [ini, fim, render, nome] of [
395
- [RELANCE_INI, RELANCE_FIM, renderizarRelance, 'a linha de relance'],
396
- [ESTADO_INI, ESTADO_FIM, renderizarEstado, 'a tabela "Estado com evidências"'],
408
+ [RELANCE_INI, RELANCE_FIM, renderizarRelance, (m) => m.nomeDaRelance],
409
+ [ESTADO_INI, ESTADO_FIM, renderizarEstado, (m) => m.nomeDoEstado],
397
410
  ]) {
398
411
  const atual = blocoEntre(d.corpo, ini, fim);
399
412
  if (atual === null) {
400
- achados.push(erro(d.arquivo, d.id, 'docs.paridade.estado', `falta ${nome} gerada do frontmatter`, 'copie os marcadores do modelo e rode ork docs sincronizar --escrever'));
413
+ achados.push(erro(d.arquivo, d.id, 'docs.paridade.estado', (m) => m.faltaTabela(nome(m)), (m) => m.faltaTabelaCorrecao));
401
414
  }
402
415
  else if (atual !== render(d)) {
403
- achados.push(erro(d.arquivo, d.id, 'docs.paridade.estado', `${nome} diverge do frontmatter`, 'o estado se edita no frontmatter; rode ork docs sincronizar --escrever para regerar a tabela'));
416
+ achados.push(erro(d.arquivo, d.id, 'docs.paridade.estado', (m) => m.tabelaDiverge(nome(m)), (m) => m.tabelaDivergeCorrecao));
404
417
  }
405
418
  }
406
419
  }
@@ -410,14 +423,14 @@ function verificarReferencias(raiz, d, porId, achados) {
410
423
  if (esperadoDoPai && pai !== undefined && pai !== null) {
411
424
  const idPai = String(pai);
412
425
  if (!esperadoDoPai.test(idPai)) {
413
- achados.push(erro(d.arquivo, d.id, 'docs.referencia', `pai "${idPai}" não é do nível acima de ${d.tipo}`));
426
+ achados.push(erro(d.arquivo, d.id, 'docs.referencia', (m) => m.paiDeOutroNivel(idPai, d.tipo)));
414
427
  }
415
428
  else if (!porId.has(idPai)) {
416
- achados.push(erro(d.arquivo, d.id, 'docs.referencia', `pai ${idPai} não existe`, 'crie a página do pai ou corrija o ID'));
429
+ achados.push(erro(d.arquivo, d.id, 'docs.referencia', (m) => m.paiNaoExiste(idPai), (m) => m.paiNaoExisteCorrecao));
417
430
  }
418
431
  }
419
432
  else if (esperadoDoPai && d.tipo !== 'roadmap' && (pai === undefined || pai === null)) {
420
- achados.push(erro(d.arquivo, d.id, 'docs.referencia', `${d.tipo} precisa de pai`));
433
+ achados.push(erro(d.arquivo, d.id, 'docs.referencia', (m) => m.precisaDePai(d.tipo)));
421
434
  }
422
435
  const cruzadas = d.tipo === 'feature' ? [['roadmap', 'roadmap', 'features']]
423
436
  : d.tipo === 'roadmap' ? [['features', 'feature', 'roadmap']] : [];
@@ -425,10 +438,10 @@ function verificarReferencias(raiz, d, porId, achados) {
425
438
  for (const alvo of lista(d.dados[chave])) {
426
439
  const outro = porId.get(alvo);
427
440
  if (!outro || outro.tipo !== tipoAlvo) {
428
- achados.push(erro(d.arquivo, d.id, 'docs.referencia', `${chave} cita ${alvo}, que não existe como ${tipoAlvo}`));
441
+ achados.push(erro(d.arquivo, d.id, 'docs.referencia', (m) => m.citaInexistente(chave, alvo, tipoAlvo)));
429
442
  }
430
443
  else if (!lista(outro.dados[chaveDeVolta]).includes(d.id)) {
431
- achados.push(aviso(d.arquivo, d.id, 'docs.referencia.reciproca', `${alvo} não cita ${d.id} de volta`, `acrescente ${d.id} em ${chaveDeVolta} de ${alvo}`));
444
+ achados.push(aviso(d.arquivo, d.id, 'docs.referencia.reciproca', (m) => m.naoCitaDeVolta(alvo, d.id), (m) => m.naoCitaDeVoltaCorrecao(d.id, chaveDeVolta, alvo)));
432
445
  }
433
446
  }
434
447
  }
@@ -439,7 +452,7 @@ function verificarReferencias(raiz, d, porId, achados) {
439
452
  continue;
440
453
  const abs = path.resolve(path.dirname(path.join(raiz, d.arquivo)), decodeURIComponent(alvo));
441
454
  if (!fs.existsSync(abs)) {
442
- achados.push(erro(d.arquivo, d.id, 'docs.link', `link quebrado: ${alvo}`));
455
+ achados.push(erro(d.arquivo, d.id, 'docs.link', (m) => m.linkQuebrado(alvo)));
443
456
  }
444
457
  }
445
458
  }
@@ -451,36 +464,36 @@ function verificarLeitura(d, achados) {
451
464
  const linhas = d.corpo.split('\n');
452
465
  const h1 = linhas.find((l) => l.startsWith('# '));
453
466
  if (!h1 || !h1.includes(d.id)) {
454
- achados.push(erro(d.arquivo, d.id, 'docs.leitura.titulo', 'o título (#) não começa pelo ID', `# ${d.id} — <nome>: humano e agente acham a página pelo mesmo nome`));
467
+ achados.push(erro(d.arquivo, d.id, 'docs.leitura.titulo', (m) => m.tituloSemId, (m) => m.tituloSemIdCorrecao(d.id)));
455
468
  }
456
469
  const frase = linhas.find((l) => /^>\s*\*\*Em uma frase:\*\*/.test(l));
457
470
  if (!frase) {
458
- achados.push(erro(d.arquivo, d.id, 'docs.leitura.resumo', 'falta a linha "> **Em uma frase:**" logo abaixo do título', 'escreva o que a página responde, antes de qualquer detalhe'));
471
+ achados.push(erro(d.arquivo, d.id, 'docs.leitura.resumo', (m) => m.faltaFrase, (m) => m.faltaFraseCorrecao));
459
472
  }
460
473
  else {
461
474
  const n = frase.replace(/^>\s*\*\*Em uma frase:\*\*\s*/, '').trim().length;
462
475
  if (n === 0)
463
- achados.push(erro(d.arquivo, d.id, 'docs.leitura.resumo', 'a frase de abertura está vazia'));
476
+ achados.push(erro(d.arquivo, d.id, 'docs.leitura.resumo', (m) => m.fraseVazia));
464
477
  else if (n > exports.LIMITE_DA_FRASE) {
465
- achados.push(erro(d.arquivo, d.id, 'docs.leitura.resumo', `a frase de abertura tem ${n} caracteres (limite ${exports.LIMITE_DA_FRASE})`, 'corte para uma ideia só; o resto vai em tópicos'));
478
+ achados.push(erro(d.arquivo, d.id, 'docs.leitura.resumo', (m) => m.fraseLonga(n, exports.LIMITE_DA_FRASE), (m) => m.fraseLongaCorrecao));
466
479
  }
467
480
  }
468
481
  const h2 = new Set(linhas.filter((l) => l.startsWith('## ')).map((l) => l.slice(3).trim()));
469
482
  for (const s of SECOES[d.tipo]) {
470
483
  if (!h2.has(s)) {
471
- achados.push(erro(d.arquivo, d.id, 'docs.secao', `falta a seção "## ${s}"`, 'se não se aplica, escreva dentro dela: Não aplicável — motivo'));
484
+ achados.push(erro(d.arquivo, d.id, 'docs.secao', (m) => m.faltaSecao(s), (m) => m.faltaSecaoCorrecao));
472
485
  }
473
486
  }
474
487
  const texto = semCodigo(d.corpo);
475
- for (const m of texto.matchAll(/\[(\.\.\.|[^\]\n]{1,60})\](?!\()/g)) {
476
- achados.push(erro(d.arquivo, d.id, 'docs.modelo', `campo do modelo não preenchido: [${m[1]}]`, 'preencha, ou escreva "A definir — responsável, prazo" / "Não aplicável — motivo"'));
488
+ for (const [, campo] of texto.matchAll(/\[(\.\.\.|[^\]\n]{1,60})\](?!\()/g)) {
489
+ achados.push(erro(d.arquivo, d.id, 'docs.modelo', (m) => m.campoDoModelo(campo), (m) => m.campoDoModeloCorrecao));
477
490
  }
478
491
  for (const p of texto.split(/\n\s*\n/)) {
479
492
  const bloco = p.trim();
480
493
  if (!bloco || /^(#|>|\||[-*+] |\d+\. |<!--)/.test(bloco))
481
494
  continue;
482
495
  if (bloco.length > exports.LIMITE_DO_PARAGRAFO) {
483
- achados.push(aviso(d.arquivo, d.id, 'docs.leitura.paragrafo', `parágrafo com ${bloco.length} caracteres`, 'quebre em tópicos: uma ideia por linha'));
496
+ achados.push(aviso(d.arquivo, d.id, 'docs.leitura.paragrafo', (m) => m.paragrafoLongo(bloco.length), (m) => m.paragrafoLongoCorrecao));
484
497
  }
485
498
  }
486
499
  }
@@ -489,36 +502,36 @@ function verificarFontes(raiz, d, comandos, achados) {
489
502
  if (f === undefined || f === null)
490
503
  return;
491
504
  if (!ehMapa(f)) {
492
- achados.push(erro(d.arquivo, d.id, 'docs.frontmatter.valor', 'fontes é um mapa (codigo, testes, simbolos, contratos, comandos)'));
505
+ achados.push(erro(d.arquivo, d.id, 'docs.frontmatter.valor', (m) => m.fontesNaoMapa));
493
506
  return;
494
507
  }
495
508
  const existe = (p) => fs.existsSync(path.join(raiz, p));
496
509
  for (const chave of ['codigo', 'testes', 'docs']) {
497
510
  for (const p of lista(f[chave])) {
498
511
  if (path.isAbsolute(p) || p.split('/').includes('..')) {
499
- achados.push(erro(d.arquivo, d.id, 'docs.paridade.fonte', `${p}: caminho fora do repositório`, 'use caminho relativo à raiz'));
512
+ achados.push(erro(d.arquivo, d.id, 'docs.paridade.fonte', (m) => m.caminhoFora(p), (m) => m.caminhoForaCorrecao));
500
513
  }
501
514
  else if (!existe(p)) {
502
- achados.push(erro(d.arquivo, d.id, 'docs.paridade.fonte', `${p} não existe no repositório`, 'a doc descreve o código que existe: corrija o caminho ou a página'));
515
+ achados.push(erro(d.arquivo, d.id, 'docs.paridade.fonte', (m) => m.caminhoNaoExiste(p), (m) => m.caminhoNaoExisteCorrecao));
503
516
  }
504
517
  }
505
518
  }
506
519
  for (const s of lista(f.simbolos)) {
507
520
  const [arq, simbolo] = s.split('#');
508
521
  if (!arq || !simbolo) {
509
- achados.push(erro(d.arquivo, d.id, 'docs.paridade.simbolo', `símbolo "${s}" fora do formato arquivo#nome`));
522
+ achados.push(erro(d.arquivo, d.id, 'docs.paridade.simbolo', (m) => m.simboloForaDoFormato(s)));
510
523
  }
511
524
  else if (!existe(arq)) {
512
- achados.push(erro(d.arquivo, d.id, 'docs.paridade.simbolo', `${arq} não existe (símbolo ${simbolo})`));
525
+ achados.push(erro(d.arquivo, d.id, 'docs.paridade.simbolo', (m) => m.arquivoDoSimbolo(arq, simbolo)));
513
526
  }
514
527
  else if (!new RegExp(`\\b${escapar(simbolo)}\\b`).test(fs.readFileSync(path.join(raiz, arq), 'utf8'))) {
515
- achados.push(erro(d.arquivo, d.id, 'docs.paridade.simbolo', `${simbolo} não aparece em ${arq}`, 'o código mudou de nome ou a página ficou para trás'));
528
+ achados.push(erro(d.arquivo, d.id, 'docs.paridade.simbolo', (m) => m.simboloAusente(simbolo, arq), (m) => m.simboloAusenteCorrecao));
516
529
  }
517
530
  }
518
531
  const codigo = lista(f.codigo).filter(existe).map((p) => fs.readFileSync(path.join(raiz, p), 'utf8'));
519
532
  for (const c of lista(f.contratos)) {
520
533
  if (!codigo.some((t) => t.includes(c))) {
521
- achados.push(erro(d.arquivo, d.id, 'docs.paridade.contrato', `o contrato ${c} não aparece nos arquivos de fontes.codigo`));
534
+ achados.push(erro(d.arquivo, d.id, 'docs.paridade.contrato', (m) => m.contratoAusente(c)));
522
535
  }
523
536
  }
524
537
  if (comandos) {
@@ -530,7 +543,8 @@ function verificarFontes(raiz, d, comandos, achados) {
530
543
  const temSubcomandos = [...comandos].some((c) => c.startsWith(`${topo} `));
531
544
  const exigePar = temSubcomandos && /^[a-z][a-z-]*$/.test(sub);
532
545
  if (!comandos.has(topo) || (exigePar && !comandos.has(`${topo} ${sub}`))) {
533
- achados.push(erro(d.arquivo, d.id, 'docs.paridade.comando', `o CLI não declara "${[programa, topo, sub].join(' ').trim()}"`, 'confira `ork --help`: a doc descreve o CLI que existe'));
546
+ const comando = [programa, topo, sub].join(' ').trim();
547
+ achados.push(erro(d.arquivo, d.id, 'docs.paridade.comando', (m) => m.comandoAusente(comando), (m) => m.comandoAusenteCorrecao));
534
548
  }
535
549
  }
536
550
  }
@@ -546,26 +560,28 @@ function verificarEstadoDoRoadmap(raiz, d, base, achados) {
546
560
  const [ciclo, codigo, testes, deploy] = [e.ciclo, e.codigo, e.testes, e.deploy].map((v) => String(v ?? ''));
547
561
  // Coerencia entre dimensoes (padrao 3.6): o status nao pode esconder o que falta.
548
562
  if (ciclo === 'Concluído' && codigo !== 'Mesclado') {
549
- achados.push(erro(d.arquivo, d.id, 'docs.estado.coerencia', 'ciclo Concluído com código que não está Mesclado'));
563
+ achados.push(erro(d.arquivo, d.id, 'docs.estado.coerencia', (m) => m.concluidoSemMerge));
550
564
  }
551
565
  if (ciclo === 'Concluído' && testes !== 'Aprovados') {
552
- achados.push(erro(d.arquivo, d.id, 'docs.estado.coerencia', 'ciclo Concluído com testes que não estão Aprovados'));
566
+ achados.push(erro(d.arquivo, d.id, 'docs.estado.coerencia', (m) => m.concluidoSemTestes));
553
567
  }
554
568
  if (deploy === 'Produção' && codigo !== 'Mesclado') {
555
- achados.push(erro(d.arquivo, d.id, 'docs.estado.coerencia', 'deploy em Produção com código que não está Mesclado'));
569
+ achados.push(erro(d.arquivo, d.id, 'docs.estado.coerencia', (m) => m.producaoSemMerge));
556
570
  }
557
571
  if (ciclo === 'Bloqueado' && !ehMapa(d.dados.bloqueio)) {
558
- achados.push(erro(d.arquivo, d.id, 'docs.estado.bloqueio', 'Bloqueado exige o mapa "bloqueio"', 'bloqueio: motivo, dependencia, responsavel, proxima_revisao'));
572
+ achados.push(erro(d.arquivo, d.id, 'docs.estado.bloqueio', (m) => m.bloqueadoSemMapa, (m) => m.bloqueadoSemMapaCorrecao));
559
573
  }
560
574
  if (codigo === 'Mesclado' && !commit) {
561
- achados.push(erro(d.arquivo, d.id, 'docs.paridade.git', 'código Mesclado sem o commit do merge', 'preencha evidencias.codigo.commit (ork docs sincronizar faz isso a partir do ledger e do git)'));
575
+ achados.push(erro(d.arquivo, d.id, 'docs.paridade.git', (m) => m.mescladoSemCommit, (m) => m.mescladoSemCommitCorrecao));
562
576
  }
563
577
  if (commit && base) {
564
- if (!git(raiz, ['cat-file', '-e', `${commit}^{commit}`]).ok) {
565
- achados.push(erro(d.arquivo, d.id, 'docs.paridade.git', `o commit ${commit} não existe neste repositório`));
578
+ // RM-047: o commit vem do frontmatter do clone; só sha hexadecimal vai ao git.
579
+ if (!(0, branch_de_estado_1.shaValido)(commit) || !git(raiz, ['cat-file', '-e', `${commit}^{commit}`]).ok) {
580
+ achados.push(erro(d.arquivo, d.id, 'docs.paridade.git', (m) => m.commitInexistente(commit)));
566
581
  }
567
582
  else if (codigo === 'Mesclado' && !git(raiz, ['merge-base', '--is-ancestor', commit, base]).ok) {
568
- achados.push(erro(d.arquivo, d.id, 'docs.paridade.git', `o commit ${commit} não está na ${base}: o merge não aconteceu`, 'volte o estado.codigo para "PR aberto" ou "Branch criada" até o merge'));
583
+ const naBase = base;
584
+ achados.push(erro(d.arquivo, d.id, 'docs.paridade.git', (m) => m.commitForaDaBase(commit, naBase), (m) => m.commitForaDaBaseCorrecao));
569
585
  }
570
586
  }
571
587
  }
@@ -581,9 +597,7 @@ function verificarMergeDaThread(raiz, d, base, achados, pr = false) {
581
597
  if (!pendente)
582
598
  return;
583
599
  const { thread, merges, codigo } = pendente;
584
- achados.push((pr ? aviso : erro)(d.arquivo, d.id, 'docs.paridade.merge', `a thread ${thread} entrou na ${base} pelo merge ${merges[0].slice(0, 7)} (ship(${thread})), e o estado.codigo diz "${codigo || 'vazio'}"` +
585
- (pr ? ' (no PR, aviso: o push da main reprova)' : ''), `abra um PR de docs sobre a ${base} atualizada com ork docs sincronizar --escrever --so ${d.id} (o item e os índices); ` +
586
- `se o item tem outra fatia em curso, aponte sdlc.thread para a thread dela`));
600
+ achados.push((pr ? aviso : erro)(d.arquivo, d.id, 'docs.paridade.merge', (m) => m.mergeDaThread(thread, base, merges[0].slice(0, 7), codigo, pr), (m) => m.mergeDaThreadCorrecao(base, d.id)));
587
601
  }
588
602
  /**
589
603
  * A regra do `docs.paridade.merge`, isolada para o `ork ship registrar-pr` (RM-044, A3): a pagina cujo
@@ -650,34 +664,33 @@ function verificarIndices(raiz, docs, achados, pr = false) {
650
664
  continue;
651
665
  if (atual === '') {
652
666
  if (docs.length > 0) {
653
- achados.push(aviso(arquivo, undefined, 'docs.paridade.indice', 'o índice ainda não foi gerado', 'rode ork docs sincronizar --escrever'));
667
+ achados.push(aviso(arquivo, undefined, 'docs.paridade.indice', (m) => m.indiceNaoGerado, (m) => m.indiceNaoGeradoCorrecao));
654
668
  }
655
669
  }
656
670
  else if (atual !== gerar(docs)) {
657
- achados.push((pr ? aviso : erro)(arquivo, undefined, 'docs.paridade.indice', `o índice diverge do frontmatter das páginas${pr ? ' (no PR, aviso: o push da main reprova)' : ''}`, 'o índice é gerado do frontmatter: rode ork docs sincronizar --escrever e commite o índice'));
671
+ achados.push((pr ? aviso : erro)(arquivo, undefined, 'docs.paridade.indice', (m) => m.indiceDiverge(pr), (m) => m.indiceDivergeCorrecao));
658
672
  }
659
673
  }
660
674
  }
661
675
  // --------------------------------------------------------------------------------------------
662
676
  // Saida para humano (TDAH) e para agente
677
+ /** O texto da verificacao, no locale ativo; a mensagem e a correcao de cada achado sao remontadas (G4 da F3b). */
663
678
  function textoDaVerificacao(docs, achados) {
679
+ const m = (0, locale_1.msg)().docs;
664
680
  const conta = (t) => docs.filter((d) => d.tipo === t).length;
665
681
  const erros = achados.filter((a) => a.gravidade === 'erro');
666
682
  const avisos = achados.filter((a) => a.gravidade === 'aviso');
667
683
  const L = [];
668
- L.push(`Documentação: ${docs.length} páginas — ${conta('feature')} features, ${conta('roadmap')} itens de roadmap, `
669
- + `${conta('plataforma') + conta('sistema') + conta('modulo')} de contexto`);
670
- L.push(erros.length === 0
671
- ? `OK: nenhum erro de paridade${avisos.length ? ` · ${avisos.length} aviso(s) de leitura` : ''}`
672
- : `REPROVADO: ${erros.length} erro(s)${avisos.length ? ` · ${avisos.length} aviso(s)` : ''}`);
673
- for (const [titulo, grupo] of [['Erros', erros], ['Avisos', avisos]]) {
684
+ L.push(m.resumo(docs.length, conta('feature'), conta('roadmap'), conta('plataforma') + conta('sistema') + conta('modulo')));
685
+ L.push(erros.length === 0 ? m.semErro(avisos.length) : m.reprovado(erros.length, avisos.length));
686
+ for (const [titulo, grupo] of [[m.tituloErros, erros], [m.tituloAvisos, avisos]]) {
674
687
  if (grupo.length === 0)
675
688
  continue;
676
689
  L.push('', titulo);
677
690
  for (const a of grupo) {
678
- L.push(` ${(a.id ?? a.arquivo).padEnd(9)} ${a.mensagem}`);
691
+ L.push(` ${(a.id ?? a.arquivo).padEnd(9)} ${(0, locale_1.remontar)(a.mensagem)}`);
679
692
  if (a.correcao)
680
- L.push(` ${''.padEnd(9)} → ${a.correcao}`);
693
+ L.push(` ${''.padEnd(9)} → ${(0, locale_1.remontar)(a.correcao)}`);
681
694
  }
682
695
  }
683
696
  return L.join('\n');
@@ -755,7 +768,7 @@ function mergeDaThread(raiz, thread, base) {
755
768
  try {
756
769
  const eventos = (0, ledger_1.lerLedger)((0, thread_1.dirThread)(raiz, thread));
757
770
  const ship = eventos.filter((e) => e.tipo === 'ship_done' && typeof e.mergeSha === 'string')
758
- .find((e) => git(raiz, ['merge-base', '--is-ancestor', String(e.mergeSha), base]).ok);
771
+ .find((e) => (0, branch_de_estado_1.shaValido)(e.mergeSha) && (0, branch_de_estado_1.branchValida)(base) && git(raiz, ['merge-base', '--is-ancestor', e.mergeSha, base]).ok);
759
772
  if (ship)
760
773
  return { sha: String(ship.mergeSha).slice(0, 7), fonte: 'ledger ship_done' };
761
774
  }
@@ -773,6 +786,9 @@ function mergesDaThreadNoGit(raiz, thread, base) {
773
786
  // Sem `-n 1`: o git corta antes de inverter, e `--reverse -n 1` devolveria o mais recente.
774
787
  // GO-FIX 2 (achado 4 do CHECK): so a linha de primeiro pai da base e o assunto que COMECA com
775
788
  // `ship(<thread>)`, como no `mergeDaEntrega`. Commit que cita o merge no corpo, ou o Revert dele, nao e merge.
789
+ // RM-047 (fronteira de confiança): a base pode ser o `worktree.base_branch` cru do clone.
790
+ if (!(0, branch_de_estado_1.branchValida)(base))
791
+ return [];
776
792
  const log = git(raiz, ['log', base, '--first-parent', '--reverse', '--format=%H%x09%s', '--fixed-strings', `--grep=ship(${thread})`]);
777
793
  if (!log.ok)
778
794
  return [];
@@ -929,18 +945,18 @@ function tabelaDoProduto(docs) {
929
945
  }
930
946
  return L.join('\n');
931
947
  }
948
+ /** O texto da sincronizacao, no locale ativo; o campo e os valores de cada mudanca sao dado e so a impressao os traduz. */
932
949
  function textoDaSincronizacao(r, escreveu) {
950
+ const m = (0, locale_1.msg)().docs;
933
951
  const L = [];
934
- const ids = new Set(r.mudancas.map((m) => m.id));
935
- L.push(r.mudancas.length === 0 && r.indices.length === 0
936
- ? 'Sincronizado: a documentação já bate com o ledger e o git.'
937
- : `${escreveu ? 'Atualizado' : 'A atualizar'}: ${ids.size} item(ns) de roadmap, ${r.indices.length} índice(s).`);
938
- for (const m of r.mudancas)
939
- L.push(` ${m.id.padEnd(7)} ${m.campo}: ${m.de || '—'} → ${m.para} (${m.fonte})`);
952
+ const ids = new Set(r.mudancas.map((x) => x.id));
953
+ L.push(r.mudancas.length === 0 && r.indices.length === 0 ? m.sincronizado : m.aAtualizar(escreveu, ids.size, r.indices.length));
954
+ for (const x of r.mudancas)
955
+ L.push(m.linhaDaMudanca(x.id, x.campo, x.de, x.para, x.fonte));
940
956
  for (const i of r.indices)
941
- L.push(` índice ${i}`);
957
+ L.push(m.indice(i));
942
958
  if (!escreveu && (r.mudancas.length || r.indices.length))
943
- L.push('', 'Nada foi gravado. Para gravar: ork docs sincronizar --escrever');
959
+ L.push('', m.nadaGravado);
944
960
  return L.join('\n');
945
961
  }
946
962
  // --------------------------------------------------------------------------------------------
@@ -954,16 +970,21 @@ const ARQUIVOS_DO_PADRAO = [
954
970
  ['roadmap/README.md', `${exports.DIR_ROADMAP}/README.md`],
955
971
  ['markdownlint-cli2.jsonc', '.markdownlint-cli2.jsonc'],
956
972
  ];
957
- function dirDosModelos() {
958
- for (const c of [path.join(__dirname, '..', 'assets', 'docs'), path.join(__dirname, '..', '..', 'assets', 'docs')]) {
973
+ /**
974
+ * A pasta dos modelos do nucleo na lingua pedida. RM-061 (F3a, D3 e D6): o ingles mora em `assets/docs-en/`, com os
975
+ * mesmos nomes; o contrato que o `ork docs verificar` le (frontmatter, secoes, `Em uma frase`) e o mesmo nas duas.
976
+ */
977
+ function dirDosModelos(locale = locale_1.LOCALE_PADRAO) {
978
+ const pasta = locale === 'en' ? 'docs-en' : 'docs';
979
+ for (const c of [path.join(__dirname, '..', 'assets', pasta), path.join(__dirname, '..', '..', 'assets', pasta)]) {
959
980
  if (fs.existsSync(c))
960
981
  return c;
961
982
  }
962
- throw new Error('docs.modelos: assets/docs do nucleo nao encontrado');
983
+ throw new Error(`docs.modelos: assets/${pasta} do nucleo nao encontrado`);
963
984
  }
964
- /** Cria o que falta; nunca sobrescreve pagina existente. Devolve o que criou. */
965
- function iniciarDocs(raiz) {
966
- const origem = dirDosModelos();
985
+ /** Cria o que falta, no `locale` pedido (pt-BR por omissao); nunca sobrescreve pagina existente. Devolve o que criou. */
986
+ function iniciarDocs(raiz, locale = locale_1.LOCALE_PADRAO) {
987
+ const origem = dirDosModelos(locale);
967
988
  const criados = [];
968
989
  for (const [de, para] of ARQUIVOS_DO_PADRAO) {
969
990
  const destino = path.join(raiz, para);