@orkastery/cli 0.5.6 → 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 (385) 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 +37 -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/ork-mensageiro/.claude-plugin/plugin.json +14 -0
  16. package/adapters/claude-code/mods/ork-mensageiro/hooks/caixa.ts +215 -0
  17. package/adapters/claude-code/mods/ork-mensageiro/hooks/hooks.json +3 -0
  18. package/adapters/claude-code/mods/ork-mensageiro/hooks/painel.tsx +165 -0
  19. package/adapters/claude-code/mods/ork-mensageiro/hooks/recepcao.ts +256 -0
  20. package/adapters/claude-code/mods/ork-mensageiro/hooks/register.tsx +481 -0
  21. package/adapters/claude-code/mods/ork-mensageiro/orkastery-mod.json +5 -0
  22. package/adapters/claude-code/mods/ork-mensageiro/types/index.d.ts +85 -0
  23. package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +9 -5
  24. package/adapters/claude-code/mods/ork-ritual/.claude-plugin/plugin.json +14 -0
  25. package/adapters/claude-code/mods/ork-ritual/hooks/hooks.json +3 -0
  26. package/adapters/claude-code/mods/ork-ritual/hooks/nota.ts +88 -0
  27. package/adapters/claude-code/mods/ork-ritual/hooks/register.tsx +494 -0
  28. package/adapters/claude-code/mods/ork-ritual/hooks/replay.tsx +271 -0
  29. package/adapters/claude-code/mods/ork-ritual/hooks/ritual.ts +218 -0
  30. package/adapters/claude-code/mods/ork-ritual/orkastery-mod.json +5 -0
  31. package/adapters/claude-code/mods/ork-ritual/types/index.d.ts +106 -0
  32. package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +1 -1
  33. package/adapters/codex/skills/ork/SKILL.md +2 -0
  34. package/adapters/hermes/README.md +64 -1
  35. package/adapters/hermes/bin/ork-conhecimento-colecoes.sh +14 -0
  36. package/adapters/hermes/bin/ork-conhecimento-listar.sh +15 -0
  37. package/adapters/hermes/bin/ork-conhecimento-mostrar.sh +16 -0
  38. package/adapters/hermes/bin/ork-conhecimento-verificar.sh +15 -0
  39. package/adapters/hermes/bin/ork-vigia-batida.py +127 -0
  40. package/adapters/hermes/hermes.plugin.json +4 -0
  41. package/adapters/hermes/hitl-ingress/__init__.py +101 -8
  42. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +2 -2
  43. package/adapters/openclaw/README.md +81 -9
  44. package/adapters/openclaw/bin/ork-vigia-batida.js +86 -0
  45. package/adapters/openclaw/dist/hitl-ingress.js +106 -9
  46. package/adapters/openclaw/dist/index.js +86 -0
  47. package/adapters/openclaw/openclaw.plugin.json +34 -4
  48. package/adapters/openclaw/package.json +2 -2
  49. package/adapters/openclaw/src/hitl-ingress.ts +103 -9
  50. package/adapters/openclaw/src/index.ts +94 -0
  51. package/assets/adapters-en/claude-code/README.md +403 -0
  52. package/assets/adapters-en/claude-code/agents/ork-check.md +33 -0
  53. package/assets/adapters-en/claude-code/agents/ork-go.md +33 -0
  54. package/assets/adapters-en/claude-code/agents/ork-goal.md +34 -0
  55. package/assets/adapters-en/claude-code/agents/ork-master.md +35 -0
  56. package/assets/adapters-en/claude-code/agents/ork-plan.md +33 -0
  57. package/assets/adapters-en/claude-code/agents/ork-ship.md +33 -0
  58. package/assets/adapters-en/claude-code/commands/check.md +46 -0
  59. package/assets/adapters-en/claude-code/commands/go.md +46 -0
  60. package/assets/adapters-en/claude-code/commands/goal.md +55 -0
  61. package/assets/adapters-en/claude-code/commands/master.md +54 -0
  62. package/assets/adapters-en/claude-code/commands/onboarding.md +22 -0
  63. package/assets/adapters-en/claude-code/commands/ork.md +126 -0
  64. package/assets/adapters-en/claude-code/commands/plan.md +47 -0
  65. package/assets/adapters-en/claude-code/commands/ship.md +45 -0
  66. package/assets/adapters-en/codex/skills/ork/SKILL.md +85 -0
  67. package/assets/adapters-en/hermes/README.md +273 -0
  68. package/assets/adapters-en/hermes/skills/orkastery-devmaster/SKILL.md +169 -0
  69. package/assets/references-en/README.md +25 -0
  70. package/assets/references-en/code-review-axes.md +82 -0
  71. package/assets/references-en/definition-of-done.md +74 -0
  72. package/assets/references-en/performance-checklist.md +53 -0
  73. package/assets/references-en/security-checklist.md +101 -0
  74. package/assets/references-en/testing-patterns.md +51 -0
  75. package/assets/security-scan/defaults/.golangci.yml +2 -0
  76. package/assets/security-scan/defaults/eslint.config.mjs +11 -0
  77. package/assets/security-scan/defaults/gitleaks.toml +3 -0
  78. package/assets/security-scan/defaults/ruff.toml +1 -0
  79. package/assets/security-scan/tools-agil.json +87 -0
  80. package/assets/security-scan/tools.json +625 -0
  81. package/assets/skills-en/core/onboarding/SKILL.md +58 -0
  82. package/assets/skills-en/core/orkastery-bootstrap/SKILL.md +119 -0
  83. package/assets/skills-en/core/thread-state/SKILL.md +88 -0
  84. package/assets/skills-en/governance/decision-triage/SKILL.md +65 -0
  85. package/assets/skills-en/governance/narrative-guardian/SKILL.md +66 -0
  86. package/assets/skills-en/governance/roadmap-keeper/SKILL.md +60 -0
  87. package/assets/skills-en/governance/scope-check-capability-map/SKILL.md +71 -0
  88. package/assets/skills-en/observability/thread-tracing/SKILL.md +63 -0
  89. package/assets/skills-en/phases/check-quality/SKILL.md +103 -0
  90. package/assets/skills-en/phases/go-implementation/SKILL.md +78 -0
  91. package/assets/skills-en/phases/goal-definition/SKILL.md +69 -0
  92. package/assets/skills-en/phases/master-metrics/SKILL.md +72 -0
  93. package/assets/skills-en/phases/plan-specification/SKILL.md +67 -0
  94. package/assets/skills-en/phases/security-remediation/SKILL.md +70 -0
  95. package/assets/skills-en/phases/ship-release/SKILL.md +71 -0
  96. package/assets/skills-en/reviewers/code-reviewer/SKILL.md +61 -0
  97. package/assets/skills-en/reviewers/security-auditor/SKILL.md +93 -0
  98. package/assets/skills-en/reviewers/test-engineer/SKILL.md +66 -0
  99. package/assets/skills-en/reviewers/web-performance-auditor/SKILL.md +63 -0
  100. package/dist/adapters/claude-bg.js +118 -4
  101. package/dist/adapters/codex-controller-worker.js +12 -5
  102. package/dist/adapters/codex-events.js +16 -4
  103. package/dist/adapters/codex.js +3 -1
  104. package/dist/atualizar-branch.js +245 -0
  105. package/dist/auditoria.js +13 -11
  106. package/dist/auditrun.js +51 -46
  107. package/dist/autorizacao-duravel.js +327 -0
  108. package/dist/board.js +94 -40
  109. package/dist/branch-de-estado.js +16 -8
  110. package/dist/busca-semantica.js +7 -5
  111. package/dist/catalogo.js +2 -1
  112. package/dist/changelog-reconciliacao.js +290 -0
  113. package/dist/check-agil.js +500 -0
  114. package/dist/check-modo.js +41 -0
  115. package/dist/check-paralelo.js +183 -0
  116. package/dist/ci.js +248 -45
  117. package/dist/ciclos.js +8 -6
  118. package/dist/claim-lint.js +12 -8
  119. package/dist/claims-conferir.js +47 -39
  120. package/dist/claims.js +10 -9
  121. package/dist/company-brain-client.js +10 -3
  122. package/dist/company-brain-migration.js +11 -5
  123. package/dist/conducao-batida.js +759 -0
  124. package/dist/conducao-sentinela.js +25 -8
  125. package/dist/conducao.js +84 -29
  126. package/dist/conhecimento-consulta.js +270 -0
  127. package/dist/conhecimento.js +111 -87
  128. package/dist/conta-esgotada.js +127 -0
  129. package/dist/dado-privado.js +816 -0
  130. package/dist/decisao-autonoma.js +5 -4
  131. package/dist/demo.js +14 -12
  132. package/dist/dependencias-da-worktree.js +25 -0
  133. package/dist/divida.js +38 -36
  134. package/dist/docs.js +81 -74
  135. package/dist/doctor-forja.js +345 -0
  136. package/dist/doctor-pulse-cron.js +113 -1
  137. package/dist/doctor.js +164 -6
  138. package/dist/dsn-da-memoria.js +417 -0
  139. package/dist/entrega-por-mod.js +503 -0
  140. package/dist/entrega-pr.js +143 -43
  141. package/dist/esgotamentos.js +13 -11
  142. package/dist/estado-thread.js +21 -18
  143. package/dist/evalrunner.js +35 -32
  144. package/dist/fabrica-batida.js +34 -21
  145. package/dist/fabrica-estado.js +13 -10
  146. package/dist/fix.js +21 -19
  147. package/dist/forja/adaptador.js +6 -0
  148. package/dist/forja/ambiente-de-ci.js +27 -0
  149. package/dist/forja/api.js +256 -0
  150. package/dist/forja/cache.js +89 -0
  151. package/dist/forja/cli.js +60 -0
  152. package/dist/forja/contrato.js +9 -0
  153. package/dist/forja/endereco.js +43 -0
  154. package/dist/forja/estado.js +22 -0
  155. package/dist/forja/executor.js +73 -0
  156. package/dist/forja/github/ci.js +95 -0
  157. package/dist/forja/github/dono-da-rede.js +18 -0
  158. package/dist/forja/github/metadados.js +15 -0
  159. package/dist/forja/github/pedidos.js +200 -0
  160. package/dist/forja/gitlab/ci.js +141 -0
  161. package/dist/forja/gitlab/consultas.js +59 -0
  162. package/dist/forja/gitlab/dono-da-rede.js +43 -0
  163. package/dist/forja/gitlab/metadados.js +15 -0
  164. package/dist/forja/gitlab/pedidos-abertos.js +158 -0
  165. package/dist/forja/gitlab/pedidos.js +141 -0
  166. package/dist/forja/produtor.js +32 -0
  167. package/dist/forja/registro.js +31 -0
  168. package/dist/forja/resolver.js +121 -0
  169. package/dist/forja/texto.js +13 -0
  170. package/dist/forja/versao.js +71 -0
  171. package/dist/forja.js +123 -80
  172. package/dist/handoff.js +23 -13
  173. package/dist/hitl-contract.js +46 -43
  174. package/dist/hitl-curto.js +37 -25
  175. package/dist/hitl-gates.js +13 -11
  176. package/dist/hitl-local-receipt.js +51 -0
  177. package/dist/hitl-local.js +11 -2
  178. package/dist/hitl-lock.js +5 -11
  179. package/dist/hitl-public-receipt.js +11 -0
  180. package/dist/hitl-resumo.js +44 -1
  181. package/dist/hitl-sessions.js +62 -9
  182. package/dist/hitl-texto-livre.js +7 -4
  183. package/dist/hitl.js +34 -31
  184. package/dist/horario.js +16 -0
  185. package/dist/hosts.js +104 -134
  186. package/dist/index.js +848 -548
  187. package/dist/indice-vetorial.js +14 -12
  188. package/dist/init.js +11 -2
  189. package/dist/integracoes-locais.js +2 -0
  190. package/dist/intelligence-graph-cli.js +123 -69
  191. package/dist/intelligence-graph-query.js +37 -22
  192. package/dist/leases.js +19 -18
  193. package/dist/ledger-stats.js +17 -16
  194. package/dist/ledger.js +31 -1
  195. package/dist/licoes.js +12 -11
  196. package/dist/locale-accounts.js +220 -0
  197. package/dist/locale-adapter.js +291 -0
  198. package/dist/locale-ajuda.js +76 -4
  199. package/dist/locale-audit.js +199 -0
  200. package/dist/locale-claims.js +213 -0
  201. package/dist/locale-conducao.js +138 -0
  202. package/dist/locale-conhecimento.js +181 -0
  203. package/dist/locale-decisao.js +205 -0
  204. package/dist/locale-docs.js +230 -0
  205. package/dist/locale-estado.js +101 -0
  206. package/dist/locale-forja.js +290 -0
  207. package/dist/locale-gerados.js +5 -0
  208. package/dist/locale-grafo.js +129 -0
  209. package/dist/locale-master.js +83 -0
  210. package/dist/locale-network.js +524 -0
  211. package/dist/locale-operacao-restante.js +931 -0
  212. package/dist/locale-projetos.js +100 -0
  213. package/dist/locale-prompts.js +194 -0
  214. package/dist/locale-pulse.js +140 -2
  215. package/dist/locale-reservas.js +87 -0
  216. package/dist/locale-retry.js +145 -6
  217. package/dist/locale-security-scan.js +69 -0
  218. package/dist/locale-setup.js +192 -0
  219. package/dist/locale-ship.js +169 -66
  220. package/dist/locale-thread.js +149 -5
  221. package/dist/locale-verify.js +80 -4
  222. package/dist/locale-worktree.js +246 -0
  223. package/dist/locale.js +553 -9
  224. package/dist/maestro-runtime.js +22 -3
  225. package/dist/manifest.js +287 -11
  226. package/dist/maquina-ociosa.js +211 -0
  227. package/dist/maquina.js +10 -5
  228. package/dist/master-nota-local.js +200 -0
  229. package/dist/master-nota.js +10 -2
  230. package/dist/master.js +118 -41
  231. package/dist/mcp-conhecimento.js +52 -0
  232. package/dist/mcp-experiencia.js +26 -5
  233. package/dist/mcp-install.js +73 -8
  234. package/dist/mcp-noctum.js +101 -0
  235. package/dist/mcp-server.js +82 -14
  236. package/dist/mcp-ship-transporte.js +977 -0
  237. package/dist/mcp-ship.js +68 -24
  238. package/dist/mcp-transportes.js +17 -0
  239. package/dist/memoria.js +63 -58
  240. package/dist/modos-migracao.js +8 -6
  241. package/dist/modos.js +17 -18
  242. package/dist/network-roadmap.js +85 -49
  243. package/dist/noctum-aceite.js +789 -0
  244. package/dist/noctum-arco.js +540 -33
  245. package/dist/noctum-capacidade.js +3 -3
  246. package/dist/noctum-changelog.js +399 -0
  247. package/dist/noctum-cli.js +482 -0
  248. package/dist/noctum-coordenacao.js +1225 -0
  249. package/dist/noctum-entrega.js +1169 -0
  250. package/dist/noctum-envelope.js +252 -16
  251. package/dist/noctum-execucao.js +95 -23
  252. package/dist/noctum-fechamento.js +405 -0
  253. package/dist/noctum-fila.js +43 -9
  254. package/dist/noctum-guarda.js +256 -0
  255. package/dist/noctum-integracao.js +507 -0
  256. package/dist/noctum-maquinas.js +383 -0
  257. package/dist/noctum-medicao.js +450 -0
  258. package/dist/noctum-modo.js +362 -0
  259. package/dist/noctum-pergunta-canal.js +96 -0
  260. package/dist/noctum-pergunta.js +115 -0
  261. package/dist/noctum-provas.js +838 -0
  262. package/dist/noctum-reconciliacao.js +591 -0
  263. package/dist/noctum-registro.js +215 -0
  264. package/dist/noctum-relatorio.js +827 -0
  265. package/dist/noctum-resposta.js +207 -0
  266. package/dist/noctum-sessoes-em-voo.js +93 -0
  267. package/dist/noctum-supervisao.js +649 -0
  268. package/dist/noctum-terminal.js +459 -0
  269. package/dist/noctum-transporte.js +655 -0
  270. package/dist/noctum-vigia.js +639 -0
  271. package/dist/ocupacao.js +3 -1
  272. package/dist/onboarding.js +16 -5
  273. package/dist/orkmind.js +39 -23
  274. package/dist/orquestracao.js +31 -35
  275. package/dist/parado-no-condutor.js +146 -124
  276. package/dist/phase.js +53 -27
  277. package/dist/policies.js +33 -0
  278. package/dist/postura-local.js +4 -3
  279. package/dist/procedencia.js +9 -14
  280. package/dist/projeto-alvo.js +59 -20
  281. package/dist/prompts.js +136 -42
  282. package/dist/prova-minima.js +5 -6
  283. package/dist/pulse-cadencia.js +5 -4
  284. package/dist/pulse-consentimento.js +53 -1
  285. package/dist/pulse-delivery.js +143 -27
  286. package/dist/pulse-resposta.js +368 -4
  287. package/dist/pulse.js +136 -3
  288. package/dist/ratelimit.js +12 -4
  289. package/dist/recall.js +14 -13
  290. package/dist/rede-adesao.js +13 -8
  291. package/dist/rede-forja.js +108 -24
  292. package/dist/rede-status.js +63 -45
  293. package/dist/rede.js +86 -46
  294. package/dist/retomada-checkpoint.js +101 -0
  295. package/dist/retry.js +228 -73
  296. package/dist/roadmap-reservas.js +32 -32
  297. package/dist/runtime-ambiente.js +5 -0
  298. package/dist/runtime-context.js +117 -43
  299. package/dist/runtime-escada.js +423 -0
  300. package/dist/runtime-profiles.js +103 -46
  301. package/dist/saida-segura.js +3 -2
  302. package/dist/security-scan/agil.js +355 -0
  303. package/dist/security-scan/cli.js +76 -0
  304. package/dist/security-scan/compare.js +149 -0
  305. package/dist/security-scan/config.js +93 -0
  306. package/dist/security-scan/detect.js +97 -0
  307. package/dist/security-scan/executor.js +188 -0
  308. package/dist/security-scan/guard.js +180 -0
  309. package/dist/security-scan/imagem-de-lint.js +96 -0
  310. package/dist/security-scan/normalize/actionlint.js +12 -0
  311. package/dist/security-scan/normalize/eslint.js +12 -0
  312. package/dist/security-scan/normalize/gitleaks.js +13 -0
  313. package/dist/security-scan/normalize/golangci-lint.js +13 -0
  314. package/dist/security-scan/normalize/govulncheck.js +36 -0
  315. package/dist/security-scan/normalize/index.js +25 -0
  316. package/dist/security-scan/normalize/npm-audit.js +30 -0
  317. package/dist/security-scan/normalize/osv-scanner.js +32 -0
  318. package/dist/security-scan/normalize/oxlint.js +51 -0
  319. package/dist/security-scan/normalize/pip-audit.js +16 -0
  320. package/dist/security-scan/normalize/ruff.js +12 -0
  321. package/dist/security-scan/normalize/semgrep.js +20 -0
  322. package/dist/security-scan/normalize/trivy.js +33 -0
  323. package/dist/security-scan/normalize/util.js +204 -0
  324. package/dist/security-scan/normalize/zizmor.js +19 -0
  325. package/dist/security-scan/report.js +156 -0
  326. package/dist/security-scan/run.js +448 -0
  327. package/dist/security-scan/tools.js +62 -0
  328. package/dist/security-scan/trabalhador.js +74 -0
  329. package/dist/security-scan/types.js +15 -0
  330. package/dist/session-events.js +19 -2
  331. package/dist/session-watcher-claude.js +74 -19
  332. package/dist/session-watcher.js +156 -10
  333. package/dist/sessoes-contas.js +9 -0
  334. package/dist/sessoes-inventario.js +1 -1
  335. package/dist/sessoes.js +25 -23
  336. package/dist/setup.js +59 -58
  337. package/dist/ship-publicar.js +263 -92
  338. package/dist/ship.js +160 -17
  339. package/dist/superficie.js +14 -11
  340. package/dist/thread-close.js +9 -9
  341. package/dist/thread.js +121 -18
  342. package/dist/tokens.js +15 -11
  343. package/dist/trabalho-thread.js +297 -0
  344. package/dist/transporte-do-canal.js +189 -0
  345. package/dist/types.js +12 -1
  346. package/dist/util.js +5 -2
  347. package/dist/varredura-acoes.js +507 -0
  348. package/dist/verify.js +472 -29
  349. package/dist/worktree-local.js +12 -10
  350. package/dist/worktree.js +81 -85
  351. package/eval/casos/check-quality.json +77 -0
  352. package/eval/casos/security-auditor.json +148 -0
  353. package/eval/casos/security-remediation.json +161 -0
  354. package/eval/fixtures/security-scan/README.md +8 -0
  355. package/eval/fixtures/security-scan/go/.github/workflows/ci.yml +12 -0
  356. package/eval/fixtures/security-scan/go/Dockerfile +4 -0
  357. package/eval/fixtures/security-scan/go/README.md +4 -0
  358. package/eval/fixtures/security-scan/go/config.go +4 -0
  359. package/eval/fixtures/security-scan/go/go.mod +5 -0
  360. package/eval/fixtures/security-scan/go/go.sum +2 -0
  361. package/eval/fixtures/security-scan/go/main.go +31 -0
  362. package/eval/fixtures/security-scan/js/.github/workflows/ci.yml +12 -0
  363. package/eval/fixtures/security-scan/js/Dockerfile +3 -0
  364. package/eval/fixtures/security-scan/js/README.md +4 -0
  365. package/eval/fixtures/security-scan/js/package-lock.json +844 -0
  366. package/eval/fixtures/security-scan/js/package.json +10 -0
  367. package/eval/fixtures/security-scan/js/src/config.js +4 -0
  368. package/eval/fixtures/security-scan/js/src/server.js +17 -0
  369. package/eval/fixtures/security-scan/js/src/util.ts +4 -0
  370. package/eval/fixtures/security-scan/js/tsconfig.json +4 -0
  371. package/eval/fixtures/security-scan/python/.github/workflows/ci.yml +12 -0
  372. package/eval/fixtures/security-scan/python/Dockerfile +3 -0
  373. package/eval/fixtures/security-scan/python/README.md +4 -0
  374. package/eval/fixtures/security-scan/python/app/__init__.py +0 -0
  375. package/eval/fixtures/security-scan/python/app/config.py +2 -0
  376. package/eval/fixtures/security-scan/python/app/main.py +19 -0
  377. package/eval/fixtures/security-scan/python/requirements.txt +1 -0
  378. package/package.json +9 -4
  379. package/references/security-checklist.md +3 -3
  380. package/skills/README.md +1 -0
  381. package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
  382. package/skills/phases/check-quality/SKILL.md +16 -0
  383. package/skills/phases/go-implementation/SKILL.md +6 -0
  384. package/skills/phases/security-remediation/SKILL.md +70 -0
  385. package/skills/reviewers/security-auditor/SKILL.md +25 -0
