@orkastery/cli 0.2.0 → 0.3.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 (242) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +86 -65
  3. package/adapters/README.md +30 -15
  4. package/adapters/claude-code/.claude-plugin/plugin.json +11 -5
  5. package/adapters/claude-code/README.md +110 -8
  6. package/adapters/claude-code/commands/onboarding.md +21 -0
  7. package/adapters/claude-code/commands/ork.md +99 -27
  8. package/adapters/claude-code/hooks/hooks.json +6 -1
  9. package/adapters/claude-code/hooks/ork-sensor.js +66 -0
  10. package/adapters/codex/skills/ork/SKILL.md +57 -0
  11. package/adapters/hermes/README.md +163 -0
  12. package/adapters/hermes/bin/ork-abrir-thread.sh +2 -0
  13. package/adapters/hermes/bin/ork-brain.sh +4 -0
  14. package/adapters/hermes/bin/ork-hitl-answer.py +82 -0
  15. package/adapters/hermes/bin/ork-maestro.sh +6 -0
  16. package/adapters/hermes/bin/ork-master-enviar.py +84 -0
  17. package/adapters/hermes/bin/ork-objective-message.sh +17 -0
  18. package/adapters/hermes/bin/ork-objective-status.sh +12 -0
  19. package/adapters/hermes/bin/ork-pulse-enviar.py +47 -0
  20. package/adapters/hermes/hermes.plugin.json +26 -4
  21. package/adapters/hermes/hitl-ingress/__init__.py +356 -0
  22. package/adapters/hermes/hitl-ingress/plugin.yaml +4 -0
  23. package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +75 -22
  24. package/adapters/openclaw/README.md +135 -26
  25. package/adapters/openclaw/bin/ork-brain.sh +4 -0
  26. package/adapters/openclaw/construir.sh +19 -0
  27. package/adapters/openclaw/dist/hitl-ingress.js +199 -0
  28. package/adapters/openclaw/dist/index.js +437 -0
  29. package/adapters/openclaw/openclaw.plugin.json +39 -134
  30. package/adapters/openclaw/package.json +26 -0
  31. package/adapters/openclaw/src/hitl-ingress.ts +180 -0
  32. package/adapters/openclaw/src/index.ts +458 -0
  33. package/adapters/openclaw/src/tipos-openclaw.d.ts +58 -0
  34. package/adapters/openclaw/tsconfig.json +15 -0
  35. package/assets/docs/markdownlint-cli2.jsonc +22 -0
  36. package/assets/docs/padroes/documentacao-de-produto.md +133 -0
  37. package/assets/docs/padroes/roadmap-de-produto.md +98 -0
  38. package/assets/docs/produto/README.md +14 -0
  39. package/assets/docs/produto/_modelo-feature.md +59 -0
  40. package/assets/docs/roadmap/README.md +14 -0
  41. package/assets/docs/roadmap/_modelo-item.md +73 -0
  42. package/assets/orkmind-native-schema.json +32 -0
  43. package/assets/orkmind_bridge.py +357 -0
  44. package/assets/orkmind_fixture.py +67 -0
  45. package/assets/orkmind_prospective.py +138 -0
  46. package/assets/reference-tariffs-i07.json +23 -0
  47. package/dist/adapters/claude-bg.js +488 -39
  48. package/dist/adapters/codex-controller-sensor.js +449 -0
  49. package/dist/adapters/codex-controller-worker.js +361 -0
  50. package/dist/adapters/codex-controller.js +252 -0
  51. package/dist/adapters/codex-events.js +205 -0
  52. package/dist/adapters/codex-question.js +26 -0
  53. package/dist/adapters/codex-runner.js +133 -0
  54. package/dist/adapters/codex.js +394 -0
  55. package/dist/agents-md.js +84 -0
  56. package/dist/auditoria.js +11 -8
  57. package/dist/auditrun.js +5 -4
  58. package/dist/board.js +173 -22
  59. package/dist/branch-de-estado.js +136 -0
  60. package/dist/canarios-hitl.js +177 -0
  61. package/dist/canarios-i43.js +543 -0
  62. package/dist/canarios-pulse.js +147 -0
  63. package/dist/canarios-sensores.js +129 -0
  64. package/dist/canarios.js +111 -2
  65. package/dist/catalogo.js +9 -0
  66. package/dist/ci.js +216 -0
  67. package/dist/ciclos.js +2 -1
  68. package/dist/claim-lint.js +64 -0
  69. package/dist/claims.js +60 -0
  70. package/dist/company-brain-capture.js +195 -0
  71. package/dist/company-brain-cli.js +123 -0
  72. package/dist/company-brain-client.js +61 -0
  73. package/dist/company-brain-contract.js +166 -0
  74. package/dist/company-brain-journal.js +192 -0
  75. package/dist/company-brain-mcp.js +33 -0
  76. package/dist/company-brain-migration.js +60 -0
  77. package/dist/company-brain-source.js +177 -0
  78. package/dist/company-brain-worker.js +18 -0
  79. package/dist/conducao-texto.js +61 -0
  80. package/dist/conducao.js +876 -0
  81. package/dist/contrato-publico.js +39 -0
  82. package/dist/creation-operation-store.js +251 -0
  83. package/dist/creation-operation.js +148 -0
  84. package/dist/decisao-autonoma.js +183 -0
  85. package/dist/delegation.js +79 -0
  86. package/dist/demo.js +120 -0
  87. package/dist/docs.js +828 -0
  88. package/dist/doctor.js +183 -24
  89. package/dist/entrega-pr.js +117 -0
  90. package/dist/escopo-escrita.js +71 -0
  91. package/dist/estado-thread.js +222 -0
  92. package/dist/evalrunner.js +12 -0
  93. package/dist/fabrica-estado.js +329 -0
  94. package/dist/fabrica-publicar.js +76 -0
  95. package/dist/fix.js +21 -0
  96. package/dist/gates.js +55 -9
  97. package/dist/handoff.js +39 -23
  98. package/dist/hitl-canais.js +333 -0
  99. package/dist/hitl-classificacao.js +131 -0
  100. package/dist/hitl-contract.js +465 -0
  101. package/dist/hitl-estado.js +136 -0
  102. package/dist/hitl-gates.js +554 -0
  103. package/dist/hitl-ingress-receipt.js +382 -0
  104. package/dist/hitl-local-atestado.js +57 -0
  105. package/dist/hitl-local-receipt.js +328 -0
  106. package/dist/hitl-local.js +143 -0
  107. package/dist/hitl-lock.js +139 -0
  108. package/dist/hitl-lote.js +223 -0
  109. package/dist/hitl-native-offer.js +97 -0
  110. package/dist/hitl-native.js +65 -0
  111. package/dist/hitl-presentation.js +209 -0
  112. package/dist/hitl-public-receipt.js +176 -0
  113. package/dist/hitl-resumo.js +209 -0
  114. package/dist/hitl-sessions.js +475 -0
  115. package/dist/hitl.js +711 -0
  116. package/dist/horario.js +269 -0
  117. package/dist/hosts.js +198 -22
  118. package/dist/index.js +1736 -93
  119. package/dist/indice.js +99 -0
  120. package/dist/init.js +28 -3
  121. package/dist/integracoes-locais.js +17 -0
  122. package/dist/leases.js +65 -21
  123. package/dist/ledger-stats.js +272 -0
  124. package/dist/ledger.js +107 -2
  125. package/dist/licoes.js +215 -0
  126. package/dist/liveness.js +218 -0
  127. package/dist/maestro-actions.js +51 -0
  128. package/dist/maestro-authority.js +152 -0
  129. package/dist/maestro-cli.js +97 -0
  130. package/dist/maestro-contract.js +55 -0
  131. package/dist/maestro-discovery.js +132 -0
  132. package/dist/maestro-runtime.js +268 -0
  133. package/dist/maestro-snapshot.js +86 -0
  134. package/dist/maestro-sources.js +224 -0
  135. package/dist/manifest.js +165 -6
  136. package/dist/maquina.js +102 -0
  137. package/dist/master-audit.js +101 -0
  138. package/dist/master-batch.js +43 -0
  139. package/dist/master-digest.js +149 -0
  140. package/dist/master-migracao.js +155 -0
  141. package/dist/master.js +361 -77
  142. package/dist/mcp-artifacts.js +234 -0
  143. package/dist/mcp-git.js +433 -0
  144. package/dist/mcp-install.js +310 -0
  145. package/dist/mcp-maestro.js +25 -0
  146. package/dist/mcp-server.js +469 -0
  147. package/dist/mcp-ship.js +436 -0
  148. package/dist/mcp-verify.js +173 -0
  149. package/dist/memoria-humana.js +207 -0
  150. package/dist/memoria.js +314 -78
  151. package/dist/memory-migration.js +279 -0
  152. package/dist/memory-prospective.js +148 -0
  153. package/dist/modos-migracao.js +191 -0
  154. package/dist/modos.js +151 -15
  155. package/dist/monitor-lock.js +110 -0
  156. package/dist/objective.js +449 -0
  157. package/dist/ocupacao.js +267 -0
  158. package/dist/onboarding.js +303 -0
  159. package/dist/orkmind.js +389 -90
  160. package/dist/orquestracao.js +96 -69
  161. package/dist/phase.js +596 -150
  162. package/dist/playbook-capabilities.js +150 -0
  163. package/dist/playbook-contracts.js +188 -0
  164. package/dist/portfolio-context.js +61 -0
  165. package/dist/portfolio.js +180 -0
  166. package/dist/preflight.js +207 -0
  167. package/dist/process-audit.js +112 -0
  168. package/dist/project-state.js +93 -0
  169. package/dist/prompts.js +25 -5
  170. package/dist/prova-minima.js +112 -0
  171. package/dist/pulse-cadencia.js +163 -0
  172. package/dist/pulse-consentimento.js +260 -0
  173. package/dist/pulse-delivery.js +323 -0
  174. package/dist/pulse-resposta.js +542 -0
  175. package/dist/pulse.js +262 -0
  176. package/dist/ratelimit.js +35 -2
  177. package/dist/recall.js +80 -3
  178. package/dist/redacao-saida.js +45 -0
  179. package/dist/redacao-url.js +66 -0
  180. package/dist/retry.js +637 -115
  181. package/dist/roadmap-reservas.js +243 -0
  182. package/dist/runtime-ambiente.js +38 -0
  183. package/dist/runtime-context.js +215 -0
  184. package/dist/runtime-profiles.js +869 -0
  185. package/dist/runtimes.js +103 -0
  186. package/dist/sandbox.js +9 -0
  187. package/dist/session-events.js +203 -0
  188. package/dist/session-watcher-claude.js +637 -0
  189. package/dist/session-watcher.js +683 -0
  190. package/dist/sessoes-adopt.js +154 -0
  191. package/dist/sessoes-inventario.js +159 -0
  192. package/dist/sessoes.js +16 -35
  193. package/dist/setup.js +691 -0
  194. package/dist/ship.js +150 -15
  195. package/dist/slug.js +1 -1
  196. package/dist/thread-close.js +115 -0
  197. package/dist/thread.js +142 -28
  198. package/dist/tokens.js +1 -1
  199. package/dist/util.js +4 -2
  200. package/dist/verify-sandbox.js +265 -0
  201. package/dist/verify.js +270 -25
  202. package/dist/versao.js +60 -0
  203. package/dist/worktree.js +31 -2
  204. package/dist/write-activation.js +291 -0
  205. package/dist/yaml.js +2 -0
  206. package/eval/casos/onboarding.json +102 -0
  207. package/eval/casos/orkastery-bootstrap.json +35 -1
  208. package/eval/casos/scope-check-capability-map.json +45 -7
  209. package/eval/casos/ship-release.json +2 -2
  210. package/eval/fixtures/b0-slug-e-modos/caso.json +35 -22
  211. package/eval/fixtures/b2-master-log/caso.json +1 -1
  212. package/eval/fixtures/fx-adapter-editado-detectado/caso.json +19 -0
  213. package/eval/fixtures/fx-auto-quiet/caso.json +11 -0
  214. package/eval/fixtures/fx-blanket-approve/caso.json +10 -0
  215. package/eval/fixtures/fx-check-runtime-cruzado/caso.json +20 -0
  216. package/eval/fixtures/fx-codex-dry/caso.json +18 -0
  217. package/eval/fixtures/fx-donewhen-executavel/caso.json +15 -0
  218. package/eval/fixtures/fx-estado-dividido/caso.json +15 -0
  219. package/eval/fixtures/fx-fase-orfa/caso.json +116 -0
  220. package/eval/fixtures/fx-happy/caso.json +6 -4
  221. package/eval/fixtures/fx-hitl-latency/caso.json +20 -0
  222. package/eval/fixtures/fx-indice-reversao/caso.json +25 -0
  223. package/eval/fixtures/fx-listagem-abertas/caso.json +16 -0
  224. package/eval/fixtures/fx-maestro-bootstrap/caso.json +21 -0
  225. package/eval/fixtures/fx-modo-aposentado-escritor/caso.json +21 -0
  226. package/eval/fixtures/fx-modo-aposentado-leitor/caso.json +16 -0
  227. package/eval/fixtures/fx-objective-oscillation/caso.json +14 -0
  228. package/eval/fixtures/fx-omnicanal/caso.json +17 -0
  229. package/eval/fixtures/fx-sensores-runtime/caso.json +17 -0
  230. package/monitor/company-brain.cjs +17 -0
  231. package/monitor/pulse-scope.cjs +45 -0
  232. package/monitor/pulse.cron +18 -0
  233. package/monitor/varredura-pulse.sh +27 -0
  234. package/package.json +25 -4
  235. package/schemas/claims.schema.json +25 -0
  236. package/schemas/company-brain.schema.json +1158 -0
  237. package/schemas/creation-operation.schema.json +365 -0
  238. package/schemas/maestro-snapshot.schema.json +2716 -0
  239. package/skills/core/onboarding/SKILL.md +50 -0
  240. package/skills/core/orkastery-bootstrap/SKILL.md +95 -65
  241. package/skills/core/thread-state/SKILL.md +3 -1
  242. package/skills/governance/scope-check-capability-map/SKILL.md +17 -7
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ /**
3
+ * Registro dos runtimes de despacho homologados.
4
+ *
5
+ * O nucleo despacha fase por um runtime adapter resolvido POR NOME, e este arquivo e o
6
+ * domicilio unico dessa resolucao (decisao D1 da thread ork-homologarcod). Dois runtimes
7
+ * homologados:
8
+ *
9
+ * claude-bg o PADRAO, mais maduro: `claude --bg`, sessao visivel no app e em
10
+ * `claude agents --json` (homologado em 02/09/2026).
11
+ * codex o segundo runtime: `codex exec` headless desanexado, sessao verificada no
12
+ * rollout que o proprio Codex grava (homologado em 06/09/2026).
13
+ *
14
+ * Paridade sem downgrade: o contrato do claude-bg nao muda com a chegada do codex, e todo
15
+ * runtime novo entra por aqui com o MESMO contrato de despacho (dry-run, rate limit
16
+ * reconhecido, re-verificacao externa, nunca self-report).
17
+ */
18
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ var desc = Object.getOwnPropertyDescriptor(m, k);
21
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
22
+ desc = { enumerable: true, get: function() { return m[k]; } };
23
+ }
24
+ Object.defineProperty(o, k2, desc);
25
+ }) : (function(o, m, k, k2) {
26
+ if (k2 === undefined) k2 = k;
27
+ o[k2] = m[k];
28
+ }));
29
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
30
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
31
+ }) : function(o, v) {
32
+ o["default"] = v;
33
+ });
34
+ var __importStar = (this && this.__importStar) || (function () {
35
+ var ownKeys = function(o) {
36
+ ownKeys = Object.getOwnPropertyNames || function (o) {
37
+ var ar = [];
38
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
39
+ return ar;
40
+ };
41
+ return ownKeys(o);
42
+ };
43
+ return function (mod) {
44
+ if (mod && mod.__esModule) return mod;
45
+ var result = {};
46
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
47
+ __setModuleDefault(result, mod);
48
+ return result;
49
+ };
50
+ })();
51
+ Object.defineProperty(exports, "__esModule", { value: true });
52
+ exports.ORDEM_DOS_RUNTIMES = exports.RUNTIMES = exports.RUNTIME_PADRAO = void 0;
53
+ exports.runtimeConhecido = runtimeConhecido;
54
+ exports.resolverRuntime = resolverRuntime;
55
+ const claudeBg = __importStar(require("./adapters/claude-bg"));
56
+ const codex = __importStar(require("./adapters/codex"));
57
+ const hitl_ingress_receipt_1 = require("./hitl-ingress-receipt");
58
+ exports.RUNTIME_PADRAO = 'claude-bg';
59
+ /** Phase e retry atravessam o mesmo preparo, antes de retirar segredos do filho. */
60
+ function comRecibosPublicos(p, dispatch) {
61
+ if (!p.dryRun && p.vinculo) {
62
+ try {
63
+ (0, hitl_ingress_receipt_1.prepararRecibosParaDespacho)(p.contextoRuntime?.projeto ?? p.cwd, p.vinculo.thread);
64
+ }
65
+ catch {
66
+ return { ok: false, comando: [], sessionId: null, verificada: false,
67
+ stdout: '', stderr: '', erro: 'hitl.receipt.prepare-unavailable: despacho não iniciado' };
68
+ }
69
+ }
70
+ return dispatch(p);
71
+ }
72
+ exports.RUNTIMES = {
73
+ 'claude-bg': {
74
+ nome: claudeBg.NOME_ADAPTER,
75
+ fonteVerificacao: 'claude agents --json',
76
+ disponivel: claudeBg.disponivel,
77
+ versao: claudeBg.versao,
78
+ montarComando: (p) => claudeBg.montarComando(p),
79
+ despachar: (p) => comRecibosPublicos(p, claudeBg.despachar),
80
+ },
81
+ codex: {
82
+ nome: codex.NOME_ADAPTER,
83
+ fonteVerificacao: 'rollout do codex em $CODEX_HOME/sessions',
84
+ disponivel: codex.disponivel,
85
+ versao: codex.versao,
86
+ montarComando: (p) => codex.montarComando(p),
87
+ despachar: (p) => comRecibosPublicos(p, codex.despachar),
88
+ },
89
+ };
90
+ /** Os runtimes na ordem de maturidade (o padrao primeiro). */
91
+ exports.ORDEM_DOS_RUNTIMES = ['claude-bg', 'codex'];
92
+ /** O nome e de um runtime homologado? */
93
+ function runtimeConhecido(nome) {
94
+ return Object.prototype.hasOwnProperty.call(exports.RUNTIMES, nome);
95
+ }
96
+ /** Resolve o adapter pelo nome, com erro tipado quando o runtime nao existe. */
97
+ function resolverRuntime(nome) {
98
+ const adapter = exports.RUNTIMES[nome];
99
+ if (!adapter) {
100
+ throw new Error(`runtime de despacho desconhecido: "${nome}" (homologados: ${exports.ORDEM_DOS_RUNTIMES.join(', ')})`);
101
+ }
102
+ return adapter;
103
+ }
package/dist/sandbox.js CHANGED
@@ -79,6 +79,15 @@ function commitar(dir, arquivo, conteudo, mensagem) {
79
79
  * proprio manifesto testa o canario, nao o produto.
80
80
  */
81
81
  function sandboxGit(nome, abbrev = 'evl') {
82
+ // I-49: canario nunca escreve no registro compartilhado de contas do usuario.
83
+ if (!process.env.ORK_CONTAS_DIR) {
84
+ process.env.ORK_CONTAS_DIR = path.join(fs.mkdtempSync(path.join(os.tmpdir(), 'ork-contas-eval-')), 'private');
85
+ }
86
+ // I-51: canario nunca publica o estado da fabrica.
87
+ if (process.env.ORK_FABRICA_PUBLICAR === undefined)
88
+ process.env.ORK_FABRICA_PUBLICAR = '0';
89
+ if (!process.env.ORK_USUARIO_DIR)
90
+ process.env.ORK_USUARIO_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'ork-usuario-eval-'));
82
91
  const dir = dirTemporario(nome);
