@orkastery/cli 0.5.6 → 0.6.1

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 (396) 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 +123 -9
  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/adapters/grok-events.js +227 -0
  105. package/dist/adapters/grok-mcp-servidor.js +612 -0
  106. package/dist/adapters/grok-mcp.js +178 -0
  107. package/dist/adapters/grok.js +686 -0
  108. package/dist/agendador-cpu.js +92 -0
  109. package/dist/atualizar-branch.js +245 -0
  110. package/dist/auditoria.js +13 -11
  111. package/dist/auditrun.js +51 -46
  112. package/dist/autorizacao-duravel.js +327 -0
  113. package/dist/board.js +94 -40
  114. package/dist/branch-de-estado.js +23 -10
  115. package/dist/busca-semantica.js +7 -5
  116. package/dist/catalogo.js +2 -1
  117. package/dist/changelog-reconciliacao.js +290 -0
  118. package/dist/check-agil.js +528 -0
  119. package/dist/check-modo.js +41 -0
  120. package/dist/check-paralelo.js +238 -0
  121. package/dist/ci.js +248 -45
  122. package/dist/ciclos.js +8 -6
  123. package/dist/claim-lint.js +12 -8
  124. package/dist/claims-conferir.js +47 -39
  125. package/dist/claims.js +10 -9
  126. package/dist/company-brain-client.js +10 -3
  127. package/dist/company-brain-migration.js +11 -5
  128. package/dist/conducao-batida.js +759 -0
  129. package/dist/conducao-sentinela.js +25 -8
  130. package/dist/conducao.js +89 -29
  131. package/dist/conhecimento-consulta.js +270 -0
  132. package/dist/conhecimento.js +111 -87
  133. package/dist/conta-esgotada.js +127 -0
  134. package/dist/dado-privado.js +816 -0
  135. package/dist/decisao-autonoma.js +5 -4
  136. package/dist/demo.js +14 -12
  137. package/dist/dependencias-da-worktree.js +25 -0
  138. package/dist/divida.js +38 -36
  139. package/dist/docs.js +89 -89
  140. package/dist/doctor-forja.js +343 -0
  141. package/dist/doctor-pulse-cron.js +113 -1
  142. package/dist/doctor.js +164 -6
  143. package/dist/dsn-da-memoria.js +417 -0
  144. package/dist/entrega-por-mod.js +503 -0
  145. package/dist/entrega-pr.js +154 -54
  146. package/dist/esgotamentos.js +13 -11
  147. package/dist/estado-thread.js +21 -18
  148. package/dist/evalrunner.js +35 -32
  149. package/dist/fabrica-batida.js +34 -21
  150. package/dist/fabrica-estado.js +33 -21
  151. package/dist/fix.js +21 -19
  152. package/dist/forja/adaptador.js +6 -0
  153. package/dist/forja/ambiente-de-ci.js +27 -0
  154. package/dist/forja/api.js +256 -0
  155. package/dist/forja/cache.js +89 -0
  156. package/dist/forja/cli.js +60 -0
  157. package/dist/forja/contrato.js +9 -0
  158. package/dist/forja/endereco.js +43 -0
  159. package/dist/forja/estado.js +22 -0
  160. package/dist/forja/executor.js +73 -0
  161. package/dist/forja/github/ci.js +95 -0
  162. package/dist/forja/github/dono-da-rede.js +18 -0
  163. package/dist/forja/github/metadados.js +15 -0
  164. package/dist/forja/github/pedidos.js +200 -0
  165. package/dist/forja/gitlab/ci.js +141 -0
  166. package/dist/forja/gitlab/consultas.js +59 -0
  167. package/dist/forja/gitlab/dono-da-rede.js +43 -0
  168. package/dist/forja/gitlab/metadados.js +15 -0
  169. package/dist/forja/gitlab/pedidos-abertos.js +158 -0
  170. package/dist/forja/gitlab/pedidos.js +141 -0
  171. package/dist/forja/produtor.js +32 -0
  172. package/dist/forja/registro.js +31 -0
  173. package/dist/forja/resolver.js +121 -0
  174. package/dist/forja/texto.js +13 -0
  175. package/dist/forja/versao.js +71 -0
  176. package/dist/forja.js +123 -80
  177. package/dist/handoff.js +23 -13
  178. package/dist/hitl-contract.js +46 -43
  179. package/dist/hitl-curto.js +37 -25
  180. package/dist/hitl-gates.js +13 -11
  181. package/dist/hitl-local-receipt.js +51 -0
  182. package/dist/hitl-local.js +11 -2
  183. package/dist/hitl-lock.js +5 -11
  184. package/dist/hitl-public-receipt.js +11 -0
  185. package/dist/hitl-resumo.js +44 -1
  186. package/dist/hitl-sessions.js +62 -9
  187. package/dist/hitl-texto-livre.js +7 -4
  188. package/dist/hitl.js +34 -31
  189. package/dist/horario.js +20 -1
  190. package/dist/hosts.js +104 -134
  191. package/dist/index.js +864 -554
  192. package/dist/indice-vetorial.js +14 -12
  193. package/dist/init.js +11 -2
  194. package/dist/integracoes-locais.js +4 -0
  195. package/dist/intelligence-graph-cli.js +123 -69
  196. package/dist/intelligence-graph-query.js +37 -22
  197. package/dist/leases.js +19 -18
  198. package/dist/ledger-stats.js +17 -16
  199. package/dist/ledger.js +31 -1
  200. package/dist/licoes.js +12 -11
  201. package/dist/locale-accounts.js +228 -0
  202. package/dist/locale-adapter.js +291 -0
  203. package/dist/locale-ajuda.js +86 -10
  204. package/dist/locale-audit.js +199 -0
  205. package/dist/locale-claims.js +213 -0
  206. package/dist/locale-conducao.js +138 -0
  207. package/dist/locale-conhecimento.js +181 -0
  208. package/dist/locale-decisao.js +205 -0
  209. package/dist/locale-docs.js +230 -0
  210. package/dist/locale-estado.js +101 -0
  211. package/dist/locale-forja.js +288 -0
  212. package/dist/locale-gerados.js +5 -0
  213. package/dist/locale-grafo.js +129 -0
  214. package/dist/locale-master.js +83 -0
  215. package/dist/locale-network.js +524 -0
  216. package/dist/locale-operacao-restante.js +931 -0
  217. package/dist/locale-projetos.js +100 -0
  218. package/dist/locale-prompts.js +194 -0
  219. package/dist/locale-pulse.js +140 -2
  220. package/dist/locale-reservas.js +87 -0
  221. package/dist/locale-retry.js +183 -6
  222. package/dist/locale-security-scan.js +69 -0
  223. package/dist/locale-setup.js +192 -0
  224. package/dist/locale-ship.js +177 -66
  225. package/dist/locale-thread.js +149 -5
  226. package/dist/locale-verify.js +80 -4
  227. package/dist/locale-worktree.js +246 -0
  228. package/dist/locale.js +553 -9
  229. package/dist/maestro-runtime.js +22 -3
  230. package/dist/manifest.js +293 -12
  231. package/dist/maquina-ociosa.js +211 -0
  232. package/dist/maquina.js +10 -5
  233. package/dist/master-nota-local.js +200 -0
  234. package/dist/master-nota.js +10 -2
  235. package/dist/master.js +118 -41
  236. package/dist/mcp-conhecimento.js +52 -0
  237. package/dist/mcp-experiencia.js +26 -5
  238. package/dist/mcp-install.js +90 -15
  239. package/dist/mcp-noctum.js +101 -0
  240. package/dist/mcp-server.js +116 -22
  241. package/dist/mcp-ship-transporte.js +977 -0
  242. package/dist/mcp-ship.js +68 -24
  243. package/dist/mcp-transportes.js +17 -0
  244. package/dist/memoria.js +63 -58
  245. package/dist/merge-da-entrega.js +85 -0
  246. package/dist/modos-migracao.js +8 -6
  247. package/dist/modos.js +17 -18
  248. package/dist/network-roadmap.js +94 -54
  249. package/dist/noctum-aceite.js +929 -0
  250. package/dist/noctum-arco.js +540 -33
  251. package/dist/noctum-capacidade.js +3 -3
  252. package/dist/noctum-changelog.js +399 -0
  253. package/dist/noctum-cli.js +539 -0
  254. package/dist/noctum-coordenacao.js +1225 -0
  255. package/dist/noctum-entrega.js +1217 -0
  256. package/dist/noctum-envelope.js +253 -17
  257. package/dist/noctum-execucao.js +100 -24
  258. package/dist/noctum-fechamento.js +416 -0
  259. package/dist/noctum-fila.js +49 -10
  260. package/dist/noctum-guarda.js +333 -0
  261. package/dist/noctum-integracao.js +507 -0
  262. package/dist/noctum-maquinas.js +387 -0
  263. package/dist/noctum-medicao.js +450 -0
  264. package/dist/noctum-modo.js +390 -0
  265. package/dist/noctum-pergunta-canal.js +96 -0
  266. package/dist/noctum-pergunta.js +115 -0
  267. package/dist/noctum-provas.js +838 -0
  268. package/dist/noctum-reconciliacao.js +594 -0
  269. package/dist/noctum-rede.js +102 -0
  270. package/dist/noctum-registro.js +215 -0
  271. package/dist/noctum-relatorio.js +861 -0
  272. package/dist/noctum-resposta.js +207 -0
  273. package/dist/noctum-retomada-rede.js +71 -0
  274. package/dist/noctum-sessoes-em-voo.js +93 -0
  275. package/dist/noctum-supervisao.js +649 -0
  276. package/dist/noctum-terminal.js +459 -0
  277. package/dist/noctum-transporte.js +655 -0
  278. package/dist/noctum-vigia.js +679 -0
  279. package/dist/ocupacao.js +3 -1
  280. package/dist/onboarding.js +16 -5
  281. package/dist/orkmind.js +39 -23
  282. package/dist/orquestracao.js +31 -35
  283. package/dist/parado-no-condutor.js +160 -139
  284. package/dist/phase.js +96 -42
  285. package/dist/policies.js +33 -0
  286. package/dist/postura-local.js +11 -6
  287. package/dist/preflight.js +2 -1
  288. package/dist/procedencia.js +9 -14
  289. package/dist/projeto-alvo.js +59 -20
  290. package/dist/prompts.js +136 -42
  291. package/dist/prova-minima.js +5 -6
  292. package/dist/pulse-cadencia.js +5 -4
  293. package/dist/pulse-consentimento.js +53 -1
  294. package/dist/pulse-delivery.js +143 -27
  295. package/dist/pulse-resposta.js +368 -4
  296. package/dist/pulse.js +136 -3
  297. package/dist/ratelimit.js +13 -4
  298. package/dist/recall.js +14 -13
  299. package/dist/rede-adesao.js +13 -8
  300. package/dist/rede-forja.js +108 -24
  301. package/dist/rede-status.js +63 -45
  302. package/dist/rede.js +86 -46
  303. package/dist/retomada-checkpoint.js +101 -0
  304. package/dist/retry.js +326 -78
  305. package/dist/roadmap-reservas.js +32 -32
  306. package/dist/runtime-ambiente.js +5 -0
  307. package/dist/runtime-context.js +279 -85
  308. package/dist/runtime-escada.js +429 -0
  309. package/dist/runtime-profiles.js +130 -63
  310. package/dist/runtimes.js +42 -5
  311. package/dist/saida-segura.js +3 -2
  312. package/dist/security-scan/agil.js +366 -0
  313. package/dist/security-scan/cli.js +76 -0
  314. package/dist/security-scan/compare.js +149 -0
  315. package/dist/security-scan/config.js +93 -0
  316. package/dist/security-scan/detect.js +97 -0
  317. package/dist/security-scan/executor.js +196 -0
  318. package/dist/security-scan/guard.js +180 -0
  319. package/dist/security-scan/imagem-de-lint.js +96 -0
  320. package/dist/security-scan/normalize/actionlint.js +12 -0
  321. package/dist/security-scan/normalize/eslint.js +12 -0
  322. package/dist/security-scan/normalize/gitleaks.js +13 -0
  323. package/dist/security-scan/normalize/golangci-lint.js +13 -0
  324. package/dist/security-scan/normalize/govulncheck.js +36 -0
  325. package/dist/security-scan/normalize/index.js +25 -0
  326. package/dist/security-scan/normalize/npm-audit.js +30 -0
  327. package/dist/security-scan/normalize/osv-scanner.js +32 -0
  328. package/dist/security-scan/normalize/oxlint.js +51 -0
  329. package/dist/security-scan/normalize/pip-audit.js +16 -0
  330. package/dist/security-scan/normalize/ruff.js +12 -0
  331. package/dist/security-scan/normalize/semgrep.js +20 -0
  332. package/dist/security-scan/normalize/trivy.js +33 -0
  333. package/dist/security-scan/normalize/util.js +204 -0
  334. package/dist/security-scan/normalize/zizmor.js +19 -0
  335. package/dist/security-scan/report.js +156 -0
  336. package/dist/security-scan/run.js +448 -0
  337. package/dist/security-scan/tools.js +62 -0
  338. package/dist/security-scan/trabalhador.js +74 -0
  339. package/dist/security-scan/types.js +15 -0
  340. package/dist/session-events.js +19 -2
  341. package/dist/session-watcher-claude.js +74 -19
  342. package/dist/session-watcher-grok.js +425 -0
  343. package/dist/session-watcher.js +174 -13
  344. package/dist/sessoes-contas.js +42 -5
  345. package/dist/sessoes-inventario.js +1 -1
  346. package/dist/sessoes.js +25 -23
  347. package/dist/setup.js +67 -66
  348. package/dist/ship-publicar.js +263 -92
  349. package/dist/ship.js +160 -17
  350. package/dist/superficie.js +14 -11
  351. package/dist/thread-close.js +9 -9
  352. package/dist/thread.js +121 -18
  353. package/dist/tokens.js +15 -11
  354. package/dist/trabalho-thread.js +297 -0
  355. package/dist/transporte-do-canal.js +189 -0
  356. package/dist/types.js +12 -1
  357. package/dist/util.js +5 -2
  358. package/dist/varredura-acoes.js +500 -0
  359. package/dist/verify.js +491 -32
  360. package/dist/worktree-local.js +12 -10
  361. package/dist/worktree.js +81 -85
  362. package/eval/casos/check-quality.json +77 -0
  363. package/eval/casos/security-auditor.json +148 -0
  364. package/eval/casos/security-remediation.json +161 -0
  365. package/eval/fixtures/security-scan/README.md +8 -0
  366. package/eval/fixtures/security-scan/go/.github/workflows/ci.yml +12 -0
  367. package/eval/fixtures/security-scan/go/Dockerfile +4 -0
  368. package/eval/fixtures/security-scan/go/README.md +4 -0
  369. package/eval/fixtures/security-scan/go/config.go +4 -0
  370. package/eval/fixtures/security-scan/go/go.mod +5 -0
  371. package/eval/fixtures/security-scan/go/go.sum +2 -0
  372. package/eval/fixtures/security-scan/go/main.go +31 -0
  373. package/eval/fixtures/security-scan/js/.github/workflows/ci.yml +12 -0
  374. package/eval/fixtures/security-scan/js/Dockerfile +3 -0
  375. package/eval/fixtures/security-scan/js/README.md +4 -0
  376. package/eval/fixtures/security-scan/js/package-lock.json +844 -0
  377. package/eval/fixtures/security-scan/js/package.json +10 -0
  378. package/eval/fixtures/security-scan/js/src/config.js +4 -0
  379. package/eval/fixtures/security-scan/js/src/server.js +17 -0
  380. package/eval/fixtures/security-scan/js/src/util.ts +4 -0
  381. package/eval/fixtures/security-scan/js/tsconfig.json +4 -0
  382. package/eval/fixtures/security-scan/python/.github/workflows/ci.yml +12 -0
  383. package/eval/fixtures/security-scan/python/Dockerfile +3 -0
  384. package/eval/fixtures/security-scan/python/README.md +4 -0
  385. package/eval/fixtures/security-scan/python/app/__init__.py +0 -0
  386. package/eval/fixtures/security-scan/python/app/config.py +2 -0
  387. package/eval/fixtures/security-scan/python/app/main.py +19 -0
  388. package/eval/fixtures/security-scan/python/requirements.txt +1 -0
  389. package/package.json +10 -5
  390. package/references/security-checklist.md +3 -3
  391. package/skills/README.md +1 -0
  392. package/skills/core/orkastery-bootstrap/SKILL.md +2 -2
  393. package/skills/phases/check-quality/SKILL.md +16 -0
  394. package/skills/phases/go-implementation/SKILL.md +6 -0
  395. package/skills/phases/security-remediation/SKILL.md +70 -0
  396. package/skills/reviewers/security-auditor/SKILL.md +25 -0
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.COLUNAS_DE_PERFIS = exports.POLITICA_PADRAO = exports.ARQUIVO_CONTAS = exports.CONTRATO_CONTAS = exports.ESTADOS_DE_PERFIL = exports.RUNTIMES_COM_PERFIL = exports.VARIAVEL_DO_PERFIL = exports.ARQUIVO_PERFIS = exports.CONTRATO_PERFIS = void 0;
36
+ exports.COLUNAS_DE_PERFIS = exports.POLITICA_PADRAO = exports.ARQUIVO_CONTAS = exports.CONTRATO_CONTAS = exports.ESTADOS_DE_PERFIL = exports.RUNTIMES_COM_INVENTARIO = exports.CAMPO_DO_PERFIL = exports.RUNTIMES_COM_PERFIL = exports.VARIAVEL_DO_PERFIL = exports.ARQUIVO_PERFIS = exports.CONTRATO_PERFIS = void 0;
37
37
  exports.runtimeComPerfil = runtimeComPerfil;