@@ -33,11 +33,12 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.CONTRATO_FORJA_SEM_LEITURA = exports.ghPadrao = exports.FORJA_SEM_LEITURA = exports.LIMITE_DE_RECENTES = exports.LIMITE_DE_PRS = exports.VALIDADE_DO_RETRATO_MIN = exports.LIMIAR_PARADO_NO_CONDUTOR_MIN = exports.CONTRATO_PRS = void 0;
36
+ exports.CONTRATO_FORJA_SEM_LEITURA = exports.ghPadrao = exports.FORJA_SEM_LEITURA = exports.LIMITES_DOS_PEDIDOS = exports.LIMITE_DE_RECENTES = exports.LIMITE_DE_PRS = exports.VALIDADE_DO_RETRATO_MIN = exports.LIMIAR_PARADO_NO_CONDUTOR_MIN = exports.CONTRATO_PRS = void 0;
37
37
  exports.nomeDeCheck = nomeDeCheck;
38
38
  exports.prDaForja = prDaForja;
39
39
  exports.githubDoRemoto = githubDoRemoto;
40
40
  exports.repositorioDoRemoto = repositorioDoRemoto;
41
+ exports.forjaDoRemotoDoPulse = forjaDoRemotoDoPulse;
41
42
  exports.lerPrsDaForja = lerPrsDaForja;
