oxe-cc 1.7.0 → 1.8.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.
@@ -809,19 +809,40 @@ function copilotLegacyHome() {
809
809
  return path.join(os.homedir(), '.copilot');
810
810
  }
811
811
 
812
- function copilotLegacyPaths() {
813
- const root = copilotLegacyHome();
814
- return {
815
- root,
816
- promptsDir: path.join(root, 'prompts'),
817
- instructions: path.join(root, 'copilot-instructions.md'),
818
- };
819
- }
820
-
821
- /**
822
- * @param {string} filePath
823
- */
824
- function readJsonFileSafe(filePath) {
812
+ function copilotLegacyPaths() {
813
+ const root = copilotLegacyHome();
814
+ return {
815
+ root,
816
+ promptsDir: path.join(root, 'prompts'),
817
+ instructions: path.join(root, 'copilot-instructions.md'),
818
+ };
819
+ }
820
+
821
+ function expandHomePath(value) {
822
+ if (typeof value !== 'string') return value;
823
+ if (value === '~') return os.homedir();
824
+ if (value.startsWith('~/') || value.startsWith('~\\')) return path.join(os.homedir(), value.slice(2));
825
+ return value;
826
+ }
827
+
828
+ function codexHome() {
829
+ if (process.env.CODEX_HOME) return path.resolve(expandHomePath(process.env.CODEX_HOME));
830
+ return path.join(os.homedir(), '.codex');
831
+ }
832
+
833
+ function codexIntegrationPaths() {
834
+ const root = codexHome();
835
+ return {
836
+ root,
837
+ promptsDir: path.join(root, 'prompts'),
838
+ skillsRoot: path.join(os.homedir(), '.agents', 'skills'),
839
+ };
840
+ }
841
+
842
+ /**
843
+ * @param {string} filePath
844
+ */
845
+ function readJsonFileSafe(filePath) {
825
846
  if (!fs.existsSync(filePath)) return { ok: false, data: null, error: null };
826
847
  try {
827
848
  return { ok: true, data: JSON.parse(fs.readFileSync(filePath, 'utf8')), error: null };
@@ -1270,19 +1291,45 @@ function summarizeEnterpriseRuntime(target, activeRun, activeSession, config) {
1270
1291
  * @param {string} dir
1271
1292
  * @returns {string[]}
1272
1293
  */
1273
- function listOxePromptFiles(dir) {
1274
- if (!fs.existsSync(dir)) return [];
1275
- return fs
1276
- .readdirSync(dir, { withFileTypes: true })
1277
- .filter((entry) => entry.isFile() && /^oxe-.*\.prompt\.md$/i.test(entry.name))
1294
+ function listOxePromptFiles(dir) {
1295
+ if (!fs.existsSync(dir)) return [];
1296
+ return fs
1297
+ .readdirSync(dir, { withFileTypes: true })
1298
+ .filter((entry) => entry.isFile() && /^oxe-.*\.prompt\.md$/i.test(entry.name))
1278
1299
  .map((entry) => path.join(dir, entry.name))
1279
- .sort();
1280
- }
1281
-
1282
- /**
1283
- * @param {string} filePath
1284
- * @returns {boolean}
1285
- */
1300
+ .sort();
1301
+ }
1302
+
1303
+ /**
1304
+ * @param {string} dir
1305
+ * @returns {string[]}
1306
+ */
1307
+ function listOxeCodexPromptFiles(dir) {
1308
+ if (!fs.existsSync(dir)) return [];
1309
+ return fs
1310
+ .readdirSync(dir, { withFileTypes: true })
1311
+ .filter((entry) => entry.isFile() && (entry.name === 'oxe.md' || /^oxe-.*\.md$/i.test(entry.name)))
1312
+ .map((entry) => path.join(dir, entry.name))
1313
+ .sort();
1314
+ }
1315
+
1316
+ /**
1317
+ * @param {string} root
1318
+ * @returns {string[]}
1319
+ */
1320
+ function listOxeSkillDirs(root) {
1321
+ if (!fs.existsSync(root)) return [];
1322
+ return fs
1323
+ .readdirSync(root, { withFileTypes: true })
1324
+ .filter((entry) => entry.isDirectory() && /^oxe($|-)/i.test(entry.name) && fs.existsSync(path.join(root, entry.name, 'SKILL.md')))
1325
+ .map((entry) => path.join(root, entry.name))
1326
+ .sort();
1327
+ }
1328
+
1329
+ /**
1330
+ * @param {string} filePath
1331
+ * @returns {boolean}
1332
+ */
1286
1333
  function hasOxeInstructionBlock(filePath) {
1287
1334
  if (!fs.existsSync(filePath)) return false;
1288
1335
  const text = fs.readFileSync(filePath, 'utf8');
@@ -1430,13 +1477,67 @@ function copilotIntegrationReport(target) {
1430
1477
  },
1431
1478
  manifest,
1432
1479
  warnings,
1433
- };
1434
- }
1435
-
1436
- /**
1437
- * Valida o arquivo plan-agents.json (se existir) e retorna avisos.
1438
- * @param {string} target
1439
- * @returns {string[]}
1480
+ };
1481
+ }
1482
+
1483
+ /**
1484
+ * @param {string} target
1485
+ */
1486
+ function codexIntegrationReport(target) {
1487
+ const paths = codexIntegrationPaths();
1488
+ const promptFiles = listOxeCodexPromptFiles(paths.promptsDir);
1489
+ const skillDirs = listOxeSkillDirs(paths.skillsRoot);
1490
+ const promptNames = promptFiles.map((filePath) => path.basename(filePath));
1491
+ const skillNames = skillDirs.map((dirPath) => path.basename(dirPath));
1492
+ const promptPathWarnings = [];
1493
+ for (const filePath of promptFiles) {
1494
+ for (const warning of promptWorkflowPathWarnings(filePath, target)) promptPathWarnings.push(warning);
1495
+ }
1496
+
1497
+ /** @type {string[]} */
1498
+ const warnings = [];
1499
+ const detected = promptFiles.length > 0 || skillDirs.length > 0;
1500
+ const commandsReady = promptNames.includes('oxe.md');
1501
+ const skillsReady = skillNames.includes('oxe');
1502
+ if (detected && promptFiles.length === 0) {
1503
+ warnings.push('Codex tem skills OXE instaladas, mas ~/.codex/prompts não contém prompts OXE; a barra / não listará /oxe.');
1504
+ }
1505
+ if (promptFiles.length > 0 && !commandsReady) {
1506
+ warnings.push('Codex prompts OXE existem, mas o entrypoint principal oxe.md está ausente.');
1507
+ }
1508
+ if (skillDirs.length > 0 && !skillsReady) {
1509
+ warnings.push('Codex skills OXE existem, mas o skill raiz oxe está ausente.');
1510
+ }
1511
+ if (promptFiles.length > 0 && skillDirs.length === 0) {
1512
+ warnings.push('Codex prompts OXE existem, mas ~/.agents/skills não contém skills OXE; recursos especializados podem não aparecer.');
1513
+ }
1514
+ for (const warning of promptPathWarnings) warnings.push(warning);
1515
+
1516
+ let status = 'not_installed';
1517
+ if (commandsReady && skillsReady && promptPathWarnings.length === 0) {
1518
+ status = warnings.length ? 'warning' : 'healthy';
1519
+ } else if (detected) {
1520
+ status = commandsReady ? 'warning' : 'broken';
1521
+ }
1522
+
1523
+ return {
1524
+ status,
1525
+ detected,
1526
+ commandsReady,
1527
+ skillsReady,
1528
+ root: paths.root,
1529
+ promptsDir: paths.promptsDir,
1530
+ skillsRoot: paths.skillsRoot,
1531
+ promptFiles,
1532
+ skillDirs,
1533
+ warnings,
1534
+ };
1535
+ }
1536
+
1537
+ /**
1538
+ * Valida o arquivo plan-agents.json (se existir) e retorna avisos.
1539
+ * @param {string} target
1540
+ * @returns {string[]}
1440
1541
  */
1441
1542
  function planAgentsWarnings(target) {
1442
1543
  const p = oxePaths(target);
@@ -2221,10 +2322,12 @@ function buildHealthReport(target) {
2221
2322
  ...planAgentsWarnings(target),
2222
2323
  ];
2223
2324
  const planWarn = suppressExecutionWorkspaceGates ? [] : executionPlanWarn;
2224
- const sessionWarn = sessionWarnings(target, activeSession);
2325
+ const sessionWarn = sessionWarnings(target, activeSession);
2225
2326
  const installWarn = installationCompletenessWarnings(target);
2226
2327
  const copilot = copilotIntegrationReport(target);
2227
2328
  const copilotWarn = copilot.warnings;
2329
+ const codex = codexIntegrationReport(target);
2330
+ const codexWarn = codex.warnings;
2228
2331
  const reviewWarn = suppressExecutionWorkspaceGates ? [] : planReviewWarnings(stateText, p);
2229
2332
  const planSelfEvaluation = {
2230
2333
  ...parsedPlanSelfEvaluation,
@@ -2418,10 +2521,11 @@ function buildHealthReport(target) {
2418
2521
  planWarningCount +
2419
2522
  capabilityWarn.length +
2420
2523
  investigationWarn.length +
2421
- sessionWarn.length +
2422
- installWarn.length +
2423
- copilotWarn.length +
2424
- contextWarn.length +
2524
+ sessionWarn.length +
2525
+ installWarn.length +
2526
+ copilotWarn.length +
2527
+ codexWarn.length +
2528
+ contextWarn.length +
2425
2529
  semanticsWarn.length +
2426
2530
  (azureReport ? azureReport.warnings.length : 0) +
2427
2531
  (sumWarn ? 1 : 0);
@@ -2450,9 +2554,11 @@ function buildHealthReport(target) {
2450
2554
  installWarn,
2451
2555
  copilotWarn,
2452
2556
  contextWarn,
2453
- semanticsWarn,
2454
- copilot,
2455
- summaryGapWarn: sumWarn,
2557
+ semanticsWarn,
2558
+ copilot,
2559
+ codexWarn,
2560
+ codex,
2561
+ summaryGapWarn: sumWarn,
2456
2562
  specWarn,
2457
2563
  planWarn,
2458
2564
  planSelfEvaluation,
@@ -2532,9 +2638,11 @@ module.exports = {
2532
2638
  parsePlanReviewStatus,
2533
2639
  isStaleScan,
2534
2640
  isStaleLessons,
2535
- copilotWorkspacePaths,
2536
- copilotLegacyPaths,
2641
+ copilotWorkspacePaths,
2642
+ copilotLegacyPaths,
2537
2643
  copilotIntegrationReport,
2644
+ codexIntegrationPaths,
2645
+ codexIntegrationReport,
2538
2646
  normalizePlanConfidenceThreshold,
2539
2647
  isExecutablePlanConfidence,
2540
2648
  hasExecutablePlanSelfEvaluation,