38
38
  exports.validarDiretorioDePerfil = validarDiretorioDePerfil;
39
39
  exports.validarIdDePerfil = validarIdDePerfil;
@@ -54,6 +54,9 @@ exports.prepararDiretorioDoPerfil = prepararDiretorioDoPerfil;
54
54
  exports.adicionarPerfil = adicionarPerfil;
55
55
  exports.desativarPerfil = desativarPerfil;
56
56
  exports.reativarPerfil = reativarPerfil;
57
+ exports.expirarPerfisVencidos = expirarPerfisVencidos;
58
+ exports.classificarTipoDeLimite = classificarTipoDeLimite;
59
+ exports.tipoDeLimiteDoPerfil = tipoDeLimiteDoPerfil;
57
60
  exports.marcarFalhaDePerfil = marcarFalhaDePerfil;
58
61
  exports.registrarConferenciaInconclusiva = registrarConferenciaInconclusiva;
59
62
  exports.registrarUsoDePerfil = registrarUsoDePerfil;
@@ -65,6 +68,7 @@ exports.aplicarContasCompartilhadas = aplicarContasCompartilhadas;
65
68
  exports.lerPerfisComContas = lerPerfisComContas;
66
69
  exports.perfisDoRuntime = perfisDoRuntime;
67
70
  exports.perfilDisponivel = perfilDisponivel;