42
43
  exports.gravarRetratoDePrs = gravarRetratoDePrs;
43
44
  exports.avisarForjaSemLeitura = avisarForjaSemLeitura;
@@ -78,11 +79,18 @@ exports.entregasDoProjeto = entregasDoProjeto;
78
79
  */
79
80
  const fs = __importStar(require("node:fs"));
80
81
  const path = __importStar(require("node:path"));
81
- const node_child_process_1 = require("node:child_process");
82
+ const api_1 = require("./forja/api");
83
+ const cli_1 = require("./forja/cli");
84
+ const endereco_1 = require("./forja/endereco");
85
+ const executor_1 = require("./forja/executor");
86
+ const resolver_1 = require("./forja/resolver");
87
+ const registro_1 = require("./forja/registro");
88
+ const estado_1 = require("./forja/estado");
82
89
  const branch_de_estado_1 = require("./branch-de-estado");
83
90
  const conducao_1 = require("./conducao");
84
91
  const estado_thread_1 = require("./estado-thread");
85
92
  const forja_1 = require("./forja");
93
+ const locale_1 = require("./locale");
86
94
  const hitl_1 = require("./hitl");
87
95
  const hitl_contract_1 = require("./hitl-contract");
88
96
  const hitl_classificacao_1 = require("./hitl-classificacao");
@@ -103,36 +111,26 @@ exports.VALIDADE_DO_RETRATO_MIN = 60;
103
111
  exports.LIMITE_DE_PRS = 200;
104
112
  /** Quantos PRs recentes (de qualquer estado) a segunda leitura pede: so para achar o mesclado e o fechado. */
105
113
  exports.LIMITE_DE_RECENTES = 100;
114
+ const PRAZO_DO_GH_MS = 30000;
115
+ /** Os tetos e o prazo de cada chamada da leitura de pedidos, que o adaptador de cada forja respeita. */
116
+ exports.LIMITES_DOS_PEDIDOS = { abertos: exports.LIMITE_DE_PRS, recentes: exports.LIMITE_DE_RECENTES, candidatas: 10,
117
+ minimoDaConferenciaMs: 5000, prazoMs: PRAZO_DO_GH_MS };
106
118
  /** Retrato com data mais a frente do relogio do que isto nao vale (relogio adiantado ou arquivo mexido). */
107
119
  const FOLGA_DO_RELOGIO_MIN = 5;
108
120
  const ARQUIVO_DOS_PRS = 'prs.json';
109
- const PRAZO_DO_GH_MS = 30000;
110
121
  /** A leitura inteira da forja numa batida: cabe com folga nos 240 s que a varredura da ao subprocesso do pulse. */
111
122
  const ORCAMENTO_DA_LEITURA_MS = 60000;
