@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
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.mergeDaEntrega = mergeDaEntrega;
4
+ exports.enderecoDoRemotoDaRaiz = enderecoDoRemotoDaRaiz;
5
+ exports.forjaDaEntrega = forjaDaEntrega;
4
6
  exports.registrarEntregaPorPr = registrarEntregaPorPr;
5
7
  exports.registrarEntregaExternaPorPr = registrarEntregaExternaPorPr;
6
8
  exports.registrarEntregasPorPr = registrarEntregasPorPr;
@@ -17,13 +19,24 @@ exports.registrarEntregasPorPr = registrarEntregasPorPr;
17
19
  * head do PR. Sem CI verde, nao registra: merge sem prova independente nao e entrega.
18
20
  */
19
21
  const branch_de_estado_1 = require("./branch-de-estado");
22
+ const produtor_1 = require("./forja/produtor");
20
23
  const ci_1 = require("./ci");
24
+ const api_1 = require("./forja/api");
25
+ const cli_1 = require("./forja/cli");
26
+ const endereco_1 = require("./forja/endereco");
27
+ const pedidos_1 = require("./forja/gitlab/pedidos");
28
+ const cache_1 = require("./forja/cache");
29
+ const resolver_1 = require("./forja/resolver");
21
30
  const docs_1 = require("./docs");
22
31
  const fabrica_publicar_1 = require("./fabrica-publicar");
23
32
  const ledger_1 = require("./ledger");
24
33
  const modos_1 = require("./modos");
34
+ const noctum_guarda_1 = require("./noctum-guarda");
25
35
  const thread_1 = require("./thread");
26
36
  const util_1 = require("./util");
37
+ const executor_1 = require("./forja/executor");
38
+ const registro_1 = require("./forja/registro");
39
+ const locale_1 = require("./locale");
27
40
  /** O merge `ship(<thread>)` mais recente na base remota, com o head do PR (segundo pai). */
