oxe-cc 1.8.0 → 1.9.1
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/AGENTS.md +1 -1
- package/CHANGELOG.md +94 -0
- package/README.md +15 -12
- package/bin/lib/oxe-manifest.cjs +20 -13
- package/bin/lib/oxe-operational.cjs +305 -79
- package/bin/lib/oxe-project-health.cjs +79 -18
- package/bin/lib/oxe-rationality.cjs +9 -7
- package/bin/lib/oxe-release.cjs +26 -0
- package/bin/oxe-cc.js +224 -52
- package/docs/RELEASE-READINESS.md +6 -1
- package/lib/runtime/compiler/graph-compiler.js +1 -1
- package/lib/runtime/executor/action-tool-map.js +4 -0
- package/lib/runtime/executor/built-in-tools.js +27 -0
- package/lib/runtime/executor/llm-task-executor.d.ts +4 -1
- package/lib/runtime/executor/llm-task-executor.js +41 -5
- package/lib/runtime/executor/node-prompt-builder.d.ts +4 -1
- package/lib/runtime/executor/node-prompt-builder.js +13 -2
- package/lib/runtime/models/failure.d.ts +1 -1
- package/lib/runtime/scheduler/multi-agent-coordinator.d.ts +39 -0
- package/lib/runtime/scheduler/multi-agent-coordinator.js +222 -13
- package/lib/runtime/scheduler/scheduler.d.ts +5 -1
- package/lib/runtime/scheduler/scheduler.js +82 -14
- package/lib/runtime/verification/verification-compiler.js +7 -5
- package/lib/runtime/workspace/strategies/git-worktree.js +18 -9
- package/lib/sdk/index.cjs +48 -44
- package/oxe/templates/PLAN.template.md +23 -9
- package/oxe/templates/SPEC.template.md +55 -22
- package/oxe/workflows/plan.md +18 -6
- package/oxe/workflows/spec.md +31 -9
- package/package.json +106 -100
- package/packages/runtime/package.json +18 -18
- package/packages/runtime/src/compiler/graph-compiler.ts +1 -1
- package/packages/runtime/src/evidence/evidence-store.ts +2 -2
- package/packages/runtime/src/executor/action-tool-map.ts +4 -0
- package/packages/runtime/src/executor/built-in-tools.ts +29 -0
- package/packages/runtime/src/executor/llm-task-executor.ts +46 -4
- package/packages/runtime/src/executor/node-prompt-builder.ts +18 -1
- package/packages/runtime/src/models/failure.ts +2 -0
- package/packages/runtime/src/scheduler/multi-agent-coordinator.ts +320 -46
- package/packages/runtime/src/scheduler/scheduler.ts +93 -15
- package/packages/runtime/src/verification/verification-compiler.ts +7 -5
- package/packages/runtime/src/workspace/strategies/git-worktree.ts +24 -16
- package/vscode-extension/package.json +185 -185
- package/vscode-extension/oxe-agents-0.9.1.vsix +0 -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/oxe-agents-1.4.0.vsix +0 -0
- package/vscode-extension/oxe-agents-1.5.0.vsix +0 -0
- package/vscode-extension/oxe-agents-1.5.1.vsix +0 -0
- package/vscode-extension/oxe-agents-1.6.0.vsix +0 -0
- package/vscode-extension/oxe-agents-1.7.0.vsix +0 -0
- package/vscode-extension/oxe-agents-1.8.0.vsix +0 -0
package/bin/oxe-cc.js
CHANGED
|
@@ -209,8 +209,8 @@ function buildInstallSummary(opts, fullLayout) {
|
|
|
209
209
|
if (opts.copilotCli || opts.allAgents || anyGranularAgent(opts)) agentHint.push('CLIs / multi-agente');
|
|
210
210
|
if (agentHint.length) {
|
|
211
211
|
nextSteps.push({
|
|
212
|
-
desc: `
|
|
213
|
-
cmd: '/oxe
|
|
212
|
+
desc: `Entrar no fluxo OXE no agente (${agentHint.join(', ')}) e deixar o router indicar o primeiro passo:`,
|
|
213
|
+
cmd: '/oxe',
|
|
214
214
|
});
|
|
215
215
|
} else if (opts.oxeOnly) {
|
|
216
216
|
nextSteps.push({
|
|
@@ -220,7 +220,7 @@ function buildInstallSummary(opts, fullLayout) {
|
|
|
220
220
|
} else {
|
|
221
221
|
nextSteps.push({
|
|
222
222
|
desc: 'Primeiro passo do fluxo no seu editor:',
|
|
223
|
-
cmd: '/oxe
|
|
223
|
+
cmd: '/oxe',
|
|
224
224
|
});
|
|
225
225
|
}
|
|
226
226
|
|
|
@@ -252,6 +252,7 @@ function buildUninstallFooter(u) {
|
|
|
252
252
|
const bullets = [];
|
|
253
253
|
const p = u.dryRun ? '[simulação] ' : '';
|
|
254
254
|
const rm = u.dryRun ? 'Seriam removidos' : 'Removidos';
|
|
255
|
+
const localIdeArtifacts = shouldAlsoRemoveLocalIdeArtifacts(u);
|
|
255
256
|
const granularAgents = [
|
|
256
257
|
u.agentOpenCode ? 'OpenCode' : null,
|
|
257
258
|
u.agentGemini ? 'Gemini' : null,
|
|
@@ -277,9 +278,9 @@ function buildUninstallFooter(u) {
|
|
|
277
278
|
} else if (granularAgents.length) {
|
|
278
279
|
bullets.push(`${p}${rm} apenas as integrações selecionadas: ${granularAgents.join(', ')}.`);
|
|
279
280
|
}
|
|
280
|
-
if (
|
|
281
|
+
if (localIdeArtifacts) {
|
|
281
282
|
bullets.push(
|
|
282
|
-
`${p}${rm} integrações OXE no repositório (.cursor, .github, .claude, .copilot, .opencode, … conforme flags).`
|
|
283
|
+
`${p}${rm} integrações OXE no repositório (.cursor, .github, .claude, .copilot, .opencode, … conforme flags ou artefatos locais detectados).`
|
|
283
284
|
);
|
|
284
285
|
}
|
|
285
286
|
if (u.globalCli) bullets.push(`${p}${rm} também o pacote npm global oxe-cc do PATH.`);
|
|
@@ -1533,7 +1534,9 @@ function printOxeHealthDiagnostics(target, c, diagOpts = {}) {
|
|
|
1533
1534
|
typeof r.planSelfEvaluation.confidence === 'number' ? `${r.planSelfEvaluation.confidence}%` : '—';
|
|
1534
1535
|
console.log(` ${c ? dim : ''}Plano (autoavaliação):${c ? reset : ''} melhor=${best} | confiança=${conf}`);
|
|
1535
1536
|
}
|
|
1536
|
-
if (
|
|
1537
|
+
if (r.executionRationality && r.executionRationality.applicable === false) {
|
|
1538
|
+
console.log(` ${c ? dim : ''}Prontidão racional:${c ? reset : ''} não aplicável ainda (PLAN.md ausente)`);
|
|
1539
|
+
} else if (typeof r.executionRationalityReady === 'boolean') {
|
|
1537
1540
|
console.log(
|
|
1538
1541
|
` ${c ? dim : ''}Prontidão racional:${c ? reset : ''} implementation=${r.implementationPackReady ? 'ok' : 'pendente'} | anchors=${r.referenceAnchorsReady ? 'ok' : 'pendente'} | fixtures=${r.fixturePackReady ? 'ok' : 'pendente'}`
|
|
1539
1542
|
);
|
|
@@ -1670,7 +1673,7 @@ function runStatusFull(target) {
|
|
|
1670
1673
|
|
|
1671
1674
|
printSection('OXE ▸ status --full');
|
|
1672
1675
|
console.log(` ${c ? green : ''}Projeto:${c ? reset : ''} ${c ? cyan : ''}${target}${c ? reset : ''}`);
|
|
1673
|
-
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || '
|
|
1676
|
+
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || '— (sem sessão ativa)'}${c ? reset : ''}`);
|
|
1674
1677
|
console.log(` ${c ? green : ''}Workspace mode:${c ? reset : ''} ${report.workspaceMode || 'oxe_project'}`);
|
|
1675
1678
|
console.log(` ${c ? green : ''}Fase:${c ? reset : ''} ${report.phase || '—'}`);
|
|
1676
1679
|
|
|
@@ -2102,10 +2105,18 @@ function runDoctor(target, options = {}) {
|
|
|
2102
2105
|
.sort();
|
|
2103
2106
|
|
|
2104
2107
|
if (!wfTgt) {
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
)
|
|
2108
|
-
|
|
2108
|
+
// If the project has .oxe/runs/ it's a runtime-only project — workflows are optional
|
|
2109
|
+
const hasRuntimeRuns = fs.existsSync(path.join(target, '.oxe', 'runs'));
|
|
2110
|
+
if (hasRuntimeRuns) {
|
|
2111
|
+
console.log(`${green}OK${reset} Runtime-only project (.oxe/runs/ presente) — workflows não obrigatórios.`);
|
|
2112
|
+
console.log(`${c ? dim : ''} Para instalar workflows completos: ${cyan}npx oxe-cc@latest${reset}`);
|
|
2113
|
+
} else {
|
|
2114
|
+
console.log(
|
|
2115
|
+
`${yellow}AVISO${reset} Não há oxe/workflows/ nem .oxe/workflows/ neste projeto — rode ${cyan}npx oxe-cc@latest${reset} para instalar.`
|
|
2116
|
+
);
|
|
2117
|
+
process.exit(1);
|
|
2118
|
+
}
|
|
2119
|
+
return;
|
|
2109
2120
|
}
|
|
2110
2121
|
|
|
2111
2122
|
const actual = fs
|
|
@@ -2190,6 +2201,8 @@ function runDoctor(target, options = {}) {
|
|
|
2190
2201
|
}
|
|
2191
2202
|
}
|
|
2192
2203
|
|
|
2204
|
+
const report = oxeHealth.buildHealthReport(target);
|
|
2205
|
+
|
|
2193
2206
|
// IDE health gates
|
|
2194
2207
|
console.log('');
|
|
2195
2208
|
const ideChecks = [];
|
|
@@ -2204,25 +2217,44 @@ function runDoctor(target, options = {}) {
|
|
|
2204
2217
|
|
|
2205
2218
|
const claudeLocalDir = path.join(target, 'commands', 'oxe');
|
|
2206
2219
|
const claudeGlobalDir = path.join(require('os').homedir(), '.claude', 'commands');
|
|
2207
|
-
const
|
|
2208
|
-
|
|
2220
|
+
const claudeLocalReady = fs.existsSync(claudeLocalDir);
|
|
2221
|
+
const claudeGlobalReady = fs.existsSync(claudeGlobalDir);
|
|
2222
|
+
ideChecks.push({
|
|
2223
|
+
label: 'Claude Code',
|
|
2224
|
+
ready: claudeLocalReady || claudeGlobalReady,
|
|
2225
|
+
hint: claudeLocalReady
|
|
2226
|
+
? 'commands/oxe/'
|
|
2227
|
+
: claudeGlobalReady
|
|
2228
|
+
? '~/.claude/commands/ (global do utilizador)'
|
|
2229
|
+
: 'commands/oxe/ ou ~/.claude/commands/',
|
|
2230
|
+
status: claudeLocalReady ? 'local' : claudeGlobalReady ? 'global_only' : 'missing',
|
|
2231
|
+
});
|
|
2209
2232
|
|
|
2210
2233
|
const codexReport = oxeHealth.codexIntegrationReport(target);
|
|
2211
|
-
ideChecks.push({
|
|
2234
|
+
ideChecks.push({
|
|
2235
|
+
label: 'Codex',
|
|
2236
|
+
ready: codexReport.commandsReady,
|
|
2237
|
+
hint: codexReport.promptSource === 'workspace'
|
|
2238
|
+
? '.codex/prompts/oxe.md'
|
|
2239
|
+
: codexReport.promptSource === 'global'
|
|
2240
|
+
? '~/.codex/prompts/oxe.md (global do utilizador)'
|
|
2241
|
+
: '.codex/prompts/oxe.md ou ~/.codex/prompts/oxe.md',
|
|
2242
|
+
status: codexReport.promptSource,
|
|
2243
|
+
});
|
|
2212
2244
|
|
|
2213
2245
|
for (const ide of ideChecks) {
|
|
2214
2246
|
if (ide.ready) {
|
|
2215
|
-
|
|
2247
|
+
const suffix = ide.status === 'global_only' || ide.status === 'global'
|
|
2248
|
+
? ' — apenas global'
|
|
2249
|
+
: '';
|
|
2250
|
+
console.log(`${c ? green : ''}OK${c ? reset : ''} ${ide.label} pronto (${ide.hint})${suffix}`);
|
|
2216
2251
|
} else {
|
|
2217
2252
|
console.log(`${c ? dim : ''}Obs.:${c ? reset : ''} ${ide.label} não detectado — esperado ${ide.hint}`);
|
|
2218
2253
|
}
|
|
2219
2254
|
}
|
|
2220
2255
|
|
|
2221
2256
|
// Runtime compilation check
|
|
2222
|
-
|
|
2223
|
-
const runtimeDistPath = path.join(target, 'packages', 'runtime', 'dist-tests');
|
|
2224
|
-
const runtimeCompiled = fs.existsSync(runtimeCompiledPath) || fs.existsSync(runtimeDistPath);
|
|
2225
|
-
if (runtimeCompiled) {
|
|
2257
|
+
if (report.runtimeMode && report.runtimeMode.enterprise_available) {
|
|
2226
2258
|
console.log(`${c ? green : ''}OK${c ? reset : ''} Runtime compilado detectado — modo enterprise disponível`);
|
|
2227
2259
|
} else {
|
|
2228
2260
|
console.log(`${c ? dim : ''}Obs.:${c ? reset : ''} Runtime não compilado — operando em modo legado (sem perda de UX)`);
|
|
@@ -2230,7 +2262,7 @@ function runDoctor(target, options = {}) {
|
|
|
2230
2262
|
|
|
2231
2263
|
// Readiness gate summary
|
|
2232
2264
|
const stateFilePath = path.join(target, '.oxe', 'STATE.md');
|
|
2233
|
-
let readinessCmd = '/oxe
|
|
2265
|
+
let readinessCmd = '/oxe';
|
|
2234
2266
|
let readinessDesc = 'Nenhum STATE.md encontrado';
|
|
2235
2267
|
if (fs.existsSync(stateFilePath)) {
|
|
2236
2268
|
try {
|
|
@@ -2238,7 +2270,7 @@ function runDoctor(target, options = {}) {
|
|
|
2238
2270
|
const phaseMatch = stateContent.match(/fase[:\s]+([a-z_]+)/i) || stateContent.match(/phase[:\s]+([a-z_]+)/i) || stateContent.match(/status[:\s]+([a-z_]+)/i);
|
|
2239
2271
|
const phase = phaseMatch ? phaseMatch[1].toLowerCase() : 'init';
|
|
2240
2272
|
const phaseMap = {
|
|
2241
|
-
init: { cmd: '/oxe
|
|
2273
|
+
init: { cmd: '/oxe', desc: 'Pronto para /oxe' },
|
|
2242
2274
|
scan_complete: { cmd: '/oxe-spec', desc: 'Pronto para /oxe-spec' },
|
|
2243
2275
|
spec_complete: { cmd: '/oxe-plan', desc: 'Pronto para /oxe-plan' },
|
|
2244
2276
|
plan_complete: { cmd: '/oxe-execute', desc: 'Pronto para /oxe-execute' },
|
|
@@ -2260,7 +2292,6 @@ function runDoctor(target, options = {}) {
|
|
|
2260
2292
|
}
|
|
2261
2293
|
|
|
2262
2294
|
printOxeHealthDiagnostics(target, c);
|
|
2263
|
-
const report = oxeHealth.buildHealthReport(target);
|
|
2264
2295
|
const statusColor = report.healthStatus === 'healthy' ? green : report.healthStatus === 'warning' ? yellow : red;
|
|
2265
2296
|
console.log(`\n ${statusColor}Diagnóstico ${report.healthStatus}${reset}`);
|
|
2266
2297
|
if (report.healthStatus === 'broken') {
|
|
@@ -2275,7 +2306,7 @@ function runDoctor(target, options = {}) {
|
|
|
2275
2306
|
`Saúde lógica: ${report.healthStatus}`,
|
|
2276
2307
|
],
|
|
2277
2308
|
nextSteps: [
|
|
2278
|
-
{ desc: '
|
|
2309
|
+
{ desc: 'Entrar no fluxo OXE e deixar o router apontar o primeiro passo:', cmd: '/oxe' },
|
|
2279
2310
|
{ desc: 'Ver ajuda e ordem dos passos OXE:', cmd: '/oxe-help' },
|
|
2280
2311
|
{ desc: 'Reinstalar ou atualizar arquivos do OXE:', cmd: 'npx oxe-cc@latest --force' },
|
|
2281
2312
|
],
|
|
@@ -2496,7 +2527,7 @@ ${cyan}oxe-cc${reset} — instala workflows OXE (núcleo .oxe/ + integrações:
|
|
|
2496
2527
|
npx oxe-cc init-oxe [opções] [pasta-do-projeto]
|
|
2497
2528
|
npx oxe-cc context <build|inspect> [opções] [pasta-do-projeto]
|
|
2498
2529
|
npx oxe-cc dashboard [opções] [pasta-do-projeto]
|
|
2499
|
-
npx oxe-cc runtime <status|start|pause|resume|replay|compile|verify|project|ci|promote|recover|gates|agents> [opções] [pasta-do-projeto]
|
|
2530
|
+
npx oxe-cc runtime <status|start|pause|resume|replay|compile|verify|project|ci|promote|recover|gates|agents|execute> [opções] [pasta-do-projeto]
|
|
2500
2531
|
npx oxe-cc azure <status|doctor|auth|sync|find|servicebus|eventgrid|sql|operations> [opções] [pasta-do-projeto]
|
|
2501
2532
|
npx oxe-cc capabilities <list|install|remove|update> [opções] [id]
|
|
2502
2533
|
npx oxe-cc uninstall [opções] [pasta-do-projeto]
|
|
@@ -2695,7 +2726,19 @@ function runInstall(opts) {
|
|
|
2695
2726
|
assertNotWslWindowsNode();
|
|
2696
2727
|
const home = os.homedir();
|
|
2697
2728
|
const prevManifest = oxeManifest.loadFileManifest(home);
|
|
2698
|
-
|
|
2729
|
+
const backupScopeRoots = [target];
|
|
2730
|
+
const installAgentPaths = oxeAgentInstall.buildAgentInstallPaths(!opts.ideLocal, target);
|
|
2731
|
+
if (opts.cursor) backupScopeRoots.push(installCursorBase(opts));
|
|
2732
|
+
if (opts.copilot) backupScopeRoots.push(path.join(target, '.github'));
|
|
2733
|
+
if (opts.copilotCli || opts.allAgents) {
|
|
2734
|
+
backupScopeRoots.push(installClaudeBase(opts), installCopilotCliHome(opts));
|
|
2735
|
+
}
|
|
2736
|
+
if (opts.agentOpenCode || opts.allAgents) backupScopeRoots.push(...installAgentPaths.opencodeCommandDirs);
|
|
2737
|
+
if (opts.agentGemini || opts.allAgents) backupScopeRoots.push(installAgentPaths.geminiCommandsBase);
|
|
2738
|
+
if (opts.agentCodex || opts.allAgents) backupScopeRoots.push(installAgentPaths.codexPromptsDir, installAgentPaths.codexAgentsSkillsRoot);
|
|
2739
|
+
if (opts.agentWindsurf || opts.allAgents) backupScopeRoots.push(installAgentPaths.windsurfWorkflowsDir);
|
|
2740
|
+
if (opts.agentAntigravity || opts.allAgents) backupScopeRoots.push(installAgentPaths.antigravitySkillsRoot);
|
|
2741
|
+
oxeManifest.backupModifiedFromManifest(home, prevManifest, opts, { yellow, cyan, dim, reset }, { scopeRoots: backupScopeRoots });
|
|
2699
2742
|
|
|
2700
2743
|
printSection('OXE ▸ Instalação no projeto');
|
|
2701
2744
|
const c = useAnsiColors();
|
|
@@ -2735,7 +2778,7 @@ function runInstall(opts) {
|
|
|
2735
2778
|
}
|
|
2736
2779
|
|
|
2737
2780
|
const copyOpts = { dryRun: opts.dryRun, force: opts.force };
|
|
2738
|
-
const agentPaths =
|
|
2781
|
+
const agentPaths = installAgentPaths;
|
|
2739
2782
|
|
|
2740
2783
|
if (fullLayout) {
|
|
2741
2784
|
copyDir(path.join(PKG_ROOT, 'oxe'), path.join(target, 'oxe'), copyOpts, false);
|
|
@@ -3145,6 +3188,31 @@ function uninstallLocalIdeFromProject(u, removedPaths) {
|
|
|
3145
3188
|
}
|
|
3146
3189
|
}
|
|
3147
3190
|
|
|
3191
|
+
/**
|
|
3192
|
+
* @param {UninstallOpts} u
|
|
3193
|
+
*/
|
|
3194
|
+
function shouldAlsoRemoveLocalIdeArtifacts(u) {
|
|
3195
|
+
if (u.ideLocal) return true;
|
|
3196
|
+
if (u.noProject) return false;
|
|
3197
|
+
if (!(u.allAgents || anyGranularUninstallAgent(u) || u.cursor || u.copilot || u.copilotCli)) return false;
|
|
3198
|
+
const proj = path.resolve(u.dir);
|
|
3199
|
+
const localAgentPaths = oxeAgentInstall.buildAgentInstallPaths(false, proj);
|
|
3200
|
+
if (u.cursor && fs.existsSync(path.join(proj, '.cursor', 'commands'))) return true;
|
|
3201
|
+
if (u.copilot && (fs.existsSync(path.join(proj, '.github', 'prompts')) || fs.existsSync(path.join(proj, '.github', 'copilot-instructions.md')))) {
|
|
3202
|
+
return true;
|
|
3203
|
+
}
|
|
3204
|
+
if (u.copilotCli && (fs.existsSync(path.join(proj, '.claude', 'commands')) || fs.existsSync(path.join(proj, '.copilot', 'commands')))) {
|
|
3205
|
+
return true;
|
|
3206
|
+
}
|
|
3207
|
+
const selectedAll = u.allAgents || !anyGranularUninstallAgent(u);
|
|
3208
|
+
if ((selectedAll || u.agentOpenCode) && localAgentPaths.opencodeCommandDirs.some((dir) => fs.existsSync(dir))) return true;
|
|
3209
|
+
if ((selectedAll || u.agentGemini) && fs.existsSync(localAgentPaths.geminiCommandsBase)) return true;
|
|
3210
|
+
if ((selectedAll || u.agentCodex) && (fs.existsSync(localAgentPaths.codexPromptsDir) || fs.existsSync(localAgentPaths.codexAgentsSkillsRoot))) return true;
|
|
3211
|
+
if ((selectedAll || u.agentWindsurf) && fs.existsSync(localAgentPaths.windsurfWorkflowsDir)) return true;
|
|
3212
|
+
if ((selectedAll || u.agentAntigravity) && fs.existsSync(localAgentPaths.antigravitySkillsRoot)) return true;
|
|
3213
|
+
return false;
|
|
3214
|
+
}
|
|
3215
|
+
|
|
3148
3216
|
/**
|
|
3149
3217
|
* @param {string[]} argv
|
|
3150
3218
|
* @returns {UninstallOpts}
|
|
@@ -3376,6 +3444,7 @@ function runUninstall(u) {
|
|
|
3376
3444
|
if (u.dryRun) console.log(` ${c ? yellow : ''}(dry-run)${c ? reset : ''}`);
|
|
3377
3445
|
|
|
3378
3446
|
const removedPaths = [];
|
|
3447
|
+
const removeLocalIdeArtifacts = shouldAlsoRemoveLocalIdeArtifacts(u);
|
|
3379
3448
|
|
|
3380
3449
|
if (u.cursor) {
|
|
3381
3450
|
const base = cursorUserDir(ideOpts);
|
|
@@ -3531,7 +3600,7 @@ function runUninstall(u) {
|
|
|
3531
3600
|
}
|
|
3532
3601
|
}
|
|
3533
3602
|
|
|
3534
|
-
if (
|
|
3603
|
+
if (removeLocalIdeArtifacts) {
|
|
3535
3604
|
uninstallLocalIdeFromProject(u, removedPaths);
|
|
3536
3605
|
}
|
|
3537
3606
|
|
|
@@ -3976,6 +4045,13 @@ function parseRuntimeArgs(argv) {
|
|
|
3976
4045
|
fromEventId: '',
|
|
3977
4046
|
writeReport: false,
|
|
3978
4047
|
gateId: '',
|
|
4048
|
+
// execute flags
|
|
4049
|
+
provider: '',
|
|
4050
|
+
apiKey: '',
|
|
4051
|
+
model: '',
|
|
4052
|
+
baseUrl: '',
|
|
4053
|
+
maxTurns: null,
|
|
4054
|
+
recompile: false,
|
|
3979
4055
|
decision: '',
|
|
3980
4056
|
actor: '',
|
|
3981
4057
|
targetKind: '',
|
|
@@ -4013,6 +4089,12 @@ function parseRuntimeArgs(argv) {
|
|
|
4013
4089
|
else if (a === '--status' && argv[i + 1]) out.gateStatus = String(argv[++i]);
|
|
4014
4090
|
else if (a === '--scope' && argv[i + 1]) out.gateScope = String(argv[++i]);
|
|
4015
4091
|
else if (a === '--json') out.jsonOutput = true;
|
|
4092
|
+
else if (a === '--provider' && argv[i + 1]) out.provider = String(argv[++i]);
|
|
4093
|
+
else if (a === '--api-key' && argv[i + 1]) out.apiKey = String(argv[++i]);
|
|
4094
|
+
else if (a === '--model' && argv[i + 1]) out.model = String(argv[++i]);
|
|
4095
|
+
else if (a === '--base-url' && argv[i + 1]) out.baseUrl = String(argv[++i]);
|
|
4096
|
+
else if (a === '--max-turns' && argv[i + 1]) out.maxTurns = Number(argv[++i]);
|
|
4097
|
+
else if (a === '--recompile') out.recompile = true;
|
|
4016
4098
|
else if (!a.startsWith('-')) positionals.push(a);
|
|
4017
4099
|
else {
|
|
4018
4100
|
out.parseError = true;
|
|
@@ -4155,7 +4237,7 @@ function runContext(opts) {
|
|
|
4155
4237
|
return;
|
|
4156
4238
|
}
|
|
4157
4239
|
console.log(` ${c ? green : ''}Projeto:${c ? reset : ''} ${c ? cyan : ''}${opts.dir}${c ? reset : ''}`);
|
|
4158
|
-
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || '
|
|
4240
|
+
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || '— (sem sessão ativa)'}${c ? reset : ''}`);
|
|
4159
4241
|
console.log(` ${c ? green : ''}Workflow:${c ? reset : ''} ${selectedWorkflow}`);
|
|
4160
4242
|
console.log(` ${c ? green : ''}Tier:${c ? reset : ''} ${pack.context_tier}`);
|
|
4161
4243
|
console.log(` ${c ? green : ''}Quality:${c ? reset : ''} ${pack.context_quality.score} (${pack.context_quality.status})`);
|
|
@@ -4222,7 +4304,7 @@ function runContext(opts) {
|
|
|
4222
4304
|
return;
|
|
4223
4305
|
}
|
|
4224
4306
|
console.log(` ${c ? green : ''}Projeto:${c ? reset : ''} ${c ? cyan : ''}${opts.dir}${c ? reset : ''}`);
|
|
4225
|
-
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || '
|
|
4307
|
+
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || '— (sem sessão ativa)'}${c ? reset : ''}`);
|
|
4226
4308
|
console.log(` ${c ? green : ''}Packs:${c ? reset : ''} ${packs.length}`);
|
|
4227
4309
|
for (const pack of packs) {
|
|
4228
4310
|
const qualityFlag = (pack.context_quality.score < 30 || pack.context_quality.status === 'critical') ? ` ${yellow}[CRÍTICO]${reset}` : '';
|
|
@@ -4287,7 +4369,7 @@ async function runRuntime(opts) {
|
|
|
4287
4369
|
const activeSession = opts.activeSession || oxeHealth.parseActiveSession(stateText) || null;
|
|
4288
4370
|
const p = oxeOperational.operationalPaths(opts.dir, activeSession);
|
|
4289
4371
|
console.log(` ${c ? green : ''}Projeto:${c ? reset : ''} ${c ? cyan : ''}${opts.dir}${c ? reset : ''}`);
|
|
4290
|
-
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || '
|
|
4372
|
+
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || '— (sem sessão ativa)'}${c ? reset : ''}`);
|
|
4291
4373
|
|
|
4292
4374
|
if (opts.action === 'status') {
|
|
4293
4375
|
const current = oxeOperational.readRunState(opts.dir, activeSession);
|
|
@@ -4350,13 +4432,28 @@ async function runRuntime(opts) {
|
|
|
4350
4432
|
console.log(` ${c ? green : ''}Runtime:${c ? reset : ''} ${runtimeMode.runtime_mode || 'legacy'} · fallback=${runtimeMode.fallback_mode || 'none'}`);
|
|
4351
4433
|
}
|
|
4352
4434
|
if (report.policyCoverage) {
|
|
4353
|
-
|
|
4435
|
+
const pctCov = report.policyCoverage.coveragePercent;
|
|
4436
|
+
const policyLabel = pctCov === 0
|
|
4437
|
+
? `${c ? dim : ''}não configurada (opcional)${c ? reset : ''}`
|
|
4438
|
+
: `${pctCov}% · uncovered=${report.policyCoverage.uncoveredMutations}`;
|
|
4439
|
+
console.log(` ${c ? green : ''}Policy coverage:${c ? reset : ''} ${policyLabel}`);
|
|
4354
4440
|
}
|
|
4355
4441
|
if (report.promotionReadiness) {
|
|
4356
|
-
|
|
4442
|
+
const promoStatus = report.promotionReadiness.status;
|
|
4443
|
+
const blockers = Array.isArray(report.promotionReadiness.blockers) ? report.promotionReadiness.blockers : [];
|
|
4444
|
+
// Only show blockers that are not solely due to unconfigured policy
|
|
4445
|
+
const meaningfulBlockers = blockers.filter(b => b !== 'policy_uncovered_mutations' || report.policyCoverage.coveragePercent > 0);
|
|
4446
|
+
const promoLabel = promoStatus === 'blocked' && meaningfulBlockers.length === 0
|
|
4447
|
+
? `${c ? dim : ''}n/a (execução não concluída)${c ? reset : ''}`
|
|
4448
|
+
: `${promoStatus}${meaningfulBlockers.length ? ` · ${meaningfulBlockers.join(', ')}` : ''}`;
|
|
4449
|
+
console.log(` ${c ? green : ''}Promotion readiness:${c ? reset : ''} ${promoLabel}`);
|
|
4357
4450
|
}
|
|
4358
4451
|
if (report.recoveryState) {
|
|
4359
|
-
|
|
4452
|
+
const recIssues = Array.isArray(report.recoveryState.issues) ? report.recoveryState.issues.length : 0;
|
|
4453
|
+
const recLabel = recIssues === 0
|
|
4454
|
+
? `${report.recoveryState.status} · ok`
|
|
4455
|
+
: `${report.recoveryState.status} · issues=${recIssues} — rode ${c ? cyan : ''}runtime status --verbose${c ? reset : ''} para detalhes`;
|
|
4456
|
+
console.log(` ${c ? green : ''}Recovery:${c ? reset : ''} ${recLabel} · recoveries=${report.recoveryState.recoverCount ?? 0}`);
|
|
4360
4457
|
}
|
|
4361
4458
|
if (multiAgent) {
|
|
4362
4459
|
console.log(` ${c ? green : ''}Multi-agent:${c ? reset : ''} ${multiAgent.enabled ? (multiAgent.mode || 'active') : 'disabled'} · agentes=${Array.isArray(multiAgent.agents) ? multiAgent.agents.length : 0} · ownership=${Array.isArray(multiAgent.ownership) ? multiAgent.ownership.length : 0}`);
|
|
@@ -4526,6 +4623,17 @@ async function runRuntime(opts) {
|
|
|
4526
4623
|
|
|
4527
4624
|
if (opts.action === 'compile') {
|
|
4528
4625
|
try {
|
|
4626
|
+
// --recompile: delete existing run state files so a fresh run_id is generated
|
|
4627
|
+
if (opts.recompile) {
|
|
4628
|
+
const runsDir = path.join(opts.dir, '.oxe', 'runs');
|
|
4629
|
+
if (require('fs').existsSync(runsDir)) {
|
|
4630
|
+
require('fs').readdirSync(runsDir).forEach(f => {
|
|
4631
|
+
if (f.endsWith('.json') && !f.includes('ci-results')) {
|
|
4632
|
+
require('fs').unlinkSync(path.join(runsDir, f));
|
|
4633
|
+
}
|
|
4634
|
+
});
|
|
4635
|
+
}
|
|
4636
|
+
}
|
|
4529
4637
|
const compiled = oxeOperational.compileExecutionGraphFromArtifacts(opts.dir, activeSession);
|
|
4530
4638
|
const suite = oxeOperational.compileVerificationSuiteFromArtifacts(opts.dir, activeSession, {
|
|
4531
4639
|
runState: compiled.run,
|
|
@@ -4535,7 +4643,33 @@ async function runRuntime(opts) {
|
|
|
4535
4643
|
console.log(` ${c ? green : ''}Graph:${c ? reset : ''} ${compiled.graph.metadata.node_count} nó(s) · ${compiled.graph.metadata.wave_count} onda(s)`);
|
|
4536
4644
|
console.log(` ${c ? green : ''}Checks:${c ? reset : ''} ${Array.isArray(suite.suite.checks) ? suite.suite.checks.length : 0}`);
|
|
4537
4645
|
if (compiled.validationErrors.length) {
|
|
4538
|
-
|
|
4646
|
+
// Bucket 1: static-analysis hints (HINT(...))
|
|
4647
|
+
const hints = compiled.validationErrors.filter(e => e.startsWith('HINT('));
|
|
4648
|
+
// Bucket 2: mutation-scope overlaps (info-only in single-agent)
|
|
4649
|
+
const mutationWarns = compiled.validationErrors.filter(e => e.includes('mutate the same paths in parallel'));
|
|
4650
|
+
// Bucket 3: structural errors (cycles, missing deps)
|
|
4651
|
+
const blocking = compiled.validationErrors.filter(e =>
|
|
4652
|
+
!e.startsWith('HINT(') && !e.includes('mutate the same paths in parallel')
|
|
4653
|
+
);
|
|
4654
|
+
if (blocking.length) {
|
|
4655
|
+
console.log(` ${yellow}Validation (erros):${reset} ${blocking.join(' | ')}`);
|
|
4656
|
+
}
|
|
4657
|
+
if (mutationWarns.length) {
|
|
4658
|
+
console.log(` ${c ? dim : ''}Info (single-agent — tarefas na mesma onda são sequenciais, sobreposição de arquivos não bloqueia):${c ? reset : ''}`);
|
|
4659
|
+
mutationWarns.forEach(w => console.log(` ${c ? dim : ''} · ${w}${c ? reset : ''}`));
|
|
4660
|
+
}
|
|
4661
|
+
if (hints.length) {
|
|
4662
|
+
console.log(` ${yellow}Dicas de spec/plan (detectadas em tempo de compilação):${reset}`);
|
|
4663
|
+
hints.forEach(h => {
|
|
4664
|
+
// Format: HINT(type): message
|
|
4665
|
+
const match = h.match(/^HINT\(([^)]+)\):\s*(.*)/s);
|
|
4666
|
+
if (match) {
|
|
4667
|
+
console.log(` ${yellow}⚑${reset} [${match[1]}] ${match[2]}`);
|
|
4668
|
+
} else {
|
|
4669
|
+
console.log(` ${yellow}⚑${reset} ${h}`);
|
|
4670
|
+
}
|
|
4671
|
+
});
|
|
4672
|
+
}
|
|
4539
4673
|
}
|
|
4540
4674
|
console.log(` ${c ? green : ''}Arquivo:${c ? reset : ''} ${path.join(p.runsDir, `${compiled.run.run_id}.json`)}`);
|
|
4541
4675
|
return;
|
|
@@ -4585,7 +4719,7 @@ async function runRuntime(opts) {
|
|
|
4585
4719
|
console.log(` ${c ? green : ''}✓${c ? reset : ''} Projeções geradas a partir do estado canônico.`);
|
|
4586
4720
|
console.log(` ${c ? green : ''}Run:${c ? reset : ''} ${projected.run.run_id}`);
|
|
4587
4721
|
console.log(` ${c ? green : ''}STATE:${c ? reset : ''} ${projected.paths.state}`);
|
|
4588
|
-
console.log(` ${c ? green : ''}PLAN:${c ? reset : ''} ${projected.paths.plan}`);
|
|
4722
|
+
console.log(` ${c ? green : ''}PLAN-STATUS:${c ? reset : ''} ${projected.paths.plan.replace(/PLAN\.md$/, 'PLAN-STATUS.md')}`);
|
|
4589
4723
|
console.log(` ${c ? green : ''}VERIFY:${c ? reset : ''} ${projected.paths.verify}`);
|
|
4590
4724
|
console.log(` ${c ? green : ''}RUN-SUMMARY:${c ? reset : ''} ${projected.paths.runSummary}`);
|
|
4591
4725
|
console.log(` ${c ? green : ''}PR-SUMMARY:${c ? reset : ''} ${projected.paths.prSummary}`);
|
|
@@ -4598,27 +4732,64 @@ async function runRuntime(opts) {
|
|
|
4598
4732
|
|
|
4599
4733
|
if (opts.action === 'execute') {
|
|
4600
4734
|
try {
|
|
4735
|
+
// Resolve provider: flag > env vars
|
|
4736
|
+
const apiKey = opts.apiKey || process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY || '';
|
|
4737
|
+
const model = opts.model || process.env.OXE_MODEL || 'claude-sonnet-4-6';
|
|
4738
|
+
const baseUrl = opts.baseUrl || process.env.OXE_BASE_URL || 'https://api.anthropic.com/v1';
|
|
4739
|
+
if (!apiKey) {
|
|
4740
|
+
console.error(`${red}Erro: executor LLM não configurado.${reset}`);
|
|
4741
|
+
console.error(` Use: --api-key <chave> ou exporte ANTHROPIC_API_KEY`);
|
|
4742
|
+
console.error(` Exemplo: oxe-cc runtime execute --api-key $ANTHROPIC_API_KEY --model claude-sonnet-4-6`);
|
|
4743
|
+
process.exit(1);
|
|
4744
|
+
}
|
|
4745
|
+
const providerConfig = { baseUrl, apiKey, model, maxTurns: opts.maxTurns || 10 };
|
|
4601
4746
|
const result = await oxeOperational.runRuntimeExecute(opts.dir, activeSession, {
|
|
4602
4747
|
runId: opts.runId || undefined,
|
|
4603
4748
|
heartbeatTimeoutMs: opts.heartbeatTimeoutMs || undefined,
|
|
4749
|
+
providerConfig,
|
|
4750
|
+
onProgress: (event) => {
|
|
4751
|
+
if (event.type === 'turn_start') {
|
|
4752
|
+
const turn = event.detail?.turn ?? 0;
|
|
4753
|
+
if (turn === 0) process.stdout.write(` → ${event.nodeId} `);
|
|
4754
|
+
} else if (event.type === 'tool_call') {
|
|
4755
|
+
process.stdout.write('.');
|
|
4756
|
+
} else if (event.type === 'VerificationStarted') {
|
|
4757
|
+
process.stdout.write(' [verify]');
|
|
4758
|
+
} else if (event.type === 'WorkItemCompleted') {
|
|
4759
|
+
process.stdout.write(` ✓\n`);
|
|
4760
|
+
} else if (event.type === 'WorkItemBlocked') {
|
|
4761
|
+
process.stdout.write(` ✗\n`);
|
|
4762
|
+
} else if (event.type === 'RetryScheduled') {
|
|
4763
|
+
process.stdout.write(` ↺ retry ${event.payload?.next_attempt}\n → ${event.work_item_id} `);
|
|
4764
|
+
}
|
|
4765
|
+
},
|
|
4604
4766
|
});
|
|
4605
|
-
if (opts.jsonOutput) {
|
|
4606
|
-
console.log(JSON.stringify(result, null, 2));
|
|
4607
|
-
if (result.result && result.result.failed && result.result.failed.length > 0) process.exitCode = 1;
|
|
4608
|
-
return;
|
|
4609
|
-
}
|
|
4610
|
-
const r = result.result || {};
|
|
4611
|
-
const completed = Array.isArray(r.completed) ? r.completed : [];
|
|
4612
|
-
const failed = Array.isArray(r.failed) ? r.failed : [];
|
|
4613
|
-
const blocked = Array.isArray(r.blocked) ? r.blocked : [];
|
|
4614
|
-
|
|
4615
|
-
console.log(` ${c ?
|
|
4767
|
+
if (opts.jsonOutput) {
|
|
4768
|
+
console.log(JSON.stringify(result, null, 2));
|
|
4769
|
+
if (result.result && ((result.result.failed && result.result.failed.length > 0) || result.result.status === 'blocked')) process.exitCode = 1;
|
|
4770
|
+
return;
|
|
4771
|
+
}
|
|
4772
|
+
const r = result.result || {};
|
|
4773
|
+
const completed = Array.isArray(r.completed) ? r.completed : [];
|
|
4774
|
+
const failed = Array.isArray(r.failed) ? r.failed : [];
|
|
4775
|
+
const blocked = Array.isArray(r.blocked) ? r.blocked : [];
|
|
4776
|
+
const okColor = r.status === 'blocked' ? yellow : green;
|
|
4777
|
+
console.log(` ${c ? okColor : ''}${r.status === 'blocked' ? '!' : '✓'}${c ? reset : ''} Runtime execute concluído (modo: ${result.mode})`);
|
|
4778
|
+
if (result.preflight) {
|
|
4779
|
+
console.log(` ${c ? green : ''}Preflight:${c ? reset : ''} ${result.preflight.ok ? 'ready' : 'blocked'}`);
|
|
4780
|
+
if (Array.isArray(result.preflight.blockers) && result.preflight.blockers.length) {
|
|
4781
|
+
for (const blocker of result.preflight.blockers) {
|
|
4782
|
+
console.log(` ${yellow}BLOCKER${reset} ${blocker}`);
|
|
4783
|
+
}
|
|
4784
|
+
}
|
|
4785
|
+
}
|
|
4786
|
+
console.log(` ${c ? green : ''}Completados:${c ? reset : ''} ${completed.length}`);
|
|
4616
4787
|
if (failed.length > 0)
|
|
4617
4788
|
console.log(` ${c ? red : ''}Falhos:${c ? reset : ''} ${failed.length} — ${failed.join(', ')}`);
|
|
4618
4789
|
if (blocked.length > 0)
|
|
4619
4790
|
console.log(` ${c ? '\x1b[33m' : ''}Bloqueados:${c ? reset : ''} ${blocked.length} — ${blocked.join(', ')}`);
|
|
4620
|
-
if (failed.length > 0) process.exitCode = 1;
|
|
4621
|
-
return;
|
|
4791
|
+
if (failed.length > 0 || r.status === 'blocked') process.exitCode = 1;
|
|
4792
|
+
return;
|
|
4622
4793
|
} catch (err) {
|
|
4623
4794
|
console.error(`${red}${err && err.message ? err.message : 'Falha ao executar runtime.'}${reset}`);
|
|
4624
4795
|
process.exit(1);
|
|
@@ -4794,7 +4965,7 @@ function runAzure(opts) {
|
|
|
4794
4965
|
};
|
|
4795
4966
|
|
|
4796
4967
|
console.log(` ${c ? green : ''}Projeto:${c ? reset : ''} ${c ? cyan : ''}${opts.dir}${c ? reset : ''}`);
|
|
4797
|
-
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || '
|
|
4968
|
+
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || '— (sem sessão ativa)'}${c ? reset : ''}`);
|
|
4798
4969
|
|
|
4799
4970
|
try {
|
|
4800
4971
|
if (opts.scope === 'status') {
|
|
@@ -5118,7 +5289,7 @@ function runPlanVisual(opts) {
|
|
|
5118
5289
|
const planPath = sp.plan || oxeHealth.oxePaths(opts.dir).plan;
|
|
5119
5290
|
|
|
5120
5291
|
console.log(` ${c ? green : ''}Projeto:${c ? reset : ''} ${c ? cyan : ''}${opts.dir}${c ? reset : ''}`);
|
|
5121
|
-
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || '
|
|
5292
|
+
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || '— (sem sessão ativa)'}${c ? reset : ''}`);
|
|
5122
5293
|
|
|
5123
5294
|
if (!fs.existsSync(planPath)) {
|
|
5124
5295
|
console.log(`\n ${yellow}PLAN.md não encontrado em ${planPath}${reset}`);
|
|
@@ -5172,7 +5343,7 @@ function runVerifyMatrix(opts) {
|
|
|
5172
5343
|
const verifyPath = sp.verify || oxeHealth.oxePaths(opts.dir).verify;
|
|
5173
5344
|
|
|
5174
5345
|
console.log(` ${c ? green : ''}Projeto:${c ? reset : ''} ${c ? cyan : ''}${opts.dir}${c ? reset : ''}`);
|
|
5175
|
-
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || '
|
|
5346
|
+
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || '— (sem sessão ativa)'}${c ? reset : ''}`);
|
|
5176
5347
|
|
|
5177
5348
|
const specMd = fs.existsSync(specPath) ? fs.readFileSync(specPath, 'utf8') : '';
|
|
5178
5349
|
const planMd = fs.existsSync(planPath) ? fs.readFileSync(planPath, 'utf8') : '';
|
|
@@ -5556,7 +5727,8 @@ async function main() {
|
|
|
5556
5727
|
nextSteps: [
|
|
5557
5728
|
{ desc: 'Validar o projeto:', cmd: 'npx oxe-cc doctor' },
|
|
5558
5729
|
{ desc: 'Instalar integrações IDE/CLI (se ainda não fez):', cmd: 'npx oxe-cc@latest' },
|
|
5559
|
-
{ desc: '
|
|
5730
|
+
{ desc: 'Fluxo runtime — criar spec (no agente):', cmd: '/oxe-spec → /oxe-plan → oxe-cc runtime compile → oxe-cc runtime execute' },
|
|
5731
|
+
{ desc: 'Começar pelo scan do codebase (agente):', cmd: '/oxe-scan' },
|
|
5560
5732
|
],
|
|
5561
5733
|
dryRun: opts.dryRun,
|
|
5562
5734
|
});
|
|
@@ -8,6 +8,7 @@ Este é o contrato mínimo para publicar uma versão estável do OXE sem drift e
|
|
|
8
8
|
npm test
|
|
9
9
|
npm run scan:assets
|
|
10
10
|
npm run build:vscode-ext
|
|
11
|
+
npm run release:pack-check
|
|
11
12
|
npx oxe-cc doctor --release --write-manifest
|
|
12
13
|
```
|
|
13
14
|
|
|
@@ -21,6 +22,7 @@ O `doctor --release` deve bloquear a publicação quando encontrar:
|
|
|
21
22
|
- wrappers dirty após `sync-runtime-metadata` e `sync:cursor`
|
|
22
23
|
- drift semântico entre workflows canónicos e superfícies geradas
|
|
23
24
|
- ausência ou falha dos relatórios obrigatórios da release
|
|
25
|
+
- tarball npm contendo `.tgz`, `.vsix`, `.oxe/` ou sem arquivos obrigatórios do pacote
|
|
24
26
|
|
|
25
27
|
## Relatórios obrigatórios
|
|
26
28
|
|
|
@@ -28,8 +30,10 @@ Todos os artefatos abaixo devem existir em `.oxe/release/`:
|
|
|
28
30
|
|
|
29
31
|
- `release-manifest.json`
|
|
30
32
|
- `runtime-smoke-report.json`
|
|
33
|
+
- `runtime-real-report.json`
|
|
31
34
|
- `recovery-fixture-report.json`
|
|
32
35
|
- `multi-agent-soak-report.json`
|
|
36
|
+
- `multi-agent-real-report.json` para versões `>=1.9.1`
|
|
33
37
|
|
|
34
38
|
## Defaults estáveis desta publicação
|
|
35
39
|
|
|
@@ -44,7 +48,8 @@ O pipeline de CI e o pipeline de release devem rodar o mesmo gate:
|
|
|
44
48
|
|
|
45
49
|
1. `npm test`
|
|
46
50
|
2. `npm run scan:assets`
|
|
47
|
-
3. `npm run release:
|
|
51
|
+
3. `npm run release:pack-check`
|
|
52
|
+
4. `npm run release:doctor`
|
|
48
53
|
|
|
49
54
|
Se qualquer etapa falhar, a release não está pronta.
|
|
50
55
|
|
|
@@ -26,7 +26,7 @@ function compile(plan, spec, options = {}) {
|
|
|
26
26
|
mutation_scope: task.files,
|
|
27
27
|
actions: buildActions(task),
|
|
28
28
|
verify: {
|
|
29
|
-
must_pass: task.verifyCommand ? ['tests'] : [],
|
|
29
|
+
must_pass: task.verifyCommand ? (task.aceite.length > 0 ? task.aceite : ['tests']) : [],
|
|
30
30
|
acceptance_refs: task.aceite,
|
|
31
31
|
command: task.verifyCommand,
|
|
32
32
|
},
|
|
@@ -37,5 +37,9 @@ function selectToolsForActions(actions) {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
+
// finish_task is always available so the LLM can signal authoritative completion
|
|
41
|
+
if (!seen.has('finish_task') && built_in_tools_1.BUILT_IN_TOOLS.finish_task) {
|
|
42
|
+
result.push(built_in_tools_1.BUILT_IN_TOOLS.finish_task.schema);
|
|
43
|
+
}
|
|
40
44
|
return result;
|
|
41
45
|
}
|
|
@@ -255,6 +255,32 @@ function runShell(command, cwd, timeoutMs) {
|
|
|
255
255
|
proc.on('error', (err) => { clearTimeout(timer); resolve(`[error] ${err}`); });
|
|
256
256
|
});
|
|
257
257
|
}
|
|
258
|
+
// ─── finish_task ──────────────────────────────────────────────────────────────
|
|
259
|
+
const finishTask = {
|
|
260
|
+
idempotent: true,
|
|
261
|
+
schema: {
|
|
262
|
+
type: 'function',
|
|
263
|
+
function: {
|
|
264
|
+
name: 'finish_task',
|
|
265
|
+
description: 'Signal that the task is complete. Call this when ALL required actions have been performed.',
|
|
266
|
+
parameters: {
|
|
267
|
+
type: 'object',
|
|
268
|
+
properties: {
|
|
269
|
+
summary: { type: 'string', description: 'Summary of what was accomplished' },
|
|
270
|
+
evidence_paths: { type: 'array', items: { type: 'string' }, description: 'Paths to files created or modified' },
|
|
271
|
+
},
|
|
272
|
+
required: ['summary'],
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
async execute(args, _cwd) {
|
|
277
|
+
return JSON.stringify({
|
|
278
|
+
__finish_task__: true,
|
|
279
|
+
summary: String(args.summary || ''),
|
|
280
|
+
evidence_paths: Array.isArray(args.evidence_paths) ? args.evidence_paths : [],
|
|
281
|
+
});
|
|
282
|
+
},
|
|
283
|
+
};
|
|
258
284
|
// ─── Registry ─────────────────────────────────────────────────────────────────
|
|
259
285
|
exports.BUILT_IN_TOOLS = {
|
|
260
286
|
read_file: readFile,
|
|
@@ -263,5 +289,6 @@ exports.BUILT_IN_TOOLS = {
|
|
|
263
289
|
glob,
|
|
264
290
|
grep,
|
|
265
291
|
run_command: runCommand,
|
|
292
|
+
finish_task: finishTask,
|
|
266
293
|
};
|
|
267
294
|
exports.ALL_BUILT_IN_SCHEMAS = Object.values(exports.BUILT_IN_TOOLS).map((t) => t.schema);
|
|
@@ -18,12 +18,15 @@ export interface LlmExecutorEvent {
|
|
|
18
18
|
attempt: number;
|
|
19
19
|
detail?: Record<string, unknown>;
|
|
20
20
|
}
|
|
21
|
+
export interface LlmExecuteOptions {
|
|
22
|
+
previousError?: string | null;
|
|
23
|
+
}
|
|
21
24
|
export declare class LlmTaskExecutor implements TaskExecutor {
|
|
22
25
|
private readonly provider;
|
|
23
26
|
private readonly registry?;
|
|
24
27
|
private readonly onProgress?;
|
|
25
28
|
constructor(provider: LlmProviderConfig, registry?: PluginRegistry | undefined, onProgress?: ((event: LlmExecutorEvent) => void) | undefined);
|
|
26
|
-
execute(node: GraphNode, lease: WorkspaceLease, runId: string, attempt: number): Promise<TaskResult>;
|
|
29
|
+
execute(node: GraphNode, lease: WorkspaceLease, runId: string, attempt: number, options?: LlmExecuteOptions): Promise<TaskResult>;
|
|
27
30
|
private invokeToolCall;
|
|
28
31
|
private emit;
|
|
29
32
|
}
|