@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
@@ -0,0 +1,183 @@
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.argvDoItem = argvDoItem;
37
+ exports.esperaDoGrupo = esperaDoGrupo;
38
+ exports.rodarEmParalelo = rodarEmParalelo;
39
+ /**
40
+ * RM-072 (D6 da ork-check5x): o grupo paralelo do Agile Check sem mudar a assinatura do `verificar`.
41
+ *
42
+ * O `verificar` e sincrono e tem varios chamadores (CLI, MCP, ship, fix, retry, ci, noctum). Para rodar as lanes de teste
43
+ * e a varredura ao mesmo tempo, o verify chama este modulo com `spawnSync` como processo auxiliar: ele lanca cada
44
+ * comando ao mesmo tempo, cada um com o mesmo `timeout(1)` do `executar` (o estouro leva o grupo de processos inteiro),
45
+ * grava a saida de cada um num arquivo e espera todos. O pai le os arquivos e monta cada resultado pela mesma funcao do
46
+ * `executar`. O ambiente vem do pai, ja sem `ORK_HITL_*`; cada item so acrescenta variaveis sem segredo (o modo, o
47
+ * relatorio do CHECK, o prazo interno do scan). O item que nomeia outros em `apos` so comeca quando eles terminam (a lane
48
+ * de integracao depois da varredura), e `maxParalelo` limita quantos rodam ao mesmo tempo.
49
+ */
50
+ const node_child_process_1 = require("node:child_process");
51
+ const fs = __importStar(require("node:fs"));
52
+ const os = __importStar(require("node:os"));
53
+ const path = __importStar(require("node:path"));
54
+ const TIMEOUT_BIN = '/usr/bin/timeout';
55
+ const NICE_BIN = '/usr/bin/nice';
56
+ /** O argv de um item: `nice` (se pedido e existir), `timeout(1)` (se existir) e `bash -c`. */
57
+ function argvDoItem(item, comGrupo = fs.existsSync(TIMEOUT_BIN), comNice = fs.existsSync(NICE_BIN)) {
58
+ const base = comGrupo
59
+ ? [TIMEOUT_BIN, '--kill-after=15', `${Math.ceil(item.prazoMs / 1000)}`, 'bash', '-c', item.comando]
60
+ : ['bash', '-c', item.comando];
61
+ return item.nice && comNice ? [NICE_BIN, '-n', String(item.nice), ...base] : base;
62
+ }
63
+ /** As vagas do grupo: no maximo `max` comandos ao mesmo tempo, na ordem em que pediram. */
64
+ function vagas(max) {
65
+ let livres = max;
66
+ const fila = [];
67
+ return {
68
+ tomar: () => new Promise((pronto) => { if (livres > 0) {
69
+ livres--;
70
+ pronto();
71
+ }
72
+ else
73
+ fila.push(pronto); }),
74
+ soltar: () => { const proximo = fila.shift(); if (proximo)
75
+ proximo();
76
+ else
77
+ livres++; },
78
+ };
79
+ }
80
+ /**
81
+ * O lado do auxiliar: lanca cada item quando os de `apos` terminam e ha vaga, espera todos e grava `resultado.json` ao
82
+ * lado das saidas.
83
+ */
84
+ async function rodarEspecificacao(esp) {
85
+ const comGrupo = fs.existsSync(TIMEOUT_BIN);
86
+ const limite = vagas(esp.maxParalelo && esp.maxParalelo > 0 ? esp.maxParalelo : esp.itens.length);
87
+ const porNome = new Map();
88
+ const terminados = await Promise.all(esp.itens.map((item, i) => {
89
+ const vez = (async () => {
90
+ for (const nome of item.apos ?? [])
91
+ await porNome.get(nome);
92
+ await limite.tomar();
93
+ try {
94
+ return await lancar(item, i);
95
+ }
96
+ finally {
97
+ limite.soltar();
98
+ }
99
+ })();
100
+ porNome.set(item.nome, vez);
101
+ return vez;
102
+ }));
103
+ fs.writeFileSync(path.join(esp.dir, 'resultado.json'), JSON.stringify(terminados), { mode: 0o600 });
104
+ function lancar(item, i) {
105
+ return new Promise((resolve) => {
106
+ const saida = fs.openSync(path.join(esp.dir, `${i}.out`), 'w', 0o600);
107
+ const erro = fs.openSync(path.join(esp.dir, `${i}.err`), 'w', 0o600);
108
+ const inicio = Date.now();
109
+ const [bin, ...args] = argvDoItem(item, comGrupo);
110
+ let fim = null;
111
+ const encerrar = (t) => {
112
+ if (fim)
113
+ return;
114
+ fim = t;
115
+ fs.closeSync(saida);
116
+ fs.closeSync(erro);
117
+ resolve(t);
118
+ };
119
+ // Sem o `timeout(1)`, o proprio auxiliar mata pelo prazo, como o `spawnSync` do `exec` faria.
120
+ const filho = (0, node_child_process_1.spawn)(bin, args, { cwd: item.cwd, env: { ...process.env, ...item.ambiente }, stdio: ['ignore', saida, erro],
121
+ ...(comGrupo ? {} : { timeout: item.prazoMs, killSignal: 'SIGTERM' }) });
122
+ filho.on('error', (e) => encerrar({ nome: item.nome, code: null, signal: null,
123
+ error: e.code ?? e.message, duracaoMs: Date.now() - inicio, comGrupo }));
124
+ filho.on('close', (code, signal) => encerrar({ nome: item.nome, code, signal,
125
+ ...(!comGrupo && signal && Date.now() - inicio >= item.prazoMs ? { error: 'ETIMEDOUT' } : {}),
126
+ duracaoMs: Date.now() - inicio, comGrupo }));
127
+ });
128
+ }
129
+ }
130
+ /**
131
+ * A espera do grupo inteiro: o maior prazo, ou a soma deles quando ha fila (item com `apos` ou vagas a menos que itens),
132
+ * que e o teto do pior caso.
133
+ */
134
+ function esperaDoGrupo(itens, maxParalelo) {
135
+ const comFila = itens.some((i) => i.apos?.length) || (!!maxParalelo && maxParalelo < itens.length);
136
+ return comFila ? itens.reduce((t, i) => t + i.prazoMs, 0) : Math.max(...itens.map((i) => i.prazoMs));
137
+ }
138
+ /**
139
+ * O lado do pai: roda o grupo pelo auxiliar e devolve cada processo, na ordem dos itens. A espera e a do grupo
140
+ * (`esperaDoGrupo`), com folga para o `--kill-after` e para o auxiliar gravar; o diretorio das saidas some no fim.
141
+ */
142
+ function rodarEmParalelo(itens, ambiente = process.env, opcoes = {}) {
143
+ if (itens.length === 0)
144
+ return [];
145
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'ork-check-paralelo-'));
146
+ try {
147
+ const especificacao = path.join(dir, 'especificacao.json');
148
+ const esp = { itens, dir, ...(opcoes.maxParalelo ? { maxParalelo: opcoes.maxParalelo } : {}) };
149
+ fs.writeFileSync(especificacao, JSON.stringify(esp), { mode: 0o600 });
150
+ const prazo = esperaDoGrupo(itens, opcoes.maxParalelo) + 60_000;
151
+ const r = (0, node_child_process_1.spawnSync)(process.execPath, [__filename, especificacao], { env: ambiente, encoding: 'utf8', timeout: prazo,
152
+ killSignal: 'SIGKILL' });
153
+ let terminados = [];
154
+ try {
155
+ terminados = JSON.parse(fs.readFileSync(path.join(dir, 'resultado.json'), 'utf8'));
156
+ }
157
+ catch { /* abaixo */ }
158
+ return itens.map((item, i) => {
159
+ const t = terminados[i];
160
+ const ler = (sufixo) => { try {
161
+ return fs.readFileSync(path.join(dir, `${i}.${sufixo}`), 'utf8');
162
+ }
163
+ catch {
164
+ return '';
165
+ } };
166
+ if (!t) {
167
+ // O auxiliar morreu antes de gravar: o comando nao tem veredito, e a causa vai junto.
168
+ const motivo = r.error ? r.error.code ?? r.error.message : `auxiliar saiu ${r.status ?? r.signal}`;
169
+ return { nome: item.nome, ok: false, code: -1, signal: r.signal ?? null, error: motivo, stdout: ler('out'),
170
+ stderr: `${ler('err')}${r.stderr ?? ''}`, duracaoMs: 0, comGrupo: fs.existsSync(TIMEOUT_BIN), semResultado: true };
171
+ }
172
+ return { nome: item.nome, ok: t.code === 0, code: t.code ?? -1, signal: t.signal, ...(t.error ? { error: t.error } : {}),
173
+ stdout: ler('out'), stderr: ler('err'), duracaoMs: t.duracaoMs, comGrupo: t.comGrupo };
174
+ });
175
+ }
176
+ finally {
177
+ fs.rmSync(dir, { recursive: true, force: true });
178
+ }
179
+ }
180
+ if (require.main === module) {
181
+ const esp = JSON.parse(fs.readFileSync(process.argv[2], 'utf8'));
182
+ rodarEspecificacao(esp).then(() => process.exit(0), (e) => { process.stderr.write(`check-paralelo: ${e.message}\n`); process.exit(1); });
183
+ }
package/dist/ci.js CHANGED
@@ -36,8 +36,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.BUNDLE_LEGADO = exports.DIR_DO_BUNDLE = void 0;
37
37
  exports.motivoDiferimentoCi = motivoDiferimentoCi;