71
+ exports.perfisDisponiveis = perfisDisponiveis;
68
72
  exports.politicaDeRotacao = politicaDeRotacao;
69
73
  exports.proximoPerfilDisponivel = proximoPerfilDisponivel;
70
74
  exports.proximoPerfilPorCarga = proximoPerfilPorCarga;
@@ -77,7 +81,7 @@ exports.perfisComHorario = perfisComHorario;
77
81
  * I-33 (D3): perfis de conta por runtime, contrato `ork.runtime-profiles/v1`.
78
82
  *
79
83
  * Um perfil aponta o DIRETORIO onde o proprio CLI do runtime guarda configuracao e login
80
- * (`CLAUDE_CONFIG_DIR` no claude-bg, `CODEX_HOME` no codex). O `ork` nunca le, copia nem
84
+ * (`CLAUDE_CONFIG_DIR` no claude-bg, `CODEX_HOME` no codex, `GROK_HOME` no grok). O `ork` nunca le, copia nem
81
85
  * migra o que o CLI grava la dentro: o login e feito pelo proprio CLI com o env do perfil, e
82
86
  * o store guarda so identidade, diretorio e estado de uso. Nenhum segredo entra aqui.
83
87
  *
@@ -93,11 +97,23 @@ const path = __importStar(require("node:path"));
93
97
  const node_crypto_1 = require("node:crypto");
94
98
  const estado_thread_1 = require("./estado-thread");
95
99
  const horario_1 = require("./horario");
100
+ const locale_1 = require("./locale");
96
101
  exports.CONTRATO_PERFIS = 'ork.runtime-profiles/v1';
97
102
  exports.ARQUIVO_PERFIS = 'runtime-profiles.json';
98
103
  /** Runtimes homologados que aceitam perfil, e a variavel que cada um le. */
99
- exports.VARIAVEL_DO_PERFIL = { 'claude-bg': 'CLAUDE_CONFIG_DIR', codex: 'CODEX_HOME' };
104
+ exports.VARIAVEL_DO_PERFIL = { 'claude-bg': 'CLAUDE_CONFIG_DIR', codex: 'CODEX_HOME', grok: 'GROK_HOME' };
100
105
  exports.RUNTIMES_COM_PERFIL = Object.keys(exports.VARIAVEL_DO_PERFIL);