28
41
  function mergeDaEntrega(raiz, thread, remoto, base) {
29
42
  const r = (0, util_1.exec)('git', ['log', `refs/remotes/${remoto}/${base}`, '--first-parent', '--format=%H%x09%P%x09%s', `--grep=^ship(${thread})`], raiz);
@@ -50,6 +63,28 @@ function avancarParaShip(raiz, threadId) {
50
63
  atualizada.faseAtual = 'SHIP';
51
64
  (0, thread_1.gravarThread)(raiz, atualizada);
52
65
  }
66
+ /** O endereco do remoto, de UM parse da URL; `null` quando o remoto nao existe ou nao tem host de forja. */
67
+ function enderecoDoRemotoDaRaiz(raiz, remoto) {
68
+ // Git local sem rede escondida nem pergunta de credencial no terminal.
69
+ const url = (0, util_1.exec)('git', ['remote', 'get-url', '--', remoto], raiz, 60000, { ...process.env, GIT_NO_LAZY_FETCH: '1', GIT_TERMINAL_PROMPT: '0' });
70
+ return url.ok ? (0, endereco_1.lerEnderecoDoRemoto)(url.stdout.trim()) : null;
71
+ }
72
+ /**
73
+ * A forja do remoto, de UM parse da URL e do resolver (o bloco `forja:`, o host conhecido ou a sondagem pela CLI com
74
+ * login no host): o nome do host nao decide o tipo. `erro` nulo: o remoto nao existe, nao tem host de forja (caminho
75
+ * local) ou aponta um caminho que a forja dele nao tem (subgrupo no GitHub).
76
+ */
77
+ function forjaDaEntrega(carregado, remoto, sondas = resolver_1.SONDAS_PADRAO) {
78
+ const endereco = enderecoDoRemotoDaRaiz(carregado.raiz, remoto);
79
+ if (!endereco)
80
+ return { ok: false, erro: null };
81
+ const r = (0, resolver_1.resolverForja)({ endereco, manifesto: carregado.manifesto.forja, sondas, cache: (0, cache_1.dirDoCacheDaForja)(carregado.raiz) });
82
+ if (!r.ok)
83
+ return { ok: false, erro: r.erro };
84
+ if (r.valor.tipo === 'github' && r.valor.repo.split('/').length !== 2)
85
+ return { ok: false, erro: null };
86
+ return { ok: true, valor: r.valor };
87
+ }
53
88
  function resultado(thread, acao, motivo, extra = {}) {
54
89
  return { thread, acao, motivo, mergeSha: null, headSha: null, ci: null, docsPendentes: [], ...extra };
55
90
  }
@@ -64,32 +99,50 @@ function registrarEntregaPorPr(carregado, threadId, opcoes = {}) {
64
99
  const base = carregado.manifesto.worktree.base_branch;
65
100
  const thread = (0, thread_1.lerThread)(raiz, threadId);
66
101
  if (thread.status === 'fechada')
67
- return resultado(threadId, 'ja-registrada', 'thread ja fechada');
68
- if (opcoes.buscar !== false)
69
- (0, util_1.exec)('git', ['fetch', '-q', '--', remoto, `+refs/heads/${base}:refs/remotes/${remoto}/${base}`], raiz);
102
+ return resultado(threadId, 'ja-registrada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prThreadFechada));
103
+ // RM-058, integracao (T1.1, D3 da ork-rm058integra): a entrega da thread de um arco #Noctum e do passo da entrega dele,
104
+ // com as provas dele; antes de qualquer git, e sem ledger.
105
+ const guarda = (0, noctum_guarda_1.guardaDaThread)(raiz, threadId, opcoes.arcos?.quando, { arcos: opcoes.arcos });
106
+ if (guarda)
107
+ return resultado(threadId, 'recusada', guarda.texto, { codigo: guarda.motivo });
108
+ if (opcoes.buscar !== false) {
109
+ const busca = (0, util_1.exec)('git', ['fetch', '-q', '--', remoto, `+refs/heads/${base}:refs/remotes/${remoto}/${base}`], raiz);
110
+ if (!busca.ok) {
111
+ return resultado(threadId, 'recusada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prSemLeitura(remoto, base)), { codigo: 'entrega.sem-leitura' });
112
+ }
113
+ }
70
114
  const encontrado = mergeDaEntrega(raiz, threadId, remoto, base);
71
115
  if (!encontrado)
72
- return resultado(threadId, 'sem-merge', `nenhum merge ship(${threadId}) em ${remoto}/${base}`);
116
+ return resultado(threadId, 'sem-merge', (0, locale_1.textoDoCatalogo)((m) => m.ship.prSemMerge(threadId, remoto, base)));
117
+ // Squash ou rebase: sem segundo pai o merge nao se liga ao head que a CI verificou. Com a CI exigida, a CI do commit
118
+ // da base nao prova o head, e a entrega e recusada antes de qualquer consulta. Sem CI exigida, registra como sempre.
119
+ const exigeCi = carregado.manifesto.ci.required_for_ship;
120
+ if (encontrado.headSha === null && exigeCi) {
121
+ return resultado(threadId, 'recusada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prSemVinculo(threadId, encontrado.mergeSha.slice(0, 7))), { mergeSha: encontrado.mergeSha, codigo: 'entrega.sem-vinculo' });
122
+ }
73
123
  // RM-044 (A3): o condutor roda o registrar-pr logo depois do merge; e aqui que ele fica sabendo da pagina que
74
124
  // vai deixar o push da base vermelho, lida da base remota que o fetch acabou de trazer.
75
125
  const merge = { ...encontrado, docsPendentes: (0, docs_1.docsPendentesDoMerge)(raiz, threadId, `refs/remotes/${remoto}/${base}`) };
76
126
  const dir = (0, thread_1.dirThread)(raiz, threadId);
77
127
  const jaTem = (0, ledger_1.lerLedger)(dir).some((e) => e.tipo === ledger_1.TIPOS_DE_EVENTO.shipConcluido && e.mergeSha === merge.mergeSha);
78
128
  if (jaTem)
79
- return resultado(threadId, 'ja-registrada', 'esta entrega ja tem ship_done', merge);
129
+ return resultado(threadId, 'ja-registrada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prJaTemShipDone), merge);
80
130
  // A ponta do remoto AGORA, e o merge dentro dela: e o que torna o push provado, nao presumido.
81
131
  const remotoAgora = (0, util_1.exec)('git', ['ls-remote', '--', remoto, `refs/heads/${base}`], raiz);
82
132
  const ponta = remotoAgora.ok ? remotoAgora.stdout.split('\t')[0].trim() : '';
83
133
  if (!ponta || !(0, util_1.exec)('git', ['merge-base', '--is-ancestor', merge.mergeSha, ponta], raiz).ok) {
84
- return resultado(threadId, 'recusada', `o merge ${merge.mergeSha.slice(0, 7)} nao esta na ponta de ${remoto}/${base}`, merge);
134
+ return resultado(threadId, 'recusada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prForaDaPonta(merge.mergeSha.slice(0, 7), remoto, base)), merge);
85
135
  }
86
- const ci = (0, ci_1.consultarCi)(carregado, merge.headSha ?? merge.mergeSha, remoto, opcoes.executorCi);
136
+ // A CI so e consultada no head do PR; sem head (squash ou rebase), so chega aqui sem CI exigida, e nada e consultado.
137
+ const ci = encontrado.headSha !== null
138
+ ? (0, ci_1.consultarCi)(carregado, encontrado.headSha, remoto, opcoes.executorCi)
139
+ : (0, ci_1.ciNaoExigida)(carregado, encontrado.mergeSha);
87
140
  if (ci.required && !ci.ok) {
88
- return resultado(threadId, 'recusada', `sem CI verde no head do PR: ${ci.detail}`, { ...merge, ci });
141
+ return resultado(threadId, 'recusada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prSemCiVerde((0, locale_1.remontar)(ci.detail))), { ...merge, ci });
89
142
  }
90
143
  // RM-037 (fatia 3, defeito 6): o ensaio confere tudo e para aqui, sem ledger, fase nem fabrica.
91
144
  if (opcoes.dryRun) {
92
- return resultado(threadId, 'registraria', `ensaio: registraria ship_done pelo merge ${merge.mergeSha.slice(0, 7)} do PR (nada gravado)`, { ...merge, ci });
145
+ return resultado(threadId, 'registraria', (0, locale_1.textoDoCatalogo)((m) => m.ship.prRegistraria(merge.mergeSha.slice(0, 7))), { ...merge, ci });
93
146
  }
94
147
  (0, ledger_1.registrar)(dir, threadId, ledger_1.TIPOS_DE_EVENTO.shipConcluido, {
95
148
  de: thread.base?.branch ?? null,
@@ -114,98 +167,137 @@ function registrarEntregaPorPr(carregado, threadId, opcoes = {}) {
114
167
  avancarParaShip(raiz, threadId);
115
168
  if (opcoes.publicar !== false)
116
169
  (0, fabrica_publicar_1.publicarEmSegundoPlano)(raiz);
117
- return resultado(threadId, 'registrou', `ship_done pelo merge ${merge.mergeSha.slice(0, 7)} do PR`, { ...merge, ci });
170
+ return resultado(threadId, 'registrou', (0, locale_1.textoDoCatalogo)((m) => m.ship.prRegistrou(merge.mergeSha.slice(0, 7))), { ...merge, ci });
118
171
  }
119
- const ghApi = (caminho) => (0, util_1.exec)('gh', ['api', caminho, '-H', 'Accept: application/vnd.github+json'], process.cwd(), 120000);
120
- function lerJson(r) {
121
- if (!r.ok)
122
- return null;
123
- try {
124
- return JSON.parse(r.stdout);
125
- }
126
- catch {
127
- return null;
172
+ const ghApi = (caminho) => {
173
+ const r = (0, executor_1.rodarCli)({ cmd: 'gh', args: ['api', '--hostname', 'github.com', caminho, '-H', 'Accept: application/vnd.github+json'], prazoMs: 120000,
174
+ maxBuffer: 32 * 1024 * 1024 });
175
+ return { ok: r.status === 0, code: r.status ?? -1, stdout: r.stdout, stderr: r.stderr };
176
+ };
177
+ /**
178
+ * A forja do repositorio externo: a do projeto quando ela e um GitLab (o mesmo host, a mesma porta, o mesmo caminho
179
+ * base, outro projeto); o github.com quando a forja do projeto e o GitHub ou quando o projeto nao tem remoto de forja
180
+ * (sem remoto ou caminho local), como sempre. Nao ha host de reserva: o remoto que nomeia um host de forja que nao se
181
+ * resolve, e o projeto que declara `forja.tipo: gitlab` sem a forja resolvida, nunca caem no github.com.
182
+ */
183
+ function forjaDoExterno(carregado, repo, opcoes) {
184
+ const remoto = opcoes.remoto ?? 'origin';
185
+ const doProjeto = opcoes.forja ? { ok: true, valor: opcoes.forja } : forjaDaEntrega(carregado, (0, branch_de_estado_1.exigirRemoto)(remoto, 'ship'), opcoes.sondas);
186
+ if (doProjeto.ok && doProjeto.valor.tipo === 'gitlab')
187
+ return { ok: true, gitlab: { ...doProjeto.valor, repo } };
188
+ if (carregado.manifesto.forja?.tipo === 'gitlab') {
189
+ return { ok: false, remoto, declarada: true,
190
+ erro: !doProjeto.ok && doProjeto.erro ? doProjeto.erro : { codigo: 'forja.desconhecida', detalhe: remoto } };
128
191
  }
192
+ if (!doProjeto.ok && doProjeto.erro)
193
+ return { ok: false, erro: doProjeto.erro, remoto, declarada: false };
194
+ return { ok: true, gitlab: null };
129
195
  }
130
196
  /**
131
197
  * `ork ship registrar-pr <thread> --repo <dono/nome> --pr <n>`: a thread que entrega por PR em outro
132
198
  * repositorio (os sites, por exemplo) nao tinha como virar `ship_done`, e a entrega virava decisao. A
133
- * exigencia e a mesma do caminho local: o merge dentro da ponta da base (pela API do GitHub, porque o
134
- * repositorio nao e remoto deste checkout) e o check declarado verde no head do PR. O repositorio precisa
135
- * estar declarado no manifesto; e o dono que diz onde, e com que check, a entrega vale. Idempotente.
199
+ * exigencia e a mesma do caminho local: o merge dentro da ponta da base (pela API da forja do repositorio, o GitHub
200
+ * ou o GitLab do projeto, porque o repositorio nao e remoto deste checkout) e o check declarado verde no head do PR.
201
+ * O repositorio precisa estar declarado no manifesto; e o dono que diz onde, e com que check, a entrega vale.
202
+ * Idempotente.
136
203
  */
137
204
  function registrarEntregaExternaPorPr(carregado, threadId, opcoes) {
138
205
  const raiz = carregado.raiz, repo = opcoes.repositorio, n = opcoes.pr;
139
206
  const gh = opcoes.executorGitHub ?? ghApi;
140
207
  const declarados = carregado.manifesto.ci.external_repositories;
141
208
  if (!Object.hasOwn(declarados, repo)) {
142
- return resultado(threadId, 'recusada', `o repositorio ${repo} nao esta declarado em ci.external_repositories do orkastery.yaml`);
209
+ return resultado(threadId, 'recusada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prRepoNaoDeclarado(repo)));
143
210
  }
144
211
  if (!Number.isSafeInteger(n) || n < 1)
145
- return resultado(threadId, 'recusada', `--pr precisa ser o numero do PR, recebido ${String(n)}`);
212
+ return resultado(threadId, 'recusada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prNumeroInvalido(String(n))));
146
213
  const thread = (0, thread_1.lerThread)(raiz, threadId);
147
214
  if (thread.status === 'fechada')
148
- return resultado(threadId, 'ja-registrada', 'thread ja fechada');
215
+ return resultado(threadId, 'ja-registrada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prThreadFechada));
216
+ // RM-058, integracao (T1.1): a mesma guarda do PR local, antes de consultar a forja.
217
+ const guarda = (0, noctum_guarda_1.guardaDaThread)(raiz, threadId);
218
+ if (guarda)
219
+ return resultado(threadId, 'recusada', guarda.texto, { codigo: guarda.motivo });
149
220
  const dir = (0, thread_1.dirThread)(raiz, threadId);
150
221
  if ((0, ledger_1.lerLedger)(dir).some((e) => e.tipo === ledger_1.TIPOS_DE_EVENTO.shipConcluido && e.repositorio === repo && e.pr === n)) {
151
- return resultado(threadId, 'ja-registrada', `o PR #${n} de ${repo} ja tem ship_done`);
222
+ return resultado(threadId, 'ja-registrada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prExternoJaTem(n, repo)));
152
223
  }
153
- const pr = lerJson(gh(`repos/${repo}/pulls/${n}`));
224
+ const daForja = forjaDoExterno(carregado, repo, opcoes);
225
+ if (!daForja.ok) {
226
+ const { erro, remoto, declarada } = daForja;
227
+ return resultado(threadId, 'recusada', (0, locale_1.textoDoCatalogo)((m) => declarada ? m.ship.prForjaDoExterno(repo, m.forja.motivo(erro, 'gitlab'))
228
+ : m.ship.prForjaDoProjetoNaoResolvida(repo, remoto, m.forja.motivo(erro, null))), { codigo: 'entrega.sem-leitura' });
229
+ }
230
+ const gitlab = daForja.gitlab;
231
+ // O GitHub so tem dono/nome: o caminho com subgrupo e recusado antes de qualquer consulta.
232
+ if (!gitlab && repo.split('/').length !== 2) {
233
+ return resultado(threadId, 'recusada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prRepoComSubgrupoNoGithub(repo)), { codigo: 'entrega.forja-mista' });
234
+ }
235
+ const nomeDaForja = gitlab ? 'GitLab' : undefined;
236
+ const forja = (0, registro_1.adaptadorDaForja)(gitlab ? 'gitlab' : 'github');
237
+ const api = gitlab ? (0, api_1.chamadorDaApi)(gitlab, opcoes.api ?? {}) : undefined;
238
+ const pr = (0, registro_1.exigirCapacidade)(forja, 'pedidoMesclado')({ repo, numero: n, executor: gh, api });
154
239
  if (!pr)
155
- return resultado(threadId, 'recusada', `a consulta do PR #${n} de ${repo} ao GitHub falhou`);
156
- const mergeSha = typeof pr.merge_commit_sha === 'string' && /^[0-9a-f]{40}$/.test(pr.merge_commit_sha) ? pr.merge_commit_sha : null;
157
- const headSha = typeof pr.head?.sha === 'string' && /^[0-9a-f]{40}$/.test(pr.head.sha) ? pr.head.sha : null;
158
- const base = typeof pr.base?.ref === 'string' && /^[A-Za-z0-9._/-]{1,200}$/.test(pr.base.ref) ? pr.base.ref : null;
159
- if (pr.merged !== true || !mergeSha || !headSha || !base) {
160
- return resultado(threadId, 'sem-merge', `o PR #${n} de ${repo} nao esta mesclado`);
240
+ return resultado(threadId, 'recusada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prConsultaFalhou(n, repo, nomeDaForja)));
241
+ const { mergeSha, headSha, base } = pr;
242
+ if (pr.mesclado && mergeSha && base && !headSha) {
243
+ return resultado(threadId, 'recusada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prSemHead(n, repo, nomeDaForja)), { mergeSha, codigo: 'entrega.sem-head' });
244
+ }
245
+ if (!pr.mesclado || !mergeSha || !headSha || !base) {
246
+ return resultado(threadId, 'sem-merge', (0, locale_1.textoDoCatalogo)((m) => m.ship.prNaoMesclado(n, repo, !!gitlab)));
161
247
  }
162
248
  // Achado A4 do CHECK: o PR precisa ser DESTA thread e ter entrado na branch padrao do repositorio. Sem o
163
249
  // vinculo, qualquer PR mesclado do repositorio viraria entrega de qualquer thread; sem a base, um PR
164
250
  // empilhado numa branch de feature contaria como entrega.
165
- const vinculo = [pr.title, pr.body, pr.head?.ref].filter((x) => typeof x === 'string')
251
+ const vinculo = [pr.titulo, pr.corpo, pr.branch].filter((x) => typeof x === 'string')
166
252
  // N4 do CHECK 2: a branch do proprio ork e `ork/<thread>-<variante>`, entao o hifen depois do id vale;
167
253
  // letra ou digito colado nao (outro id). Sem diferenciar maiusculas.
168
254
  .some((x) => new RegExp(`(^|[^a-z0-9-])${threadId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(?![a-z0-9])`, 'i').test(x));
169
255
  if (!vinculo) {
170
- return resultado(threadId, 'recusada', `o PR #${n} de ${repo} nao cita a thread ${threadId} no titulo, no corpo nem na branch`, { mergeSha, headSha });
256
+ return resultado(threadId, 'recusada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prNaoCitaThread(n, repo, threadId, !!gitlab)), { mergeSha, headSha });
171
257
  }
172
- const repositorio = lerJson(gh(`repos/${repo}`));
173
- if (!repositorio)
174
- return resultado(threadId, 'recusada', `a consulta de ${repo} ao GitHub falhou`, { mergeSha, headSha });
175
- if (repositorio.default_branch !== base) {
176
- return resultado(threadId, 'recusada', `o PR #${n} entrou em ${base}, e a branch padrao de ${repo} e ${repositorio.default_branch ?? 'desconhecida'}`, { mergeSha, headSha });
258
+ const branchPadrao = (0, registro_1.exigirCapacidade)(forja, 'branchPadrao')({ repo, executor: gh, api });
259
+ if (branchPadrao === null)
260
+ return resultado(threadId, 'recusada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prRepoFalhou(repo, nomeDaForja)), { mergeSha, headSha });
261
+ if (branchPadrao !== base) {
262
+ return resultado(threadId, 'recusada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prOutraBase(n, base, repo, branchPadrao || undefined, !!gitlab)), { mergeSha, headSha });
177
263
  }
178
264
  // A ponta da base AGORA, e o merge dentro dela: o push provado, pela mesma pergunta do ls-remote.
179
- const ramo = lerJson(gh(`repos/${repo}/branches/${encodeURIComponent(base)}`));
180
- const ponta = typeof ramo?.commit?.sha === 'string' && /^[0-9a-f]{40}$/.test(ramo.commit.sha) ? ramo.commit.sha : '';
181
- const comparacao = ponta ? lerJson(gh(`repos/${repo}/compare/${mergeSha}...${ponta}`)) : null;
182
- if (!ponta || !comparacao || !['ahead', 'identical'].includes(String(comparacao.status))) {
183
- return resultado(threadId, 'recusada', `o merge ${mergeSha.slice(0, 7)} nao esta na ponta de ${repo}:${base}`, { mergeSha, headSha });
265
+ const ponta = (0, registro_1.exigirCapacidade)(forja, 'pontaDaBranch')({ repo, branch: base, executor: gh, api }) ?? '';
266
+ const comparacao = ponta ? (0, registro_1.exigirCapacidade)(forja, 'comparar')({ repo, de: mergeSha, ate: ponta, executor: gh, api }) : null;
267
+ if (!ponta || comparacao === null || !['ahead', 'identical'].includes(comparacao)) {
268
+ return resultado(threadId, 'recusada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prExternoForaDaPonta(mergeSha.slice(0, 7), repo, base)), { mergeSha, headSha });
184
269
  }
185
270
  const check = declarados[repo];
186
- const ci = check ? (0, ci_1.consultarCiDoRepositorio)(repo, headSha, check, opcoes.executorCi) : null;
271
+ const ciDaForja = opcoes.ciDaForja ?? ((f, sha, contexto) => (0, ci_1.consultarCiNaForja)(f, sha, contexto, (0, produtor_1.produtoresAceitos)(carregado.manifesto, 'gitlab'), { api: opcoes.api }));
272
+ const ci = !check ? null : gitlab ? ciDaForja(gitlab, headSha, check)
273
+ : (0, ci_1.consultarCiDoRepositorio)(repo, headSha, check, opcoes.executorCi, 'github.com', (0, produtor_1.produtoresAceitos)(carregado.manifesto, 'github'));
187
274
  if (ci && !ci.ok) {
188
- return resultado(threadId, 'recusada', `sem CI verde no head do PR: ${ci.detail}`, { mergeSha, headSha, ci });
275
+ return resultado(threadId, 'recusada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prSemCiVerde((0, locale_1.remontar)(ci.detail))), { mergeSha, headSha, ci });
189
276
  }
190
277
  if (opcoes.dryRun) {
191
- return resultado(threadId, 'registraria', `ensaio: registraria ship_done pelo merge ${mergeSha.slice(0, 7)} do PR #${n} de ${repo} (nada gravado)`, { mergeSha, headSha, ci });
278
+ return resultado(threadId, 'registraria', (0, locale_1.textoDoCatalogo)((m) => m.ship.prExternoRegistraria(mergeSha.slice(0, 7), n, repo, !!gitlab)), { mergeSha, headSha, ci });
192
279
  }
193
280
  (0, ledger_1.registrar)(dir, threadId, ledger_1.TIPOS_DE_EVENTO.shipConcluido, {
194
281
  de: thread.base?.branch ?? null,
195
282
  para: `${repo}:${base}`,
196
283
  repositorio: repo,
197
284
  pr: n,
198
- url: pr.html_url ?? `https://github.com/${repo}/pull/${n}`,
285
+ url: pr.url ?? (gitlab ? `https://${(0, cli_1.hostDaApi)(gitlab)}${gitlab.caminhoBase}/${repo}/-/merge_requests/${n}` : `https://github.com/${repo}/pull/${n}`),
199
286
  shaDe: headSha,
200
287
  mergeSha,
201
288
  // RM-037 (fatia 5, A1; aviso da rodada 1 do CHECK): a ponta conferida vai em campo proprio, como no PR local; a
202
289
  // comparacao aceita `ahead`, e o recibo do Maestro confere o push contra ela.
203
290
  pontaDaBase: ponta,
204
291
  jaIncorporado: true,
205
- remoto: `github:${repo}`,
292
+ remoto: `${gitlab ? 'gitlab' : 'github'}:${repo}`,
206
293
  shaRemoto: ponta,
207
294
  pushVerificado: true,
208
- fonteDaProva: `gh api repos/${repo}/compare/${mergeSha}...${ponta} (status ${String(comparacao.status)}; ponta de ${base} por gh api repos/${repo}/branches/${base})`,
295
+ // `identical`: o merge e a propria ponta, e a comparacao nem e consultada.
296
+ fonteDaProva: gitlab && comparacao === 'identical'
297
+ ? `merge = ponta de ${base} por glab api ${(0, pedidos_1.projetoNaApi)(repo)}/repository/branches/${encodeURIComponent(base)}`
298
+ : gitlab
299
+ ? `glab api ${(0, pedidos_1.projetoNaApi)(repo)}/repository/compare?from=${ponta}&to=${mergeSha}&straight=false (status ${comparacao}; ponta de ${base} por glab api ${(0, pedidos_1.projetoNaApi)(repo)}/repository/branches/${encodeURIComponent(base)})`
300
+ : `gh api repos/${repo}/compare/${mergeSha}...${ponta} (status ${comparacao}; ponta de ${base} por gh api repos/${repo}/branches/${base})`,
209
301
  autorizadoPor: ci ? 'merge de PR com o CI independente verde no SHA exato' : 'merge de PR em repositorio externo declarado sem CI no manifesto',
210
302
  tipoDeAutorizacao: 'pr-externo',
211
303
  modo: thread.modo,
@@ -215,22 +307,31 @@ function registrarEntregaExternaPorPr(carregado, threadId, opcoes) {
215
307
  avancarParaShip(raiz, threadId);
216
308
  if (opcoes.publicar !== false)
217
309
  (0, fabrica_publicar_1.publicarEmSegundoPlano)(raiz);
218
- return resultado(threadId, 'registrou', `ship_done pelo merge ${mergeSha.slice(0, 7)} do PR #${n} de ${repo}`, { mergeSha, headSha, ci });
310
+ return resultado(threadId, 'registrou', (0, locale_1.textoDoCatalogo)((m) => m.ship.prExternoRegistrou(mergeSha.slice(0, 7), n, repo, !!gitlab)), { mergeSha, headSha, ci });
219
311
  }
220
312
  /** `ork ship registrar-pr --todas`: toda thread aberta que ja tem merge `ship(<thread>)` na base. */
221
313
  function registrarEntregasPorPr(carregado, opcoes = {}) {
222
314
  const remoto = (0, branch_de_estado_1.exigirRemoto)(opcoes.remoto ?? 'origin', 'ship');
223
315
  const base = carregado.manifesto.worktree.base_branch;
224
- (0, util_1.exec)('git', ['fetch', '-q', '--', remoto, `+refs/heads/${base}:refs/remotes/${remoto}/${base}`], carregado.raiz);
225
- const r = (0, thread_1.listarIds)(carregado.raiz)
226
- .filter((id) => (0, thread_1.lerThread)(carregado.raiz, id).status !== 'fechada')
316
+ const busca = (0, util_1.exec)('git', ['fetch', '-q', '--', remoto, `+refs/heads/${base}:refs/remotes/${remoto}/${base}`], carregado.raiz);
317
+ const abertas = (0, thread_1.listarIds)(carregado.raiz).filter((id) => (0, thread_1.lerThread)(carregado.raiz, id).status !== 'fechada');
318
+ // Sem leitura do remoto nao ha como saber quais threads tem merge: uma recusa por thread aberta, nunca lista vazia.
319
+ if (!busca.ok) {
320
+ return abertas.map((id) => resultado(id, 'recusada', (0, locale_1.textoDoCatalogo)((m) => m.ship.prSemLeitura(remoto, base)), { codigo: 'entrega.sem-leitura' }));
321
+ }
322
+ // RM-058, integracao (T1.1): os arcos lidos uma vez para o lote; a thread do arco e pulada com o motivo, e as outras seguem.
323
+ const arcos = (0, noctum_guarda_1.lerArcosDaRaiz)(carregado.raiz);
324
+ const r = abertas
227
325
  .filter((id) => mergeDaEntrega(carregado.raiz, id, remoto, base) !== null)
228
326
  .map((id) => {
229
327
  try {
230
- return registrarEntregaPorPr(carregado, id, { ...opcoes, buscar: false, publicar: false });
328
+ const guarda = (0, noctum_guarda_1.guardaDaThread)(carregado.raiz, id, arcos.quando, { arcos });
329
+ if (guarda)
330
+ return resultado(id, 'pulada', guarda.texto, { codigo: guarda.motivo });
331
+ return registrarEntregaPorPr(carregado, id, { ...opcoes, buscar: false, publicar: false, arcos });
231
332
  }
232
333
  catch (e) {
233
- return resultado(id, 'recusada', e.message);
334
+ return resultado(id, 'recusada', e instanceof locale_1.ErroDoCatalogo ? (0, locale_1.textoDoCatalogo)(e.montar) : e.message);
234
335
  }
235
336
  });
236
337
  // Uma publicacao so para o lote inteiro, nao uma por thread.
@@ -60,7 +60,16 @@ function exigirEscopoDeEscrita(threads) {
60
60
  /** Um nome autorizado nao pode ser alias de outra thread ou de estado externo. */
61
61
  function validarDiretorioDeThread(raiz, id) {
62
62
  validarThreadDeEscrita(id);
63
- const dir = (0, estado_thread_1.estadoCanonico)(raiz, id);
63
+ let dir;
64
+ // RM-047: o estadoCanonico já recusa link (estado.link); aqui a recusa mantém o código do escopo.
65
+ try {
66
+ dir = (0, estado_thread_1.estadoCanonico)(raiz, id);
67
+ }
68
+ catch (e) {
69
+ if (e.message.startsWith('estado.link'))
70
+ throw new Error('scope.thread.alias');
71
+ throw e;
72
+ }
64
73
  for (const candidato of [path.dirname(path.dirname(dir)), path.dirname(dir), dir]) {
65
74
  const stat = fs.lstatSync(candidato, { throwIfNoEntry: false });
66
75
  if (!stat)
@@ -63,9 +63,10 @@ const projeto_alvo_1 = require("./projeto-alvo");
63
63
  const runtime_profiles_1 = require("./runtime-profiles");
64
64
  const thread_1 = require("./thread");
65
65
  const util_1 = require("./util");
66
+ const locale_1 = require("./locale");
66
67
  exports.CONTRATO_ESGOTAMENTOS = 'ork.esgotamentos/v1';
67
- exports.LIMITE_DO_RELATORIO = 'o registro guarda so as marcas vivas (uso bem sucedido, login reconferido e prazo vencido ' +
68
- 'apagam a marca): o total e um piso, valido enquanto a marca existe';
68
+ /** O limite que o `--json` leva: dado, sempre em pt-BR (RM-061, F3b: o texto mora no catalogo). */
69
+ exports.LIMITE_DO_RELATORIO = (0, locale_1.msg)('pt-BR').accounts.limiteDoRelatorio;
69
70
  exports.NAO_REGISTRADO = 'nao registrado';
70
71
  function contaOpaca(chave) {
71
72
  return (0, node_crypto_1.createHash)('sha256').update(chave).digest('hex').slice(0, 12);
@@ -160,22 +161,23 @@ function relatorioDeEsgotamentos(opcoes = {}) {
160
161
  }
161
162
  /** Texto para o terminal, com o horario do dono e o fuso uma vez no fim. */
162
163
  function textoDosEsgotamentos(r) {
164
+ // RM-061 (F3b): o texto pelo catalogo; o estado da marca so se traduz aqui, e o limite do `--json` (pt-BR) sai no locale.
165
+ const t = (0, locale_1.msg)().accounts;
163
166
  const linhas = [
164
- `Esgotamentos de conta ${(0, horario_1.formatarDataHora)(r.periodo.desde)} ate ${(0, horario_1.formatarDataHora)(r.periodo.ate)} ${r.periodo.intervalo}`,
165
- ` marcas vivas no registro: ${r.marcas.length}`,
167
+ t.esgotamentosTitulo((0, horario_1.formatarDataHora)(r.periodo.desde), (0, horario_1.formatarDataHora)(r.periodo.ate), r.periodo.intervalo),
168
+ t.marcasVivas(r.marcas.length),
166
169
  ];
167
170
  for (const m of r.marcas) {
168
- const ate = m.estado === 'esgotado' ? `ate ${(0, horario_1.formatarDataHora)(m.esgotadoAte)}` : 'sem prazo';
169
- linhas.push(` conta ${m.conta} ${m.runtime} ${m.estado} desde ${(0, horario_1.formatarDataHora)(m.em)}, ${ate} visto em ${m.projeto} (${m.motivo})`);
171
+ linhas.push(t.marca(m.conta, m.runtime, t.estado(m.estado), (0, horario_1.formatarDataHora)(m.em), m.estado === 'esgotado' ? (0, horario_1.formatarDataHora)(m.esgotadoAte) : null, m.projeto, m.motivo));
170
172
  }
171
- linhas.push(` projetos lidos: ${r.projetos.length === 0 ? 'nenhum registrado'
172
- : r.projetos.map((p) => `${p.nome} (${p.presente ? `${p.despachosComPerfil} despacho(s) com perfil` : 'fora do disco'})`).join(', ')}`);
173
- linhas.push(` despachos em conta marcada por outro projeto: ${r.total}`);
173
+ linhas.push(t.projetosLidos(r.projetos.length === 0 ? null
174
+ : r.projetos.map((p) => t.projetoLido(p.nome, p.presente ? p.despachosComPerfil : null)).join(', ')));
175
+ linhas.push(t.despachosMarcados(r.total));
174
176
  if (r.despachos.length > 0) {
175
- linhas.push((0, util_1.tabela)(['QUANDO', 'PROJETO', 'THREAD', 'FASE', 'PERFIL', 'CONTA', 'MARCADA POR'], r.despachos.map((d) => [(0, horario_1.formatarDataHora)(d.em), d.projeto, d.thread, d.fase ?? '-', d.perfil, d.conta, d.marcadaPor]))
177
+ linhas.push((0, util_1.tabela)([...t.colunasDosDespachos], r.despachos.map((d) => [(0, horario_1.formatarDataHora)(d.em), d.projeto, d.thread, d.fase ?? '-', d.perfil, d.conta, d.marcadaPor]))
176
178
  .split('\n').map((l) => ` ${l}`).join('\n'));
177
179
  }
178
- linhas.push(` limite: ${r.limite}`);
180
+ linhas.push(t.limite(r.limite === exports.LIMITE_DO_RELATORIO ? t.limiteDoRelatorio : r.limite));
179
181
  linhas.push((0, horario_1.legendaDoFuso)());
180
182
  return linhas.join('\n');
181
183
  }
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.raizDoEstado = raizDoEstado;
37
37
  exports.estadoCanonico = estadoCanonico;
38
+ exports.exigirEstadoSemLink = exigirEstadoSemLink;
38
39
  exports.vincularEstado = vincularEstado;
39
40
  exports.comEstadoParaGit = comEstadoParaGit;
40
41
  exports.auditarEstado = auditarEstado;
@@ -43,6 +44,7 @@ const fs = __importStar(require("node:fs"));
43
44
  const path = __importStar(require("node:path"));
44
45
  const node_crypto_1 = require("node:crypto");
45
46
  const util_1 = require("./util");
47
+ const locale_1 = require("./locale");
46
48
  function raizDoEstado(raiz) {
47
49
  const local = path.resolve(raiz);
48
50
  const git = path.join(local, '.git');
@@ -50,7 +52,7 @@ function raizDoEstado(raiz) {
50
52
  return local;
51
53
  const match = /^gitdir: (.+)\s*$/m.exec(fs.readFileSync(git, 'utf8'));
52
54
  if (!match)
53
- throw new Error(`.git inválido em ${local}`);
55
+ throw new locale_1.ErroDoCatalogo((m) => m.estado.gitInvalido(local));
54
56
  const gitdir = path.resolve(local, match[1].trim());
55
57
  const commondir = path.join(gitdir, 'commondir');
56
58
  if (!fs.existsSync(commondir))
@@ -59,14 +61,35 @@ function raizDoEstado(raiz) {
59
61
  const principal = path.dirname(comum);
60
62
  if (!fs.existsSync(path.join(principal, '.git')) ||
61
63
  fs.realpathSync(path.join(principal, '.git')) !== fs.realpathSync(comum)) {
62
- throw new Error(`árvore principal não resolvida pelo git-common-dir: ${comum}`);
64
+ throw new locale_1.ErroDoCatalogo((m) => m.estado.arvorePrincipal(comum));
63
65
  }
64
66
  return principal;
65
67
  }
66
68
  function estadoCanonico(raiz, id) {
67
69
  if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(id))
68
- throw new Error('id de thread inválido');
69
- return path.join(raizDoEstado(raiz), '.orkastery', 'threads', id);
70
+ throw new locale_1.ErroDoCatalogo((m) => m.estado.idInvalido);
71
+ const principal = raizDoEstado(raiz);
72
+ exigirEstadoSemLink(principal, ['.orkastery', 'threads', id]);
73
+ return path.join(principal, '.orkastery', 'threads', id);
74
+ }
75
+ /**
76
+ * RM-047 (fronteira de confiança): na árvore principal, `.orkastery`, `threads` e o diretório da thread
77
+ * são pastas de verdade. Um link versionado no clone levaria ledger, claims e thread.json para fora da
78
+ * raiz, e o `ork` anexaria linhas em arquivo alheio. O link que o próprio `ork` cria fica na worktree
79
+ * (`vincularEstado`) e aponta para cá; ele nunca é um destes componentes.
80
+ */
81
+ function exigirEstadoSemLink(principal, componentes) {
82
+ let atual = principal;
83
+ for (const nome of componentes) {
84
+ atual = path.join(atual, nome);
85
+ const stat = fs.lstatSync(atual, { throwIfNoEntry: false });
86
+ if (!stat)
87
+ return;
88
+ if (stat.isSymbolicLink()) {
89
+ const rel = path.relative(principal, atual);
90
+ throw new locale_1.ErroDoCatalogo((m) => m.estado.link(rel));
91
+ }
92
+ }
70
93
  }
71
94
  function mesmoArquivo(a, b) {
72
95
  return fs.existsSync(a) && fs.existsSync(b) && fs.realpathSync(a) === fs.realpathSync(b);
@@ -75,11 +98,11 @@ function arquivos(dir, prefixo = '') {
75
98
  return fs.readdirSync(path.join(dir, prefixo), { withFileTypes: true }).flatMap(e => {
76
99
  const nome = path.join(prefixo, e.name);
77
100
  if (e.isSymbolicLink())
78
- throw new Error(`estado legado contém link: ${nome}`);
101
+ throw new locale_1.ErroDoCatalogo((m) => m.estado.legadoComLink(nome));
79
102
  if (e.isDirectory())
80
103
  return arquivos(dir, nome);
81
104
  if (!e.isFile())
82
- throw new Error(`estado legado contém arquivo especial: ${nome}`);
105
+ throw new locale_1.ErroDoCatalogo((m) => m.estado.legadoEspecial(nome));
83
106
  return [nome];
84
107
  });
85
108
  }
@@ -100,18 +123,18 @@ function vincularEstado(raiz, id, worktree, dryRun = false) {
100
123
  if (path.resolve(local) === alvo)
101
124
  return;
102
125
  if (raizDoEstado(worktree) !== raizDoEstado(raiz))
103
- throw new Error('worktree não pertence à árvore principal');
126
+ throw new locale_1.ErroDoCatalogo((m) => m.estado.foraDaArvore);
104
127
  // O índice é próprio da linked worktree. A main continua versionando seu estado.
105
128
  const rastreados = (0, util_1.exec)('git', ['ls-files', '-z', '--', `.orkastery/threads/${id}/`], worktree);
106
129
  if (!rastreados.ok)
107
- throw new Error(`índice da worktree indisponível: ${rastreados.stderr}`);
130
+ throw new locale_1.ErroDoCatalogo((m) => m.estado.indiceIndisponivel(rastreados.stderr));
108
131
  const nomes = rastreados.stdout.split('\0').filter(Boolean);
109
132
  const prepararIndice = () => {
110
133
  if (dryRun || nomes.length === 0)
111
134
  return;
112
135
  const r = (0, util_1.exec)('git', ['update-index', '--skip-worktree', '--', ...nomes], worktree);
113
136
  if (!r.ok)
114
- throw new Error(`não foi possível preservar o estado versionado no índice: ${r.stderr}`);
137
+ throw new locale_1.ErroDoCatalogo((m) => m.estado.naoPreservou(r.stderr));
115
138
  };
116
139
  if (mesmoArquivo(local, alvo)) {
117
140
  prepararIndice();
@@ -122,11 +145,11 @@ function vincularEstado(raiz, id, worktree, dryRun = false) {
122
145
  const copiar = [];
123
146
  const existe = fs.existsSync(local);
124
147
  if (!existe && fs.lstatSync(path.dirname(local), { throwIfNoEntry: false })?.isSymbolicLink()) {
125
- throw new Error('diretório de threads inesperadamente vinculado');
148
+ throw new locale_1.ErroDoCatalogo((m) => m.estado.threadsVinculado);
126
149
  }
127
150
  if (existe) {
128
151
  if (fs.lstatSync(local).isSymbolicLink())
129
- throw new Error(`link de estado aponta para outro destino: ${local}`);
152
+ throw new locale_1.ErroDoCatalogo((m) => m.estado.linkOutroDestino(local));
130
153
  for (const nome of arquivos(local)) {
131
154
  const destino = path.join(alvo, nome);
132
155
  if (!fs.existsSync(destino)) {
@@ -140,11 +163,11 @@ function vincularEstado(raiz, id, worktree, dryRun = false) {
140
163
  // Prefixo JSONL já incorporado na main não é conflito nem deve ser duplicado.
141
164
  if (nome.endsWith('.jsonl') && a.toString().endsWith('\n') && b.subarray(0, a.length).equals(a))
142
165
  continue;
143
- throw new Error(`estado dividido: ${nome} diverge entre ${local} e ${alvo}; reconcilie antes do sync`);
166
+ throw new locale_1.ErroDoCatalogo((m) => m.estado.dividido(nome, local, alvo));
144
167
  }
145
168
  }
146
169
  else if (fs.lstatSync(local, { throwIfNoEntry: false })) {
147
- throw new Error(`link de estado quebrado: ${local}`);
170
+ throw new locale_1.ErroDoCatalogo((m) => m.estado.linkQuebrado(local));
148
171
  }
149
172
  // O ensaio executa o mesmo preflight, sem tocar em arquivos ou no índice.
150
173
  if (dryRun)
@@ -178,7 +201,7 @@ function comEstadoParaGit(raiz, id, worktree, executar) {
178
201
  const git = (args) => {
179
202
  const r = (0, util_1.exec)('git', args, worktree);
180
203
  if (!r.ok)
181
- throw new Error(`preparação do estado para Git falhou: ${r.stderr || r.stdout}`);
204
+ throw new locale_1.ErroDoCatalogo((m) => m.estado.preparacaoFalhou(r.stderr || r.stdout));
182
205
  return r.stdout;
183
206
  };
184
207
  const nomes = git(['ls-files', '-z', '--', prefixo]).split('\0').filter(Boolean);
@@ -198,7 +221,7 @@ function comEstadoParaGit(raiz, id, worktree, executar) {
198
221
  const mudou = materializado && (!(0, util_1.exec)('git', ['diff', '--quiet', '--', prefixo], worktree).ok ||
199
222
  git(['ls-files', '--others', '--', prefixo]).trim() !== '');
200
223
  if (mudou)
201
- throw new Error(`estado local alterado durante operação Git: ${local}; cópia e main preservadas para reconciliação`);
224
+ throw new locale_1.ErroDoCatalogo((m) => m.estado.alteradoDuranteGit(local));
202
225
  if (fs.existsSync(local)) {
203
226
  const backup = path.join(raizDoEstado(raiz), '.orkastery', 'state-backups', `${id}-git-${(0, node_crypto_1.randomUUID)()}`);
204
227
  fs.mkdirSync(path.dirname(backup), { recursive: true });
@@ -216,7 +239,9 @@ function auditarEstado(raiz, id, worktree) {
216
239
  return fs.existsSync(file) ? fs.readFileSync(file, 'utf8').split('\n').filter(Boolean).length : 0;
217
240
  };
218
241
  const ok = mesmoArquivo(main, local);
242
+ // RM-061 (F3b, G4): o detalhe vai ao ledger do audit em pt-BR (escopo da gravacao) e a impressao o remonta.
243
+ const eventosMain = contar(main), eventosLocal = contar(local);
219
244
  return { nome: 'estado-unico', nivel: ok ? 'ok' : 'fail',
220
- detalhe: `${ok ? 'mesmo estado' : 'estado dividido'}: main=${contar(main)} eventos, worktree=${contar(local)} eventos; ${main}`,
221
- ...(ok ? {} : { correcao: `ork worktree sync ${id}; divergências exigem reconciliação preservando evidências` }) };
245
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => m.estado.estadoUnico(ok, eventosMain, eventosLocal, main)),
246
+ ...(ok ? {} : { correcao: (0, locale_1.textoDoCatalogo)((m) => m.estado.estadoUnicoCorrecao(id)) }) };
222
247
  }