@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
@@ -34,6 +34,9 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.ETAPAS = exports.MODOS_QUE_PUBLICAM = exports.CONTRATO_DA_PISTA = exports.CONTRATO_DA_PUBLICACAO = void 0;
37
+ exports.conferirCheck = conferirCheck;
38
+ exports.conferirBundle = conferirBundle;
39
+ exports.manifestoDaBranch = manifestoDaBranch;
37
40
  exports.tituloDoPr = tituloDoPr;
38
41
  exports.entreAspas = entreAspas;
39
42
  exports.comandoDoDono = comandoDoDono;
@@ -52,7 +55,7 @@ exports.pistaDeEntrega = pistaDeEntrega;
52
55
  * thread ork-rm059pista);
53
56
  * 2. empurra sem forca o sha conferido, e nao a ref, com refspec explicito, e prova pelo `git ls-remote` (a prova do
54
57
  * `ork ship`);
55
- * 3. reaproveita o PR aberto da branch ou abre um com o texto do `pr-body.md` da thread, e prova pela releitura da
58
+ * 3. reaproveita o PR (MR no GitLab) aberto da branch ou abre um com o texto do `pr-body.md` da thread, e prova pela releitura da
56
59
  * lista;
57
60
  * 4. grava `ship_published` com a prova, so quando houve efeito; o push sem prova tambem vai. Repetido, ou com o PR
58
61
  * ja mesclado no HEAD, devolve `ja-publicada`.
@@ -68,13 +71,20 @@ const fs = __importStar(require("node:fs"));
68
71
  const path = __importStar(require("node:path"));
69
72
  const branch_de_estado_1 = require("./branch-de-estado");
70
73
  const ci_1 = require("./ci");
71
- const hitl_1 = require("./hitl");
74
+ const api_1 = require("./forja/api");
75
+ const cli_1 = require("./forja/cli");
76
+ const pedidos_1 = require("./forja/gitlab/pedidos");
77
+ const registro_1 = require("./forja/registro");
78
+ const resolver_1 = require("./forja/resolver");
79
+ const cache_1 = require("./forja/cache");
80
+ const texto_1 = require("./forja/texto");
72
81
  const claims_1 = require("./claims");
73
82
  const ledger_1 = require("./ledger");
74
83
  const manifest_1 = require("./manifest");
75
84
  const modos_1 = require("./modos");
76
85
  const parado_no_condutor_1 = require("./parado-no-condutor");
77
86
  const entrega_pr_1 = require("./entrega-pr");
87
+ const noctum_guarda_1 = require("./noctum-guarda");
78
88
  const ship_1 = require("./ship");
79
89
  const session_watcher_claude_1 = require("./session-watcher-claude");
80
90
  const thread_1 = require("./thread");
@@ -96,21 +106,11 @@ const TETO_DO_CORPO = 64 * 1024;
96
106
  const PRAZO_DO_GH_MS = 45000;
97
107
  const PRAZO_DO_PUSH_MS = 180000;
98
108
  const PRAZO_DO_LS_REMOTE_MS = 60000;
99
- /** Os campos do `gh pr list` de uma branch: os do `prDaForja`, com o estado de merge do PR aberto. */
100
- const CAMPOS_DA_BRANCH = 'number,state,headRefName,headRefOid,baseRefName,isDraft,isCrossRepository,url,createdAt,mergedAt,mergeable';
101
109
  /** Git local sem rede escondida nem pergunta de credencial no terminal. */
102
110
  function git(raiz, args, prazoMs = 60000) {
103
111
  return (0, util_1.exec)('git', args, raiz, prazoMs, { ...process.env, GIT_NO_LAZY_FETCH: '1', GIT_TERMINAL_PROMPT: '0' });
104
112
  }
105
113
  const curto = (sha) => (sha ? sha.slice(0, 7) : '-');
106
- /** Texto curto: uma linha, sem controle, com teto. */
107
- function umaLinha(texto, teto = 200) {
108
- return Array.from(texto.replace(/\p{Cc}/gu, ' ').replace(/\s+/g, ' ').trim()).slice(0, teto).join('') || '-';
109
- }
110
- /** Texto de fora (stderr do git ou do gh): sem segredo, numa linha e com teto, antes de ir ao `--json` e ao ledger. */
111
- function deFora(texto, teto = 200) {
112
- return umaLinha((0, hitl_1.redigirSegredos)(texto), teto);
113
- }
114
114
  exports.ETAPAS = ['check', 'verify', 'bundle', 'branch', 'pr', 'ci', 'conflito', 'entrega'];
115
115
  const etapa = (id, estado, texto) => ({ id, estado, texto });
116
116
  /** Os caminhos mudados so cabem no bundle (`.ork-ci/`)? Lista vazia tambem nao e produto. */
@@ -138,7 +138,10 @@ function ultimoCommitDeProduto(raiz, baseRef, head) {
138
138
  }
139
139
  return null;
140
140
  }