106
+ /** O campo do perfil que guarda o diretorio de cada runtime (o store e o despacho usam o mesmo nome). */
107
+ exports.CAMPO_DO_PERFIL = { 'claude-bg': 'configDir', codex: 'codexHome', grok: 'grokHome' };
108
+ const CAMPOS_DE_DIRETORIO = Object.values(exports.CAMPO_DO_PERFIL);
109
+ /** O diretorio padrao de cada CLI na HOME, quando o processo nao informa a variavel. */
110
+ const PASTA_PADRAO = { 'claude-bg': '.claude', codex: '.codex', grok: '.grok' };
111
+ /**
112
+ * RM-067 (F3, F4): runtimes de assinatura que o #Noctum mede e cuja conta do processo o inventario sempre consulta
113
+ * (`claude agents`, rollouts do codex). Desde a F4, o `ork sessions` e a carga do rodizio leem tambem o `grok`, pela
114
+ * pasta de sessoes que ele grava (`RUNTIMES_DAS_SESSOES` em `sessoes-contas.ts`); a medicao do #Noctum segue sem ele.
115
+ */
116
+ exports.RUNTIMES_COM_INVENTARIO = ['claude-bg', 'codex'];
101
117
  /**
102
118
  * I-33 (D13): `provider-pago` e o perfil cujo proprio CLI diz que o login e por API key,
103
119
  * `api_key_helper`, Console ou provider de nuvem, e nao pela assinatura. Nunca recebe despacho;
@@ -110,7 +126,7 @@ const LIMITE_DETALHE = 200;
110
126
  const uid = () => {
111
127
  const atual = process.getuid?.();
112
128
  if (atual === undefined)
113
- throw new Error('runtime.profiles.invalid: uid do processo indisponivel');
129
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.uidIndisponivel);
114
130
  return atual;
115
131
  };
116
132
  function runtimeComPerfil(nome) {
@@ -120,37 +136,37 @@ function runtimeComPerfil(nome) {
120
136
  function validarDiretorioDePerfil(dir) {
121
137
  if (typeof dir !== 'string' || dir.length === 0 || dir.length > 1024 || /\p{Cc}/u.test(dir) ||
122
138
  !path.isAbsolute(dir) || path.normalize(dir) !== dir || dir === '/' || dir.endsWith('/'))
123
- throw new Error('runtime.profiles.invalid: diretorio do perfil precisa ser caminho absoluto normalizado');
139
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.diretorioNaoNormalizado);
124
140
  return dir;
125
141
  }
126
142
  function validarIdDePerfil(id) {
127
143
  if (typeof id !== 'string' || !ID_DE_PERFIL.test(id))
128
- throw new Error('runtime.profiles.invalid: id do perfil aceita letras, digitos, ponto, hifen e sublinhado (ate 63)');
144
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.idInvalido);
129
145
  return id;
130
146
  }
131
147
  /** Diretorio do perfil, pelo campo do seu runtime. */
132
148
  function diretorioDoPerfil(p) {
133
- const dir = p.runtime === 'claude-bg' ? p.configDir : p.codexHome;
134
- return validarDiretorioDePerfil(dir);
149
+ return validarDiretorioDePerfil(p[exports.CAMPO_DO_PERFIL[p.runtime]]);
150
+ }
151
+ /** O perfil de despacho com o diretorio no campo do seu runtime. */
152
+ function comDiretorio(id, runtime, dir) {
153
+ return { id, runtime, [exports.CAMPO_DO_PERFIL[runtime]]: dir };
135
154
  }
136
155
  /** Valida um perfil de despacho vindo do ledger, do thread.json ou do pedido da fila. */
137
156
  function validarPerfilDeDespacho(v) {
138
157
  if (!v || typeof v !== 'object' || Array.isArray(v))
139
- throw new Error('runtime.profiles.invalid: perfil de despacho ausente');
158
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.despachoAusente);
140
159
  const o = v;
141
160
  const runtime = o.runtime;
142
161
  if (typeof runtime !== 'string' || !runtimeComPerfil(runtime))
143
- throw new Error('runtime.profiles.invalid: runtime do perfil desconhecido');
144
- const campo = runtime === 'claude-bg' ? 'configDir' : 'codexHome';
145
- const outro = runtime === 'claude-bg' ? 'codexHome' : 'configDir';
146
- if (o[outro] !== undefined || Object.keys(o).some(k => !['id', 'runtime', campo].includes(k)))
147
- throw new Error('runtime.profiles.invalid: perfil de despacho com campo inesperado');
148
- const id = validarIdDePerfil(o.id), dir = validarDiretorioDePerfil(o[campo]);
149
- return runtime === 'claude-bg' ? { id, runtime, configDir: dir } : { id, runtime, codexHome: dir };
162
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.runtimeDesconhecido);
163
+ const campo = exports.CAMPO_DO_PERFIL[runtime];
164
+ if (Object.keys(o).some(k => !['id', 'runtime', campo].includes(k)))
165
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.despachoComCampo);
166
+ return comDiretorio(validarIdDePerfil(o.id), runtime, validarDiretorioDePerfil(o[campo]));
150
167
  }
151
168
  function perfilDeDespacho(p) {
152
- return p.runtime === 'claude-bg' ? { id: p.id, runtime: p.runtime, configDir: diretorioDoPerfil(p) }
153
- : { id: p.id, runtime: p.runtime, codexHome: diretorioDoPerfil(p) };
169
+ return comDiretorio(p.id, p.runtime, diretorioDoPerfil(p));
154
170
  }
155
171
  /**
156
172
  * Diretorio implicito de quem despacha sem perfil: o do ambiente informado, ou o padrao do
@@ -158,14 +174,14 @@ function perfilDeDespacho(p) {
158
174
  */
159
175
  function diretorioImplicito(runtime, env = process.env) {
160
176
  const valor = (env[exports.VARIAVEL_DO_PERFIL[runtime]] ?? '').trim();
161
- return valor !== '' ? valor : path.join(os.homedir(), runtime === 'claude-bg' ? '.claude' : '.codex');
177
+ return valor !== '' ? valor : path.join(os.homedir(), PASTA_PADRAO[runtime]);
162
178
  }
163
179
  /** Diretorio efetivo: o do perfil registrado, ou o implicito quando a sessao nao tem perfil. */
164
180
  function diretorioEfetivo(runtime, perfil, env = process.env) {
165
181
  if (!perfil)
166
182
  return diretorioImplicito(runtime, env);
167
183
  if (perfil.runtime !== runtime)
168
- throw new Error('runtime.profiles.invalid: perfil de outro runtime');
184
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.perfilDeOutroRuntime);
169
185
  return diretorioDoPerfil(perfil);
170
186
  }