83
92
  (0, util_1.exec)('git', ['init', '-b', 'main'], dir);
84
93
  (0, util_1.exec)('git', ['config', 'user.email', 'eval@orkastery.local'], dir);
@@ -0,0 +1,203 @@
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.TIPOS_SENSOR = exports.LIMITE_EVENTO_BYTES = void 0;
37
+ exports.exigirSessaoDespachada = exigirSessaoDespachada;
38
+ exports.resolverSessao = resolverSessao;
39
+ exports.comLockDeSessao = comLockDeSessao;
40
+ exports.ingerirEvento = ingerirEvento;
41
+ exports.lerPayloadSensor = lerPayloadSensor;
42
+ /** D3: o runtime observa; identidade e envelope pertencem ao ork. */
43
+ const fs = __importStar(require("node:fs"));
44
+ const path = __importStar(require("node:path"));
45
+ const node_crypto_1 = require("node:crypto");
46
+ const thread_1 = require("./thread");
47
+ const estado_thread_1 = require("./estado-thread");
48
+ const ledger_1 = require("./ledger");
49
+ exports.LIMITE_EVENTO_BYTES = 16384;
50
+ exports.TIPOS_SENSOR = ['permission_prompt', 'permission_request', 'notification',
51
+ 'stop', 'subagent_stop', 'commit', 'heartbeat', 'resumed'];
52
+ /**
53
+ * A adoção governa a identidade de uma sessão que já estava rodando e, por decisão da
54
+ * higiene de runtimes, não inventa data de despacho nem prompt executado. O sensor ancora
55
+ * no instante do despacho o dedupe do evento, o cursor por fonte e a recusa de evento
56
+ * anterior ao início, então a sessão adotada é recusada com correção acionável em vez de
57
+ * receber uma âncora fabricada a partir da adoção.
58
+ */
59
+ function exigirSessaoDespachada(sessao, sessionId) {
60
+ if (sessao.origem === 'adocao' || typeof sessao.despachadaEm !== 'string') {
61
+ throw new Error(`sessão ${sessionId} foi adotada, não despachada; os sensores exigem o instante do ` +
62
+ 'despacho: despache a fase com ork phase run para observá-la');
63
+ }
64
+ return sessao;
65
+ }
66
+ function resolverSessao(raiz, sessionId) {
67
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,127}$/.test(sessionId))
68
+ throw new Error('sessionId inválido');
69
+ const achadas = (0, thread_1.listarIds)(raiz).flatMap(id => {
70
+ const thread = (0, thread_1.lerThread)(raiz, id);
71
+ return thread.sessoes.filter(s => s.sessionId === sessionId).map(sessao => ({ thread, sessao }));
72
+ });
73
+ if (achadas.length !== 1)
74
+ throw new Error(`sessão ${achadas.length ? 'ambígua' : 'desconhecida'}; confira ork thread status`);
75
+ const achada = achadas[0];
76
+ if (achada.thread.worktree) {
77
+ const estado = (0, estado_thread_1.auditarEstado)(raiz, achada.thread.id, achada.thread.worktree);
78
+ if (estado.nivel !== 'ok')
79
+ throw new Error(estado.detalhe);
80
+ }
81
+ return achada;
82
+ }
83
+ function validarPayload(bruto, tipo, agoraMs) {
84
+ if (Buffer.byteLength(bruto) > exports.LIMITE_EVENTO_BYTES)
85
+ throw new Error('payload excede 16384 bytes');
86
+ const p = JSON.parse(bruto.trim() || '{}');
87
+ if (!p || typeof p !== 'object' || Array.isArray(p))
88
+ throw new Error('payload deve ser objeto JSON');
89
+ const campos = ['observedAt', 'eventId', 'notificationType', 'commit'];
90
+ for (const [k, v] of Object.entries(p)) {
91
+ if (!campos.includes(k) || typeof v !== 'string')
92
+ throw new Error(`campo de payload inválido: ${k}`);
93
+ }
94
+ const payload = p;
95
+ if (payload.observedAt !== undefined && (!/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{3}Z$/.test(payload.observedAt) ||
96
+ !Number.isFinite(Date.parse(payload.observedAt)) || new Date(payload.observedAt).toISOString() !== payload.observedAt ||
97
+ Date.parse(payload.observedAt) > agoraMs))
98
+ throw new Error('observedAt inválido ou futuro');
99
+ if (payload.eventId !== undefined && !/^[a-zA-Z0-9._:-]{1,160}$/.test(payload.eventId))
100
+ throw new Error('eventId inválido');
101
+ if (payload.notificationType !== undefined && !['permission_prompt', 'idle_prompt', 'auth_success', 'elicitation_dialog'].includes(payload.notificationType)) {
102
+ throw new Error('notificationType inválido');
103
+ }
104
+ if ((tipo === 'commit' && !payload.commit) || (payload.commit !== undefined &&
105
+ (tipo !== 'commit' || !/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(payload.commit))))
106
+ throw new Error('commit exige SHA completo');
107
+ return payload;
108
+ }
109
+ /** Mesmo lock do carimbo HITL: pulse e hook não criam dois episódios concorrentes. */
110
+ function comLockDeSessao(dir, executar) {
111
+ const lock = path.join(dir, 'ledger.jsonl.hitl-lock');
112
+ const dono = path.join(lock, 'pid');
113
+ try {
114
+ fs.mkdirSync(lock);
115
+ }
116
+ catch (e) {
117
+ if (e.code !== 'EEXIST')
118
+ throw e;
119
+ const pid = fs.existsSync(dono) ? Number(fs.readFileSync(dono, 'utf8')) : null;
120
+ if (pid !== null) {
121
+ if (!Number.isInteger(pid) || pid <= 0)
122
+ throw new Error('lock de sessão inválido');
123
+ try {
124
+ process.kill(pid, 0);
125
+ throw new Error('ingestão ocupada; tente novamente');
126
+ }
127
+ catch (erro) {
128
+ if (erro.code !== 'ESRCH')
129
+ throw erro;
130
+ }
131
+ }
132
+ else if (Date.now() - fs.statSync(lock).mtimeMs < 60000)
133
+ throw new Error('ingestão ocupada; tente novamente');
134
+ fs.rmSync(dono, { force: true });
135
+ fs.rmdirSync(lock);
136
+ fs.mkdirSync(lock);
137
+ }
138
+ fs.writeFileSync(dono, String(process.pid), { flag: 'wx', mode: 0o600 });
139
+ try {
140
+ return executar();
141
+ }
142
+ finally {
143
+ if (fs.readFileSync(dono, 'utf8') === String(process.pid)) {
144
+ fs.unlinkSync(dono);
145
+ fs.rmdirSync(lock);
146
+ }
147
+ }
148
+ }
149
+ function ingerirEvento(raiz, sessionId, tipoBruto, bruto = '{}', agoraMs = Date.now()) {
150
+ if (!exports.TIPOS_SENSOR.includes(tipoBruto))
151
+ throw new Error(`tipo inválido; use ${exports.TIPOS_SENSOR.join(', ')}`);
152
+ const tipo = tipoBruto;
153
+ const payload = validarPayload(bruto, tipo, agoraMs);
154
+ const { thread, sessao: registrada } = resolverSessao(raiz, sessionId);
155
+ const sessao = exigirSessaoDespachada(registrada, sessionId);
156
+ const observedAt = payload.observedAt ?? new Date(agoraMs).toISOString();
157
+ if (Date.parse(observedAt) < Date.parse(sessao.despachadaEm))
158
+ throw new Error('evento anterior ao despacho');
159
+ const dir = (0, thread_1.dirThread)(raiz, thread.id);
160
+ const bloqueio = tipo === 'permission_prompt' || tipo === 'permission_request' ||
161
+ (tipo === 'notification' && payload.notificationType === 'permission_prompt');
162
+ const retomada = tipo === 'resumed' || tipo === 'heartbeat' || tipo === 'commit';
163
+ const eventoTipo = bloqueio ? 'sessao_bloqueada' : tipo === 'stop' ? 'runtime_stop' :
164
+ tipo === 'subagent_stop' ? 'runtime_subagent_stop' : tipo === 'commit' ? 'commit' : 'runtime_event';
165
+ const identidade = payload.eventId ?? payload.commit ?? { ...payload, observedAt };
166
+ const eventId = (0, node_crypto_1.createHash)('sha256').update(JSON.stringify([sessionId, sessao.despachadaEm, tipo, identidade])).digest('hex');
167
+ return comLockDeSessao(dir, () => {
168
+ const eventos = (0, ledger_1.lerLedger)(dir);
169
+ if (eventos.some(e => e.sensorEventId === eventId))
170
+ return { gravado: false, thread: thread.id, tipo: eventoTipo, observedAt };
171
+ const ultimo = eventos.filter(e => e.sessionId === sessionId &&
172
+ ['sessao_bloqueada', 'sessao_destravada'].includes(e.tipo)).at(-1);
173
+ if (bloqueio && (ultimo?.tipo === 'sessao_bloqueada' || (ultimo && Date.parse(ultimo.ts) >= Date.parse(observedAt)))) {
174
+ return { gravado: false, thread: thread.id, tipo: eventoTipo, observedAt: ultimo.ts };
175
+ }
176
+ const dados = { ts: observedAt, fase: sessao.fase, sessionId, runtime: sessao.runtime,
177
+ despachoEm: sessao.despachadaEm, fonte: 'ork sessions event', sensor: tipo, sensorEventId: eventId,
178
+ recebidoEm: new Date(agoraMs).toISOString(), ...(payload.commit ? { commit: payload.commit } : {}),
179
+ // I-34: a notificação de ociosidade depois do Stop não é atividade; sem o tipo gravado,
180
+ // o observador claude-bg não teria como distingui-la e trataria o Stop como superado.
181
+ ...(tipo === 'notification' && payload.notificationType ? { notificationType: payload.notificationType } : {}),
182
+ ...(bloqueio ? { tipoDeHitl: 'permissao', pergunta: null, estadoRuntime: 'blocked' } : {}) };
183
+ if (retomada && ultimo?.tipo === 'sessao_bloqueada' && Date.parse(observedAt) > Date.parse(ultimo.ts)) {
184
+ (0, ledger_1.registrar)(dir, thread.id, 'sessao_destravada', { ...dados, sensorEventId: eventId + ':resume' });
185
+ }
186
+ (0, ledger_1.registrar)(dir, thread.id, eventoTipo, dados);
187
+ return { gravado: true, thread: thread.id, tipo: eventoTipo, observedAt };
188
+ });
189
+ }
190
+ /** Leitura limitada antes do JSON.parse, inclusive quando stdin é pipe. */
191
+ function lerPayloadSensor(fd = 0) {
192
+ const buffer = Buffer.alloc(exports.LIMITE_EVENTO_BYTES + 1);
193
+ let total = 0;
194
+ while (total <= exports.LIMITE_EVENTO_BYTES) {
195
+ const n = fs.readSync(fd, buffer, total, buffer.length - total, null);
196
+ if (!n)
197
+ return buffer.subarray(0, total).toString('utf8');
198
+ total += n;
199
+ if (total > exports.LIMITE_EVENTO_BYTES)
200
+ throw new Error('payload excede 16384 bytes');
201
+ }
202
+ throw new Error('payload excede 16384 bytes');
203
+ }