141
- /** O CHECK: exatamente um veredito, PASSOU, gravado depois do ultimo commit de produto. */
141
+ /**
142
+ * O CHECK: exatamente um veredito, PASSOU, gravado depois do ultimo commit de produto. RM-063 (F7): a batida da conducao
143
+ * tambem o le antes do merge do PR, para nada entrar na base sem ter passado pelo CHECK.
144
+ */
142
145
  function conferirCheck(raiz, t, baseRef, head) {
143
146
  if (!(t.fases ?? []).includes('CHECK')) {
144
147
  return { etapa: etapa('check', 'nao-se-aplica', (0, locale_1.textoDoCatalogo)((m) => m.ship.publicar.checkSemCiclo((0, modos_1.tagDoModo)(t.modo)))), passou: true };
@@ -249,7 +252,7 @@ function manifestoDaBranch(carregado, head) {
249
252
  if (!doHead)
250
253
  return carregado;
251
254
  return { ...carregado, manifesto: { ...carregado.manifesto,
252
- verify: { ...carregado.manifesto.verify, typecheck: doHead.typecheck, build: doHead.build, test: doHead.test },
255
+ verify: { ...carregado.manifesto.verify, typecheck: doHead.typecheck, build: doHead.build, test: doHead.test, security_scan: doHead.securityScan },
253
256
  ci: { ...carregado.manifesto.ci, command: doHead.ciCommand } } };
254
257
  }
255
258
  return carregado;
@@ -288,7 +291,7 @@ function refDaBase(refs, remoto, base) {
288
291
  function pontaNoRemoto(raiz, remoto, branch) {
289
292
  const r = git(raiz, ['ls-remote', '--', remoto, `refs/heads/${branch}`], PRAZO_DO_LS_REMOTE_MS);
290
293
  if (!r.ok)
291
- return { sha: null, erro: deFora(r.stderr || r.stdout || `codigo ${r.code}`) };
294
+ return { sha: null, erro: (0, texto_1.deFora)(r.stderr || r.stdout || `codigo ${r.code}`) };
292
295
  const alvo = `refs/heads/${branch}`;
293
296
  const linha = r.stdout.split('\n').map((l) => l.trim().split(/\s+/)).find((partes) => partes[1] === alvo);
294
297
  const sha = linha?.[0] ?? '';
@@ -317,22 +320,59 @@ function pontasNoRemoto(raiz, remoto) {
317
320
  }
318
321
  return mapa;
319
322
  }
320
- /** Os PRs de uma branch, da base do projeto, do mais novo para o mais velho. */
321
- function prsDaBranch(executor, forja, base, branch) {
322
- const r = executor(['pr', 'list', `--repo=${forja.host}/${forja.repositorio}`, `--head=${branch}`, '--state=all', '--limit=10',
323
- `--json=${CAMPOS_DA_BRANCH}`], PRAZO_DO_GH_MS);
324
- if (r.status !== 0)
325
- return { prs: [], erro: deFora(r.stderr || r.stdout || `codigo ${r.status ?? '-'}`) };
326
- try {
327
- const lista = JSON.parse(r.stdout);
328
- if (!Array.isArray(lista))
329
- throw new Error('a resposta nao e uma lista');
330
- const prs = lista.map((p) => (0, parado_no_condutor_1.prDaForja)(p, base)).filter((p) => !!p && p.branch === branch);
331
- return { prs: prs.sort((a, b) => b.numero - a.numero), erro: null };
332
- }
333
- catch (e) {
334
- return { prs: [], erro: deFora(e.message) };
335
- }
323
+ /**
324
+ * O tipo da forja sem rede nem CLI, para o comando que o dono roda: o fixado, o bloco `forja:`, o host conhecido ou a
325
+ * sondagem que ja esta no cache de 24 h. Remoto sem host (caminho local) segue o GitHub de sempre; host proprio que
326
+ * nada disso resolve da `null`, e o comando do dono mostra as duas forjas.
327
+ */
328
+ function tipoSemRede(carregado, remoto, fixado) {
329
+ if (fixado)
330
+ return fixado;
331
+ if (carregado.manifesto.forja?.tipo)
332
+ return carregado.manifesto.forja.tipo;
333
+ const endereco = (0, entrega_pr_1.enderecoDoRemotoDaRaiz)(carregado.raiz, remoto);
334
+ if (!endereco)
335
+ return 'github';
336
+ const r = (0, resolver_1.resolverForja)({ endereco, manifesto: carregado.manifesto.forja, sondas: {}, cache: (0, cache_1.dirDoCacheDaForja)(carregado.raiz) });
337
+ return r.ok ? r.valor.tipo : null;
338
+ }
339
+ function pedidosDoGithub(forja, executor) {
340
+ const gh = (0, registro_1.adaptadorDaForja)('github');
341
+ return {
342
+ tipo: 'github',
343
+ listar: (base, branch) => (0, registro_1.exigirCapacidade)(gh, 'pedidosDaBranch')({ ...forja, base, branch, executor, prazoMs: PRAZO_DO_GH_MS }),
344
+ abrir: (base, branch, titulo, corpo) => (0, registro_1.exigirCapacidade)(gh, 'abrirPedido')({ ...forja, base, branch, titulo, corpo, executor,
345
+ prazoMs: PRAZO_DO_GH_MS }),
346
+ passoDaLista: (branch) => `gh pr list --head ${branch} --state all`,
347
+ passoDaCriacao: (base, branch) => `gh pr create --base ${base} --head ${branch}`,
348
+ ensaioDaCriacao: (base, branch, titulo, corpo) => `gh pr create --base ${base} --head ${branch} --title "${titulo}" --body-file <${corpo}>`,
349
+ };
350
+ }
351
+ /** O GitLab pela API com a CLI logada; o gh nunca roda aqui. */
352
+ function pedidosDoGitlab(f, opcoes) {
353
+ const gl = (0, registro_1.adaptadorDaForja)('gitlab');
354
+ const semGh = () => ({ status: 1, stdout: '', stderr: 'o gh não fala com o GitLab' });
355
+ const comum = { host: (0, cli_1.hostDaApi)(f), repositorio: f.repo, executor: semGh, prazoMs: PRAZO_DO_GH_MS, api: (0, api_1.chamadorDaApi)(f, opcoes) };
356
+ const projeto = (0, pedidos_1.projetoNaApi)(f.repo);
357
+ return {
358
+ tipo: 'gitlab',
359
+ listar: (base, branch) => (0, registro_1.exigirCapacidade)(gl, 'pedidosDaBranch')({ ...comum, base, branch }),
360
+ abrir: (base, branch, titulo, corpo) => (0, registro_1.exigirCapacidade)(gl, 'abrirPedido')({ ...comum, base, branch, titulo, corpo }),
361
+ passoDaLista: (branch) => `glab api ${(0, pedidos_1.caminhoDosMrsDaBranch)(f.repo, branch)}`,
362
+ passoDaCriacao: (base, branch) => `glab api --method POST ${projeto}/merge_requests (source_branch=${branch}, target_branch=${base})`,
363
+ ensaioDaCriacao: (base, branch, titulo, corpo) => `glab api --method POST ${projeto}/merge_requests (source_branch=${branch}, target_branch=${base}, title="${titulo}", description <${corpo}>)`,
364
+ };
365
+ }
366
+ /** Os pedidos da entrega: o GitHub fixo dos testes, a forja fixada, ou a resolvida do remoto. */
367
+ function pedidosDaEntrega(carregado, remoto, opcoes) {
368
+ const executor = opcoes.executorGh ?? parado_no_condutor_1.ghPadrao;
369
+ if (opcoes.forja)
370
+ return { ok: true, pedidos: pedidosDoGithub(opcoes.forja, executor) };
371
+ const r = opcoes.forjaResolvida ? { ok: true, valor: opcoes.forjaResolvida } : (0, entrega_pr_1.forjaDaEntrega)(carregado, remoto, opcoes.sondas);
372
+ if (!r.ok)
373
+ return r;
374
+ return { ok: true, pedidos: r.valor.tipo === 'gitlab' ? pedidosDoGitlab(r.valor, opcoes.api ?? {})
375
+ : pedidosDoGithub({ host: r.valor.host, repositorio: r.valor.repo }, executor) };
336
376
  }
337
377
  // ---------------------------------------------------------------------------
338
378
  // O corpo e o titulo do PR.
@@ -345,7 +385,7 @@ function corpoDaThread(raiz, threadId) {
345
385
  if (!st.isFile() || st.size === 0 || st.size > TETO_DO_CORPO)
346
386
  return null;
347
387
  const texto = fs.readFileSync(arquivo, 'utf8');
348
- // O corpo vai ao gh como argumento (A5 da revisao): com NUL ele nao passa, e vale o corpo padrao.
388
+ // O corpo vai ao gh por um arquivo temporario 600, nunca pelo argv; com NUL ele nao e texto de PR, e vale o corpo padrao.
349
389
  return texto.includes('\0') ? null : { arquivo, texto };
350
390
  }
351
391
  catch {
@@ -360,13 +400,13 @@ function tituloDoPr(t, corpo) {
360
400
  if (!l)
361
401
  continue;
362
402
  const m = /^#{1,6}\s+(.+)$/.exec(l);
363
- titulo = m ? umaLinha(m[1], 120) : null;
403
+ titulo = m ? (0, texto_1.umaLinha)(m[1], 120) : null;
364
404
  break;
365
405
  }
366
406
  const prefixo = `ship(${t.id})`;
367
407
  if (titulo?.startsWith(prefixo))
368
408
  return titulo;
369
- return `${prefixo}: ${titulo ?? umaLinha(t.nome || t.id, 120)}`;
409
+ return `${prefixo}: ${titulo ?? (0, texto_1.umaLinha)(t.nome || t.id, 120)}`;
370
410
  }
371
411
  /** Uma palavra do shell entre aspas simples: nada dentro dela vira comando, nem `;`, `$`, crase ou barra. */
372
412
  function entreAspas(s) {
@@ -374,10 +414,21 @@ function entreAspas(s) {
374
414
  }
375
415
  /**
376
416
  * O que o dono roda no proprio terminal quando o modo da thread nao autoriza o push. A branch e a base vem do estado e do
377
- * manifesto, que podem ser do clone: cada parte vai entre aspas simples (A4 da revisao).
417
+ * manifesto, que podem ser do clone: cada parte vai entre aspas simples (A4 da revisao). No GitLab, a descricao vai pelo
418
+ * `--description-file` (ou o titulo, sem `pr-body.md`) e nunca pelo `--fill`, que empurra a branch e pode trocar o titulo;
419
+ * o `glab mr create` nao arma merge.
378
420
  */
379
- function comandoDoDono(remoto, base, branch, titulo, comCorpo) {
380
- return `git push -u ${entreAspas(remoto)} ${entreAspas(branch)} && gh pr create --base ${entreAspas(base)} --head ${entreAspas(branch)} ` +
421
+ function comandoDoDono(remoto, base, branch, titulo, comCorpo, tipo = 'github') {
422
+ if (tipo === null) {
423
+ const gh = comandoDoDono(remoto, base, branch, titulo, comCorpo, 'github'), glab = comandoDoDono(remoto, base, branch, titulo, comCorpo, 'gitlab');
424
+ return (0, locale_1.textoDoCatalogo)((m) => m.ship.publicar.comandoDasDuasForjas(gh, glab));
425
+ }
426
+ const push = `git push -u ${entreAspas(remoto)} ${entreAspas(branch)}`;
427
+ if (tipo === 'gitlab') {
428
+ return `${push} && glab mr create --source-branch ${entreAspas(branch)} --target-branch ${entreAspas(base)} --title ${entreAspas(titulo)} ` +
429
+ `${comCorpo ? `--description-file ${entreAspas(comCorpo)}` : `--description ${entreAspas(titulo)}`} --yes`;
430
+ }
431
+ return `${push} && gh pr create --base ${entreAspas(base)} --head ${entreAspas(branch)} ` +
381
432
  `--title ${entreAspas(titulo)} ${comCorpo ? `--body-file ${entreAspas(comCorpo)}` : '--fill'}`;
382
433
  }
383
434
  /**
@@ -390,7 +441,6 @@ function publicarEntrega(carregado, threadId, opcoes = {}) {
390
441
  const remoto = (0, branch_de_estado_1.exigirRemoto)(opcoes.remoto ?? 'origin', 'ship');
391
442
  const quando = opcoes.quando ?? new Date().toISOString();
392
443
  const dryRun = opcoes.dryRun === true;
393
- const executor = opcoes.executorGh ?? parado_no_condutor_1.ghPadrao;
394
444
  const p = (m) => m.ship.publicar;
395
445
  const r = {
396
446
  contrato: exports.CONTRATO_DA_PUBLICACAO, thread: threadId, modo: null, tag: null, acao: 'recusada', motivo: null,
@@ -404,7 +454,7 @@ function publicarEntrega(carregado, threadId, opcoes = {}) {
404
454
  lida = (0, thread_1.lerThread)(raiz, threadId);
405
455
  }
406
456
  catch (e) {
407
- return recusar('artifact.missing', (0, locale_1.textoDoCatalogo)((m) => p(m).threadInexistente(umaLinha(threadId, 80), deFora(e.message))), (0, locale_1.textoDoCatalogo)((m) => p(m).threadInexistenteCorrecao));
457
+ return recusar('artifact.missing', (0, locale_1.textoDoCatalogo)((m) => p(m).threadInexistente((0, texto_1.umaLinha)(threadId, 80), (0, texto_1.deFora)(e.message))), (0, locale_1.textoDoCatalogo)((m) => p(m).threadInexistenteCorrecao));
408
458
  }
409
459
  const t = lida;
410
460
  r.thread = t.id;
@@ -413,6 +463,11 @@ function publicarEntrega(carregado, threadId, opcoes = {}) {
413
463
  if (t.status === 'fechada') {
414
464
  return recusar('artifact.missing', (0, locale_1.textoDoCatalogo)((m) => p(m).threadFechada(t.id)), (0, locale_1.textoDoCatalogo)((m) => p(m).threadFechadaCorrecao));
415
465
  }
466
+ // RM-058, integração (T1.1, D3 da ork-rm058integra): a thread de um arco #Noctum que a guarda só é publicada pelo próprio
467
+ // arco (`doArco`). Antes de qualquer git, e sem ledger, como as outras recusas daqui.
468
+ const guarda = (0, noctum_guarda_1.guardaDaThread)(raiz, t.id, quando, { doArco: opcoes.doArco });
469
+ if (guarda)
470
+ return { ...recusar('policy.violation', guarda.detalhe, guarda.correcao), codigo: guarda.motivo };
416
471
  const refs = (0, parado_no_condutor_1.refsLocais)(raiz, remoto);
417
472
  const baseRef = refDaBase(refs, remoto, base);
418
473
  const f = fatosDaThread(carregado, t, refs, baseRef, quando);
@@ -421,7 +476,7 @@ function publicarEntrega(carregado, threadId, opcoes = {}) {
421
476
  const corpo = corpoDaThread(raiz, t.id);
422
477
  // 2. O modo que ja autoriza push (D1): fora dele, o push e do dono, e a correcao diz o comando dele.
423
478
  if (!exports.MODOS_QUE_PUBLICAM.includes(t.modo)) {
424
- const comando = comandoDoDono(remoto, base, f.branch, tituloDoPr(t, corpo?.texto ?? null), corpo ? path.relative(raiz, corpo.arquivo) : null);
479
+ const comando = comandoDoDono(remoto, base, f.branch, tituloDoPr(t, corpo?.texto ?? null), corpo ? path.relative(raiz, corpo.arquivo) : null, tipoSemRede(carregado, remoto, opcoes.forja ? 'github' : opcoes.forjaResolvida?.tipo));
425
480
  return recusar('human.pending', (0, locale_1.textoDoCatalogo)((m) => p(m).modoSemPush((0, modos_1.tagDoModo)(t.modo))), (0, locale_1.textoDoCatalogo)((m) => p(m).modoSemPushCorrecao(comando)));
426
481
  }
427
482
  // 3. Ninguem conduz a thread agora: a branch pode mudar no meio da publicacao.
@@ -451,22 +506,28 @@ function publicarEntrega(carregado, threadId, opcoes = {}) {
451
506
  if (!git(raiz, ['remote', 'get-url', '--', remoto]).ok) {
452
507
  return recusar('runtime.unavailable', (0, locale_1.textoDoCatalogo)((m) => p(m).semRemoto(remoto)), (0, locale_1.textoDoCatalogo)((m) => p(m).semRemotoCorrecao));
453
508
  }
454
- const forja = opcoes.forja ?? (0, parado_no_condutor_1.githubDoRemoto)(raiz, remoto);
455
- if (!forja)
456
- return recusar('runtime.unavailable', (0, locale_1.textoDoCatalogo)((m) => p(m).semForja(remoto)), (0, locale_1.textoDoCatalogo)((m) => p(m).semForjaCorrecao));
509
+ const daForja = pedidosDaEntrega(carregado, remoto, opcoes);
510
+ if (!daForja.ok) {
511
+ const erro = daForja.erro;
512
+ return recusar('runtime.unavailable', (0, locale_1.textoDoCatalogo)((m) => p(m).semForja(remoto, erro ? m.forja.motivo(erro, null) : null)), (0, locale_1.textoDoCatalogo)((m) => p(m).semForjaCorrecao));
513
+ }
514
+ const pedidos = daForja.pedidos;
515
+ const noGitlab = pedidos.tipo === 'gitlab';
516
+ const rede = (m) => (noGitlab ? p(m).redeCorrecaoGitlab : p(m).redeCorrecao);
457
517
  // 9. A ponta no remoto e os PRs da branch, antes de qualquer efeito.
458
518
  const provaDoPush = `git ls-remote ${remoto} refs/heads/${f.branch}`;
459
519
  const antes = pontaNoRemoto(raiz, remoto, f.branch);
460
520
  r.passos.push(provaDoPush);
461
521
  if (antes.erro !== null) {
462
- return recusar('runtime.unavailable', (0, locale_1.textoDoCatalogo)((m) => p(m).lsRemoteFalhou(remoto, antes.erro ?? '-')), (0, locale_1.textoDoCatalogo)((m) => p(m).redeCorrecao));
522
+ return recusar('runtime.unavailable', (0, locale_1.textoDoCatalogo)((m) => p(m).lsRemoteFalhou(remoto, antes.erro ?? '-')), (0, locale_1.textoDoCatalogo)(rede));
463
523
  }
464
524
  r.remotaAntes = antes.sha;
465
525
  r.remota = antes.sha;
466
- const lidos = prsDaBranch(executor, forja, base, f.branch);
467
- r.passos.push(`gh pr list --head ${f.branch} --state all`);
526
+ const lidos = pedidos.listar(base, f.branch);
527
+ r.passos.push(pedidos.passoDaLista(f.branch));
468
528
  if (lidos.erro !== null) {
469
- return recusar('runtime.unavailable', (0, locale_1.textoDoCatalogo)((m) => p(m).prsFalharam(lidos.erro ?? '-')), (0, locale_1.textoDoCatalogo)((m) => p(m).redeCorrecao));
529
+ const erro = lidos.erro;
530
+ return recusar('runtime.unavailable', (0, locale_1.textoDoCatalogo)((m) => noGitlab ? p(m).prsFalharamGitlab(erro) : p(m).prsFalharam(erro)), (0, locale_1.textoDoCatalogo)(rede));
470
531
  }
471
532
  const aberto = lidos.prs.find((x) => x.estado === 'aberto') ?? null;
472
533
  const mesclado = lidos.prs.find((x) => x.estado === 'mesclado' && x.head === head) ?? null;
@@ -475,11 +536,11 @@ function publicarEntrega(carregado, threadId, opcoes = {}) {
475
536
  // A2 da revisao: o PR mesclado no HEAD ja e a entrega, com ou sem a branch no remoto (o GitHub pode te-la apagado).
476
537
  if (mesclado && !aberto) {
477
538
  return { ...r, acao: 'ja-publicada', pr: { numero: mesclado.numero, url: mesclado.url, criado: false, head: mesclado.head },
478
- detalhe: (0, locale_1.textoDoCatalogo)((m) => p(m).jaMesclado(mesclado.numero)), correcao: (0, locale_1.textoDoCatalogo)((m) => p(m).registreAEntrega(t.id)) };
539
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => p(m).jaMesclado(mesclado.numero, noGitlab)), correcao: (0, locale_1.textoDoCatalogo)((m) => p(m).registreAEntrega(t.id)) };
479
540
  }
480
541
  if (noRemoto && aberto) {
481
542
  return { ...r, acao: 'ja-publicada', pr: { numero: aberto.numero, url: aberto.url, criado: false, head: aberto.head },
482
- detalhe: (0, locale_1.textoDoCatalogo)((m) => p(m).jaPublicada(aberto.numero)) };
543
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => p(m).jaPublicada(aberto.numero, noGitlab)) };
483
544
  }
484
545
  // O remoto com commit que a branch local nao tem, ou que esta copia nem conhece (A3 da revisao): o push sem forca
485
546
  // seria recusado. Nunca forcar.
@@ -488,8 +549,9 @@ function publicarEntrega(carregado, threadId, opcoes = {}) {
488
549
  }
489
550
  r.corpo = corpo ? 'pr-body.md' : 'padrao';
490
551
  const titulo = tituloDoPr(t, corpo?.texto ?? null);
491
- // A5 da revisao: o corpo vai ao gh como texto, o mesmo que foi lido agora; o gh nunca reabre o arquivo.
492
- const textoDoCorpo = corpo?.texto ?? (0, locale_1.textoDoCatalogo)((m) => p(m).corpoPadrao((0, modos_1.tagDoModo)(t.modo), f.branch, curto(head), carregado.manifesto.ci.context || 'ork-verify'));
552
+ // A5 da revisao: o corpo e o texto lido agora, gravado num arquivo temporario 600 so para o `gh pr create`
553
+ // (`--body-file`); o gh nunca reabre o `pr-body.md`.
554
+ const textoDoCorpo = corpo?.texto ?? (0, locale_1.textoDoCatalogo)((m) => p(m).corpoPadrao((0, modos_1.tagDoModo)(t.modo), f.branch, curto(head), carregado.manifesto.ci.context || 'ork-verify', noGitlab));
493
555
  // B1 da revisao: o push leva o sha conferido, e nao a ref: o commit que chegue a branch depois das conferencias fica
494
556
  // fora desta publicacao.
495
557
  const refspec = `${head}:refs/heads/${f.branch}`;
@@ -497,10 +559,10 @@ function publicarEntrega(carregado, threadId, opcoes = {}) {
497
559
  const passos = [...r.passos];
498
560
  if (!noRemoto)
499
561
  passos.push(`git push -- ${remoto} ${refspec}`, provaDoPush);
500
- passos.push(aberto ? (0, locale_1.textoDoCatalogo)((m) => p(m).passoReaproveita(aberto.numero))
501
- : `gh pr create --base ${base} --head ${f.branch} --title "${titulo}" --body <${corpo ? 'pr-body.md' : 'padrao'}>`);
562
+ passos.push(aberto ? (0, locale_1.textoDoCatalogo)((m) => p(m).passoReaproveita(aberto.numero, noGitlab))
563
+ : pedidos.ensaioDaCriacao(base, f.branch, titulo, corpo ? 'pr-body.md' : 'padrao'));
502
564
  return { ...r, acao: 'publicaria', passos, pr: aberto ? { numero: aberto.numero, url: aberto.url, criado: false, head: aberto.head } : null,
503
- detalhe: (0, locale_1.textoDoCatalogo)((m) => p(m).publicaria(curto(head), aberto?.numero ?? null)) };
565
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => p(m).publicaria(curto(head), aberto?.numero ?? null, noGitlab)) };
504
566
  }
505
567
  // A evidencia de cada efeito, com a prova ou a falta dela.
506
568
  let pushFeito = false;
@@ -511,6 +573,9 @@ function publicarEntrega(carregado, threadId, opcoes = {}) {
511
573
  });
512
574
  // Efeito 1: o push sem forca do sha conferido, provado pelo ls-remote.
513
575
  if (!noRemoto) {
576
+ const conferido = opcoes.antesDoEfeito?.('push') ?? null;
577
+ if (conferido)
578
+ return recusar('policy.violation', conferido.recusa, conferido.correcao);
514
579
  const argv = ['push', '--', remoto, refspec];
515
580
  const push = (opcoes.executorGit ?? ((args, prazoMs) => git(raiz, args, prazoMs)))(argv, PRAZO_DO_PUSH_MS);
516
581
  r.passos.push(`git ${argv.join(' ')}`);
@@ -521,9 +586,9 @@ function publicarEntrega(carregado, threadId, opcoes = {}) {
521
586
  // O push que saiu com erro mas chegou (o prazo venceu depois da escrita no remoto) conta: quem decide e o ls-remote.
522
587
  pushFeito = push.ok || r.pushVerificado;
523
588
  if (!pushFeito) {
524
- const erro = deFora(push.stderr || push.stdout || `codigo ${push.code}`, 300);
589
+ const erro = (0, texto_1.deFora)(push.stderr || push.stdout || `codigo ${push.code}`, 300);
525
590
  const recusado = /rejected|non-fast-forward|fetch first|stale info|failed to update ref/i.test(erro);
526
- return recusar(recusado ? 'tree.blocked' : 'runtime.unavailable', (0, locale_1.textoDoCatalogo)((m) => p(m).pushFalhou(remoto, f.branch, erro)), (0, locale_1.textoDoCatalogo)((m) => recusado ? p(m).remotoDivergiuCorrecao(remoto, f.branch) : p(m).redeCorrecao));
591
+ return recusar(recusado ? 'tree.blocked' : 'runtime.unavailable', (0, locale_1.textoDoCatalogo)((m) => p(m).pushFalhou(remoto, f.branch, erro)), (0, locale_1.textoDoCatalogo)((m) => recusado ? p(m).remotoDivergiuCorrecao(remoto, f.branch) : rede(m)));
527
592
  }
528
593
  if (!r.pushVerificado) {
529
594
  // B1 da revisao: o push aconteceu e o remoto nao mostra o HEAD; a tentativa vai ao ledger com o que ele respondeu.
@@ -535,35 +600,41 @@ function publicarEntrega(carregado, threadId, opcoes = {}) {
535
600
  let pr = aberto ? { numero: aberto.numero, url: aberto.url, criado: false, head: aberto.head } : null;
536
601
  let erroDoPr = null;
537
602
  if (!pr) {
538
- const argv = ['pr', 'create', `--repo=${forja.host}/${forja.repositorio}`, `--base=${base}`, `--head=${f.branch}`, `--title=${titulo}`,
539
- `--body=${textoDoCorpo}`];
540
- const criado = executor(argv, PRAZO_DO_GH_MS);
541
- r.passos.push(`gh pr create --base ${base} --head ${f.branch}`);
542
- const relidos = prsDaBranch(executor, forja, base, f.branch);
543
- r.passos.push(`gh pr list --head ${f.branch} --state all (prova do PR)`);
603
+ const conferido = opcoes.antesDoEfeito?.('pr', { titulo, corpo: textoDoCorpo }) ?? null;
604
+ if (conferido) {
605
+ // O push desta chamada aconteceu: ele vai ao ledger com a prova, e o PR fica para depois (B1 da revisao).
606
+ if (pushFeito)
607
+ gravar({ pr: null, prRecusado: conferido.recusa.slice(0, 300) });
608
+ return recusar('policy.violation', conferido.recusa, conferido.correcao);
609
+ }
610
+ const criado = pedidos.abrir(base, f.branch, titulo, textoDoCorpo);
611
+ r.passos.push(pedidos.passoDaCriacao(base, f.branch));
612
+ const relidos = pedidos.listar(base, f.branch);
613
+ r.passos.push(`${pedidos.passoDaLista(f.branch)} (prova do PR)`);
544
614
  const achado = relidos.prs.find((x) => x.estado === 'aberto') ?? null;
545
615
  if (achado)
546
616
  pr = { numero: achado.numero, url: achado.url, criado: criado.status === 0, head: achado.head };
547
617
  else {
548
- erroDoPr = criado.status !== 0 ? deFora(criado.stderr || criado.stdout || `codigo ${criado.status ?? '-'}`)
549
- : relidos.erro ?? (0, locale_1.textoDoCatalogo)((m) => p(m).prSemReleitura);
618
+ erroDoPr = criado.status !== 0 ? (0, texto_1.deFora)(criado.stderr || criado.stdout || `codigo ${criado.status ?? '-'}`)
619
+ : relidos.erro ?? (0, locale_1.textoDoCatalogo)((m) => noGitlab ? p(m).prSemReleituraGitlab : p(m).prSemReleitura);
550
620
  }
551
621
  }
552
622
  r.pr = pr;
553
623
  // A evidencia: so com efeito (push ou PR novo), com a prova.
554
624
  if (pushFeito || pr?.criado || erroDoPr) {
555
625
  gravar({ pr: pr ? { numero: pr.numero, url: pr.url, criado: pr.criado, head: pr.head } : null,
556
- ...(pr ? { provaDoPr: `gh pr list --head ${f.branch} --state all` } : {}), ...(erroDoPr ? { erroDoPr } : {}) });
626
+ ...(pr ? { provaDoPr: pedidos.passoDaLista(f.branch) } : {}), ...(erroDoPr ? { erroDoPr } : {}) });
557
627
  }
558
628
  if (erroDoPr) {
559
- return recusar('runtime.unavailable', (0, locale_1.textoDoCatalogo)((m) => p(m).prFalhou(curto(head), erroDoPr ?? '-')), (0, locale_1.textoDoCatalogo)((m) => p(m).prFalhouCorrecao(t.id)));
629
+ const erro = erroDoPr;
630
+ return recusar('runtime.unavailable', (0, locale_1.textoDoCatalogo)((m) => noGitlab ? p(m).prFalhouGitlab(curto(head), erro) : p(m).prFalhou(curto(head), erro)), (0, locale_1.textoDoCatalogo)((m) => noGitlab ? p(m).prFalhouCorrecaoGitlab(t.id) : p(m).prFalhouCorrecao(t.id)));
560
631
  }
561
632
  // S7 da revisao: sem push e sem PR aberto por este processo, quem publicou foi outro; a entrega ja estava publicada.
562
633
  if (!pushFeito && !pr?.criado) {
563
- return { ...r, acao: 'ja-publicada', motivo: null, correcao: '', detalhe: (0, locale_1.textoDoCatalogo)((m) => p(m).jaPublicada(pr?.numero ?? 0)) };
634
+ return { ...r, acao: 'ja-publicada', motivo: null, correcao: '', detalhe: (0, locale_1.textoDoCatalogo)((m) => p(m).jaPublicada(pr?.numero ?? 0, noGitlab)) };
564
635
  }
565
636
  return { ...r, acao: 'publicou', motivo: null, correcao: '',
566
- detalhe: (0, locale_1.textoDoCatalogo)((m) => p(m).publicou(curto(head), pr?.numero ?? 0, pr?.criado === true)) };
637
+ detalhe: (0, locale_1.textoDoCatalogo)((m) => p(m).publicou(curto(head), pr?.numero ?? 0, pr?.criado === true, noGitlab)) };
567
638
  }
568
639
  /** As linhas da saida de texto do `ork ship publicar`, no locale ativo. */
569
640
  function linhasDaPublicacao(r) {
@@ -580,8 +651,9 @@ function linhasDaPublicacao(r) {
580
651
  linhas.push(r.pushVerificado ? p.linhaPushProvado : p.linhaPushSemProva);
581
652
  }
582
653
  }
654
+ // O MR do GitLab se reconhece pelos passos, que dizem a CLI de cada forja.
583
655
  if (r.pr)
584
- linhas.push(p.linhaPr(r.pr.numero, r.pr.criado, r.pr.url ?? ''));
656
+ linhas.push(p.linhaPr(r.pr.numero, r.pr.criado, r.pr.url ?? '', r.passos.some((x) => x.startsWith('glab '))));
585
657
  if (r.corpo)
586
658
  linhas.push(p.linhaCorpo(r.corpo));
587
659
  if (r.acao === 'recusada')
@@ -626,9 +698,62 @@ function entregaLocal(raiz, f, remotas, remoto, base) {
626
698
  const naEntrega = (passouDoCheck && f.comProduto) || (!!remota && f.comProduto) || mergeSemRegistro || entregue;
627
699
  return { remota, entregue, merge, mergeSemRegistro, naEntrega };
628
700
  }
701
+ /** Quantas branches a pista confere uma a uma no GitLab por chamada; as outras ficam "sem conferir". */
702
+ const MRS_CONFERIDOS_POR_LEITURA = 20;
703
+ /** Os MRs das branches candidatas, uma leitura por branch; a primeira que falha deixa a lista sem leitura. */
704
+ function lerMrsDasCandidatas(pedidos, base, candidatas) {
705
+ const prs = [], semConferir = [];
706
+ for (const [i, branch] of [...new Set(candidatas)].entries()) {
707
+ if (i >= MRS_CONFERIDOS_POR_LEITURA) {
708
+ semConferir.push(branch);
709
+ continue;
710
+ }
711
+ const lidos = pedidos.listar(base, branch);
712
+ if (lidos.erro !== null)
713
+ return { erro: lidos.erro };
714
+ prs.push(...lidos.prs);
715
+ }
716
+ return { prs, semConferir };
717
+ }
718
+ /**
719
+ * A etapa `ci` do MR aberto pela CI do head. O mesmo mapa do rollup do GitHub: `success` e `bloqueado` (`manual`,
720
+ * `skipped`) sao verdes, vermelho e falhou, pendente e ausente esperam, e a leitura que falhou nao e lida.
721
+ */
722
+ function etapaDaCiNoHead(ci, contexto, pr) {
723
+ const c = (m) => m.ship.publicar;
724
+ if (ci.state === 'success' || (ci.state === 'failure' && ci.bloqueado)) {
725
+ return etapa('ci', 'feita', (0, locale_1.textoDoCatalogo)((m) => c(m).ciVerde(contexto, curto(pr.head))));
726
+ }
727
+ if (ci.state === 'failure')
728
+ return etapa('ci', 'falhou', (0, locale_1.textoDoCatalogo)((m) => c(m).ciVermelho(contexto, pr.numero, true)));
729
+ if (ci.state === 'pending')
730
+ return etapa('ci', 'pendente', (0, locale_1.textoDoCatalogo)((m) => c(m).ciEsperando(contexto, pr.numero, true)));
731
+ if (ci.state === 'missing')
732
+ return etapa('ci', 'pendente', (0, locale_1.textoDoCatalogo)((m) => c(m).ciSemCheck(contexto, pr.numero, true)));
733
+ return etapa('ci', 'nao-lida', ci.detail);
734
+ }
735
+ /**
736
+ * O GitLab do remoto, quando e ele; `null` deixa a pista no caminho do GitHub de sempre. `erro` quando o remoto e do
737
+ * GitLab (pelo bloco `forja:` ou pelo host conhecido) e a forja nao resolveu: a pista diz "sem leitura", nunca "sem MR".
738
+ */
739
+ function gitlabDaPista(carregado, remoto, opcoes) {
740
+ if (opcoes.forja)
741
+ return null;
742
+ if (opcoes.forjaResolvida)
743
+ return opcoes.forjaResolvida.tipo === 'gitlab' ? opcoes.forjaResolvida : null;
744
+ // So o remoto que ja se sabe do GitLab, sem rede, passa pela resolucao aqui; o host proprio sem tipo e resolvido
745
+ // uma vez pela pista, como o pulse o resolveria, e o resto segue pelo caminho do GitHub.
746
+ if (tipoSemRede(carregado, remoto) !== 'gitlab')
747
+ return null;
748
+ const r = (0, entrega_pr_1.forjaDaEntrega)(carregado, remoto, opcoes.sondas);
749
+ if (r.ok)
750
+ return r.valor.tipo === 'gitlab' ? r.valor : null;
751
+ return r.erro ? { erro: r.erro } : null;
752
+ }
629
753
  /** O que a pista de uma thread diz, das leituras ja feitas. */
630
754
  function pistaDaThread(carregado, f, local, leitura) {
631
755
  const { t } = f;
756
+ const gl = leitura.tipo === 'gitlab';
632
757
  const raiz = carregado.raiz;
633
758
  const { remota, entregue, merge, mergeSemRegistro } = local;
634
759
  const pr = leitura.prs ? prDaBranchNaLista(leitura.prs, f.branch, f.head) : null;
@@ -666,24 +791,25 @@ function pistaDaThread(carregado, f, local, leitura) {
666
791
  conflitoEtapa = etapa('conflito', 'nao-lida', texto);
667
792
  }
668
793
  else if (!pr || pr.estado === 'fechado') {
669
- prEtapa = etapa('pr', 'pendente', pr ? (0, locale_1.textoDoCatalogo)((m) => c(m).prFechado(pr.numero)) : (0, locale_1.textoDoCatalogo)((m) => c(m).semPr));
794
+ prEtapa = etapa('pr', 'pendente', pr ? (0, locale_1.textoDoCatalogo)((m) => c(m).prFechado(pr.numero, gl)) : (0, locale_1.textoDoCatalogo)((m) => c(m).semPr));
670
795
  ciEtapa = etapa('ci', leitura.ciExigido ? 'pendente' : 'nao-se-aplica', (0, locale_1.textoDoCatalogo)((m) => leitura.ciExigido ? c(m).ciSemPr : c(m).ciNaoExigido));
671
796
  conflitoEtapa = etapa('conflito', 'nao-se-aplica', (0, locale_1.textoDoCatalogo)((m) => c(m).conflitoSemPr));
672
797
  }
673
798
  else if (pr.estado === 'mesclado') {
674
- prEtapa = etapa('pr', 'feita', (0, locale_1.textoDoCatalogo)((m) => c(m).prMesclado(pr.numero)));
799
+ prEtapa = etapa('pr', 'feita', (0, locale_1.textoDoCatalogo)((m) => c(m).prMesclado(pr.numero, gl)));
675
800
  ciEtapa = etapa('ci', 'nao-se-aplica', (0, locale_1.textoDoCatalogo)((m) => c(m).ciDoMesclado));
676
- conflitoEtapa = etapa('conflito', 'feita', (0, locale_1.textoDoCatalogo)((m) => c(m).prMesclado(pr.numero)));
801
+ conflitoEtapa = etapa('conflito', 'feita', (0, locale_1.textoDoCatalogo)((m) => c(m).prMesclado(pr.numero, gl)));
677
802
  }
678
803
  else {
679
- prEtapa = etapa('pr', 'feita', (0, locale_1.textoDoCatalogo)((m) => pr.rascunho ? c(m).prRascunho(pr.numero) : c(m).prAberto(pr.numero)));
804
+ prEtapa = etapa('pr', 'feita', (0, locale_1.textoDoCatalogo)((m) => pr.rascunho ? c(m).prRascunho(pr.numero, gl) : c(m).prAberto(pr.numero, gl)));
680
805
  const check = pr.checks.find((k) => k.nome === leitura.contexto);
681
806
  ciEtapa = !leitura.ciExigido ? etapa('ci', 'nao-se-aplica', (0, locale_1.textoDoCatalogo)((m) => c(m).ciNaoExigido))
682
- : !check ? etapa('ci', 'pendente', (0, locale_1.textoDoCatalogo)((m) => c(m).ciSemCheck(leitura.contexto, pr.numero)))
683
- : check.situacao === 'verde' ? etapa('ci', 'feita', (0, locale_1.textoDoCatalogo)((m) => c(m).ciVerde(leitura.contexto, curto(pr.head))))
684
- : check.situacao === 'vermelho' ? etapa('ci', 'falhou', (0, locale_1.textoDoCatalogo)((m) => c(m).ciVermelho(leitura.contexto, pr.numero)))
685
- : etapa('ci', 'pendente', (0, locale_1.textoDoCatalogo)((m) => c(m).ciEsperando(leitura.contexto, pr.numero)));
686
- conflitoEtapa = pr.conflito === true ? etapa('conflito', 'falhou', (0, locale_1.textoDoCatalogo)((m) => c(m).conflito(pr.numero)))
807
+ : leitura.ciDoPedido ? leitura.ciDoPedido(pr)
808
+ : !check ? etapa('ci', 'pendente', (0, locale_1.textoDoCatalogo)((m) => c(m).ciSemCheck(leitura.contexto, pr.numero, gl)))
809
+ : check.situacao === 'verde' ? etapa('ci', 'feita', (0, locale_1.textoDoCatalogo)((m) => c(m).ciVerde(leitura.contexto, curto(pr.head))))
810
+ : check.situacao === 'vermelho' ? etapa('ci', 'falhou', (0, locale_1.textoDoCatalogo)((m) => c(m).ciVermelho(leitura.contexto, pr.numero, gl)))
811
+ : etapa('ci', 'pendente', (0, locale_1.textoDoCatalogo)((m) => c(m).ciEsperando(leitura.contexto, pr.numero, gl)));
812
+ conflitoEtapa = pr.conflito === true ? etapa('conflito', 'falhou', (0, locale_1.textoDoCatalogo)((m) => c(m).conflito(pr.numero, gl)))
687
813
  : pr.conflito === false ? etapa('conflito', 'feita', (0, locale_1.textoDoCatalogo)((m) => c(m).semConflito))
688
814
  : etapa('conflito', 'nao-lida', (0, locale_1.textoDoCatalogo)((m) => c(m).conflitoNaoCalculado));
689
815
  }
@@ -715,21 +841,21 @@ function pistaDaThread(carregado, f, local, leitura) {
715
841
  else if (branchEtapa.estado === 'pendente' || (prEtapa.estado === 'pendente')) {
716
842
  proximo = publicavel
717
843
  ? { acao: 'publicar', disponivel: true, comando: `ork ship publicar ${t.id}`,
718
- texto: (0, locale_1.textoDoCatalogo)((m) => pr?.estado === 'aberto' ? c(m).proximoPublicarNoPr(pr.numero) : c(m).proximoPublicar) }
844
+ texto: (0, locale_1.textoDoCatalogo)((m) => pr?.estado === 'aberto' ? c(m).proximoPublicarNoPr(pr.numero, gl) : c(m).proximoPublicar) }
719
845
  : { acao: 'publicar', disponivel: false, texto: (0, locale_1.textoDoCatalogo)((m) => c(m).proximoDoDono(t.id, (0, modos_1.tagDoModo)(t.modo))),
720
- comando: comandoDoDono(leitura.remoto, leitura.base, f.branch, tituloDoPr(t, corpo?.texto ?? null), corpo ? path.relative(raiz, corpo.arquivo) : null) };
846
+ comando: comandoDoDono(leitura.remoto, leitura.base, f.branch, tituloDoPr(t, corpo?.texto ?? null), corpo ? path.relative(raiz, corpo.arquivo) : null, leitura.tipo) };
721
847
  }
722
848
  else if (prEtapa.estado === 'nao-lida')
723
849
  proximo = nada(prEtapa.texto, `ork ship pista ${t.id}`);
724
850
  else if (conflitoEtapa.estado === 'falhou')
725
- proximo = nada((0, locale_1.textoDoCatalogo)((m) => c(m).proximoConflito(pr?.numero ?? 0)));
851
+ proximo = nada((0, locale_1.textoDoCatalogo)((m) => c(m).proximoConflito(pr?.numero ?? 0, gl)));
726
852
  else if (ciEtapa.estado === 'falhou')
727
- proximo = nada((0, locale_1.textoDoCatalogo)((m) => c(m).proximoCiVermelho(leitura.contexto, pr?.numero ?? 0)));
853
+ proximo = nada((0, locale_1.textoDoCatalogo)((m) => c(m).proximoCiVermelho(leitura.contexto, pr?.numero ?? 0, gl)));
728
854
  else if (ciEtapa.estado === 'pendente' || ciEtapa.estado === 'nao-lida') {
729
- proximo = nada((0, locale_1.textoDoCatalogo)((m) => c(m).proximoEsperandoCi(leitura.contexto, pr?.numero ?? 0)), pr ? `ork ci status --sha ${pr.head}` : null);
855
+ proximo = nada((0, locale_1.textoDoCatalogo)((m) => c(m).proximoEsperandoCi(leitura.contexto, pr?.numero ?? 0, gl)), pr ? `ork ci status --sha ${pr.head}` : null);
730
856
  }
731
857
  else
732
- proximo = nada((0, locale_1.textoDoCatalogo)((m) => pr?.rascunho ? c(m).proximoRascunho(pr.numero) : c(m).proximoMerge(pr?.numero ?? 0)));
858
+ proximo = nada((0, locale_1.textoDoCatalogo)((m) => pr?.rascunho ? c(m).proximoRascunho(pr.numero, gl) : c(m).proximoMerge(pr?.numero ?? 0, gl)));
733
859
  return {
734
860
  thread: t.id, nome: t.nome, modo: t.modo, tag: (0, modos_1.tagDoModo)(t.modo), publicavel, conduzida: !!f.conducao, branch: f.branch, head: f.head,
735
861
  remota, pr: pr ? { numero: pr.numero, url: pr.url, estado: pr.estado, rascunho: pr.rascunho, head: pr.head } : null,
@@ -771,18 +897,63 @@ function pistaDeEntrega(carregado, opcoes = {}) {
771
897
  let prsNaoLidos = null;
772
898
  let parcial = false;
773
899
  let semConferir = new Set();
900
+ let ciDoPedido;
901
+ let prsNaoLidosDoGitlab = false;
902
+ let doHostProprio;
774
903
  if (candidatas.length) {
775
- const leitura = (0, parado_no_condutor_1.lerPrsDaForja)(carregado, { quando: lidoEm, executor: opcoes.executorGh, remoto, candidatas, forja: opcoes.forja });
776
- if (leitura.ok) {
777
- prs = leitura.retrato.prs;
778
- parcial = leitura.retrato.parcial;
779
- semConferir = new Set(leitura.retrato.semConferir ?? []);
904
+ let gitlab = gitlabDaPista(carregado, remoto, opcoes);
905
+ // Host proprio sem o bloco `forja:` (um GitLab como o de um piloto, ou um GitHub Enterprise): a forja e resolvida uma
906
+ // vez, como o pulse a resolve, e a leitura segue pela forja certa, com o mesmo criterio do gate no GitLab.
907
+ let naoResolvida = null;
908
+ if (!gitlab && !opcoes.forja && !opcoes.forjaResolvida && tipoSemRede(carregado, remoto) === null) {
909
+ const lido = (0, parado_no_condutor_1.forjaDoRemotoDoPulse)(carregado, remoto, { executor: opcoes.executorGh, sondas: opcoes.sondas });
910
+ if (!lido.ok)
911
+ naoResolvida = lido.erro;
912
+ else if (lido.forja.tipo === 'gitlab')
913
+ gitlab = lido.forja;
914
+ else
915
+ doHostProprio = lido.forja;
780
916
  }
781
- else {
917
+ if (naoResolvida !== null) {
782
918
  prs = null;
783
- prsNaoLidos = deFora(leitura.erro);
919
+ prsNaoLidos = (0, texto_1.deFora)(naoResolvida);
920
+ }
921
+ else if (gitlab && 'erro' in gitlab) {
922
+ prs = null;
923
+ prsNaoLidos = (0, locale_1.textoDoCatalogo)((m) => m.forja.motivo(gitlab.erro, 'gitlab'));
924
+ prsNaoLidosDoGitlab = true;
925
+ }
926
+ else if (gitlab) {
927
+ const lidos = lerMrsDasCandidatas(pedidosDoGitlab(gitlab, opcoes.api ?? {}), base, candidatas);
928
+ if ('erro' in lidos) {
929
+ prs = null;
930
+ prsNaoLidos = (0, texto_1.deFora)(lidos.erro);
931
+ }
932
+ else {
933
+ prs = lidos.prs;
934
+ semConferir = new Set(lidos.semConferir);
935
+ }
936
+ const ciDoHead = opcoes.ciDoHead ?? ((sha) => (0, ci_1.consultarCi)(carregado, sha, remoto, undefined, undefined, opcoes.sondas, opcoes.api));
937
+ ciDoPedido = (pr) => etapaDaCiNoHead(ciDoHead(pr.head), contexto, pr);
938
+ }
939
+ else {
940
+ const fixada = opcoes.forja ?? (opcoes.forjaResolvida?.tipo === 'github'
941
+ ? { host: (0, cli_1.hostDaApi)(opcoes.forjaResolvida), repositorio: opcoes.forjaResolvida.repo } : undefined);
942
+ const leitura = (0, parado_no_condutor_1.lerPrsDaForja)(carregado, { quando: lidoEm, executor: opcoes.executorGh, remoto, candidatas, forja: fixada,
943
+ resolvida: doHostProprio, sondas: opcoes.sondas });
944
+ if (leitura.ok) {
945
+ prs = leitura.retrato.prs;
946
+ parcial = leitura.retrato.parcial;
947
+ semConferir = new Set(leitura.retrato.semConferir ?? []);
948
+ }
949
+ else {
950
+ prs = null;
951
+ prsNaoLidos = (0, texto_1.deFora)(leitura.erro);
952
+ }
784
953
  }
785
954
  }
955
+ const tipo = ciDoPedido || prsNaoLidosDoGitlab ? 'gitlab' : doHostProprio ? 'github'
956
+ : tipoSemRede(carregado, remoto, opcoes.forja ? 'github' : opcoes.forjaResolvida?.tipo);
786
957
  // S8 da revisao (rodada 2): a candidata sem nenhum PR na leitura foi conferida uma a uma pelo `--head`, que a lista
787
958
  // cortada nao limita; so a que nao foi conferida, ou que so tem PR achado na lista cortada, fica em duvida.
788
959
  const comPrNaLeitura = new Set((prs ?? []).map((x) => x.branch));
@@ -791,7 +962,7 @@ function pistaDeEntrega(carregado, opcoes = {}) {
791
962
  : parcial && !conferida(branch) ? 'parcial' : null);
792
963
  const pistas = fatos.flatMap((f) => {
793
964
  const local = locais.get(f.t.id);
794
- const x = local ? pistaDaThread(carregado, f, local, { remoto, base, remotasLidas: remotas !== null, prs, prsNaoLidos, corte, ciExigido, contexto })
965
+ const x = local ? pistaDaThread(carregado, f, local, { remoto, base, remotasLidas: remotas !== null, prs, prsNaoLidos, corte, ciExigido, contexto, tipo, ciDoPedido })
795
966
  : null;
796
967
  return x ? [x] : [];
797
968
  });