oxe-cc 1.4.0 → 1.5.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/.cursor/commands/oxe-ask.md +4 -2
- package/.cursor/commands/oxe-capabilities.md +4 -2
- package/.cursor/commands/oxe-checkpoint.md +4 -2
- package/.cursor/commands/oxe-compact.md +4 -2
- package/.cursor/commands/oxe-dashboard.md +4 -2
- package/.cursor/commands/oxe-debug.md +4 -2
- package/.cursor/commands/oxe-discuss.md +4 -2
- package/.cursor/commands/oxe-execute.md +5 -3
- package/.cursor/commands/oxe-forensics.md +4 -2
- package/.cursor/commands/oxe-help.md +4 -2
- package/.cursor/commands/oxe-loop.md +4 -2
- package/.cursor/commands/oxe-milestone.md +4 -2
- package/.cursor/commands/oxe-next.md +4 -2
- package/.cursor/commands/oxe-obs.md +4 -2
- package/.cursor/commands/oxe-plan-agent.md +4 -2
- package/.cursor/commands/oxe-plan.md +4 -2
- package/.cursor/commands/oxe-project.md +4 -2
- package/.cursor/commands/oxe-quick.md +4 -2
- package/.cursor/commands/oxe-research.md +4 -2
- package/.cursor/commands/oxe-retro.md +4 -2
- package/.cursor/commands/oxe-review-pr.md +4 -2
- package/.cursor/commands/oxe-route.md +4 -2
- package/.cursor/commands/oxe-scan.md +4 -2
- package/.cursor/commands/oxe-security.md +4 -2
- package/.cursor/commands/oxe-session.md +5 -3
- package/.cursor/commands/oxe-ship.md +4 -2
- package/.cursor/commands/oxe-skill.md +4 -2
- package/.cursor/commands/oxe-spec.md +4 -2
- package/.cursor/commands/oxe-ui-review.md +4 -2
- package/.cursor/commands/oxe-ui-spec.md +4 -2
- package/.cursor/commands/oxe-update.md +4 -2
- package/.cursor/commands/oxe-validate-gaps.md +4 -2
- package/.cursor/commands/oxe-verify-audit.md +46 -0
- package/.cursor/commands/oxe-verify.md +4 -2
- package/.cursor/commands/oxe-workflow-authoring.md +47 -0
- package/.cursor/commands/oxe-workstream.md +4 -2
- package/.cursor/commands/oxe.md +6 -2
- package/.github/prompts/oxe-ask.prompt.md +4 -2
- package/.github/prompts/oxe-capabilities.prompt.md +4 -2
- package/.github/prompts/oxe-checkpoint.prompt.md +4 -2
- package/.github/prompts/oxe-compact.prompt.md +5 -3
- package/.github/prompts/oxe-dashboard.prompt.md +4 -2
- package/.github/prompts/oxe-debug.prompt.md +4 -2
- package/.github/prompts/oxe-discuss.prompt.md +6 -2
- package/.github/prompts/oxe-execute.prompt.md +5 -3
- package/.github/prompts/oxe-forensics.prompt.md +4 -2
- package/.github/prompts/oxe-help.prompt.md +6 -2
- package/.github/prompts/oxe-loop.prompt.md +4 -2
- package/.github/prompts/oxe-milestone.prompt.md +4 -2
- package/.github/prompts/oxe-next.prompt.md +6 -2
- package/.github/prompts/oxe-obs.prompt.md +4 -2
- package/.github/prompts/oxe-plan-agent.prompt.md +5 -2
- package/.github/prompts/oxe-plan.prompt.md +4 -2
- package/.github/prompts/oxe-project.prompt.md +4 -2
- package/.github/prompts/oxe-quick.prompt.md +4 -2
- package/.github/prompts/oxe-research.prompt.md +4 -2
- package/.github/prompts/oxe-retro.prompt.md +4 -2
- package/.github/prompts/oxe-review-pr.prompt.md +4 -2
- package/.github/prompts/oxe-route.prompt.md +4 -2
- package/.github/prompts/oxe-scan.prompt.md +4 -2
- package/.github/prompts/oxe-security.prompt.md +4 -2
- package/.github/prompts/oxe-session.prompt.md +5 -3
- package/.github/prompts/oxe-ship.prompt.md +4 -2
- package/.github/prompts/oxe-skill.prompt.md +4 -2
- package/.github/prompts/oxe-spec.prompt.md +4 -2
- package/.github/prompts/oxe-ui-review.prompt.md +4 -2
- package/.github/prompts/oxe-ui-spec.prompt.md +4 -2
- package/.github/prompts/oxe-update.prompt.md +4 -2
- package/.github/prompts/oxe-validate-gaps.prompt.md +4 -2
- package/.github/prompts/oxe-verify-audit.prompt.md +46 -0
- package/.github/prompts/oxe-verify.prompt.md +4 -2
- package/.github/prompts/oxe-workflow-authoring.prompt.md +47 -0
- package/.github/prompts/oxe-workstream.prompt.md +4 -2
- package/.github/prompts/oxe.prompt.md +6 -2
- package/.github/workflows/ci.yml +57 -20
- package/.github/workflows/release.yml +94 -0
- package/AGENTS.md +3 -1
- package/CHANGELOG.md +383 -342
- package/QUICKSTART.md +99 -0
- package/README.md +89 -65
- package/bin/lib/oxe-agent-install.cjs +127 -107
- package/bin/lib/oxe-install-resolve.cjs +10 -0
- package/bin/lib/oxe-operational.cjs +34 -28
- package/bin/lib/oxe-project-health.cjs +38 -6
- package/bin/lib/oxe-release.cjs +423 -0
- package/bin/lib/oxe-runtime-semantics.cjs +68 -24
- package/bin/oxe-cc.js +388 -55
- package/commands/oxe/ask.md +7 -3
- package/commands/oxe/capabilities.md +6 -2
- package/commands/oxe/checkpoint.md +5 -1
- package/commands/oxe/compact.md +6 -2
- package/commands/oxe/dashboard.md +6 -2
- package/commands/oxe/debug.md +6 -2
- package/commands/oxe/discuss.md +6 -2
- package/commands/oxe/execute.md +6 -2
- package/commands/oxe/forensics.md +6 -2
- package/commands/oxe/help.md +6 -2
- package/commands/oxe/loop.md +6 -2
- package/commands/oxe/milestone.md +6 -2
- package/commands/oxe/next.md +6 -2
- package/commands/oxe/obs.md +6 -2
- package/commands/oxe/oxe.md +6 -2
- package/commands/oxe/plan-agent.md +6 -2
- package/commands/oxe/plan.md +6 -2
- package/commands/oxe/project.md +6 -2
- package/commands/oxe/quick.md +6 -2
- package/commands/oxe/research.md +6 -2
- package/commands/oxe/retro.md +6 -2
- package/commands/oxe/review-pr.md +6 -2
- package/commands/oxe/route.md +6 -2
- package/commands/oxe/scan.md +6 -2
- package/commands/oxe/security.md +6 -2
- package/commands/oxe/session.md +6 -2
- package/commands/oxe/ship.md +6 -2
- package/commands/oxe/skill.md +6 -2
- package/commands/oxe/spec.md +6 -2
- package/commands/oxe/ui-review.md +6 -2
- package/commands/oxe/ui-spec.md +6 -2
- package/commands/oxe/update.md +6 -2
- package/commands/oxe/validate-gaps.md +6 -2
- package/commands/oxe/verify-audit.md +50 -0
- package/commands/oxe/verify.md +6 -2
- package/commands/oxe/workflow-authoring.md +50 -0
- package/commands/oxe/workstream.md +6 -2
- package/docs/INCIDENT-PLAYBOOK.md +181 -0
- package/docs/RELEASE-READINESS.md +46 -0
- package/docs/ROLES.md +129 -0
- package/docs/RUNTIME-SMOKE-MATRIX.md +128 -0
- package/docs/TEAM-ADOPTION.md +153 -0
- package/docs/WALKTHROUGH.md +241 -0
- package/lib/runtime/scheduler/multi-agent-coordinator.d.ts +28 -0
- package/lib/runtime/scheduler/multi-agent-coordinator.js +152 -26
- package/lib/sdk/README.md +2 -0
- package/lib/sdk/index.cjs +22 -8
- package/lib/sdk/index.d.ts +60 -16
- package/oxe/templates/config.template.json +1 -0
- package/package.json +30 -22
- package/packages/runtime/package.json +1 -1
- package/packages/runtime/src/scheduler/multi-agent-coordinator.ts +357 -193
- 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/package.json +1 -1
package/bin/oxe-cc.js
CHANGED
|
@@ -24,6 +24,7 @@ const oxeAzure = require(path.join(__dirname, 'lib', 'oxe-azure.cjs'));
|
|
|
24
24
|
const oxePlugins = require(path.join(__dirname, 'lib', 'oxe-plugins.cjs'));
|
|
25
25
|
const oxeContext = require(path.join(__dirname, 'lib', 'oxe-context-engine.cjs'));
|
|
26
26
|
const oxeRuntimeSemantics = require(path.join(__dirname, 'lib', 'oxe-runtime-semantics.cjs'));
|
|
27
|
+
const oxeRelease = require(path.join(__dirname, 'lib', 'oxe-release.cjs'));
|
|
27
28
|
|
|
28
29
|
/** Merge markers for ~/.copilot/copilot-instructions.md (bloco OXE). */
|
|
29
30
|
const OXE_INST_BEGIN = '<!-- oxe-cc:install-begin -->';
|
|
@@ -251,6 +252,13 @@ function buildUninstallFooter(u) {
|
|
|
251
252
|
const bullets = [];
|
|
252
253
|
const p = u.dryRun ? '[simulação] ' : '';
|
|
253
254
|
const rm = u.dryRun ? 'Seriam removidos' : 'Removidos';
|
|
255
|
+
const granularAgents = [
|
|
256
|
+
u.agentOpenCode ? 'OpenCode' : null,
|
|
257
|
+
u.agentGemini ? 'Gemini' : null,
|
|
258
|
+
u.agentCodex ? 'Codex' : null,
|
|
259
|
+
u.agentWindsurf ? 'Windsurf' : null,
|
|
260
|
+
u.agentAntigravity ? 'Antigravity' : null,
|
|
261
|
+
].filter(Boolean);
|
|
254
262
|
if (u.cursor) bullets.push(`${p}${rm} artefatos OXE em ~/.cursor (comandos e regras).`);
|
|
255
263
|
if (u.copilot) {
|
|
256
264
|
bullets.push(`${p}${rm} prompt files OXE em .github/prompts/ e o bloco OXE em .github/copilot-instructions.md.`);
|
|
@@ -258,12 +266,16 @@ function buildUninstallFooter(u) {
|
|
|
258
266
|
if (u.copilotLegacyClean) {
|
|
259
267
|
bullets.push(`${p}${rm} apenas o legado global do Copilot VS Code em ~/.copilot/ (prompts oxe-* e bloco OXE global).`);
|
|
260
268
|
}
|
|
261
|
-
if (u.copilotCli
|
|
262
|
-
bullets.push(`${p}${rm} comandos oxe-* em ~/.claude/commands e ~/.copilot/commands.`);
|
|
269
|
+
if (u.copilotCli) {
|
|
270
|
+
bullets.push(`${p}${rm} comandos oxe/oxe-* em ~/.claude/commands e ~/.copilot/commands.`);
|
|
263
271
|
bullets.push(`${p}${rm} skills OXE (marcadas oxe-cc) em ~/.copilot/skills/oxe*/.`);
|
|
272
|
+
}
|
|
273
|
+
if (u.allAgents) {
|
|
264
274
|
bullets.push(
|
|
265
275
|
`${p}${rm} extensões multi-agente marcadas oxe-cc (OpenCode, Gemini TOML, Windsurf workflows, Codex prompts/skills, Antigravity), se existirem.`
|
|
266
276
|
);
|
|
277
|
+
} else if (granularAgents.length) {
|
|
278
|
+
bullets.push(`${p}${rm} apenas as integrações selecionadas: ${granularAgents.join(', ')}.`);
|
|
267
279
|
}
|
|
268
280
|
if (u.ideLocal) {
|
|
269
281
|
bullets.push(
|
|
@@ -285,13 +297,30 @@ function buildUninstallFooter(u) {
|
|
|
285
297
|
return { bullets, nextSteps, dryRun: u.dryRun };
|
|
286
298
|
}
|
|
287
299
|
|
|
288
|
-
/** @typedef {{ help: boolean, version: boolean, cursor: boolean, copilot: boolean, copilotCli: boolean, allAgents: boolean, agentOpenCode: boolean, agentGemini: boolean, agentCodex: boolean, agentWindsurf: boolean, agentAntigravity: boolean, vscode: boolean, commands: boolean, agents: boolean, force: boolean, dryRun: boolean, dir: string, all: boolean, noInitOxe: boolean, oxeOnly: boolean, globalCli: boolean, noGlobalCli: boolean, installAssetsGlobal: boolean, explicitScope: boolean, integrationsUnset: boolean, ideLocal: boolean, explicitIdeScope: boolean, explicitConfigDir: string | null, parseError: boolean, unknownFlag: string, conflictFlags: string, ignoreInstallConfig: boolean }} InstallOpts */
|
|
300
|
+
/** @typedef {{ help: boolean, version: boolean, cursor: boolean, copilot: boolean, copilotCli: boolean, allAgents: boolean, agentOpenCode: boolean, agentGemini: boolean, agentCodex: boolean, agentWindsurf: boolean, agentAntigravity: boolean, vscode: boolean, commands: boolean, agents: boolean, force: boolean, dryRun: boolean, dir: string, all: boolean, noInitOxe: boolean, oxeOnly: boolean, globalCli: boolean, noGlobalCli: boolean, installAssetsGlobal: boolean, explicitScope: boolean, integrationsUnset: boolean, ideLocal: boolean, explicitIdeScope: boolean, explicitConfigDir: string | null, parseError: boolean, unknownFlag: string, conflictFlags: string, ignoreInstallConfig: boolean, releaseDoctor: boolean, writeManifest: boolean }} InstallOpts */
|
|
289
301
|
|
|
290
302
|
/** @param {InstallOpts} o */
|
|
291
303
|
function anyGranularAgent(o) {
|
|
292
304
|
return !!(o.agentOpenCode || o.agentGemini || o.agentCodex || o.agentWindsurf || o.agentAntigravity);
|
|
293
305
|
}
|
|
294
306
|
|
|
307
|
+
/** @param {UninstallOpts} o */
|
|
308
|
+
function anyGranularUninstallAgent(o) {
|
|
309
|
+
return !!(o.agentOpenCode || o.agentGemini || o.agentCodex || o.agentWindsurf || o.agentAntigravity);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/** @param {UninstallOpts} u */
|
|
313
|
+
function buildAgentCleanupTargets(u) {
|
|
314
|
+
if (u.allAgents || !anyGranularUninstallAgent(u)) return null;
|
|
315
|
+
return {
|
|
316
|
+
opencode: Boolean(u.agentOpenCode),
|
|
317
|
+
gemini: Boolean(u.agentGemini),
|
|
318
|
+
windsurf: Boolean(u.agentWindsurf),
|
|
319
|
+
codex: Boolean(u.agentCodex),
|
|
320
|
+
antigravity: Boolean(u.agentAntigravity),
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
|
|
295
324
|
/** @param {InstallOpts} o */
|
|
296
325
|
function anyIdeIntegration(o) {
|
|
297
326
|
return !!(o.cursor || o.copilot || o.copilotCli || o.allAgents || anyGranularAgent(o));
|
|
@@ -336,6 +365,8 @@ function parseInstallArgs(argv) {
|
|
|
336
365
|
unknownFlag: '',
|
|
337
366
|
conflictFlags: '',
|
|
338
367
|
ignoreInstallConfig: false,
|
|
368
|
+
releaseDoctor: false,
|
|
369
|
+
writeManifest: false,
|
|
339
370
|
/** Saída JSON em `status` (CI / agentes). */
|
|
340
371
|
jsonOutput: false,
|
|
341
372
|
/** Lembretes agregados scan/compact em `status`. */
|
|
@@ -387,6 +418,8 @@ function parseInstallArgs(argv) {
|
|
|
387
418
|
} else if (a === '--json') out.jsonOutput = true;
|
|
388
419
|
else if (a === '--hints') out.statusHints = true;
|
|
389
420
|
else if (a === '--full') out.statusFull = true;
|
|
421
|
+
else if (a === '--release') out.releaseDoctor = true;
|
|
422
|
+
else if (a === '--write-manifest') out.writeManifest = true;
|
|
390
423
|
else if (!a.startsWith('-')) out.restPositional.push(a);
|
|
391
424
|
else {
|
|
392
425
|
out.parseError = true;
|
|
@@ -429,6 +462,14 @@ function parseInstallArgs(argv) {
|
|
|
429
462
|
out.agentWindsurf = true;
|
|
430
463
|
out.agentAntigravity = true;
|
|
431
464
|
}
|
|
465
|
+
if (!out.conflictFlags && out.oxeOnly) {
|
|
466
|
+
const IDE_FLAGS = ['--cursor', '--copilot', '--copilot-vscode', '--copilot-cli', '--all-agents',
|
|
467
|
+
'--opencode', '--gemini', '--codex', '--windsurf', '--antigravity', '--vscode'];
|
|
468
|
+
const conflicting = IDE_FLAGS.filter((f) => argv.includes(f));
|
|
469
|
+
if (conflicting.length > 0) {
|
|
470
|
+
out.conflictFlags = `--oxe-only não combina com flags de IDE (${conflicting.join(', ')})`;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
432
473
|
if (out.oxeOnly) {
|
|
433
474
|
out.cursor = false;
|
|
434
475
|
out.copilot = false;
|
|
@@ -749,7 +790,11 @@ function writeCopilotVsCodeManifest(opts, info) {
|
|
|
749
790
|
const promptFiles = fs.existsSync(promptsDir)
|
|
750
791
|
? fs
|
|
751
792
|
.readdirSync(promptsDir, { withFileTypes: true })
|
|
752
|
-
.filter(
|
|
793
|
+
.filter(
|
|
794
|
+
(entry) =>
|
|
795
|
+
entry.isFile() &&
|
|
796
|
+
(entry.name === 'oxe.prompt.md' || /^oxe-.*\.prompt\.md$/i.test(entry.name))
|
|
797
|
+
)
|
|
753
798
|
.map((entry) => entry.name)
|
|
754
799
|
.sort()
|
|
755
800
|
: [];
|
|
@@ -1010,6 +1055,27 @@ async function promptInstallScope(opts) {
|
|
|
1010
1055
|
}
|
|
1011
1056
|
}
|
|
1012
1057
|
|
|
1058
|
+
/**
|
|
1059
|
+
* Grava a escolha resolvida de ide_scope de volta em .oxe/config.json para que
|
|
1060
|
+
* futuras reinstalações/updates não precisem perguntar novamente.
|
|
1061
|
+
* @param {InstallOpts} opts
|
|
1062
|
+
*/
|
|
1063
|
+
function persistIdeScope(opts) {
|
|
1064
|
+
if (opts.dryRun || opts.oxeOnly) return;
|
|
1065
|
+
const configPath = path.join(opts.dir, '.oxe', 'config.json');
|
|
1066
|
+
if (!fs.existsSync(configPath)) return;
|
|
1067
|
+
try {
|
|
1068
|
+
const cfg = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
1069
|
+
const scope = opts.ideLocal ? 'local' : 'global';
|
|
1070
|
+
if (!cfg.install || typeof cfg.install !== 'object') cfg.install = {};
|
|
1071
|
+
if (cfg.install.ide_scope === scope) return;
|
|
1072
|
+
cfg.install.ide_scope = scope;
|
|
1073
|
+
fs.writeFileSync(configPath, JSON.stringify(cfg, null, 2) + '\n', 'utf8');
|
|
1074
|
+
} catch {
|
|
1075
|
+
/* silêncio — não bloquear instalação por falha ao persistir config */
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1013
1079
|
/** @param {InstallOpts} opts */
|
|
1014
1080
|
async function resolveInteractiveInstall(opts) {
|
|
1015
1081
|
if (!opts.ignoreInstallConfig) {
|
|
@@ -1252,7 +1318,13 @@ function bootstrapOxe(target, opts) {
|
|
|
1252
1318
|
|
|
1253
1319
|
if (fs.existsSync(configSrc)) {
|
|
1254
1320
|
if (!fs.existsSync(configDest) || opts.force) {
|
|
1255
|
-
|
|
1321
|
+
try {
|
|
1322
|
+
const cfgRaw = JSON.parse(fs.readFileSync(configSrc, 'utf8'));
|
|
1323
|
+
delete cfgRaw._comment;
|
|
1324
|
+
fs.writeFileSync(configDest, JSON.stringify(cfgRaw, null, 2) + '\n', 'utf8');
|
|
1325
|
+
} catch {
|
|
1326
|
+
copyFile(configSrc, configDest, { dryRun: false });
|
|
1327
|
+
}
|
|
1256
1328
|
console.log(`${green}init${reset} ${configDest}`);
|
|
1257
1329
|
} else {
|
|
1258
1330
|
console.log(`${dim}omitido${reset} ${configDest} (já existe — use --force para substituir)`);
|
|
@@ -1834,6 +1906,39 @@ function runStatus(target, opts = {}) {
|
|
|
1834
1906
|
|
|
1835
1907
|
printOxeHealthDiagnostics(target, c, { skipScanCompactAgeWarnings: Boolean(opts.hints) });
|
|
1836
1908
|
|
|
1909
|
+
// IDE readiness summary
|
|
1910
|
+
const ideStatusLines = [];
|
|
1911
|
+
const _copilotPromptsDir = path.join(target, '.github', 'prompts');
|
|
1912
|
+
const _copilotInstructions = path.join(target, '.github', 'copilot-instructions.md');
|
|
1913
|
+
ideStatusLines.push(`Copilot ${fs.existsSync(_copilotPromptsDir) || fs.existsSync(_copilotInstructions) ? (c ? green + '✓' + reset : '✓') : (c ? dim + '✗' + reset : '✗')}`);
|
|
1914
|
+
ideStatusLines.push(`Cursor ${fs.existsSync(path.join(target, '.cursor', 'commands')) ? (c ? green + '✓' + reset : '✓') : (c ? dim + '✗' + reset : '✗')}`);
|
|
1915
|
+
const _claudeLocal = path.join(target, 'commands', 'oxe');
|
|
1916
|
+
const _claudeGlobal = path.join(require('os').homedir(), '.claude', 'commands');
|
|
1917
|
+
ideStatusLines.push(`Claude Code ${fs.existsSync(_claudeLocal) || fs.existsSync(_claudeGlobal) ? (c ? green + '✓' + reset : '✓') : (c ? dim + '✗' + reset : '✗')}`);
|
|
1918
|
+
console.log(`\n ${c ? dim : ''}IDEs:${c ? reset : ''} ${ideStatusLines.join(' ')}`);
|
|
1919
|
+
|
|
1920
|
+
// Gates pending in default view
|
|
1921
|
+
const pendingGateCount = report.pendingGates ? (report.pendingGates.pendingCount || 0) : 0;
|
|
1922
|
+
const staleGateCount = report.pendingGates ? (report.pendingGates.staleGateCount || 0) : 0;
|
|
1923
|
+
if (pendingGateCount > 0 || staleGateCount > 0) {
|
|
1924
|
+
const gateMsg = [];
|
|
1925
|
+
if (pendingGateCount > 0) gateMsg.push(`${pendingGateCount} pendente(s)`);
|
|
1926
|
+
if (staleGateCount > 0) gateMsg.push(`${staleGateCount} stale`);
|
|
1927
|
+
console.log(` ${c ? yellow : ''}⚠ Gates:${c ? reset : ''} ${gateMsg.join(', ')} — ${c ? cyan : ''}npx oxe-cc runtime gates list --dir .${c ? reset : ''}`);
|
|
1928
|
+
}
|
|
1929
|
+
|
|
1930
|
+
// Explicit blockage diagnosis
|
|
1931
|
+
const specMissing = !fs.existsSync(path.join(target, '.oxe', 'SPEC.md'));
|
|
1932
|
+
const planMissing = !fs.existsSync(path.join(target, '.oxe', 'PLAN.md'));
|
|
1933
|
+
const verifyMissing = !fs.existsSync(path.join(target, '.oxe', 'VERIFY.md'));
|
|
1934
|
+
if (specMissing) {
|
|
1935
|
+
console.log(` ${c ? yellow : ''}⚠ Bloqueio:${c ? reset : ''} SPEC.md ausente — rode ${c ? cyan : ''}/oxe-spec${c ? reset : ''} antes de planejar`);
|
|
1936
|
+
} else if (planMissing) {
|
|
1937
|
+
console.log(` ${c ? yellow : ''}⚠ Bloqueio:${c ? reset : ''} PLAN.md ausente — rode ${c ? cyan : ''}/oxe-plan${c ? reset : ''}`);
|
|
1938
|
+
} else if (verifyMissing && !planMissing) {
|
|
1939
|
+
console.log(` ${c ? dim : ''}Obs.:${c ? reset : ''} VERIFY.md ainda não gerado — rode ${c ? cyan : ''}/oxe-verify${c ? reset : ''} após executar`);
|
|
1940
|
+
}
|
|
1941
|
+
|
|
1837
1942
|
if (opts.hints) {
|
|
1838
1943
|
console.log(`\n ${c ? cyan : ''}Lembretes (rotina OXE)${reset}`);
|
|
1839
1944
|
if (routineHints.length) {
|
|
@@ -1865,7 +1970,46 @@ function runStatus(target, opts = {}) {
|
|
|
1865
1970
|
}
|
|
1866
1971
|
|
|
1867
1972
|
/** @param {string} target */
|
|
1868
|
-
function runDoctor(target) {
|
|
1973
|
+
function runDoctor(target, options = {}) {
|
|
1974
|
+
if (options.release) {
|
|
1975
|
+
if (!options.json) printSection('OXE ▸ doctor --release');
|
|
1976
|
+
const c = useAnsiColors();
|
|
1977
|
+
const result = oxeRelease.checkReleaseConsistency(target, {
|
|
1978
|
+
packageRoot: PKG_ROOT,
|
|
1979
|
+
writeManifest: Boolean(options.writeManifest),
|
|
1980
|
+
});
|
|
1981
|
+
if (options.json) {
|
|
1982
|
+
console.log(
|
|
1983
|
+
JSON.stringify(
|
|
1984
|
+
{
|
|
1985
|
+
status: result.ok ? 'ok' : 'blocked',
|
|
1986
|
+
blockers: result.blockers,
|
|
1987
|
+
warnings: result.warnings,
|
|
1988
|
+
manifestPath: result.manifestPath,
|
|
1989
|
+
manifest: result.manifest,
|
|
1990
|
+
},
|
|
1991
|
+
null,
|
|
1992
|
+
2
|
|
1993
|
+
)
|
|
1994
|
+
);
|
|
1995
|
+
} else {
|
|
1996
|
+
console.log(` ${c ? green : ''}Projeto:${c ? reset : ''} ${c ? cyan : ''}${target}${c ? reset : ''}`);
|
|
1997
|
+
console.log(` ${c ? green : ''}Versão alvo:${c ? reset : ''} ${result.manifest.versions.rootPackage.version || '—'}`);
|
|
1998
|
+
console.log(` ${c ? green : ''}Manifest:${c ? reset : ''} ${result.manifestPath}`);
|
|
1999
|
+
if (result.ok) {
|
|
2000
|
+
console.log(` ${c ? green : ''}✓${c ? reset : ''} release readiness OK`);
|
|
2001
|
+
} else {
|
|
2002
|
+
console.log(` ${c ? red : ''}✗${c ? reset : ''} release readiness bloqueada`);
|
|
2003
|
+
for (const blocker of result.blockers) {
|
|
2004
|
+
console.log(` - ${blocker}`);
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
for (const warning of result.warnings) {
|
|
2008
|
+
console.log(` ${c ? yellow : ''}!${c ? reset : ''} ${warning}`);
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
process.exit(result.ok ? 0 : 1);
|
|
2012
|
+
}
|
|
1869
2013
|
printSection('OXE ▸ doctor');
|
|
1870
2014
|
const v = process.versions.node;
|
|
1871
2015
|
const major = parseInt(v.split('.')[0], 10);
|
|
@@ -1979,6 +2123,72 @@ function runDoctor(target) {
|
|
|
1979
2123
|
}
|
|
1980
2124
|
}
|
|
1981
2125
|
|
|
2126
|
+
// IDE health gates
|
|
2127
|
+
console.log('');
|
|
2128
|
+
const ideChecks = [];
|
|
2129
|
+
const copilotPromptsDir = path.join(target, '.github', 'prompts');
|
|
2130
|
+
const copilotInstructions = path.join(target, '.github', 'copilot-instructions.md');
|
|
2131
|
+
const copilotReady = fs.existsSync(copilotPromptsDir) || fs.existsSync(copilotInstructions);
|
|
2132
|
+
ideChecks.push({ label: 'Copilot', ready: copilotReady, hint: '.github/prompts/ ou copilot-instructions.md' });
|
|
2133
|
+
|
|
2134
|
+
const cursorDir = path.join(target, '.cursor', 'commands');
|
|
2135
|
+
const cursorReady = fs.existsSync(cursorDir);
|
|
2136
|
+
ideChecks.push({ label: 'Cursor', ready: cursorReady, hint: '.cursor/commands/' });
|
|
2137
|
+
|
|
2138
|
+
const claudeLocalDir = path.join(target, 'commands', 'oxe');
|
|
2139
|
+
const claudeGlobalDir = path.join(require('os').homedir(), '.claude', 'commands');
|
|
2140
|
+
const claudeReady = fs.existsSync(claudeLocalDir) || fs.existsSync(claudeGlobalDir);
|
|
2141
|
+
ideChecks.push({ label: 'Claude Code', ready: claudeReady, hint: 'commands/oxe/ ou ~/.claude/commands/' });
|
|
2142
|
+
|
|
2143
|
+
for (const ide of ideChecks) {
|
|
2144
|
+
if (ide.ready) {
|
|
2145
|
+
console.log(`${c ? green : ''}OK${c ? reset : ''} ${ide.label} pronto (${ide.hint})`);
|
|
2146
|
+
} else {
|
|
2147
|
+
console.log(`${c ? dim : ''}Obs.:${c ? reset : ''} ${ide.label} não detectado — esperado ${ide.hint}`);
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
// Runtime compilation check
|
|
2152
|
+
const runtimeCompiledPath = path.join(target, 'lib', 'runtime', 'index.js');
|
|
2153
|
+
const runtimeDistPath = path.join(target, 'packages', 'runtime', 'dist-tests');
|
|
2154
|
+
const runtimeCompiled = fs.existsSync(runtimeCompiledPath) || fs.existsSync(runtimeDistPath);
|
|
2155
|
+
if (runtimeCompiled) {
|
|
2156
|
+
console.log(`${c ? green : ''}OK${c ? reset : ''} Runtime compilado detectado — modo enterprise disponível`);
|
|
2157
|
+
} else {
|
|
2158
|
+
console.log(`${c ? dim : ''}Obs.:${c ? reset : ''} Runtime não compilado — operando em modo legado (sem perda de UX)`);
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2161
|
+
// Readiness gate summary
|
|
2162
|
+
const stateFilePath = path.join(target, '.oxe', 'STATE.md');
|
|
2163
|
+
let readinessCmd = '/oxe-scan';
|
|
2164
|
+
let readinessDesc = 'Nenhum STATE.md encontrado';
|
|
2165
|
+
if (fs.existsSync(stateFilePath)) {
|
|
2166
|
+
try {
|
|
2167
|
+
const stateContent = fs.readFileSync(stateFilePath, 'utf8');
|
|
2168
|
+
const phaseMatch = stateContent.match(/fase[:\s]+([a-z_]+)/i) || stateContent.match(/phase[:\s]+([a-z_]+)/i) || stateContent.match(/status[:\s]+([a-z_]+)/i);
|
|
2169
|
+
const phase = phaseMatch ? phaseMatch[1].toLowerCase() : 'init';
|
|
2170
|
+
const phaseMap = {
|
|
2171
|
+
init: { cmd: '/oxe-scan', desc: 'Pronto para /oxe-scan' },
|
|
2172
|
+
scan_complete: { cmd: '/oxe-spec', desc: 'Pronto para /oxe-spec' },
|
|
2173
|
+
spec_complete: { cmd: '/oxe-plan', desc: 'Pronto para /oxe-plan' },
|
|
2174
|
+
plan_complete: { cmd: '/oxe-execute', desc: 'Pronto para /oxe-execute' },
|
|
2175
|
+
execute_complete: { cmd: '/oxe-verify', desc: 'Pronto para /oxe-verify' },
|
|
2176
|
+
verify_complete: { cmd: 'runtime promote --target pr_draft', desc: 'Pronto para promoção' },
|
|
2177
|
+
};
|
|
2178
|
+
const next = phaseMap[phase] || { cmd: '/oxe', desc: `Fase detectada: ${phase}` };
|
|
2179
|
+
readinessCmd = next.cmd;
|
|
2180
|
+
readinessDesc = next.desc;
|
|
2181
|
+
} catch (_) { /* ignore */ }
|
|
2182
|
+
}
|
|
2183
|
+
const specPath = path.join(target, '.oxe', 'SPEC.md');
|
|
2184
|
+
const specExists = fs.existsSync(specPath);
|
|
2185
|
+
console.log('');
|
|
2186
|
+
if (specExists) {
|
|
2187
|
+
console.log(` ${c ? green : ''}✓ ${readinessDesc}${c ? reset : ''} — próximo: ${c ? cyan : ''}${readinessCmd}${c ? reset : ''}`);
|
|
2188
|
+
} else {
|
|
2189
|
+
console.log(` ${c ? yellow : ''}⚠ Falta SPEC — rode ${c ? cyan : ''}${readinessCmd}${c ? reset : ''}`);
|
|
2190
|
+
}
|
|
2191
|
+
|
|
1982
2192
|
printOxeHealthDiagnostics(target, c);
|
|
1983
2193
|
const report = oxeHealth.buildHealthReport(target);
|
|
1984
2194
|
const statusColor = report.healthStatus === 'healthy' ? green : report.healthStatus === 'warning' ? yellow : red;
|
|
@@ -1986,10 +2196,12 @@ function runDoctor(target) {
|
|
|
1986
2196
|
if (report.healthStatus === 'broken') {
|
|
1987
2197
|
process.exitCode = 1;
|
|
1988
2198
|
}
|
|
2199
|
+
const ideReadySummary = ideChecks.filter((i) => i.ready).map((i) => i.label).join(', ') || 'nenhuma IDE detectada';
|
|
1989
2200
|
printSummaryAndNextSteps(c, {
|
|
1990
2201
|
bullets: [
|
|
1991
2202
|
`Projeto em ${target}`,
|
|
1992
2203
|
`Workflows conferidos em ${wfLabel}`,
|
|
2204
|
+
`IDEs prontas: ${ideReadySummary}`,
|
|
1993
2205
|
`Saúde lógica: ${report.healthStatus}`,
|
|
1994
2206
|
],
|
|
1995
2207
|
nextSteps: [
|
|
@@ -2018,6 +2230,12 @@ function installGlobalCliPackage() {
|
|
|
2018
2230
|
shell: true,
|
|
2019
2231
|
env: process.env,
|
|
2020
2232
|
});
|
|
2233
|
+
if (r.error) {
|
|
2234
|
+
console.log(
|
|
2235
|
+
`\n ${c ? yellow : ''}⚠${c ? reset : ''} npm install -g falhou (${r.error.message}). Tente manualmente: ${c ? cyan : ''}npm install -g ${spec}${c ? reset : ''}\n`
|
|
2236
|
+
);
|
|
2237
|
+
return false;
|
|
2238
|
+
}
|
|
2021
2239
|
if (r.status === 0) {
|
|
2022
2240
|
console.log(
|
|
2023
2241
|
`\n ${c ? green : ''}✓${c ? reset : ''} ${c ? cyan : ''}oxe-cc${c ? reset : ''} disponível globalmente (execute ${c ? cyan : ''}oxe-cc --help${c ? reset : ''} em qualquer pasta).\n`
|
|
@@ -2199,30 +2417,37 @@ function usage() {
|
|
|
2199
2417
|
console.log(`
|
|
2200
2418
|
${cyan}oxe-cc${reset} — instala workflows OXE (núcleo .oxe/ + integrações: Cursor, Copilot, Claude, OpenCode, Gemini, Codex, Windsurf, Antigravity, …)
|
|
2201
2419
|
|
|
2202
|
-
${green}Uso:${reset}
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
npx oxe-cc runtime <status|start|pause|resume|replay|compile|verify|project|ci|promote|recover|gates> [opções] [pasta-do-projeto]
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
${green}
|
|
2420
|
+
${green}Uso:${reset}
|
|
2421
|
+
npx oxe-cc@latest [opções] [pasta-do-projeto]
|
|
2422
|
+
npx oxe-cc@latest install [opções] [pasta-do-projeto] ${dim}(equivalente à instalação predefinida)${reset}
|
|
2423
|
+
npx oxe-cc@latest --dir /caminho/do/projeto
|
|
2424
|
+
npx oxe-cc doctor [--release] [--write-manifest] [opções] [pasta-do-projeto]
|
|
2425
|
+
npx oxe-cc status [opções] [pasta-do-projeto]
|
|
2426
|
+
npx oxe-cc init-oxe [opções] [pasta-do-projeto]
|
|
2427
|
+
npx oxe-cc context <build|inspect> [opções] [pasta-do-projeto]
|
|
2428
|
+
npx oxe-cc dashboard [opções] [pasta-do-projeto]
|
|
2429
|
+
npx oxe-cc runtime <status|start|pause|resume|replay|compile|verify|project|ci|promote|recover|gates|agents> [opções] [pasta-do-projeto]
|
|
2430
|
+
npx oxe-cc azure <status|doctor|auth|sync|find|servicebus|eventgrid|sql|operations> [opções] [pasta-do-projeto]
|
|
2431
|
+
npx oxe-cc capabilities <list|install|remove|update> [opções] [id]
|
|
2432
|
+
npx oxe-cc uninstall [opções] [pasta-do-projeto]
|
|
2433
|
+
npx oxe-cc update [opções] [argumentos extras…]
|
|
2434
|
+
|
|
2435
|
+
${green}doctor${reset}
|
|
2436
|
+
--release valida release readiness: versões, changelog, wrappers, runtime build e relatórios obrigatórios
|
|
2437
|
+
--write-manifest persiste .oxe/release/release-manifest.json durante doctor --release
|
|
2438
|
+
--json saída estruturada para CI
|
|
2439
|
+
|
|
2440
|
+
${green}uninstall${reset} (remove OXE da pasta do usuário + pastas de workflows no repo)
|
|
2218
2441
|
--cursor / --copilot / --copilot-cli só essa integração (omissão = todas)
|
|
2219
2442
|
--copilot-vscode alias explícito de --copilot
|
|
2220
2443
|
--copilot-legacy-clean limpa só o legado antigo do Copilot VS Code em ~/.copilot/
|
|
2221
2444
|
--all-agents também remove ficheiros multi-plataforma (com --copilot-cli implícito)
|
|
2445
|
+
--opencode / --gemini / --codex / --windsurf / --antigravity
|
|
2446
|
+
remove só esse agente multi-runtime
|
|
2222
2447
|
--ide-local remove integrações IDE neste repositório (.cursor, .github, .claude, .copilot, …)
|
|
2223
2448
|
--ide-only não apagar .oxe/workflows, oxe/, etc. no projeto
|
|
2224
2449
|
--global-cli, -g também executa npm uninstall -g oxe-cc
|
|
2225
|
-
--config-dir <caminho> com exatamente uma flag IDE acima (não combina com --ide-local nem
|
|
2450
|
+
--config-dir <caminho> com exatamente uma flag IDE acima (não combina com --ide-local, --copilot nem agentes granulares)
|
|
2226
2451
|
--dry-run
|
|
2227
2452
|
--dir <pasta> raiz do projeto (padrão: diretório atual)
|
|
2228
2453
|
|
|
@@ -2260,7 +2485,7 @@ ${green}runtime${reset} (controle operacional explícito do ACTIVE-RUN)
|
|
|
2260
2485
|
verify executa a suite enterprise, coleta evidência e projeta VERIFY.md
|
|
2261
2486
|
project projeta markdowns derivados do estado canônico
|
|
2262
2487
|
ci executa checks do runtime e persiste o resultado na run
|
|
2263
|
-
promote promove remotamente a run ativa (estável: pr_draft)
|
|
2488
|
+
promote promove remotamente a run ativa (estável: pr_draft)
|
|
2264
2489
|
recover reidrata estado canônico/journal/gates/policy da run ativa
|
|
2265
2490
|
gates <list|show|resolve> fila operacional de gates pendentes e resoluções auditáveis
|
|
2266
2491
|
--session <sessions/sNNN-slug> força sessão específica
|
|
@@ -2274,7 +2499,7 @@ ${green}runtime${reset} (controle operacional explícito do ACTIVE-RUN)
|
|
|
2274
2499
|
--gate <gate_id> (gates show|resolve) gate alvo
|
|
2275
2500
|
--decision <approve|reject|waive> (gates resolve) decisão aplicada
|
|
2276
2501
|
--actor <id> (gates resolve) ator responsável
|
|
2277
|
-
--target <pr_draft|branch_push> (promote) alvo remoto; padrão pr_draft, branch_push é avançado
|
|
2502
|
+
--target <pr_draft|branch_push> (promote) alvo remoto; padrão pr_draft, branch_push é avançado
|
|
2278
2503
|
--remote <nome> (promote) remote git; padrão origin
|
|
2279
2504
|
--base <branch> (promote) branch/ref base; padrão main
|
|
2280
2505
|
--minimum-coverage <0-100> (promote) cobertura mínima exigida; padrão 100
|
|
@@ -2619,8 +2844,8 @@ function runInstall(opts) {
|
|
|
2619
2844
|
}
|
|
2620
2845
|
trackFile(runtimeSemanticsManifestPath(opts));
|
|
2621
2846
|
if (opts.copilotCli || opts.allAgents) {
|
|
2622
|
-
addTracked(path.join(installClaudeBase(opts), 'commands'), (n) =>
|
|
2623
|
-
addTracked(path.join(cpCliHome, 'commands'), (n) =>
|
|
2847
|
+
addTracked(path.join(installClaudeBase(opts), 'commands'), (n) => oxeAgentInstall.isOxeCommandMarkdownName(n));
|
|
2848
|
+
addTracked(path.join(cpCliHome, 'commands'), (n) => oxeAgentInstall.isOxeCommandMarkdownName(n));
|
|
2624
2849
|
const skRoot = path.join(cpCliHome, 'skills');
|
|
2625
2850
|
if (fs.existsSync(skRoot)) {
|
|
2626
2851
|
for (const sub of fs.readdirSync(skRoot, { withFileTypes: true })) {
|
|
@@ -2638,7 +2863,7 @@ function runInstall(opts) {
|
|
|
2638
2863
|
}
|
|
2639
2864
|
if (opts.agentOpenCode || opts.allAgents) {
|
|
2640
2865
|
for (const d of agentPaths.opencodeCommandDirs) {
|
|
2641
|
-
addTracked(d, (n) =>
|
|
2866
|
+
addTracked(d, (n) => oxeAgentInstall.isOxeCommandMarkdownName(n));
|
|
2642
2867
|
}
|
|
2643
2868
|
}
|
|
2644
2869
|
if (opts.agentGemini || opts.allAgents) {
|
|
@@ -2657,7 +2882,7 @@ function runInstall(opts) {
|
|
|
2657
2882
|
if (opts.agentCodex || opts.allAgents) {
|
|
2658
2883
|
const cxPrompts = agentPaths.codexPromptsDir;
|
|
2659
2884
|
if (fs.existsSync(cxPrompts)) {
|
|
2660
|
-
addTracked(cxPrompts, (n) =>
|
|
2885
|
+
addTracked(cxPrompts, (n) => oxeAgentInstall.isOxeCommandMarkdownName(n));
|
|
2661
2886
|
}
|
|
2662
2887
|
}
|
|
2663
2888
|
if (opts.agentAntigravity || opts.allAgents) {
|
|
@@ -2702,7 +2927,7 @@ function runInstall(opts) {
|
|
|
2702
2927
|
console.log(` ${c ? green : ''}✓${c ? reset : ''} Instalação concluída com sucesso.\n`);
|
|
2703
2928
|
}
|
|
2704
2929
|
|
|
2705
|
-
/** @typedef {{ help: boolean, dryRun: boolean, cursor: boolean, copilot: boolean, copilotCli: boolean, allAgents: boolean, globalCli: boolean, ideLocal: boolean, ideExplicit: boolean, noProject: boolean, copilotLegacyClean: boolean, dir: string, explicitConfigDir: string | null, parseError: boolean, unknownFlag: string, conflictFlags: string }} UninstallOpts */
|
|
2930
|
+
/** @typedef {{ help: boolean, dryRun: boolean, cursor: boolean, copilot: boolean, copilotCli: boolean, allAgents: boolean, agentOpenCode: boolean, agentGemini: boolean, agentCodex: boolean, agentWindsurf: boolean, agentAntigravity: boolean, globalCli: boolean, ideLocal: boolean, ideExplicit: boolean, noProject: boolean, copilotLegacyClean: boolean, dir: string, explicitConfigDir: string | null, parseError: boolean, unknownFlag: string, conflictFlags: string }} UninstallOpts */
|
|
2706
2931
|
|
|
2707
2932
|
/**
|
|
2708
2933
|
* @param {UninstallOpts} u
|
|
@@ -2718,7 +2943,7 @@ function uninstallLocalIdeFromProject(u, removedPaths) {
|
|
|
2718
2943
|
const cmdDir = path.join(proj, '.cursor', 'commands');
|
|
2719
2944
|
if (fs.existsSync(cmdDir)) {
|
|
2720
2945
|
for (const name of fs.readdirSync(cmdDir)) {
|
|
2721
|
-
if (
|
|
2946
|
+
if (oxeAgentInstall.isOxeCommandMarkdownName(name)) {
|
|
2722
2947
|
const p = path.join(cmdDir, name);
|
|
2723
2948
|
unlinkQuiet(p, u);
|
|
2724
2949
|
track(p);
|
|
@@ -2744,7 +2969,7 @@ function uninstallLocalIdeFromProject(u, removedPaths) {
|
|
|
2744
2969
|
const pr = path.join(proj, '.github', 'prompts');
|
|
2745
2970
|
if (fs.existsSync(pr)) {
|
|
2746
2971
|
for (const name of fs.readdirSync(pr)) {
|
|
2747
|
-
if (/^oxe-.*\.prompt\.md$/i.test(name)) {
|
|
2972
|
+
if (name === 'oxe.prompt.md' || /^oxe-.*\.prompt\.md$/i.test(name)) {
|
|
2748
2973
|
const p = path.join(pr, name);
|
|
2749
2974
|
unlinkQuiet(p, u);
|
|
2750
2975
|
track(p);
|
|
@@ -2761,7 +2986,7 @@ function uninstallLocalIdeFromProject(u, removedPaths) {
|
|
|
2761
2986
|
const cmdDir = path.join(base, 'commands');
|
|
2762
2987
|
if (!fs.existsSync(cmdDir)) continue;
|
|
2763
2988
|
for (const name of fs.readdirSync(cmdDir)) {
|
|
2764
|
-
if (
|
|
2989
|
+
if (oxeAgentInstall.isOxeCommandMarkdownName(name)) {
|
|
2765
2990
|
const p = path.join(cmdDir, name);
|
|
2766
2991
|
unlinkQuiet(p, u);
|
|
2767
2992
|
track(p);
|
|
@@ -2792,16 +3017,20 @@ function uninstallLocalIdeFromProject(u, removedPaths) {
|
|
|
2792
3017
|
}
|
|
2793
3018
|
}
|
|
2794
3019
|
|
|
2795
|
-
if (u.
|
|
3020
|
+
if (u.allAgents || anyGranularUninstallAgent(u)) {
|
|
2796
3021
|
const localPaths = oxeAgentInstall.buildAgentInstallPaths(false, proj);
|
|
3022
|
+
const cleanupTargets = buildAgentCleanupTargets(u);
|
|
2797
3023
|
if (!u.dryRun) {
|
|
2798
|
-
oxeAgentInstall.cleanupMarkedUnifiedArtifacts(u, localPaths);
|
|
3024
|
+
oxeAgentInstall.cleanupMarkedUnifiedArtifacts({ dryRun: u.dryRun, targets: cleanupTargets }, localPaths);
|
|
2799
3025
|
} else {
|
|
2800
|
-
|
|
3026
|
+
const label = cleanupTargets
|
|
3027
|
+
? Object.keys(cleanupTargets).filter((key) => cleanupTargets[key]).join(', ')
|
|
3028
|
+
: 'OpenCode, Gemini, Windsurf, Codex, Antigravity';
|
|
3029
|
+
console.log(`${dim}agents${reset} (dry-run) limparia marcadores oxe-cc em pastas locais do projeto (${label})`);
|
|
2801
3030
|
}
|
|
2802
3031
|
}
|
|
2803
3032
|
|
|
2804
|
-
if (u.cursor || u.copilot || u.copilotCli || u.allAgents) {
|
|
3033
|
+
if (u.cursor || u.copilot || u.copilotCli || u.allAgents || anyGranularUninstallAgent(u)) {
|
|
2805
3034
|
const runtimeManifest = path.join(proj, '.oxe', 'install', 'runtime-semantics.json');
|
|
2806
3035
|
unlinkQuiet(runtimeManifest, u);
|
|
2807
3036
|
track(runtimeManifest);
|
|
@@ -2821,6 +3050,11 @@ function parseUninstallArgs(argv) {
|
|
|
2821
3050
|
copilot: false,
|
|
2822
3051
|
copilotCli: false,
|
|
2823
3052
|
allAgents: false,
|
|
3053
|
+
agentOpenCode: false,
|
|
3054
|
+
agentGemini: false,
|
|
3055
|
+
agentCodex: false,
|
|
3056
|
+
agentWindsurf: false,
|
|
3057
|
+
agentAntigravity: false,
|
|
2824
3058
|
globalCli: false,
|
|
2825
3059
|
ideLocal: false,
|
|
2826
3060
|
ideExplicit: false,
|
|
@@ -2848,11 +3082,31 @@ function parseUninstallArgs(argv) {
|
|
|
2848
3082
|
} else if (a === '--copilot-cli') {
|
|
2849
3083
|
out.copilotCli = true;
|
|
2850
3084
|
out.ideExplicit = true;
|
|
3085
|
+
} else if (a === '--opencode') {
|
|
3086
|
+
out.agentOpenCode = true;
|
|
3087
|
+
out.ideExplicit = true;
|
|
3088
|
+
} else if (a === '--gemini') {
|
|
3089
|
+
out.agentGemini = true;
|
|
3090
|
+
out.ideExplicit = true;
|
|
3091
|
+
} else if (a === '--codex') {
|
|
3092
|
+
out.agentCodex = true;
|
|
3093
|
+
out.ideExplicit = true;
|
|
3094
|
+
} else if (a === '--windsurf') {
|
|
3095
|
+
out.agentWindsurf = true;
|
|
3096
|
+
out.ideExplicit = true;
|
|
3097
|
+
} else if (a === '--antigravity') {
|
|
3098
|
+
out.agentAntigravity = true;
|
|
3099
|
+
out.ideExplicit = true;
|
|
2851
3100
|
} else if (a === '--copilot-legacy-clean') {
|
|
2852
3101
|
out.copilotLegacyClean = true;
|
|
2853
3102
|
} else if (a === '--all-agents') {
|
|
2854
3103
|
out.allAgents = true;
|
|
2855
3104
|
out.copilotCli = true;
|
|
3105
|
+
out.agentOpenCode = true;
|
|
3106
|
+
out.agentGemini = true;
|
|
3107
|
+
out.agentCodex = true;
|
|
3108
|
+
out.agentWindsurf = true;
|
|
3109
|
+
out.agentAntigravity = true;
|
|
2856
3110
|
out.ideExplicit = true;
|
|
2857
3111
|
} else if (a === '--global-cli' || a === '-g') {
|
|
2858
3112
|
out.globalCli = true;
|
|
@@ -2871,6 +3125,7 @@ function parseUninstallArgs(argv) {
|
|
|
2871
3125
|
out.cursor = true;
|
|
2872
3126
|
out.copilot = true;
|
|
2873
3127
|
out.copilotCli = true;
|
|
3128
|
+
out.allAgents = true;
|
|
2874
3129
|
} else if (out.copilotLegacyClean && !out.ideExplicit && !out.noProject) {
|
|
2875
3130
|
out.noProject = true;
|
|
2876
3131
|
}
|
|
@@ -2879,6 +3134,8 @@ function parseUninstallArgs(argv) {
|
|
|
2879
3134
|
out.conflictFlags = '--config-dir não combina com --ide-local';
|
|
2880
3135
|
} else if (out.allAgents) {
|
|
2881
3136
|
out.conflictFlags = '--config-dir não combina com --all-agents';
|
|
3137
|
+
} else if (anyGranularUninstallAgent(out)) {
|
|
3138
|
+
out.conflictFlags = '--config-dir só é suportado com exatamente um entre --cursor, --copilot e --copilot-cli';
|
|
2882
3139
|
} else if (out.copilot && !out.cursor && !out.copilotCli) {
|
|
2883
3140
|
out.conflictFlags =
|
|
2884
3141
|
'--config-dir não combina com --copilot porque o GitHub Copilot no VS Code usa .github/ no workspace';
|
|
@@ -2925,7 +3182,7 @@ function cleanupLegacyCopilotVsCode(ideOpts, opts, removedPaths) {
|
|
|
2925
3182
|
const pr = copilotLegacyPromptDir(ideOpts);
|
|
2926
3183
|
if (!fs.existsSync(pr)) return;
|
|
2927
3184
|
for (const name of fs.readdirSync(pr)) {
|
|
2928
|
-
if (!/^oxe-.*\.prompt\.md$/i.test(name)) continue;
|
|
3185
|
+
if (name !== 'oxe.prompt.md' && !/^oxe-.*\.prompt\.md$/i.test(name)) continue;
|
|
2929
3186
|
const promptPath = path.join(pr, name);
|
|
2930
3187
|
unlinkQuiet(promptPath, opts);
|
|
2931
3188
|
removedPaths.push(promptPath);
|
|
@@ -2973,6 +3230,11 @@ function runUninstall(u) {
|
|
|
2973
3230
|
copilot: u.copilot,
|
|
2974
3231
|
copilotCli: u.copilotCli,
|
|
2975
3232
|
allAgents: u.allAgents,
|
|
3233
|
+
agentOpenCode: u.agentOpenCode,
|
|
3234
|
+
agentGemini: u.agentGemini,
|
|
3235
|
+
agentCodex: u.agentCodex,
|
|
3236
|
+
agentWindsurf: u.agentWindsurf,
|
|
3237
|
+
agentAntigravity: u.agentAntigravity,
|
|
2976
3238
|
vscode: false,
|
|
2977
3239
|
commands: false,
|
|
2978
3240
|
agents: false,
|
|
@@ -3013,7 +3275,7 @@ function runUninstall(u) {
|
|
|
3013
3275
|
const ruleDir = path.join(base, 'rules');
|
|
3014
3276
|
if (fs.existsSync(cmdDir)) {
|
|
3015
3277
|
for (const name of fs.readdirSync(cmdDir)) {
|
|
3016
|
-
if (
|
|
3278
|
+
if (oxeAgentInstall.isOxeCommandMarkdownName(name)) {
|
|
3017
3279
|
const p = path.join(cmdDir, name);
|
|
3018
3280
|
unlinkQuiet(p, u);
|
|
3019
3281
|
removedPaths.push(p);
|
|
@@ -3038,7 +3300,7 @@ function runUninstall(u) {
|
|
|
3038
3300
|
const pr = path.join(u.dir, '.github', 'prompts');
|
|
3039
3301
|
if (fs.existsSync(pr)) {
|
|
3040
3302
|
for (const name of fs.readdirSync(pr)) {
|
|
3041
|
-
if (/^oxe-.*\.prompt\.md$/i.test(name)) {
|
|
3303
|
+
if (name === 'oxe.prompt.md' || /^oxe-.*\.prompt\.md$/i.test(name)) {
|
|
3042
3304
|
const p = path.join(pr, name);
|
|
3043
3305
|
unlinkQuiet(p, u);
|
|
3044
3306
|
removedPaths.push(p);
|
|
@@ -3059,7 +3321,7 @@ function runUninstall(u) {
|
|
|
3059
3321
|
const cmdDir = path.join(base, 'commands');
|
|
3060
3322
|
if (!fs.existsSync(cmdDir)) continue;
|
|
3061
3323
|
for (const name of fs.readdirSync(cmdDir)) {
|
|
3062
|
-
if (
|
|
3324
|
+
if (oxeAgentInstall.isOxeCommandMarkdownName(name)) {
|
|
3063
3325
|
const p = path.join(cmdDir, name);
|
|
3064
3326
|
unlinkQuiet(p, u);
|
|
3065
3327
|
removedPaths.push(p);
|
|
@@ -3088,10 +3350,66 @@ function runUninstall(u) {
|
|
|
3088
3350
|
removedPaths.push(skillFile);
|
|
3089
3351
|
}
|
|
3090
3352
|
}
|
|
3353
|
+
}
|
|
3354
|
+
|
|
3355
|
+
if (u.allAgents || anyGranularUninstallAgent(u)) {
|
|
3356
|
+
const cleanupTargets = buildAgentCleanupTargets(u);
|
|
3091
3357
|
if (u.dryRun) {
|
|
3092
|
-
|
|
3358
|
+
const label = cleanupTargets
|
|
3359
|
+
? Object.keys(cleanupTargets).filter((key) => cleanupTargets[key]).join(', ')
|
|
3360
|
+
: 'OpenCode, Gemini, Windsurf, Codex, Antigravity';
|
|
3361
|
+
console.log(`${dim}agents${reset} (dry-run) limparia ${label || 'OpenCode, Gemini, Windsurf, Codex, Antigravity'} (marcadores oxe-cc)`);
|
|
3093
3362
|
} else {
|
|
3094
|
-
oxeAgentInstall.cleanupMarkedUnifiedArtifacts(u);
|
|
3363
|
+
oxeAgentInstall.cleanupMarkedUnifiedArtifacts({ dryRun: u.dryRun, targets: cleanupTargets });
|
|
3364
|
+
}
|
|
3365
|
+
const globalAgentPaths = oxeAgentInstall.buildAgentInstallPaths(true, u.dir);
|
|
3366
|
+
const shouldTrack = (name) => !cleanupTargets || cleanupTargets[name] !== false;
|
|
3367
|
+
const pushRemoved = (filePath) => {
|
|
3368
|
+
if (removedPaths.indexOf(filePath) === -1) removedPaths.push(filePath);
|
|
3369
|
+
};
|
|
3370
|
+
if (shouldTrack('opencode')) {
|
|
3371
|
+
for (const dir of globalAgentPaths.opencodeCommandDirs) {
|
|
3372
|
+
if (!fs.existsSync(dir)) continue;
|
|
3373
|
+
for (const name of fs.readdirSync(dir)) {
|
|
3374
|
+
if (!oxeAgentInstall.isOxeCommandMarkdownName(name)) continue;
|
|
3375
|
+
pushRemoved(path.join(dir, name));
|
|
3376
|
+
}
|
|
3377
|
+
}
|
|
3378
|
+
}
|
|
3379
|
+
if (shouldTrack('gemini')) {
|
|
3380
|
+
pushRemoved(path.join(globalAgentPaths.geminiCommandsBase, 'oxe.toml'));
|
|
3381
|
+
const geminiSub = path.join(globalAgentPaths.geminiCommandsBase, 'oxe');
|
|
3382
|
+
if (fs.existsSync(geminiSub)) {
|
|
3383
|
+
for (const name of fs.readdirSync(geminiSub)) {
|
|
3384
|
+
if (name.endsWith('.toml')) pushRemoved(path.join(geminiSub, name));
|
|
3385
|
+
}
|
|
3386
|
+
}
|
|
3387
|
+
}
|
|
3388
|
+
if (shouldTrack('windsurf') && fs.existsSync(globalAgentPaths.windsurfWorkflowsDir)) {
|
|
3389
|
+
for (const name of fs.readdirSync(globalAgentPaths.windsurfWorkflowsDir)) {
|
|
3390
|
+
if (!oxeAgentInstall.isOxeCommandMarkdownName(name)) continue;
|
|
3391
|
+
pushRemoved(path.join(globalAgentPaths.windsurfWorkflowsDir, name));
|
|
3392
|
+
}
|
|
3393
|
+
}
|
|
3394
|
+
if (shouldTrack('codex')) {
|
|
3395
|
+
if (fs.existsSync(globalAgentPaths.codexPromptsDir)) {
|
|
3396
|
+
for (const name of fs.readdirSync(globalAgentPaths.codexPromptsDir)) {
|
|
3397
|
+
if (!oxeAgentInstall.isOxeCommandMarkdownName(name)) continue;
|
|
3398
|
+
pushRemoved(path.join(globalAgentPaths.codexPromptsDir, name));
|
|
3399
|
+
}
|
|
3400
|
+
}
|
|
3401
|
+
if (fs.existsSync(globalAgentPaths.codexAgentsSkillsRoot)) {
|
|
3402
|
+
for (const entry of fs.readdirSync(globalAgentPaths.codexAgentsSkillsRoot, { withFileTypes: true })) {
|
|
3403
|
+
if (!entry.isDirectory() || !/^oxe($|-)/.test(entry.name)) continue;
|
|
3404
|
+
pushRemoved(path.join(globalAgentPaths.codexAgentsSkillsRoot, entry.name, 'SKILL.md'));
|
|
3405
|
+
}
|
|
3406
|
+
}
|
|
3407
|
+
}
|
|
3408
|
+
if (shouldTrack('antigravity') && fs.existsSync(globalAgentPaths.antigravitySkillsRoot)) {
|
|
3409
|
+
for (const entry of fs.readdirSync(globalAgentPaths.antigravitySkillsRoot, { withFileTypes: true })) {
|
|
3410
|
+
if (!entry.isDirectory() || !/^oxe($|-)/.test(entry.name)) continue;
|
|
3411
|
+
pushRemoved(path.join(globalAgentPaths.antigravitySkillsRoot, entry.name, 'SKILL.md'));
|
|
3412
|
+
}
|
|
3095
3413
|
}
|
|
3096
3414
|
}
|
|
3097
3415
|
|
|
@@ -3126,7 +3444,7 @@ function runUninstall(u) {
|
|
|
3126
3444
|
}
|
|
3127
3445
|
}
|
|
3128
3446
|
|
|
3129
|
-
if (!u.dryRun && (u.cursor || u.copilot || u.copilotCli || u.copilotLegacyClean)) {
|
|
3447
|
+
if (!u.dryRun && (u.cursor || u.copilot || u.copilotCli || u.copilotLegacyClean || anyGranularUninstallAgent(u))) {
|
|
3130
3448
|
const prev = oxeManifest.loadFileManifest(home);
|
|
3131
3449
|
const next = { ...prev };
|
|
3132
3450
|
for (const p of removedPaths) delete next[p];
|
|
@@ -3333,7 +3651,7 @@ function runUpdate(u) {
|
|
|
3333
3651
|
const r = spawnSync('npx', args, {
|
|
3334
3652
|
cwd: u.dir,
|
|
3335
3653
|
stdio: 'inherit',
|
|
3336
|
-
env: { ...process.env },
|
|
3654
|
+
env: { ...process.env, OXE_NO_PROMPT: '1' },
|
|
3337
3655
|
shell: process.platform === 'win32',
|
|
3338
3656
|
});
|
|
3339
3657
|
if (r.error) {
|
|
@@ -3951,15 +4269,24 @@ async function runRuntime(opts) {
|
|
|
3951
4269
|
console.log(JSON.stringify(gates, null, 2));
|
|
3952
4270
|
return;
|
|
3953
4271
|
}
|
|
4272
|
+
const slaHours = gates.gateSlaHours || 24;
|
|
3954
4273
|
console.log(` ${c ? green : ''}Run:${c ? reset : ''} ${runId || '—'}`);
|
|
3955
|
-
console.log(` ${c ? green : ''}Gates:${c ? reset : ''} total=${gates.total} pendentes=${gates.pending.length} stale=${gates.stalePending.length} resolvidos<24h=${gates.resolvedRecent.length} SLA=${
|
|
4274
|
+
console.log(` ${c ? green : ''}Gates:${c ? reset : ''} total=${gates.total} pendentes=${gates.pending.length} stale=${gates.stalePending.length} resolvidos<24h=${gates.resolvedRecent.length} SLA=${slaHours}h`);
|
|
3956
4275
|
console.log(` ${c ? green : ''}Filtros:${c ? reset : ''} status=${gates.filters.status || 'all'} scope=${gates.filters.scope || '—'} task=${gates.filters.workItemId || '—'}`);
|
|
3957
|
-
|
|
4276
|
+
const allPending = [...gates.pending];
|
|
4277
|
+
for (const gate of allPending) {
|
|
3958
4278
|
const ageHours = gate.requested_at ? Math.max(0, Math.round((Date.now() - Date.parse(gate.requested_at)) / 36e5)) : null;
|
|
3959
|
-
|
|
4279
|
+
const isStale = ageHours != null && ageHours > slaHours;
|
|
4280
|
+
const icon = isStale ? `${c ? yellow : ''}⚠ stale (>${slaHours}h)${c ? reset : ''}` : `${c ? yellow : ''}⏳ pending${c ? reset : ''}`;
|
|
4281
|
+
const suggested = gate.action === 'approve' ? 'approve' : 'approve|reject|waive';
|
|
4282
|
+
console.log(` ${icon} ${gate.gate_id} · ${gate.scope || '—'} · ${gate.work_item_id || 'run'}${ageHours != null ? ` · ${ageHours}h aberto` : ''}`);
|
|
4283
|
+
console.log(` ${c ? dim : ''}ação sugerida: --decision ${suggested} · impacto: bloqueia promoção${c ? reset : ''}`);
|
|
3960
4284
|
}
|
|
3961
4285
|
for (const gate of gates.resolvedRecent) {
|
|
3962
|
-
console.log(` ${green}
|
|
4286
|
+
console.log(` ${c ? green : ''}✓ resolved${c ? reset : ''} ${gate.gate_id} · ${gate.scope || '—'} · ${gate.decision || '—'} · ${gate.actor || '—'}`);
|
|
4287
|
+
}
|
|
4288
|
+
if (gates.pending.length === 0 && gates.resolvedRecent.length === 0) {
|
|
4289
|
+
console.log(` ${c ? dim : ''}Nenhum gate pendente.${c ? reset : ''}`);
|
|
3963
4290
|
}
|
|
3964
4291
|
return;
|
|
3965
4292
|
}
|
|
@@ -4012,11 +4339,16 @@ async function runRuntime(opts) {
|
|
|
4012
4339
|
console.log(JSON.stringify(resolved, null, 2));
|
|
4013
4340
|
return;
|
|
4014
4341
|
}
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4342
|
+
const remaining = resolved.impact ? (resolved.impact.pendingRemaining || 0) : 0;
|
|
4343
|
+
const staleRemaining = resolved.impact ? (resolved.impact.staleRemaining || 0) : 0;
|
|
4344
|
+
const canPromote = remaining === 0 && staleRemaining === 0;
|
|
4345
|
+
console.log(` ${c ? green : ''}✓${c ? reset : ''} Gate ${resolved.gate.gate_id} resolvido (${resolved.gate.decision}).`);
|
|
4018
4346
|
console.log(` ${c ? green : ''}Ator:${c ? reset : ''} ${resolved.gate.actor}`);
|
|
4019
|
-
|
|
4347
|
+
if (canPromote) {
|
|
4348
|
+
console.log(` ${c ? green : ''}✓ Run pode avançar para promoção — nenhum gate restante.${c ? reset : ''}`);
|
|
4349
|
+
} else {
|
|
4350
|
+
console.log(` ${c ? yellow : ''}⚠ Run ainda bloqueada por ${remaining} gate(s) restante(s)${staleRemaining > 0 ? ` (${staleRemaining} stale)` : ''}.${c ? reset : ''}`);
|
|
4351
|
+
}
|
|
4020
4352
|
return;
|
|
4021
4353
|
} catch (err) {
|
|
4022
4354
|
console.error(`${red}${err && err.message ? err.message : 'Falha ao resolver gate.'}${reset}`);
|
|
@@ -5033,7 +5365,7 @@ async function main() {
|
|
|
5033
5365
|
process.exit(0);
|
|
5034
5366
|
}
|
|
5035
5367
|
|
|
5036
|
-
if (!(command === 'status' && opts.jsonOutput)) {
|
|
5368
|
+
if (!((command === 'status' && opts.jsonOutput) || (command === 'doctor' && opts.jsonOutput))) {
|
|
5037
5369
|
printBanner();
|
|
5038
5370
|
}
|
|
5039
5371
|
|
|
@@ -5043,7 +5375,7 @@ async function main() {
|
|
|
5043
5375
|
console.error(`${yellow}Diretório não encontrado: ${target}${reset}`);
|
|
5044
5376
|
process.exit(1);
|
|
5045
5377
|
}
|
|
5046
|
-
runDoctor(target);
|
|
5378
|
+
runDoctor(target, { release: opts.releaseDoctor, json: opts.jsonOutput, writeManifest: opts.writeManifest });
|
|
5047
5379
|
return;
|
|
5048
5380
|
}
|
|
5049
5381
|
|
|
@@ -5086,6 +5418,7 @@ async function main() {
|
|
|
5086
5418
|
}
|
|
5087
5419
|
|
|
5088
5420
|
await resolveInteractiveInstall(opts);
|
|
5421
|
+
persistIdeScope(opts);
|
|
5089
5422
|
runInstall(opts);
|
|
5090
5423
|
await maybePromptGlobalCli(opts);
|
|
5091
5424
|
}
|