@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
package/dist/thread.js CHANGED
@@ -61,6 +61,9 @@ exports.avisoDaWorktree = avisoDaWorktree;
61
61
  exports.prepararPedido = prepararPedido;
62
62
  exports.pedidoDaThread = pedidoDaThread;
63
63
  exports.novaThread = novaThread;
64
+ exports.dependenciasPendentes = dependenciasPendentes;
65
+ exports.prepararDependenciasPendentes = prepararDependenciasPendentes;
66
+ exports.prepararDependenciasDaThread = prepararDependenciasDaThread;
64
67
  exports.exigirVarianteCompativel = exigirVarianteCompativel;
65
68
  exports.blocoDaThread = blocoDaThread;
66
69
  exports.pausaNaThread = pausaNaThread;
@@ -84,9 +87,12 @@ const ledger_1 = require("./ledger");
84
87
  const estado_thread_1 = require("./estado-thread");
85
88
  const creation_operation_store_1 = require("./creation-operation-store");
86
89
  const horario_1 = require("./horario");
90
+ const check_modo_1 = require("./check-modo");
87
91
  const maquina_1 = require("./maquina");
88
92
  const conducao_texto_1 = require("./conducao-texto");
89
93
  const locale_1 = require("./locale");
94
+ const branch_de_estado_1 = require("./branch-de-estado");
95
+ const dependencias_da_worktree_1 = require("./dependencias-da-worktree");
90
96
  /** Diretorio de threads do projeto. */