38
38
  exports.repositorioGitHub = repositorioGitHub;
39
+ exports.loginDoGh = loginDoGh;
40
+ exports.ciNaoExigida = ciNaoExigida;
39
41
  exports.consultarCi = consultarCi;
40
42
  exports.consultarCiDoRepositorio = consultarCiDoRepositorio;
43
+ exports.consultarCiNaForja = consultarCiNaForja;
41
44
  exports.executarCi = executarCi;
42
45
  exports.arquivoDoBundle = arquivoDoBundle;
43
46
  exports.comandosDoBundle = comandosDoBundle;
@@ -48,8 +51,20 @@ exports.bundleDaBranch = bundleDaBranch;
48
51
  exports.executarCiDaBranch = executarCiDaBranch;
49
52
  exports.executarBundleCi = executarBundleCi;
50
53
  /** GitHub CI como CHECK independente (I-12). */
54
+ const ambiente_de_ci_1 = require("./forja/ambiente-de-ci");
55
+ const endereco_1 = require("./forja/endereco");
56
+ const forja_1 = require("./forja");
57
+ const cli_1 = require("./forja/cli");
58
+ const api_1 = require("./forja/api");
59
+ const versao_1 = require("./forja/versao");
60
+ const resolver_1 = require("./forja/resolver");
61
+ const cache_1 = require("./forja/cache");
51
62
  const branch_de_estado_1 = require("./branch-de-estado");
52
63
  const util_1 = require("./util");
64
+ const executor_1 = require("./forja/executor");
65
+ const estado_1 = require("./forja/estado");
66
+ const produtor_1 = require("./forja/produtor");
67
+ const registro_1 = require("./forja/registro");
53
68
  const worktree_1 = require("./worktree");