171
187
  /**
@@ -194,7 +210,7 @@ function perfilDoRegistro(eventos, sessao) {
194
210
  const perfil = validarPerfilDeDespacho(bruto);
195
211
  if (doSensor?.perfil !== undefined && doDespacho?.perfil !== undefined &&
196
212
  JSON.stringify(validarPerfilDeDespacho(doDespacho.perfil)) !== JSON.stringify(perfil))
197
- throw new Error('runtime.profiles.invalid: perfil do sensor diverge do despacho');
213
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.sensorDiverge);
198
214
  return perfil;
199
215
  }
200
216
  // ---------------------------------------------------------------------------
@@ -210,7 +226,7 @@ function validarPasta(pasta) {
210
226
  const st = fs.lstatSync(pasta);
211
227
  if (!st.isDirectory() || st.isSymbolicLink() || st.uid !== uid() || (st.mode & 0o777) !== 0o700 ||
212
228
  fs.realpathSync(pasta) !== pasta)
213
- throw new Error('runtime.profiles.invalid: pasta privada precisa ser 0700 do proprio usuario');
229
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.pastaPrivada);
214
230
  return st;
215
231
  }
216
232
  function garantirPasta(raiz) {
@@ -218,7 +234,7 @@ function garantirPasta(raiz) {
218
234
  const estado = path.dirname(pasta);
219
235
  const stEstado = fs.lstatSync(estado);
220
236
  if (!stEstado.isDirectory() || stEstado.isSymbolicLink() || fs.realpathSync(estado) !== estado)
221
- throw new Error('runtime.profiles.invalid: diretorio de estado invalido');
237
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.diretorioDeEstado);
222
238
  try {
223
239
  fs.mkdirSync(pasta, { mode: 0o700 });
224
240
  fs.chmodSync(pasta, 0o700);
@@ -234,26 +250,26 @@ function data(v, campo) {
234
250
  if (v === null)
235
251
  return null;
236
252
  if (typeof v !== 'string' || !Number.isFinite(Date.parse(v)))
237
- throw new Error(`runtime.profiles.invalid: ${campo} invalido`);
253
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.dataInvalida(campo));
238
254
  return v;
239
255
  }
240
256
  function validarPerfil(v) {
241
257
  if (!v || typeof v !== 'object' || Array.isArray(v))
242
- throw new Error('runtime.profiles.invalid: perfil invalido');
258
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.perfilInvalido);
243
259
  const o = v;
244
260
  const despacho = validarPerfilDeDespacho({ id: o.id, runtime: o.runtime,
245
- ...(o.configDir !== undefined ? { configDir: o.configDir } : {}), ...(o.codexHome !== undefined ? { codexHome: o.codexHome } : {}) });
246
- const permitidos = ['id', 'runtime', 'configDir', 'codexHome', 'estado', 'esgotadoAte', 'ultimaFalha', 'ultimoUso', 'criadoEm'];
261
+ ...Object.fromEntries(CAMPOS_DE_DIRETORIO.filter(c => o[c] !== undefined).map(c => [c, o[c]])) });
262
+ const permitidos = ['id', 'runtime', ...CAMPOS_DE_DIRETORIO, 'estado', 'esgotadoAte', 'ultimaFalha', 'ultimoUso', 'criadoEm'];
247
263
  if (Object.keys(o).some(k => !permitidos.includes(k)))
248
- throw new Error('runtime.profiles.invalid: campo inesperado no perfil');
264
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.campoInesperado);
249
265
  if (!exports.ESTADOS_DE_PERFIL.includes(o.estado))
250
- throw new Error('runtime.profiles.invalid: estado do perfil desconhecido');
266
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.estadoDesconhecido);
251
267
  let ultimaFalha = null;
252
268
  if (o.ultimaFalha !== null) {
253
269
  const f = o.ultimaFalha;
254
270
  if (!f || typeof f !== 'object' || typeof f.motivo !== 'string' || typeof f.detalhe !== 'string' ||
255
271
  f.detalhe.length > LIMITE_DETALHE || Object.keys(f).some(k => !['motivo', 'em', 'detalhe'].includes(k)))
256
- throw new Error('runtime.profiles.invalid: ultimaFalha invalida');
272
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.ultimaFalhaInvalida);
257
273
  ultimaFalha = { motivo: f.motivo, em: data(f.em, 'ultimaFalha.em'), detalhe: f.detalhe };
258
274
  }
259
275
  return { ...despacho, estado: o.estado, esgotadoAte: data(o.esgotadoAte, 'esgotadoAte'),
@@ -262,15 +278,15 @@ function validarPerfil(v) {
262
278
  /** Conteudo validado; ids unicos e diretorio unico por runtime. */
263
279
  function validarStore(v) {
264
280
  if (!v || typeof v !== 'object' || Array.isArray(v))
265
- throw new Error('runtime.profiles.invalid: store invalido');
281
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.storeInvalido);
266
282
  const o = v;
267
283
  if (o.contrato !== exports.CONTRATO_PERFIS || !Array.isArray(o.perfis) || Object.keys(o).sort().join(',') !== 'contrato,perfis')
268
- throw new Error(`runtime.profiles.invalid: contrato ${exports.CONTRATO_PERFIS} esperado`);
284
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.contratoEsperado(exports.CONTRATO_PERFIS));
269
285
  const perfis = o.perfis.map(validarPerfil);
270
286
  if (new Set(perfis.map(p => p.id)).size !== perfis.length)
271
- throw new Error('runtime.profiles.invalid: id de perfil repetido');
287
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.idRepetido);
272
288
  if (new Set(perfis.map(p => `${p.runtime}|${diretorioDoPerfil(p)}`)).size !== perfis.length)
273
- throw new Error('runtime.profiles.invalid: dois perfis do mesmo runtime no mesmo diretorio');
289
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.mesmoDiretorio);
274
290
  return { contrato: exports.CONTRATO_PERFIS, perfis };
275
291
  }
276
292
  /** Le o store. Sem pasta privada ou sem arquivo: store vazio (nenhum perfil configurado). */
@@ -292,19 +308,19 @@ function lerPerfis(raiz) {
292
308
  catch (e) {
293
309
  if (e.code === 'ENOENT')
294
310
  return storeVazio();
295
- throw new Error('runtime.profiles.invalid: arquivo de perfis ilegivel ou link simbolico');
311
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.arquivoIlegivel);
296
312
  }
297
313
  try {
298
314
  const st = fs.fstatSync(fd), atual = fs.lstatSync(pasta);
299
315
  if (!st.isFile() || st.nlink !== 1 || st.uid !== uid() || (st.mode & 0o777) !== 0o600 || st.size > LIMITE_STORE_BYTES ||
300
316
  atual.dev !== pastaSt.dev || atual.ino !== pastaSt.ino)
301
- throw new Error('runtime.profiles.invalid: arquivo de perfis precisa ser 0600 do proprio usuario');
317
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.arquivoSemPermissao);
302
318
  let bruto;
303
319
  try {
304
320
  bruto = JSON.parse(fs.readFileSync(fd, 'utf8'));
305
321
  }
306
322
  catch {
307
- throw new Error('runtime.profiles.invalid: arquivo de perfis com JSON invalido');
323
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.arquivoJson);
308
324
  }
309
325
  return validarStore(bruto);
310
326
  }
@@ -331,7 +347,7 @@ function gravarArquivoPrivado(pasta, pastaSt, arquivo, conteudo) {
331
347
  const atual = fs.lstatSync(pasta);
332
348
  if (atual.dev !== pastaSt.dev || atual.ino !== pastaSt.ino) {
333
349
  fs.rmSync(temp, { force: true });
334
- throw new Error('runtime.profiles.invalid: pasta privada trocada durante a gravacao');
350
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.pastaTrocada);
335
351
  }
336
352
  fs.renameSync(temp, path.join(pasta, arquivo));
337
353
  const dfd = fs.openSync(pasta, fs.constants.O_RDONLY | fs.constants.O_DIRECTORY);
@@ -429,7 +445,7 @@ function comLockDoStore(pasta, executar, arquivo = exports.ARQUIVO_PERFIS) {
429
445
  continue;
430
446
  }
431
447
  if (Date.now() >= prazo)
432
- throw new Error('runtime.profiles.busy: store de perfis ocupado; tente novamente');
448
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.storeOcupado);
433
449
  Atomics.wait(pausa, 0, 0, 2 + Math.floor(Math.random() * 18));
434
450
  }
