@orkastery/cli 0.5.3 → 0.5.6
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.
- package/adapters/claude-code/README.md +158 -0
- package/adapters/claude-code/mods/autoridade.json +56 -0
- package/adapters/claude-code/mods/ork-clima/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-clima/hooks/contas.ts +283 -0
- package/adapters/claude-code/mods/ork-clima/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-clima/hooks/previsao.ts +393 -0
- package/adapters/claude-code/mods/ork-clima/hooks/register.ts +205 -0
- package/adapters/claude-code/mods/ork-clima/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-clima/types/index.d.ts +80 -0
- package/adapters/claude-code/mods/ork-freio/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-freio/hooks/carga.ts +160 -0
- package/adapters/claude-code/mods/ork-freio/hooks/conferencia.ts +309 -0
- package/adapters/claude-code/mods/ork-freio/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-freio/hooks/lote.ts +270 -0
- package/adapters/claude-code/mods/ork-freio/hooks/register.ts +285 -0
- package/adapters/claude-code/mods/ork-freio/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-freio/types/index.d.ts +127 -0
- package/adapters/claude-code/mods/ork-mesa/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/cartoes.tsx +246 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/decidir.ts +110 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/fila.ts +253 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/obvia.ts +98 -0
- package/adapters/claude-code/mods/ork-mesa/hooks/register.tsx +493 -0
- package/adapters/claude-code/mods/ork-mesa/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-mesa/types/index.d.ts +131 -0
- package/adapters/claude-code/mods/ork-pista/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-pista/hooks/acoes.ts +71 -0
- package/adapters/claude-code/mods/ork-pista/hooks/ci.ts +117 -0
- package/adapters/claude-code/mods/ork-pista/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-pista/hooks/pista.tsx +356 -0
- package/adapters/claude-code/mods/ork-pista/hooks/register.tsx +439 -0
- package/adapters/claude-code/mods/ork-pista/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-pista/types/index.d.ts +85 -0
- package/adapters/claude-code/mods/ork-ponte/.claude-plugin/plugin.json +13 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/faixa.tsx +57 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/guarda.ts +410 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/mostrado.ts +55 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/nucleo.ts +157 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/papel.ts +42 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/register.ts +331 -0
- package/adapters/claude-code/mods/ork-ponte/hooks/vigia.ts +76 -0
- package/adapters/claude-code/mods/ork-ponte/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-ponte/types/index.d.ts +178 -0
- package/adapters/claude-code/mods/ork-portao/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-portao/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-portao/hooks/lease.ts +201 -0
- package/adapters/claude-code/mods/ork-portao/hooks/plano.ts +304 -0
- package/adapters/claude-code/mods/ork-portao/hooks/register.ts +339 -0
- package/adapters/claude-code/mods/ork-portao/hooks/verify.ts +152 -0
- package/adapters/claude-code/mods/ork-portao/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-portao/types/index.d.ts +60 -0
- package/adapters/claude-code/mods/ork-radar/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-radar/hooks/colisao.ts +420 -0
- package/adapters/claude-code/mods/ork-radar/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-radar/hooks/mapa.tsx +322 -0
- package/adapters/claude-code/mods/ork-radar/hooks/register.tsx +470 -0
- package/adapters/claude-code/mods/ork-radar/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-radar/types/index.d.ts +72 -0
- package/adapters/claude-code/mods/ork-sentinela/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/alertas.ts +85 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/despacho.ts +156 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/register.ts +511 -0
- package/adapters/claude-code/mods/ork-sentinela/hooks/vigia.ts +186 -0
- package/adapters/claude-code/mods/ork-sentinela/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-sentinela/types/index.d.ts +65 -0
- package/adapters/claude-code/mods/ork-torre/.claude-plugin/plugin.json +14 -0
- package/adapters/claude-code/mods/ork-torre/hooks/agenda.ts +60 -0
- package/adapters/claude-code/mods/ork-torre/hooks/detalhe.tsx +236 -0
- package/adapters/claude-code/mods/ork-torre/hooks/frases.ts +42 -0
- package/adapters/claude-code/mods/ork-torre/hooks/hooks.json +3 -0
- package/adapters/claude-code/mods/ork-torre/hooks/painel.tsx +344 -0
- package/adapters/claude-code/mods/ork-torre/hooks/rede.ts +97 -0
- package/adapters/claude-code/mods/ork-torre/hooks/register.tsx +437 -0
- package/adapters/claude-code/mods/ork-torre/orkastery-mod.json +5 -0
- package/adapters/claude-code/mods/ork-torre/types/index.d.ts +108 -0
- package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +1 -1
- package/adapters/openclaw/README.md +2 -1
- package/adapters/openclaw/openclaw.plugin.json +1 -1
- package/adapters/openclaw/package.json +1 -1
- package/assets/docs-en/markdownlint-cli2.jsonc +22 -0
- package/assets/docs-en/padroes/documentacao-de-produto.md +135 -0
- package/assets/docs-en/padroes/roadmap-de-produto.md +100 -0
- package/assets/docs-en/produto/README.md +14 -0
- package/assets/docs-en/produto/_modelo-feature.md +62 -0
- package/assets/docs-en/roadmap/README.md +14 -0
- package/assets/docs-en/roadmap/_modelo-item.md +75 -0
- package/dist/adapters/claude-bg.js +77 -13
- package/dist/adapters/codex.js +10 -1
- package/dist/agents-md.js +24 -15
- package/dist/auditrun.js +17 -2
- package/dist/board.js +4 -3
- package/dist/branch-de-estado.js +23 -1
- package/dist/catalogo.js +33 -0
- package/dist/ci.js +13 -7
- package/dist/claims-conferir.js +342 -0
- package/dist/claims.js +3 -1
- package/dist/company-brain-client.js +36 -1
- package/dist/company-brain-journal.js +2 -1
- package/dist/company-brain-migration.js +36 -1
- package/dist/conducao-sentinela.js +388 -0
- package/dist/conducao-texto.js +12 -18
- package/dist/conducao.js +122 -30
- package/dist/conhecimento.js +490 -0
- package/dist/docs.js +22 -8
- package/dist/doctor-pulse-cron.js +182 -27
- package/dist/doctor-rede.js +18 -17
- package/dist/doctor.js +115 -111
- package/dist/entrega-pr.js +22 -21
- package/dist/escopo-escrita.js +10 -1
- package/dist/estado-thread.js +23 -1
- package/dist/experiencia-instalacao.js +45 -25
- package/dist/fabrica-batida.js +310 -0
- package/dist/fabrica-estado.js +38 -8
- package/dist/fabrica-publicar.js +3 -1
- package/dist/fila-pesada.js +444 -0
- package/dist/fix.js +3 -2
- package/dist/forja.js +1 -1
- package/dist/gates.js +3 -28
- package/dist/handoff.js +10 -6
- package/dist/hitl-local-receipt.js +2 -0
- package/dist/hitl-resumo.js +29 -3
- package/dist/hitl-tempo-parado.js +4 -4
- package/dist/hitl.js +29 -33
- package/dist/horario.js +14 -7
- package/dist/hosts.js +52 -1
- package/dist/impedimento.js +108 -14
- package/dist/index.js +623 -521
- package/dist/indice.js +7 -1
- package/dist/init.js +43 -47
- package/dist/instabilidade.js +144 -0
- package/dist/integracoes-locais.js +2 -0
- package/dist/intelligence-graph-cli.js +92 -21
- package/dist/intelligence-graph-contexto.js +56 -17
- package/dist/intelligence-graph-contract.js +2 -1
- package/dist/intelligence-graph-extract-md.js +56 -4
- package/dist/intelligence-graph-extract-ts.js +71 -3
- package/dist/intelligence-graph-query.js +66 -19
- package/dist/ledger.js +15 -1
- package/dist/liveness.js +6 -3
- package/dist/locale-ajuda.js +761 -0
- package/dist/locale-gerados.js +160 -0
- package/dist/locale-master.js +99 -0
- package/dist/locale-onboarding.js +92 -0
- package/dist/locale-phase.js +151 -0
- package/dist/locale-pulse.js +211 -0
- package/dist/locale-retry.js +385 -0
- package/dist/locale-roadmap.js +102 -0
- package/dist/locale-ship.js +494 -0
- package/dist/locale-thread.js +277 -0
- package/dist/locale-verify.js +125 -0
- package/dist/locale.js +714 -0
- package/dist/manifest.js +129 -3
- package/dist/maquina.js +23 -4
- package/dist/master-digest.js +6 -1
- package/dist/master-nota.js +4 -6
- package/dist/master.js +21 -24
- package/dist/mcp-artifacts.js +11 -2
- package/dist/mcp-git.js +23 -6
- package/dist/mcp-grafo.js +7 -4
- package/dist/mcp-server.js +8 -2
- package/dist/mcp-ship.js +3 -1
- package/dist/mcp-verify.js +6 -1
- package/dist/modos.js +3 -6
- package/dist/network-roadmap.js +5 -2
- package/dist/noctum-arco.js +911 -0
- package/dist/noctum-capacidade.js +141 -0
- package/dist/noctum-envelope.js +810 -0
- package/dist/noctum-execucao.js +304 -0
- package/dist/noctum-fila.js +280 -0
- package/dist/ocupacao.js +29 -2
- package/dist/onboarding.js +40 -21
- package/dist/orkmind.js +9 -2
- package/dist/orquestracao.js +13 -12
- package/dist/parado-no-condutor.js +34 -9
- package/dist/phase.js +94 -39
- package/dist/policies.js +4 -4
- package/dist/portfolio.js +4 -2
- package/dist/postura-local.js +234 -0
- package/dist/preflight.js +11 -10
- package/dist/procedencia.js +225 -0
- package/dist/projeto-alvo.js +127 -4
- package/dist/prompts.js +6 -2
- package/dist/pulse-delivery.js +13 -2
- package/dist/pulse.js +52 -19
- package/dist/ratelimit.js +4 -2
- package/dist/redacao-saida.js +63 -0
- package/dist/rede-status.js +3 -2
- package/dist/retry.js +232 -148
- package/dist/roadmap-reservas.js +20 -3
- package/dist/roadmap-status.js +129 -33
- package/dist/runtime-context.js +181 -3
- package/dist/runtimes.js +2 -1
- package/dist/session-events.js +7 -3
- package/dist/session-watcher-claude.js +7 -1
- package/dist/session-watcher.js +185 -33
- package/dist/sessoes-contas.js +1 -1
- package/dist/ship-publicar.js +800 -0
- package/dist/ship.js +84 -81
- package/dist/steal.js +77 -0
- package/dist/thread-close.js +3 -2
- package/dist/thread.js +153 -82
- package/dist/util.js +8 -1
- package/dist/verify.js +141 -52
- package/dist/vida-da-thread.js +254 -0
- package/dist/worktree-local.js +165 -0
- package/dist/worktree.js +20 -0
- package/dist/yaml.js +27 -8
- package/package.json +1 -1
- package/schemas/code-artifact-graph.v1.schema.json +2 -1
|
@@ -75,6 +75,7 @@ const session_events_1 = require("./session-events");
|
|
|
75
75
|
const ledger_1 = require("./ledger");
|
|
76
76
|
const thread_1 = require("./thread");
|
|
77
77
|
const util_1 = require("./util");
|
|
78
|
+
const procedencia_1 = require("./procedencia");
|
|
78
79
|
const hitl_1 = require("./hitl");
|
|
79
80
|
/** Uma consulta nativa custa cerca de 0,3 s; cinco segundos mantém o custo abaixo de 10%. */
|
|
80
81
|
exports.INTERVALO_WATCH_CLAUDE_MS = 5000;
|
|
@@ -546,6 +547,9 @@ function provaDoOrk(raiz, threadId, sessao, eventos, fonte) {
|
|
|
546
547
|
const cwd = fonte?.cwd, headNoDespacho = fonte?.head;
|
|
547
548
|
if (!cwd || typeof headNoDespacho !== 'string')
|
|
548
549
|
return falta('HEAD da worktree no despacho não registrado; commit não conferível', { commits: [], recusados: registrados });
|
|
550
|
+
// RM-047 (P2): o git da prova só roda na worktree registrada; o cwd vem do ledger.
|
|
551
|
+
if ((0, procedencia_1.cwdLocalOuNulo)(raiz, threadId, cwd, 'ledger') === null)
|
|
552
|
+
return falta('cwd do despacho fora das worktrees registradas no git; commit não conferível', { commits: [], recusados: registrados });
|
|
549
553
|
const commits = registrados.filter(sha => commitConferido(cwd, sha, headNoDespacho));
|
|
550
554
|
const recusados = registrados.filter(sha => !commits.includes(sha));
|
|
551
555
|
if (!commits.length)
|
|
@@ -622,7 +626,9 @@ function garantirFonteClaude(raiz, thread, sessao) {
|
|
|
622
626
|
if (atual)
|
|
623
627
|
return atual;
|
|
624
628
|
const despacho = eventos.filter(e => e.tipo === 'phase_dispatch' && e.sessionId === sessao.sessionId).at(-1);
|
|
625
|
-
|
|
629
|
+
// RM-047 (P2): o cwd do ledger ou do thread.json so vale como worktree registrada no git.
|
|
630
|
+
const cwd = typeof despacho?.cwd === 'string' ? (0, procedencia_1.exigirCwdLocal)(raiz, thread.id, despacho.cwd, 'ledger')
|
|
631
|
+
: (0, procedencia_1.diretorioDaThread)(raiz, thread);
|
|
626
632
|
const fonte = { nativo: 'claude-agents', cwd, origem: 'sessions.watch' };
|
|
627
633
|
validarFonteClaude(eventos, sessao.sessionId, fonte);
|
|
628
634
|
if (!(0, ledger_1.registrarSeExiste)(dir, thread.id, 'session_sensor_registered', { fase: sessao.fase, sessionId: sessao.sessionId,
|
package/dist/session-watcher.js
CHANGED
|
@@ -33,10 +33,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.BLOCO_WATCH_BYTES = exports.INTERVALO_WATCH_MS = exports.LIMITE_MORTE_MS = void 0;
|
|
36
|
+
exports.BLOCO_WATCH_BYTES = exports.MAX_FALHAS_WATCH = exports.MAX_ESPERA_ERRO_WATCH_MS = exports.INTERVALO_WATCH_MS = exports.LIMITE_MORTE_MS = void 0;
|
|
37
37
|
exports.observarSessao = observarSessao;
|
|
38
38
|
exports.validarFonteWatcher = validarFonteWatcher;
|
|
39
39
|
exports.iniciarWatcher = iniciarWatcher;
|
|
40
|
+
exports.acompanharSessao = acompanharSessao;
|
|
40
41
|
/** D6: observador restrito a uma sessão, cursor canônico e resultados idempotentes. */
|
|
41
42
|
const fs = __importStar(require("node:fs"));
|
|
42
43
|
const path = __importStar(require("node:path"));
|
|
@@ -110,6 +111,8 @@ function semProvaNativa(snapshot, terminal, fonteVencedora, fechamento, sessionI
|
|
|
110
111
|
}
|
|
111
112
|
exports.LIMITE_MORTE_MS = 600000;
|
|
112
113
|
exports.INTERVALO_WATCH_MS = 1000;
|
|
114
|
+
exports.MAX_ESPERA_ERRO_WATCH_MS = 30000;
|
|
115
|
+
exports.MAX_FALHAS_WATCH = 12;
|
|
113
116
|
exports.BLOCO_WATCH_BYTES = codex_events_1.LIMITE_LINHA_CODEX + 65536;
|
|
114
117
|
function lerJson(file) {
|
|
115
118
|
if (!fs.existsSync(file))
|
|
@@ -291,8 +294,87 @@ function desfazerNaThreadRemovida(pasta, criadas) {
|
|
|
291
294
|
catch { /* já removida ou não vazia */ }
|
|
292
295
|
}
|
|
293
296
|
}
|
|
297
|
+
/** Diagnóstico fechado: mensagens de E/S e JSON podem conter caminhos e segredos. */
|
|
298
|
+
function diagnosticoWatcher(e) {
|
|
299
|
+
const erro = e;
|
|
300
|
+
const code = ['ENOENT', 'EAGAIN', 'EBUSY', 'EINTR', 'EACCES', 'EPERM', 'EIO', 'ENOSPC', 'SESSION_STATE_SPLIT']
|
|
301
|
+
.includes(erro?.code ?? '') ? erro.code : null;
|
|
302
|
+
const nome = e instanceof Error ? e.constructor.name : '';
|
|
303
|
+
const construtor = ['Error', 'SyntaxError', 'TypeError', 'RangeError', 'ReferenceError', 'URIError', 'EvalError', 'AggregateError']
|
|
304
|
+
.includes(nome) ? nome : 'desconhecido';
|
|
305
|
+
const base = { code, construtor };
|
|
306
|
+
const mensagem = erro?.message ?? '';
|
|
307
|
+
if (mensagem === 'prazo de observação esgotado')
|
|
308
|
+
return { ...base, categoria: 'observacao.prazo',
|
|
309
|
+
erro: 'nenhuma observação bem-sucedida dentro do orçamento de espera', transitorio: false };
|
|
310
|
+
// Só motivos literais do núcleo saem no diagnóstico: nenhum conteúdo de metadado.
|
|
311
|
+
const motivos = ['sessão do controller divergente', 'instância do controller divergente',
|
|
312
|
+
'vínculo thread/fase/prompt do controller divergente', 'cwd do controller divergente',
|
|
313
|
+
'identidade do controller divergente da registrada', 'identidade do runtime divergente da registrada',
|
|
314
|
+
'rollout do controller ausente', 'rollout do controller divergente do registrado',
|
|
315
|
+
'rollout do controller rotacionado sem vínculo provado com a fonte fixada',
|
|
316
|
+
'descritor consumidor de rollout divergente da fonte fixada'];
|
|
317
|
+
const metadado = /^runtime\.unavailable: metadado (state\.json|launch\.json|process-launch\.json) de controller (inválido|ausente)$/.test(mensagem);
|
|
318
|
+
const categoria = metadado || motivos.some(m => mensagem === `runtime.unavailable: ${m}`) ? mensagem
|
|
319
|
+
: mensagem === 'controlador registrado divergente do despacho' ? 'controller.registro-divergente'
|
|
320
|
+
: mensagem === 'despacho do controller sem cwd registrado' ? 'controller.cwd-ausente'
|
|
321
|
+
: mensagem.startsWith('runtime.unavailable:') ? 'runtime.unavailable: motivo não categorizado'
|
|
322
|
+
: code ? `io.${code}` : construtor;
|
|
323
|
+
if (code === 'SESSION_STATE_SPLIT')
|
|
324
|
+
return { ...base, categoria: 'estado.dividido',
|
|
325
|
+
erro: 'estado canônico temporariamente sem vínculo; auditoria será repetida', transitorio: true };
|
|
326
|
+
if (['ENOENT', 'EAGAIN', 'EBUSY', 'EINTR'].includes(erro?.code ?? ''))
|
|
327
|
+
return { ...base, categoria, erro: `leitura temporariamente indisponível (${erro.code})`, transitorio: true };
|
|
328
|
+
if (e instanceof SyntaxError || /^JSON invalido em /.test(erro?.message ?? '') ||
|
|
329
|
+
metadado)
|
|
330
|
+
return { ...base, categoria: metadado ? categoria : 'json.invalido', erro: 'metadado JSON indisponível ou incompleto', transitorio: true };
|
|
331
|
+
if (/^(ingestão ocupada|creation\.busy:)/.test(erro?.message ?? ''))
|
|
332
|
+
return { ...base, categoria: 'observacao.ocupada', erro: 'observação ocupada; nova tentativa agendada', transitorio: true };
|
|
333
|
+
return { ...base, categoria, erro: 'falha permanente na observação; confira vínculo e fonte do sensor', transitorio: false };
|
|
334
|
+
}
|
|
335
|
+
const errosRegistrados = new WeakSet();
|
|
336
|
+
function registrarErroWatcher(raiz, threadId, sessionId, e, serie) {
|
|
337
|
+
if (!serie && e && typeof e === 'object' && errosRegistrados.has(e))
|
|
338
|
+
return true;
|
|
339
|
+
const dados = diagnosticoWatcher(e);
|
|
340
|
+
if (dados.categoria === 'observacao.ocupada')
|
|
341
|
+
return true;
|
|
342
|
+
const registrado = (0, ledger_1.registrarSeExiste)((0, thread_1.dirThread)(raiz, threadId), threadId, 'session_watcher_error', {
|
|
343
|
+
sessionId, motivo: 'runtime.unavailable', ...dados, ...serie,
|
|
344
|
+
transitorio: dados.transitorio && (!serie?.encerramento || serie.encerramento === 'recuperado'), origem: 'sessions.watch',
|
|
345
|
+
});
|
|
346
|
+
if (registrado && e && typeof e === 'object')
|
|
347
|
+
errosRegistrados.add(e);
|
|
348
|
+
return registrado !== null;
|
|
349
|
+
}
|
|
350
|
+
/** Falhar ao diagnosticar não troca o erro observado nem interrompe o retry transitório. */
|
|
351
|
+
function tentarRegistrarErroWatcher(...args) {
|
|
352
|
+
try {
|
|
353
|
+
return registrarErroWatcher(...args);
|
|
354
|
+
}
|
|
355
|
+
catch {
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
function observarSemDiagnostico(carregado, sessionId, opcoes) {
|
|
360
|
+
return observarSessaoResolvida(carregado, sessionId, (0, session_events_1.resolverSessao)(carregado.raiz, sessionId, opcoes.threadId), opcoes);
|
|
361
|
+
}
|
|
294
362
|
function observarSessao(carregado, sessionId, opcoes = {}) {
|
|
295
|
-
|
|
363
|
+
let threadId = opcoes.threadId;
|
|
364
|
+
try {
|
|
365
|
+
const resolvida = (0, session_events_1.resolverSessao)(carregado.raiz, sessionId, threadId);
|
|
366
|
+
// Recusa de entrada sem despacho não é falha de um watcher ancorado.
|
|
367
|
+
threadId = resolvida.sessao.origem !== 'adocao' && resolvida.sessao.despachadaEm
|
|
368
|
+
? resolvida.thread.id : undefined;
|
|
369
|
+
return observarSessaoResolvida(carregado, sessionId, resolvida, opcoes);
|
|
370
|
+
}
|
|
371
|
+
catch (e) {
|
|
372
|
+
if (threadId)
|
|
373
|
+
tentarRegistrarErroWatcher(carregado.raiz, threadId, sessionId, e);
|
|
374
|
+
throw e;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
function observarSessaoResolvida(carregado, sessionId, { thread, sessao: registrada }, opcoes) {
|
|
296
378
|
const sessao = (0, session_events_1.exigirSessaoDespachada)(registrada, sessionId);
|
|
297
379
|
if (sessao.runtime !== 'codex' && sessao.runtime !== 'claude-bg')
|
|
298
380
|
throw new Error('watch requer sessão Codex ou claude-bg registrada');
|
|
@@ -398,6 +480,27 @@ function observarSessao(carregado, sessionId, opcoes = {}) {
|
|
|
398
480
|
cursor.progressoEm = Math.max(cursor.progressoEm, leitura.quando);
|
|
399
481
|
}
|
|
400
482
|
}
|
|
483
|
+
// Commit MCP é produção do núcleo, mesmo quando app-server não avança o rollout.
|
|
484
|
+
// Só renova inatividade com ambos os processos vivos, dentro deste despacho e
|
|
485
|
+
// sem terminal/erro nativo. Não substitui terminal, close ou prova de conclusão.
|
|
486
|
+
let progressoMcpEventId;
|
|
487
|
+
if (snapshot?.estadoController === 'vivo' && snapshot.estadoRuntime === 'vivo' &&
|
|
488
|
+
['working', 'running'].includes(snapshot.estado) && !snapshot.fechamento &&
|
|
489
|
+
!snapshot.terminalNativo && !snapshot.erro && !snapshot.limitacao) {
|
|
490
|
+
for (const e of (0, session_watcher_claude_1.eventosDoIntervalo)(eventos, sessao)) {
|
|
491
|
+
const quando = Date.parse(e.ts);
|
|
492
|
+
if (e.tipo !== 'mcp_git_committed' || e.thread !== thread.id || e.origem !== 'mcp.git' ||
|
|
493
|
+
e.estadoAuditado !== true || typeof e.commit !== 'string' || !/^[a-f0-9]{40}$/.test(e.commit) ||
|
|
494
|
+
(e.sessionId !== undefined && e.sessionId !== sessionId) ||
|
|
495
|
+
(e.despachoEm !== undefined && e.despachoEm !== sessao.despachadaEm) ||
|
|
496
|
+
quando > now || quando <= cursor.progressoEm)
|
|
497
|
+
continue;
|
|
498
|
+
cresceu = true;
|
|
499
|
+
cursor.crescimentoEm = Math.max(cursor.crescimentoEm, quando);
|
|
500
|
+
cursor.progressoEm = quando;
|
|
501
|
+
progressoMcpEventId = e.eventId;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
401
504
|
// Erro de metadados posterior não obriga a reler o mesmo backlog no restart.
|
|
402
505
|
(0, codex_runner_1.gravarAtomico)(file, cursor);
|
|
403
506
|
const processo = registro?.processoPath ? lerJson(registro.processoPath) : null;
|
|
@@ -482,7 +585,8 @@ function observarSessao(carregado, sessionId, opcoes = {}) {
|
|
|
482
585
|
if (!atuais.some(e => e.sensorEventId === heartbeatId))
|
|
483
586
|
(0, ledger_1.registrar)(dir, thread.id, 'runtime_heartbeat', {
|
|
484
587
|
ts: new Date(cursor.crescimentoEm).toISOString(), fase: sessao.fase, sessionId, despachoEm: sessao.despachadaEm,
|
|
485
|
-
sensorEventId: heartbeatId, fonte: 'progresso reconhecido do stream/rollout',
|
|
588
|
+
sensorEventId: heartbeatId, fonte: progressoMcpEventId ? 'mcp_git_committed do despacho' : 'progresso reconhecido do stream/rollout',
|
|
589
|
+
...(progressoMcpEventId ? { mcpEventId: progressoMcpEventId } : {}), bytesLidos,
|
|
486
590
|
});
|
|
487
591
|
cursor.heartbeatEm = cursor.crescimentoEm;
|
|
488
592
|
(0, codex_runner_1.gravarAtomico)(file, cursor);
|
|
@@ -548,13 +652,6 @@ function observarSessao(carregado, sessionId, opcoes = {}) {
|
|
|
548
652
|
// Thread apagada no meio da observação: encerra sem erro, sem recriar a pasta e sem resíduo.
|
|
549
653
|
if (!(0, ledger_1.threadPresente)(dir))
|
|
550
654
|
return desfazer();
|
|
551
|
-
if (!/ocupad/.test(e.message) && !(0, ledger_1.registrarSeExiste)(dir, thread.id, 'session_watcher_error', {
|
|
552
|
-
fase: sessao.fase, sessionId, despachoEm: sessao.despachadaEm, motivo: 'runtime.unavailable',
|
|
553
|
-
// Não copiar conteúdo de metadados/logs em mensagens de JSON.parse.
|
|
554
|
-
erro: e instanceof SyntaxError ? 'metadado JSON inválido' : e.message,
|
|
555
|
-
origem: 'sessions.watch',
|
|
556
|
-
}))
|
|
557
|
-
return removida;
|
|
558
655
|
throw e;
|
|
559
656
|
}
|
|
560
657
|
}
|
|
@@ -612,7 +709,7 @@ function iniciarWatcher(raiz, sessionId) {
|
|
|
612
709
|
const err = fs.openSync(path.join(dir, `watcher-${sessionId}.stderr`), 'a', 0o600);
|
|
613
710
|
let child;
|
|
614
711
|
try {
|
|
615
|
-
child = (0, node_child_process_1.spawn)(process.execPath, [__filename, '--run', raiz, sessionId, readyPath, token], {
|
|
712
|
+
child = (0, node_child_process_1.spawn)(process.execPath, [__filename, '--run', raiz, sessionId, readyPath, token, thread.id], {
|
|
616
713
|
cwd: raiz, detached: true, stdio: ['ignore', 'ignore', err],
|
|
617
714
|
});
|
|
618
715
|
}
|
|
@@ -661,47 +758,102 @@ function iniciarWatcher(raiz, sessionId) {
|
|
|
661
758
|
}
|
|
662
759
|
async function acompanhar() {
|
|
663
760
|
const carregado = (0, manifest_1.exigirManifesto)(process.argv[3]), sessionId = process.argv[4];
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
761
|
+
const threadId = process.argv[7] ?? (0, session_events_1.resolverSessao)(carregado.raiz, sessionId).thread.id;
|
|
762
|
+
try {
|
|
763
|
+
const readyPath = process.argv[5], token = process.argv[6];
|
|
764
|
+
if (readyPath && token) {
|
|
765
|
+
validarFonteWatcher(carregado.raiz, sessionId);
|
|
766
|
+
const sessao = (0, session_events_1.exigirSessaoDespachada)((0, session_events_1.resolverSessao)(carregado.raiz, sessionId, threadId).sessao, sessionId);
|
|
767
|
+
const identidade = (0, codex_runner_1.identidadeProcesso)(process.pid);
|
|
768
|
+
if (!identidade)
|
|
769
|
+
throw new Error('watcher sem identidade propria');
|
|
770
|
+
(0, codex_runner_1.gravarAtomico)(readyPath, { token, sessionId, despachoEm: sessao.despachadaEm, identidade });
|
|
771
|
+
const deadline = Date.now() + 5000;
|
|
772
|
+
while (lerJson(readyPath + '.ack')?.token !== token) {
|
|
773
|
+
if (Date.now() >= deadline)
|
|
774
|
+
throw new Error('watcher sem confirmacao do pai');
|
|
775
|
+
await new Promise(r => setTimeout(r, 10));
|
|
776
|
+
}
|
|
678
777
|
}
|
|
778
|
+
await acompanharSessao(carregado, sessionId, { threadId });
|
|
679
779
|
}
|
|
680
|
-
|
|
780
|
+
catch (e) {
|
|
781
|
+
tentarRegistrarErroWatcher(carregado.raiz, threadId, sessionId, e);
|
|
782
|
+
throw e;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
/** Mesmo laço do processo destacado, com relógio e espera injetáveis para regressões. */
|
|
786
|
+
async function acompanharSessao(carregado, sessionId, opcoes) {
|
|
787
|
+
const dir = (0, thread_1.dirThread)(carregado.raiz, opcoes.threadId);
|
|
788
|
+
const esperar = opcoes.esperar ?? ((ms) => new Promise(r => setTimeout(r, ms)));
|
|
789
|
+
const agora = opcoes.agora ?? Date.now;
|
|
790
|
+
let falhas = 0, tentativas = 0, esperas = 0, ultimaObservacao = agora(), ultimoErro;
|
|
681
791
|
for (;;) {
|
|
682
792
|
// Projeto ou thread apagados encerram o laço em silêncio: nada a observar nem a recriar.
|
|
683
793
|
if (!(0, ledger_1.threadPresente)(dir))
|
|
684
794
|
return;
|
|
685
795
|
let atual;
|
|
686
796
|
try {
|
|
687
|
-
atual = (0, thread_1.lerThread)(carregado.raiz,
|
|
797
|
+
atual = (0, thread_1.lerThread)(carregado.raiz, opcoes.threadId);
|
|
688
798
|
if (atual.status !== 'aberta' || atual.sessoes.at(-1)?.sessionId !== sessionId)
|
|
689
799
|
return;
|
|
690
|
-
|
|
800
|
+
// O laço agrega sua série de erros; a API de observação avulsa diagnostica separadamente.
|
|
801
|
+
const r = observarSemDiagnostico(carregado, sessionId, { threadId: opcoes.threadId, agoraMs: opcoes.agora?.() });
|
|
802
|
+
if (r.ocupado)
|
|
803
|
+
throw new Error('ingestão ocupada; tente novamente');
|
|
804
|
+
if (!r.ocupado) {
|
|
805
|
+
if (falhas)
|
|
806
|
+
tentarRegistrarErroWatcher(carregado.raiz, opcoes.threadId, sessionId, ultimoErro, { falhasConsecutivas: falhas, etapa: 'final', encerramento: 'recuperado' });
|
|
807
|
+
falhas = 0;
|
|
808
|
+
tentativas = 0;
|
|
809
|
+
esperas = 0;
|
|
810
|
+
ultimaObservacao = agora();
|
|
811
|
+
}
|
|
691
812
|
if (r.concluido || r.encerrado)
|
|
692
813
|
return;
|
|
693
814
|
}
|
|
694
815
|
catch (e) {
|
|
695
816
|
if (!(0, ledger_1.threadPresente)(dir))
|
|
696
817
|
return;
|
|
697
|
-
|
|
698
|
-
|
|
818
|
+
esperas++;
|
|
819
|
+
const dados = diagnosticoWatcher(e), ocupado = dados.categoria === 'observacao.ocupada';
|
|
820
|
+
const expirou = agora() - ultimaObservacao >= exports.LIMITE_MORTE_MS;
|
|
821
|
+
// Contenção não é erro. Estado dividido exige nova auditoria; ambos consomem
|
|
822
|
+
// só tempo, sem antecipar os 600 s pelo teto das outras falhas.
|
|
823
|
+
if (!ocupado || expirou) {
|
|
824
|
+
if (ocupado)
|
|
825
|
+
e = new Error('prazo de observação esgotado');
|
|
826
|
+
falhas++;
|
|
827
|
+
if (!ocupado && dados.categoria !== 'estado.dividido')
|
|
828
|
+
tentativas++;
|
|
829
|
+
ultimoErro = e;
|
|
830
|
+
const encerramento = ocupado ? 'prazo' : !dados.transitorio ? 'permanente'
|
|
831
|
+
: expirou ? 'prazo' : tentativas >= exports.MAX_FALHAS_WATCH ? 'tentativas' : undefined;
|
|
832
|
+
if (falhas === 1 || encerramento)
|
|
833
|
+
tentarRegistrarErroWatcher(carregado.raiz, opcoes.threadId, sessionId, e, { falhasConsecutivas: falhas, etapa: encerramento ? 'final' : 'inicial', ...(encerramento ? { encerramento } : {}) });
|
|
834
|
+
if (encerramento)
|
|
835
|
+
throw e;
|
|
836
|
+
}
|
|
699
837
|
}
|
|
700
|
-
await
|
|
838
|
+
await esperar(esperas ? Math.min(exports.MAX_ESPERA_ERRO_WATCH_MS, exports.INTERVALO_WATCH_MS * 2 ** Math.min(esperas - 1, 5), Math.max(1, exports.LIMITE_MORTE_MS - (agora() - ultimaObservacao)))
|
|
839
|
+
: atual?.sessoes.at(-1)?.runtime === 'claude-bg' ? session_watcher_claude_1.INTERVALO_WATCH_CLAUDE_MS : exports.INTERVALO_WATCH_MS);
|
|
701
840
|
}
|
|
702
841
|
}
|
|
703
842
|
if (require.main === module && process.argv[2] === '--run')
|
|
704
|
-
acompanhar().catch(
|
|
705
|
-
|
|
843
|
+
acompanhar().catch(e => {
|
|
844
|
+
// O dispatcher fornece o vínculo antes do spawn: até falha ao carregar o manifesto
|
|
845
|
+
// precisa de diagnóstico. Sem ledger acessível, o stderr não promete um recibo inexistente.
|
|
846
|
+
let registroIndisponivel = !process.argv[7];
|
|
847
|
+
if (process.argv[7]) {
|
|
848
|
+
try {
|
|
849
|
+
registroIndisponivel = !registrarErroWatcher(process.argv[3], process.argv[7], process.argv[4], e);
|
|
850
|
+
}
|
|
851
|
+
catch {
|
|
852
|
+
registroIndisponivel = true;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
process.stderr.write(registroIndisponivel
|
|
856
|
+
? 'ork watcher: observação interrompida; não foi possível registrar session_watcher_error.\n'
|
|
857
|
+
: 'ork watcher: observação interrompida; confira session_watcher_error e estado canônico.\n');
|
|
706
858
|
process.exitCode = 1;
|
|
707
859
|
});
|
package/dist/sessoes-contas.js
CHANGED
|
@@ -132,7 +132,7 @@ function consultarContas(raiz, opcoes = {}) {
|
|
|
132
132
|
fontes.push({ origem: `claude agents (${rotulo(conta)})`, ok: false, detalhe: e.message });
|
|
133
133
|
continue;
|
|
134
134
|
}
|
|
135
|
-
const r = (0, claude_bg_1.consultarSessoes)(undefined, opcoes.todas, ambiente);
|
|
135
|
+
const r = (0, claude_bg_1.consultarSessoes)(undefined, opcoes.todas, ambiente, opcoes.prazoMs);
|
|
136
136
|
const origem = `claude agents --json${opcoes.todas ? ' --all' : ''} (${rotulo(conta)})`;
|
|
137
137
|
// Fatia 2 do ensaio da 0.5.0 (P1): só o ENOENT antes da consulta prova a fonte ausente; qualquer
|
|
138
138
|
// outra falha do `claude` continua deixando o inventário incompleto.
|