@orkastery/cli 0.6.3 → 0.6.5

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.
@@ -0,0 +1,149 @@
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.CONTRATO_DA_SELECAO = void 0;
37
+ exports.comandoDaSelecao = comandoDaSelecao;
38
+ exports.planejarSelecaoNativa = planejarSelecaoNativa;
39
+ /** RM-081 F5: decisão conservadora da seleção nativa por mudanças no Agile. */
40
+ const path = __importStar(require("node:path"));
41
+ const leases_1 = require("./leases");
42
+ const manifest_1 = require("./manifest");
43
+ const util_1 = require("./util");
44
+ exports.CONTRATO_DA_SELECAO = 'ork.check.selecao/v1';
45
+ const LOCKFILES = new Set(['package-lock.json', 'npm-shrinkwrap.json', 'pnpm-lock.yaml', 'yarn.lock', 'poetry.lock',
46
+ 'Pipfile.lock', 'go.mod', 'go.sum', 'Package.resolved']);
47
+ function objeto(v) {
48
+ return v && typeof v === 'object' && !Array.isArray(v) ? v : null;
49
+ }
50
+ function sha(v) {
51
+ return typeof v === 'string' && /^[0-9a-f]{40,64}$/i.test(v);
52
+ }
53
+ /** Um argumento shell fechado, como o filtro nominal da F3. */
54
+ function argumento(valor) {
55
+ return `'${valor.replace(/'/g, `'"'"'`)}'`;
56
+ }
57
+ function comandoDaSelecao(declaracao, base, arquivos) {
58
+ return declaracao.comando.includes('{base}')
59
+ ? declaracao.comando.replace('{base}', argumento(base))
60
+ : declaracao.comando.replace('{arquivos}', arquivos.map(argumento).join(' '));
61
+ }
62
+ function baseAtual(cwd, manifesto, commit) {
63
+ const r = (0, util_1.exec)('git', ['merge-base', commit, manifesto.worktree.base_branch], cwd);
64
+ const base = r.stdout.trim();
65
+ return r.ok && sha(base) ? base : null;
66
+ }
67
+ function arvoreLimpa(cwd) {
68
+ const r = (0, util_1.exec)('git', ['status', '--porcelain=v1', '-z', '--untracked-files=all', '--', '.', ':(exclude).orkastery'], cwd);
69
+ return r.ok && r.stdout === '';
70
+ }
71
+ function arquivosMudados(cwd, anterior, atual) {
72
+ const r = (0, util_1.exec)('git', ['diff', '--name-only', '--no-renames', '-z', anterior, atual, '--', '.', ':(exclude).orkastery'], cwd);
73
+ if (!r.ok)
74
+ return null;
75
+ return [...new Set(r.stdout.split('\0').filter(Boolean).map((arquivo) => arquivo.split(path.sep).join('/')))].sort();
76
+ }
77
+ function lockfile(arquivo) {
78
+ const nome = path.posix.basename(arquivo);
79
+ return LOCKFILES.has(nome) || /^requirements(?:\.[^.]+)?\.txt$/.test(nome)
80
+ || /(?:^|[.-])lock(?:b|\.(?:json|ya?ml|toml))?$/i.test(nome);
81
+ }
82
+ function inteira(motivo, arquivos) {
83
+ return { modo: 'inteira', motivo, ...(arquivos?.length ? { arquivos } : {}) };
84
+ }
85
+ function todasInteiras(declaracoes, motivo, arquivos) {
86
+ return Object.fromEntries(Object.keys(declaracoes).map((lane) => [lane, inteira(motivo, arquivos)]));
87
+ }
88
+ /**
89
+ * Decide uma vez, antes dos comandos. O último `verify_run` é o cache: qualquer forma desconhecida,
90
+ * veredito vermelho, base diferente ou árvore suja devolve a suíte inteira.
91
+ */
92
+ function planejarSelecaoNativa(cwd, manifesto, eventos, commit, modo) {
93
+ const declaracoes = manifesto.check?.agile?.selecao ?? {};
94
+ if (modo !== 'agile' || Object.keys(declaracoes).length === 0)
95
+ return { lanes: {}, cache: null };
96
+ const base = baseAtual(cwd, manifesto, commit);
97
+ const limpa = arvoreLimpa(cwd);
98
+ const cache = base && limpa ? { contrato: exports.CONTRATO_DA_SELECAO, base, head: commit } : null;
99
+ const ultima = [...eventos].reverse().find((evento) => evento.tipo === 'verify_run');
100
+ if (!ultima)
101
+ return { lanes: todasInteiras(declaracoes, 'rodada-fria'), cache };
102
+ const anterior = objeto(ultima.selecao);
103
+ if (!anterior)
104
+ return { lanes: todasInteiras(declaracoes, 'cache-ausente'), cache };
105
+ if (!base || !limpa || ultima.veredito !== 'verdade sustentada' || anterior.contrato !== exports.CONTRATO_DA_SELECAO
106
+ || !sha(anterior.base) || !sha(anterior.head) || anterior.head !== ultima.commit) {
107
+ return { lanes: todasInteiras(declaracoes, 'cache-invalido'), cache };
108
+ }
109
+ if (anterior.base !== base)
110
+ return { lanes: todasInteiras(declaracoes, 'base-mudou'), cache };
111
+ if (!(0, util_1.exec)('git', ['merge-base', '--is-ancestor', anterior.head, commit], cwd).ok) {
112
+ return { lanes: todasInteiras(declaracoes, 'cache-invalido'), cache };
113
+ }
114
+ const mudados = arquivosMudados(cwd, anterior.head, commit);
115
+ if (!mudados)
116
+ return { lanes: todasInteiras(declaracoes, 'cache-invalido'), cache };
117
+ const manifestos = new Set([manifest_1.NOME_MANIFESTO, manifest_1.NOME_MANIFESTO_LEGADO]);
118
+ const mudancaNoManifesto = mudados.filter((arquivo) => manifestos.has(path.posix.basename(arquivo)));
119
+ if (mudancaNoManifesto.length)
120
+ return { lanes: todasInteiras(declaracoes, 'manifesto-mudou', mudancaNoManifesto), cache };
121
+ const lockfiles = mudados.filter(lockfile);
122
+ if (lockfiles.length)
123
+ return { lanes: todasInteiras(declaracoes, 'lockfile-mudou', lockfiles), cache };
124
+ const lanes = {};
125
+ for (const [lane, declaracao] of Object.entries(declaracoes)) {
126
+ if (!declaracao.mapeia.length) {
127
+ lanes[lane] = inteira('runner-sem-garantia');
128
+ continue;
129
+ }
130
+ const configuracao = mudados.filter((arquivo) => (declaracao.configuracao ?? [])
131
+ .some((glob) => (0, leases_1.caminhoBateComGlob)(arquivo, glob)));
132
+ if (configuracao.length) {
133
+ lanes[lane] = inteira('configuracao-mudou', configuracao);
134
+ continue;
135
+ }
136
+ const fora = mudados.filter((arquivo) => !declaracao.mapeia.some((glob) => (0, leases_1.caminhoBateComGlob)(arquivo, glob)));
137
+ if (fora.length) {
138
+ lanes[lane] = inteira('fora-do-mapeamento', fora);
139
+ continue;
140
+ }
141
+ if (!mudados.length) {
142
+ lanes[lane] = inteira('sem-mudancas');
143
+ continue;
144
+ }
145
+ lanes[lane] = { modo: 'selecionada', motivo: 'selecionada', arquivos: mudados,
146
+ base: anterior.head, comando: comandoDaSelecao(declaracao, anterior.head, mudados) };
147
+ }
148
+ return { lanes, cache };
149
+ }
@@ -0,0 +1,95 @@
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.taskCompleteFixadoDaFonte = taskCompleteFixadoDaFonte;
37
+ exports.taskCompleteFixadoDaSessao = taskCompleteFixadoDaSessao;
38
+ /** RM-075: prova somente leitura de `task_complete` no rollout já fixado pelo controller. */
39
+ const fs = __importStar(require("node:fs"));
40
+ const path = __importStar(require("node:path"));
41
+ const node_crypto_1 = require("node:crypto");
42
+ const codex_controller_sensor_1 = require("./adapters/codex-controller-sensor");
43
+ const codex_events_1 = require("./adapters/codex-events");
44
+ const thread_1 = require("./thread");
45
+ const BLOCO = 256 * 1024;
46
+ const chaveDaFonte = (sessionId, despachoEm) => (0, node_crypto_1.createHash)('sha256').update(sessionId + '|' + despachoEm).digest('hex');
47
+ /** O parser percorre o descritor autenticado inteiro; linha parcial ou corrupção não prova terminal. */
48
+ function taskCompleteFixadoDaFonte(fonte, agoraMs = Date.now()) {
49
+ return (0, codex_controller_sensor_1.consumirRolloutControllerFixado)(fonte, (fd, tamanho) => {
50
+ const parser = new codex_events_1.ParserCodex();
51
+ let terminal = null;
52
+ for (let offset = 0; offset < tamanho;) {
53
+ const buffer = Buffer.alloc(Math.min(BLOCO, tamanho - offset));
54
+ const lidos = fs.readSync(fd, buffer, 0, buffer.length, offset);
55
+ if (lidos <= 0)
56
+ break;
57
+ for (const atual of parser.push(buffer.subarray(0, lidos), agoraMs))
58
+ terminal = atual;
59
+ offset += lidos;
60
+ }
61
+ if (parser.estado.invalido || parser.bytesPendentes > 0 || parser.estado.turnoAberto ||
62
+ terminal?.fonte !== 'rollout.task_complete' ||
63
+ (terminal.numeroTurno ?? 0) < parser.estado.turnos)
64
+ return null;
65
+ return { terminal, fonte };
66
+ });
67
+ }
68
+ /**
69
+ * Resolve somente a fixação correspondente ao despacho. Sem pin autenticado, controller ou cwd,
70
+ * devolve `null`: nunca descobre outro rollout para fabricar a prova.
71
+ */
72
+ function taskCompleteFixadoDaSessao(raiz, thread, sessao, eventos, agoraMs = Date.now()) {
73
+ if (sessao.runtime !== 'codex')
74
+ return null;
75
+ const registro = eventos.filter(e => e.tipo === 'session_sensor_registered' &&
76
+ e.sessionId === sessao.sessionId && e.despachoEm === sessao.despachadaEm).at(-1);
77
+ if (typeof registro?.controlador !== 'string')
78
+ return null;
79
+ const despacho = eventos.filter(e => e.tipo === 'phase_dispatch' && e.sessionId === sessao.sessionId).at(-1);
80
+ if (despacho?.controlador !== undefined && despacho.controlador !== registro.controlador)
81
+ throw new Error('controlador registrado divergente do despacho');
82
+ const cwd = (despacho?.cwd ?? registro.cwd);
83
+ if (!cwd)
84
+ return null;
85
+ const dir = (0, thread_1.dirThread)(raiz, thread.id);
86
+ const chave = chaveDaFonte(sessao.sessionId, sessao.despachadaEm);
87
+ const esperado = {
88
+ dirSessoes: path.join(dir, 'sessoes'), sessionId: sessao.sessionId, cwd,
89
+ despachoEm: sessao.despachadaEm, agoraMs,
90
+ fixacao: path.join(dir, 'sessoes', `watcher-source-${chave}.json`),
91
+ vinculo: { thread: thread.id, fase: sessao.fase, promptSha256: sessao.promptSha256 },
92
+ };
93
+ const fonte = (0, codex_controller_sensor_1.lerFonteControllerFixada)(esperado.fixacao, esperado);
94
+ return fonte ? taskCompleteFixadoDaFonte(fonte, agoraMs) : null;
95
+ }