91
97
  function dirThreads(raiz) {
92
98
  return path.join((0, manifest_1.dirEstado)((0, estado_thread_1.raizDoEstado)(raiz)), 'threads');
@@ -172,9 +178,11 @@ function alvoDaWorktree(carregado, id, slug, opcoes = {}) {
172
178
  */
173
179
  function worktreePrevista(carregado, id, slug, opcoes = {}) {
174
180
  const alvo = alvoDaWorktree(carregado, id, slug, opcoes);
181
+ const base = opcoes.base ?? carregado.manifesto.worktree.base_branch;
182
+ const remoto = (0, branch_de_estado_1.exigirRemoto)(carregado.manifesto.fabrica.remoto, 'worktree');
175
183
  const refs = opcoes.branchExistente
176
184
  ? [opcoes.branchExistente]
177
- : [opcoes.base ?? carregado.manifesto.worktree.base_branch, 'HEAD'];
185
+ : [(0, branch_de_estado_1.refRemota)(remoto, base), base, 'HEAD'];
178
186
  let commit = null;
179
187
  for (const ref of refs) {
180
188
  const r = (0, util_1.exec)('git', ['rev-parse', '--verify', ref], carregado.raiz);
@@ -189,6 +197,36 @@ function worktreePrevista(carregado, id, slug, opcoes = {}) {
189
197
  : commit === null ? 'sem-commit' : branchJaExiste ? 'branch-existe' : null;
190
198
  return { ...alvo, commit, falha };
191
199
  }
200
+ /**
201
+ * Resolve a base de uma worktree nova. Com remoto configurado e presente, a fonte e sempre
202
+ * `refs/remotes/<remoto>/<base>` atualizada por um fetch explicito; a branch local pode pertencer a
203
+ * outra worktree e ficar parada indefinidamente. Repositorio sem esse remoto preserva o caso local.
204
+ */
205
+ function baseAtualDaWorktree(carregado, base) {
206
+ const { raiz, manifesto } = carregado;
207
+ const remoto = (0, branch_de_estado_1.exigirRemoto)(manifesto.fabrica.remoto, 'worktree');
208
+ const temRemoto = (0, util_1.exec)('git', ['remote', 'get-url', '--', remoto], raiz).ok;
209
+ let ref = base;
210
+ if (temRemoto) {
211
+ ref = (0, branch_de_estado_1.refRemota)(remoto, base);
212
+ const ambiente = { ...process.env, GIT_TERMINAL_PROMPT: '0',
213
+ GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND ?? 'ssh -o BatchMode=yes' };
214
+ const fetch = (0, util_1.exec)('git', ['fetch', '-q', '--no-tags', '--', remoto,
215
+ `+refs/heads/${base}:${ref}`], raiz, 120000, ambiente);
216
+ if (!fetch.ok) {
217
+ const saida = (fetch.stderr || fetch.stdout).trim().split('\n').slice(-2).join(' | ');
218
+ throw new locale_1.ErroDoCatalogo((m) => m.worktree.baseRemotaFalhou(remoto, base, saida));
219
+ }
220
+ }
221
+ const resolvida = (0, util_1.exec)('git', ['rev-parse', '--verify', ref], raiz);
222
+ if (!resolvida.ok) {
223
+ // Repositorio local ainda sem a branch do manifesto conserva a recusa historica do
224
+ // `git worktree add ... HEAD`; com remoto presente, o fetch acima ja teria recusado.
225
+ const head = (0, util_1.exec)('git', ['rev-parse', '--verify', 'HEAD'], raiz);
226
+ return { ref: 'HEAD', commit: head.ok ? head.stdout.trim() : util_1.COMMIT_DESCONHECIDO };
227
+ }
228
+ return { ref, commit: resolvida.stdout.trim() };
229
+ }
192
230
  /**
193
231
  * Cria a worktree isolada da thread (paralelismo sem colisao entre threads).
194
232
  *
@@ -202,31 +240,38 @@ function criarWorktree(carregado, id, slug, opcoes = {}) {
202
240
  (0, worktree_local_1.exigirPastaDasWorktrees)(raiz, manifesto);
203
241
  const { dir, branch } = alvoDaWorktree(carregado, id, slug, opcoes);
204
242
  if (fs.existsSync(dir)) {
205
- throw new Error(`worktree ja existe em ${dir}`);
243
+ throw new locale_1.ErroDoCatalogo((m) => m.worktree.worktreeJaExisteEm(dir));
206
244
  }
207
245
  const base = opcoes.base ?? manifesto.worktree.base_branch;
208
- const commitBase = (0, util_1.exec)('git', ['rev-parse', '--verify', base], raiz);
209
- const ref = commitBase.ok ? commitBase.stdout.trim() : 'HEAD';
246
+ const resolvida = opcoes.branchExistente
247
+ ? (() => {
248
+ const r = (0, util_1.exec)('git', ['rev-parse', '--verify', opcoes.branchExistente], raiz);
249
+ if (!r.ok)
250
+ throw new locale_1.ErroDoCatalogo((m) => m.worktree.baseInexistente(opcoes.branchExistente));
251
+ return { ref: opcoes.branchExistente, commit: r.stdout.trim() };
252
+ })()
253
+ : baseAtualDaWorktree(carregado, base);
210
254
  // Fatia 2 do ensaio da 0.5.0 (P3): a pasta das worktrees que o ork cria agora nasce fora do git.
211
255
  const pastaDasWorktrees = path.dirname(dir);
212
256
  const pastaNova = !fs.existsSync(pastaDasWorktrees);
213
257
  // Branch nova (`-b`) no caso comum; branch que ja existe no ciclo `merge-branch`.
214
258
  const argumentos = opcoes.branchExistente
215
259
  ? ['worktree', 'add', dir, opcoes.branchExistente]
216
- : ['worktree', 'add', '-b', branch, dir, ref];
260
+ : ['worktree', 'add', '-b', branch, dir, resolvida.ref];
217
261
  const r = (0, util_1.exec)('git', argumentos, raiz);
218
262
  if (!r.ok) {
219
- throw new Error(`git worktree add falhou: ${(r.stderr || r.stdout).trim()}`);
263
+ const saida = (r.stderr || r.stdout).trim();
264
+ throw new locale_1.ErroDoCatalogo((m) => m.worktree.worktreeAddFalhou(saida));
220
265
  }
221
266
  if (pastaNova)
222
267
  (0, util_1.ignorarPastaNoGit)(pastaDasWorktrees, (0, estado_thread_1.raizDoEstado)(raiz));
223
268
  const lista = (0, util_1.exec)('git', ['worktree', 'list', '--porcelain'], raiz);
224
269
  const criada = lista.ok && lista.stdout.split('\n').some((l) => l.trim() === `worktree ${dir}`);
225
270
  if (!criada) {
226
- throw new Error(`worktree nao apareceu em \`git worktree list\` apos a criacao: ${dir}`);
271
+ throw new locale_1.ErroDoCatalogo((m) => m.worktree.worktreeNaoApareceu(dir));
227
272
  }
228
273
  (0, estado_thread_1.vincularEstado)(raiz, id, dir);
229
- return { dir, branch };
274
+ return { dir, branch, commit: resolvida.commit };
230
275
  }
231
276
  /**
232
277
  * Resolve `--worktree`, `--sem-worktree` e `worktree.por_thread`. As flags vencem a chave; as duas juntas, ou
@@ -387,7 +432,63 @@ function gravarPedido(dir, texto) {
387
432
  function novaThread(carregado, opcoes) {
388
433
  if (opcoes.dryRun)
389
434
  return criarThreadSerializada(carregado, opcoes);
390
- return (0, creation_operation_store_1.withCreationLock)((0, estado_thread_1.raizDoEstado)(carregado.raiz), 'threads', () => criarThreadSerializada(carregado, opcoes));
435
+ const criada = (0, creation_operation_store_1.withCreationLock)((0, estado_thread_1.raizDoEstado)(carregado.raiz), 'threads', () => criarThreadSerializada(carregado, opcoes));
436
+ // RM-037 (defeito 2 de 19 e 20/10/2026): o preparo das dependencias roda depois da trava de criacao, que espera
437
+ // segundos, e nao os minutos de um `npm ci`.
438
+ if (!criada.gravada || !criada.worktreePor || !criada.thread.worktree)
439
+ return criada;
440
+ if (opcoes.adiarDependencias) {
441
+ adiarDependenciasDaThread(carregado, criada.thread.id, criada.thread.worktree);
442
+ return { ...criada, dependencias: null };
443
+ }
444
+ return { ...criada, dependencias: prepararDependenciasDaThread(carregado, criada.thread.id, criada.thread.worktree) };
445
+ }
446
+ /** RM-037 (CHECK 3 da ork-rm037defeit2): a criacao que nao pode esperar o preparo so o anota como pendente. */
447
+ function adiarDependenciasDaThread(carregado, id, dir) {
448
+ const { dependencias } = carregado.manifesto.worktree;
449
+ if (!dependencias)
450
+ return;
451
+ (0, ledger_1.registrar)(dirThread(carregado.raiz, id), id, ledger_1.TIPOS_DE_EVENTO.worktreeDependenciasPendentes, { dir, comando: dependencias, fonte: 'worktree.dependencias do manifesto' });
452
+ }
453
+ /**
454
+ * RM-037 (CHECK 3 da ork-rm037defeit2): a worktree `dir` tem o preparo adiado na criacao sem um preparo ok depois dele? O
455
+ * preparo que falhou nao cobre: a baseline e o verify o repetem e recusam seguir enquanto ele falhar.
456
+ */
457
+ function dependenciasPendentes(eventos, dir) {
458
+ let pendente = false;
459
+ for (const e of eventos) {
460
+ if (typeof e.dir !== 'string' || path.resolve(e.dir) !== path.resolve(dir))
461
+ continue;
462
+ if (e.tipo === ledger_1.TIPOS_DE_EVENTO.worktreeDependenciasPendentes)
463
+ pendente = true;
464
+ else if (e.tipo === ledger_1.TIPOS_DE_EVENTO.worktreeDependencias && e.ok === true)
465
+ pendente = false;
466
+ }
467
+ return pendente;
468
+ }
469
+ /**
470
+ * RM-037 (CHECK 3 da ork-rm037defeit2): roda o preparo que a criacao adiou, antes de a baseline ou o verify rodarem um
471
+ * comando, com a vez na fila pesada que eles ja seguram; `antes` so e chamado quando ha preparo a rodar (a renovacao da
472
+ * conducao pelo prazo dele), e o `executor` da operacao, quando ela traz um (o do sandbox do MCP), roda o preparo no lugar
473
+ * do executor do verify. Devolve o preparo rodado agora, ou `null` sem nada pendente; quem chama recusa a falha.
474
+ */
475
+ function prepararDependenciasPendentes(carregado, id, dir, opcoes = {}) {
476
+ if (!dependenciasPendentes((0, ledger_1.lerLedger)(dirThread(carregado.raiz, id)), dir))
477
+ return null;
478
+ opcoes.antes?.();
479
+ return prepararDependenciasDaThread(carregado, id, dir, opcoes.executor);
480
+ }
481
+ /**
482
+ * RM-037 (defeito 2 de 19 e 20/10/2026): roda `worktree.dependencias` na worktree que acabou de nascer e grava o
483
+ * resultado no ledger da thread. Sem a chave no manifesto, nada roda e nada se grava. A falha nao desfaz nada.
484
+ */
485
+ function prepararDependenciasDaThread(carregado, id, dir, executor) {
486
+ const comando = carregado.manifesto.worktree.dependencias;
487
+ if (!comando)
488
+ return null;
489
+ const preparo = (0, dependencias_da_worktree_1.prepararDependencias)(dir, comando, undefined, executor);
490
+ (0, ledger_1.registrar)(dirThread(carregado.raiz, id), id, ledger_1.TIPOS_DE_EVENTO.worktreeDependencias, (0, dependencias_da_worktree_1.eventoDoPreparo)(dir, preparo));
491
+ return preparo;
391
492
  }
392
493
  /**
393
494
  * I-42 (D12): variante que redesenha blocos nao cabe num modo de bloco unico e parcial.
@@ -552,10 +653,9 @@ function criarThreadSerializada(carregado, opcoes) {
552
653
  branchExistente: opcoes.branch,
553
654
  });
554
655
  thread.worktree = worktreeCriada.dir;
555
- const commitDaBranch = (0, util_1.exec)('git', ['rev-parse', worktreeCriada.branch], raiz);
556
656
  thread.base = {
557
657
  branch: worktreeCriada.branch,
558
- commit: commitDaBranch.ok ? commitDaBranch.stdout.trim() : thread.base.commit,
658
+ commit: worktreeCriada.commit,
559
659
  };
560
660
  }
561
661
  // RM-059 (T6.0): o pedido vai ao lado do thread.json, so com permissao do dono, como ele, e antes dele: o
@@ -652,6 +752,10 @@ function resumoDaThread(thread, conducao) {
652
752
  if (thread.score) {
653
753
  linhas.push(campo(r.score, m.score(thread.score.valor, thread.score.avaliadoPor, thread.score.regime, (0, horario_1.formatarDataHoraRotulada)(thread.score.avaliadoEm))));
654
754
  }
755
+ // RM-072 (D17): o modo do ultimo CHECK, so quando a thread ja teve verify.
756
+ if (thread.check) {
757
+ linhas.push(campo(r.check, m.check(check_modo_1.NOME_DO_MODO[thread.check.modo], thread.check.origem, (0, horario_1.formatarDataHoraRotulada)(thread.check.em), (0, util_1.shaCurto)(thread.check.commit))));
758
+ }
655
759
  linhas.push(m.blocosPrevistos);
656
760
  for (const b of thread.blocos) {
657
761
  const marca = b.pausa ? m.pausaPrevista(m.pausaSobre(b.pausaSobre)) : m.semPausa;
@@ -688,23 +792,22 @@ function threadsDaListagem(raiz, opcoes = {}) {
688
792
  /** Tabela de `ork thread list`. */
689
793
  function tabelaDeThreads(raiz, opcoes = {}) {
690
794
  const linhas = threadsDaListagem(raiz, opcoes);
795
+ // RM-061 (F3b): o texto pelo catalogo; o status (dado do `--json`) so se traduz na impressao, pelo id.
796
+ const mt = (0, locale_1.msg)().thread;
691
797
  if (linhas.length === 0) {
692
798
  // A divida paga aqui: a mensagem sugeria `--modo default`, um modo que
693
799
  // `parseModo` recusa, e e a origem provavel das 3 threads com `modo: default`
694
800
  // gravadas em disco. A sugestao agora e um modo que existe.
695
- const vazio = opcoes.todas === true
696
- ? 'Nenhuma thread em .orkastery/threads.'
697
- : 'Nenhuma thread aberta ou pausada (use --todas para ver as fechadas).';
698
- return `${vazio} Crie uma com: ork thread new "<nome>" --modo ${modos_1.ORDEM_DOS_MODOS[0]}`;
801
+ return mt.listaVazia(opcoes.todas === true, modos_1.ORDEM_DOS_MODOS[0]);
699
802
  }
700
803
  const corpo = linhas.map((l) => [
701
- l.id, l.slug, l.tag, l.fase, l.status, String(l.pausas), String(l.sessoes),
804
+ l.id, l.slug, l.tag, l.fase, mt.status(l.status), String(l.pausas), String(l.sessoes),
702
805
  ]);
703
- const t = (0, util_1.tabela)(['ID', 'SLUG', 'MODO', 'FASE', 'STATUS', 'PAUSAS', 'SESSOES'], corpo);
806
+ const t = (0, util_1.tabela)([...mt.colunasDaLista], corpo);
704
807
  if (opcoes.todas === true)
705
808
  return t;
706
809
  const fechadas = listarIds(raiz).length - linhas.length;
707
- return fechadas > 0 ? `${t}\n\n ${fechadas} fechada(s) omitida(s). Use --todas para ver todas.` : t;
810
+ return fechadas > 0 ? `${t}\n\n${mt.fechadasOmitidas(fechadas)}` : t;
708
811
  }
709
812
  /** Fase valida e pertencente ao ciclo da thread. */
710
813
  function exigirFase(thread, bruto) {
package/dist/tokens.js CHANGED
@@ -63,6 +63,7 @@ const modos_1 = require("./modos");
63
63
  const phase_1 = require("./phase");
64
64
  const thread_1 = require("./thread");
65
65
  const util_1 = require("./util");
66
+ const locale_1 = require("./locale");
66
67
  /**
67
68
  * Janela nominal usada na estimativa por transcript.
68
69
  * Declarada, nao escondida: quem le a medida sabe contra o que ela foi calculada.
@@ -208,21 +209,24 @@ function gateDeTokens(carregado, threadId, opcoes = {}) {
208
209
  }
209
210
  /** Texto de `ork gate next`. */
210
211
  function textoDoGateDeTokens(v) {
212
+ const m = (0, locale_1.msg)().operacao.restante.gate.tokens;
213
+ const detalhe = m.localizarDetalhe(v.medida.fonte, v.medida.detalhe);
214
+ const razao = m.localizarRazao(v.medida.ocupacao, v.limiares.rotate_above, v.limiares.force_rotate_above, v.passoPesado, v.razao.includes('refazer fase reprovada'), v.proximoPasso, v.razao);
211
215
  const linhas = [];
212
- linhas.push(`ork gate next: thread ${v.thread}`);
213
- linhas.push(` ocupacao ${v.medida.ocupacao === null ? 'nao medivel' : `${(v.medida.ocupacao * 100).toFixed(1)}%`}`);
214
- linhas.push(` fonte ${v.medida.fonte}`);
215
- linhas.push(` ${v.medida.detalhe}`);
216
- linhas.push(` limiares rotate_above ${v.limiares.rotate_above} | force_rotate_above ${v.limiares.force_rotate_above}`);
217
- linhas.push(` proximo passo ${v.proximoPasso} (${v.passoPesado ? 'pesado' : 'leve'})`);
216
+ linhas.push(m.titulo(v.thread));
217
+ linhas.push(m.ocupacao(v.medida.ocupacao === null ? m.naoMedivel : `${(v.medida.ocupacao * 100).toFixed(1)}%`));
218
+ linhas.push(m.fonte(v.medida.fonte));
219
+ linhas.push(m.detalhe(detalhe));
220
+ linhas.push(m.limiares(v.limiares.rotate_above, v.limiares.force_rotate_above));
221
+ linhas.push(m.proximo(v.proximoPasso, v.passoPesado ? m.pesado : m.leve));
218
222
  linhas.push('');
219
- linhas.push(`VEREDITO: ${v.veredito} (decidido por ${v.decididoPor})`);
220
- linhas.push(` razao: ${v.razao}`);
223
+ linhas.push(m.veredito(v.veredito, v.decididoPor));
224
+ linhas.push(m.razao(razao));
221
225
  if (v.slugSugerido) {
222
- linhas.push(` slug da nova sessao: ${v.slugSugerido}`);
223
- linhas.push(` proximo passo: ork handoff export ${v.thread} --proxima-fase ${v.proximoPasso}`);
226
+ linhas.push(m.slug(v.slugSugerido));
227
+ linhas.push(m.handoff(v.thread, v.proximoPasso));
224
228
  }
225
229
  linhas.push('');
226
- linhas.push(`Registrado no ledger como token_gate: ork phase list ${v.thread}`);
230
+ linhas.push(m.ledger(v.thread));
227
231
  return linhas.join('\n');
228
232
  }
@@ -0,0 +1,297 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.LIMITE_DE_ARQUIVOS_DO_TRABALHO = exports.LIMITE_TOTAL_DO_TRABALHO = exports.LIMITE_DE_ARQUIVO_DO_TRABALHO = void 0;
37
+ exports.diretorioDoTrabalho = diretorioDoTrabalho;
38
+ exports.caminhoDoTrabalho = caminhoDoTrabalho;
39
+ exports.garantirDiretorioDoTrabalho = garantirDiretorioDoTrabalho;
40
+ exports.gravarRespostaFinalDaSessao = gravarRespostaFinalDaSessao;
41
+ exports.resumirTrabalhoDaThread = resumirTrabalhoDaThread;
42
+ exports.formatarResumoDoTrabalho = formatarResumoDoTrabalho;
43
+ /** RM-064 T4: o trabalho pequeno da sessão acompanha a thread entre contas. */
44
+ const node_crypto_1 = require("node:crypto");
45
+ const fs = __importStar(require("node:fs"));
46
+ const path = __importStar(require("node:path"));
47
+ const thread_1 = require("./thread");
48
+ exports.LIMITE_DE_ARQUIVO_DO_TRABALHO = 256 * 1024;
49
+ exports.LIMITE_TOTAL_DO_TRABALHO = 512 * 1024;
50
+ exports.LIMITE_DE_ARQUIVOS_DO_TRABALHO = 24;
51
+ const LIMITE_DE_ENTRADAS = 256;
52
+ const PROFUNDIDADE_MAXIMA = 4;
53
+ /** Caminho real no estado canônico. O prompt usa a forma relativa e portátil de `caminhoDoTrabalho`. */
54
+ function diretorioDoTrabalho(raiz, threadId) {
55
+ return path.join((0, thread_1.dirThread)(raiz, threadId), 'trabalho');
56
+ }
57
+ function caminhoDoTrabalho(threadId) {
58
+ return `.orkastery/threads/${threadId}/trabalho/`;
59
+ }
60
+ function abrirDiretorioDoTrabalho(raiz, threadId) {
61
+ const diretorio = diretorioDoTrabalho(raiz, threadId);
62
+ fs.mkdirSync(diretorio, { recursive: true, mode: 0o700 });
63
+ let fd;
64
+ try {
65
+ fd = fs.openSync(diretorio, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW | fs.constants.O_DIRECTORY);
66
+ }
67
+ catch {
68
+ throw new Error('trabalho da thread precisa ser diretorio real, nunca link');
69
+ }
70
+ try {
71
+ const aberto = fs.fstatSync(fd);
72
+ if (!aberto.isDirectory())
73
+ throw new Error('trabalho da thread precisa ser diretorio real, nunca link');
74
+ // `mode` de mkdir só vale na criação. Pelo descritor, uma troca de caminho não aplica modo em outro alvo.
75
+ fs.fchmodSync(fd, 0o700);
76
+ const real = fs.realpathSync(diretorio), peloCaminho = fs.statSync(real);
77
+ if (aberto.dev !== peloCaminho.dev || aberto.ino !== peloCaminho.ino)
78
+ throw new Error('trabalho da thread mudou durante a abertura');
79
+ return { diretorio, real, fd };
80
+ }
81
+ catch (erro) {
82
+ fs.closeSync(fd);
83
+ throw erro;
84
+ }
85
+ }
86
+ function garantirDiretorioDoTrabalho(raiz, threadId) {
87
+ const aberto = abrirDiretorioDoTrabalho(raiz, threadId);
88
+ fs.closeSync(aberto.fd);
89
+ const { diretorio } = aberto;
90
+ return diretorio;
91
+ }
92
+ function nomeSeguro(nome) {
93
+ return nome.replace(/[\u0000-\u001f\u007f]/g, '?');
94
+ }
95
+ /**
96
+ * Persiste a resposta do runtime na pasta privada da thread. O ledger recebe somente este recibo:
97
+ * conteúdo de agente pode conter detalhes grandes ou sensíveis e nunca é copiado para o evento.
98
+ */
99
+ function gravarRespostaFinalDaSessao(raiz, threadId, sessionId, texto) {
100
+ if (!/^[a-zA-Z0-9-]{1,128}$/.test(sessionId))
101
+ throw new Error('id de sessão inválido para resposta final');
102
+ const aberto = abrirDiretorioDoTrabalho(raiz, threadId);
103
+ const bruto = Buffer.from(texto, 'utf8');
104
+ const truncada = bruto.byteLength > exports.LIMITE_DE_ARQUIVO_DO_TRABALHO;
105
+ const conteudo = truncada
106
+ ? Buffer.from(bruto.subarray(0, exports.LIMITE_DE_ARQUIVO_DO_TRABALHO).toString('utf8').replace(/\uFFFD$/, ''), 'utf8')
107
+ : bruto;
108
+ const arquivo = `resposta-final-${sessionId}.md`;
109
+ const alvo = path.join(aberto.diretorio, arquivo);
110
+ const temporario = path.join(aberto.diretorio, `.${arquivo}.${process.pid}.${(0, node_crypto_1.randomUUID)()}.tmp`);
111
+ try {
112
+ fs.writeFileSync(temporario, conteudo, { mode: 0o600, flag: 'wx' });
113
+ fs.chmodSync(temporario, 0o600);
114
+ try {
115
+ fs.linkSync(temporario, alvo);
116
+ }
117
+ catch (e) {
118
+ if (e.code !== 'EEXIST')
119
+ throw e;
120
+ const existente = lerArquivoSeguro(aberto.real, alvo, {});
121
+ if (existente.estado !== 'ok' || !existente.conteudo.equals(conteudo))
122
+ throw new Error('resposta final já existe com conteúdo divergente');
123
+ }
124
+ const persistido = lerArquivoSeguro(aberto.real, alvo, {});
125
+ if (persistido.estado !== 'ok')
126
+ throw new Error('resposta final não pôde ser reconferida');
127
+ fs.chmodSync(alvo, 0o600);
128
+ return { arquivo, bytes: persistido.conteudo.byteLength,
129
+ sha256: (0, node_crypto_1.createHash)('sha256').update(persistido.conteudo).digest('hex'), truncada };
130
+ }
131
+ finally {
132
+ try {
133
+ fs.rmSync(temporario, { force: true });
134
+ }
135
+ catch { /* temporário já ausente */ }
136
+ fs.closeSync(aberto.fd);
137
+ }
138
+ }
139
+ const contido = (base, alvo) => alvo === base || alvo.startsWith(base + path.sep);
140
+ /** Abre a entrada sem seguir o componente final e nunca lê mais que o teto mais um byte. */
141
+ function lerArquivoSeguro(baseReal, absoluto, opcoes) {
142
+ try {
143
+ const antes = fs.realpathSync(absoluto);
144
+ if (!contido(baseReal, antes))
145
+ return { estado: 'link' };
146
+ }
147
+ catch {
148
+ return { estado: 'outro' };
149
+ }
150
+ opcoes.antesDeAbrir?.(absoluto);
151
+ let fd;
152
+ try {
153
+ fd = fs.openSync(absoluto, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW | fs.constants.O_NONBLOCK);
154
+ }
155
+ catch (erro) {
156
+ return { estado: erro.code === 'ELOOP' ? 'link' : 'outro' };
157
+ }
158
+ try {
159
+ const inicial = fs.fstatSync(fd);
160
+ if (!inicial.isFile())
161
+ return { estado: 'outro' };
162
+ if (inicial.size > exports.LIMITE_DE_ARQUIVO_DO_TRABALHO)
163
+ return { estado: 'grande' };
164
+ const buffer = Buffer.alloc(exports.LIMITE_DE_ARQUIVO_DO_TRABALHO + 1);
165
+ let lidos = 0;
166
+ while (lidos < buffer.length) {
167
+ const n = fs.readSync(fd, buffer, lidos, buffer.length - lidos, null);
168
+ if (n === 0)
169
+ break;
170
+ lidos += n;
171
+ }
172
+ const final = fs.fstatSync(fd);
173
+ if (lidos > exports.LIMITE_DE_ARQUIVO_DO_TRABALHO || final.size > exports.LIMITE_DE_ARQUIVO_DO_TRABALHO)
174
+ return { estado: 'grande' };
175
+ // Confere que o caminho ainda aponta para o mesmo inode aberto e continua dentro da pasta.
176
+ let peloCaminho, realDepois;
177
+ try {
178
+ realDepois = fs.realpathSync(absoluto);
179
+ peloCaminho = fs.statSync(realDepois);
180
+ }
181
+ catch {
182
+ return { estado: 'outro' };
183
+ }
184
+ if (!contido(baseReal, realDepois) || peloCaminho.dev !== final.dev || peloCaminho.ino !== final.ino)
185
+ return { estado: 'link' };
186
+ // Mudança durante a leitura não produz hash de estado híbrido.
187
+ if (lidos !== final.size || inicial.size !== final.size || inicial.mtimeMs !== final.mtimeMs || inicial.ctimeMs !== final.ctimeMs)
188
+ return { estado: 'outro' };
189
+ return { estado: 'ok', conteudo: buffer.subarray(0, lidos) };
190
+ }
191
+ finally {
192
+ fs.closeSync(fd);
193
+ }
194
+ }
195
+ /**
196
+ * Inventário deliberadamente limitado: não segue links, lê cada arquivo por descritor limitado e não deixa uma árvore
197
+ * de job dominar o prompt. A sessão sucessora recebe nomes, tamanhos e hashes; lê o arquivo pelo caminho se precisar.
198
+ */
199
+ function resumirTrabalhoDaThread(raiz, threadId, opcoes = {}) {
200
+ const aberto = abrirDiretorioDoTrabalho(raiz, threadId);
201
+ const base = aberto.diretorio, baseReal = aberto.real;
202
+ const arquivos = [];
203
+ const ignorados = { grandes: 0, links: 0, excedentes: 0, outros: 0 };
204
+ let bytes = 0;
205
+ let entradas = 0;
206
+ const visitar = (diretorio, relativo, profundidade) => {
207
+ if (profundidade > PROFUNDIDADE_MAXIMA || entradas >= LIMITE_DE_ENTRADAS) {
208
+ ignorados.excedentes += 1;
209
+ return;
210
+ }
211
+ let dir;
212
+ try {
213
+ const real = fs.realpathSync(diretorio);
214
+ if (!contido(baseReal, real) || !fs.lstatSync(diretorio).isDirectory()) {
215
+ ignorados.links += 1;
216
+ return;
217
+ }
218
+ dir = fs.opendirSync(diretorio);
219
+ }
220
+ catch {
221
+ ignorados.outros += 1;
222
+ return;
223
+ }
224
+ const itens = [];
225
+ try {
226
+ while (entradas + itens.length < LIMITE_DE_ENTRADAS) {
227
+ const item = dir.readSync();
228
+ if (!item)
229
+ break;
230
+ itens.push(item);
231
+ }
232
+ if (entradas + itens.length >= LIMITE_DE_ENTRADAS && dir.readSync())
233
+ ignorados.excedentes += 1;
234
+ }
235
+ finally {
236
+ dir.closeSync();
237
+ }
238
+ entradas += itens.length;
239
+ itens.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
240
+ for (const item of itens) {
241
+ const absoluto = path.join(diretorio, item.name);
242
+ const nome = path.posix.join(relativo, nomeSeguro(item.name));
243
+ if (item.isSymbolicLink()) {
244
+ ignorados.links += 1;
245
+ continue;
246
+ }
247
+ if (item.isDirectory()) {
248
+ visitar(absoluto, nome, profundidade + 1);
249
+ continue;
250
+ }
251
+ if (!item.isFile()) {
252
+ ignorados.outros += 1;
253
+ continue;
254
+ }
255
+ // Lista ou orçamento já cheios: o arquivo só conta como excedente, sem ser aberto nem lido.
256
+ if (arquivos.length >= exports.LIMITE_DE_ARQUIVOS_DO_TRABALHO || bytes >= exports.LIMITE_TOTAL_DO_TRABALHO) {
257
+ ignorados.excedentes += 1;
258
+ continue;
259
+ }
260
+ const leitura = lerArquivoSeguro(baseReal, absoluto, opcoes);
261
+ if (leitura.estado !== 'ok') {
262
+ if (leitura.estado === 'grande')
263
+ ignorados.grandes += 1;
264
+ else if (leitura.estado === 'link')
265
+ ignorados.links += 1;
266
+ else
267
+ ignorados.outros += 1;
268
+ continue;
269
+ }
270
+ if (arquivos.length >= exports.LIMITE_DE_ARQUIVOS_DO_TRABALHO || bytes + leitura.conteudo.byteLength > exports.LIMITE_TOTAL_DO_TRABALHO) {
271
+ ignorados.excedentes += 1;
272
+ continue;
273
+ }
274
+ arquivos.push({ arquivo: nome, bytes: leitura.conteudo.byteLength,
275
+ sha256: (0, node_crypto_1.createHash)('sha256').update(leitura.conteudo).digest('hex') });
276
+ bytes += leitura.conteudo.byteLength;
277
+ }
278
+ };
279
+ try {
280
+ visitar(base, '', 0);
281
+ return { caminho: caminhoDoTrabalho(threadId), arquivos, ignorados };
282
+ }
283
+ finally {
284
+ fs.closeSync(aberto.fd);
285
+ }
286
+ }
287
+ function formatarResumoDoTrabalho(resumo) {
288
+ const linhas = resumo.arquivos.length
289
+ ? resumo.arquivos.map((a) => ` - \`${a.arquivo.replace(/`/g, '\\`')}\` (${a.bytes} bytes, sha256 \`${a.sha256}\`)`)
290
+ : [' - (nenhum arquivo pequeno)'];
291
+ const totalIgnorado = Object.values(resumo.ignorados).reduce((soma, n) => soma + n, 0);
292
+ if (totalIgnorado > 0) {
293
+ linhas.push(` - Ignorados pelos limites: ${resumo.ignorados.grandes} grandes, ${resumo.ignorados.links} links, ` +
294
+ `${resumo.ignorados.excedentes} excedentes, ${resumo.ignorados.outros} outros.`);
295
+ }
296
+ return linhas.join('\n');
297
+ }