435
451
  try {
@@ -470,7 +486,7 @@ function atualizarPerfis(raiz, mutar) {
470
486
  function exigirPerfil(store, id) {
471
487
  const p = store.perfis.find(x => x.id === id);
472
488
  if (!p)
473
- throw new Error(`runtime.profiles.unknown: perfil "${id}" nao existe (veja: ork accounts list)`);
489
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.perfilNaoExiste(id));
474
490
  return p;
475
491
  }
476
492
  /**
@@ -507,33 +523,34 @@ function prepararDiretorioDoPerfil(dir) {
507
523
  fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
508
524
  }
509
525
  catch (e) {
510
- throw new Error(`runtime.profiles.invalid: diretorio do perfil inacessivel (${e.code ?? 'erro'})`);
526
+ const codigo = e.code ?? 'erro';
527
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.diretorioInacessivel(codigo));
511
528
  }
512
529
  let st;
513
530
  try {
514
531
  st = fs.statSync(dir);
515
532
  }
516
533
  catch (e) {
517
- throw new Error(`runtime.profiles.invalid: diretorio do perfil inacessivel (${e.code ?? 'erro'})`);
534
+ const codigo = e.code ?? 'erro';
535
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.diretorioInacessivel(codigo));
518
536
  }
519
537
  if (!st.isDirectory())
520
- throw new Error('runtime.profiles.invalid: o caminho do perfil nao e diretorio');
538
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.naoEDiretorio);
521
539
  if (st.uid !== uid())
522
- throw new Error('runtime.profiles.invalid: diretorio do perfil pertence a outro usuario');
540
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.outroUsuario);
523
541
  try {
524
542
  fs.accessSync(dir, fs.constants.R_OK | fs.constants.W_OK | fs.constants.X_OK);
525
543
  }
526
544
  catch {
527
- throw new Error('runtime.profiles.invalid: diretorio do perfil sem leitura e escrita para este usuario');
545
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.semLeituraEscrita);
528
546
  }
529
547
  }
530
548
  function adicionarPerfil(raiz, novo, agoraIso = new Date().toISOString()) {
531
549
  if (!runtimeComPerfil(novo.runtime))
532
- throw new Error(`runtime.profiles.invalid: runtime "${novo.runtime}" nao aceita perfil`);
550
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.runtimeSemPerfil(novo.runtime));
533
551
  const runtime = novo.runtime;
534
552
  const dir = validarDiretorioDePerfil(novo.dir);
535
- const perfil = { id: validarIdDePerfil(novo.id), runtime,
536
- ...(runtime === 'claude-bg' ? { configDir: dir } : { codexHome: dir }),
553
+ const perfil = { ...comDiretorio(validarIdDePerfil(novo.id), runtime, dir),
537
554
  estado: 'ativo', esgotadoAte: null, ultimaFalha: null, ultimoUso: null, criadoEm: agoraIso };
538
555
  return atualizarPerfis(raiz, store => {
539
556
  const existente = store.perfis.find(p => p.id === perfil.id);
@@ -544,16 +561,16 @@ function adicionarPerfil(raiz, novo, agoraIso = new Date().toISOString()) {
544
561
  existente.esgotadoAte = null;
545
562
  return { ...existente };
546
563
  }
547
- throw new Error(`runtime.profiles.invalid: perfil "${perfil.id}" ja existe` +
548
- (existente.estado === 'desativado' ? ` (desativado em ${diretorioDoPerfil(existente)}; reative com o mesmo --runtime e --dir)` : ''));
564
+ const desativadoEm = existente.estado === 'desativado' ? diretorioDoPerfil(existente) : null;
565
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.jaExiste(perfil.id, desativadoEm));
549
566
  }
550
567
  if (store.perfis.some(p => p.runtime === runtime && diretorioDoPerfil(p) === dir))
551
- throw new Error(`runtime.profiles.invalid: ja ha perfil ${runtime} em ${dir}`);
568
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.jaHaPerfil(runtime, dir));
552
569
  // A7: o mesmo diretorio por outro caminho (link simbolico) e a mesma conta, nao outro perfil.
553
570
  const real = caminhoRealDoPerfil(dir);
554
571
  const mesmo = store.perfis.find(p => p.runtime === runtime && caminhoRealDoPerfil(diretorioDoPerfil(p)) === real);
555
572
  if (mesmo)
556
- throw new Error(`runtime.profiles.invalid: ${dir} e o mesmo diretorio do perfil "${mesmo.id}" (${real})`);
573
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.mesmoDiretorioDoPerfil(dir, mesmo.id, real));
557
574
  store.perfis.push(perfil);
558
575
  return perfil;
559
576
  });
@@ -571,7 +588,7 @@ function reativarPerfil(raiz, id) {
571
588
  const p = atualizarPerfis(raiz, store => {
572
589
  const p = exigirPerfil(store, id);
573
590
  if (p.estado === 'desativado')
574
- throw new Error(`runtime.profiles.invalid: perfil "${id}" esta desativado`);
591
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.estaDesativado(id));
575
592
  p.estado = 'ativo';
576
593
  p.esgotadoAte = null;
577
594
  return { ...p };
@@ -580,13 +597,56 @@ function reativarPerfil(raiz, id) {
580
597
  publicarEstadoDaConta(p, (0, estado_thread_1.raizDoEstado)(raiz));
581
598
  return p;
582
599
  }
600
+ /** RM-064 T7: `accounts check` materializa a disponibilidade que antes existia só na leitura pura. */
601
+ function expirarPerfisVencidos(raiz, agoraMs = Date.now()) {
602
+ const temVencido = lerPerfis(raiz).perfis.some(p => p.estado === 'esgotado' && p.esgotadoAte !== null &&
603
+ Date.parse(p.esgotadoAte) <= agoraMs);
604
+ if (!temVencido)
605
+ return [];
606
+ const expirados = atualizarPerfis(raiz, store => {
607
+ const saida = [];
608
+ for (const p of store.perfis) {
609
+ if (p.estado !== 'esgotado' || p.esgotadoAte === null || Date.parse(p.esgotadoAte) > agoraMs)
610
+ continue;
611
+ p.estado = 'ativo';
612
+ p.esgotadoAte = null;
613
+ saida.push({ ...p });
614
+ }
615
+ return saida;
616
+ });
617
+ for (const p of expirados)
618
+ publicarEstadoDaConta(p, (0, estado_thread_1.raizDoEstado)(raiz), agoraMs);
619
+ return expirados;
620
+ }
621
+ /**
622
+ * Classificação conservadora da evidência curta guardada; texto desconhecido continua desconhecido. O limite de gasto
623
+ * dito por extenso vence o semanal: a fala real "individual spend limit ... your weekly limit resets" é de gasto, e
624
+ * a semana ali é só o prazo de volta.
625
+ */
626
+ function classificarTipoDeLimite(detalhe) {
627
+ const texto = detalhe ?? '';
628
+ if (!texto)
629
+ return 'nenhum';
630
+ if (/spend(?:ing)?\s+(?:cap|limit)|limite\s+de\s+gasto/iu.test(texto))
631
+ return 'gasto-admin';
632
+ if (/weekly|semana(?:l)?/iu.test(texto))
633
+ return 'semanal';
634
+ if (/admin(?:istrator|istrador)?/iu.test(texto))
635
+ return 'gasto-admin';
636
+ if (/session|sess[aã]o|\b\d+(?:[.,]\d+)?\s*(?:hours?|horas?|h)\b/iu.test(texto))
637
+ return 'sessao';
638
+ return 'outro';
639
+ }
640
+ function tipoDeLimiteDoPerfil(p) {
641
+ return p.ultimaFalha?.motivo === 'runtime.quota-exhausted' ? classificarTipoDeLimite(p.ultimaFalha.detalhe) : 'nenhum';
642
+ }
583
643
  /**
584
644
  * D5: marca a falha de conta. Cota esgotada sai do rodizio ate `esgotadoAte`; auth ausente
585
645
  * sai sem prazo, ate o login ser refeito e conferido.
586
646
  */
587
647
  function marcarFalhaDePerfil(raiz, id, falha) {
588
648
  if (falha.estado === 'esgotado' && (falha.esgotadoAte === null || !Number.isFinite(Date.parse(falha.esgotadoAte))))
589
- throw new Error('runtime.profiles.invalid: cota esgotada exige esgotadoAte');
649
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.cotaExigePrazo);
590
650
  const marcado = atualizarPerfis(raiz, store => {
591
651
  const p = exigirPerfil(store, id);
592
652
  if (p.estado !== 'desativado')
@@ -609,7 +669,7 @@ const detalheCurto = (detalhe) => Array.from(detalhe.replace(/\p{Cc}/gu, ' ')).s
609
669
  function registrarConferenciaInconclusiva(raiz, id, detalhe, em = new Date().toISOString()) {
610
670
  return atualizarPerfis(raiz, store => {
611
671
  const p = exigirPerfil(store, id);
612
- p.ultimaFalha = { motivo: 'runtime.unavailable', em, detalhe: detalheCurto(`conferencia de login inconclusiva: ${detalhe}`) };
672
+ p.ultimaFalha = { motivo: 'runtime.unavailable', em, detalhe: detalheCurto((0, locale_1.msg)('pt-BR').accounts.inconclusiva(detalhe)) };
613
673
  return { ...p };
614
674
  });
615
675
  }
@@ -674,12 +734,12 @@ function chaveDaConta(p) {
674
734
  function validarRegistroDeContas(v) {
675
735
  if (!v || typeof v !== 'object' || v.contrato !== exports.CONTRATO_CONTAS ||
676
736
  !Array.isArray(v.contas))
677
- throw new Error('runtime.profiles.invalid: registro de contas invalido');
737
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.registroInvalido);
678
738
  const contas = v.contas.map((c) => {
679
739
  const o = c;
680
740
  if (!o || typeof o.chave !== 'string' || !ESTADOS_COMPARTILHADOS.includes(String(o.estado)) ||
681
741
  typeof o.motivo !== 'string' || typeof o.detalhe !== 'string' || typeof o.projeto !== 'string' || typeof o.em !== 'string')
682
- throw new Error('runtime.profiles.invalid: conta compartilhada invalida');
742
+ throw new locale_1.ErroDoCatalogo((m) => m.accounts.contaInvalida);
683
743
  return { chave: o.chave, estado: o.estado, esgotadoAte: data(o.esgotadoAte ?? null, 'esgotadoAte'),
684
744
  motivo: o.motivo, detalhe: detalheCurto(o.detalhe), em: data(o.em, 'em'), projeto: o.projeto };
685
745
  });
@@ -760,7 +820,7 @@ function aplicarContasCompartilhadas(store, contas, agoraMs = Date.now()) {
760
820
  }
761
821
  if (!c)
762
822
  return p;
763
- const falha = { motivo: c.motivo, em: c.em, detalhe: detalheCurto(`visto em outro projeto: ${c.detalhe}`) };
823
+ const falha = { motivo: c.motivo, em: c.em, detalhe: detalheCurto((0, locale_1.msg)('pt-BR').accounts.vistoEmOutroProjeto(c.detalhe)) };
764
824
  if (c.estado === 'esgotado') {
765
825
  const ate = c.esgotadoAte === null ? NaN : Date.parse(c.esgotadoAte);
766
826
  if (!(ate > agoraMs))
@@ -790,6 +850,10 @@ function perfilDisponivel(p, agoraMs = Date.now()) {
790
850
  return true;
791
851
  return p.estado === 'esgotado' && p.esgotadoAte !== null && Date.parse(p.esgotadoAte) <= agoraMs;
792
852
  }
853
+ /** Única lista de candidatos automáticos: estado configurado continua existindo, mas nunca vira destino. */
854
+ function perfisDisponiveis(store, runtime, agoraMs = Date.now()) {
855
+ return perfisDoRuntime(store, runtime).filter((p) => perfilDisponivel(p, agoraMs));
856
+ }
793
857
  /** Defaults da D16: por cota ligada (decisao do dono em 19/09/2026) e por login perdido ligada. */
794
858
  exports.POLITICA_PADRAO = { mesmoRuntimePorCota: true, mesmoRuntimePorAuth: true };
795
859
  function politicaDeRotacao(manifesto) {
@@ -833,9 +897,9 @@ function proximoPerfilPorCarga(store, runtime, politica, carga, opcoes = {}) {
833
897
  if (!daVez)
834
898
  return null;
835
899
  const agoraMs = opcoes.agoraMs ?? Date.now();
836
- const candidatos = perfisDoRuntime(store, runtime)
900
+ const candidatos = perfisDisponiveis(store, runtime, agoraMs)
837
901
  .map((p, i) => ({ p, i }))
838
- .filter(({ p }) => !(opcoes.excluir ?? []).includes(p.id) && perfilDisponivel(p, agoraMs));
902
+ .filter(({ p }) => !(opcoes.excluir ?? []).includes(p.id));
839
903
  const uso = (p) => p.ultimoUso === null ? -Infinity : Date.parse(p.ultimoUso);
840
904
  candidatos.sort((x, y) => (carga.get(x.p.id) ?? 0) - (carga.get(y.p.id) ?? 0) || uso(x.p) - uso(y.p) || x.i - y.i);
841
905
  return candidatos[0]?.p ?? daVez;
@@ -879,12 +943,15 @@ function menorEsgotadoAte(store, runtimes, agoraMs = Date.now()) {
879
943
  * vez, pela `legendaDoFuso()`, quando `perfisComHorario` acusa alguma coluna preenchida.
880
944
  */
881
945
  function linhasDePerfis(store) {
882
- return store.perfis.map(p => [p.id, p.runtime, diretorioDoPerfil(p), p.estado,
946
+ // RM-061 (F3b): o estado (dado do store e do `--json`) so se traduz aqui, pelo id; o motivo tipado sai igual.
947
+ const m = (0, locale_1.msg)().accounts;
948
+ return store.perfis.map(p => [p.id, p.runtime, diretorioDoPerfil(p), m.estado(p.estado),
883
949
  p.esgotadoAte ? (0, horario_1.formatarDataHora)(p.esgotadoAte) : '-', p.ultimoUso ? (0, horario_1.formatarDataHora)(p.ultimoUso) : '-',
884
- p.ultimaFalha ? `${p.ultimaFalha.motivo} em ${(0, horario_1.formatarDataHora)(p.ultimaFalha.em)}` : '-']);
950
+ p.ultimaFalha ? m.falhaEm(p.ultimaFalha.motivo, (0, horario_1.formatarDataHora)(p.ultimaFalha.em)) : '-']);
885
951
  }
886
952
  /** True quando a tabela mostra algum horario, e a mensagem precisa dizer o fuso uma vez. */
887
953
  function perfisComHorario(store) {
888
954
  return store.perfis.some(p => p.esgotadoAte !== null || p.ultimoUso !== null || p.ultimaFalha !== null);
889
955
  }
890
- exports.COLUNAS_DE_PERFIS = ['PERFIL', 'RUNTIME', 'DIRETORIO', 'ESTADO', 'ESGOTADO ATE', 'ULTIMO USO', 'ULTIMA FALHA'];
956
+ /** As colunas da tabela em pt-BR; o CLI usa as do catalogo, no locale do comando (`msg().accounts.colunas`). */
957
+ exports.COLUNAS_DE_PERFIS = [...(0, locale_1.msg)('pt-BR').accounts.colunas];
package/dist/runtimes.js CHANGED
@@ -10,6 +10,10 @@
10
10
  * `claude agents --json` (homologado em 02/09/2026).
11
11
  * codex o segundo runtime: `codex exec` headless desanexado, sessao verificada no
12
12
  * rollout que o proprio Codex grava (homologado em 06/09/2026).
13
+ * grok RM-067 (F1 e F2): o Grok Build headless, `grok -p` com `streaming-json`, sessao
14
+ * verificada na pasta que o proprio runtime grava. Desde a F4, runtime de bloco e de
15
+ * fallback no `ork setup`, sempre com o modelo dado pelo dono; nunca o padrao do projeto
16
+ * (`runtime.adapter`), que segue com o claude-bg e o codex.
13
17
  *
14
18
  * Paridade sem downgrade: o contrato do claude-bg nao muda com a chegada do codex, e todo
15
19
  * runtime novo entra por aqui com o MESMO contrato de despacho (dry-run, rate limit
@@ -49,11 +53,14 @@ var __importStar = (this && this.__importStar) || (function () {
49
53
  };
50
54
  })();
51
55
  Object.defineProperty(exports, "__esModule", { value: true });
52
- exports.ORDEM_DOS_RUNTIMES = exports.RUNTIMES = exports.RUNTIME_PADRAO = void 0;
56
+ exports.RUNTIMES_SEM_COTA_TIPADA = exports.RUNTIMES_DE_BLOCO = exports.ORDEM_DOS_RUNTIMES = exports.RUNTIMES = exports.RUNTIME_PADRAO = void 0;
53
57
  exports.runtimeConhecido = runtimeConhecido;
58
+ exports.runtimeDeBloco = runtimeDeBloco;
59
+ exports.runtimeDoManifesto = runtimeDoManifesto;
54
60
  exports.resolverRuntime = resolverRuntime;
55
61
  const claudeBg = __importStar(require("./adapters/claude-bg"));
56
62
  const codex = __importStar(require("./adapters/codex"));
63
+ const grok = __importStar(require("./adapters/grok"));
57
64
  const hitl_ingress_receipt_1 = require("./hitl-ingress-receipt");
58
65
  const locale_1 = require("./locale");
59
66
  exports.RUNTIME_PADRAO = 'claude-bg';
@@ -87,18 +94,48 @@ exports.RUNTIMES = {
87
94
  montarComando: (p) => codex.montarComando(p),
88
95
  despachar: (p) => comRecibosPublicos(p, codex.despachar),
89
96
  },
97
+ grok: {
98
+ nome: grok.NOME_ADAPTER,
99
+ fonteVerificacao: grok.FONTE_VERIFICACAO,
100
+ disponivel: () => grok.disponivel(),
101
+ versao: grok.versao,
102
+ montarComando: (p) => grok.montarComando(p),
103
+ despachar: (p) => comRecibosPublicos(p, grok.despachar),
104
+ },
90
105
  };
91
- /** Os runtimes na ordem de maturidade (o padrao primeiro). */
106
+ /**
107
+ * Os runtimes que podem ser o padrao do projeto (`runtime.adapter` do manifesto), na ordem de maturidade (o padrao
108
+ * primeiro). RM-067 (F4): o grok fica fora, porque fazer dele o runtime padrao esta fora do escopo da RM-067 e ele nao tem
109
+ * modelo padrao.
110
+ */
92
111
  exports.ORDEM_DOS_RUNTIMES = ['claude-bg', 'codex'];
93
- /** O nome e de um runtime homologado? */
112
+ /**
113
+ * Os runtimes que o setup aceita como runtime ou fallback de bloco. RM-067 (F4): os do padrao e o grok, este sempre com o
114
+ * modelo dado pelo dono (o setup exige `--model` ao trocar o runtime, e a entrada de fallback e `runtime:modelo[:esforco]`).
115
+ */
116
+ exports.RUNTIMES_DE_BLOCO = [...exports.ORDEM_DOS_RUNTIMES, 'grok'];
117
+ /**
118
+ * RM-067 (F3): runtimes cuja cota esgotada ainda nao vem tipada do proprio runtime. A escada automatica nunca troca a conta
119
+ * deles: sem o sinal tipado, nada prova que o perfil esgotou. O grok sai daqui quando a F5 ler o formato estruturado.
120
+ */
121
+ exports.RUNTIMES_SEM_COTA_TIPADA = ['grok'];
122
+ /** O nome e de um runtime homologado (resolve por nome no despacho)? */
94
123
  function runtimeConhecido(nome) {
95
124
  return Object.prototype.hasOwnProperty.call(exports.RUNTIMES, nome);
96
125
  }
126
+ /** O runtime pode ser runtime de bloco ou fallback no setup? */
127
+ function runtimeDeBloco(nome) {
128
+ return exports.RUNTIMES_DE_BLOCO.includes(nome);
129
+ }
130
+ /** O runtime pode ser o `runtime.adapter` do manifesto? */
131
+ function runtimeDoManifesto(nome) {
132
+ return exports.ORDEM_DOS_RUNTIMES.includes(nome);
133
+ }
97
134
  /** Resolve o adapter pelo nome, com erro tipado quando o runtime nao existe. */
98
135
  function resolverRuntime(nome) {
99
- const adapter = exports.RUNTIMES[nome];
136
+ const adapter = runtimeConhecido(nome) ? exports.RUNTIMES[nome] : undefined;
100
137
  if (!adapter) {
101
- throw new locale_1.ErroDoCatalogo((m) => m.phase.runtimeDesconhecido(nome, exports.ORDEM_DOS_RUNTIMES.join(', ')));
138
+ throw new locale_1.ErroDoCatalogo((m) => m.phase.runtimeDesconhecido(nome, exports.RUNTIMES_DE_BLOCO.join(', ')));
102
139
  }
103
140
  return adapter;
104
141
  }
@@ -51,8 +51,9 @@ function valoresEmUmaLinha(valor) {
51
51
  /**
52
52
  * O JSON para a tela: o mesmo valor, com os caracteres invisiveis escritos como `\uXXXX` (quem le o
53
53
  * JSON recebe o mesmo texto; so o terminal deixa de executa-lo). A quebra de linha da indentacao fica.
54
+ * Com `indentacao` 0, o JSON sai compacto (a resposta de uma tool MCP, RM-026 K7).
54
55
  */
55
- function jsonSemInvisivel(valor) {
56
- return JSON.stringify(valor, null, 2).replace(INVISIVEIS, (c) => c === '\n' ? c
56
+ function jsonSemInvisivel(valor, indentacao = 2) {
57
+ return JSON.stringify(valor, null, indentacao).replace(INVISIVEIS, (c) => c === '\n' ? c
57
58
  : Array.from({ length: c.length }, (_, i) => `\\u${c.charCodeAt(i).toString(16).padStart(4, '0')}`).join(''));
58
59
  }