112
- const CAMPOS_DOS_RECENTES = 'number,state,headRefName,headRefOid,baseRefName,isDraft,isCrossRepository,url,createdAt,mergedAt';
113
- /** RM-059 (F7, D11 da ork-rm059pista): o estado de merge do PR aberto, que a pista de entrega mostra como conflito. */
114
- const CAMPOS_DO_GH = `${CAMPOS_DOS_RECENTES},statusCheckRollup,mergeable`;
115
- /** Quantas branches candidatas a "sem PR" sao conferidas uma a uma por batida; o resto fica "PR nao lido". */
116
- const LIMITE_DE_CANDIDATAS = 10;
117
- /** A conferencia de uma candidata so comeca com este tempo de sobra no orcamento; com menos, a branch fica sem conferir. */
118
- const MINIMO_DA_CONFERENCIA_MS = 5000;
119
123
  /** As fases que o ciclo despacha antes da entrega: depois de um bloco que para nelas, o passo e despachar, nao publicar. */
120
124
  const FASES_ANTES_DA_ENTREGA = ['GOAL', 'PLAN', 'GO', 'CHECK'];
121
125
  /** Os modos em que a #TAG ja autoriza o push (`autorizacaoDePush`, `core/src/ship.ts`). */
122
126
  const MODOS_COM_PUSH_AUTORIZADO = ['auto', 'maestro'];
123
127
  /** RM-037 (fatia 5, A5): o que as linhas e o resumo dizem quando a forja nao tem leitura de PR. */
124
128
  exports.FORJA_SEM_LEITURA = 'forja sem leitura de PR';
125
- /** O ambiente do `gh`: sem cor, sem prompt e sem host ou repositorio herdados (o host vai no `--repo`). */
126
- function ambienteDoGh() {
127
- const env = { ...process.env, GH_PROMPT_DISABLED: '1', NO_COLOR: '1', CLICOLOR: '0', CLICOLOR_FORCE: '0' };
128
- delete env.GH_HOST;
129
- delete env.GH_REPO;
130
- delete env.GH_FORCE_TTY;
131
- return env;
132
- }
133
129
  const ghPadrao = (args, timeoutMs) => {
134
- const r = (0, node_child_process_1.spawnSync)('gh', [...args], { encoding: 'utf8', timeout: timeoutMs, maxBuffer: 16 * 1024 * 1024, env: ambienteDoGh() });
135
- return { status: r.status, stdout: r.stdout ?? '', stderr: r.error ? r.error.message : (r.stderr ?? '') };
130
+ const r = (0, executor_1.rodarCli)({ cmd: 'gh', args, prazoMs: timeoutMs, maxBuffer: 16 * 1024 * 1024, procurarBinario: false,
131
+ acrescentar: { GH_PROMPT_DISABLED: '1', NO_COLOR: '1', CLICOLOR: '0', CLICOLOR_FORCE: '0' },
132
+ apagar: ['GH_HOST', 'GH_REPO', 'GH_FORCE_TTY'] });
133
+ return { status: r.status, stdout: r.stdout, stderr: r.mensagemDoErro ?? r.stderr };
136
134
  };
137
135
  exports.ghPadrao = ghPadrao;
138
136
  /** Git local sem rede escondida: clone parcial nunca busca objeto durante uma leitura daqui. */
