@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
@@ -42,6 +42,7 @@ exports.faseJaFeita = faseJaFeita;
42
42
  exports.bloqueioDepoisDoDespacho = bloqueioDepoisDoDespacho;
43
43
  exports.passoDaThread = passoDaThread;
44
44
  exports.passosDoCondutor = passosDoCondutor;
45
+ exports.passoDeQuemAge = passoDeQuemAge;
45
46
  exports.statusDaSentinela = statusDaSentinela;
46
47
  exports.textoDoStatusDaSentinela = textoDoStatusDaSentinela;
47
48
  /**
@@ -52,7 +53,8 @@ exports.textoDoStatusDaSentinela = textoDoStatusDaSentinela;
52
53
  * Dois fatos moram aqui, e so aqui:
53
54
  *
54
55
  * - a PRESENCA dela nesta maquina, com prazo curto renovado pela batida: enquanto ela vale, o condutor externo cede
55
- * o despacho e o retry; vencida (a sessao do dono fechou), ele volta a conduzir sozinho, como reserva;
56
+ * o despacho e o retry, menos a retomada por cota (RM-064 T5, `passosDaBatida`); vencida (a sessao do dono fechou),
57
+ * ele volta a conduzir sozinho, como reserva;
56
58
  * - o PASSO DO CONDUTOR de cada thread aberta, calculado com as mesmas leituras do pulse (`entregasDoProjeto`,
57
59
  * `esperaDoCondutor`), sem o limiar de 30 min e sem ler a forja. No #Auto, depois de uma fase concluida, sai a
58
60
  * fase seguinte a prova mais adiantada que a sessao do bloco deixou (artefato gravado depois do despacho, produto
@@ -69,8 +71,10 @@ const estado_thread_1 = require("./estado-thread");
69
71
  const ledger_1 = require("./ledger");
70
72
  const manifest_1 = require("./manifest");
71
73
  const maquina_1 = require("./maquina");
74
+ const noctum_guarda_1 = require("./noctum-guarda");
72
75
  const parado_no_condutor_1 = require("./parado-no-condutor");
73
76
  const thread_1 = require("./thread");
77
+ const locale_1 = require("./locale");
74
78
  var conducao_2 = require("./conducao");
75
79
  Object.defineProperty(exports, "CANAL_DA_SENTINELA", { enumerable: true, get: function () { return conducao_2.CANAL_DA_SENTINELA; } });
76
80
  Object.defineProperty(exports, "CONTRATO_DA_SENTINELA", { enumerable: true, get: function () { return conducao_2.CONTRATO_DA_SENTINELA; } });
@@ -343,6 +347,8 @@ function temPedidoGuardado(raiz, t) {
343
347
  function passosDoCondutor(carregado, opcoes = {}) {
344
348
  const quando = opcoes.quando ?? new Date().toISOString();
345
349
  const entregas = (0, parado_no_condutor_1.entregasDoProjeto)(carregado, { quando, limiarMin: 0 });
350
+ // RM-058, integracao (T1.2): os arcos desta raiz, lidos uma vez para todas as threads.
351
+ const arcos = (0, noctum_guarda_1.lerArcosDaRaiz)(carregado.raiz, quando);
346
352
  const passos = [];
347
353
  for (const estado of entregas.estados) {
348
354
  let t;
@@ -357,10 +363,21 @@ function passosDoCondutor(carregado, opcoes = {}) {
357
363
  eventos = (0, ledger_1.lerLedger)((0, thread_1.dirThread)(carregado.raiz, t.id));
358
364
  }
359
365
  catch { /* ledger ilegivel: sem bloqueio */ }
360
- passos.push(passoDaThread(t, estado, eventos, temPedidoGuardado(carregado.raiz, t), (fase) => faseJaFeita(carregado.raiz, t, fase, estado, eventos), (0, parado_no_condutor_1.pendenciaDoDono)(t, eventos, quando)));
366
+ const passo = passoDaThread(t, estado, eventos, temPedidoGuardado(carregado.raiz, t), (fase) => faseJaFeita(carregado.raiz, t, fase, estado, eventos), (0, parado_no_condutor_1.pendenciaDoDono)(t, eventos, quando));
367
+ const arco = (0, noctum_guarda_1.arcoDoPasso)(carregado.raiz, arcos, t.id, eventos);
368
+ passos.push(arco ? { ...passo, arco } : passo);
361
369
  }
362
370
  return passos.sort((a, b) => (a.thread < b.thread ? -1 : a.thread > b.thread ? 1 : 0));
363
371
  }
372
+ /**
373
+ * RM-058, integracao (T1.2): o passo como quem age o le. A thread que o arco segura nao tem acao nenhuma de fora; a que ele
374
+ * retem nao e despachada nem retomada. O motivo vai no `porque`, e o passo do nucleo (o da fila do arco) nao muda.
375
+ */
376
+ function passoDeQuemAge(p) {
377
+ if (!p.arco || (p.arco.efeito === 'retencao' && p.acao !== 'despachar' && p.acao !== 'retomar'))
378
+ return p;
379
+ return { ...p, acao: 'nada', fase: null, porque: p.arco.detalhe };
380
+ }
364
381
  /** O `ork conducao sentinela status`: a presenca desta maquina e o passo do condutor em cada thread aberta. */
