oxe-cc 0.9.3 → 1.0.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/README.md +1 -1
- package/bin/banner.txt +1 -1
- package/bin/lib/oxe-dashboard.cjs +9 -7
- package/bin/lib/oxe-operational.cjs +569 -4
- package/bin/oxe-cc.js +141 -57
- package/lib/runtime/compiler/graph-compiler.d.ts +83 -0
- package/lib/runtime/compiler/graph-compiler.js +135 -0
- package/lib/runtime/compiler/index.d.ts +1 -0
- package/lib/runtime/compiler/index.js +17 -0
- package/lib/runtime/context/context-pack-builder.d.ts +36 -0
- package/lib/runtime/context/context-pack-builder.js +136 -0
- package/lib/runtime/context/index.d.ts +1 -0
- package/lib/runtime/context/index.js +17 -0
- package/lib/runtime/delivery/branch-manager.d.ts +19 -0
- package/lib/runtime/delivery/branch-manager.js +78 -0
- package/lib/runtime/delivery/ci-checks.d.ts +34 -0
- package/lib/runtime/delivery/ci-checks.js +209 -0
- package/lib/runtime/delivery/index.d.ts +3 -0
- package/lib/runtime/delivery/index.js +19 -0
- package/lib/runtime/delivery/pr-manager.d.ts +30 -0
- package/lib/runtime/delivery/pr-manager.js +82 -0
- package/lib/runtime/events/bus.d.ts +9 -0
- package/lib/runtime/events/bus.js +63 -0
- package/lib/runtime/events/catalog.d.ts +3 -0
- package/lib/runtime/events/catalog.js +30 -0
- package/lib/runtime/events/envelope.d.ts +13 -0
- package/lib/runtime/events/envelope.js +2 -0
- package/lib/runtime/events/index.d.ts +3 -0
- package/lib/runtime/events/index.js +19 -0
- package/lib/runtime/evidence/evidence-store.d.ts +22 -0
- package/lib/runtime/evidence/evidence-store.js +106 -0
- package/lib/runtime/evidence/index.d.ts +1 -0
- package/lib/runtime/evidence/index.js +17 -0
- package/lib/runtime/gate/gate-manager.d.ts +39 -0
- package/lib/runtime/gate/gate-manager.js +104 -0
- package/lib/runtime/gate/index.d.ts +1 -0
- package/lib/runtime/gate/index.js +17 -0
- package/lib/runtime/index.d.ts +16 -0
- package/lib/runtime/index.js +40 -0
- package/lib/runtime/models/attempt.d.ts +12 -0
- package/lib/runtime/models/attempt.js +2 -0
- package/lib/runtime/models/evidence.d.ts +9 -0
- package/lib/runtime/models/evidence.js +2 -0
- package/lib/runtime/models/gate-decision.d.ts +10 -0
- package/lib/runtime/models/gate-decision.js +2 -0
- package/lib/runtime/models/index.d.ts +8 -0
- package/lib/runtime/models/index.js +24 -0
- package/lib/runtime/models/run.d.ts +13 -0
- package/lib/runtime/models/run.js +2 -0
- package/lib/runtime/models/session.d.ts +10 -0
- package/lib/runtime/models/session.js +2 -0
- package/lib/runtime/models/verification-result.d.ts +9 -0
- package/lib/runtime/models/verification-result.js +2 -0
- package/lib/runtime/models/work-item.d.ts +15 -0
- package/lib/runtime/models/work-item.js +2 -0
- package/lib/runtime/models/workspace.d.ts +25 -0
- package/lib/runtime/models/workspace.js +2 -0
- package/lib/runtime/plugins/index.d.ts +2 -0
- package/lib/runtime/plugins/index.js +18 -0
- package/lib/runtime/plugins/plugin-abi.d.ts +76 -0
- package/lib/runtime/plugins/plugin-abi.js +2 -0
- package/lib/runtime/plugins/plugin-registry.d.ts +21 -0
- package/lib/runtime/plugins/plugin-registry.js +114 -0
- package/lib/runtime/policy/index.d.ts +1 -0
- package/lib/runtime/policy/index.js +17 -0
- package/lib/runtime/policy/policy-engine.d.ts +40 -0
- package/lib/runtime/policy/policy-engine.js +80 -0
- package/lib/runtime/projection/index.d.ts +1 -0
- package/lib/runtime/projection/index.js +17 -0
- package/lib/runtime/projection/projection-engine.d.ts +11 -0
- package/lib/runtime/projection/projection-engine.js +218 -0
- package/lib/runtime/reducers/debug-reducer.d.ts +10 -0
- package/lib/runtime/reducers/debug-reducer.js +30 -0
- package/lib/runtime/reducers/index.d.ts +2 -0
- package/lib/runtime/reducers/index.js +18 -0
- package/lib/runtime/reducers/run-state-reducer.d.ts +20 -0
- package/lib/runtime/reducers/run-state-reducer.js +110 -0
- package/lib/runtime/scheduler/index.d.ts +1 -0
- package/lib/runtime/scheduler/index.js +17 -0
- package/lib/runtime/scheduler/multi-agent-coordinator.d.ts +34 -0
- package/lib/runtime/scheduler/multi-agent-coordinator.js +166 -0
- package/lib/runtime/scheduler/scheduler.d.ts +39 -0
- package/lib/runtime/scheduler/scheduler.js +196 -0
- package/lib/runtime/verification/index.d.ts +1 -0
- package/lib/runtime/verification/index.js +17 -0
- package/lib/runtime/verification/verification-compiler.d.ts +56 -0
- package/lib/runtime/verification/verification-compiler.js +147 -0
- package/lib/runtime/workspace/index.d.ts +5 -0
- package/lib/runtime/workspace/index.js +24 -0
- package/lib/runtime/workspace/strategies/ephemeral-container.d.ts +22 -0
- package/lib/runtime/workspace/strategies/ephemeral-container.js +109 -0
- package/lib/runtime/workspace/strategies/git-worktree.d.ts +12 -0
- package/lib/runtime/workspace/strategies/git-worktree.js +79 -0
- package/lib/runtime/workspace/strategies/inplace.d.ts +10 -0
- package/lib/runtime/workspace/strategies/inplace.js +37 -0
- package/lib/runtime/workspace/workspace-manager.d.ts +13 -0
- package/lib/runtime/workspace/workspace-manager.js +2 -0
- package/lib/sdk/index.cjs +24 -7
- package/lib/sdk/index.d.ts +17 -7
- package/package.json +9 -3
- package/packages/runtime/package.json +17 -0
- package/packages/runtime/src/compiler/graph-compiler.ts +245 -0
- package/packages/runtime/src/compiler/index.ts +1 -0
- package/packages/runtime/src/context/context-pack-builder.ts +193 -0
- package/packages/runtime/src/context/index.ts +1 -0
- package/packages/runtime/src/delivery/branch-manager.ts +84 -0
- package/packages/runtime/src/delivery/ci-checks.ts +252 -0
- package/packages/runtime/src/delivery/index.ts +3 -0
- package/packages/runtime/src/delivery/pr-manager.ts +112 -0
- package/packages/runtime/src/events/bus.ts +92 -0
- package/packages/runtime/src/events/catalog.ts +29 -0
- package/packages/runtime/src/events/envelope.ts +14 -0
- package/packages/runtime/src/events/index.ts +3 -0
- package/packages/runtime/src/evidence/evidence-store.ts +130 -0
- package/packages/runtime/src/evidence/index.ts +1 -0
- package/packages/runtime/src/gate/gate-manager.ts +137 -0
- package/packages/runtime/src/gate/index.ts +1 -0
- package/packages/runtime/src/index.ts +32 -0
- package/packages/runtime/src/models/attempt.ts +19 -0
- package/packages/runtime/src/models/evidence.ts +21 -0
- package/packages/runtime/src/models/gate-decision.ts +21 -0
- package/packages/runtime/src/models/index.ts +8 -0
- package/packages/runtime/src/models/run.ts +24 -0
- package/packages/runtime/src/models/session.ts +11 -0
- package/packages/runtime/src/models/verification-result.ts +10 -0
- package/packages/runtime/src/models/work-item.ts +25 -0
- package/packages/runtime/src/models/workspace.ts +28 -0
- package/packages/runtime/src/plugins/index.ts +2 -0
- package/packages/runtime/src/plugins/plugin-abi.ts +95 -0
- package/packages/runtime/src/plugins/plugin-registry.ts +119 -0
- package/packages/runtime/src/policy/index.ts +1 -0
- package/packages/runtime/src/policy/policy-engine.ts +113 -0
- package/packages/runtime/src/projection/index.ts +1 -0
- package/packages/runtime/src/projection/projection-engine.ts +249 -0
- package/packages/runtime/src/reducers/debug-reducer.ts +36 -0
- package/packages/runtime/src/reducers/index.ts +2 -0
- package/packages/runtime/src/reducers/run-state-reducer.ts +127 -0
- package/packages/runtime/src/scheduler/index.ts +1 -0
- package/packages/runtime/src/scheduler/multi-agent-coordinator.ts +231 -0
- package/packages/runtime/src/scheduler/scheduler.ts +281 -0
- package/packages/runtime/src/verification/index.ts +1 -0
- package/packages/runtime/src/verification/verification-compiler.ts +225 -0
- package/packages/runtime/src/workspace/index.ts +5 -0
- package/packages/runtime/src/workspace/strategies/ephemeral-container.ts +121 -0
- package/packages/runtime/src/workspace/strategies/git-worktree.ts +77 -0
- package/packages/runtime/src/workspace/strategies/inplace.ts +35 -0
- package/packages/runtime/src/workspace/workspace-manager.ts +15 -0
- package/packages/runtime/tsconfig.json +17 -0
- package/vscode-extension/oxe-agents-0.9.2.vsix +0 -0
- package/vscode-extension/oxe-agents-1.0.0.vsix +0 -0
- package/vscode-extension/package.json +1 -1
package/bin/oxe-cc.js
CHANGED
|
@@ -2125,7 +2125,7 @@ ${green}Uso:${reset}
|
|
|
2125
2125
|
npx oxe-cc init-oxe [opções] [pasta-do-projeto]
|
|
2126
2126
|
npx oxe-cc context <build|inspect> [opções] [pasta-do-projeto]
|
|
2127
2127
|
npx oxe-cc dashboard [opções] [pasta-do-projeto]
|
|
2128
|
-
npx oxe-cc runtime <status|start|pause|resume|replay> [opções] [pasta-do-projeto]
|
|
2128
|
+
npx oxe-cc runtime <status|start|pause|resume|replay|compile|project|ci> [opções] [pasta-do-projeto]
|
|
2129
2129
|
npx oxe-cc azure <status|doctor|auth|sync|find|servicebus|eventgrid|sql|operations> [opções] [pasta-do-projeto]
|
|
2130
2130
|
npx oxe-cc capabilities <list|install|remove|update> [opções] [id]
|
|
2131
2131
|
npx oxe-cc uninstall [opções] [pasta-do-projeto]
|
|
@@ -2167,18 +2167,24 @@ ${green}context${reset} (Context Engine V2: seleção, compressão e inspeção
|
|
|
2167
2167
|
--json saída estruturada em JSON
|
|
2168
2168
|
--dir <pasta> raiz do projeto (padrão: diretório atual)
|
|
2169
2169
|
|
|
2170
|
-
${green}runtime${reset} (controle operacional explícito do ACTIVE-RUN)
|
|
2171
|
-
status mostra o run ativo resolvido para a sessão atual
|
|
2172
|
-
start cria um novo run com tracing inicial
|
|
2173
|
-
pause pausa o run ativo e preserva o cursor
|
|
2174
|
-
resume retoma o run ativo
|
|
2175
|
-
replay marca replay parcial por onda ou tarefa
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
--
|
|
2180
|
-
--
|
|
2181
|
-
--
|
|
2170
|
+
${green}runtime${reset} (controle operacional explícito do ACTIVE-RUN)
|
|
2171
|
+
status mostra o run ativo resolvido para a sessão atual
|
|
2172
|
+
start cria um novo run com tracing inicial
|
|
2173
|
+
pause pausa o run ativo e preserva o cursor
|
|
2174
|
+
resume retoma o run ativo
|
|
2175
|
+
replay marca replay parcial por onda ou tarefa
|
|
2176
|
+
compile compila PLAN/SPEC em ExecutionGraph formal + verification suite
|
|
2177
|
+
project projeta markdowns derivados do estado canônico
|
|
2178
|
+
ci executa checks do runtime e persiste o resultado na run
|
|
2179
|
+
--session <sessions/sNNN-slug> força sessão específica
|
|
2180
|
+
--wave <número> fixa onda atual/cursor
|
|
2181
|
+
--task <Tn> fixa tarefa atual/cursor
|
|
2182
|
+
--mode <complete|wave|task> modo operacional do cursor
|
|
2183
|
+
--reason <texto> motivo explícito da transição
|
|
2184
|
+
--run <run_id> (replay|ci) filtra um run específico
|
|
2185
|
+
--from <event_id> (replay) começa em um event_id específico
|
|
2186
|
+
--write (replay) gera REPLAY-SESSION.md
|
|
2187
|
+
--dir <pasta> raiz do projeto (padrão: diretório atual)
|
|
2182
2188
|
|
|
2183
2189
|
${green}azure${reset} (provider Azure nativo via Azure CLI no Windows)
|
|
2184
2190
|
status estado compacto: CLI, login, subscription, inventário, pendências
|
|
@@ -3707,11 +3713,11 @@ async function runDashboard(opts) {
|
|
|
3707
3713
|
/**
|
|
3708
3714
|
* @param {RuntimeOpts} opts
|
|
3709
3715
|
*/
|
|
3710
|
-
function runRuntime(opts) {
|
|
3711
|
-
const c = useAnsiColors();
|
|
3712
|
-
printSection('OXE ▸ runtime');
|
|
3713
|
-
if (!fs.existsSync(opts.dir)) {
|
|
3714
|
-
console.error(`${yellow}Diretório não encontrado: ${opts.dir}${reset}`);
|
|
3716
|
+
async function runRuntime(opts) {
|
|
3717
|
+
const c = useAnsiColors();
|
|
3718
|
+
printSection('OXE ▸ runtime');
|
|
3719
|
+
if (!fs.existsSync(opts.dir)) {
|
|
3720
|
+
console.error(`${yellow}Diretório não encontrado: ${opts.dir}${reset}`);
|
|
3715
3721
|
process.exit(1);
|
|
3716
3722
|
}
|
|
3717
3723
|
bootstrapOxe(opts.dir, { dryRun: false, force: false });
|
|
@@ -3722,20 +3728,32 @@ function runRuntime(opts) {
|
|
|
3722
3728
|
console.log(` ${c ? green : ''}Projeto:${c ? reset : ''} ${c ? cyan : ''}${opts.dir}${c ? reset : ''}`);
|
|
3723
3729
|
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || 'modo legado'}${c ? reset : ''}`);
|
|
3724
3730
|
|
|
3725
|
-
if (opts.action === 'status') {
|
|
3726
|
-
const current = oxeOperational.readRunState(opts.dir, activeSession);
|
|
3727
|
-
if (!current) {
|
|
3728
|
-
console.log(` ${yellow}Nenhum ACTIVE-RUN encontrado.${reset}`);
|
|
3729
|
-
return;
|
|
3730
|
-
}
|
|
3731
|
-
console.log(` ${c ? green : ''}Run:${c ? reset : ''} ${current.run_id}`);
|
|
3732
|
-
console.log(` ${c ? green : ''}Estado:${c ? reset : ''} ${current.status}`);
|
|
3733
|
-
console.log(` ${c ? green : ''}Cursor:${c ? reset : ''} onda=${current.cursor && current.cursor.wave != null ? current.cursor.wave : '—'} tarefa=${current.cursor && current.cursor.task ? current.cursor.task : '—'} modo=${current.cursor && current.cursor.mode ? current.cursor.mode : '—'}`);
|
|
3734
|
-
console.log(` ${c ? green : ''}Arquivo:${c ? reset : ''} ${path.join(p.runsDir, `${current.run_id}.json`)}`);
|
|
3735
|
-
|
|
3736
|
-
}
|
|
3737
|
-
|
|
3738
|
-
|
|
3731
|
+
if (opts.action === 'status') {
|
|
3732
|
+
const current = oxeOperational.readRunState(opts.dir, activeSession);
|
|
3733
|
+
if (!current) {
|
|
3734
|
+
console.log(` ${yellow}Nenhum ACTIVE-RUN encontrado.${reset}`);
|
|
3735
|
+
return;
|
|
3736
|
+
}
|
|
3737
|
+
console.log(` ${c ? green : ''}Run:${c ? reset : ''} ${current.run_id}`);
|
|
3738
|
+
console.log(` ${c ? green : ''}Estado:${c ? reset : ''} ${current.status}`);
|
|
3739
|
+
console.log(` ${c ? green : ''}Cursor:${c ? reset : ''} onda=${current.cursor && current.cursor.wave != null ? current.cursor.wave : '—'} tarefa=${current.cursor && current.cursor.task ? current.cursor.task : '—'} modo=${current.cursor && current.cursor.mode ? current.cursor.mode : '—'}`);
|
|
3740
|
+
console.log(` ${c ? green : ''}Arquivo:${c ? reset : ''} ${path.join(p.runsDir, `${current.run_id}.json`)}`);
|
|
3741
|
+
if (current.compiled_graph && current.compiled_graph.metadata) {
|
|
3742
|
+
console.log(` ${c ? green : ''}Graph:${c ? reset : ''} ${current.compiled_graph.metadata.node_count || 0} nós · ${current.compiled_graph.metadata.wave_count || 0} ondas`);
|
|
3743
|
+
}
|
|
3744
|
+
if (current.canonical_state && current.canonical_state.summary) {
|
|
3745
|
+
console.log(` ${c ? green : ''}Canonical:${c ? reset : ''} work_items=${current.canonical_state.summary.work_item_count || 0} · attempts=${current.canonical_state.summary.attempt_count || 0}`);
|
|
3746
|
+
}
|
|
3747
|
+
if (current.ci_checks && current.ci_checks.summary) {
|
|
3748
|
+
console.log(` ${c ? green : ''}CI:${c ? reset : ''} pass=${current.ci_checks.summary.pass || 0} fail=${current.ci_checks.summary.fail || 0} skip=${current.ci_checks.summary.skip || 0} error=${current.ci_checks.summary.error || 0}`);
|
|
3749
|
+
}
|
|
3750
|
+
if (current.projections && current.projections.generated_at) {
|
|
3751
|
+
console.log(` ${c ? green : ''}Projection:${c ? reset : ''} ${current.projections.generated_at}`);
|
|
3752
|
+
}
|
|
3753
|
+
return;
|
|
3754
|
+
}
|
|
3755
|
+
|
|
3756
|
+
if (opts.action === 'replay' && !opts.task) {
|
|
3739
3757
|
const report = oxeOperational.replayEvents(opts.dir, activeSession, {
|
|
3740
3758
|
runId: opts.runId || undefined,
|
|
3741
3759
|
fromEventId: opts.fromEventId || undefined,
|
|
@@ -3747,34 +3765,97 @@ function runRuntime(opts) {
|
|
|
3747
3765
|
console.log(` ${c ? green : ''}Ondas:${c ? reset : ''} ${report.waveIds.join(', ') || '—'}`);
|
|
3748
3766
|
console.log(` ${c ? green : ''}Tarefas:${c ? reset : ''} ${report.taskSequence.join(', ') || '—'}`);
|
|
3749
3767
|
console.log(` ${c ? green : ''}Falhas:${c ? reset : ''} ${report.failureEvents.length}`);
|
|
3750
|
-
if (report.totalEvents > 0) {
|
|
3751
|
-
console.log('');
|
|
3752
|
-
const dim = c ? '\x1b[2m' : '';
|
|
3753
|
-
console.log(` ${dim}# Tipo Wave Task Delta Timestamp${c ? reset : ''}`);
|
|
3754
|
-
for (let i = 0; i < Math.min(report.events.length, 50); i++) {
|
|
3755
|
-
const e = report.events[i];
|
|
3756
|
-
const delta = i > 0 ? `+${(e._delta_ms / 1000).toFixed(1)}s` : '—';
|
|
3757
|
-
const num = String(i + 1).padStart(3);
|
|
3758
|
-
const type = String(e.type).padEnd(22).slice(0, 22);
|
|
3759
|
-
const wave = String(e.wave_id || '—').padEnd(7).slice(0, 7);
|
|
3760
|
-
const task = String(e.task_id || '—').padEnd(7).slice(0, 7);
|
|
3761
|
-
const deltaStr = delta.padStart(10);
|
|
3762
|
-
console.log(` ${num} ${type} ${wave} ${task} ${deltaStr} ${e.timestamp}`);
|
|
3763
|
-
}
|
|
3768
|
+
if (report.totalEvents > 0) {
|
|
3769
|
+
console.log('');
|
|
3770
|
+
const dim = c ? '\x1b[2m' : '';
|
|
3771
|
+
console.log(` ${dim}# Tipo Wave Task Delta Timestamp${c ? reset : ''}`);
|
|
3772
|
+
for (let i = 0; i < Math.min(report.events.length, 50); i++) {
|
|
3773
|
+
const e = report.events[i];
|
|
3774
|
+
const delta = i > 0 ? `+${(e._delta_ms / 1000).toFixed(1)}s` : '—';
|
|
3775
|
+
const num = String(i + 1).padStart(3);
|
|
3776
|
+
const type = String(e.type).padEnd(22).slice(0, 22);
|
|
3777
|
+
const wave = String(e.wave_id || '—').padEnd(7).slice(0, 7);
|
|
3778
|
+
const task = String(e.task_id || e.work_item_id || '—').padEnd(7).slice(0, 7);
|
|
3779
|
+
const deltaStr = delta.padStart(10);
|
|
3780
|
+
console.log(` ${num} ${type} ${wave} ${task} ${deltaStr} ${e.timestamp}`);
|
|
3781
|
+
}
|
|
3764
3782
|
if (report.events.length > 50) {
|
|
3765
3783
|
console.log(` … (${report.events.length - 50} mais)`);
|
|
3766
3784
|
}
|
|
3767
3785
|
}
|
|
3768
3786
|
if (report._reportPath) {
|
|
3769
3787
|
console.log(`\n ${c ? green : ''}Relatório:${c ? reset : ''} ${report._reportPath}`);
|
|
3770
|
-
}
|
|
3771
|
-
return;
|
|
3772
|
-
}
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3788
|
+
}
|
|
3789
|
+
return;
|
|
3790
|
+
}
|
|
3791
|
+
|
|
3792
|
+
if (opts.action === 'compile') {
|
|
3793
|
+
try {
|
|
3794
|
+
const compiled = oxeOperational.compileExecutionGraphFromArtifacts(opts.dir, activeSession);
|
|
3795
|
+
const suite = oxeOperational.compileVerificationSuiteFromArtifacts(opts.dir, activeSession, {
|
|
3796
|
+
runState: compiled.run,
|
|
3797
|
+
});
|
|
3798
|
+
console.log(` ${c ? green : ''}✓${c ? reset : ''} Runtime compilado.`);
|
|
3799
|
+
console.log(` ${c ? green : ''}Run:${c ? reset : ''} ${compiled.run.run_id}`);
|
|
3800
|
+
console.log(` ${c ? green : ''}Graph:${c ? reset : ''} ${compiled.graph.metadata.node_count} nó(s) · ${compiled.graph.metadata.wave_count} onda(s)`);
|
|
3801
|
+
console.log(` ${c ? green : ''}Checks:${c ? reset : ''} ${Array.isArray(suite.suite.checks) ? suite.suite.checks.length : 0}`);
|
|
3802
|
+
if (compiled.validationErrors.length) {
|
|
3803
|
+
console.log(` ${yellow}Validation:${reset} ${compiled.validationErrors.join(' | ')}`);
|
|
3804
|
+
}
|
|
3805
|
+
console.log(` ${c ? green : ''}Arquivo:${c ? reset : ''} ${path.join(p.runsDir, `${compiled.run.run_id}.json`)}`);
|
|
3806
|
+
return;
|
|
3807
|
+
} catch (err) {
|
|
3808
|
+
console.error(`${red}${err && err.message ? err.message : 'Falha ao compilar o runtime.'}${reset}`);
|
|
3809
|
+
process.exit(1);
|
|
3810
|
+
}
|
|
3811
|
+
}
|
|
3812
|
+
|
|
3813
|
+
if (opts.action === 'project') {
|
|
3814
|
+
try {
|
|
3815
|
+
const projected = oxeOperational.projectRuntimeArtifacts(opts.dir, activeSession, { write: true });
|
|
3816
|
+
console.log(` ${c ? green : ''}✓${c ? reset : ''} Projeções geradas a partir do estado canônico.`);
|
|
3817
|
+
console.log(` ${c ? green : ''}Run:${c ? reset : ''} ${projected.run.run_id}`);
|
|
3818
|
+
console.log(` ${c ? green : ''}STATE:${c ? reset : ''} ${projected.paths.state}`);
|
|
3819
|
+
console.log(` ${c ? green : ''}PLAN:${c ? reset : ''} ${projected.paths.plan}`);
|
|
3820
|
+
console.log(` ${c ? green : ''}VERIFY:${c ? reset : ''} ${projected.paths.verify}`);
|
|
3821
|
+
console.log(` ${c ? green : ''}RUN-SUMMARY:${c ? reset : ''} ${projected.paths.runSummary}`);
|
|
3822
|
+
console.log(` ${c ? green : ''}PR-SUMMARY:${c ? reset : ''} ${projected.paths.prSummary}`);
|
|
3823
|
+
return;
|
|
3824
|
+
} catch (err) {
|
|
3825
|
+
console.error(`${red}${err && err.message ? err.message : 'Falha ao projetar artefatos do runtime.'}${reset}`);
|
|
3826
|
+
process.exit(1);
|
|
3827
|
+
}
|
|
3828
|
+
}
|
|
3829
|
+
|
|
3830
|
+
if (opts.action === 'ci') {
|
|
3831
|
+
try {
|
|
3832
|
+
const report = await oxeOperational.runRuntimeCiChecks(opts.dir, activeSession, {
|
|
3833
|
+
runId: opts.runId || undefined,
|
|
3834
|
+
});
|
|
3835
|
+
console.log(` ${c ? green : ''}Run:${c ? reset : ''} ${report.runId || '—'}`);
|
|
3836
|
+
for (const result of report.results) {
|
|
3837
|
+
const color = result.status === 'pass'
|
|
3838
|
+
? green
|
|
3839
|
+
: result.status === 'skip'
|
|
3840
|
+
? dim
|
|
3841
|
+
: red;
|
|
3842
|
+
console.log(` ${c ? color : ''}${result.status.toUpperCase()}${c ? reset : ''} ${result.check} · ${result.message}`);
|
|
3843
|
+
}
|
|
3844
|
+
console.log(` ${c ? green : ''}Resumo:${c ? reset : ''} pass=${report.summary.pass} fail=${report.summary.fail} skip=${report.summary.skip} error=${report.summary.error}`);
|
|
3845
|
+
if (!report.summary.allPassed) {
|
|
3846
|
+
process.exitCode = 1;
|
|
3847
|
+
}
|
|
3848
|
+
return;
|
|
3849
|
+
} catch (err) {
|
|
3850
|
+
console.error(`${red}${err && err.message ? err.message : 'Falha ao executar checks do runtime.'}${reset}`);
|
|
3851
|
+
process.exit(1);
|
|
3852
|
+
}
|
|
3853
|
+
}
|
|
3854
|
+
|
|
3855
|
+
try {
|
|
3856
|
+
const next = oxeOperational.applyRuntimeAction(opts.dir, activeSession, {
|
|
3857
|
+
action: opts.action,
|
|
3858
|
+
wave: opts.wave,
|
|
3778
3859
|
task: opts.task || null,
|
|
3779
3860
|
mode: opts.mode || null,
|
|
3780
3861
|
reason: opts.reason || '',
|
|
@@ -4427,9 +4508,12 @@ async function main() {
|
|
|
4427
4508
|
console.error(`${yellow}Diretório não encontrado: ${runtime.dir}${reset}`);
|
|
4428
4509
|
process.exit(1);
|
|
4429
4510
|
}
|
|
4430
|
-
runRuntime(runtime)
|
|
4431
|
-
|
|
4432
|
-
|
|
4511
|
+
runRuntime(runtime).catch((err) => {
|
|
4512
|
+
console.error(`${red}${err && err.message ? err.message : 'Falha ao executar runtime.'}${reset}`);
|
|
4513
|
+
process.exit(1);
|
|
4514
|
+
});
|
|
4515
|
+
return;
|
|
4516
|
+
}
|
|
4433
4517
|
|
|
4434
4518
|
if (command === 'plugins') {
|
|
4435
4519
|
printBanner();
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { WorkspaceStrategy } from '../models/workspace';
|
|
2
|
+
export interface ParsedTask {
|
|
3
|
+
id: string;
|
|
4
|
+
title: string;
|
|
5
|
+
wave: number | null;
|
|
6
|
+
dependsOn: string[];
|
|
7
|
+
files: string[];
|
|
8
|
+
verifyCommand: string | null;
|
|
9
|
+
aceite: string[];
|
|
10
|
+
done: boolean;
|
|
11
|
+
meta?: Record<string, unknown> | null;
|
|
12
|
+
}
|
|
13
|
+
export interface ParsedSpecCriterion {
|
|
14
|
+
id: string;
|
|
15
|
+
criterion: string;
|
|
16
|
+
howToVerify: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ParsedSpec {
|
|
19
|
+
objective: string | null;
|
|
20
|
+
criteria: ParsedSpecCriterion[];
|
|
21
|
+
}
|
|
22
|
+
export interface ParsedPlan {
|
|
23
|
+
tasks: ParsedTask[];
|
|
24
|
+
waves: Record<number, string[]>;
|
|
25
|
+
totalTasks: number;
|
|
26
|
+
}
|
|
27
|
+
export interface Action {
|
|
28
|
+
type: 'read_code' | 'generate_patch' | 'run_tests' | 'run_lint' | 'collect_evidence' | 'custom';
|
|
29
|
+
command?: string;
|
|
30
|
+
targets?: string[];
|
|
31
|
+
}
|
|
32
|
+
export interface VerifyContract {
|
|
33
|
+
must_pass: string[];
|
|
34
|
+
acceptance_refs: string[];
|
|
35
|
+
command: string | null;
|
|
36
|
+
}
|
|
37
|
+
export interface NodePolicy {
|
|
38
|
+
requires_human_approval: boolean;
|
|
39
|
+
max_retries: number;
|
|
40
|
+
}
|
|
41
|
+
export interface GraphNode {
|
|
42
|
+
id: string;
|
|
43
|
+
title: string;
|
|
44
|
+
wave: number;
|
|
45
|
+
depends_on: string[];
|
|
46
|
+
workspace_strategy: WorkspaceStrategy;
|
|
47
|
+
mutation_scope: string[];
|
|
48
|
+
actions: Action[];
|
|
49
|
+
verify: VerifyContract;
|
|
50
|
+
policy: NodePolicy;
|
|
51
|
+
}
|
|
52
|
+
export interface GraphEdge {
|
|
53
|
+
from: string;
|
|
54
|
+
to: string;
|
|
55
|
+
type: 'dependency' | 'wave_sequence';
|
|
56
|
+
}
|
|
57
|
+
export interface Wave {
|
|
58
|
+
wave_number: number;
|
|
59
|
+
node_ids: string[];
|
|
60
|
+
}
|
|
61
|
+
export interface ExecutionGraphMetadata {
|
|
62
|
+
compiled_at: string;
|
|
63
|
+
plan_hash: string;
|
|
64
|
+
spec_hash: string;
|
|
65
|
+
node_count: number;
|
|
66
|
+
wave_count: number;
|
|
67
|
+
}
|
|
68
|
+
export interface ExecutionGraph {
|
|
69
|
+
nodes: Map<string, GraphNode>;
|
|
70
|
+
edges: GraphEdge[];
|
|
71
|
+
waves: Wave[];
|
|
72
|
+
metadata: ExecutionGraphMetadata;
|
|
73
|
+
}
|
|
74
|
+
export interface CompilerOptions {
|
|
75
|
+
default_workspace_strategy?: WorkspaceStrategy;
|
|
76
|
+
default_max_retries?: number;
|
|
77
|
+
require_approval_for_all?: boolean;
|
|
78
|
+
skip_done_tasks?: boolean;
|
|
79
|
+
}
|
|
80
|
+
export declare function compile(plan: ParsedPlan, spec: ParsedSpec, options?: CompilerOptions): ExecutionGraph;
|
|
81
|
+
export declare function validateGraph(graph: ExecutionGraph): string[];
|
|
82
|
+
export declare function toSerializable(graph: ExecutionGraph): Record<string, unknown>;
|
|
83
|
+
export declare function fromSerializable(raw: Record<string, unknown>): ExecutionGraph;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.compile = compile;
|
|
7
|
+
exports.validateGraph = validateGraph;
|
|
8
|
+
exports.toSerializable = toSerializable;
|
|
9
|
+
exports.fromSerializable = fromSerializable;
|
|
10
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
11
|
+
function compile(plan, spec, options = {}) {
|
|
12
|
+
const { default_workspace_strategy = 'git_worktree', default_max_retries = 2, require_approval_for_all = false, skip_done_tasks = false, } = options;
|
|
13
|
+
const nodes = new Map();
|
|
14
|
+
const edges = [];
|
|
15
|
+
const waveMap = new Map();
|
|
16
|
+
for (const task of plan.tasks) {
|
|
17
|
+
if (skip_done_tasks && task.done)
|
|
18
|
+
continue;
|
|
19
|
+
const waveNumber = task.wave ?? 1;
|
|
20
|
+
const node = {
|
|
21
|
+
id: task.id,
|
|
22
|
+
title: task.title,
|
|
23
|
+
wave: waveNumber,
|
|
24
|
+
depends_on: task.dependsOn,
|
|
25
|
+
workspace_strategy: default_workspace_strategy,
|
|
26
|
+
mutation_scope: task.files,
|
|
27
|
+
actions: buildActions(task),
|
|
28
|
+
verify: {
|
|
29
|
+
must_pass: task.verifyCommand ? ['tests'] : [],
|
|
30
|
+
acceptance_refs: task.aceite,
|
|
31
|
+
command: task.verifyCommand,
|
|
32
|
+
},
|
|
33
|
+
policy: {
|
|
34
|
+
requires_human_approval: require_approval_for_all,
|
|
35
|
+
max_retries: default_max_retries,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
nodes.set(task.id, node);
|
|
39
|
+
for (const dep of task.dependsOn) {
|
|
40
|
+
edges.push({ from: dep, to: task.id, type: 'dependency' });
|
|
41
|
+
}
|
|
42
|
+
if (!waveMap.has(waveNumber))
|
|
43
|
+
waveMap.set(waveNumber, []);
|
|
44
|
+
waveMap.get(waveNumber).push(task.id);
|
|
45
|
+
}
|
|
46
|
+
const waves = Array.from(waveMap.entries())
|
|
47
|
+
.sort(([a], [b]) => a - b)
|
|
48
|
+
.map(([wave_number, node_ids]) => ({ wave_number, node_ids }));
|
|
49
|
+
return {
|
|
50
|
+
nodes,
|
|
51
|
+
edges,
|
|
52
|
+
waves,
|
|
53
|
+
metadata: {
|
|
54
|
+
compiled_at: new Date().toISOString(),
|
|
55
|
+
plan_hash: hashObject(plan),
|
|
56
|
+
spec_hash: hashObject(spec),
|
|
57
|
+
node_count: nodes.size,
|
|
58
|
+
wave_count: waves.length,
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function validateGraph(graph) {
|
|
63
|
+
const errors = [];
|
|
64
|
+
const nodeIds = new Set(graph.nodes.keys());
|
|
65
|
+
for (const [id, node] of graph.nodes) {
|
|
66
|
+
for (const dep of node.depends_on) {
|
|
67
|
+
if (!nodeIds.has(dep)) {
|
|
68
|
+
errors.push(`Node ${id} depends on unknown node ${dep}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Detect cycles using DFS
|
|
73
|
+
const visited = new Set();
|
|
74
|
+
const inStack = new Set();
|
|
75
|
+
function hasCycle(nodeId) {
|
|
76
|
+
if (inStack.has(nodeId))
|
|
77
|
+
return true;
|
|
78
|
+
if (visited.has(nodeId))
|
|
79
|
+
return false;
|
|
80
|
+
visited.add(nodeId);
|
|
81
|
+
inStack.add(nodeId);
|
|
82
|
+
const node = graph.nodes.get(nodeId);
|
|
83
|
+
if (node) {
|
|
84
|
+
for (const dep of node.depends_on) {
|
|
85
|
+
if (hasCycle(dep))
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
inStack.delete(nodeId);
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
for (const id of nodeIds) {
|
|
93
|
+
if (hasCycle(id)) {
|
|
94
|
+
errors.push(`Cycle detected involving node ${id}`);
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return errors;
|
|
99
|
+
}
|
|
100
|
+
function toSerializable(graph) {
|
|
101
|
+
return {
|
|
102
|
+
nodes: Object.fromEntries(graph.nodes),
|
|
103
|
+
edges: graph.edges,
|
|
104
|
+
waves: graph.waves,
|
|
105
|
+
metadata: graph.metadata,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function fromSerializable(raw) {
|
|
109
|
+
const nodes = new Map(Object.entries(raw.nodes));
|
|
110
|
+
return {
|
|
111
|
+
nodes,
|
|
112
|
+
edges: raw.edges,
|
|
113
|
+
waves: raw.waves,
|
|
114
|
+
metadata: raw.metadata,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function buildActions(task) {
|
|
118
|
+
const actions = [];
|
|
119
|
+
if (task.files.length > 0) {
|
|
120
|
+
actions.push({ type: 'read_code', targets: task.files });
|
|
121
|
+
}
|
|
122
|
+
actions.push({ type: 'generate_patch' });
|
|
123
|
+
if (task.verifyCommand) {
|
|
124
|
+
actions.push({ type: 'run_tests', command: task.verifyCommand });
|
|
125
|
+
}
|
|
126
|
+
actions.push({ type: 'collect_evidence' });
|
|
127
|
+
return actions;
|
|
128
|
+
}
|
|
129
|
+
function hashObject(obj) {
|
|
130
|
+
return crypto_1.default
|
|
131
|
+
.createHash('sha256')
|
|
132
|
+
.update(JSON.stringify(obj))
|
|
133
|
+
.digest('hex')
|
|
134
|
+
.slice(0, 12);
|
|
135
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './graph-compiler';
|
|
@@ -0,0 +1,17 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./graph-compiler"), exports);
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { WorkItem } from '../models/work-item';
|
|
2
|
+
import type { Evidence } from '../models/evidence';
|
|
3
|
+
import type { RunState } from '../reducers/run-state-reducer';
|
|
4
|
+
export interface ContextArtifact {
|
|
5
|
+
id: string;
|
|
6
|
+
kind: 'evidence' | 'lesson' | 'file' | 'summary';
|
|
7
|
+
content: string;
|
|
8
|
+
relevanceScore: number;
|
|
9
|
+
tags: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface LessonMetric {
|
|
12
|
+
lesson_id: string;
|
|
13
|
+
title: string;
|
|
14
|
+
tags: string[];
|
|
15
|
+
embedding?: number[];
|
|
16
|
+
content: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ContextPackOptions {
|
|
19
|
+
maxArtifacts?: number;
|
|
20
|
+
maxTokensEstimate?: number;
|
|
21
|
+
deduplicateThreshold?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface ContextPack {
|
|
24
|
+
work_item_id: string;
|
|
25
|
+
artifacts: ContextArtifact[];
|
|
26
|
+
total_artifacts_considered: number;
|
|
27
|
+
redundancy_removed: number;
|
|
28
|
+
built_at: string;
|
|
29
|
+
}
|
|
30
|
+
export declare class ContextPackBuilder {
|
|
31
|
+
private readonly opts;
|
|
32
|
+
constructor(opts?: ContextPackOptions);
|
|
33
|
+
build(workItem: WorkItem, state: RunState, evidenceItems: Evidence[], evidenceContents: Map<string, string>, lessons: LessonMetric[]): ContextPack;
|
|
34
|
+
/** Convenience: build with no evidence, just lessons and state summary */
|
|
35
|
+
buildLightweight(workItem: WorkItem, state: RunState, lessons: LessonMetric[]): ContextPack;
|
|
36
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContextPackBuilder = void 0;
|
|
4
|
+
// ─── Relevance scoring ────────────────────────────────────────────────────────
|
|
5
|
+
function scoreEvidenceRelevance(evidence, workItem) {
|
|
6
|
+
let score = 0.5;
|
|
7
|
+
const eid = evidence.evidence_id.toLowerCase();
|
|
8
|
+
const title = workItem.title.toLowerCase();
|
|
9
|
+
const scope = workItem.mutation_scope ?? [];
|
|
10
|
+
if (scope.some((s) => eid.includes(s.toLowerCase())))
|
|
11
|
+
score += 0.3;
|
|
12
|
+
if (title.split(/\s+/).some((w) => w.length > 3 && eid.includes(w)))
|
|
13
|
+
score += 0.1;
|
|
14
|
+
if (evidence.type === 'junit_xml')
|
|
15
|
+
score += 0.05;
|
|
16
|
+
if (evidence.type === 'diff')
|
|
17
|
+
score += 0.05;
|
|
18
|
+
return Math.min(score, 1.0);
|
|
19
|
+
}
|
|
20
|
+
function scoreLessonRelevance(lesson, workItem) {
|
|
21
|
+
const itemTags = new Set([
|
|
22
|
+
...workItem.mutation_scope.map((s) => s.toLowerCase()),
|
|
23
|
+
...workItem.title.toLowerCase().split(/\s+/).filter((w) => w.length > 3),
|
|
24
|
+
]);
|
|
25
|
+
const lessonTags = lesson.tags.map((t) => t.toLowerCase());
|
|
26
|
+
const overlap = lessonTags.filter((t) => itemTags.has(t)).length;
|
|
27
|
+
const jaccard = overlap / (itemTags.size + lessonTags.length - overlap || 1);
|
|
28
|
+
return Math.min(0.3 + jaccard * 0.7, 1.0);
|
|
29
|
+
}
|
|
30
|
+
// ─── Redundancy elimination ───────────────────────────────────────────────────
|
|
31
|
+
function cosineSimilarity(a, b) {
|
|
32
|
+
const wordsA = new Set(a.content.toLowerCase().split(/\W+/).filter((w) => w.length > 3));
|
|
33
|
+
const wordsB = new Set(b.content.toLowerCase().split(/\W+/).filter((w) => w.length > 3));
|
|
34
|
+
if (wordsA.size === 0 || wordsB.size === 0)
|
|
35
|
+
return 0;
|
|
36
|
+
let intersection = 0;
|
|
37
|
+
for (const w of wordsA)
|
|
38
|
+
if (wordsB.has(w))
|
|
39
|
+
intersection++;
|
|
40
|
+
return intersection / Math.sqrt(wordsA.size * wordsB.size);
|
|
41
|
+
}
|
|
42
|
+
function deduplicateArtifacts(artifacts, threshold) {
|
|
43
|
+
const kept = [];
|
|
44
|
+
let removed = 0;
|
|
45
|
+
for (const candidate of artifacts) {
|
|
46
|
+
const isDuplicate = kept.some((existing) => cosineSimilarity(candidate, existing) >= threshold);
|
|
47
|
+
if (isDuplicate) {
|
|
48
|
+
removed++;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
kept.push(candidate);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return { kept, removed };
|
|
55
|
+
}
|
|
56
|
+
// ─── Token budget estimation ──────────────────────────────────────────────────
|
|
57
|
+
function estimateTokens(text) {
|
|
58
|
+
return Math.ceil(text.length / 4);
|
|
59
|
+
}
|
|
60
|
+
function applyTokenBudget(artifacts, maxTokens) {
|
|
61
|
+
let used = 0;
|
|
62
|
+
const result = [];
|
|
63
|
+
for (const a of artifacts) {
|
|
64
|
+
const t = estimateTokens(a.content);
|
|
65
|
+
if (used + t > maxTokens)
|
|
66
|
+
break;
|
|
67
|
+
result.push(a);
|
|
68
|
+
used += t;
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
// ─── Context Pack Builder ─────────────────────────────────────────────────────
|
|
73
|
+
class ContextPackBuilder {
|
|
74
|
+
constructor(opts = {}) {
|
|
75
|
+
this.opts = opts;
|
|
76
|
+
}
|
|
77
|
+
build(workItem, state, evidenceItems, evidenceContents, lessons) {
|
|
78
|
+
const { maxArtifacts = 20, maxTokensEstimate = 8000, deduplicateThreshold = 0.85, } = this.opts;
|
|
79
|
+
const raw = [];
|
|
80
|
+
// Score and collect evidence
|
|
81
|
+
for (const ev of evidenceItems) {
|
|
82
|
+
const content = evidenceContents.get(ev.evidence_id) ?? '';
|
|
83
|
+
if (!content)
|
|
84
|
+
continue;
|
|
85
|
+
raw.push({
|
|
86
|
+
id: ev.evidence_id,
|
|
87
|
+
kind: 'evidence',
|
|
88
|
+
content,
|
|
89
|
+
relevanceScore: scoreEvidenceRelevance(ev, workItem),
|
|
90
|
+
tags: [ev.type, workItem.work_item_id],
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// Score and collect lessons
|
|
94
|
+
for (const lesson of lessons) {
|
|
95
|
+
raw.push({
|
|
96
|
+
id: lesson.lesson_id,
|
|
97
|
+
kind: 'lesson',
|
|
98
|
+
content: lesson.content,
|
|
99
|
+
relevanceScore: scoreLessonRelevance(lesson, workItem),
|
|
100
|
+
tags: lesson.tags,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
// Add run-level summary if available
|
|
104
|
+
const completedCount = state.completedWorkItems.size;
|
|
105
|
+
if (completedCount > 0) {
|
|
106
|
+
raw.push({
|
|
107
|
+
id: `run-summary-${workItem.run_id}`,
|
|
108
|
+
kind: 'summary',
|
|
109
|
+
content: `Run progress: ${completedCount} completed, ${state.failedWorkItems.size} failed, ${state.blockedWorkItems.size} blocked.`,
|
|
110
|
+
relevanceScore: 0.4,
|
|
111
|
+
tags: ['run-context'],
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
const totalConsidered = raw.length;
|
|
115
|
+
// Sort by relevance descending
|
|
116
|
+
raw.sort((a, b) => b.relevanceScore - a.relevanceScore);
|
|
117
|
+
// Deduplicate
|
|
118
|
+
const { kept, removed } = deduplicateArtifacts(raw, deduplicateThreshold);
|
|
119
|
+
// Apply max artifacts cap
|
|
120
|
+
const capped = kept.slice(0, maxArtifacts);
|
|
121
|
+
// Apply token budget
|
|
122
|
+
const final = applyTokenBudget(capped, maxTokensEstimate);
|
|
123
|
+
return {
|
|
124
|
+
work_item_id: workItem.work_item_id,
|
|
125
|
+
artifacts: final,
|
|
126
|
+
total_artifacts_considered: totalConsidered,
|
|
127
|
+
redundancy_removed: removed,
|
|
128
|
+
built_at: new Date().toISOString(),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/** Convenience: build with no evidence, just lessons and state summary */
|
|
132
|
+
buildLightweight(workItem, state, lessons) {
|
|
133
|
+
return this.build(workItem, state, [], new Map(), lessons);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
exports.ContextPackBuilder = ContextPackBuilder;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './context-pack-builder';
|