54
69
  const procedencia_1 = require("./procedencia");
55
70
  const verify_1 = require("./verify");
@@ -62,6 +77,10 @@ const integracoes_locais_1 = require("./integracoes-locais");
62
77
  const ledger_1 = require("./ledger");
63
78
  const thread_1 = require("./thread");
64
79
  const locale_1 = require("./locale");
80
+ const dado_privado_1 = require("./dado-privado");
81
+ const policies_1 = require("./policies");
82
+ /** O comeco de todo retrato da CI exigida; `fonte` e `produtor` so com check decisivo. */
83
+ const baseDaCi = (provider, repository, sha, context) => ({ schema: 'ork.ci-status/v2', required: true, provider, repository, sha, context, fonte: null, produtor: null });
65
84
  const MARCADORES_DE_HOST = [
66
85
  /(^|[\s;&|])\/home\//,
67
86
  /(^|[\s;&|])localhost(?=[:/\s;&|]|$)/,
@@ -128,61 +147,206 @@ function motivoDiferimentoCi(claim, raiz) {
128
147
  return null;
129
148
  }
130
149
  function repositorioGitHub(url) {
131
- const match = url.trim().replace(/\.git$/, '').match(/(?:github\.com[/:])([^/]+\/[^/]+)$/i);
132
- return match?.[1] ?? null;
150
+ const e = (0, endereco_1.lerEnderecoDoRemoto)(url);
151
+ return e && (e.host === 'github.com' || e.host === 'ssh.github.com') && e.caminho.split('/').length === 2 ? e.caminho : null;
152
+ }
153
+ /** O host da API para o gh: `--hostname host`, ou `GH_HOST=host:porta` (o gh recusa `--hostname` com porta). */
154
+ function hostDoGh(host) {
155
+ return host.includes(':') ? { args: [], acrescentar: { GH_HOST: host } } : { args: ['--hostname', host] };
133
156
  }
134
157
  function executorPadrao(input) {
135
- return (0, util_1.exec)('gh', [
136
- 'api', `repos/${input.repository}/commits/${input.sha}/check-runs`,
137
- '-H', 'Accept: application/vnd.github+json',
138
- ], process.cwd(), 120000);
158
+ // 32 MiB, o teto do `forja.ts`: uma pagina de 100 check-runs passa de 1 MiB com facilidade.
159
+ const h = hostDoGh(input.host ?? 'github.com');
160
+ const r = (0, executor_1.rodarCli)({ cmd: 'gh', args: ['api', ...h.args, input.caminho ?? `repos/${input.repository}/commits/${input.sha}/check-runs`,
161
+ '-H', 'Accept: application/vnd.github+json'], prazoMs: 120000, maxBuffer: 32 * 1024 * 1024, acrescentar: h.acrescentar });
162
+ return { ok: r.status === 0, code: r.status ?? -1, stdout: r.stdout, stderr: r.stderr };
163
+ }
164
+ /**
165
+ * O `gh` tem login no host exato (`host` ou `host:porta`)? So o github.com dispensa a pergunta. Com porta o
166
+ * `auth status` roda sem `--hostname` e sai 0 se QUALQUER host tem login: o `temLogin` confere a linha do host exato.
167
+ */
168
+ function loginDoGh(host, rodar) {
169
+ const m = /^(.+?)(?::(\d+))?$/.exec(host);
170
+ return (0, api_1.temLogin)({ tipo: 'github', host: m ? m[1] : host, porta: m?.[2] ? Number(m[2]) : null, caminhoBase: '', ca: null }, rodar);
171
+ }
172
+ const loginPadrao = (host) => loginDoGh(host);
173
+ /**
174
+ * A forja do remoto: o repositorio e o host saem de UM parse do remoto (`lerEnderecoDoRemoto`) e da forja resolvida (o
175
+ * bloco `forja:`, o host conhecido ou a sondagem pela CLI com login no host), sem host de reserva: o caminho nunca e
176
+ * consultado num host que o remoto ou o manifesto nao nomeiam. O nome do host nao decide o tipo. No GitHub o
177
+ * repositorio e `dono/nome`; no GitLab, o caminho inteiro, com subgrupos. `ssh.github.com` (SSH pela 443) e o
178
+ * github.com; a porta de um remoto SSH nao e a da API.
179
+ */
180
+ function alvoDaCi(carregado, remoto, url, sondas) {
181
+ const naoReconhecido = () => ({ ok: false, detalhe: (0, locale_1.textoDoCatalogo)((m) => m.ship.ciRemotoNaoGithub(remoto)) });
182
+ const endereco = (0, endereco_1.lerEnderecoDoRemoto)(url.trim());
183
+ if (!endereco)
184
+ return naoReconhecido();
185
+ // O tipo sondado fica 24 h no cache da raiz: um GHE sem bloco `forja:` nao paga as sondas a cada consulta.
186
+ const forja = (0, resolver_1.resolverForja)({ endereco, manifesto: carregado.manifesto.forja, sondas, cache: (0, cache_1.dirDoCacheDaForja)(carregado.raiz) });
187
+ if (!forja.ok)
188
+ return { ok: false, detalhe: (0, locale_1.textoDoCatalogo)((m) => m.ship.ciForjaNaoResolvida(remoto, m.forja.motivo(forja.erro, null))) };
189
+ if (forja.valor.tipo === 'github' && forja.valor.repo.split('/').length !== 2)
190
+ return naoReconhecido();
191
+ return { ok: true, forja: forja.valor };
192
+ }
193
+ /** O resultado da CI quando o projeto nao a exige (`ci.required_for_ship: false`): nada e consultado na forja. */
194
+ function ciNaoExigida(carregado, sha) {
195
+ const context = carregado.manifesto.ci.context || 'ork-verify';
196
+ return { ...baseDaCi(null, null, sha, context), required: false, ok: true, state: 'disabled', url: null,
197
+ detail: (0, locale_1.textoDoCatalogo)((m) => m.ship.ciNaoExigidoDetalhe) };
139
198
  }
140
- function consultarCi(carregado, sha, remoto = 'origin', executor = executorPadrao) {
199
+ function consultarCi(carregado, sha, remoto = 'origin', executor = executorPadrao, loginNoHost = loginPadrao, sondas = resolver_1.SONDAS_PADRAO, api = {}) {
141
200
  const { ci } = carregado.manifesto;
142
201
  const context = ci.context || 'ork-verify';
202
+ const falha = (detalhe, provider = null) => ({ ...baseDaCi(provider, null, sha, context), ok: false, state: 'unavailable', url: null, detail: detalhe });
143
203
  if (!ci.required_for_ship)
144
- return { schema: 'ork.ci-status/v1', required: false, ok: true, provider: 'github', repository: null, sha, context, state: 'disabled', url: null, detail: (0, locale_1.textoDoCatalogo)((m) => m.ship.ciNaoExigidoDetalhe) };
204
+ return ciNaoExigida(carregado, sha);
145
205
  // RM-047: o `--remoto` do `ork ci status` vem da linha de comando; so nome de remoto chega ao git.
146
206
  const remote = (0, util_1.exec)('git', ['remote', 'get-url', '--', (0, branch_de_estado_1.exigirRemoto)(remoto, 'ci')], carregado.raiz);
147
- const repository = remote.ok ? repositorioGitHub(remote.stdout) : null;
148
- if (!repository)
149
- return { schema: 'ork.ci-status/v1', required: true, ok: false, provider: 'github', repository: null, sha, context, state: 'unavailable', url: null, detail: (0, locale_1.textoDoCatalogo)((m) => m.ship.ciRemotoNaoGithub(remoto)) };
150
- return consultarCiDoRepositorio(repository, sha, context, executor);
207
+ const alvo = remote.ok ? alvoDaCi(carregado, remoto, remote.stdout, sondas)
208
+ : { ok: false, detalhe: (0, locale_1.textoDoCatalogo)((m) => m.ship.ciRemotoNaoGithub(remoto)) };
209
+ if (!alvo.ok)
210
+ return falha(alvo.detalhe);
211
+ const { forja } = alvo;
212
+ const produtores = (0, produtor_1.produtoresAceitos)(carregado.manifesto, forja.tipo);
213
+ // Fora do GitHub, a CI vai pela API da CLI logada (`chamarApi`), que confere o login no host antes da primeira chamada.
214
+ if (forja.tipo !== 'github')
215
+ return consultarCiNaForja(forja, sha, context, produtores, { api, cache: (0, cache_1.dirDoCacheDaForja)(carregado.raiz) });
216
+ // Fronteira de confianca: so o github.com e consultado sem pergunta; outro host so com login do `gh` nele.
217
+ const host = (0, cli_1.hostDaApi)(forja);
218
+ if (host !== 'github.com' && !loginNoHost(host))
219
+ return falha((0, locale_1.textoDoCatalogo)((m) => m.ship.ciHostSemLogin(host)), 'github');
220
+ return consultarCiDoRepositorio(forja.repo, sha, context, executor, host, produtores);
151
221
  }
152
222
  /**
153
223
  * O check `context` no `sha` de um repositorio GitHub ja resolvido: o do remoto do projeto ou, desde a
154
- * RM-037 (rm037defeito, defeito 5), um repositorio externo declarado em `ci.external_repositories`.
224
+ * RM-037 (rm037defeito, defeito 5), um repositorio externo declarado em `ci.external_repositories`. So produtor de
225
+ * `produtores` (`ci.produtor`) aprova.
155
226
  */
156
- function consultarCiDoRepositorio(repository, sha, context, executor = executorPadrao) {
157
- const result = executor({ repository, sha, context });
158
- if (!result.ok)
159
- return { schema: 'ork.ci-status/v1', required: true, ok: false, provider: 'github', repository, sha, context, state: 'unavailable', url: null, detail: (result.stderr || result.stdout || (0, locale_1.textoDoCatalogo)((m) => m.ship.ciConsultaFalhou)).trim().slice(0, 400) };
160
- let payload;
161
- try {
162
- payload = JSON.parse(result.stdout);
227
+ function consultarCiDoRepositorio(repository, sha, context, executor = executorPadrao, host = 'github.com', produtores = produtor_1.PRODUTORES_PADRAO.github) {
228
+ const base = baseDaCi('github', repository, sha, context);
229
+ const lido = (0, registro_1.exigirCapacidade)((0, registro_1.adaptadorDaForja)('github'), 'checksNoCommit')({ repository, sha, context, executor, host });
230
+ if (!lido.ok && lido.erro.codigo === 'forja.resposta-invalida') {
231
+ return { ...base, ok: false, state: 'unavailable', url: null, detail: (0, locale_1.textoDoCatalogo)((m) => lido.erro.detalhe === 'incompleto'
232
+ ? m.ship.ciIncompleto(context) : m.ship.ciRespostaInvalida) };
163
233
  }
164
- catch {
165
- return { schema: 'ork.ci-status/v1', required: true, ok: false, provider: 'github', repository, sha, context, state: 'unavailable', url: null, detail: (0, locale_1.textoDoCatalogo)((m) => m.ship.ciRespostaInvalida) };
234
+ if (!lido.ok)
235
+ return { ...base, ok: false, state: 'unavailable', url: null, detail: (0, forja_1.detalheSeguro)(lido.erro.detalhe || (0, locale_1.textoDoCatalogo)((m) => m.ship.ciConsultaFalhou)) };
236
+ return decidirCi(base, lido.valor, produtores, (m) => m.ship.ciVerde);
237
+ }
238
+ /**
239
+ * O check `context` no `sha` pela API da forja ja resolvida (`estadoDeCi`): o GitLab do projeto ou, na entrega externa,
240
+ * o de um repositorio declarado. A versao abaixo do piso recusa antes de ler a CI. So produtor de `produtores` aprova; o
241
+ * check que so rodou em resultado mesclado sem vinculo com o `sha` nunca aprova (`ci.merged-results-sem-vinculo`).
242
+ */
243
+ function consultarCiNaForja(forja, sha, context, produtores, o = {}) {
244
+ const base = baseDaCi(forja.tipo, forja.repo, sha, context);
245
+ const naoLida = (erro) => ({ ...base, ok: false, state: 'unavailable', url: null,
246
+ detail: (0, locale_1.textoDoCatalogo)((m) => m.ship.ciLeituraFalhou(context, m.forja.motivo(erro, forja.tipo))) });
247
+ const ler = (0, registro_1.adaptadorDaForja)(forja.tipo).estadoDeCi;
248
+ if (!ler)
249
+ return naoLida({ codigo: 'forja.sem-capacidade', detalhe: `${forja.tipo}: estadoDeCi` });
250
+ const api = (0, api_1.chamadorDaApi)(forja, o.api);
251
+ const meta = (0, versao_1.lerMetadados)(forja, { cache: o.cache ?? null, api });
252
+ if (!meta.ok)
253
+ return naoLida(meta.erro);
254
+ const piso = (0, versao_1.recusaAbaixoDoPiso)(forja.tipo, meta.valor);
255
+ if (piso)
256
+ return naoLida(piso);
257
+ const lido = ler({ api, repo: forja.repo, sha, context, edicao: meta.valor.edicao });
258
+ if (!lido.ok)
259
+ return naoLida(lido.erro);
260
+ const decidido = decidirCi(base, lido.valor.checks, produtores, (m) => (forja.tipo === 'gitlab' ? m.ship.ciVerdeNoGitlab : m.ship.ciVerde));
261
+ if (lido.valor.mescladoSemVinculo && decidido.state !== 'failure' && decidido.state !== 'pending') {
262
+ return { ...base, ok: false, state: 'missing', url: null, detail: (0, locale_1.textoDoCatalogo)((m) => m.ship.ciMescladoSemVinculo(context, sha.slice(0, 8))) };
166
263
  }
167
- const checks = (payload.check_runs ?? []).filter((check) => check.name === context);
264
+ return decidido;
265
+ }
266
+ /** O motivo de um check bloqueado: a conclusao do check-run ou, sem ela, o estado do job (`manual`, `skipped`). */
267
+ const motivoDoBloqueio = (c) => c.conclusao ?? c.status;
268
+ /**
269
+ * A regra do gate sobre os checks lidos de qualquer forja. O mais novo de cada produtor conta. So produtor da lista
270
+ * aprova: o verde de quem esta fora dela e descartado; vermelho, pendente ou bloqueado de qualquer um continua contando
271
+ * (quem escreve status no repositorio pode atrasar o gate, nunca aprova-lo). Com varios, a combinacao e conservadora:
272
+ * vermelho ou bloqueado de qualquer um reprova; senao, pendente de qualquer um espera; so todos verdes passam. A fonte
273
+ * e o produtor do retrato sao os do check que decidiu.
274
+ */
275
+ function decidirCi(base, checks, produtores, verde) {
276
+ const context = base.context;
168
277
  if (!checks.length)
169
- return { schema: 'ork.ci-status/v1', required: true, ok: false, provider: 'github', repository, sha, context, state: 'missing', url: null, detail: (0, locale_1.textoDoCatalogo)((m) => m.ship.ciSemCheck(context)) };
170
- const check = checks.at(-1);
171
- const status = check.status ?? 'unknown';
172
- const conclusion = check.conclusion ?? '';
173
- const url = check.html_url ?? '';
174
- const state = status !== 'completed' ? 'pending' : conclusion === 'success' ? 'success' : 'failure';
175
- return { schema: 'ork.ci-status/v1', required: true, ok: state === 'success', provider: 'github', repository, sha, context, state, url: url || null, detail: (0, locale_1.textoDoCatalogo)((m) => state === 'success' ? m.ship.ciVerde : m.ship.ciEstado(context, String(status), conclusion)) };
278
+ return { ...base, ok: false, state: 'missing', url: null, detail: (0, locale_1.textoDoCatalogo)((m) => m.ship.ciSemCheck(context)) };
279
+ const escolhidos = maisNovoPorProdutor(checks);
280
+ const contam = escolhidos.filter((c) => (0, produtor_1.produtorAceito)(c, produtores) || (0, estado_1.estadoDoCheck)(c.fonte, c.status, c.conclusao) !== 'verde');
281
+ if (!contam.length) {
282
+ const descartados = escolhidos.map(nomeDoProdutor).join(', ');
283
+ return { ...base, ok: false, state: 'missing', url: null, detail: (0, locale_1.textoDoCatalogo)((m) => escolhidos.every((c) => c.fonte === 'commit-status')
284
+ ? m.ship.ciStatusSemProdutorConfiavel(context) : m.ship.ciSemProdutorAceito(context, descartados, produtores.join(', '))) };
285
+ }
286
+ if (contam.length === 1) {
287
+ const check = contam[0];
288
+ const estado = (0, estado_1.estadoDoCheck)(check.fonte, check.status, check.conclusao);
289
+ const state = estadoNoGate(estado);
290
+ return { ...base, fonte: check.fonte, produtor: (0, produtor_1.produtorDeSaida)(check), ok: state === 'success', state, url: check.url || null,
291
+ ...(estado === 'bloqueado' ? { bloqueado: true } : {}),
292
+ detail: (0, locale_1.textoDoCatalogo)((m) => state === 'success' ? verde(m) : estado === 'bloqueado' ? m.ship.ciBloqueado(context, motivoDoBloqueio(check))
293
+ : m.ship.ciEstado(context, String(check.status), check.conclusao ?? '')) };
294
+ }
295
+ const lidos = contam.map((check) => {
296
+ const estado = (0, estado_1.estadoDoCheck)(check.fonte, check.status, check.conclusao);
297
+ return { check, estado, state: estadoNoGate(estado) };
298
+ });
299
+ const state = lidos.some((l) => l.state === 'failure') ? 'failure' : lidos.some((l) => l.state === 'pending') ? 'pending' : 'success';
300
+ const decisivo = lidos.find((l) => l.state === state);
301
+ // O estado do ork por produtor, com o motivo do bloqueio.
302
+ const porProdutor = lidos.map((l) => `${nomeDoProdutor(l.check)} ${l.estado}${l.estado === 'bloqueado' ? ` (${motivoDoBloqueio(l.check)})` : ''}`).join(', ');
303
+ // Bloqueado so quando todo check que conta e verde ou bloqueado: pendente ou vermelho de qualquer um desfaz a marca.
304
+ const soBloqueados = state === 'failure' && lidos.every((l) => l.estado === 'verde' || l.estado === 'bloqueado')
305
+ && lidos.some((l) => l.estado === 'bloqueado');
306
+ return { ...base, fonte: decisivo.check.fonte, produtor: (0, produtor_1.produtorDeSaida)(decisivo.check), ok: state === 'success', state, url: decisivo.check.url || null,
307
+ ...(soBloqueados ? { bloqueado: true } : {}),
308
+ detail: (0, locale_1.textoDoCatalogo)((m) => m.ship.ciProdutores(context, porProdutor)) };
176
309
  }
177
- function executarCi(carregado, threadId) {
310
+ function estadoNoGate(estado) {
311
+ return estado === 'verde' ? 'success' : estado === 'pendente' ? 'pending' : 'failure';
312
+ }
313
+ /** O produtor como aparece no detalhe; check-run e commit status do mesmo nome sao produtores distintos. */
314
+ function nomeDoProdutor(check) {
315
+ return `${check.produtor ?? '?'}${check.fonte === 'commit-status' ? ' (status)' : ''}`;
316
+ }
317
+ /**
318
+ * O check mais novo de cada produtor: maior `concluidoEm`, depois maior `ordem`. Sem `concluidoEm` (ainda rodando) e
319
+ * o mais novo; data ilegivel e a mais velha. Saida ordenada pelo nome do produtor, para o detalhe ser estavel.
320
+ */
321
+ function maisNovoPorProdutor(checks) {
322
+ const quando = (c) => {
323
+ if (c.concluidoEm === null)
324
+ return Number.POSITIVE_INFINITY;
325
+ const t = Date.parse(c.concluidoEm);
326
+ return Number.isNaN(t) ? Number.NEGATIVE_INFINITY : t;
327
+ };
328
+ const porProdutor = new Map();
329
+ for (const c of checks) {
330
+ const chave = nomeDoProdutor(c);
331
+ const atual = porProdutor.get(chave);
332
+ if (!atual || quando(c) > quando(atual) || (quando(c) === quando(atual) && c.ordem > atual.ordem))
333
+ porProdutor.set(chave, c);
334
+ }
335
+ return [...porProdutor.entries()].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)).map(([, c]) => c);
336
+ }
337
+ /**
338
+ * `ork ci run <thread>`: o verify da thread no runner. O runner (GitHub Actions ou GitLab CI) diz a forja, o projeto e
339
+ * a pagina do job; fora dele, so o commit verificado.
340
+ */
341
+ function executarCi(carregado, threadId, env = process.env) {
178
342
  const verify = (0, verify_1.verificar)(carregado, threadId);
179
343
  const context = carregado.manifesto.ci.context || 'ork-verify';
180
- const repository = process.env.GITHUB_REPOSITORY ?? null;
344
+ const runner = (0, ambiente_de_ci_1.ambienteDeCi)(env);
181
345
  return {
182
346
  status: {
183
- schema: 'ork.ci-status/v1', required: true, ok: verify.ok, provider: 'github', repository,
184
- sha: verify.commit, context, state: verify.ok ? 'success' : 'failure',
185
- url: process.env.GITHUB_SERVER_URL && repository && process.env.GITHUB_RUN_ID ? `${process.env.GITHUB_SERVER_URL}/${repository}/actions/runs/${process.env.GITHUB_RUN_ID}` : null,
347
+ ...baseDaCi(runner?.tipo ?? null, runner?.repository ?? null, verify.commit, context), ok: verify.ok,
348
+ state: verify.ok ? 'success' : 'failure', url: runner?.url ?? null,
349
+ fonte: runner ? (runner.tipo === 'github' ? 'check-run' : 'pipeline-job') : null, produtor: runner?.produtor ?? null,
186
350
  detail: verify.ok ? 'ork verify aprovado no runner independente' : `ork verify reprovou: ${verify.motivos.join(', ')}`,
187
351
  },
188
352
  verify,
@@ -207,9 +371,13 @@ function arquivoDoBundle(threadId) {
207
371
  }
208
372
  /** Os comandos que o bundle leva ao runner; o `ork ship publicar` confere os do bundle no HEAD contra estes. */
209
373
  function comandosDoBundle(carregado) {
210
- return carregado.manifesto.ci.command
211
- ? [{ name: 'ci', command: carregado.manifesto.ci.command }]
212
- : (0, verify_2.comandosDoManifesto)(carregado.manifesto).map(({ nome, comando }) => ({ name: nome, command: comando }));
374
+ // O scan e obrigatorio no runner: la a ferramenta ausente reprova em vez de ficar `unavailable` em silencio.
375
+ const doManifesto = (0, verify_2.comandosDoManifesto)(carregado.manifesto).map(({ nome, comando }) => ({
376
+ name: nome, command: nome === 'security_scan' ? `ORK_SECURITY_SCAN_REQUIRED=1 ${comando}` : comando,
377
+ }));
378
+ if (!carregado.manifesto.ci.command)
379
+ return doManifesto;
380
+ return [{ name: 'ci', command: carregado.manifesto.ci.command }, ...doManifesto.filter((c) => c.name === 'security_scan')];
213
381
  }
214
382
  /**
215
383
  * I-53 (RM-037, P6): o lint no `ci prepare`. Claim nascida sob a regra (com o campo `lint`) que
@@ -224,11 +392,16 @@ function lintDoBundle(claims) {
224
392
  if (achado.regra === 'suite-inteira' && claim.lint !== undefined)
225
393
  recusas.push(linha);
226
394
  else
227
- avisos.push(achado.regra === 'suite-inteira' ? `${linha} (claim anterior ao lint: so aviso)` : linha);
395
+ avisos.push(achado.regra === 'suite-inteira' ? anteriorAoLint(linha) : linha);
228
396
  }
229
397
  }
230
398
  return { recusas, avisos };
231
399
  }
400
+ /** RM-061 (F3d, GO-FIX 1): a linha da claim anterior ao lint, remontavel no locale do comando como a linha de dentro. */
401
+ function anteriorAoLint(linha) {
402
+ const montar = (0, locale_1.montadorDe)(linha);
403
+ return (0, locale_1.textoDoCatalogo)((m) => m.operacao.produto.ci.anteriorAoLint(montar(m)));
404
+ }
232
405
  /**
233
406
  * RM-037 (rm037defeito, defeito 6): onde o bundle nasce. Ele e artefato da branch da thread (o commit
234
407
  * `ci(<thread>)` vai no PR dela), entao o destino e a worktree da thread, rodando o `ork` da raiz ou da
@@ -253,14 +426,14 @@ function prepararBundleCi(carregado, threadId, opcoes = {}) {
253
426
  for (const aviso of lint.avisos)
254
427
  opcoes.aoAvisar?.(aviso);
255
428
  if (lint.recusas.length) {
256
- throw new Error(`claims.lint: o bundle nao foi gerado; retire a claim e registre de novo com o comando focado:\n ` +
257
- lint.recusas.join('\n '));
429
+ const montadores = lint.recusas.map(locale_1.montadorDe);
430
+ throw new locale_1.ErroDoCatalogo((m) => m.operacao.produto.ci.lintRecusado(montadores.map((montar) => montar(m)).join('\n ')));
258
431
  }
259
432
  const destino = destinoDoBundle(carregado, threadId);
260
433
  // Achado S8 do CHECK: a worktree registrada que sumiu nao e silencio; o bundle na raiz vem com aviso.
261
434
  const registrada = (0, thread_1.lerThread)(carregado.raiz, threadId).worktree;
262
435
  if (registrada && destino !== registrada) {
263
- opcoes.aoAvisar?.(`a worktree ${registrada} da thread nao existe mais; o bundle vai para a raiz do projeto`);
436
+ opcoes.aoAvisar?.((0, locale_1.textoDoCatalogo)((m) => m.operacao.produto.ci.worktreeSumiu(registrada)));
264
437
  }
265
438
  const classified = activeClaims.map((claim) => ({
266
439
  claim,
@@ -277,12 +450,37 @@ function prepararBundleCi(carregado, threadId, opcoes = {}) {
277
450
  .map((item) => ({ id: item.claim.id, reason: item.reason })),
278
451
  commands,
279
452
  };
453
+ const texto = JSON.stringify(bundle, null, 2) + '\n';
454
+ barreiraDoBundle(carregado, threadId, destino, path.posix.join(exports.DIR_DO_BUNDLE, nomeDoArquivo), texto, opcoes);
280
455
  const dir = path.join(destino, '.ork-ci');
281
456
  fs.mkdirSync(dir, { recursive: true });
282
457
  const file = path.join(dir, nomeDoArquivo);
283
- fs.writeFileSync(file, JSON.stringify(bundle, null, 2) + '\n', 'utf8');
458
+ fs.writeFileSync(file, texto, 'utf8');
284
459
  return file;
285
460
  }
461
+ /**
462
+ * RM-062 (F2): com a policy `dado_privado`, o diff da thread e o texto do bundle novo passam pela barreira antes de o
463
+ * arquivo existir. O bundle anterior da propria thread sai do diff, porque o novo o substitui. Em `block`, achado
464
+ * recusa e nada e gravado; em `warn`, avisa e grava. A linha da lista local (presente ou ausente) sai sempre.
465
+ */
466
+ function barreiraDoBundle(carregado, threadId, destino, caminho, texto, opcoes) {
467
+ const barreira = (0, dado_privado_1.barreiraDaThread)(carregado, (0, thread_1.lerThread)(carregado.raiz, threadId), destino, 'ci.prepare', { extra: (c) => (0, dado_privado_1.varrerTexto)(c, caminho, texto), ignorar: [caminho] });
468
+ if (!barreira)
469
+ return;
470
+ const v = barreira.varredura;
471
+ opcoes.aoInformar?.(`dado privado (policy dado_privado em ${barreira.severidade}): ${(0, dado_privado_1.textoDoEscopo)(v)}; ` +
472
+ `lista local ${(0, dado_privado_1.textoDaListaLocal)(v)}`);
473
+ const recusas = (0, policies_1.bloqueantes)(barreira.violacoes);
474
+ if (recusas.length) {
475
+ throw new Error(`privado.achado: o bundle nao foi gerado; ${recusas.map((r) => r.detalhe).join('; ')}\n ` +
476
+ [...v.achados.slice(0, 20).map(dado_privado_1.linhaDoAchado), `correcao: ${recusas[0].correcao}`].join('\n '));
477
+ }
478
+ for (const aviso of (0, policies_1.avisos)(barreira.violacoes)) {
479
+ (0, ledger_1.registrar)((0, thread_1.dirThread)(carregado.raiz, threadId), threadId, ledger_1.TIPOS_DE_EVENTO.politicaAviso, { gate: 'ci.prepare',
480
+ policy: aviso.policy, motivo: aviso.motivo, detalhe: aviso.detalhe, correcao: aviso.correcao });
481
+ opcoes.aoAvisar?.(`policy ${aviso.policy}: ${aviso.detalhe}`);
482
+ }
483
+ }
286
484
  function lerBundle(raiz, file) {
287
485
  const absolute = path.resolve(raiz, file);
288
486
  const stat = fs.statSync(absolute);
@@ -360,8 +558,13 @@ function rodarBundle(carregado, bundle) {
360
558
  const preparo = comandoDoPreparo
361
559
  ? (0, verify_2.executar)('preparo', comandoDoPreparo, carregado.raiz, (0, verify_2.prazoDoComando)(carregado.manifesto, 'preparo'))
362
560
  : null;
363
- const claims = bundle.claims.map((claim) => (0, verify_2.verificarClaim)(claim, carregado.raiz));
364
- const commands = bundle.commands.map((item) => (0, verify_2.executar)(item.name, item.command, carregado.raiz));
561
+ const claims = bundle.claims.map((claim) => (0, verify_2.verificarClaim)(claim, carregado.raiz, (0, verify_2.executorDoManifesto)(carregado.manifesto)));
562
+ // O comando lógico `ci` executa o script de testes hermético (`test:ci`) e herda o mesmo teto configurado
563
+ // para `test`. Assim a suíte não volta silenciosamente ao default de 600 s no runner hospedado.
564
+ const doManifesto = (0, verify_2.executorDoManifesto)(carregado.manifesto);
565
+ const commands = bundle.commands.map((item) => item.name === 'ci'
566
+ ? (0, verify_2.executar)(item.name, item.command, carregado.raiz, (0, verify_2.prazoDoComando)(carregado.manifesto, 'test'))
567
+ : doManifesto(item.name, item.command, carregado.raiz));
365
568
  const ok = claims.every((item) => item.verificado || item.motivo === 'claims.unverifiable') && commands.every((item) => item.ok);
366
569
  return { schema: 'ork.ci-run/v1', ok, thread: bundle.thread, commit: (0, verify_2.commitReal)(carregado.raiz), preparo, claims, commands };
367
570
  }
package/dist/ciclos.js CHANGED
@@ -16,6 +16,7 @@ exports.somenteAnalise = somenteAnalise;
16
16
  exports.aplicarVariante = aplicarVariante;
17
17
  exports.tabelaDeVariantes = tabelaDeVariantes;
18
18
  const modos_1 = require("./modos");
19
+ const locale_1 = require("./locale");
19
20
  /** As 5 variantes de ciclo, com o que cada uma muda na criacao da thread. */
20
21
  exports.VARIANTES = {
21
22
  greenfield: {
@@ -139,19 +140,20 @@ function aplicarVariante(blocos, variante) {
139
140
  }
140
141
  /** Tabela das variantes de ciclo, usada por `ork ciclos`. */
141
142
  function tabelaDeVariantes() {
142
- const linhas = ['Variantes de ciclo (`ork thread new --ciclo <variante>`)', ''];
143
+ const m = (0, locale_1.msg)().operacao.ciclos;
144
+ const linhas = [m.titulo, ''];
143
145
  for (const v of exports.ORDEM_DAS_VARIANTES) {
144
146
  const def = exports.VARIANTES[v];
145
147
  const exige = [];
146
148
  if (def.exigeBranch)
147
149
  exige.push('--branch <existente>');
148
150
  if (def.exigeWorktree)
149
- exige.push('worktree isolada');
150
- linhas.push(` ${v.padEnd(20)} ${def.descricao}`);
151
- linhas.push(` ${''.padEnd(20)} exige: ${exige.join(', ') || 'nada'} | ` +
152
- `muda os blocos do modo: ${def.mudaBlocos ? 'sim' : 'nao'}`);
151
+ exige.push(m.worktree);
152
+ linhas.push(` ${v.padEnd(20)} ${m.descricoes[v] ?? def.descricao}`);
153
+ linhas.push(` ${''.padEnd(20)} ${m.exige}: ${exige.join(', ') || m.nada} | ` +
154
+ `${m.muda}: ${def.mudaBlocos ? m.sim : m.nao}`);
153
155
  }
154
156
  linhas.push('');
155
- linhas.push('A variante muda como a thread NASCE. Verificacao e gates nao mudam.');
157
+ linhas.push(m.fecho);
156
158
  return linhas.join('\n');
157
159
  }