oxe-cc 0.7.0 → 0.9.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 +34 -0
- package/.cursor/commands/oxe-capabilities.md +34 -0
- package/.cursor/commands/oxe-checkpoint.md +34 -0
- package/.cursor/commands/oxe-compact.md +33 -0
- package/.cursor/commands/oxe-dashboard.md +34 -0
- package/.cursor/commands/oxe-debug.md +34 -0
- package/.cursor/commands/oxe-discuss.md +34 -0
- package/.cursor/commands/oxe-execute.md +34 -0
- package/.cursor/commands/oxe-forensics.md +34 -0
- package/.cursor/commands/oxe-help.md +33 -0
- package/.cursor/commands/oxe-loop.md +34 -0
- package/.cursor/commands/oxe-milestone.md +34 -0
- package/.cursor/commands/oxe-next.md +33 -0
- package/.cursor/commands/oxe-obs.md +34 -0
- package/.cursor/commands/oxe-plan-agent.md +33 -0
- package/.cursor/commands/oxe-plan.md +34 -0
- package/.cursor/commands/oxe-project.md +34 -0
- package/.cursor/commands/oxe-quick.md +34 -0
- package/.cursor/commands/oxe-research.md +34 -0
- package/.cursor/commands/oxe-retro.md +34 -0
- package/.cursor/commands/oxe-review-pr.md +34 -0
- package/.cursor/commands/oxe-route.md +34 -0
- package/.cursor/commands/oxe-scan.md +34 -0
- package/.cursor/commands/oxe-security.md +34 -0
- package/.cursor/commands/oxe-session.md +34 -0
- package/.cursor/commands/oxe-skill.md +45 -0
- package/.cursor/commands/oxe-spec.md +34 -0
- package/.cursor/commands/oxe-ui-review.md +34 -0
- package/.cursor/commands/oxe-ui-spec.md +34 -0
- package/.cursor/commands/oxe-update.md +33 -0
- package/.cursor/commands/oxe-validate-gaps.md +34 -0
- package/.cursor/commands/oxe-verify.md +34 -0
- package/.cursor/commands/oxe-workstream.md +34 -0
- package/.cursor/commands/oxe.md +38 -2
- package/.github/copilot-instructions.md +20 -5
- package/.github/prompts/oxe-ask.prompt.md +33 -0
- package/.github/prompts/oxe-capabilities.prompt.md +33 -0
- package/.github/prompts/oxe-checkpoint.prompt.md +45 -12
- package/.github/prompts/oxe-compact.prompt.md +44 -11
- package/.github/prompts/oxe-dashboard.prompt.md +33 -0
- package/.github/prompts/oxe-debug.prompt.md +45 -12
- package/.github/prompts/oxe-discuss.prompt.md +33 -0
- package/.github/prompts/oxe-execute.prompt.md +45 -12
- package/.github/prompts/oxe-forensics.prompt.md +45 -12
- package/.github/prompts/oxe-help.prompt.md +42 -9
- package/.github/prompts/oxe-loop.prompt.md +45 -12
- package/.github/prompts/oxe-milestone.prompt.md +45 -12
- package/.github/prompts/oxe-next.prompt.md +42 -9
- package/.github/prompts/oxe-obs.prompt.md +45 -12
- package/.github/prompts/oxe-plan-agent.prompt.md +43 -10
- package/.github/prompts/oxe-plan.prompt.md +45 -12
- package/.github/prompts/oxe-project.prompt.md +45 -12
- package/.github/prompts/oxe-quick.prompt.md +45 -12
- package/.github/prompts/oxe-research.prompt.md +45 -12
- package/.github/prompts/oxe-retro.prompt.md +45 -12
- package/.github/prompts/oxe-review-pr.prompt.md +45 -12
- package/.github/prompts/oxe-route.prompt.md +45 -12
- package/.github/prompts/oxe-scan.prompt.md +45 -12
- package/.github/prompts/oxe-security.prompt.md +45 -12
- package/.github/prompts/oxe-session.prompt.md +33 -0
- package/.github/prompts/oxe-skill.prompt.md +45 -0
- package/.github/prompts/oxe-spec.prompt.md +45 -12
- package/.github/prompts/oxe-ui-review.prompt.md +45 -12
- package/.github/prompts/oxe-ui-spec.prompt.md +45 -12
- package/.github/prompts/oxe-update.prompt.md +44 -11
- package/.github/prompts/oxe-validate-gaps.prompt.md +45 -12
- package/.github/prompts/oxe-verify.prompt.md +45 -12
- package/.github/prompts/oxe-workstream.prompt.md +45 -12
- package/.github/prompts/oxe.prompt.md +45 -12
- package/AGENTS.md +6 -4
- package/CHANGELOG.md +45 -0
- package/README.md +38 -8
- package/bin/banner.txt +1 -1
- package/bin/lib/oxe-agent-install.cjs +69 -55
- package/bin/lib/oxe-context-engine.cjs +866 -0
- package/bin/lib/oxe-dashboard.cjs +605 -588
- package/bin/lib/oxe-operational.cjs +105 -0
- package/bin/lib/oxe-plugins.cjs +115 -0
- package/bin/lib/oxe-project-health.cjs +1139 -666
- package/bin/lib/oxe-runtime-semantics.cjs +459 -0
- package/bin/lib/oxe-security.cjs +64 -0
- package/bin/oxe-cc.js +615 -46
- package/commands/oxe/ask.md +33 -0
- package/commands/oxe/capabilities.md +33 -0
- package/commands/oxe/checkpoint.md +49 -16
- package/commands/oxe/compact.md +43 -10
- package/commands/oxe/dashboard.md +33 -0
- package/commands/oxe/debug.md +49 -16
- package/commands/oxe/discuss.md +33 -0
- package/commands/oxe/execute.md +49 -16
- package/commands/oxe/forensics.md +49 -16
- package/commands/oxe/help.md +44 -11
- package/commands/oxe/loop.md +50 -17
- package/commands/oxe/milestone.md +49 -16
- package/commands/oxe/next.md +45 -12
- package/commands/oxe/obs.md +49 -16
- package/commands/oxe/oxe.md +49 -16
- package/commands/oxe/plan-agent.md +48 -15
- package/commands/oxe/plan.md +48 -15
- package/commands/oxe/project.md +49 -16
- package/commands/oxe/quick.md +49 -16
- package/commands/oxe/research.md +49 -16
- package/commands/oxe/retro.md +49 -16
- package/commands/oxe/review-pr.md +49 -16
- package/commands/oxe/route.md +44 -11
- package/commands/oxe/scan.md +49 -16
- package/commands/oxe/security.md +49 -16
- package/commands/oxe/session.md +33 -0
- package/commands/oxe/skill.md +49 -0
- package/commands/oxe/spec.md +47 -14
- package/commands/oxe/ui-review.md +49 -16
- package/commands/oxe/ui-spec.md +49 -16
- package/commands/oxe/update.md +49 -16
- package/commands/oxe/validate-gaps.md +49 -16
- package/commands/oxe/verify.md +48 -15
- package/commands/oxe/workstream.md +49 -16
- package/lib/sdk/index.cjs +140 -7
- package/lib/sdk/index.d.ts +266 -1
- package/oxe/templates/HYPOTHESES.template.md +33 -0
- package/oxe/templates/PLAN.template.md +53 -22
- package/oxe/templates/SESSION.template.md +2 -0
- package/oxe/templates/SKILL.template.md +26 -0
- package/oxe/templates/WORKFLOW_AUTHORING.md +18 -2
- package/oxe/templates/config.template.json +16 -14
- package/oxe/workflows/ask.md +28 -7
- package/oxe/workflows/capabilities.md +2 -0
- package/oxe/workflows/dashboard.md +12 -2
- package/oxe/workflows/debug.md +9 -4
- package/oxe/workflows/discuss.md +12 -6
- package/oxe/workflows/execute.md +34 -12
- package/oxe/workflows/forensics.md +14 -9
- package/oxe/workflows/help.md +20 -9
- package/oxe/workflows/loop.md +13 -7
- package/oxe/workflows/next.md +6 -4
- package/oxe/workflows/plan-agent.md +3 -2
- package/oxe/workflows/plan.md +26 -3
- package/oxe/workflows/quick.md +10 -3
- package/oxe/workflows/references/reasoning-discovery.md +28 -0
- package/oxe/workflows/references/reasoning-execution.md +29 -0
- package/oxe/workflows/references/reasoning-planning.md +32 -0
- package/oxe/workflows/references/reasoning-review.md +29 -0
- package/oxe/workflows/references/reasoning-status.md +24 -0
- package/oxe/workflows/references/workflow-runtime-contracts.json +879 -0
- package/oxe/workflows/research.md +8 -2
- package/oxe/workflows/retro.md +7 -2
- package/oxe/workflows/review-pr.md +12 -8
- package/oxe/workflows/route.md +16 -13
- package/oxe/workflows/security.md +3 -2
- package/oxe/workflows/session.md +44 -0
- package/oxe/workflows/skill.md +44 -0
- package/oxe/workflows/spec.md +21 -18
- package/oxe/workflows/ui-review.md +13 -7
- package/oxe/workflows/update.md +3 -1
- package/oxe/workflows/validate-gaps.md +12 -6
- package/oxe/workflows/verify-audit.md +73 -0
- package/oxe/workflows/verify.md +40 -16
- package/package.json +4 -3
package/bin/oxe-cc.js
CHANGED
|
@@ -21,6 +21,9 @@ const oxeNpmVersion = require(path.join(__dirname, 'lib', 'oxe-npm-version.cjs')
|
|
|
21
21
|
const oxeDashboard = require(path.join(__dirname, 'lib', 'oxe-dashboard.cjs'));
|
|
22
22
|
const oxeOperational = require(path.join(__dirname, 'lib', 'oxe-operational.cjs'));
|
|
23
23
|
const oxeAzure = require(path.join(__dirname, 'lib', 'oxe-azure.cjs'));
|
|
24
|
+
const oxePlugins = require(path.join(__dirname, 'lib', 'oxe-plugins.cjs'));
|
|
25
|
+
const oxeContext = require(path.join(__dirname, 'lib', 'oxe-context-engine.cjs'));
|
|
26
|
+
const oxeRuntimeSemantics = require(path.join(__dirname, 'lib', 'oxe-runtime-semantics.cjs'));
|
|
24
27
|
|
|
25
28
|
/** Merge markers for ~/.copilot/copilot-instructions.md (bloco OXE). */
|
|
26
29
|
const OXE_INST_BEGIN = '<!-- oxe-cc:install-begin -->';
|
|
@@ -162,7 +165,7 @@ function buildInstallSummary(opts, fullLayout) {
|
|
|
162
165
|
}
|
|
163
166
|
if (opts.copilot) {
|
|
164
167
|
bullets.push(
|
|
165
|
-
`${prefix}Copilot (VS Code):
|
|
168
|
+
`${prefix}Copilot (VS Code): integração workspace-first em ${displayPathForUser(copilotInstructionsPath(opts))} + ${displayPathForUser(copilotPromptsDirPath(opts))}`
|
|
166
169
|
);
|
|
167
170
|
}
|
|
168
171
|
if (opts.copilotCli && !opts.allAgents) {
|
|
@@ -249,7 +252,12 @@ function buildUninstallFooter(u) {
|
|
|
249
252
|
const p = u.dryRun ? '[simulação] ' : '';
|
|
250
253
|
const rm = u.dryRun ? 'Seriam removidos' : 'Removidos';
|
|
251
254
|
if (u.cursor) bullets.push(`${p}${rm} artefatos OXE em ~/.cursor (comandos e regras).`);
|
|
252
|
-
if (u.copilot)
|
|
255
|
+
if (u.copilot) {
|
|
256
|
+
bullets.push(`${p}${rm} prompt files OXE em .github/prompts/ e o bloco OXE em .github/copilot-instructions.md.`);
|
|
257
|
+
}
|
|
258
|
+
if (u.copilotLegacyClean) {
|
|
259
|
+
bullets.push(`${p}${rm} apenas o legado global do Copilot VS Code em ~/.copilot/ (prompts oxe-* e bloco OXE global).`);
|
|
260
|
+
}
|
|
253
261
|
if (u.copilotCli || u.allAgents) {
|
|
254
262
|
bullets.push(`${p}${rm} comandos oxe-* em ~/.claude/commands e ~/.copilot/commands.`);
|
|
255
263
|
bullets.push(`${p}${rm} skills OXE (marcadas oxe-cc) em ~/.copilot/skills/oxe*/.`);
|
|
@@ -356,7 +364,7 @@ function parseInstallArgs(argv) {
|
|
|
356
364
|
out.ideLocal = true;
|
|
357
365
|
out.explicitIdeScope = true;
|
|
358
366
|
} else if (a === '--cursor') out.cursor = true;
|
|
359
|
-
else if (a === '--copilot') out.copilot = true;
|
|
367
|
+
else if (a === '--copilot' || a === '--copilot-vscode') out.copilot = true;
|
|
360
368
|
else if (a === '--copilot-cli') out.copilotCli = true;
|
|
361
369
|
else if (a === '--all-agents') out.allAgents = true;
|
|
362
370
|
else if (a === '--opencode') out.agentOpenCode = true;
|
|
@@ -403,7 +411,10 @@ function parseInstallArgs(argv) {
|
|
|
403
411
|
out.conflictFlags = '--config-dir não combina com --oxe-only nem com --all-agents';
|
|
404
412
|
} else {
|
|
405
413
|
const ideCount = [out.cursor, out.copilot, out.copilotCli].filter(Boolean).length;
|
|
406
|
-
if (
|
|
414
|
+
if (out.copilot && !out.cursor && !out.copilotCli) {
|
|
415
|
+
out.conflictFlags =
|
|
416
|
+
'--config-dir não combina com --copilot porque o GitHub Copilot no VS Code usa .github/ no workspace';
|
|
417
|
+
} else if (ideCount !== 1) {
|
|
407
418
|
out.conflictFlags =
|
|
408
419
|
'--config-dir exige exatamente um entre --cursor, --copilot e --copilot-cli (e não combina com --oxe-only)';
|
|
409
420
|
}
|
|
@@ -557,24 +568,38 @@ function installClaudeBase(opts) {
|
|
|
557
568
|
return claudeUserDir(opts);
|
|
558
569
|
}
|
|
559
570
|
|
|
560
|
-
/** Ficheiro copilot-instructions (VS Code):
|
|
571
|
+
/** Ficheiro copilot-instructions (VS Code): sempre no workspace (.github/). */
|
|
561
572
|
function copilotInstructionsPath(opts) {
|
|
562
573
|
const target = path.resolve(opts.dir);
|
|
563
|
-
|
|
564
|
-
return path.join(target, '.github', 'copilot-instructions.md');
|
|
565
|
-
}
|
|
566
|
-
return path.join(copilotUserDir(opts), 'copilot-instructions.md');
|
|
574
|
+
return path.join(target, '.github', 'copilot-instructions.md');
|
|
567
575
|
}
|
|
568
576
|
|
|
569
|
-
/** Pasta de
|
|
577
|
+
/** Pasta de prompt files do Copilot VS Code: sempre no workspace (.github/prompts). */
|
|
570
578
|
function copilotPromptsDirPath(opts) {
|
|
571
579
|
const target = path.resolve(opts.dir);
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
580
|
+
return path.join(target, '.github', 'prompts');
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/** Artefato de auditoria da integração Copilot VS Code. */
|
|
584
|
+
function copilotWorkspaceManifestPath(opts) {
|
|
585
|
+
return path.join(path.resolve(opts.dir), '.oxe', 'install', 'copilot-vscode.json');
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
/** Artefato de auditoria da semântica multi-runtime. */
|
|
589
|
+
function runtimeSemanticsManifestPath(opts) {
|
|
590
|
+
return path.join(path.resolve(opts.dir), '.oxe', 'install', 'runtime-semantics.json');
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/** Integração legado do Copilot VS Code em ~/.copilot/. */
|
|
594
|
+
function copilotLegacyPromptDir(opts) {
|
|
575
595
|
return path.join(copilotUserDir(opts), 'prompts');
|
|
576
596
|
}
|
|
577
597
|
|
|
598
|
+
/** Integração legado do Copilot VS Code em ~/.copilot/. */
|
|
599
|
+
function copilotLegacyInstructionsPath(opts) {
|
|
600
|
+
return path.join(copilotUserDir(opts), 'copilot-instructions.md');
|
|
601
|
+
}
|
|
602
|
+
|
|
578
603
|
/** Layout “clássico”: pasta `oxe/` na raiz do repo. Caso contrário: só `.oxe/` (workflows em `.oxe/workflows`). */
|
|
579
604
|
function useFullRepoLayout(opts) {
|
|
580
605
|
return opts.installAssetsGlobal === true;
|
|
@@ -655,6 +680,114 @@ function installMergedCopilotInstructions(srcPath, destPath, opts, idePathRewrit
|
|
|
655
680
|
fs.writeFileSync(destPath, merged, 'utf8');
|
|
656
681
|
}
|
|
657
682
|
|
|
683
|
+
/**
|
|
684
|
+
* @param {InstallOpts} opts
|
|
685
|
+
* @param {{ layout: 'nested' | 'classic' }} info
|
|
686
|
+
*/
|
|
687
|
+
function writeCopilotVsCodeManifest(opts, info) {
|
|
688
|
+
const promptsDir = copilotPromptsDirPath(opts);
|
|
689
|
+
const instructionsPath = copilotInstructionsPath(opts);
|
|
690
|
+
const manifestPath = copilotWorkspaceManifestPath(opts);
|
|
691
|
+
const promptFiles = fs.existsSync(promptsDir)
|
|
692
|
+
? fs
|
|
693
|
+
.readdirSync(promptsDir, { withFileTypes: true })
|
|
694
|
+
.filter((entry) => entry.isFile() && /^oxe-.*\.prompt\.md$/i.test(entry.name))
|
|
695
|
+
.map((entry) => entry.name)
|
|
696
|
+
.sort()
|
|
697
|
+
: [];
|
|
698
|
+
const payload = {
|
|
699
|
+
schema_version: 1,
|
|
700
|
+
target: 'copilot-vscode',
|
|
701
|
+
synced_at: new Date().toISOString(),
|
|
702
|
+
oxe_version: readPkgVersion(),
|
|
703
|
+
layout: info.layout,
|
|
704
|
+
instructions_path: path.relative(path.resolve(opts.dir), instructionsPath).replace(/\\/g, '/'),
|
|
705
|
+
prompt_files: promptFiles,
|
|
706
|
+
hashes: {},
|
|
707
|
+
};
|
|
708
|
+
if (fs.existsSync(instructionsPath)) {
|
|
709
|
+
payload.hashes[payload.instructions_path] = oxeManifest.sha256File(instructionsPath);
|
|
710
|
+
}
|
|
711
|
+
for (const name of promptFiles) {
|
|
712
|
+
const rel = path.posix.join('.github', 'prompts', name);
|
|
713
|
+
payload.hashes[rel] = oxeManifest.sha256File(path.join(promptsDir, name));
|
|
714
|
+
}
|
|
715
|
+
ensureDir(path.dirname(manifestPath));
|
|
716
|
+
fs.writeFileSync(manifestPath, JSON.stringify(payload, null, 2) + '\n', 'utf8');
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
* @param {InstallOpts} opts
|
|
721
|
+
* @param {{ layout: 'nested' | 'classic' }} info
|
|
722
|
+
*/
|
|
723
|
+
function writeRuntimeSemanticsManifest(opts, info) {
|
|
724
|
+
const target = path.resolve(opts.dir);
|
|
725
|
+
const manifestPath = runtimeSemanticsManifestPath(opts);
|
|
726
|
+
const audit = oxeRuntimeSemantics.auditRuntimeTargets(target);
|
|
727
|
+
const wrappers = {};
|
|
728
|
+
const collectWrapper = (name, root, nameFilter) => {
|
|
729
|
+
if (!fs.existsSync(root)) return;
|
|
730
|
+
const files = oxeManifest.collectFilesRecursive(root, nameFilter);
|
|
731
|
+
wrappers[name] = {
|
|
732
|
+
path: path.relative(target, root).replace(/\\/g, '/'),
|
|
733
|
+
files: files
|
|
734
|
+
.map((filePath) => ({
|
|
735
|
+
path: path.relative(target, filePath).replace(/\\/g, '/'),
|
|
736
|
+
hash: oxeManifest.sha256File(filePath),
|
|
737
|
+
}))
|
|
738
|
+
.sort((a, b) => a.path.localeCompare(b.path)),
|
|
739
|
+
};
|
|
740
|
+
};
|
|
741
|
+
collectWrapper('commands', path.join(target, 'commands', 'oxe'), (name) => name.endsWith('.md'));
|
|
742
|
+
collectWrapper(
|
|
743
|
+
'copilot_prompts',
|
|
744
|
+
path.join(target, '.github', 'prompts'),
|
|
745
|
+
(name) => (name === 'oxe.prompt.md' || name.startsWith('oxe-')) && name.endsWith('.prompt.md')
|
|
746
|
+
);
|
|
747
|
+
collectWrapper(
|
|
748
|
+
'cursor_commands',
|
|
749
|
+
path.join(target, '.cursor', 'commands'),
|
|
750
|
+
(name) => (name === 'oxe.md' || name.startsWith('oxe-')) && name.endsWith('.md')
|
|
751
|
+
);
|
|
752
|
+
const payload = {
|
|
753
|
+
schema_version: 1,
|
|
754
|
+
target: 'runtime-semantics',
|
|
755
|
+
synced_at: new Date().toISOString(),
|
|
756
|
+
oxe_version: readPkgVersion(),
|
|
757
|
+
contract_version: oxeRuntimeSemantics.CONTRACT_VERSION,
|
|
758
|
+
layout: info.layout,
|
|
759
|
+
installed_runtimes: {
|
|
760
|
+
cursor: Boolean(opts.cursor),
|
|
761
|
+
copilot_vscode: Boolean(opts.copilot),
|
|
762
|
+
copilot_cli: Boolean(opts.copilotCli || opts.allAgents),
|
|
763
|
+
opencode: Boolean(opts.agentOpenCode || opts.allAgents),
|
|
764
|
+
gemini: Boolean(opts.agentGemini || opts.allAgents),
|
|
765
|
+
codex: Boolean(opts.agentCodex || opts.allAgents),
|
|
766
|
+
windsurf: Boolean(opts.agentWindsurf || opts.allAgents),
|
|
767
|
+
antigravity: Boolean(opts.agentAntigravity || opts.allAgents),
|
|
768
|
+
},
|
|
769
|
+
semantics_hashes: Object.fromEntries(
|
|
770
|
+
oxeRuntimeSemantics.getAllWorkflowContracts().map((contract) => [
|
|
771
|
+
contract.workflow_slug,
|
|
772
|
+
oxeRuntimeSemantics.computeSemanticsHash(contract.workflow_slug),
|
|
773
|
+
])
|
|
774
|
+
),
|
|
775
|
+
wrappers,
|
|
776
|
+
audit: {
|
|
777
|
+
ok: audit.ok,
|
|
778
|
+
warnings: audit.warnings,
|
|
779
|
+
mismatches: audit.mismatches.map((entry) => ({
|
|
780
|
+
target: entry.target,
|
|
781
|
+
slug: entry.slug,
|
|
782
|
+
file: path.relative(target, entry.file).replace(/\\/g, '/'),
|
|
783
|
+
issues: entry.issues,
|
|
784
|
+
})),
|
|
785
|
+
},
|
|
786
|
+
};
|
|
787
|
+
ensureDir(path.dirname(manifestPath));
|
|
788
|
+
fs.writeFileSync(manifestPath, JSON.stringify(payload, null, 2) + '\n', 'utf8');
|
|
789
|
+
}
|
|
790
|
+
|
|
658
791
|
function canInstallPrompt() {
|
|
659
792
|
return (
|
|
660
793
|
process.stdin.isTTY === true &&
|
|
@@ -1024,6 +1157,10 @@ function bootstrapOxe(target, opts) {
|
|
|
1024
1157
|
const capabilitiesDir = path.join(oxeDir, 'capabilities');
|
|
1025
1158
|
const investigationsDir = path.join(oxeDir, 'investigations');
|
|
1026
1159
|
const dashboardDir = path.join(oxeDir, 'dashboard');
|
|
1160
|
+
const contextDir = path.join(oxeDir, 'context');
|
|
1161
|
+
const contextPacksDir = path.join(contextDir, 'packs');
|
|
1162
|
+
const contextSummariesDir = path.join(contextDir, 'summaries');
|
|
1163
|
+
const installDir = path.join(oxeDir, 'install');
|
|
1027
1164
|
const stateSrc = path.join(PKG_ROOT, 'oxe', 'templates', 'STATE.md');
|
|
1028
1165
|
const stateDest = path.join(oxeDir, 'STATE.md');
|
|
1029
1166
|
const configSrc = path.join(PKG_ROOT, 'oxe', 'templates', 'config.template.json');
|
|
@@ -1035,7 +1172,7 @@ function bootstrapOxe(target, opts) {
|
|
|
1035
1172
|
}
|
|
1036
1173
|
|
|
1037
1174
|
if (opts.dryRun) {
|
|
1038
|
-
console.log(`${dim}init${reset} ${oxeDir}/ (STATE.md, config.json, codebase/, capabilities/, investigations/, dashboard/, runs/, OXE-EVENTS.ndjson, ACTIVE-RUN.json)`);
|
|
1175
|
+
console.log(`${dim}init${reset} ${oxeDir}/ (STATE.md, config.json, codebase/, capabilities/, investigations/, dashboard/, context/, install/, runs/, OXE-EVENTS.ndjson, ACTIVE-RUN.json)`);
|
|
1039
1176
|
ensureGitignoreIgnoresOxeDir(target, { dryRun: true });
|
|
1040
1177
|
return;
|
|
1041
1178
|
}
|
|
@@ -1044,6 +1181,9 @@ function bootstrapOxe(target, opts) {
|
|
|
1044
1181
|
ensureDir(capabilitiesDir);
|
|
1045
1182
|
ensureDir(investigationsDir);
|
|
1046
1183
|
ensureDir(dashboardDir);
|
|
1184
|
+
ensureDir(contextPacksDir);
|
|
1185
|
+
ensureDir(contextSummariesDir);
|
|
1186
|
+
ensureDir(installDir);
|
|
1047
1187
|
|
|
1048
1188
|
if (!fs.existsSync(stateDest) || opts.force) {
|
|
1049
1189
|
copyFile(stateSrc, stateDest, { dryRun: false });
|
|
@@ -1248,21 +1388,42 @@ function printOxeHealthDiagnostics(target, c, diagOpts = {}) {
|
|
|
1248
1388
|
if (r.activeSession) {
|
|
1249
1389
|
console.log(` ${c ? dim : ''}Sessão ativa:${c ? reset : ''} ${r.activeSession}`);
|
|
1250
1390
|
}
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1391
|
+
if (r.planReviewStatus) {
|
|
1392
|
+
console.log(` ${c ? dim : ''}Revisão do plano:${c ? reset : ''} ${r.planReviewStatus}`);
|
|
1393
|
+
}
|
|
1394
|
+
if (r.activeRun && r.activeRun.run_id) {
|
|
1395
|
+
console.log(` ${c ? dim : ''}Run ativo:${c ? reset : ''} ${r.activeRun.run_id} (${r.activeRun.status || 'planned'})`);
|
|
1396
|
+
}
|
|
1397
|
+
if (r.eventsSummary) {
|
|
1398
|
+
console.log(` ${c ? dim : ''}Tracing:${c ? reset : ''} ${r.eventsSummary.total} evento(s)`);
|
|
1399
|
+
}
|
|
1260
1400
|
if (r.planSelfEvaluation && r.planSelfEvaluation.hasSection) {
|
|
1261
1401
|
const best = r.planSelfEvaluation.bestPlan || '—';
|
|
1262
1402
|
const conf =
|
|
1263
1403
|
typeof r.planSelfEvaluation.confidence === 'number' ? `${r.planSelfEvaluation.confidence}%` : '—';
|
|
1264
1404
|
console.log(` ${c ? dim : ''}Plano (autoavaliação):${c ? reset : ''} melhor=${best} | confiança=${conf}`);
|
|
1265
1405
|
}
|
|
1406
|
+
if (r.contextQuality) {
|
|
1407
|
+
console.log(
|
|
1408
|
+
` ${c ? dim : ''}Contexto:${c ? reset : ''} score=${r.contextQuality.primaryScore != null ? r.contextQuality.primaryScore : '—'} | workflow=${r.contextQuality.primaryWorkflow || '—'} | status=${r.contextQuality.primaryStatus || '—'}`
|
|
1409
|
+
);
|
|
1410
|
+
}
|
|
1411
|
+
if (r.semanticsDrift) {
|
|
1412
|
+
console.log(` ${c ? dim : ''}Semântica multi-runtime:${c ? reset : ''} ${r.semanticsDrift.ok ? 'alinhada' : 'com drift'}`);
|
|
1413
|
+
}
|
|
1414
|
+
if (r.copilot && (r.copilot.detected || r.copilot.warnings.length)) {
|
|
1415
|
+
const promptSource =
|
|
1416
|
+
r.copilot.promptSource === 'workspace'
|
|
1417
|
+
? '.github/prompts/'
|
|
1418
|
+
: r.copilot.promptSource === 'legacy_global'
|
|
1419
|
+
? '~/.copilot/prompts/ (legado)'
|
|
1420
|
+
: 'ausente';
|
|
1421
|
+
console.log(` ${c ? dim : ''}Copilot VS Code:${c ? reset : ''} target=workspace | source=${promptSource}`);
|
|
1422
|
+
console.log(` ${c ? dim : ''}Copilot workspace:${c ? reset : ''} ${displayPathForUser(r.copilot.workspace.promptsDir)}`);
|
|
1423
|
+
if (r.copilot.legacy.detected) {
|
|
1424
|
+
console.log(` ${c ? dim : ''}Legado global:${c ? reset : ''} ${displayPathForUser(r.copilot.legacy.root)}`);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1266
1427
|
if (r.azureActive && r.azure) {
|
|
1267
1428
|
console.log(` ${c ? dim : ''}Azure:${c ? reset : ''} ${r.azure.authStatus && r.azure.authStatus.login_active ? 'login ativo' : 'sem login'} | subscription=${r.azure.profile && (r.azure.profile.subscription_name || r.azure.profile.subscription_id) || '—'}`);
|
|
1268
1429
|
console.log(` ${c ? dim : ''}Azure inventory:${c ? reset : ''} total=${r.azure.inventorySummary ? r.azure.inventorySummary.total : 0} | pendências=${r.azure.pendingOperations || 0}`);
|
|
@@ -1328,6 +1489,15 @@ function printOxeHealthDiagnostics(target, c, diagOpts = {}) {
|
|
|
1328
1489
|
for (const w of r.installWarn) {
|
|
1329
1490
|
console.log(` ${yellow}AVISO${reset} ${w}`);
|
|
1330
1491
|
}
|
|
1492
|
+
for (const w of r.copilotWarn) {
|
|
1493
|
+
console.log(` ${yellow}AVISO${reset} ${w}`);
|
|
1494
|
+
}
|
|
1495
|
+
for (const w of r.contextWarn || []) {
|
|
1496
|
+
console.log(` ${yellow}AVISO${reset} ${w}`);
|
|
1497
|
+
}
|
|
1498
|
+
for (const w of r.semanticsWarn || []) {
|
|
1499
|
+
console.log(` ${yellow}AVISO${reset} ${w}`);
|
|
1500
|
+
}
|
|
1331
1501
|
if (r.summaryGapWarn) {
|
|
1332
1502
|
console.log(` ${yellow}AVISO${reset} ${r.summaryGapWarn}`);
|
|
1333
1503
|
}
|
|
@@ -1371,6 +1541,17 @@ function runStatusFull(target) {
|
|
|
1371
1541
|
const healthColor = report.healthStatus === 'healthy' ? green : report.healthStatus === 'warning' ? yellow : red;
|
|
1372
1542
|
console.log(` ${c ? green : ''}Saúde:${c ? reset : ''} ${c ? healthColor : ''}${report.healthStatus}${c ? reset : ''}`);
|
|
1373
1543
|
|
|
1544
|
+
if (report.copilot && (report.copilot.detected || report.copilot.warnings.length)) {
|
|
1545
|
+
console.log(`\n ${c ? yellow : ''}Copilot VS Code${c ? reset : ''}`);
|
|
1546
|
+
console.log(` ${c ? dim : ''}Target:${c ? reset : ''} workspace (.github/)`);
|
|
1547
|
+
console.log(` ${c ? dim : ''}Source:${c ? reset : ''} ${report.copilot.promptSource}`);
|
|
1548
|
+
console.log(` ${c ? dim : ''}Workspace prompts:${c ? reset : ''} ${displayPathForUser(report.copilot.workspace.promptsDir)}`);
|
|
1549
|
+
console.log(` ${c ? dim : ''}Legado global:${c ? reset : ''} ${report.copilot.legacy.detected ? 'detectado' : 'não'}`);
|
|
1550
|
+
for (const warning of report.copilotWarn.slice(0, 3)) {
|
|
1551
|
+
console.log(` ${c ? yellow : ''} • ${warning}${c ? reset : ''}`);
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1374
1555
|
// Coverage matrix
|
|
1375
1556
|
const specPath = activeSession && sp.spec ? sp.spec : p.spec;
|
|
1376
1557
|
const planPath = activeSession && sp.plan ? sp.plan : p.plan;
|
|
@@ -1404,6 +1585,18 @@ function runStatusFull(target) {
|
|
|
1404
1585
|
console.log(` ${c ? dim : ''}Run:${c ? reset : ''} ${ar.run_id || '—'} ${c ? dim : ''}Estado:${c ? reset : ''} ${ar.status || '—'} ${c ? dim : ''}Onda:${c ? reset : ''} ${ar.current_wave != null ? ar.current_wave : '—'}`);
|
|
1405
1586
|
}
|
|
1406
1587
|
|
|
1588
|
+
if (report.contextQuality || report.semanticsDrift) {
|
|
1589
|
+
const primaryWorkflow = report.contextQuality && report.contextQuality.primaryWorkflow ? report.contextQuality.primaryWorkflow : 'dashboard';
|
|
1590
|
+
const primaryScore = report.contextQuality && report.contextQuality.primaryScore != null ? report.contextQuality.primaryScore : null;
|
|
1591
|
+
const primaryStatus = report.contextQuality && report.contextQuality.primaryStatus ? report.contextQuality.primaryStatus : '—';
|
|
1592
|
+
const freshness = report.packFreshness && report.packFreshness[primaryWorkflow] ? report.packFreshness[primaryWorkflow] : null;
|
|
1593
|
+
console.log(`\n ${c ? yellow : ''}Contexto e semântica${c ? reset : ''}`);
|
|
1594
|
+
console.log(` ${c ? dim : ''}Pack primário:${c ? reset : ''} ${primaryWorkflow}`);
|
|
1595
|
+
console.log(` ${c ? dim : ''}Qualidade:${c ? reset : ''} ${primaryScore != null ? `${primaryScore} (${primaryStatus})` : '—'}`);
|
|
1596
|
+
console.log(` ${c ? dim : ''}Freshness:${c ? reset : ''} ${freshness ? `${freshness.reason}${freshness.pack_age_hours != null ? ` · ${freshness.pack_age_hours}h` : ''}` : '—'}`);
|
|
1597
|
+
console.log(` ${c ? dim : ''}Drift semântico:${c ? reset : ''} ${report.semanticsDrift && report.semanticsDrift.ok ? 'não detectado' : 'detectado'}`);
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1407
1600
|
// Plan self-evaluation
|
|
1408
1601
|
if (report.planSelfEvaluation) {
|
|
1409
1602
|
const pse = report.planSelfEvaluation;
|
|
@@ -1437,7 +1630,7 @@ function runStatus(target, opts = {}) {
|
|
|
1437
1630
|
if (opts.json) {
|
|
1438
1631
|
/** @type {Record<string, unknown>} */
|
|
1439
1632
|
const payload = {
|
|
1440
|
-
oxeStatusSchema:
|
|
1633
|
+
oxeStatusSchema: 3,
|
|
1441
1634
|
projectRoot: path.resolve(target),
|
|
1442
1635
|
nextStep: report.next.step,
|
|
1443
1636
|
cursorCmd: report.next.cursorCmd,
|
|
@@ -1454,9 +1647,15 @@ function runStatus(target, opts = {}) {
|
|
|
1454
1647
|
planReviewStatus: report.planReviewStatus,
|
|
1455
1648
|
activeRun: report.activeRun,
|
|
1456
1649
|
eventsSummary: report.eventsSummary,
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1650
|
+
memoryLayers: report.memoryLayers,
|
|
1651
|
+
azureActive: report.azureActive,
|
|
1652
|
+
azure: report.azure,
|
|
1653
|
+
copilot: report.copilot,
|
|
1654
|
+
contextPacks: report.contextPacks,
|
|
1655
|
+
contextQuality: report.contextQuality,
|
|
1656
|
+
semanticsDrift: report.semanticsDrift,
|
|
1657
|
+
packFreshness: report.packFreshness,
|
|
1658
|
+
activeSummaryRefs: report.activeSummaryRefs,
|
|
1460
1659
|
diagnostics: {
|
|
1461
1660
|
configParseError: report.configParseError,
|
|
1462
1661
|
typeErrors: report.typeErrors,
|
|
@@ -1468,6 +1667,9 @@ function runStatus(target, opts = {}) {
|
|
|
1468
1667
|
investigationWarnings: report.investigationWarn,
|
|
1469
1668
|
sessionWarnings: report.sessionWarn,
|
|
1470
1669
|
installWarnings: report.installWarn,
|
|
1670
|
+
copilotWarnings: report.copilotWarn,
|
|
1671
|
+
contextWarnings: report.contextWarn,
|
|
1672
|
+
semanticsWarnings: report.semanticsWarn,
|
|
1471
1673
|
summaryGapWarning: report.summaryGapWarn,
|
|
1472
1674
|
specWarnings: report.specWarn,
|
|
1473
1675
|
planWarnings: report.planWarn,
|
|
@@ -1580,6 +1782,20 @@ function runDoctor(target) {
|
|
|
1580
1782
|
}
|
|
1581
1783
|
}
|
|
1582
1784
|
|
|
1785
|
+
// Verificar workflows sem contrato no registry de semântica
|
|
1786
|
+
const allContractSlugs = new Set(oxeRuntimeSemantics.getAllWorkflowContracts().map((ct) => ct.workflow_slug));
|
|
1787
|
+
const workflowMdFiles = fs.readdirSync(wfTgt).filter((f) => f.endsWith('.md'));
|
|
1788
|
+
const orphanedWorkflows = workflowMdFiles
|
|
1789
|
+
.map((f) => f.replace(/\.md$/, ''))
|
|
1790
|
+
.filter((slug) => !allContractSlugs.has(slug));
|
|
1791
|
+
if (orphanedWorkflows.length) {
|
|
1792
|
+
for (const slug of orphanedWorkflows) {
|
|
1793
|
+
console.log(`${yellow}AVISO${reset} Workflow sem contrato semântico no registry: ${slug}.md — adicione em workflow-runtime-contracts.json ou rode \`npx oxe-cc update\`.`);
|
|
1794
|
+
}
|
|
1795
|
+
} else {
|
|
1796
|
+
console.log(`${green}OK${reset} Todos os workflows têm contrato semântico registado`);
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1583
1799
|
const oxeState = path.join(target, '.oxe', 'STATE.md');
|
|
1584
1800
|
if (fs.existsSync(oxeState)) console.log(`${green}OK${reset} .oxe/STATE.md encontrado`);
|
|
1585
1801
|
else {
|
|
@@ -1727,6 +1943,7 @@ function updateForwardedInstallFlags() {
|
|
|
1727
1943
|
return [
|
|
1728
1944
|
'--cursor',
|
|
1729
1945
|
'--copilot',
|
|
1946
|
+
'--copilot-vscode',
|
|
1730
1947
|
'--copilot-cli',
|
|
1731
1948
|
'--all-agents',
|
|
1732
1949
|
'--opencode',
|
|
@@ -1848,6 +2065,7 @@ ${green}Uso:${reset}
|
|
|
1848
2065
|
npx oxe-cc doctor [opções] [pasta-do-projeto]
|
|
1849
2066
|
npx oxe-cc status [opções] [pasta-do-projeto]
|
|
1850
2067
|
npx oxe-cc init-oxe [opções] [pasta-do-projeto]
|
|
2068
|
+
npx oxe-cc context <build|inspect> [opções] [pasta-do-projeto]
|
|
1851
2069
|
npx oxe-cc dashboard [opções] [pasta-do-projeto]
|
|
1852
2070
|
npx oxe-cc runtime <status|start|pause|resume|replay> [opções] [pasta-do-projeto]
|
|
1853
2071
|
npx oxe-cc azure <status|doctor|auth|sync|find|servicebus|eventgrid|sql|operations> [opções] [pasta-do-projeto]
|
|
@@ -1857,11 +2075,13 @@ ${green}Uso:${reset}
|
|
|
1857
2075
|
|
|
1858
2076
|
${green}uninstall${reset} (remove OXE da pasta do usuário + pastas de workflows no repo)
|
|
1859
2077
|
--cursor / --copilot / --copilot-cli só essa integração (omissão = todas)
|
|
2078
|
+
--copilot-vscode alias explícito de --copilot
|
|
2079
|
+
--copilot-legacy-clean limpa só o legado antigo do Copilot VS Code em ~/.copilot/
|
|
1860
2080
|
--all-agents também remove ficheiros multi-plataforma (com --copilot-cli implícito)
|
|
1861
2081
|
--ide-local remove integrações IDE neste repositório (.cursor, .github, .claude, .copilot, …)
|
|
1862
2082
|
--ide-only não apagar .oxe/workflows, oxe/, etc. no projeto
|
|
1863
2083
|
--global-cli, -g também executa npm uninstall -g oxe-cc
|
|
1864
|
-
--config-dir <caminho> com exatamente uma flag IDE acima (não combina com --ide-local)
|
|
2084
|
+
--config-dir <caminho> com exatamente uma flag IDE acima (não combina com --ide-local nem com --copilot)
|
|
1865
2085
|
--dry-run
|
|
1866
2086
|
--dir <pasta> raiz do projeto (padrão: diretório atual)
|
|
1867
2087
|
|
|
@@ -1880,6 +2100,15 @@ ${green}dashboard${reset} (interface web local para revisão e aprovação do pl
|
|
|
1880
2100
|
--dump-context imprime JSON consolidado e sai
|
|
1881
2101
|
--dir <pasta> raiz do projeto (padrão: diretório atual)
|
|
1882
2102
|
|
|
2103
|
+
${green}context${reset} (Context Engine V2: seleção, compressão e inspeção determinística)
|
|
2104
|
+
build [--workflow <slug>] gera pack(s) em .oxe/context/packs/
|
|
2105
|
+
inspect [--workflow <slug>] lê um pack existente ou resolve sob demanda
|
|
2106
|
+
--workflow <slug> workflow alvo (omissão: build=todos; inspect=dashboard)
|
|
2107
|
+
--tier <minimal|standard|full> tier de contexto (padrão: standard)
|
|
2108
|
+
--session <sessions/sNNN-slug> força sessão específica
|
|
2109
|
+
--json saída estruturada em JSON
|
|
2110
|
+
--dir <pasta> raiz do projeto (padrão: diretório atual)
|
|
2111
|
+
|
|
1883
2112
|
${green}runtime${reset} (controle operacional explícito do ACTIVE-RUN)
|
|
1884
2113
|
status mostra o run ativo resolvido para a sessão atual
|
|
1885
2114
|
start cria um novo run com tracing inicial
|
|
@@ -1936,13 +2165,14 @@ ${green}azure${reset} (provider Azure nativo via Azure CLI no Windows)
|
|
|
1936
2165
|
|
|
1937
2166
|
${green}Opções da instalação:${reset}
|
|
1938
2167
|
--cursor Copia comandos e regras para ~/.cursor (padrão com --all)
|
|
1939
|
-
--copilot
|
|
2168
|
+
--copilot Instala GitHub Copilot VS Code no workspace: .github/copilot-instructions.md + .github/prompts/
|
|
2169
|
+
--copilot-vscode Alias explícito de --copilot
|
|
1940
2170
|
--copilot-cli Skills em ~/.copilot/skills (/oxe, /oxe-scan, …) + cópia legado em ~/.claude/commands e ~/.copilot/commands
|
|
1941
2171
|
(subconjunto de --all-agents)
|
|
1942
2172
|
--all-agents Cursor+Copilot + CLIs + OpenCode, Gemini (TOML), Codex, Windsurf, Antigravity
|
|
1943
2173
|
--opencode / --gemini / --codex / --windsurf / --antigravity só esse agente (sem os outros)
|
|
1944
2174
|
--ide-global Instalar integrações IDE nas pastas do utilizador (~/.cursor, …) — predefinido
|
|
1945
|
-
--ide-local Instalar integrações IDE
|
|
2175
|
+
--ide-local Instalar integrações IDE locais quando suportado (.cursor, .claude, .copilot CLI, …); Copilot VS Code continua em .github/
|
|
1946
2176
|
--vscode Também copia .vscode/settings.json (chat.promptFiles)
|
|
1947
2177
|
--all, -a Cursor + Copilot (padrão se não passar --cursor nem --copilot)
|
|
1948
2178
|
--no-commands Não copia commands/oxe
|
|
@@ -1955,7 +2185,7 @@ ${green}Opções da instalação:${reset}
|
|
|
1955
2185
|
--no-global-cli, -l Não pergunta pelo CLI global (recomendado em CI)
|
|
1956
2186
|
--force, -f Sobrescreve arquivos existentes
|
|
1957
2187
|
--dry-run Lista ações sem gravar
|
|
1958
|
-
--config-dir, -c <pasta> Só com exatamente um de --cursor
|
|
2188
|
+
--config-dir, -c <pasta> Só com exatamente um de --cursor ou --copilot-cli (não use com --copilot nem --all-agents)
|
|
1959
2189
|
--no-install-config Ignora o bloco install em .oxe/config.json (só integração/layout vindos das flags ou do menu)
|
|
1960
2190
|
--dir <pasta> Pasta de destino (padrão: diretório atual)
|
|
1961
2191
|
-h, --help
|
|
@@ -2032,15 +2262,22 @@ function runInstall(opts) {
|
|
|
2032
2262
|
}
|
|
2033
2263
|
const ideAny = anyIdeIntegration(opts);
|
|
2034
2264
|
if (ideAny) {
|
|
2035
|
-
const
|
|
2036
|
-
|
|
2037
|
-
|
|
2265
|
+
const scopeParts = [];
|
|
2266
|
+
if (opts.cursor) {
|
|
2267
|
+
scopeParts.push(opts.ideLocal ? '.cursor no repositório' : '~/.cursor');
|
|
2268
|
+
}
|
|
2269
|
+
if (opts.copilot) {
|
|
2270
|
+
scopeParts.push('.github/ no repositório (Copilot VS Code)');
|
|
2271
|
+
}
|
|
2272
|
+
if (opts.copilotCli || opts.allAgents) {
|
|
2273
|
+
scopeParts.push(opts.ideLocal ? '.copilot/.claude no repositório (CLI)' : '~/.copilot + ~/.claude (CLI)');
|
|
2274
|
+
}
|
|
2038
2275
|
const extra = opts.allAgents
|
|
2039
2276
|
? `${c ? dim : ''} + OpenCode, Gemini, Codex, Windsurf, Antigravity${c ? reset : ''}`
|
|
2040
2277
|
: anyGranularAgent(opts)
|
|
2041
2278
|
? `${c ? dim : ''} + agentes selecionados${c ? reset : ''}`
|
|
2042
2279
|
: '';
|
|
2043
|
-
console.log(` ${c ? dim : ''}Integrações IDE:${c ? reset : ''} ${
|
|
2280
|
+
console.log(` ${c ? dim : ''}Integrações IDE:${c ? reset : ''} ${scopeParts.join('; ')}${extra}`);
|
|
2044
2281
|
}
|
|
2045
2282
|
|
|
2046
2283
|
const copyOpts = { dryRun: opts.dryRun, force: opts.force };
|
|
@@ -2143,6 +2380,9 @@ function runInstall(opts) {
|
|
|
2143
2380
|
if (fs.existsSync(prompts)) {
|
|
2144
2381
|
copyDir(prompts, copilotPromptsDirPath(opts), copyOpts, idePathRewrite);
|
|
2145
2382
|
}
|
|
2383
|
+
if (!opts.dryRun) {
|
|
2384
|
+
writeCopilotVsCodeManifest(opts, { layout: fullLayout ? 'classic' : 'nested' });
|
|
2385
|
+
}
|
|
2146
2386
|
}
|
|
2147
2387
|
|
|
2148
2388
|
if (opts.vscode && fullLayout) {
|
|
@@ -2176,6 +2416,10 @@ function runInstall(opts) {
|
|
|
2176
2416
|
if (!opts.noInitOxe) bootstrapOxe(target, { dryRun: opts.dryRun, force: opts.force });
|
|
2177
2417
|
else ensureGitignoreIgnoresOxeDir(target, { dryRun: opts.dryRun });
|
|
2178
2418
|
|
|
2419
|
+
if (!opts.dryRun) {
|
|
2420
|
+
writeRuntimeSemanticsManifest(opts, { layout: fullLayout ? 'classic' : 'nested' });
|
|
2421
|
+
}
|
|
2422
|
+
|
|
2179
2423
|
if (!opts.dryRun && (opts.cursor || opts.copilot || opts.copilotCli || opts.allAgents || anyGranularAgent(opts))) {
|
|
2180
2424
|
const nextFiles = {};
|
|
2181
2425
|
const addTracked = (root, nameFilter) => {
|
|
@@ -2212,7 +2456,9 @@ function runInstall(opts) {
|
|
|
2212
2456
|
}
|
|
2213
2457
|
}
|
|
2214
2458
|
addTracked(copilotPromptsDirPath(opts), (n) => n.startsWith('oxe-'));
|
|
2459
|
+
trackFile(copilotWorkspaceManifestPath(opts));
|
|
2215
2460
|
}
|
|
2461
|
+
trackFile(runtimeSemanticsManifestPath(opts));
|
|
2216
2462
|
if (opts.copilotCli || opts.allAgents) {
|
|
2217
2463
|
addTracked(path.join(installClaudeBase(opts), 'commands'), (n) => n.startsWith('oxe-') && n.endsWith('.md'));
|
|
2218
2464
|
addTracked(path.join(cpCliHome, 'commands'), (n) => n.startsWith('oxe-') && n.endsWith('.md'));
|
|
@@ -2278,10 +2524,23 @@ function runInstall(opts) {
|
|
|
2278
2524
|
}
|
|
2279
2525
|
|
|
2280
2526
|
printSummaryAndNextSteps(c, buildInstallSummary(opts, fullLayout));
|
|
2527
|
+
if (opts.copilot) {
|
|
2528
|
+
const copilotReport = oxeHealth.copilotIntegrationReport(target);
|
|
2529
|
+
if (copilotReport.legacy && copilotReport.legacy.detected) {
|
|
2530
|
+
console.log(
|
|
2531
|
+
` ${yellow}Nota:${reset} legado do Copilot VS Code detectado em ${c ? cyan : ''}${displayPathForUser(
|
|
2532
|
+
copilotReport.legacy.root
|
|
2533
|
+
)}${reset}. O OXE agora usa ${c ? cyan : ''}.github/${reset} no workspace para a IDE.`
|
|
2534
|
+
);
|
|
2535
|
+
console.log(
|
|
2536
|
+
` ${c ? dim : ''}Limpeza opcional:${c ? reset : ''} ${c ? cyan : ''}npx oxe-cc uninstall --copilot-legacy-clean --dir "${target}"${reset}`
|
|
2537
|
+
);
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2281
2540
|
console.log(` ${c ? green : ''}✓${c ? reset : ''} Instalação concluída com sucesso.\n`);
|
|
2282
2541
|
}
|
|
2283
2542
|
|
|
2284
|
-
/** @typedef {{ help: boolean, dryRun: boolean, cursor: boolean, copilot: boolean, copilotCli: boolean, allAgents: boolean, globalCli: boolean, ideLocal: boolean, ideExplicit: boolean, noProject: boolean, dir: string, explicitConfigDir: string | null, parseError: boolean, unknownFlag: string, conflictFlags: string }} UninstallOpts */
|
|
2543
|
+
/** @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 */
|
|
2285
2544
|
|
|
2286
2545
|
/**
|
|
2287
2546
|
* @param {UninstallOpts} u
|
|
@@ -2319,16 +2578,20 @@ function uninstallLocalIdeFromProject(u, removedPaths) {
|
|
|
2319
2578
|
if (u.copilot) {
|
|
2320
2579
|
const inst = path.join(proj, '.github', 'copilot-instructions.md');
|
|
2321
2580
|
stripOxeFromCopilotInstructions(inst, u);
|
|
2581
|
+
if (fs.existsSync(inst)) track(inst);
|
|
2322
2582
|
const pr = path.join(proj, '.github', 'prompts');
|
|
2323
2583
|
if (fs.existsSync(pr)) {
|
|
2324
2584
|
for (const name of fs.readdirSync(pr)) {
|
|
2325
|
-
if (
|
|
2585
|
+
if (/^oxe-.*\.prompt\.md$/i.test(name)) {
|
|
2326
2586
|
const p = path.join(pr, name);
|
|
2327
2587
|
unlinkQuiet(p, u);
|
|
2328
2588
|
track(p);
|
|
2329
2589
|
}
|
|
2330
2590
|
}
|
|
2331
2591
|
}
|
|
2592
|
+
const manifest = path.join(proj, '.oxe', 'install', 'copilot-vscode.json');
|
|
2593
|
+
unlinkQuiet(manifest, u);
|
|
2594
|
+
track(manifest);
|
|
2332
2595
|
}
|
|
2333
2596
|
|
|
2334
2597
|
if (u.copilotCli || u.allAgents) {
|
|
@@ -2375,6 +2638,12 @@ function uninstallLocalIdeFromProject(u, removedPaths) {
|
|
|
2375
2638
|
console.log(`${dim}agents${reset} (dry-run) limparia marcadores oxe-cc em pastas locais do projeto (OpenCode, Gemini, …)`);
|
|
2376
2639
|
}
|
|
2377
2640
|
}
|
|
2641
|
+
|
|
2642
|
+
if (u.cursor || u.copilot || u.copilotCli || u.allAgents) {
|
|
2643
|
+
const runtimeManifest = path.join(proj, '.oxe', 'install', 'runtime-semantics.json');
|
|
2644
|
+
unlinkQuiet(runtimeManifest, u);
|
|
2645
|
+
track(runtimeManifest);
|
|
2646
|
+
}
|
|
2378
2647
|
}
|
|
2379
2648
|
|
|
2380
2649
|
/**
|
|
@@ -2394,6 +2663,7 @@ function parseUninstallArgs(argv) {
|
|
|
2394
2663
|
ideLocal: false,
|
|
2395
2664
|
ideExplicit: false,
|
|
2396
2665
|
noProject: false,
|
|
2666
|
+
copilotLegacyClean: false,
|
|
2397
2667
|
dir: process.cwd(),
|
|
2398
2668
|
explicitConfigDir: null,
|
|
2399
2669
|
parseError: false,
|
|
@@ -2410,12 +2680,14 @@ function parseUninstallArgs(argv) {
|
|
|
2410
2680
|
} else if (a === '--cursor') {
|
|
2411
2681
|
out.cursor = true;
|
|
2412
2682
|
out.ideExplicit = true;
|
|
2413
|
-
} else if (a === '--copilot') {
|
|
2683
|
+
} else if (a === '--copilot' || a === '--copilot-vscode') {
|
|
2414
2684
|
out.copilot = true;
|
|
2415
2685
|
out.ideExplicit = true;
|
|
2416
2686
|
} else if (a === '--copilot-cli') {
|
|
2417
2687
|
out.copilotCli = true;
|
|
2418
2688
|
out.ideExplicit = true;
|
|
2689
|
+
} else if (a === '--copilot-legacy-clean') {
|
|
2690
|
+
out.copilotLegacyClean = true;
|
|
2419
2691
|
} else if (a === '--all-agents') {
|
|
2420
2692
|
out.allAgents = true;
|
|
2421
2693
|
out.copilotCli = true;
|
|
@@ -2433,16 +2705,21 @@ function parseUninstallArgs(argv) {
|
|
|
2433
2705
|
}
|
|
2434
2706
|
}
|
|
2435
2707
|
if (rest.length) out.dir = rest[0];
|
|
2436
|
-
if (!out.ideExplicit) {
|
|
2708
|
+
if (!out.ideExplicit && !out.copilotLegacyClean) {
|
|
2437
2709
|
out.cursor = true;
|
|
2438
2710
|
out.copilot = true;
|
|
2439
2711
|
out.copilotCli = true;
|
|
2712
|
+
} else if (out.copilotLegacyClean && !out.ideExplicit && !out.noProject) {
|
|
2713
|
+
out.noProject = true;
|
|
2440
2714
|
}
|
|
2441
2715
|
if (!out.conflictFlags && out.explicitConfigDir) {
|
|
2442
2716
|
if (out.ideLocal) {
|
|
2443
2717
|
out.conflictFlags = '--config-dir não combina com --ide-local';
|
|
2444
2718
|
} else if (out.allAgents) {
|
|
2445
2719
|
out.conflictFlags = '--config-dir não combina com --all-agents';
|
|
2720
|
+
} else if (out.copilot && !out.cursor && !out.copilotCli) {
|
|
2721
|
+
out.conflictFlags =
|
|
2722
|
+
'--config-dir não combina com --copilot porque o GitHub Copilot no VS Code usa .github/ no workspace';
|
|
2446
2723
|
} else {
|
|
2447
2724
|
const n = [out.cursor, out.copilot, out.copilotCli].filter(Boolean).length;
|
|
2448
2725
|
if (n !== 1) {
|
|
@@ -2474,6 +2751,25 @@ function stripOxeFromCopilotInstructions(destPath, opts) {
|
|
|
2474
2751
|
fs.writeFileSync(destPath, merged ? `${merged}\n` : '\n', 'utf8');
|
|
2475
2752
|
}
|
|
2476
2753
|
|
|
2754
|
+
/**
|
|
2755
|
+
* @param {InstallOpts} ideOpts
|
|
2756
|
+
* @param {UninstallOpts} opts
|
|
2757
|
+
* @param {string[]} removedPaths
|
|
2758
|
+
*/
|
|
2759
|
+
function cleanupLegacyCopilotVsCode(ideOpts, opts, removedPaths) {
|
|
2760
|
+
const inst = copilotLegacyInstructionsPath(ideOpts);
|
|
2761
|
+
stripOxeFromCopilotInstructions(inst, opts);
|
|
2762
|
+
if (fs.existsSync(inst)) removedPaths.push(inst);
|
|
2763
|
+
const pr = copilotLegacyPromptDir(ideOpts);
|
|
2764
|
+
if (!fs.existsSync(pr)) return;
|
|
2765
|
+
for (const name of fs.readdirSync(pr)) {
|
|
2766
|
+
if (!/^oxe-.*\.prompt\.md$/i.test(name)) continue;
|
|
2767
|
+
const promptPath = path.join(pr, name);
|
|
2768
|
+
unlinkQuiet(promptPath, opts);
|
|
2769
|
+
removedPaths.push(promptPath);
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2772
|
+
|
|
2477
2773
|
/**
|
|
2478
2774
|
* @param {string} filePath
|
|
2479
2775
|
* @param {{ dryRun: boolean }} opts
|
|
@@ -2574,19 +2870,26 @@ function runUninstall(u) {
|
|
|
2574
2870
|
}
|
|
2575
2871
|
|
|
2576
2872
|
if (u.copilot) {
|
|
2577
|
-
const
|
|
2578
|
-
const inst = path.join(root, 'copilot-instructions.md');
|
|
2873
|
+
const inst = path.join(u.dir, '.github', 'copilot-instructions.md');
|
|
2579
2874
|
stripOxeFromCopilotInstructions(inst, u);
|
|
2580
|
-
|
|
2875
|
+
if (fs.existsSync(inst)) removedPaths.push(inst);
|
|
2876
|
+
const pr = path.join(u.dir, '.github', 'prompts');
|
|
2581
2877
|
if (fs.existsSync(pr)) {
|
|
2582
2878
|
for (const name of fs.readdirSync(pr)) {
|
|
2583
|
-
if (
|
|
2879
|
+
if (/^oxe-.*\.prompt\.md$/i.test(name)) {
|
|
2584
2880
|
const p = path.join(pr, name);
|
|
2585
2881
|
unlinkQuiet(p, u);
|
|
2586
2882
|
removedPaths.push(p);
|
|
2587
2883
|
}
|
|
2588
2884
|
}
|
|
2589
2885
|
}
|
|
2886
|
+
const manifest = copilotWorkspaceManifestPath(ideOpts);
|
|
2887
|
+
unlinkQuiet(manifest, u);
|
|
2888
|
+
removedPaths.push(manifest);
|
|
2889
|
+
}
|
|
2890
|
+
|
|
2891
|
+
if (u.copilotLegacyClean) {
|
|
2892
|
+
cleanupLegacyCopilotVsCode(ideOpts, u, removedPaths);
|
|
2590
2893
|
}
|
|
2591
2894
|
|
|
2592
2895
|
if (u.copilotCli) {
|
|
@@ -2661,12 +2964,12 @@ function runUninstall(u) {
|
|
|
2661
2964
|
}
|
|
2662
2965
|
}
|
|
2663
2966
|
|
|
2664
|
-
if (!u.dryRun && (u.cursor || u.copilot || u.copilotCli)) {
|
|
2967
|
+
if (!u.dryRun && (u.cursor || u.copilot || u.copilotCli || u.copilotLegacyClean)) {
|
|
2665
2968
|
const prev = oxeManifest.loadFileManifest(home);
|
|
2666
2969
|
const next = { ...prev };
|
|
2667
2970
|
for (const p of removedPaths) delete next[p];
|
|
2668
2971
|
if (u.copilot) {
|
|
2669
|
-
const instPath = path.join(
|
|
2972
|
+
const instPath = path.join(u.dir, '.github', 'copilot-instructions.md');
|
|
2670
2973
|
if (fs.existsSync(instPath)) {
|
|
2671
2974
|
try {
|
|
2672
2975
|
next[instPath] = oxeManifest.sha256File(instPath);
|
|
@@ -2931,6 +3234,10 @@ function parseCapabilitiesArgs(argv) {
|
|
|
2931
3234
|
* @typedef {{ help: boolean, dir: string, port: number, noOpen: boolean, readOnly: boolean, dumpContext: boolean, activeSession: string|null, parseError: boolean, unknownFlag: string }} DashboardOpts
|
|
2932
3235
|
*/
|
|
2933
3236
|
|
|
3237
|
+
/**
|
|
3238
|
+
* @typedef {{ help: boolean, dir: string, action: 'build'|'inspect', workflow: string, tier: 'minimal'|'standard'|'full', activeSession: string|null, json: boolean, parseError: boolean, unknownFlag: string }} ContextOpts
|
|
3239
|
+
*/
|
|
3240
|
+
|
|
2934
3241
|
/**
|
|
2935
3242
|
* @typedef {{ help: boolean, dir: string, action: string, activeSession: string|null, wave: number|null, task: string, mode: string, reason: string, parseError: boolean, unknownFlag: string }} RuntimeOpts
|
|
2936
3243
|
*/
|
|
@@ -3008,6 +3315,49 @@ function parseDashboardArgs(argv) {
|
|
|
3008
3315
|
return out;
|
|
3009
3316
|
}
|
|
3010
3317
|
|
|
3318
|
+
/**
|
|
3319
|
+
* @param {string[]} argv
|
|
3320
|
+
* @returns {ContextOpts}
|
|
3321
|
+
*/
|
|
3322
|
+
function parseContextArgs(argv) {
|
|
3323
|
+
/** @type {ContextOpts} */
|
|
3324
|
+
const out = {
|
|
3325
|
+
help: false,
|
|
3326
|
+
dir: process.cwd(),
|
|
3327
|
+
action: 'build',
|
|
3328
|
+
workflow: '',
|
|
3329
|
+
tier: 'standard',
|
|
3330
|
+
activeSession: null,
|
|
3331
|
+
json: false,
|
|
3332
|
+
parseError: false,
|
|
3333
|
+
unknownFlag: '',
|
|
3334
|
+
};
|
|
3335
|
+
const positionals = [];
|
|
3336
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
3337
|
+
const a = argv[i];
|
|
3338
|
+
if (a === '-h' || a === '--help') out.help = true;
|
|
3339
|
+
else if (a === '--dir' && argv[i + 1]) out.dir = path.resolve(argv[++i]);
|
|
3340
|
+
else if (a === '--workflow' && argv[i + 1]) out.workflow = String(argv[++i]);
|
|
3341
|
+
else if (a === '--tier' && argv[i + 1]) {
|
|
3342
|
+
const tier = String(argv[++i]);
|
|
3343
|
+
out.tier = ['minimal', 'standard', 'full'].includes(tier) ? /** @type {'minimal'|'standard'|'full'} */ (tier) : 'standard';
|
|
3344
|
+
}
|
|
3345
|
+
else if (a === '--session' && argv[i + 1]) out.activeSession = String(argv[++i]).replace(/\\/g, '/');
|
|
3346
|
+
else if (a === '--json') out.json = true;
|
|
3347
|
+
else if (!a.startsWith('-')) positionals.push(a);
|
|
3348
|
+
else {
|
|
3349
|
+
out.parseError = true;
|
|
3350
|
+
out.unknownFlag = a;
|
|
3351
|
+
break;
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3354
|
+
if (positionals[0] === 'build' || positionals[0] === 'inspect') {
|
|
3355
|
+
out.action = /** @type {'build'|'inspect'} */ (positionals[0]);
|
|
3356
|
+
}
|
|
3357
|
+
if (!out.workflow && positionals[1]) out.workflow = String(positionals[1]);
|
|
3358
|
+
return out;
|
|
3359
|
+
}
|
|
3360
|
+
|
|
3011
3361
|
/**
|
|
3012
3362
|
* @param {string[]} argv
|
|
3013
3363
|
* @returns {RuntimeOpts}
|
|
@@ -3023,6 +3373,9 @@ function parseRuntimeArgs(argv) {
|
|
|
3023
3373
|
task: '',
|
|
3024
3374
|
mode: '',
|
|
3025
3375
|
reason: '',
|
|
3376
|
+
runId: '',
|
|
3377
|
+
fromEventId: '',
|
|
3378
|
+
writeReport: false,
|
|
3026
3379
|
parseError: false,
|
|
3027
3380
|
unknownFlag: '',
|
|
3028
3381
|
};
|
|
@@ -3036,6 +3389,9 @@ function parseRuntimeArgs(argv) {
|
|
|
3036
3389
|
else if (a === '--task' && argv[i + 1]) out.task = String(argv[++i]);
|
|
3037
3390
|
else if (a === '--mode' && argv[i + 1]) out.mode = String(argv[++i]);
|
|
3038
3391
|
else if (a === '--reason' && argv[i + 1]) out.reason = String(argv[++i]);
|
|
3392
|
+
else if (a === '--run' && argv[i + 1]) out.runId = String(argv[++i]);
|
|
3393
|
+
else if (a === '--from' && argv[i + 1]) out.fromEventId = String(argv[++i]);
|
|
3394
|
+
else if (a === '--write') out.writeReport = true;
|
|
3039
3395
|
else if (!a.startsWith('-')) positionals.push(a);
|
|
3040
3396
|
else {
|
|
3041
3397
|
out.parseError = true;
|
|
@@ -3138,6 +3494,114 @@ function parseAzureArgs(argv) {
|
|
|
3138
3494
|
return out;
|
|
3139
3495
|
}
|
|
3140
3496
|
|
|
3497
|
+
/**
|
|
3498
|
+
* @param {ContextOpts} opts
|
|
3499
|
+
*/
|
|
3500
|
+
function runContext(opts) {
|
|
3501
|
+
const c = useAnsiColors();
|
|
3502
|
+
printSection('OXE ▸ context');
|
|
3503
|
+
if (!fs.existsSync(opts.dir)) {
|
|
3504
|
+
console.error(`${yellow}Diretório não encontrado: ${opts.dir}${reset}`);
|
|
3505
|
+
process.exit(1);
|
|
3506
|
+
}
|
|
3507
|
+
const statePath = oxeHealth.oxePaths(opts.dir).state;
|
|
3508
|
+
const stateText = fs.existsSync(statePath) ? fs.readFileSync(statePath, 'utf8') : '';
|
|
3509
|
+
const activeSession = opts.activeSession || oxeHealth.parseActiveSession(stateText) || null;
|
|
3510
|
+
const workflow = opts.workflow || '';
|
|
3511
|
+
|
|
3512
|
+
if (opts.action === 'inspect') {
|
|
3513
|
+
const selectedWorkflow = workflow || 'dashboard';
|
|
3514
|
+
let pack;
|
|
3515
|
+
try {
|
|
3516
|
+
pack = oxeContext.inspectContextPack(opts.dir, {
|
|
3517
|
+
workflow: selectedWorkflow,
|
|
3518
|
+
tier: opts.tier,
|
|
3519
|
+
activeSession,
|
|
3520
|
+
});
|
|
3521
|
+
} catch (err) {
|
|
3522
|
+
console.error(`${red}Erro ao inspecionar context pack para "${selectedWorkflow}": ${err instanceof Error ? err.message : String(err)}${reset}`);
|
|
3523
|
+
process.exit(1);
|
|
3524
|
+
}
|
|
3525
|
+
if (opts.json) {
|
|
3526
|
+
console.log(JSON.stringify(pack, null, 2));
|
|
3527
|
+
return;
|
|
3528
|
+
}
|
|
3529
|
+
console.log(` ${c ? green : ''}Projeto:${c ? reset : ''} ${c ? cyan : ''}${opts.dir}${c ? reset : ''}`);
|
|
3530
|
+
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || 'modo legado'}${c ? reset : ''}`);
|
|
3531
|
+
console.log(` ${c ? green : ''}Workflow:${c ? reset : ''} ${selectedWorkflow}`);
|
|
3532
|
+
console.log(` ${c ? green : ''}Tier:${c ? reset : ''} ${pack.context_tier}`);
|
|
3533
|
+
console.log(` ${c ? green : ''}Quality:${c ? reset : ''} ${pack.context_quality.score} (${pack.context_quality.status})`);
|
|
3534
|
+
if (pack.context_quality.score < 30 || pack.context_quality.status === 'critical') {
|
|
3535
|
+
console.log(` ${yellow}AVISO${reset} Contexto crítico — artefatos obrigatórios ausentes. Use \`oxe-cc context build --workflow ${selectedWorkflow}\` para regenerar.`);
|
|
3536
|
+
}
|
|
3537
|
+
console.log(` ${c ? green : ''}Freshness:${c ? reset : ''} ${pack.freshness.reason}${pack.freshness.pack_age_hours != null ? ` · ${pack.freshness.pack_age_hours}h` : ''}`);
|
|
3538
|
+
console.log(` ${c ? green : ''}Pack:${c ? reset : ''} ${pack.path || '—'}`);
|
|
3539
|
+
console.log(` ${c ? green : ''}Artefatos:${c ? reset : ''} ${(pack.read_order || []).join(', ') || '—'}`);
|
|
3540
|
+
if ((pack.gaps || []).length) {
|
|
3541
|
+
for (const gap of pack.gaps) {
|
|
3542
|
+
console.log(` ${gap.severity === 'critical' ? red : yellow}${gap.severity.toUpperCase()}${reset} ${gap.alias}: ${gap.reason}`);
|
|
3543
|
+
}
|
|
3544
|
+
}
|
|
3545
|
+
if ((pack.conflicts || []).length) {
|
|
3546
|
+
for (const conflict of pack.conflicts) {
|
|
3547
|
+
console.log(` ${yellow}CONFLICT${reset} ${conflict.alias}: ${conflict.reason}`);
|
|
3548
|
+
}
|
|
3549
|
+
}
|
|
3550
|
+
return;
|
|
3551
|
+
}
|
|
3552
|
+
|
|
3553
|
+
if (workflow) {
|
|
3554
|
+
bootstrapOxe(opts.dir, { dryRun: false, force: false });
|
|
3555
|
+
let pack;
|
|
3556
|
+
try {
|
|
3557
|
+
pack = oxeContext.buildContextPack(opts.dir, {
|
|
3558
|
+
workflow,
|
|
3559
|
+
tier: opts.tier,
|
|
3560
|
+
activeSession,
|
|
3561
|
+
write: true,
|
|
3562
|
+
});
|
|
3563
|
+
} catch (err) {
|
|
3564
|
+
console.error(`${red}Erro ao gerar context pack para "${workflow}": ${err instanceof Error ? err.message : String(err)}${reset}`);
|
|
3565
|
+
process.exit(1);
|
|
3566
|
+
}
|
|
3567
|
+
if (opts.json) {
|
|
3568
|
+
console.log(JSON.stringify(pack, null, 2));
|
|
3569
|
+
return;
|
|
3570
|
+
}
|
|
3571
|
+
console.log(` ${c ? green : ''}✓${c ? reset : ''} Context pack gerado para ${workflow}.`);
|
|
3572
|
+
console.log(` ${c ? green : ''}Quality:${c ? reset : ''} ${pack.context_quality.score} (${pack.context_quality.status})`);
|
|
3573
|
+
if (pack.context_quality.score < 30 || pack.context_quality.status === 'critical') {
|
|
3574
|
+
console.log(` ${yellow}AVISO${reset} Contexto crítico — artefatos obrigatórios ausentes. Verifique o STATE e os artefatos do workflow.`);
|
|
3575
|
+
}
|
|
3576
|
+
console.log(` ${c ? green : ''}Pack:${c ? reset : ''} ${oxeContext.resolvePackFile(opts.dir, workflow, activeSession)}`);
|
|
3577
|
+
return;
|
|
3578
|
+
}
|
|
3579
|
+
|
|
3580
|
+
bootstrapOxe(opts.dir, { dryRun: false, force: false });
|
|
3581
|
+
let packs;
|
|
3582
|
+
try {
|
|
3583
|
+
packs = oxeContext.buildAllContextPacks(opts.dir, {
|
|
3584
|
+
tier: opts.tier,
|
|
3585
|
+
activeSession,
|
|
3586
|
+
write: true,
|
|
3587
|
+
});
|
|
3588
|
+
} catch (err) {
|
|
3589
|
+
console.error(`${red}Erro ao gerar context packs: ${err instanceof Error ? err.message : String(err)}${reset}`);
|
|
3590
|
+
process.exit(1);
|
|
3591
|
+
}
|
|
3592
|
+
if (opts.json) {
|
|
3593
|
+
console.log(JSON.stringify(packs, null, 2));
|
|
3594
|
+
return;
|
|
3595
|
+
}
|
|
3596
|
+
console.log(` ${c ? green : ''}Projeto:${c ? reset : ''} ${c ? cyan : ''}${opts.dir}${c ? reset : ''}`);
|
|
3597
|
+
console.log(` ${c ? green : ''}Sessão:${c ? reset : ''} ${c ? cyan : ''}${activeSession || 'modo legado'}${c ? reset : ''}`);
|
|
3598
|
+
console.log(` ${c ? green : ''}Packs:${c ? reset : ''} ${packs.length}`);
|
|
3599
|
+
for (const pack of packs) {
|
|
3600
|
+
const qualityFlag = (pack.context_quality.score < 30 || pack.context_quality.status === 'critical') ? ` ${yellow}[CRÍTICO]${reset}` : '';
|
|
3601
|
+
console.log(` ${c ? dim : ''}•${c ? reset : ''} ${pack.workflow} · ${pack.context_quality.score} (${pack.context_quality.status}) · ${pack.freshness.reason}${qualityFlag}`);
|
|
3602
|
+
}
|
|
3603
|
+
}
|
|
3604
|
+
|
|
3141
3605
|
/**
|
|
3142
3606
|
* @param {DashboardOpts} opts
|
|
3143
3607
|
*/
|
|
@@ -3210,6 +3674,42 @@ function runRuntime(opts) {
|
|
|
3210
3674
|
return;
|
|
3211
3675
|
}
|
|
3212
3676
|
|
|
3677
|
+
if (opts.action === 'replay' && !opts.task) {
|
|
3678
|
+
const report = oxeOperational.replayEvents(opts.dir, activeSession, {
|
|
3679
|
+
runId: opts.runId || undefined,
|
|
3680
|
+
fromEventId: opts.fromEventId || undefined,
|
|
3681
|
+
waveId: opts.wave != null ? opts.wave : undefined,
|
|
3682
|
+
writeReport: opts.writeReport || false,
|
|
3683
|
+
});
|
|
3684
|
+
console.log(` ${c ? green : ''}Total eventos:${c ? reset : ''} ${report.totalEvents}`);
|
|
3685
|
+
console.log(` ${c ? green : ''}Duração:${c ? reset : ''} ${report.duration_ms != null ? `${(report.duration_ms / 1000).toFixed(1)}s` : '—'}`);
|
|
3686
|
+
console.log(` ${c ? green : ''}Ondas:${c ? reset : ''} ${report.waveIds.join(', ') || '—'}`);
|
|
3687
|
+
console.log(` ${c ? green : ''}Tarefas:${c ? reset : ''} ${report.taskSequence.join(', ') || '—'}`);
|
|
3688
|
+
console.log(` ${c ? green : ''}Falhas:${c ? reset : ''} ${report.failureEvents.length}`);
|
|
3689
|
+
if (report.totalEvents > 0) {
|
|
3690
|
+
console.log('');
|
|
3691
|
+
const dim = c ? '\x1b[2m' : '';
|
|
3692
|
+
console.log(` ${dim}# Tipo Wave Task Delta Timestamp${c ? reset : ''}`);
|
|
3693
|
+
for (let i = 0; i < Math.min(report.events.length, 50); i++) {
|
|
3694
|
+
const e = report.events[i];
|
|
3695
|
+
const delta = i > 0 ? `+${(e._delta_ms / 1000).toFixed(1)}s` : '—';
|
|
3696
|
+
const num = String(i + 1).padStart(3);
|
|
3697
|
+
const type = String(e.type).padEnd(22).slice(0, 22);
|
|
3698
|
+
const wave = String(e.wave_id || '—').padEnd(7).slice(0, 7);
|
|
3699
|
+
const task = String(e.task_id || '—').padEnd(7).slice(0, 7);
|
|
3700
|
+
const deltaStr = delta.padStart(10);
|
|
3701
|
+
console.log(` ${num} ${type} ${wave} ${task} ${deltaStr} ${e.timestamp}`);
|
|
3702
|
+
}
|
|
3703
|
+
if (report.events.length > 50) {
|
|
3704
|
+
console.log(` … (${report.events.length - 50} mais)`);
|
|
3705
|
+
}
|
|
3706
|
+
}
|
|
3707
|
+
if (report._reportPath) {
|
|
3708
|
+
console.log(`\n ${c ? green : ''}Relatório:${c ? reset : ''} ${report._reportPath}`);
|
|
3709
|
+
}
|
|
3710
|
+
return;
|
|
3711
|
+
}
|
|
3712
|
+
|
|
3213
3713
|
try {
|
|
3214
3714
|
const next = oxeOperational.applyRuntimeAction(opts.dir, activeSession, {
|
|
3215
3715
|
action: opts.action,
|
|
@@ -3714,12 +4214,14 @@ async function main() {
|
|
|
3714
4214
|
argv[0] === 'doctor' ||
|
|
3715
4215
|
argv[0] === 'status' ||
|
|
3716
4216
|
argv[0] === 'init-oxe' ||
|
|
4217
|
+
argv[0] === 'context' ||
|
|
3717
4218
|
argv[0] === 'dashboard' ||
|
|
3718
4219
|
argv[0] === 'runtime' ||
|
|
3719
4220
|
argv[0] === 'azure' ||
|
|
3720
4221
|
argv[0] === 'uninstall' ||
|
|
3721
4222
|
argv[0] === 'update' ||
|
|
3722
4223
|
argv[0] === 'capabilities' ||
|
|
4224
|
+
argv[0] === 'plugins' ||
|
|
3723
4225
|
argv[0] === 'plan' ||
|
|
3724
4226
|
argv[0] === 'verify' ||
|
|
3725
4227
|
argv[0] === 'install'
|
|
@@ -3828,6 +4330,24 @@ async function main() {
|
|
|
3828
4330
|
return;
|
|
3829
4331
|
}
|
|
3830
4332
|
|
|
4333
|
+
if (command === 'context') {
|
|
4334
|
+
const contextOpts = parseContextArgs(argv);
|
|
4335
|
+
if (contextOpts.help) {
|
|
4336
|
+
printBanner();
|
|
4337
|
+
usage();
|
|
4338
|
+
process.exit(0);
|
|
4339
|
+
}
|
|
4340
|
+
if (contextOpts.parseError) {
|
|
4341
|
+
printBanner();
|
|
4342
|
+
console.error(`${red}Opção desconhecida:${reset} ${contextOpts.unknownFlag}`);
|
|
4343
|
+
usage();
|
|
4344
|
+
process.exit(1);
|
|
4345
|
+
}
|
|
4346
|
+
printBanner();
|
|
4347
|
+
runContext(contextOpts);
|
|
4348
|
+
return;
|
|
4349
|
+
}
|
|
4350
|
+
|
|
3831
4351
|
if (command === 'runtime') {
|
|
3832
4352
|
const runtime = parseRuntimeArgs(argv);
|
|
3833
4353
|
if (runtime.help) {
|
|
@@ -3850,6 +4370,55 @@ async function main() {
|
|
|
3850
4370
|
return;
|
|
3851
4371
|
}
|
|
3852
4372
|
|
|
4373
|
+
if (command === 'plugins') {
|
|
4374
|
+
printBanner();
|
|
4375
|
+
// Parse --dir flag
|
|
4376
|
+
let pluginsDir = process.cwd();
|
|
4377
|
+
const pluginsArgv = argv.slice();
|
|
4378
|
+
for (let i = 0; i < pluginsArgv.length; i++) {
|
|
4379
|
+
if (pluginsArgv[i] === '--dir' && pluginsArgv[i + 1]) {
|
|
4380
|
+
pluginsDir = path.resolve(pluginsArgv[++i]);
|
|
4381
|
+
pluginsArgv.splice(i - 1, 2);
|
|
4382
|
+
i -= 2;
|
|
4383
|
+
}
|
|
4384
|
+
}
|
|
4385
|
+
const c = useAnsiColors();
|
|
4386
|
+
const subCmd = pluginsArgv[0] || 'list';
|
|
4387
|
+
const pluginTarget = pluginsArgv[1] || '';
|
|
4388
|
+
|
|
4389
|
+
if (subCmd === 'list') {
|
|
4390
|
+
const result = oxePlugins.loadPlugins(pluginsDir);
|
|
4391
|
+
console.log(`\n ${c ? green : ''}Plugins carregados:${c ? reset : ''} ${result.plugins.length}`);
|
|
4392
|
+
for (const p of result.plugins) {
|
|
4393
|
+
console.log(` • ${p.name}${p.version ? ` (${p.version})` : ''} — hooks: ${Object.keys(p.hooks).join(', ')}`);
|
|
4394
|
+
}
|
|
4395
|
+
if (result.errors.length) {
|
|
4396
|
+
console.log(`\n ${c ? yellow : ''}Erros:${c ? reset : ''}`);
|
|
4397
|
+
for (const e of result.errors) {
|
|
4398
|
+
console.log(` ✗ ${e.file}: ${e.error}`);
|
|
4399
|
+
}
|
|
4400
|
+
}
|
|
4401
|
+
} else if (subCmd === 'install' && pluginTarget) {
|
|
4402
|
+
const src = pluginTarget.startsWith('npm:') ? pluginTarget.slice(4) : pluginTarget;
|
|
4403
|
+
const ver = pluginsArgv[2] || '';
|
|
4404
|
+
console.log(` Instalando plugin: ${src}${ver ? `@${ver}` : ''}...`);
|
|
4405
|
+
const result = oxePlugins.installNpmPlugin(pluginsDir, src, ver || undefined);
|
|
4406
|
+
if (result.ok) {
|
|
4407
|
+
console.log(` ${c ? green : ''}✓${c ? reset : ''} Instalado em: ${result.path}`);
|
|
4408
|
+
console.log(` ${c ? dim : ''}Adicione ao .oxe/config.json: "plugins": [{ "source": "npm:${src}" }]${c ? reset : ''}`);
|
|
4409
|
+
} else {
|
|
4410
|
+
console.error(` ${c ? red : ''}✗ Falha:${c ? reset : ''} ${result.error}`);
|
|
4411
|
+
process.exit(1);
|
|
4412
|
+
}
|
|
4413
|
+
} else if (subCmd === 'remove' && pluginTarget) {
|
|
4414
|
+
console.log(` ${c ? yellow : ''}Remove "${pluginTarget}" de .oxe/config.json → plugins[] manualmente.${c ? reset : ''}`);
|
|
4415
|
+
console.log(` ${c ? dim : ''}Arquivos npm: rm -rf .oxe/plugins/_npm/node_modules/${pluginTarget}${c ? reset : ''}`);
|
|
4416
|
+
} else {
|
|
4417
|
+
console.log(` ${c ? yellow : ''}Uso: oxe-cc plugins list | install <npm:pkg|path> | remove <id>${c ? reset : ''}`);
|
|
4418
|
+
}
|
|
4419
|
+
return;
|
|
4420
|
+
}
|
|
4421
|
+
|
|
3853
4422
|
if (command === 'azure') {
|
|
3854
4423
|
const azure = parseAzureArgs(argv);
|
|
3855
4424
|
if (azure.help) {
|
|
@@ -3957,7 +4526,7 @@ async function main() {
|
|
|
3957
4526
|
printSummaryAndNextSteps(c0, {
|
|
3958
4527
|
bullets: opts.dryRun
|
|
3959
4528
|
? ['[simulação] Seriam criados ou atualizados .oxe/STATE.md, .oxe/config.json, .oxe/codebase/, .oxe/ACTIVE-RUN.json e .oxe/OXE-EVENTS.ndjson']
|
|
3960
|
-
: ['.oxe/STATE.md, .oxe/config.json, .oxe/codebase/, .oxe/ACTIVE-RUN.json e .oxe/OXE-EVENTS.ndjson (criados ou atualizados conforme --force)'],
|
|
4529
|
+
: ['.oxe/STATE.md, .oxe/config.json, .oxe/codebase/, .oxe/context/, .oxe/ACTIVE-RUN.json e .oxe/OXE-EVENTS.ndjson (criados ou atualizados conforme --force)'],
|
|
3961
4530
|
nextSteps: [
|
|
3962
4531
|
{ desc: 'Validar o projeto:', cmd: 'npx oxe-cc doctor' },
|
|
3963
4532
|
{ desc: 'Instalar integrações IDE/CLI (se ainda não fez):', cmd: 'npx oxe-cc@latest' },
|