365
382
  function statusDaSentinela(carregado, opcoes = {}) {
366
383
  const agora = opcoes.agora ?? new Date();
@@ -368,20 +385,20 @@ function statusDaSentinela(carregado, opcoes = {}) {
368
385
  return {
369
386
  contrato: conducao_1.CONTRATO_DA_SENTINELA, consultadoEm: agora.toISOString(), maquina,
370
387
  presenca: presencaDaSentinela(carregado.raiz, { agora, maquina }),
371
- threads: passosDoCondutor(carregado, { quando: agora.toISOString() }),
388
+ // RM-058, integracao (T1.2): a Sentinela despacha o que este status diz; a thread do arco sai com `nada` e o motivo.
389
+ threads: passosDoCondutor(carregado, { quando: agora.toISOString() }).map(passoDeQuemAge),
372
390
  };
373
391
  }
374
392
  /** O status em texto, para o terminal. */
375
393
  function textoDoStatusDaSentinela(s) {
394
+ const m = (0, locale_1.msg)().conducao.sentinela;
376
395
  const linhas = [];
377
396
  const p = s.presenca;
378
- linhas.push(!p ? `Sentinela: desligada na maquina ${s.maquina}; o condutor externo conduz.`
379
- : p.ativa ? `Sentinela: ligada na maquina ${s.maquina}, canal ${p.canal}, sessao ${p.sessao.slice(0, 8)}; o condutor externo cede o despacho e o retry.`
380
- : `Sentinela: a presenca da sessao ${p.sessao.slice(0, 8)} venceu; o condutor externo conduz.`);
397
+ linhas.push(!p ? m.desligada(s.maquina) : p.ativa ? m.ligada(s.maquina, p.canal, p.sessao.slice(0, 8)) : m.vencida(p.sessao.slice(0, 8)));
381
398
  if (s.threads.length === 0)
382
- linhas.push(' nenhuma thread aberta neste checkout');
399
+ linhas.push(m.nenhuma);
383
400
  for (const t of s.threads) {
384
- const acao = t.acao === 'despachar' ? `despachar ${t.fase}` : t.acao;
401
+ const acao = t.acao === 'despachar' ? m.despachar(t.fase) : t.acao;
385
402
  linhas.push(` ${t.thread.padEnd(20)} ${t.modo.padEnd(8)} ${acao.padEnd(16)} ${t.porque}`);
386
403
  }
387
404
  return linhas.join('\n');
package/dist/conducao.js CHANGED
@@ -239,10 +239,30 @@ function nomeDaConducao(threadId) {
239
239
  }
240
240
  /** Estados em que o runtime ja deu a sessao por encerrada. */
241
241
  const TERMINAIS = ['done', 'completed', 'exited', 'stopped', 'failed'];
242
+ /** Os eventos que sao contabilidade do proprio ork, e nao sinal de que a sessao voltou a trabalhar. */
243
+ const SO_DA_CONTABILIDADE = /^(conducao_|retry_|session_watcher_|despacho_idempotente$|varredura_acao$)/;
244
+ /**
245
+ * RM-063 (fatia 3, achado c): o observador viu a sessao num estado terminal do runtime (`done`, `failed`, `stopped`) e
246
+ * encerrou sem inferir a conclusao da fase (`session_watcher_error` com `estadoNativo`). A fase pode nao estar provada,
247
+ * mas a sessao nao executa mais nada: o lease dela cai. Vale o ultimo desses vistos, se nenhum evento da mesma sessao
248
+ * depois dele mostra trabalho (a sessao retomada por alguem).
249
+ */
250
+ function terminalVistoPeloObservador(eventos, sessionId, desde) {
251
+ let visto = null;
252
+ for (const e of eventos) {
253
+ if (e.sessionId !== sessionId || Date.parse(e.ts) < desde)
254
+ continue;
255
+ if (e.tipo === 'session_watcher_error' && typeof e.estadoNativo === 'string' && TERMINAIS.includes(e.estadoNativo))
256
+ visto = e;
257
+ else if (visto && !SO_DA_CONTABILIDADE.test(e.tipo))
258
+ visto = null;
259
+ }
260
+ return visto;
261
+ }
242
262
  /**
243
263
  * O evento que prova que a sessao dona do lease acabou: o resultado da fase dela (a prova da I-34
244
- * que o observador grava), a morte registrada, a superacao, ou a thread fechada. So conta evento
245
- * posterior ao inicio da conducao.
264
+ * que o observador grava), a morte registrada, a superacao, o estado terminal que o observador viu
265
+ * no runtime (RM-063), ou a thread fechada. So conta evento posterior ao inicio da conducao.
246
266
  */
247
267
  function fimDaSessao(eventos, lease) {
248
268
  const dono = lease.conducao?.dono;
@@ -250,7 +270,7 @@ function fimDaSessao(eventos, lease) {
250
270
  return null;
251
271
  const desde = Date.parse(lease.adquiridoEm);
252
272
  return eventos.find((e) => Date.parse(e.ts) >= desde && ((['phase_result', 'sessao_morta', 'session_superseded'].includes(e.tipo) && e.sessionId === dono.sessionId) ||
253
- ['thread_closed_admin', 'master_done'].includes(e.tipo))) ?? null;
273
+ ['thread_closed_admin', 'master_done'].includes(e.tipo))) ?? terminalVistoPeloObservador(eventos, dono.sessionId, desde);
254
274
  }
255
275
  /**
256
276
  * A leitura pura, para quem so tem os dados (o snapshot do Maestro le por um leitor confinado).
@@ -375,16 +395,49 @@ const emCurso = new Map();
375
395
  function chave(raiz, threadId) {
376
396
  return `${(0, leases_1.caminhoLease)(raiz, nomeDaConducao(threadId))}`;
377
397
  }
398
+ /**
399
+ * RM-063 (fatia 3, achado c): a consulta do claude-bg na conta do perfil da sessao (`CLAUDE_CONFIG_DIR` dele). A conta do
400
+ * processo nao lista a sessao de outro perfil, e a ausencia la nao prova nada; na conta dela, prova. `null` quando o
401
+ * perfil nao esta mais no store desta maquina (vale a consulta de sempre).
402
+ */
403
+ function consultaNaContaDoPerfil(dono, raiz) {
404
+ if (dono.runtime !== 'claude-bg' || !dono.perfil)
405
+ return null;
406
+ // Carregados na hora, como o controle nativo: a leitura da conducao nao puxa o adapter inteiro.
407
+ const { lerPerfis, perfilDeDespacho } = require('./runtime-profiles');
408
+ const { ambienteDoPerfil, consultarSessoes } = require('./adapters/claude-bg');
409
+ let perfil = null;
410
+ try {
411
+ const p = lerPerfis(raiz).perfis.find((x) => x.id === dono.perfil && x.runtime === 'claude-bg');
412
+ perfil = p ? perfilDeDespacho(p) : null;
413
+ }
414
+ catch {
415
+ return null;
416
+ }
417
+ if (!perfil?.configDir)
418
+ return null;
419
+ const r = consultarSessoes(undefined, true, ambienteDoPerfil(perfil));
420
+ if (!r.ok)
421
+ return { ok: false, estado: null, detalhe: `o runtime nao respondeu a consulta na conta do perfil ${dono.perfil}`, naConta: true };
422
+ const achada = r.sessoes.find((x) => x.sessionId === dono.sessionId);
423
+ const estado = achada ? String(achada.state ?? achada.status ?? '') : null;
424
+ return { ok: true, estado, detalhe: achada ? `estado ${estado} na conta do perfil ${dono.perfil}` : `sessao ausente da conta do perfil ${dono.perfil}`,
425
+ naConta: true };
426
+ }
378
427
  /** A consulta padrao: o controle nativo do runtime (claude-bg ou o controller do codex). */
379
428
  const consultaNativa = (dono, raiz, threadId) => {
380
429
  try {
430
+ const naConta = consultaNaContaDoPerfil(dono, raiz);
431
+ if (naConta)
432
+ return naConta;
381
433
  // Carregado na hora: o modulo de sessoes puxa o HITL inteiro, que nao pertence a leitura.
382
434
  const { controleNativo } = require('./hitl-sessions');
383
435
  const r = controleNativo(dono.runtime, raiz, threadId, dono.sessionId).consultar();
384
436
  if (!r.ok)
385
437
  return { ok: false, estado: null, detalhe: 'o runtime nao respondeu a consulta' };
386
438
  const achadas = r.sessoes.filter((s) => s.sessionId === dono.sessionId);
387
- return { ok: true, estado: achadas[0]?.estado ?? null, detalhe: achadas.length ? `estado ${achadas[0].estado}` : 'sessao ausente' };
439
+ return { ok: true, estado: achadas[0]?.estado ?? null, detalhe: achadas.length ? `estado ${achadas[0].estado}` : 'sessao ausente',
440
+ naConta: !dono.perfil };
388
441
  }
389
442
  catch (e) {
390
443
  return { ok: false, estado: null, detalhe: e.message };
@@ -425,7 +478,9 @@ function provaDeFimDaSessao(raiz, threadId, lease, pedido, anotarEstado = () =>
425
478
  anotarEstado(r.estado);
426
479
  if (r.estado && TERMINAIS.includes(r.estado))
427
480
  return { motivo: 'sessao-orfa', prova: `runtime ${dono.runtime}: ${r.detalhe}` };
428
- if (r.estado === null && !dono.perfil)
481
+ // A ausencia so prova o fim quando a consulta foi feita na conta da sessao: sem perfil, a do processo; com perfil, a
482
+ // dele (RM-063, fatia 3, achado c).
483
+ if (r.estado === null && (!dono.perfil || r.naConta === true))
429
484
  return { motivo: 'sessao-orfa', prova: `runtime ${dono.runtime}: ${r.detalhe}` };
430
485
  return null;
431
486
  }
@@ -624,9 +679,10 @@ function sucessaoAindaVale(raiz, threadId, estado) {
624
679
  // Sem resposta do runtime nao ha prova de que ela segue parada: a sucessao nao vale.
625
680
  if (!r.ok)
626
681
  return false;
627
- // S1 do CHECK 6: a sessao que sumiu do runtime, sem perfil, acabou; a mesma prova de `provaDeFimDaSessao`.
682
+ // S1 do CHECK 6: a sessao que sumiu do runtime, sem perfil (ou da conta do perfil dela), acabou; a mesma prova de
683
+ // `provaDeFimDaSessao`.
628
684
  if (r.estado === null)
629
- return !dono.perfil;
685
+ return !dono.perfil || r.naConta === true;
630
686
  return r.estado === 'blocked' || TERMINAIS.includes(r.estado);
631
687
  }
632
688
  function renovar(raiz, threadId, estado, prazoDoProximoMs, agoraMs) {
@@ -718,6 +774,7 @@ function comandoDeEsperar(threadId, pedido) {
718
774
  case 'baseline': return `ork verify ${threadId} --baseline --esperar 30`;
719
775
  case 'fix.open': return `ork fix open ${threadId} --esperar 30`;
720
776
  case 'fix.reverify': return `ork fix reverify ${threadId} --esperar 30`;
777
+ case 'branch.atualizar': return `ork conducao atualizar ${threadId} --esperar 30`;
721
778
  default: return `ork verify ${threadId} --esperar 30`;
722
779
  }
723
780
  }
@@ -731,32 +788,30 @@ function comandoDeAcompanhar(threadId, atual) {
731
788
  * aconteceu e o que fazer: o texto sai daqui e de lugar nenhum mais, e o JSON e a mesma estrutura.
732
789
  */
733
790
  function recusaDeConducao(threadId, atual, pedido, opcoes = {}) {
791
+ const m = (0, locale_1.msg)().conducao.recusa;
734
792
  const conducao = atual
735
793
  ? { ...atual, desdeLocal: (0, horario_1.formatarDataHoraRotulada)(atual.desde, opcoes), linha: (0, conducao_texto_1.linhaDeConducao)(atual, opcoes) }
736
794
  : null;
737
795
  const acoes = [
738
- { acao: 'esperar', comando: comandoDeEsperar(threadId, pedido),
739
- explicacao: 'Esperar a vez: repete este pedido e segue sozinho quando a conducao atual terminar (ate 30 min).' },
740
- { acao: 'acompanhar', comando: comandoDeAcompanhar(threadId, atual),
741
- explicacao: 'Acompanhar quem conduz, sem mexer em nada.' },
742
- { acao: 'assumir', comando: `ork conducao assumir ${threadId} --por <voce> --motivo "<por que>"`,
743
- explicacao: 'Assumir a conducao: encerra a atual pelo proprio runtime e registra no ledger quem assumiu, de qual canal e por que.' },
796
+ { acao: 'esperar', comando: comandoDeEsperar(threadId, pedido), explicacao: m.esperar },
797
+ { acao: 'acompanhar', comando: comandoDeAcompanhar(threadId, atual), explicacao: m.acompanhar },
798
+ { acao: 'assumir', comando: m.comandoAssumir(threadId),
799
+ explicacao: m.assumir },
744
800
  ];
745
801
  const linhas = [
746
- `Pedido nao executado: a thread ${threadId} ja esta sendo conduzida agora, e duas execucoes na mesma worktree ` +
747
- 'se corrompem (foi o que aconteceu em 19/09/2026).',
802
+ m.titulo(threadId),
748
803
  ];
749
804
  if (conducao) {
750
- linhas.push(` Quem conduz: canal ${conducao.canal}, ${(0, conducao_texto_1.quemConduz)(conducao)}, fase ${conducao.fase ?? '-'}, desde ${conducao.desdeLocal}.`);
805
+ linhas.push(m.quem(conducao.canal, (0, conducao_texto_1.quemConduz)(conducao), conducao.fase ?? '-', conducao.desdeLocal));
751
806
  if (conducao.promptSha256)
752
- linhas.push(` Pedido em curso: prompt sha256 ${conducao.promptSha256.slice(0, 12)}.`);
807
+ linhas.push(m.prompt(conducao.promptSha256.slice(0, 12)));
753
808
  }
754
809
  else {
755
- linhas.push(' Outra operacao esta tomando a conducao neste instante; o registro dela ainda nao apareceu.');
810
+ linhas.push(m.entrando);
756
811
  }
757
- linhas.push(` Pedido recusado: ${conducao_texto_1.NOME_DA_OPERACAO[pedido.operacao]}${pedido.fase ? ` da fase ${pedido.fase}` : ''}, pelo canal ${pedido.canal}.`);
758
- linhas.push('O que voce pode fazer:');
759
- acoes.forEach((a, i) => { linhas.push(` ${i + 1}. ${a.explicacao}`); linhas.push(` ${a.comando}`); });
812
+ linhas.push(m.pedido((0, locale_1.msg)().thread.operacoes[pedido.operacao], pedido.fase ?? null, pedido.canal));
813
+ linhas.push(m.opcoes);
814
+ acoes.forEach((a, i) => { linhas.push(m.passo(i + 1, a.explicacao)); linhas.push(` ${a.comando}`); });
760
815
  return {
761
816
  contrato: 'ork.conducao-recusa/v1',
762
817
  motivo: 'conducao.em-andamento',
@@ -1032,8 +1087,7 @@ function assumirConducao(raiz, threadId, opcoes) {
1032
1087
  worktree: estadoDaWorktree(raiz, threadId),
1033
1088
  });
1034
1089
  return { ok: true, thread: threadId, anterior, mecanismo,
1035
- detalhe: `conducao assumida por ${por} pelo canal ${opcoes.canal}; a proxima operacao desse canal usa a reserva ate ` +
1036
- `${(0, horario_1.formatarDataHoraRotulada)(reserva.expiraEm)}` };
1090
+ detalhe: (0, locale_1.msg)().conducao.cli.detalheAssumida(por, opcoes.canal, (0, horario_1.formatarDataHoraRotulada)(reserva.expiraEm)) };
1037
1091
  }
1038
1092
  finally {
1039
1093
  fs.closeSync(fd);
@@ -1041,14 +1095,15 @@ function assumirConducao(raiz, threadId, opcoes) {
1041
1095
  }
1042
1096
  /** Texto de `ork conducao status`. */
1043
1097
  function textoDoStatusDaConducao(threadId, atual) {
1098
+ const m = (0, locale_1.msg)().conducao.status;
1044
1099
  if (!atual)
1045
- return `Thread ${threadId}: ninguem conduz agora. Qualquer canal pode despachar ou verificar.`;
1046
- const linhas = [`Thread ${threadId}: ${(0, conducao_texto_1.linhaDeConducao)(atual)}`];
1100
+ return m.livre(threadId);
1101
+ const linhas = [m.titulo(threadId, (0, conducao_texto_1.linhaDeConducao)(atual))];
1047
1102
  if (atual.promptSha256)
1048
- linhas.push(` prompt sha256 ${atual.promptSha256.slice(0, 12)}`);
1049
- linhas.push(` prazo do lease (metadado, nao prova): ${(0, horario_1.formatarDataHoraRotulada)(atual.expiraEm)}`);
1103
+ linhas.push(m.prompt(atual.promptSha256.slice(0, 12)));
1104
+ linhas.push(m.prazo((0, horario_1.formatarDataHoraRotulada)(atual.expiraEm)));
1050
1105
  if (atual.sessao)
1051
- linhas.push(` acompanhar: ork sessions logs ${atual.sessao.slice(0, 8)}`);
1052
- linhas.push(` assumir: ork conducao assumir ${threadId} --por <voce> --motivo "<por que>"`);
1106
+ linhas.push(m.acompanhar(atual.sessao.slice(0, 8)));
1107
+ linhas.push(m.assumir(threadId));
1053
1108
  return linhas.join('\n');
1054
1109
  }
@@ -0,0 +1,270 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CONSULTAS_DO_CONHECIMENTO = void 0;
4
+ exports.brainDoProjeto = brainDoProjeto;
5
+ exports.consultarConhecimento = consultarConhecimento;
6
+ exports.consultaRespondeu = consultaRespondeu;
7
+ exports.textoDoConhecimento = textoDoConhecimento;
8
+ /**
9
+ * RM-026 K7 (fatia 2): as consultas do conhecimento escrito, a porta pública do contrato `ork.conhecimento/v1`. A CLI
10
+ * (`ork conhecimento listar|mostrar|colecoes|verificar`) e as tools MCP (`ork_conhecimento_*`) chamam
11
+ * `consultarConhecimento` e devolvem o mesmo JSON (D11).
12
+ *
13
+ * Só leitura. O id do Brain referenciado confere por `get` no Company Brain (D12), só onde a resposta mostra
14
+ * referência: o `mostrar` (as do documento pedido) e o `verificar` (as de todos). `listar` e `colecoes` não abrem o
15
+ * Brain e não mostram referência nem lacuna de referência. Id inexistente, retido e Brain fora do ar são lacunas
16
+ * distintas, nunca resposta. O transporte do Brain é o do `ork brain get` (`memory.cli` conferido no manifesto, cwd
17
+ * fora do clone), na fronteira da RM-047. Contrato: docs/referencia/contratos/conhecimento-rm026.md.
18
+ */
19
+ const company_brain_client_1 = require("./company-brain-client");
20
+ const company_brain_contract_1 = require("./company-brain-contract");
21
+ const conhecimento_1 = require("./conhecimento");
22
+ const locale_1 = require("./locale");
23
+ const project_state_1 = require("./project-state");
24
+ const saida_segura_1 = require("./saida-segura");
25
+ exports.CONSULTAS_DO_CONHECIMENTO = ['listar', 'mostrar', 'colecoes', 'verificar'];
26
+ /**
27
+ * O Brain do projeto, como o `ork brain get` o abre: a configuração de memória vem da árvore principal também numa
28
+ * worktree (`memoryState`), e o tenant do pedido é o dela.
29
+ */
30
+ function brainDoProjeto(c) {
31
+ const contexto = (0, project_state_1.memoryState)(c);
32
+ return { transporte: (0, company_brain_client_1.brainClient)(contexto.loaded), tenant: contexto.loaded.manifesto.memory.tenant };
33
+ }
34
+ const comparar = (a, b) => a < b ? -1 : a > b ? 1 : 0;
35
+ const t = conhecimento_1.detalheDoConhecimento;
36
+ /** Lacuna da pasta: nada foi lido, e nenhuma consulta responde. */
37
+ const daPasta = (l) => l.codigo.startsWith('conhecimento.');
38
+ /** O código de erro do Brain, só quando tem a forma de um; texto alheio não chega ao detalhe. */
39
+ const erroDoBrain = (e) => typeof e === 'string' && /^brain\.[a-z0-9.-]{1,80}$/.test(e) ? e : null;
40
+ /** O código de uma exceção na abertura do Brain (`project-state.memory.unavailable`), só quando tem a forma de um. */
41
+ const codigoDaExcecao = (e) => {
42
+ const m = e instanceof Error ? e.message : '';
43
+ return /^[a-z][a-z0-9-]*(?:\.[a-z0-9-]+){1,4}$/.test(m) && m.length <= 80 ? m : null;
44
+ };
45
+ /** D12: a resposta `ok` do `get` vale só no contrato da entidade, com o id e o tenant pedidos. */
46
+ function referenciaDoBrain(r, id, tenant) {
47
+ let e;
48
+ try {
49
+ e = (0, company_brain_contract_1.validateContract)(r.entity);
50
+ }
51
+ catch {
52
+ return null;
53
+ }
54
+ if (e.schema !== 'orkmind.company-brain-entity/v1' || e.id !== id || e.tenant_id !== tenant)
55
+ return null;
56
+ return { id, kind: e.kind, titulo: (0, saida_segura_1.emUmaLinha)(e.title), versao: e.version, fonte: e.source.source_ref, sha256: e.source.source_hash };
57
+ }
58
+ /** Os estados do Brain que encerram a conferência: os mesmos que o contexto e o dossiê tratam como falha. */
59
+ const FALHAS_DO_BRAIN = ['unavailable', 'forbidden', 'conflict'];
60
+ /**
61
+ * D12 (revista depois do CHECK): um `get` por id distinto, em ordem, até o teto de `get` e o prazo da consulta (cada
62
+ * `get` é um processo do `memory.cli`). O Brain que não responde (fora do ar, sem configuração, recusa ou conflito) para
63
+ * a conferência: nenhum `get` sai depois, e o resto leva o mesmo detalhe. A resposta fora do contrato vale só para o id
64
+ * dela. `unknown` e `empty` são o id que o Brain não tem, como no dossiê.
65
+ */
66
+ function conferirNoBrain(ids, abrir, limites) {
67
+ const conferidas = new Map();
68
+ const naoConferida = (detalhe) => ({ codigo: 'referencia.brain-indisponivel', detalhe });
69
+ let brain = null, parada = null, gets = 0;
70
+ const inicio = Date.now();
71
+ for (const id of [...new Set(ids)].sort(comparar)) {
72
+ if (parada === null && gets >= limites.getsDoBrain)
73
+ parada = t((l) => l.brainTeto(limites.getsDoBrain));
74
+ if (parada === null && gets > 0 && Date.now() - inicio > limites.msDaConferencia) {
75
+ parada = t((l) => l.brainPrazo(limites.msDaConferencia / 1000));
76
+ }
77
+ if (parada !== null) {
78
+ conferidas.set(id, naoConferida(parada));
79
+ continue;
80
+ }
81
+ if (brain === null) {
82
+ try {
83
+ brain = abrir();
84
+ }
85
+ catch (e) {
86
+ const codigo = codigoDaExcecao(e);
87
+ parada = t((l) => l.brainSemConfiguracao(codigo));
88
+ conferidas.set(id, naoConferida(parada));
89
+ continue;
90
+ }
91
+ }
92
+ gets++;
93
+ let r;
94
+ try {
95
+ r = brain.transporte({ schema: company_brain_client_1.BRAIN_API, operation: 'get', payload: { tenant_id: brain.tenant, id } });
96
+ }
97
+ catch (e) {
98
+ const codigo = erroDoBrain(codigoDaExcecao(e));
99
+ parada = t((l) => l.brainNaoRespondeu('unavailable', codigo));
100
+ conferidas.set(id, naoConferida(parada));
101
+ continue;
102
+ }
103
+ if (r.state === 'ok')
104
+ conferidas.set(id, referenciaDoBrain(r, id, brain.tenant) ?? naoConferida(t((l) => l.brainForaDoContrato)));
105
+ else if (r.state === 'unknown' || r.state === 'empty') {
106
+ conferidas.set(id, { codigo: 'referencia.brain-inexistente', detalhe: t((l) => l.brainInexistente) });
107
+ }
108
+ else if (r.state === 'withheld')
109
+ conferidas.set(id, { codigo: 'referencia.brain-retido', detalhe: t((l) => l.brainRetido) });
110
+ else if (FALHAS_DO_BRAIN.includes(r.state)) {
111
+ const estado = r.state, erro = erroDoBrain(r.error);
112
+ parada = t((l) => l.brainNaoRespondeu(estado, erro));
113
+ conferidas.set(id, naoConferida(parada));
114
+ }
115
+ else
116
+ conferidas.set(id, naoConferida(t((l) => l.brainForaDoContrato)));
117
+ }
118
+ return conferidas;
119
+ }
120
+ /** As referências do Brain conferidas; a que não confere vira lacuna, e o documento segue sem ela (D4). */
121
+ function conferirDocumentos(docs, abrir, lacunas, limites) {
122
+ const conferencias = conferirNoBrain(docs.flatMap((d) => d.referencias.brain), abrir, limites);
123
+ return docs.map((d) => {
124
+ const brain = [];
125
+ for (const id of d.referencias.brain) {
126
+ const r = conferencias.get(id);
127
+ if ('codigo' in r)
128
+ lacunas.push((0, conhecimento_1.lacunaDoConhecimento)(r.codigo, r.detalhe, { arquivo: d.arquivo, documento: d.id, referencia: id }));
129
+ else
130
+ brain.push(r);
131
+ }
132
+ return { id: d.id, titulo: d.titulo, colecoes: d.colecoes, referencias: { brain, decisoes: d.referencias.decisoes },
133
+ arquivo: d.arquivo, bytes: d.bytes, sha256: d.sha256 };
134
+ });
135
+ }
136
+ const resumo = (d) => ({ id: d.id, titulo: d.titulo, colecoes: d.colecoes, arquivo: d.arquivo, bytes: d.bytes, sha256: d.sha256 });
137
+ /**
138
+ * A consulta pedida, no contrato `ork.conhecimento/v1`. Nunca lança por causa do conteúdo do repositório nem do Brain:
139
+ * o que não vale vira lacuna. O pedido fora da forma (id de documento, nome de coleção) é erro de quem chama; a CLI e
140
+ * as tools o recusam antes. A resposta nasce em pt-BR em qualquer locale (D13): o detalhe das lacunas é o do `--json`
141
+ * e do MCP, e só a impressão o remonta.
142
+ */
143
+ function consultarConhecimento(c, pedido, abrirBrain = () => brainDoProjeto(c), limites = conhecimento_1.LIMITES_DO_CONHECIMENTO) {
144
+ if (pedido.consulta === 'mostrar' && !conhecimento_1.ID_DE_DOCUMENTO.test(pedido.id))
145
+ throw new Error('conhecimento.pedido-invalido: id de documento');
146
+ if (pedido.consulta === 'listar' && pedido.colecao !== undefined && !conhecimento_1.NOME_DE_COLECAO.test(pedido.colecao)) {
147
+ throw new Error('conhecimento.pedido-invalido: nome de coleção');
148
+ }
149
+ return (0, locale_1.comLocale)('pt-BR', () => responder(c, pedido, abrirBrain, limites));
150
+ }
151
+ function responder(c, pedido, abrirBrain, limites) {
152
+ // D12 (revista): as decisões só conferem onde a resposta as mostra; listar e colecoes não leem ledger.
153
+ const k = (0, conhecimento_1.lerConhecimento)(c, limites, pedido.consulta === 'mostrar' ? { corpoDe: pedido.id, decisoesDe: pedido.id }
154
+ : pedido.consulta === 'verificar' ? {} : { decisoesDe: 'nenhum' });
155
+ const base = { contrato: conhecimento_1.CONTRATO_CONHECIMENTO, consulta: pedido.consulta, dir: k.dir };
156
+ // D12: quem não mostra referência não mostra a lacuna dela.
157
+ const semReferencia = () => k.lacunas.filter((l) => !l.codigo.startsWith('referencia.'));
158
+ switch (pedido.consulta) {
159
+ case 'listar': {
160
+ const colecao = pedido.colecao ?? null;
161
+ return { ...base, consulta: 'listar', colecao,
162
+ documentos: k.documentos.filter((d) => colecao === null || d.colecoes.includes(colecao)).map(resumo), lacunas: semReferencia() };
163
+ }
164
+ case 'colecoes':
165
+ return { ...base, consulta: 'colecoes', colecoes: k.colecoes, lacunas: semReferencia() };
166
+ case 'mostrar': {
167
+ const comum = { ...base, consulta: 'mostrar', id: pedido.id };
168
+ if (k.lacunas.some(daPasta))
169
+ return { ...comum, documento: null, lacunas: k.lacunas };
170
+ const lacunas = k.lacunas.filter((l) => l.documento === pedido.id);
171
+ const doc = k.documentos.find((d) => d.id === pedido.id);
172
+ if (!doc) {
173
+ // D13: o id que nenhum documento válido tem; os arquivos que viraram lacuna antes de o id ser lido entram na conta.
174
+ if (!lacunas.length) {
175
+ const semId = k.lacunas.filter((l) => l.arquivo !== null && l.documento === null).length;
176
+ lacunas.push((0, conhecimento_1.lacunaDoConhecimento)('documento.inexistente', t((l) => l.documentoInexistente(pedido.id, semId)), { documento: pedido.id }));
177
+ }
178
+ return { ...comum, documento: null, lacunas };
179
+ }
180
+ const [conferido] = conferirDocumentos([doc], abrirBrain, lacunas, limites);
181
+ return { ...comum, documento: { ...conferido, corpo: doc.corpo ?? '' }, lacunas: lacunas.sort(conhecimento_1.compararLacunas) };
182
+ }
183
+ case 'verificar': {
184
+ const lacunas = [...k.lacunas];
185
+ const documentos = conferirDocumentos(k.documentos, abrirBrain, lacunas, limites);
186
+ return { ...base, consulta: 'verificar', documentos, colecoes: k.colecoes, lacunas: lacunas.sort(conhecimento_1.compararLacunas) };
187
+ }
188
+ }
189
+ }
190
+ /**
191
+ * D13: a consulta respondeu? `listar` e `colecoes`, quando a pasta foi lida; `mostrar`, quando o documento veio;
192
+ * `verificar`, sem nenhuma lacuna. É a saída 0 da CLI e a tool sem `isError`.
193
+ */
194
+ function consultaRespondeu(r) {
195
+ if (r.consulta === 'verificar')
196
+ return r.lacunas.length === 0;
197
+ if (r.consulta === 'mostrar')
198
+ return r.documento !== null;
199
+ return !r.lacunas.some(daPasta);
200
+ }
201
+ /**
202
+ * D13: o texto para gente, pelo catálogo, no locale ativo. O detalhe das lacunas nasce em pt-BR na consulta e é
203
+ * remontado aqui; o corpo do documento é dado do repositório e sai linha a linha, sem caractere invisível.
204
+ */
205
+ function textoDoConhecimento(r) {
206
+ const m = (0, locale_1.msg)().conhecimento, linhas = [];
207
+ const leu = !r.lacunas.some(daPasta), dir = r.dir ?? '';
208
+ if (r.consulta === 'listar') {
209
+ if (!leu)
210
+ linhas.push(m.naoLido);
211
+ else {
212
+ linhas.push(m.listar(dir, r.documentos.length, r.colecao));
213
+ const largura = r.documentos.reduce((n, d) => Math.max(n, d.id.length), 0);
214
+ for (const d of r.documentos)
215
+ linhas.push(m.documento(d.id.padEnd(largura), d.titulo, d.colecoes.join(', ')));
216
+ if (!r.documentos.length)
217
+ linhas.push(m.nenhumDocumento);
218
+ }
219
+ }
220
+ else if (r.consulta === 'colecoes') {
221
+ if (!leu)
222
+ linhas.push(m.naoLido);
223
+ else {
224
+ linhas.push(m.colecoes(dir, r.colecoes.length));
225
+ const largura = r.colecoes.reduce((n, x) => Math.max(n, x.nome.length), 0);
226
+ for (const x of r.colecoes)
227
+ linhas.push(m.colecao(x.nome.padEnd(largura), x.documentos.join(', ')));
228
+ if (!r.colecoes.length)
229
+ linhas.push(m.nenhumaColecao);
230
+ }
231
+ }
232
+ else if (r.consulta === 'mostrar') {
233
+ const d = r.documento;
234
+ if (!d)
235
+ linhas.push(leu ? m.semDocumento(r.id) : m.naoLido);
236
+ else {
237
+ linhas.push(m.mostrar(d.id, d.titulo), m.colecoesDoDocumento(d.colecoes.join(', ')), m.arquivo(d.arquivo), m.versao(d.sha256, d.bytes));
238
+ for (const b of d.referencias.brain)
239
+ linhas.push(m.brain(b.id, b.titulo, b.kind, b.versao, b.fonte));
240
+ for (const x of d.referencias.decisoes)
241
+ linhas.push(m.decisao(x.ref, x.tipo, x.fonte));
242
+ if (!d.referencias.brain.length && !d.referencias.decisoes.length)
243
+ linhas.push(m.semReferencia);
244
+ }
245
+ }
246
+ else if (!leu)
247
+ linhas.push(m.naoLido);
248
+ else {
249
+ const soma = (f) => r.documentos.reduce((n, d) => n + f(d), 0);
250
+ linhas.push(m.verificar(dir, r.documentos.length, soma((d) => d.referencias.brain.length), soma((d) => d.referencias.decisoes.length)));
251
+ }
252
+ if (r.lacunas.length) {
253
+ linhas.push(m.lacunasTitulo(r.lacunas.length));
254
+ for (const l of r.lacunas) {
255
+ const onde = (l.arquivo ?? m.pasta) + (l.documento ? ` (${l.documento})` : '') + (l.referencia !== null ? `, ${m.naReferencia(l.referencia)}` : '');
256
+ linhas.push(m.lacuna(l.codigo, onde, (0, locale_1.remontar)(l.detalhe)));
257
+ }
258
+ }
259
+ if (r.consulta === 'listar' && r.documentos.length)
260
+ linhas.push(m.paraLer);
261
+ if (r.consulta === 'verificar')
262
+ linhas.push(r.lacunas.length ? m.reprovado(r.lacunas.length) : m.aprovado);
263
+ // O corpo vai linha a linha: espalhar um documento de muitas linhas nos argumentos estoura a pilha (achado do CHECK).
264
+ if (r.consulta === 'mostrar' && r.documento) {
265
+ linhas.push('', m.corpo);
266
+ for (const linha of r.documento.corpo.replace(/\n$/, '').split('\n'))
267
+ linhas.push((0, saida_segura_1.emUmaLinha)(linha));
268
+ }
269
+ return linhas.join('\n');
270
+ }