@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.
- package/LICENSE +1 -1
- package/README.md +86 -65
- package/adapters/README.md +30 -15
- package/adapters/claude-code/.claude-plugin/plugin.json +11 -5
- package/adapters/claude-code/README.md +110 -8
- package/adapters/claude-code/commands/onboarding.md +21 -0
- package/adapters/claude-code/commands/ork.md +99 -27
- package/adapters/claude-code/hooks/hooks.json +6 -1
- package/adapters/claude-code/hooks/ork-sensor.js +66 -0
- package/adapters/codex/skills/ork/SKILL.md +57 -0
- package/adapters/hermes/README.md +163 -0
- package/adapters/hermes/bin/ork-abrir-thread.sh +2 -0
- package/adapters/hermes/bin/ork-brain.sh +4 -0
- package/adapters/hermes/bin/ork-hitl-answer.py +82 -0
- package/adapters/hermes/bin/ork-maestro.sh +6 -0
- package/adapters/hermes/bin/ork-master-enviar.py +84 -0
- package/adapters/hermes/bin/ork-objective-message.sh +17 -0
- package/adapters/hermes/bin/ork-objective-status.sh +12 -0
- package/adapters/hermes/bin/ork-pulse-enviar.py +47 -0
- package/adapters/hermes/hermes.plugin.json +26 -4
- package/adapters/hermes/hitl-ingress/__init__.py +356 -0
- package/adapters/hermes/hitl-ingress/plugin.yaml +4 -0
- package/adapters/hermes/skills/orkastery-devmaster/SKILL.md +75 -22
- package/adapters/openclaw/README.md +135 -26
- package/adapters/openclaw/bin/ork-brain.sh +4 -0
- package/adapters/openclaw/construir.sh +19 -0
- package/adapters/openclaw/dist/hitl-ingress.js +199 -0
- package/adapters/openclaw/dist/index.js +437 -0
- package/adapters/openclaw/openclaw.plugin.json +39 -134
- package/adapters/openclaw/package.json +26 -0
- package/adapters/openclaw/src/hitl-ingress.ts +180 -0
- package/adapters/openclaw/src/index.ts +458 -0
- package/adapters/openclaw/src/tipos-openclaw.d.ts +58 -0
- package/adapters/openclaw/tsconfig.json +15 -0
- package/assets/docs/markdownlint-cli2.jsonc +22 -0
- package/assets/docs/padroes/documentacao-de-produto.md +133 -0
- package/assets/docs/padroes/roadmap-de-produto.md +98 -0
- package/assets/docs/produto/README.md +14 -0
- package/assets/docs/produto/_modelo-feature.md +59 -0
- package/assets/docs/roadmap/README.md +14 -0
- package/assets/docs/roadmap/_modelo-item.md +73 -0
- package/assets/orkmind-native-schema.json +32 -0
- package/assets/orkmind_bridge.py +357 -0
- package/assets/orkmind_fixture.py +67 -0
- package/assets/orkmind_prospective.py +138 -0
- package/assets/reference-tariffs-i07.json +23 -0
- package/dist/adapters/claude-bg.js +488 -39
- package/dist/adapters/codex-controller-sensor.js +449 -0
- package/dist/adapters/codex-controller-worker.js +361 -0
- package/dist/adapters/codex-controller.js +252 -0
- package/dist/adapters/codex-events.js +205 -0
- package/dist/adapters/codex-question.js +26 -0
- package/dist/adapters/codex-runner.js +133 -0
- package/dist/adapters/codex.js +394 -0
- package/dist/agents-md.js +84 -0
- package/dist/auditoria.js +11 -8
- package/dist/auditrun.js +5 -4
- package/dist/board.js +173 -22
- package/dist/branch-de-estado.js +136 -0
- package/dist/canarios-hitl.js +177 -0
- package/dist/canarios-i43.js +543 -0
- package/dist/canarios-pulse.js +147 -0
- package/dist/canarios-sensores.js +129 -0
- package/dist/canarios.js +111 -2
- package/dist/catalogo.js +9 -0
- package/dist/ci.js +216 -0
- package/dist/ciclos.js +2 -1
- package/dist/claim-lint.js +64 -0
- package/dist/claims.js +60 -0
- package/dist/company-brain-capture.js +195 -0
- package/dist/company-brain-cli.js +123 -0
- package/dist/company-brain-client.js +61 -0
- package/dist/company-brain-contract.js +166 -0
- package/dist/company-brain-journal.js +192 -0
- package/dist/company-brain-mcp.js +33 -0
- package/dist/company-brain-migration.js +60 -0
- package/dist/company-brain-source.js +177 -0
- package/dist/company-brain-worker.js +18 -0
- package/dist/conducao-texto.js +61 -0
- package/dist/conducao.js +876 -0
- package/dist/contrato-publico.js +39 -0
- package/dist/creation-operation-store.js +251 -0
- package/dist/creation-operation.js +148 -0
- package/dist/decisao-autonoma.js +183 -0
- package/dist/delegation.js +79 -0
- package/dist/demo.js +120 -0
- package/dist/docs.js +828 -0
- package/dist/doctor.js +183 -24
- package/dist/entrega-pr.js +117 -0
- package/dist/escopo-escrita.js +71 -0
- package/dist/estado-thread.js +222 -0
- package/dist/evalrunner.js +12 -0
- package/dist/fabrica-estado.js +329 -0
- package/dist/fabrica-publicar.js +76 -0
- package/dist/fix.js +21 -0
- package/dist/gates.js +55 -9
- package/dist/handoff.js +39 -23
- package/dist/hitl-canais.js +333 -0
- package/dist/hitl-classificacao.js +131 -0
- package/dist/hitl-contract.js +465 -0
- package/dist/hitl-estado.js +136 -0
- package/dist/hitl-gates.js +554 -0
- package/dist/hitl-ingress-receipt.js +382 -0
- package/dist/hitl-local-atestado.js +57 -0
- package/dist/hitl-local-receipt.js +328 -0
- package/dist/hitl-local.js +143 -0
- package/dist/hitl-lock.js +139 -0
- package/dist/hitl-lote.js +223 -0
- package/dist/hitl-native-offer.js +97 -0
- package/dist/hitl-native.js +65 -0
- package/dist/hitl-presentation.js +209 -0
- package/dist/hitl-public-receipt.js +176 -0
- package/dist/hitl-resumo.js +209 -0
- package/dist/hitl-sessions.js +475 -0
- package/dist/hitl.js +711 -0
- package/dist/horario.js +269 -0
- package/dist/hosts.js +198 -22
- package/dist/index.js +1736 -93
- package/dist/indice.js +99 -0
- package/dist/init.js +28 -3
- package/dist/integracoes-locais.js +17 -0
- package/dist/leases.js +65 -21
- package/dist/ledger-stats.js +272 -0
- package/dist/ledger.js +107 -2
- package/dist/licoes.js +215 -0
- package/dist/liveness.js +218 -0
- package/dist/maestro-actions.js +51 -0
- package/dist/maestro-authority.js +152 -0
- package/dist/maestro-cli.js +97 -0
- package/dist/maestro-contract.js +55 -0
- package/dist/maestro-discovery.js +132 -0
- package/dist/maestro-runtime.js +268 -0
- package/dist/maestro-snapshot.js +86 -0
- package/dist/maestro-sources.js +224 -0
- package/dist/manifest.js +165 -6
- package/dist/maquina.js +102 -0
- package/dist/master-audit.js +101 -0
- package/dist/master-batch.js +43 -0
- package/dist/master-digest.js +149 -0
- package/dist/master-migracao.js +155 -0
- package/dist/master.js +361 -77
- package/dist/mcp-artifacts.js +234 -0
- package/dist/mcp-git.js +433 -0
- package/dist/mcp-install.js +310 -0
- package/dist/mcp-maestro.js +25 -0
- package/dist/mcp-server.js +469 -0
- package/dist/mcp-ship.js +436 -0
- package/dist/mcp-verify.js +173 -0
- package/dist/memoria-humana.js +207 -0
- package/dist/memoria.js +314 -78
- package/dist/memory-migration.js +279 -0
- package/dist/memory-prospective.js +148 -0
- package/dist/modos-migracao.js +191 -0
- package/dist/modos.js +151 -15
- package/dist/monitor-lock.js +110 -0
- package/dist/objective.js +449 -0
- package/dist/ocupacao.js +267 -0
- package/dist/onboarding.js +303 -0
- package/dist/orkmind.js +389 -90
- package/dist/orquestracao.js +96 -69
- package/dist/phase.js +596 -150
- package/dist/playbook-capabilities.js +150 -0
- package/dist/playbook-contracts.js +188 -0
- package/dist/portfolio-context.js +61 -0
- package/dist/portfolio.js +180 -0
- package/dist/preflight.js +207 -0
- package/dist/process-audit.js +112 -0
- package/dist/project-state.js +93 -0
- package/dist/prompts.js +25 -5
- package/dist/prova-minima.js +112 -0
- package/dist/pulse-cadencia.js +163 -0
- package/dist/pulse-consentimento.js +260 -0
- package/dist/pulse-delivery.js +323 -0
- package/dist/pulse-resposta.js +542 -0
- package/dist/pulse.js +262 -0
- package/dist/ratelimit.js +35 -2
- package/dist/recall.js +80 -3
- package/dist/redacao-saida.js +45 -0
- package/dist/redacao-url.js +66 -0
- package/dist/retry.js +637 -115
- package/dist/roadmap-reservas.js +243 -0
- package/dist/runtime-ambiente.js +38 -0
- package/dist/runtime-context.js +215 -0
- package/dist/runtime-profiles.js +869 -0
- package/dist/runtimes.js +103 -0
- package/dist/sandbox.js +9 -0
- package/dist/session-events.js +203 -0
- package/dist/session-watcher-claude.js +637 -0
- package/dist/session-watcher.js +683 -0
- package/dist/sessoes-adopt.js +154 -0
- package/dist/sessoes-inventario.js +159 -0
- package/dist/sessoes.js +16 -35
- package/dist/setup.js +691 -0
- package/dist/ship.js +150 -15
- package/dist/slug.js +1 -1
- package/dist/thread-close.js +115 -0
- package/dist/thread.js +142 -28
- package/dist/tokens.js +1 -1
- package/dist/util.js +4 -2
- package/dist/verify-sandbox.js +265 -0
- package/dist/verify.js +270 -25
- package/dist/versao.js +60 -0
- package/dist/worktree.js +31 -2
- package/dist/write-activation.js +291 -0
- package/dist/yaml.js +2 -0
- package/eval/casos/onboarding.json +102 -0
- package/eval/casos/orkastery-bootstrap.json +35 -1
- package/eval/casos/scope-check-capability-map.json +45 -7
- package/eval/casos/ship-release.json +2 -2
- package/eval/fixtures/b0-slug-e-modos/caso.json +35 -22
- package/eval/fixtures/b2-master-log/caso.json +1 -1
- package/eval/fixtures/fx-adapter-editado-detectado/caso.json +19 -0
- package/eval/fixtures/fx-auto-quiet/caso.json +11 -0
- package/eval/fixtures/fx-blanket-approve/caso.json +10 -0
- package/eval/fixtures/fx-check-runtime-cruzado/caso.json +20 -0
- package/eval/fixtures/fx-codex-dry/caso.json +18 -0
- package/eval/fixtures/fx-donewhen-executavel/caso.json +15 -0
- package/eval/fixtures/fx-estado-dividido/caso.json +15 -0
- package/eval/fixtures/fx-fase-orfa/caso.json +116 -0
- package/eval/fixtures/fx-happy/caso.json +6 -4
- package/eval/fixtures/fx-hitl-latency/caso.json +20 -0
- package/eval/fixtures/fx-indice-reversao/caso.json +25 -0
- package/eval/fixtures/fx-listagem-abertas/caso.json +16 -0
- package/eval/fixtures/fx-maestro-bootstrap/caso.json +21 -0
- package/eval/fixtures/fx-modo-aposentado-escritor/caso.json +21 -0
- package/eval/fixtures/fx-modo-aposentado-leitor/caso.json +16 -0
- package/eval/fixtures/fx-objective-oscillation/caso.json +14 -0
- package/eval/fixtures/fx-omnicanal/caso.json +17 -0
- package/eval/fixtures/fx-sensores-runtime/caso.json +17 -0
- package/monitor/company-brain.cjs +17 -0
- package/monitor/pulse-scope.cjs +45 -0
- package/monitor/pulse.cron +18 -0
- package/monitor/varredura-pulse.sh +27 -0
- package/package.json +25 -4
- package/schemas/claims.schema.json +25 -0
- package/schemas/company-brain.schema.json +1158 -0
- package/schemas/creation-operation.schema.json +365 -0
- package/schemas/maestro-snapshot.schema.json +2716 -0
- package/skills/core/onboarding/SKILL.md +50 -0
- package/skills/core/orkastery-bootstrap/SKILL.md +95 -65
- package/skills/core/thread-state/SKILL.md +3 -1
- package/skills/governance/scope-check-capability-map/SKILL.md +17 -7
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** Runtime Codex governado pelo controller app-server. Assinatura ChatGPT obrigatória.
|
|
3
|
+
* Helpers exec/rollout permanecem para leitura de histórico; não são fallback de despacho.
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.SANDBOX_PADRAO = exports.SANDBOXES_DO_CODEX = exports.ENVS_REMOVIDAS_DO_DESPACHO = exports.NOME_ADAPTER = void 0;
|
|
40
|
+
exports.ambienteDoDespacho = ambienteDoDespacho;
|
|
41
|
+
exports.disponivel = disponivel;
|
|
42
|
+
exports.versao = versao;
|
|
43
|
+
exports.casaDoCodex = casaDoCodex;
|
|
44
|
+
exports.conferirAuth = conferirAuth;
|
|
45
|
+
exports.consultarRollouts = consultarRollouts;
|
|
46
|
+
exports.sondarSandbox = sondarSandbox;
|
|
47
|
+
exports.montarComando = montarComando;
|
|
48
|
+
exports.extrairThreadId = extrairThreadId;
|
|
49
|
+
exports.acharRollout = acharRollout;
|
|
50
|
+
exports.parseRateLimitCodex = parseRateLimitCodex;
|
|
51
|
+
exports.despachar = despachar;
|
|
52
|
+
exports.logs = logs;
|
|
53
|
+
const codex_controller_1 = require("./codex-controller");
|
|
54
|
+
const runtime_context_1 = require("../runtime-context");
|
|
55
|
+
const fs = __importStar(require("node:fs"));
|
|
56
|
+
const path = __importStar(require("node:path"));
|
|
57
|
+
const util_1 = require("../util");
|
|
58
|
+
const runtime_ambiente_1 = require("../runtime-ambiente");
|
|
59
|
+
const claude_bg_1 = require("./claude-bg");
|
|
60
|
+
const runtime_profiles_1 = require("../runtime-profiles");
|
|
61
|
+
exports.NOME_ADAPTER = 'codex';
|
|
62
|
+
/**
|
|
63
|
+
* Variaveis que REDIRECIONAM o codex para um provider pago por token.
|
|
64
|
+
*
|
|
65
|
+
* O despacho usa a sessao autenticada (`codex login`, plano ChatGPT). Uma OPENAI_API_KEY
|
|
66
|
+
* no ambiente pode virar cobranca por token sem ninguem pedir, o mesmo risco do claude-bg,
|
|
67
|
+
* entao o adapter LIMPA essas variaveis do ambiente do filho em vez de confiar que o CLI
|
|
68
|
+
* vai ignora-las.
|
|
69
|
+
*/
|
|
70
|
+
exports.ENVS_REMOVIDAS_DO_DESPACHO = [...runtime_ambiente_1.ENVS_DE_PROVIDER_PAGO, 'CODEX_API_KEY'];
|
|
71
|
+
/**
|
|
72
|
+
* O ambiente do despacho: o do processo, sem as variaveis de provider pago e sem
|
|
73
|
+
* `CODEX_API_KEY`. A lista da higiene de runtime nao cobre a chave especifica do Codex,
|
|
74
|
+
* entao o adapter a remove aqui: a assinatura ChatGPT continua sendo a unica credencial.
|
|
75
|
+
*/
|
|
76
|
+
function ambienteDoDespacho(base = process.env, perfil) {
|
|
77
|
+
const env = (0, runtime_ambiente_1.ambienteDeAssinatura)(base);
|
|
78
|
+
for (const nome of exports.ENVS_REMOVIDAS_DO_DESPACHO)
|
|
79
|
+
delete env[nome];
|
|
80
|
+
// I-33 (D2): o `CODEX_HOME` do filho vem do `codexHome` do perfil; sem perfil, o do processo.
|
|
81
|
+
if (perfil && (perfil.runtime !== 'codex' || !perfil.codexHome))
|
|
82
|
+
throw new Error('runtime.profiles.invalid: perfil sem codexHome no despacho codex');
|
|
83
|
+
return (0, runtime_profiles_1.ambienteComPerfil)(env, perfil);
|
|
84
|
+
}
|
|
85
|
+
function exec(cmd, args, cwd, timeoutMs, ambiente = ambienteDoDespacho()) {
|
|
86
|
+
return (0, util_1.exec)(cmd, args, cwd, timeoutMs, ambiente);
|
|
87
|
+
}
|
|
88
|
+
/** Modos de sandbox aceitos pelo `codex exec --sandbox`. */
|
|
89
|
+
exports.SANDBOXES_DO_CODEX = ['read-only', 'workspace-write', 'danger-full-access'];
|
|
90
|
+
/** Sandbox padrao do despacho: escreve no workspace, sem rede para o agente. */
|
|
91
|
+
exports.SANDBOX_PADRAO = 'workspace-write';
|
|
92
|
+
/** O runtime esta disponivel nesta maquina? */
|
|
93
|
+
function disponivel() {
|
|
94
|
+
return (0, util_1.noPath)('codex');
|
|
95
|
+
}
|
|
96
|
+
/** Versao do runtime, para o `ork doctor`. */
|
|
97
|
+
function versao() {
|
|
98
|
+
const r = exec('codex', ['--version'], undefined, 30000);
|
|
99
|
+
return r.ok ? r.stdout.trim() : null;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Raiz do estado do Codex: o `codexHome` do perfil da sessao (I-33, D4) ou, sem perfil, o
|
|
103
|
+
* `CODEX_HOME` do processo com fallback `~/.codex`.
|
|
104
|
+
*/
|
|
105
|
+
function casaDoCodex(perfil) {
|
|
106
|
+
return (0, runtime_profiles_1.diretorioEfetivo)('codex', perfil);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* I-33 (D7, D13): `codex login status` com o env do perfil. Aprova so o login da ASSINATURA
|
|
110
|
+
* ("Logged in using ChatGPT"); login por API key sai 0 mas cobra por token: `pago`, nunca despacha,
|
|
111
|
+
* e o trecho mascarado da chave nao vai ao detalhe. O `ork` nunca abre nada dentro do
|
|
112
|
+
* `CODEX_HOME`: quem responde e o CLI.
|
|
113
|
+
*/
|
|
114
|
+
function conferirAuth(perfil) {
|
|
115
|
+
let ambiente;
|
|
116
|
+
try {
|
|
117
|
+
ambiente = ambienteDoDespacho(process.env, perfil);
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
return { ok: false, detalhe: e.message };
|
|
121
|
+
}
|
|
122
|
+
const r = exec('codex', ['login', 'status'], undefined, 30000, ambiente);
|
|
123
|
+
// A14: sem codigo de saida (timeout, sinal ou binario ausente), a conferencia e inconclusiva.
|
|
124
|
+
if (r.code === -1)
|
|
125
|
+
return { ok: false, transitorio: true, detalhe: 'codex login status sem resposta (timeout, sinal ou binario ausente)' };
|
|
126
|
+
const linha = (r.stdout + '\n' + r.stderr).split('\n').map(l => l.trim()).find(l => l !== '') ?? '';
|
|
127
|
+
const trecho = linha.replace(/\p{Cc}/gu, '').slice(0, 120);
|
|
128
|
+
if (!r.ok)
|
|
129
|
+
return { ok: false, detalhe: `codex login status saiu ${r.code}${trecho ? `: ${trecho}` : ''}` };
|
|
130
|
+
if (/logged in using chatgpt/i.test(trecho))
|
|
131
|
+
return { ok: true, detalhe: 'codex login status: Logged in using ChatGPT' };
|
|
132
|
+
return { ok: false, pago: true, detalhe: /api key/i.test(trecho) ? 'codex login status: login por API key (provider pago)'
|
|
133
|
+
: 'codex login status: login sem assinatura ChatGPT comprovada (tratado como provider pago)' };
|
|
134
|
+
}
|
|
135
|
+
/** Somente metadados do cabeçalho e eventos terminais; prompts nunca saem do leitor. */
|
|
136
|
+
function consultarRollouts(todas = false, casa = casaDoCodex()) {
|
|
137
|
+
const fontes = [path.join(casa, 'sessions'), ...(todas ? [path.join(casa, 'archived_sessions')] : [])];
|
|
138
|
+
const resultadosFontes = [];
|
|
139
|
+
const sessoes = [];
|
|
140
|
+
const ids = new Set();
|
|
141
|
+
for (const dirFonte of fontes) {
|
|
142
|
+
const fonte = { origem: dirFonte, ok: true, detalhe: '' };
|
|
143
|
+
resultadosFontes.push(fonte);
|
|
144
|
+
const falhar = (origem, detalhe) => {
|
|
145
|
+
fonte.ok = false;
|
|
146
|
+
fonte.detalhe = 'inventário parcial; fonte contém erro de diretório, leitura ou metadados';
|
|
147
|
+
if (origem === dirFonte)
|
|
148
|
+
fonte.detalhe = detalhe;
|
|
149
|
+
else
|
|
150
|
+
resultadosFontes.push({ origem, ok: false, detalhe });
|
|
151
|
+
};
|
|
152
|
+
const visitar = (dir) => {
|
|
153
|
+
let entradas;
|
|
154
|
+
try {
|
|
155
|
+
if (!fs.lstatSync(dir).isDirectory())
|
|
156
|
+
throw new Error('diretório inválido');
|
|
157
|
+
entradas = fs.readdirSync(dir, { withFileTypes: true });
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
falhar(dir, 'diretório inacessível ou inválido');
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
for (const entrada of entradas) {
|
|
164
|
+
const arquivo = path.join(dir, entrada.name);
|
|
165
|
+
if (entrada.isSymbolicLink()) {
|
|
166
|
+
falhar(arquivo, 'link inesperado');
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (entrada.isDirectory()) {
|
|
170
|
+
visitar(arquivo);
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (!entrada.isFile() || !entrada.name.endsWith('.jsonl'))
|
|
174
|
+
continue;
|
|
175
|
+
try {
|
|
176
|
+
const fd = fs.openSync(arquivo, 'r');
|
|
177
|
+
let primeira, cauda;
|
|
178
|
+
try {
|
|
179
|
+
const tamanho = fs.fstatSync(fd).size;
|
|
180
|
+
const cab = Buffer.alloc(Math.min(tamanho, 65536));
|
|
181
|
+
fs.readSync(fd, cab, 0, cab.length, 0);
|
|
182
|
+
primeira = cab.toString('utf8').split('\n')[0];
|
|
183
|
+
const fim = Buffer.alloc(Math.min(tamanho, 131072));
|
|
184
|
+
fs.readSync(fd, fim, 0, fim.length, tamanho - fim.length);
|
|
185
|
+
cauda = fim.toString('utf8');
|
|
186
|
+
}
|
|
187
|
+
finally {
|
|
188
|
+
fs.closeSync(fd);
|
|
189
|
+
}
|
|
190
|
+
const meta = JSON.parse(primeira);
|
|
191
|
+
const p = meta.payload;
|
|
192
|
+
if (meta.type !== 'session_meta' || !p || typeof p.id !== 'string' ||
|
|
193
|
+
!/^[a-f0-9-]{8,}$/i.test(p.id) || typeof p.cwd !== 'string' || !path.isAbsolute(p.cwd) ||
|
|
194
|
+
ids.has(p.id))
|
|
195
|
+
throw new Error('metadados inválidos ou duplicados');
|
|
196
|
+
ids.add(p.id);
|
|
197
|
+
// Ausência de evento terminal é desconhecimento, não prova de processo vivo.
|
|
198
|
+
let state = 'unknown';
|
|
199
|
+
for (const linha of cauda.split('\n')) {
|
|
200
|
+
try {
|
|
201
|
+
const e = JSON.parse(linha);
|
|
202
|
+
if (e.type === 'event_msg' && e.payload?.type === 'task_started')
|
|
203
|
+
state = 'unknown';
|
|
204
|
+
if (e.type === 'event_msg' && ['task_complete', 'task_aborted'].includes(e.payload?.type))
|
|
205
|
+
state = 'completed';
|
|
206
|
+
}
|
|
207
|
+
catch { /* primeira/última linha do recorte pode estar parcial */ }
|
|
208
|
+
}
|
|
209
|
+
if (todas || state !== 'completed')
|
|
210
|
+
sessoes.push({ sessionId: p.id, cwd: p.cwd, state, kind: 'codex-rollout' });
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
falhar(arquivo, 'leitura ou metadados inválidos ou duplicados');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
// O runtime é opcional: somente ENOENT antes da consulta prova fonte ausente.
|
|
218
|
+
// Erros durante a visita (inclusive desaparecimento) continuam invalidando a fonte.
|
|
219
|
+
try {
|
|
220
|
+
fs.lstatSync(dirFonte);
|
|
221
|
+
}
|
|
222
|
+
catch (e) {
|
|
223
|
+
if (e.code === 'ENOENT') {
|
|
224
|
+
fonte.detalhe = 'diretório opcional ausente';
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
falhar(dirFonte, 'diretório inacessível ou inválido');
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
visitar(dirFonte);
|
|
231
|
+
}
|
|
232
|
+
const ok = resultadosFontes.every(f => f.ok);
|
|
233
|
+
return { ok, sessoes, fontes, resultadosFontes,
|
|
234
|
+
detalhe: ok ? '' : 'inventário Codex incompleto: consulte as fontes com erro' };
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* A sonda deterministica do sandbox: roda `true` dentro do sandbox do Codex, SEM LLM.
|
|
238
|
+
*
|
|
239
|
+
* Numa maquina sa ela sai 0. Onde o bubblewrap nao consegue criar user namespace
|
|
240
|
+
* (Ubuntu com `apparmor_restrict_unprivileged_userns=1` e sem o pacote bubblewrap do
|
|
241
|
+
* sistema), ela sai != 0 com o erro real do bwrap, e o despacho sandboxado viraria
|
|
242
|
+
* narrativa sem execucao. E por isso que ela e check de `ork doctor`, nao detalhe.
|
|
243
|
+
*/
|
|
244
|
+
function sondarSandbox() {
|
|
245
|
+
const r = exec('codex', ['sandbox', 'true'], undefined, 30000);
|
|
246
|
+
const saida = (r.stdout + ' ' + r.stderr).trim();
|
|
247
|
+
return {
|
|
248
|
+
ok: r.ok,
|
|
249
|
+
detalhe: r.ok ? 'codex sandbox true saiu 0' : saida.slice(0, 200) || `exit ${r.code}`,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
/** Monta a linha de comando exata do despacho (usada tambem pelo `--dry-run`). */
|
|
253
|
+
function montarComando(pedido) {
|
|
254
|
+
const args = [
|
|
255
|
+
'exec',
|
|
256
|
+
'--sandbox',
|
|
257
|
+
pedido.sandbox ?? exports.SANDBOX_PADRAO,
|
|
258
|
+
// Headless de verdade: sem TTY nao ha quem aprove, entao pedir aprovacao e travar.
|
|
259
|
+
'-c',
|
|
260
|
+
'approval_policy=never',
|
|
261
|
+
'--skip-git-repo-check',
|
|
262
|
+
'-C',
|
|
263
|
+
pedido.cwd,
|
|
264
|
+
'--json',
|
|
265
|
+
];
|
|
266
|
+
if (pedido.model)
|
|
267
|
+
args.push('-m', pedido.model);
|
|
268
|
+
if (pedido.effort)
|
|
269
|
+
args.push('-c', `model_reasoning_effort=${JSON.stringify(pedido.effort)}`);
|
|
270
|
+
args.push(pedido.prompt);
|
|
271
|
+
return ['codex', ...args];
|
|
272
|
+
}
|
|
273
|
+
/** Extrai o `thread_id` do evento `thread.started` do stream JSONL. */
|
|
274
|
+
function extrairThreadId(saida) {
|
|
275
|
+
for (const linha of saida.split('\n')) {
|
|
276
|
+
if (!linha.includes('thread.started'))
|
|
277
|
+
continue;
|
|
278
|
+
try {
|
|
279
|
+
const evento = JSON.parse(linha);
|
|
280
|
+
if (evento.type === 'thread.started' && typeof evento.thread_id === 'string') {
|
|
281
|
+
return evento.thread_id;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
/* linha parcial ainda sendo escrita nao invalida a espera */
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Procura o rollout da sessao no estado do proprio Codex.
|
|
292
|
+
*
|
|
293
|
+
* O Codex grava `sessions/AAAA/MM/DD/rollout-<ts>-<thread_id>.jsonl` (medido na 0.153.4).
|
|
294
|
+
* So os dias mais recentes sao varridos: um despacho de agora nao mora num rollout de
|
|
295
|
+
* semanas atras, e varrer o historico inteiro pune quem usa o runtime ha meses.
|
|
296
|
+
*/
|
|
297
|
+
function acharRollout(threadId, dias = 3, casa = casaDoCodex()) {
|
|
298
|
+
const raiz = path.join(casa, 'sessions');
|
|
299
|
+
if (!fs.existsSync(raiz))
|
|
300
|
+
return null;
|
|
301
|
+
const diasRecentes = [];
|
|
302
|
+
const anos = fs.readdirSync(raiz).sort().reverse();
|
|
303
|
+
for (const ano of anos) {
|
|
304
|
+
const dirAno = path.join(raiz, ano);
|
|
305
|
+
if (!fs.statSync(dirAno).isDirectory())
|
|
306
|
+
continue;
|
|
307
|
+
for (const mes of fs.readdirSync(dirAno).sort().reverse()) {
|
|
308
|
+
const dirMes = path.join(dirAno, mes);
|
|
309
|
+
if (!fs.statSync(dirMes).isDirectory())
|
|
310
|
+
continue;
|
|
311
|
+
for (const dia of fs.readdirSync(dirMes).sort().reverse()) {
|
|
312
|
+
diasRecentes.push(path.join(dirMes, dia));
|
|
313
|
+
if (diasRecentes.length >= dias)
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
if (diasRecentes.length >= dias)
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
if (diasRecentes.length >= dias)
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
for (const dir of diasRecentes) {
|
|
323
|
+
if (!fs.statSync(dir).isDirectory())
|
|
324
|
+
continue;
|
|
325
|
+
const achado = fs.readdirSync(dir).find((f) => f.startsWith('rollout-') && f.endsWith(`-${threadId}.jsonl`));
|
|
326
|
+
if (achado)
|
|
327
|
+
return path.join(dir, achado);
|
|
328
|
+
}
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Rate limit na saida real do Codex.
|
|
333
|
+
*
|
|
334
|
+
* Reusa o reconhecimento do claude-bg (frases genericas + horario de reset) e acrescenta
|
|
335
|
+
* as frases proprias do plano ChatGPT. Frase reconhecida sem horario volta `sem-horario`:
|
|
336
|
+
* a janela padrao e decisao da fila do B3, nunca chute do adapter.
|
|
337
|
+
*/
|
|
338
|
+
const FRASES_DO_CODEX = [
|
|
339
|
+
/hit your usage limit/i,
|
|
340
|
+
/usage limit(?:s)? (?:reached|exceeded)/i,
|
|
341
|
+
/plan limit/i,
|
|
342
|
+
];
|
|
343
|
+
function parseRateLimitCodex(saida, agoraMs = Date.now()) {
|
|
344
|
+
const generico = (0, claude_bg_1.parseRateLimit)(saida, agoraMs);
|
|
345
|
+
if (generico)
|
|
346
|
+
return generico;
|
|
347
|
+
const frase = FRASES_DO_CODEX.find((r) => r.test(saida ?? ''));
|
|
348
|
+
if (!frase)
|
|
349
|
+
return null;
|
|
350
|
+
const linha = (saida ?? '').split('\n').find((l) => frase.test(l)) ?? saida;
|
|
351
|
+
return { resetEm: null, fonte: 'sem-horario', trecho: linha.trim().slice(0, 200) };
|
|
352
|
+
}
|
|
353
|
+
/** Despacho governado exige vínculo: nenhum fallback implícito para codex exec. */
|
|
354
|
+
function despachar(pedido) {
|
|
355
|
+
if (!pedido.vinculo)
|
|
356
|
+
return { ok: false, comando: [], sessionId: null, verificada: false, stdout: '', stderr: '',
|
|
357
|
+
erro: 'runtime.unavailable: despacho Codex exige vínculo de thread/fase/prompt; transporte legado recusado' };
|
|
358
|
+
if (pedido.contextoRuntime) {
|
|
359
|
+
try {
|
|
360
|
+
if (pedido.contextoRuntime.host !== 'codex')
|
|
361
|
+
throw Error('runtime.context.invalid: host Codex esperado');
|
|
362
|
+
if (pedido.contextoRuntime.threadId !== pedido.vinculo.thread)
|
|
363
|
+
throw Error('runtime.context.scope: thread do contexto difere do despacho');
|
|
364
|
+
(0, runtime_context_1.validarContextoRuntime)(pedido.contextoRuntime, pedido.cwd);
|
|
365
|
+
}
|
|
366
|
+
catch (e) {
|
|
367
|
+
return { ok: false, comando: [], sessionId: null, verificada: false, stdout: '', stderr: '', erro: e.message };
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
let ambiente;
|
|
371
|
+
try {
|
|
372
|
+
ambiente = { ...ambienteDoDespacho(process.env, pedido.perfil), ...(pedido.ambienteExtra ?? {}) };
|
|
373
|
+
}
|
|
374
|
+
catch (e) {
|
|
375
|
+
return { ok: false, comando: [], sessionId: null, verificada: false, stdout: '', stderr: '', erro: e.message };
|
|
376
|
+
}
|
|
377
|
+
const r = (0, codex_controller_1.despacharComController)(pedido, ambiente);
|
|
378
|
+
if (r.ok)
|
|
379
|
+
return r;
|
|
380
|
+
// I-33 (D1): o incidente de 18/09 ("Your workspace is out of credits", usage_limit_exceeded)
|
|
381
|
+
// deixa de ser `runtime.unavailable` generico quando a frase aparece na falha do despacho.
|
|
382
|
+
const falhaDeConta = (0, claude_bg_1.parseFalhaDeConta)([r.erro ?? '', r.stderr].join('\n'));
|
|
383
|
+
return falhaDeConta ? { ...r, falhaDeConta, erro: `${falhaDeConta.motivo}: ${falhaDeConta.trecho}` } : r;
|
|
384
|
+
}
|
|
385
|
+
/** Le os eventos ja escritos no log de um despacho (texto cru do stream `--json`). */
|
|
386
|
+
function logs(logPath, linhas = 60) {
|
|
387
|
+
if (!fs.existsSync(logPath))
|
|
388
|
+
return { ok: false, texto: `log nao encontrado: ${logPath}` };
|
|
389
|
+
const uteis = fs
|
|
390
|
+
.readFileSync(logPath, 'utf8')
|
|
391
|
+
.split('\n')
|
|
392
|
+
.filter((l) => l.trim() !== '');
|
|
393
|
+
return { ok: true, texto: uteis.slice(-linhas).join('\n') };
|
|
394
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
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.FIM_AGENTS_ORK = exports.INICIO_AGENTS_ORK = void 0;
|
|
37
|
+
exports.blocoAgentsMd = blocoAgentsMd;
|
|
38
|
+
exports.atualizarAgentsMd = atualizarAgentsMd;
|
|
39
|
+
/** Bloco de instrucoes do Orkastery em AGENTS.md, preservando todo texto humano. */
|
|
40
|
+
const fs = __importStar(require("node:fs"));
|
|
41
|
+
const path = __importStar(require("node:path"));
|
|
42
|
+
const util_1 = require("./util");
|
|
43
|
+
exports.INICIO_AGENTS_ORK = '<!-- orkastery:begin -->';
|
|
44
|
+
exports.FIM_AGENTS_ORK = '<!-- orkastery:end -->';
|
|
45
|
+
function seguro(valor) {
|
|
46
|
+
return valor.replace(/[\r\n\0`]+/g, ' ').trim();
|
|
47
|
+
}
|
|
48
|
+
function blocoAgentsMd(manifesto) {
|
|
49
|
+
const comandos = Object.entries(manifesto.verify)
|
|
50
|
+
.filter((item) => typeof item[1] === 'string' && item[1].trim() !== '')
|
|
51
|
+
.map(([nome, comando]) => `- ${seguro(nome)}: \`${seguro(comando)}\``);
|
|
52
|
+
return `${exports.INICIO_AGENTS_ORK}
|
|
53
|
+
## Orkastery
|
|
54
|
+
|
|
55
|
+
Projeto: **${seguro(manifesto.project.name)}** (${seguro(manifesto.project.abbrev)}). Branch base: \`${seguro(manifesto.worktree.base_branch)}\`.
|
|
56
|
+
|
|
57
|
+
- Comece com \`ork doctor\`, \`ork onboarding\` e \`ork thread status <thread>\`.
|
|
58
|
+
- Conduza o ciclo GOAL → PLAN → GO → CHECK → SHIP → MASTER pelo \`ork\`.
|
|
59
|
+
- Respeite o modo da thread: ${manifesto.conduction.allowed_modes.map(m => `#${m[0].toUpperCase()}${m.slice(1)}`).join(', ')}.
|
|
60
|
+
- Edite produto somente na worktree vinculada; estado em \`.orkastery/\` pertence ao núcleo.
|
|
61
|
+
- PLAN não implementa. GO usa commits atômicos. CHECK não corrige. SHIP acontece por \`ork ship\`.
|
|
62
|
+
- Toda alegação exige claim e comando reproduzível; self-report não é evidência.
|
|
63
|
+
${comandos.length ? `\nVerificações do manifesto:\n\n${comandos.join('\n')}\n` : ''}
|
|
64
|
+
Este bloco é mantido por \`ork init\`. Edite livremente o restante do arquivo.
|
|
65
|
+
${exports.FIM_AGENTS_ORK}`;
|
|
66
|
+
}
|
|
67
|
+
/** Cria ou substitui somente o bloco delimitado. Marcadores ambiguos recusam sem escrita. */
|
|
68
|
+
function atualizarAgentsMd(raiz, manifesto) {
|
|
69
|
+
const caminho = path.join(raiz, 'AGENTS.md');
|
|
70
|
+
const anterior = fs.existsSync(caminho) ? fs.readFileSync(caminho, 'utf8') : '';
|
|
71
|
+
const inicios = anterior.split(exports.INICIO_AGENTS_ORK).length - 1;
|
|
72
|
+
const fins = anterior.split(exports.FIM_AGENTS_ORK).length - 1;
|
|
73
|
+
if (inicios !== fins || inicios > 1 || (inicios === 1 && anterior.indexOf(exports.INICIO_AGENTS_ORK) > anterior.indexOf(exports.FIM_AGENTS_ORK))) {
|
|
74
|
+
throw new Error('AGENTS.md possui marcadores Orkastery ambiguos; corrija o bloco antes de rodar ork init');
|
|
75
|
+
}
|
|
76
|
+
const bloco = blocoAgentsMd(manifesto);
|
|
77
|
+
const proximo = inicios === 1
|
|
78
|
+
? anterior.slice(0, anterior.indexOf(exports.INICIO_AGENTS_ORK)) + bloco + anterior.slice(anterior.indexOf(exports.FIM_AGENTS_ORK) + exports.FIM_AGENTS_ORK.length)
|
|
79
|
+
: anterior === '' ? bloco + '\n' : anterior + (anterior.endsWith('\n') ? '\n' : '\n\n') + bloco + '\n';
|
|
80
|
+
if (proximo === anterior)
|
|
81
|
+
return { caminho, estado: 'inalterado' };
|
|
82
|
+
(0, util_1.gravar)(caminho, proximo);
|
|
83
|
+
return { caminho, estado: anterior === '' ? 'criado' : 'atualizado' };
|
|
84
|
+
}
|
package/dist/auditoria.js
CHANGED
|
@@ -77,6 +77,7 @@ const path = __importStar(require("node:path"));
|
|
|
77
77
|
const gates_1 = require("./gates");
|
|
78
78
|
const prompts_1 = require("./prompts");
|
|
79
79
|
const util_1 = require("./util");
|
|
80
|
+
const horario_1 = require("./horario");
|
|
80
81
|
// ---------------------------------------------------------------------------
|
|
81
82
|
// Motivos tipados da auditoria
|
|
82
83
|
// ---------------------------------------------------------------------------
|
|
@@ -409,7 +410,7 @@ exports.PACKS = {
|
|
|
409
410
|
id: 'process',
|
|
410
411
|
titulo: 'Processo (meta-auditor)',
|
|
411
412
|
objetivo: 'O unico pack que audita o METODO e nao o produto: le o ledger, os POSTMORTEMs e os MASTER logs e propoe mudanca no proprio Orkastery.',
|
|
412
|
-
estagioMinimo: '
|
|
413
|
+
estagioMinimo: 'nascente',
|
|
413
414
|
fonte: 'ledger',
|
|
414
415
|
referencias: ['references/definition-of-done.md'],
|
|
415
416
|
evidencias: [
|
|
@@ -425,7 +426,7 @@ exports.PACKS = {
|
|
|
425
426
|
{
|
|
426
427
|
id: 'PR2',
|
|
427
428
|
regra: 'Thread entregue sem score humano registrado, parada na fila de batch.',
|
|
428
|
-
evidencia: '
|
|
429
|
+
evidencia: 'thread entregue sem master_done.por humano correspondente ao score',
|
|
429
430
|
},
|
|
430
431
|
{
|
|
431
432
|
id: 'PR3',
|
|
@@ -545,9 +546,11 @@ function minutosDoHorario(bruto) {
|
|
|
545
546
|
* governando o custo daquela rodada.
|
|
546
547
|
*/
|
|
547
548
|
function janelaDeCusto(manifesto, quando = new Date()) {
|
|
548
|
-
|
|
549
|
-
const
|
|
550
|
-
const
|
|
549
|
+
// I-35: a janela e o "agora" sao do fuso do dono; sem owner.timezone, o do sistema (como antes).
|
|
550
|
+
const fuso = (0, horario_1.lerFusoDoDono)(manifesto.owner?.timezone).fuso;
|
|
551
|
+
const local = (0, horario_1.partesLocais)(quando, fuso);
|
|
552
|
+
const agora = `${local.hora}:${local.minuto}`;
|
|
553
|
+
const rotulo = (0, horario_1.rotuloDoFuso)(fuso, quando);
|
|
551
554
|
const bruta = (manifesto.audit?.janela_ociosa ?? '').trim();
|
|
552
555
|
if (bruta === '') {
|
|
553
556
|
return {
|
|
@@ -572,7 +575,7 @@ function janelaDeCusto(manifesto, quando = new Date()) {
|
|
|
572
575
|
detalhe: `audit.janela_ociosa invalida ("${bruta}"): esperado HH:MM-HH:MM`,
|
|
573
576
|
};
|
|
574
577
|
}
|
|
575
|
-
const minutosAgora =
|
|
578
|
+
const minutosAgora = Number(local.hora) * 60 + Number(local.minuto);
|
|
576
579
|
const dentro = inicio <= fim
|
|
577
580
|
? minutosAgora >= inicio && minutosAgora < fim
|
|
578
581
|
: minutosAgora >= inicio || minutosAgora < fim;
|
|
@@ -583,8 +586,8 @@ function janelaDeCusto(manifesto, quando = new Date()) {
|
|
|
583
586
|
dentro,
|
|
584
587
|
agora,
|
|
585
588
|
detalhe: dentro
|
|
586
|
-
? `${agora} esta dentro da janela ociosa ${bruta}`
|
|
587
|
-
: `${agora} esta FORA da janela ociosa ${bruta}`,
|
|
589
|
+
? `${agora} (${rotulo}) esta dentro da janela ociosa ${bruta}`
|
|
590
|
+
: `${agora} (${rotulo}) esta FORA da janela ociosa ${bruta}`,
|
|
588
591
|
};
|
|
589
592
|
}
|
|
590
593
|
/** O Graphify existe nesta maquina? Fonte externa, nunca suposicao. */
|
package/dist/auditrun.js
CHANGED
|
@@ -84,6 +84,7 @@ const superficie_1 = require("./superficie");
|
|
|
84
84
|
const thread_1 = require("./thread");
|
|
85
85
|
const util_1 = require("./util");
|
|
86
86
|
const verify_1 = require("./verify");
|
|
87
|
+
const horario_1 = require("./horario");
|
|
87
88
|
/** Versao do formato de `run.json`. */
|
|
88
89
|
exports.VERSAO_DA_RODADA = 1;
|
|
89
90
|
/** Diretorio das rodadas de auditoria do projeto. */
|
|
@@ -708,7 +709,7 @@ function relatorioDaRodada(carregado, rodadaId, opcoes = {}) {
|
|
|
708
709
|
else {
|
|
709
710
|
const v = rodada.veredito;
|
|
710
711
|
L.push(`- HEAD real: ${v.commit}`);
|
|
711
|
-
L.push(`- verificado em: ${v.verificadoEm}`);
|
|
712
|
+
L.push(`- verificado em: ${(0, horario_1.formatarDataHoraRotulada)(v.verificadoEm)}`);
|
|
712
713
|
L.push(`- veredito: ${v.ok ? 'ACHADOS SUSTENTADOS' : 'REPROVADO'}`);
|
|
713
714
|
L.push(`- motivos tipados: ${v.motivos.length > 0 ? v.motivos.join(', ') : '(nenhum)'}`);
|
|
714
715
|
L.push('');
|
|
@@ -831,10 +832,10 @@ function tabelaDoLedgerDaRodada(raiz, id) {
|
|
|
831
832
|
if (e.thread && e.thread !== id)
|
|
832
833
|
detalhe.push(`thread ${String(e.thread)}`);
|
|
833
834
|
if (e.detalhe)
|
|
834
|
-
detalhe.push(String(e.detalhe).slice(0, 90));
|
|
835
|
-
return [
|
|
835
|
+
detalhe.push((0, horario_1.localizarTexto)(String(e.detalhe)).slice(0, 90));
|
|
836
|
+
return [(0, horario_1.formatarDataHora)(e.ts, { segundos: true }), e.tipo, detalhe.join(' | ')];
|
|
836
837
|
});
|
|
837
|
-
return (0, util_1.tabela)(['QUANDO', 'EVENTO', 'DETALHE'], linhas)
|
|
838
|
+
return `${(0, util_1.tabela)(['QUANDO', 'EVENTO', 'DETALHE'], linhas)}\n${(0, horario_1.legendaDoFuso)()}`;
|
|
838
839
|
}
|
|
839
840
|
/** Quantos achados abertos existem por pack, para o resumo do CLI. */
|
|
840
841
|
function resumoDoBoard(raiz) {
|