@@ -140,6 +138,10 @@ const git = (raiz, args) => (0, util_1.exec)('git', args, raiz, 60000, { ...proc
140
138
  const SHA = /^[0-9a-f]{40}$/;
141
139
  const BRANCH = /^[A-Za-z0-9._/-]{1,200}$/;
142
140
  const REPOSITORIO = /^[A-Za-z0-9_.-]{1,100}\/[A-Za-z0-9_.-]{1,100}$/;
141
+ /** O caminho do projeto no retrato: `dono/nome` no GitHub, o caminho completo com subgrupos no GitLab. */
142
+ const CAMINHO_DO_PROJETO = /^[A-Za-z0-9_.-]{1,100}(?:\/[A-Za-z0-9_.-]{1,100}){1,19}$/;
143
+ /** O caminho do projeto na forma, sem segmento `.` ou `..`. */
144
+ const caminhoDoProjeto = (v) => CAMINHO_DO_PROJETO.test(v) && v.split('/').every((p) => p !== '.' && p !== '..');
143
145
  /** O host do GitHub Enterprise guardado no retrato: rotulos alfanumericos separados por ponto, como na forja. */
144
146
  const HOST = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/;
145
147
  /** Texto curto vindo de fora: sem controle, num teto. */
@@ -185,11 +187,13 @@ function checkDaForja(c) {
185
187
  let situacao;
186
188
  if (o.__typename === 'StatusContext' || (o.status === undefined && typeof o.state === 'string')) {
187
189
  const s = String(o.state ?? '').toUpperCase();
188
- situacao = s === 'SUCCESS' ? 'verde' : s === 'FAILURE' || s === 'ERROR' ? 'vermelho' : 'pendente';
190
+ situacao = (0, estado_1.estadoDoCheck)('commit-status', s, null);
189
191
  }
190
192
  else {
191
193
  const status = String(o.status ?? '').toUpperCase(), conclusao = String(o.conclusion ?? '').toUpperCase();
192
- situacao = status !== 'COMPLETED' ? 'pendente' : ['SUCCESS', 'NEUTRAL', 'SKIPPED'].includes(conclusao) ? 'verde' : 'vermelho';
194
+ // O pulse mostra o job pulado de proposito como verde, como sempre: so o gate trata `bloqueado` como nao verde.
195
+ const estado = (0, estado_1.estadoDoCheck)('check-run', status, conclusao);
196
+ situacao = estado === 'bloqueado' ? 'verde' : estado;
193
197
  }
194
198
  const concluidoEm = situacao === 'pendente' ? null : instante(o.completedAt) ?? instante(o.startedAt);
195
199
  return { check: { nome, situacao, concluidoEm }, chave, inicio: instante(o.startedAt) ?? instante(o.completedAt) ?? '' };
@@ -252,52 +256,97 @@ function repositorioDoRemoto(raiz, remoto) {
252
256
  const github = githubDoRemoto(raiz, remoto);
253
257
  return github && github.host === 'github.com' ? github.repositorio : null;
254
258
  }
259
+ const githubResolvido = (f) => ({ tipo: 'github', host: f.host, porta: null,
260
+ caminhoBase: '', sshHost: null, sshPorta: null, ca: null, repo: f.repositorio,
261
+ origem: { tipo: 'remoto', host: 'remoto', porta: 'padrao', caminhoBase: 'padrao' } });
262
+ /**
263
+ * As sondas do pulse: o GitHub pelo `gh auth status --hostname` de sempre (o host proprio em que o `gh` tem login e
264
+ * um GitHub Enterprise) e o GitLab pela sonda padrao (o `glab` com login no host responde o `metadata`). O `auth
265
+ * status` que falha por outro motivo que nao a falta de login (prazo, rede, `gh` ausente) fica em `falha`.
266
+ */
267
+ function sondasDoPulse(executor, prazoMs, rodar, logins, falha) {
268
+ return {
269
+ github: (alvo) => {
270
+ if (alvo.caminhoBase)
271
+ return 'nao-responde';
272
+ // Com porta propria, o login se confere no `host:porta` exato, pela sonda padrao: o `--hostname` nao leva porta.
273
+ if (alvo.porta !== null && alvo.porta !== 443)
274
+ return (0, resolver_1.sondasPadrao)(rodar, logins).github(alvo);
275
+ const auth = executor(['auth', 'status', '--hostname', alvo.host], prazoMs);
276
+ if (auth.status === 0)
277
+ return 'responde';
278
+ // So a resposta de login ausente (o `gh` 2.46 diz "You are not logged into any accounts on <host>") e o estado
279
+ // da forja; prazo estourado, `gh` ausente ou host fora do ar sao falha desta batida.
280
+ if (auth.status === 1 && /\bnot logged in/i.test(`${auth.stdout}\n${auth.stderr}`)) {
281
+ falha.ghSemLogin = true;
282
+ return 'sem-login';
283
+ }
284
+ falha.gh = `gh auth status --hostname ${alvo.host} falhou (${auth.status === null ? 'sem código de saída' : `código ${auth.status}`}): ` +
285
+ (curto((0, hitl_1.redigirSegredos)(auth.stderr || auth.stdout || ''), 120) ?? 'sem detalhe');
286
+ return 'nao-responde';
287
+ },
288
+ gitlab: (alvo) => {
289
+ const r = (0, resolver_1.sondasPadrao)(rodar, logins).gitlab(alvo);
290
+ if (r === 'sem-login')
291
+ falha.glabSemLogin = true;
292
+ return r;
293
+ },
294
+ };
295
+ }
255
296
  /**
256
- * RM-037 (fatia 5, A5): de onde o pulse le os PRs do remoto. O github.com, como sempre; o host proprio em que o `gh`
257
- * esta autenticado, que e um GitHub Enterprise (`gh auth status --hostname <host>`); ou nenhum: GitLab, caminho local,
258
- * ou host em que o `gh` nao tem login. Ficar sem leitura nao e falha desta batida (o "PR nao lido"): e o estado da
259
- * forja, que o pulse diz uma vez.
297
+ * De onde o pulse le os pedidos do remoto: a forja resolvida pelo bloco `forja:` do manifesto, pelo host conhecido ou
298
+ * pela sondagem so por CLI com login no host (nunca pelo nome do host). Ficar sem leitura (remoto sem forja, forja
299
+ * que nao se resolve, tipo sem a capacidade) nao e falha desta batida: e o estado da forja, que o pulse diz uma vez.
260
300
  */
261
- function forjaDosPrs(raiz, remoto, executor, prazoMs) {
301
+ function forjaDosPrs(carregado, remoto, executor, prazoMs, rodar, logins, sondas) {
262
302
  // RM-047: remoto que nao e nome de remoto nao chega ao git; para o pulse, e forja sem leitura.
263
303
  if (!(0, branch_de_estado_1.remotoValido)(remoto)) {
264
304
  return { leitura: false, host: null, motivo: `o remoto ${(0, branch_de_estado_1.remotoRedigido)(remoto)} não é nome de remoto do git`, semLeitura: true };
265
305
  }
266
- const url = git(raiz, ['remote', 'get-url', '--', remoto]);
306
+ const url = git(carregado.raiz, ['remote', 'get-url', '--', remoto]);
267
307
  if (!url.ok)
268
308
  return { leitura: false, host: null, motivo: `o remoto ${remoto} não está configurado neste checkout`, semLeitura: true };
269
- const endereco = (0, forja_1.enderecoDoRemoto)(url.stdout.trim());
309
+ const endereco = (0, forja_1.enderecoDoRemoto)(url.stdout.trim()), lido = (0, endereco_1.lerEnderecoDoRemoto)(url.stdout.trim());
270
310
  // Caminho local, ou apelido de SSH sem dominio (`git@github-trabalho:dono/repo.git`): nao ha host para ler.
271
- if (!endereco) {
311
+ if (!endereco || !lido) {
272
312
  return { leitura: false, host: null, motivo: `o remoto ${remoto} não tem host de forja (caminho local ou apelido de SSH)`, semLeitura: true };
273
313
  }
274
- if ((0, forja_1.identidadeDaForja)(url.stdout.trim())?.tipo === 'gitlab') {
275
- return { leitura: false, host: endereco.host, motivo: `a forja de ${remoto} (${endereco.host}) é um GitLab, e o ork só lê PR do GitHub`,
276
- semLeitura: true };
314
+ const falha = {};
315
+ // Sem o cache de 24 h: o pulse percebe na batida seguinte a CLI que perdeu o login no host.
316
+ const r = (0, resolver_1.resolverForja)({ endereco: lido, manifesto: carregado.manifesto.forja, sondas: sondas ?? sondasDoPulse(executor, prazoMs, rodar, logins, falha) });
317
+ if (!r.ok) {
318
+ if (falha.gh)
319
+ return { leitura: false, host: endereco.host, semLeitura: false, motivo: falha.gh };
320
+ const erro = r.erro;
321
+ const motivo = erro.codigo === 'forja.desconhecida' && falha.ghSemLogin
322
+ ? (0, locale_1.textoDoCatalogo)((m) => falha.glabSemLogin ? m.pulse.forjaSemLoginNasDuas(endereco.host, remoto) : m.pulse.forjaSemLogin('gh', endereco.host, remoto))
323
+ : (0, locale_1.textoDoCatalogo)((m) => m.pulse.forjaNaoResolvida(remoto, m.forja.motivo(erro, null)));
324
+ return { leitura: false, host: endereco.host, semLeitura: true, motivo };
277
325
  }
278
- const github = githubDoRemoto(raiz, remoto);
279
- if (!github) {
326
+ const forja = r.valor;
327
+ if (forja.tipo === 'github' && !REPOSITORIO.test(forja.repo)) {
280
328
  return { leitura: false, host: endereco.host, motivo: `o remoto ${remoto} (${endereco.host}) não aponta um repositório dono/nome`,
281
329
  semLeitura: true };
282
330
  }
283
- if (github.host === 'github.com')
284
- return { leitura: true, ...github };
285
- const auth = executor(['auth', 'status', '--hostname', github.host], prazoMs);
286
- if (auth.status === 0)
287
- return { leitura: true, ...github };
288
- // So a resposta de login ausente (o `gh` 2.46 diz "You are not logged into any accounts on <host>") e o estado da
289
- // forja; prazo estourado, `gh` ausente ou host fora do ar sao falha desta batida.
290
- const semLogin = auth.status === 1 && /\bnot logged in/i.test(`${auth.stdout}\n${auth.stderr}`);
291
- return { leitura: false, host: github.host, semLeitura: semLogin, motivo: semLogin
292
- ? `o gh não está autenticado em ${github.host}, a forja de ${remoto}`
293
- : `gh auth status --hostname ${github.host} falhou (${auth.status === null ? 'sem código de saída' : `código ${auth.status}`}): ` +
294
- (curto((0, hitl_1.redigirSegredos)(auth.stderr || auth.stdout || ''), 120) ?? 'sem detalhe') };
331
+ if (!(0, registro_1.adaptadorDaForja)(forja.tipo).pedidosAbertos) {
332
+ return { leitura: false, host: endereco.host, semLeitura: true,
333
+ motivo: (0, locale_1.textoDoCatalogo)((m) => m.pulse.forjaSemPedidos(forja.tipo, forja.host, remoto)) };
334
+ }
335
+ return { leitura: true, forja, hostDoRemoto: endereco.host };
336
+ }
337
+ /**
338
+ * A forja do remoto como o pulse a resolve (o bloco `forja:`, o host conhecido, o cache ou a sondagem pela CLI com
339
+ * login), sem ler pedido nenhum: a pista a usa num host proprio, para seguir o caminho da forja certa. `erro` e a frase
340
+ * que a leitura dos pedidos diria.
341
+ */
342
+ function forjaDoRemotoDoPulse(carregado, remoto, opcoes = {}) {
343
+ const lido = forjaDosPrs(carregado, remoto, opcoes.executor ?? exports.ghPadrao, PRAZO_DO_GH_MS, opcoes.rodar ?? executor_1.rodarCli, new Map(), opcoes.sondas);
344
+ return lido.leitura ? { ok: true, forja: lido.forja } : { ok: false, erro: lido.motivo };
295
345
  }
296
346
  /**
297
- * Le os PRs da base do repositorio do remoto em duas chamadas: os abertos (ate `LIMITE_DE_PRS`; e so a
298
- * lista deles que pode dizer "sem PR") e os recentes de qualquer estado (para achar o mesclado e o fechado).
299
- * O `gh` usa a autenticacao dele; nenhum token passa por aqui. RM-037 (fatia 5, A5): no GitHub Enterprise, o host
300
- * vai no `--repo`; forja sem leitura de PR nao chama o `gh pr list`.
347
+ * Le os pedidos da base do projeto pela capacidade `pedidosAbertos` da forja resolvida: os abertos (so a lista deles
348
+ * pode dizer "sem PR"), os recentes de qualquer estado e as candidatas que nao apareceram. A CLI usa a autenticacao
349
+ * dela; nenhum token passa por aqui. Forja sem leitura de pedidos nao chama CLI nenhuma alem da sondagem.
301
350
  */
302
351
  function lerPrsDaForja(carregado, opcoes = {}) {
303
352
  const lidoEm = opcoes.quando ?? new Date().toISOString();
@@ -305,79 +354,52 @@ function lerPrsDaForja(carregado, opcoes = {}) {
305
354
  const base = carregado.manifesto.worktree.base_branch;
306
355
  const orcamento = opcoes.orcamentoMs ?? ORCAMENTO_DA_LEITURA_MS, fimDaLeitura = Date.now() + orcamento;
307
356
  const resta = () => fimDaLeitura - Date.now();
308
- const executor = opcoes.executor ?? exports.ghPadrao;
309
- const forja = opcoes.forja ? { leitura: true, ...opcoes.forja }
310
- : forjaDosPrs(carregado.raiz, remoto, executor, Math.min(PRAZO_DO_GH_MS, Math.max(1, resta())));
311
- if (!forja.leitura)
312
- return { ok: false, lidoEm, erro: forja.motivo, ...(forja.semLeitura ? { semLeitura: { remoto, host: forja.host } } : {}) };
313
- const { host, repositorio } = forja;
314
- const pedir = (args) => {
315
- if (resta() <= 0)
316
- return `gh pr list: orçamento de ${Math.round(orcamento / 1000)} s da leitura esgotado`;
317
- const r = executor(['pr', 'list', `--repo=${host}/${repositorio}`, `--base=${base}`, ...args], Math.min(PRAZO_DO_GH_MS, resta()));
318
- if (r.status !== 0) {
319
- const detalhe = curto((0, hitl_1.redigirSegredos)(r.stderr || r.stdout || ''), 160) ?? 'sem detalhe';
320
- return `gh pr list falhou (${r.status === null ? 'sem código de saída' : `código ${r.status}`}): ${detalhe}`;
321
- }
322
- try {
323
- const lista = JSON.parse(r.stdout);
324
- if (!Array.isArray(lista))
325
- throw new Error('a resposta não é uma lista');
326
- return lista;
357
+ const executor = opcoes.executor ?? exports.ghPadrao, rodar = opcoes.rodar ?? executor_1.rodarCli, logins = new Map();
358
+ const lido = opcoes.resolvida ? { leitura: true, forja: opcoes.resolvida, hostDoRemoto: null }
359
+ : opcoes.forja ? { leitura: true, forja: githubResolvido(opcoes.forja), hostDoRemoto: null }
360
+ : forjaDosPrs(carregado, remoto, executor, Math.min(PRAZO_DO_GH_MS, Math.max(1, resta())), rodar, logins, opcoes.sondas);
361
+ if (!lido.leitura)
362
+ return { ok: false, lidoEm, erro: lido.motivo, ...(lido.semLeitura ? { semLeitura: { remoto, host: lido.host } } : {}) };
363
+ const forja = lido.forja;
364
+ const lidos = (0, registro_1.exigirCapacidade)((0, registro_1.adaptadorDaForja)(forja.tipo), 'pedidosAbertos')({ forja, base, candidatas: opcoes.candidatas ?? [],
365
+ contexto: carregado.manifesto.ci.context || 'ork-verify',
366
+ api: (0, api_1.chamadorDaApi)(forja, { rodar, logins }), executor, resta, orcamentoMs: orcamento, limites: exports.LIMITES_DOS_PEDIDOS });
367
+ if (!lidos.ok) {
368
+ const erro = lidos.erro, cli = cli_1.CLI_DA_FORJA[forja.tipo].cmd;
369
+ // O GitHub guarda a frase de sempre do `gh pr list` (o pulse e os snapshots a fixam); as outras dizem o motivo tipado.
370
+ if (forja.tipo === 'github')
371
+ return { ok: false, lidoEm, erro: erro.detalhe };
372
+ // A CLI sem login no host e o estado da forja, dito uma vez, como o `gh` sem login no host proprio.
373
+ if (erro.codigo === 'forja.sem-login') {
374
+ return { ok: false, lidoEm, erro: (0, locale_1.textoDoCatalogo)((m) => m.pulse.forjaSemLogin(cli, forja.host, remoto)),
375
+ semLeitura: { remoto, host: lido.hostDoRemoto ?? forja.host } };
327
376
  }
328
- catch (e) {
329
- return `resposta do gh pr list fora do formato: ${curto((0, hitl_1.redigirSegredos)(e.message), 120) ?? 'sem detalhe'}`;
330
- }
331
- };
332
- try {
333
- const porNumero = new Map();
334
- const juntar = (lista, comChecks) => {
335
- for (const bruto of lista) {
336
- const pr = prDaForja(bruto, base);
337
- if (!pr || porNumero.has(pr.numero))
338
- continue;
339
- // S-b do CHECK (rodada 3): a leitura sem rollup nunca diz que o aberto nao tem checks.
340
- if (!comChecks && pr.estado === 'aberto')
341
- pr.checks = [{ nome: 'checks não lidos', situacao: 'pendente', concluidoEm: null }];
342
- porNumero.set(pr.numero, pr);
343
- }
344
- };
345
- const abertos = pedir(['--state=open', `--limit=${exports.LIMITE_DE_PRS}`, `--json=${CAMPOS_DO_GH}`]);
346
- if (typeof abertos === 'string')
347
- return { ok: false, lidoEm, erro: abertos };
348
- juntar(abertos, true);
349
- const recentes = pedir(['--state=all', `--limit=${exports.LIMITE_DE_RECENTES}`, `--json=${CAMPOS_DOS_RECENTES}`]);
350
- if (typeof recentes === 'string')
351
- return { ok: false, lidoEm, erro: recentes };
352
- juntar(recentes, false);
353
- // R1 do CHECK (rodada 3): antes de dizer "sem PR", a branch candidata e conferida sozinha (o mesclado velho
354
- // fica fora dos recentes). Acima do teto da batida, a branch fica sem conferir, e isso e "PR nao lido".
355
- const achadas = new Set([...porNumero.values()].map((p) => p.branch));
356
- const faltam = [...new Set(opcoes.candidatas ?? [])].filter((b) => BRANCH.test(b) && !achadas.has(b));
357
- const semConferir = [];
358
- for (const [i, branch] of faltam.entries()) {
359
- // Acima do teto da batida, sem tempo para a conferencia inteira ou com ela falhando, a candidata fica sem conferir
360
- // ("PR nao lido") e o que ja foi lido vale (sugestao da seguranca na rodada 4 do CHECK).
361
- if (i >= LIMITE_DE_CANDIDATAS || resta() < MINIMO_DA_CONFERENCIA_MS) {
362
- semConferir.push(branch);
363
- continue;
364
- }
365
- const daBranch = pedir(['--state=all', `--head=${branch}`, '--limit=5', `--json=${CAMPOS_DOS_RECENTES}`]);
366
- try {
367
- if (typeof daBranch === 'string')
368
- throw new Error(daBranch);
369
- juntar(daBranch, false);
370
- }
371
- catch {
372
- semConferir.push(branch);
373
- }
374
- }
375
- return { ok: true, retrato: { contrato: exports.CONTRATO_PRS, lidoEm, repositorio, ...(host !== 'github.com' ? { host } : {}), base,
376
- parcial: abertos.length >= exports.LIMITE_DE_PRS, ...(semConferir.length ? { semConferir } : {}), prs: [...porNumero.values()] } };
377
- }
378
- catch (e) {
379
- return { ok: false, lidoEm, erro: `resposta do gh pr list fora do formato: ${curto((0, hitl_1.redigirSegredos)(e.message), 120) ?? 'sem detalhe'}` };
377
+ return { ok: false, lidoEm, erro: (0, locale_1.textoDoCatalogo)((m) => m.forja.motivo(erro, forja.tipo)) };
380
378
  }
379
+ return { ok: true, retrato: { contrato: exports.CONTRATO_PRS, lidoEm, repositorio: forja.repo, ...(forja.host !== 'github.com' ? { host: forja.host } : {}),
380
+ base, parcial: lidos.valor.parcial, ...(lidos.valor.semConferir.length ? { semConferir: lidos.valor.semConferir } : {}), prs: lidos.valor.prs } };
381
+ }
382
+ /**
383
+ * O host e o caminho do projeto no remoto, sem rede nem CLI: o que o retrato tem de bater. A resolucao roda sem
384
+ * sondas; sem tipo declarado e fora dos hosts conhecidos, valem o host (o declarado, senao o do remoto) e o caminho do
385
+ * remoto sem o caminho base.
386
+ */
387
+ function forjaDoRemotoSemRede(carregado, remoto) {
388
+ if (!(0, branch_de_estado_1.remotoValido)(remoto))
389
+ return null;
390
+ const url = git(carregado.raiz, ['remote', 'get-url', '--', remoto]);
391
+ const endereco = url.ok ? (0, endereco_1.lerEnderecoDoRemoto)(url.stdout.trim()) : null;
392
+ if (!endereco)
393
+ return null;
394
+ const m = carregado.manifesto.forja;
395
+ const r = (0, resolver_1.resolverForja)({ endereco, manifesto: m, sondas: {} });
396
+ if (r.ok)
397
+ return { host: r.valor.host, repositorio: r.valor.repo };
398
+ if (r.erro.codigo !== 'forja.desconhecida')
399
+ return null;
400
+ const prefixo = m?.caminho_base ? `${m.caminho_base.slice(1)}/` : '';
401
+ return { host: m?.host ?? endereco.host,
402
+ repositorio: prefixo && endereco.caminho.startsWith(prefixo) ? endereco.caminho.slice(prefixo.length) : endereco.caminho };
381
403
  }
382
404
  const dirDoMonitor = (raiz) => path.join((0, estado_thread_1.raizDoEstado)(raiz), '.orkastery', 'monitor');
383
405
  /** Grava o retrato de uma leitura que deu certo: arquivo novo exclusivo, so do dono, renomeado por cima. */
@@ -460,7 +482,7 @@ function lerRetratoDePrs(raiz) {
460
482
  try {
461
483
  const r = JSON.parse(fs.readFileSync(path.join(dirDoMonitor(raiz), ARQUIVO_DOS_PRS), 'utf8'));
462
484
  const lidoEm = instante(r.lidoEm);
463
- if (r.contrato !== exports.CONTRATO_PRS || !lidoEm || typeof r.repositorio !== 'string' || !REPOSITORIO.test(r.repositorio) ||
485
+ if (r.contrato !== exports.CONTRATO_PRS || !lidoEm || typeof r.repositorio !== 'string' || !caminhoDoProjeto(r.repositorio) ||
464
486
  typeof r.base !== 'string' || typeof r.parcial !== 'boolean' || !Array.isArray(r.prs) ||
465
487
  (r.host !== undefined && !(typeof r.host === 'string' && HOST.test(r.host))) ||
466
488
  (r.semConferir !== undefined && !(Array.isArray(r.semConferir) && r.semConferir.every((b) => typeof b === 'string' && BRANCH.test(b)))))
@@ -880,7 +902,7 @@ function entregasDoProjeto(carregado, opcoes) {
880
902
  const semLeituraDaForja = !!prs && !prs.ok && !!prs.semLeitura;
881
903
  let retrato = null, semRetrato = prs && !prs.ok ? (semLeituraDaForja ? exports.FORJA_SEM_LEITURA : prs.erro) : 'sem leitura dos PRs';
882
904
  if (prs?.ok) {
883
- const r = prs.retrato, atual = githubDoRemoto(raiz, remoto);
905
+ const r = prs.retrato, atual = forjaDoRemotoSemRede(carregado, remoto);
884
906
  // O retrato vale do mesmo host: o do GitHub Enterprise (`host`) ou, sem ele, o github.com.
885
907
  if (r.base !== baseBranch || !atual || r.repositorio !== atual.repositorio || (r.host ?? 'github.com') !== atual.host) {
886
908
  semRetrato = 'retrato de PRs de outro repositório ou base';
package/dist/phase.js CHANGED
@@ -33,12 +33,13 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.REGRAS_DE_EVIDENCIA = exports.CONTRATO_DAS_FASES = void 0;
36
+ exports.REGRAS_DE_EVIDENCIA = exports.REGRA_DAS_ESPERAS = exports.CONTRATO_DAS_FASES = void 0;
37
37
  exports.escolherPerfil = escolherPerfil;
38
38
  exports.perfilPedido = perfilPedido;
39
39
  exports.perfilParaDespacho = perfilParaDespacho;
40
40
  exports.runtimeCruzadoParaDespacho = runtimeCruzadoParaDespacho;
41
41
  exports.estadoParaDespacho = estadoParaDespacho;
42
+ exports.fechoDoGo = fechoDoGo;
42
43
  exports.fasesDoCicloNoPrompt = fasesDoCicloNoPrompt;
43
44
  exports.valoresDoPrompt = valoresDoPrompt;
44
45
  exports.montarPrompt = montarPrompt;
@@ -87,6 +88,7 @@ const memoria_1 = require("./memoria");
87
88
  const prompts_1 = require("./prompts");
88
89
  const slug_1 = require("./slug");
89
90
  const locale_1 = require("./locale");
91
+ const locale_prompts_1 = require("./locale-prompts");
90
92
  const thread_1 = require("./thread");
91
93
  const types_1 = require("./types");
92
94
  const util_1 = require("./util");
@@ -96,6 +98,7 @@ const horario_1 = require("./horario");
96
98
  const runtime_profiles_1 = require("./runtime-profiles");
97
99
  const sessoes_contas_1 = require("./sessoes-contas");
98
100
  const maquina_1 = require("./maquina");
101
+ const trabalho_thread_1 = require("./trabalho-thread");
99
102
  const procedencia_1 = require("./procedencia");
100
103
  const postura_local_1 = require("./postura-local");
101
104
  const fabrica_publicar_1 = require("./fabrica-publicar");
@@ -269,23 +272,31 @@ function estadoParaDespacho(raiz, thread, dryRun = false) {
269
272
  }
270
273
  /** O que cada fase canonica entrega. Vai no cabecalho do prompt de toda sessao. */
271
274
  exports.CONTRATO_DAS_FASES = {
272
- GOAL: 'GOAL (F1): objetivo verificavel, impact map, criterios de sucesso e claims com comando de verificacao. Nao implementa.',
273
- PLAN: 'PLAN (F2): plano com tarefas, touch_paths, decisoes D1..Dn com domicilio unico e verify executavel por tarefa. Nao implementa.',
274
- GO: 'GO (F3): implementacao slice por slice, um commit atomico por tarefa, dentro da worktree da thread.',
275
- CHECK: 'CHECK (F4): verificacao contra a baseline (regressao versus divida pre-existente), review de codigo, testes, seguranca e performance.',
276
- SHIP: 'SHIP (F5): merge serializado, push provado por comando, roadmap atualizado e plano de rollback.',
277
- MASTER: 'MASTER (F6): MASTER log com postmortem tipado, licoes e o score humano de 0 a 5. Uma entrega sem MASTER log nao aconteceu.',
275
+ ...locale_prompts_1.PROMPTS_PT_BR.contratoDasFases,
278
276
  };
277
+ /**
278
+ * RM-037 (ork-rm037esperas, D3): a regra das esperas, uma linha so, a mesma no prompt de toda fase e na skill e nos
279
+ * guias que o adaptador instala (`core/test/rm037-esperas.test.ts` confere os arquivos). Em 12/10/2026, sessoes de
280
+ * fase esperaram para sempre por verify ou suite mandados para segundo plano com `&`, cujo processo morreu com a
281
+ * chamada, e por lacos de espera com `pgrep -f` que acham a si mesmos, porque o proprio laco traz o texto procurado.
282
+ */
283
+ exports.REGRA_DAS_ESPERAS = locale_prompts_1.PROMPTS_PT_BR.regraDasEsperas;
279
284
  /** As regras de evidencia que valem em toda fase, em todo modo. */
280
285
  exports.REGRAS_DE_EVIDENCIA = [
281
- 'Nada de self-report: toda alegacao vem com o comando que a comprova e a saida real.',
282
- 'Trabalhe apenas no diretorio de trabalho indicado acima.',
283
- 'Passos irreversiveis (push, merge, delecao) so acontecem quando o modo autoriza.',
286
+ ...locale_prompts_1.PROMPTS_PT_BR.regrasDeEvidencia,
284
287
  // RM-058 N2 (D13 da ork-rm058n2): tres sessoes de 12/10/2026 mandaram verify ou suite para segundo plano com `&`,
285
- // perderam o processo e esperaram para sempre.
286
- 'Verify, build e suite rodam em primeiro plano, com timeout, nunca com `&` no comando: o processo em segundo plano ' +
287
- 'se perde e a sessao espera para sempre. O `ork verify` espera a vez na fila de recursos pesados.',
288
+ // perderam o processo e esperaram para sempre. RM-037 (ork-rm037esperas, D3): a linha da N2 virou a regra das
289
+ // esperas, que tambem traz a execucao em segundo plano do host e a espera por `pgrep -f`.
290
+ exports.REGRA_DAS_ESPERAS,
288
291
  ];
292
+ /**
293
+ * RM-016: o rito de saída do GO pertence ao prompt canônico, não a um adaptador. Assim Claude Code
294
+ * e Codex recebem os mesmos artefatos obrigatórios antes de a sessão encerrar. RM-061 F3c: o texto
295
+ * vem do catálogo dos prompts, e o prompt inglês leva o mesmo rito.
296
+ */
297
+ function fechoDoGo(threadId, locale = (0, locale_1.localeAtivo)()) {
298
+ return (locale === 'en' ? locale_prompts_1.PROMPTS_EN : locale_prompts_1.PROMPTS_PT_BR).fechoDoGo(threadId);
299
+ }
289
300
  /**
290
301
  * I-42 (D11): as fases que o cabecalho do prompt descreve.
291
302
  *
@@ -308,7 +319,8 @@ function fasesDoCicloNoPrompt(thread) {
308
319
  * decisao e codigo. E o que permite um projeto reescrever o texto do prompt em
309
320
  * `prompts/fase-padrao.md` sem poder mudar o que o `ork` considera verdade.
310
321
  */
311
- function valoresDoPrompt(thread, fase, pedido, memoriaInjetada = '') {
322
+ function valoresDoPrompt(thread, fase, pedido, memoriaInjetada = '', locale = (0, locale_1.localeAtivo)()) {
323
+ const mp = locale === 'en' ? locale_prompts_1.PROMPTS_EN : locale_prompts_1.PROMPTS_PT_BR;
312
324
  const def = (0, modos_1.definicaoDoModo)(thread.modo);
313
325
  const bloco = (0, thread_1.blocoDaThread)(thread, fase);
314
326
  const pausa = (0, thread_1.pausaNaThread)(thread, fase);
@@ -317,27 +329,29 @@ function valoresDoPrompt(thread, fase, pedido, memoriaInjetada = '') {
317
329
  thread: thread.id,
318
330
  bloco: bloco.fases.join('-'),
319
331
  nome: thread.nome,
320
- ciclo_canonico: fasesDoCicloNoPrompt(thread).map((f) => `${bloco.fases.includes(f) ? '>' : ' '} ${exports.CONTRATO_DAS_FASES[f]}`).join('\n'),
332
+ ciclo_canonico: fasesDoCicloNoPrompt(thread).map((f) => `${bloco.fases.includes(f) ? '>' : ' '} ${mp.contratoDasFases[f]}`).join('\n'),
321
333
  tag: def.tag,
322
334
  blocos: thread.blocos.map((b) => b.fases.join('-')).join(' / '),
323
335
  pausas: String(thread.blocos.filter((b) => b.pausa).length),
324
- linha_variante: thread.variante ? `Variante de ciclo: ${thread.variante}` : '',
336
+ linha_variante: thread.variante ? mp.variante(thread.variante) : '',
325
337
  regra_de_pausa: pausa
326
- ? `Ao fim deste bloco HA PAUSA humana sobre: ${bloco.pausaSobre}. Pare, apresente a evidencia e espere o veredito.`
327
- : 'Ao fim deste bloco NAO ha pausa humana: siga com decisao autonoma e registre no ledger quem decidiu, com que evidencia e por que.',
328
- invariantes: modos_1.INVARIANTES.map((i) => `- ${i}`).join('\n'),
338
+ ? mp.pausa(mp.pausaSobre(bloco.pausaSobre))
339
+ : mp.semPausa,
340
+ invariantes: mp.invariantes.map((i) => `- ${i}`).join('\n'),
329
341
  slug: thread.slug,
330
342
  projeto_nome: thread.projeto.name,
331
343
  projeto_abbrev: thread.projeto.abbrev,
332
344
  base_branch: thread.base.branch,
333
345
  base_commit: thread.base.commit,
334
- diretorio: thread.worktree ?? '(raiz do projeto)',
346
+ diretorio: thread.worktree ?? mp.raizDoProjeto,
347
+ trabalho: (0, trabalho_thread_1.caminhoDoTrabalho)(thread.id),
335
348
  pedido: pedido.trim(),
349
+ fecho_go: bloco.fases.includes('GO') ? mp.fechoDoGo(thread.id) : '',
336
350
  // Bloco B6: o bloco de memoria injetada deterministicamente. Vazio em toda thread sem
337
351
  // decisao fechada e sem OrkMind, e ai a linha da variavel some do prompt: o texto fica
338
352
  // byte a byte igual ao que o B4 ja despachava.
339
353
  memoria_injetada: memoriaInjetada,
340
- regras_de_evidencia: exports.REGRAS_DE_EVIDENCIA.map((r) => `- ${r}`).join('\n'),
354
+ regras_de_evidencia: [...mp.regrasDeEvidencia, mp.regraDasEsperas].map((r) => `- ${r}`).join('\n'),
341
355
  };
342
356
  }
343
357
  /**
@@ -347,8 +361,10 @@ function valoresDoPrompt(thread, fase, pedido, memoriaInjetada = '') {
347
361
  * `prompts/fase-padrao.md` (ou `prompts/fase-goal.md` e companhia) versionado no repositorio,
348
362
  * vale o do projeto, e `ork prompt lint` e quem garante que ele nao perdeu o contrato.
349
363
  */
350
- function montarPrompt(thread, fase, pedido, raiz, memoriaInjetada = '') {
351
- return (0, prompts_1.renderizar)((0, prompts_1.templateDaFase)(fase, raiz), valoresDoPrompt(thread, fase, pedido, memoriaInjetada));
364
+ function montarPrompt(thread, fase, pedido, raiz, memoriaInjetada = '', locale = (0, locale_1.localeAtivo)()) {
365
+ // RM-061 F3c: os valores falam a lingua do template escolhido; o do projeto sem par `.en` sai inteiro em pt-BR.
366
+ const template = (0, prompts_1.templateDaFase)(fase, raiz, locale);
367
+ return (0, prompts_1.renderizar)(template, valoresDoPrompt(thread, fase, pedido, memoriaInjetada, (0, prompts_1.idiomaDoTemplate)(template)));
352
368
  }
353
369
  /**
354
370
  * Monta o prompt da fase JA com a memoria injetada (bloco B6).
@@ -359,11 +375,15 @@ function montarPrompt(thread, fase, pedido, raiz, memoriaInjetada = '') {
359
375
  * com as decisoes fechadas lidas do `thread.json`: a garantia nao depende do OrkMind.
360
376
  */
361
377
  function montarPromptComMemoria(carregado, thread, fase, pedido, memoria) {
362
- const injecao = (0, memoria_1.injecaoDaFase)(carregado, memoria, thread, fase);
378
+ // RM-061 F3c: o prompt despachado e dado (arquivo com sha256 no ledger). Segue a lingua declarada do dono
379
+ // (`owner.language`), nunca o locale de quem despacha: sem ela, pt-BR, com qualquer LANG (contrato da F2a). A
380
+ // dica do grafo fala a lingua do template que conduz a fase, como os valores.
381
+ const locale = (0, prompts_1.idiomaDoTemplate)((0, prompts_1.templateDaFase)(fase, carregado.raiz, (0, locale_1.linguaDeclaradaDoDono)(carregado.manifesto.owner?.language)));
382
+ const injecao = (0, memoria_1.injecaoDaFase)(carregado, memoria, thread, fase, locale);
363
383
  // Mesma raiz usada pelo MCP e runtime-context; o manifesto da WT nao habilita a dica.
364
384
  const ligado = (0, mcp_grafo_1.grafoLigado)((0, manifest_1.exigirManifesto)((0, estado_thread_1.raizDoEstado)(carregado.raiz)).manifesto);
365
385
  return {
366
- prompt: montarPrompt(thread, fase, (0, prompts_1.pedidoComDicaDoGrafo)(pedido, thread.id, ligado), carregado.raiz, injecao.texto),
386
+ prompt: montarPrompt(thread, fase, (0, prompts_1.pedidoComDicaDoGrafo)(pedido, thread.id, ligado, locale), carregado.raiz, injecao.texto, locale),
367
387
  injecao,
368
388
  };
369
389
  }
@@ -448,6 +468,8 @@ function dadosDoDespacho(ctx, comando) {
448
468
  cwd: ctx.cwd,
449
469
  promptPath: path.relative(ctx.raiz, ctx.promptPath),
450
470
  promptSha256: ctx.promptSha256,
471
+ ...(ctx.promptOriginal ? { promptOriginalPath: path.relative(ctx.raiz, ctx.promptOriginal.path),
472
+ promptOriginalSha256: ctx.promptOriginal.sha256 } : {}),
451
473
  origem: ctx.origem,
452
474
  // I-36 (T10): a porta por onde o dono chegou. `runtime` e o motor; `canal` e a porta.
453
475
  ...(ctx.canal ? { canal: ctx.canal } : {}),
@@ -566,14 +588,14 @@ function registrarObservacao(ctx, sessao, dir, controlador, sensores) {
566
588
  const mesmoDespacho = (e) => e.sessionId === sessao.sessionId && e.despachoEm === sessao.despachadaEm;
567
589
  try {
568
590
  // I-34: claude-bg observa pela fonte nativa; no PLAN o registro guarda o sha de base do artefato.
569
- // I-33 (N1): o GO codex registra o HEAD do despacho, como a fonte claude-bg; sem ele a D11c nao ve commit pelo shell.
591
+ // I-33 (N1): o GO codex registra o HEAD do despacho, como a fonte claude-bg; ele revela commit pelo shell no checkpoint.
570
592
  const head = ctx.runtime === 'codex' && ctx.fase === 'GO' ? { head: ctx.headNoDespacho ?? null } : {};
571
593
  const fonte = ctx.runtime === 'claude-bg' ? (0, session_watcher_claude_1.fonteClaudeDoDespacho)(ctx.raiz, ctx.thread.id, ctx.fase, ctx.cwd)
572
594
  : sensores?.logPath ? { logPath: sensores.logPath, processoPath: sensores.processoPath, reciboPath: sensores.reciboPath, ...head }
573
595
  : controlador ? { controlador, cwd: ctx.cwd, ...head } : null;
574
596
  if (!fonte)
575
597
  return;
576
- (0, session_watcher_1.validarFonteWatcher)(ctx.raiz, sessao.sessionId, fonte);
598
+ (0, session_watcher_1.prepararFonteWatcher)(ctx.raiz, sessao.sessionId, fonte);
577
599
  const eventos = (0, ledger_1.lerLedger)(dir);
578
600
  if (!eventos.some(e => e.tipo === 'session_sensor_registered' && mesmoDespacho(e))) {
579
601
  (0, ledger_1.registrar)(dir, ctx.thread.id, 'session_sensor_registered', { fase: ctx.fase,
@@ -687,6 +709,8 @@ tomadaPrevia) {
687
709
  const thread = (0, thread_1.lerThread)(raiz, threadId);
688
710
  const fase = opcoes.fase;
689
711
  const dir = (0, thread_1.dirThread)(raiz, thread.id);
712
+ if (!opcoes.dryRun)
713
+ (0, trabalho_thread_1.garantirDiretorioDoTrabalho)(raiz, thread.id);
690
714
  const slug = slugDaSessao(thread, fase);
691
715
  // Resolve UMA vez o trio runtime/modelo/esforco: o mesmo objeto vai ao runtime adapter,
692
716
  // ao ledger e a resposta do CLI. Resolver duas vezes e o caminho curto para o ledger
@@ -1096,6 +1120,8 @@ tomadaPrevia) {
1096
1120
  effort,
1097
1121
  sinal,
1098
1122
  detalhe: erro,
1123
+ // RM-058 N4 (D17 da ork-rm058n4): o pedido do despacho do arco é do vigia do arco, e o `ork retry resume` não o retoma.
1124
+ ...(opcoes.correlacao ? { correlacao: opcoes.correlacao } : {}),
1099
1125
  });
1100
1126
  (0, ledger_1.registrar)(dir, thread.id, ledger_1.TIPOS_DE_EVENTO.rateLimitEnfileirado, {
1101
1127
  fase,