oxe-cc 0.7.1 → 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.
Files changed (156) hide show
  1. package/.cursor/commands/oxe-ask.md +34 -0
  2. package/.cursor/commands/oxe-capabilities.md +34 -0
  3. package/.cursor/commands/oxe-checkpoint.md +34 -0
  4. package/.cursor/commands/oxe-compact.md +33 -0
  5. package/.cursor/commands/oxe-dashboard.md +34 -0
  6. package/.cursor/commands/oxe-debug.md +34 -0
  7. package/.cursor/commands/oxe-discuss.md +34 -0
  8. package/.cursor/commands/oxe-execute.md +34 -0
  9. package/.cursor/commands/oxe-forensics.md +34 -0
  10. package/.cursor/commands/oxe-help.md +33 -0
  11. package/.cursor/commands/oxe-loop.md +34 -0
  12. package/.cursor/commands/oxe-milestone.md +34 -0
  13. package/.cursor/commands/oxe-next.md +33 -0
  14. package/.cursor/commands/oxe-obs.md +34 -0
  15. package/.cursor/commands/oxe-plan-agent.md +33 -0
  16. package/.cursor/commands/oxe-plan.md +34 -0
  17. package/.cursor/commands/oxe-project.md +34 -0
  18. package/.cursor/commands/oxe-quick.md +34 -0
  19. package/.cursor/commands/oxe-research.md +34 -0
  20. package/.cursor/commands/oxe-retro.md +34 -0
  21. package/.cursor/commands/oxe-review-pr.md +34 -0
  22. package/.cursor/commands/oxe-route.md +34 -0
  23. package/.cursor/commands/oxe-scan.md +34 -0
  24. package/.cursor/commands/oxe-security.md +34 -0
  25. package/.cursor/commands/oxe-session.md +34 -0
  26. package/.cursor/commands/oxe-skill.md +45 -0
  27. package/.cursor/commands/oxe-spec.md +34 -0
  28. package/.cursor/commands/oxe-ui-review.md +34 -0
  29. package/.cursor/commands/oxe-ui-spec.md +34 -0
  30. package/.cursor/commands/oxe-update.md +33 -0
  31. package/.cursor/commands/oxe-validate-gaps.md +34 -0
  32. package/.cursor/commands/oxe-verify.md +34 -0
  33. package/.cursor/commands/oxe-workstream.md +34 -0
  34. package/.cursor/commands/oxe.md +38 -2
  35. package/.github/copilot-instructions.md +8 -5
  36. package/.github/prompts/oxe-ask.prompt.md +33 -0
  37. package/.github/prompts/oxe-capabilities.prompt.md +33 -0
  38. package/.github/prompts/oxe-checkpoint.prompt.md +45 -12
  39. package/.github/prompts/oxe-compact.prompt.md +44 -11
  40. package/.github/prompts/oxe-dashboard.prompt.md +33 -0
  41. package/.github/prompts/oxe-debug.prompt.md +45 -12
  42. package/.github/prompts/oxe-discuss.prompt.md +33 -0
  43. package/.github/prompts/oxe-execute.prompt.md +45 -12
  44. package/.github/prompts/oxe-forensics.prompt.md +45 -12
  45. package/.github/prompts/oxe-help.prompt.md +42 -9
  46. package/.github/prompts/oxe-loop.prompt.md +45 -12
  47. package/.github/prompts/oxe-milestone.prompt.md +45 -12
  48. package/.github/prompts/oxe-next.prompt.md +42 -9
  49. package/.github/prompts/oxe-obs.prompt.md +45 -12
  50. package/.github/prompts/oxe-plan-agent.prompt.md +43 -10
  51. package/.github/prompts/oxe-plan.prompt.md +45 -12
  52. package/.github/prompts/oxe-project.prompt.md +45 -12
  53. package/.github/prompts/oxe-quick.prompt.md +45 -12
  54. package/.github/prompts/oxe-research.prompt.md +45 -12
  55. package/.github/prompts/oxe-retro.prompt.md +45 -12
  56. package/.github/prompts/oxe-review-pr.prompt.md +45 -12
  57. package/.github/prompts/oxe-route.prompt.md +45 -12
  58. package/.github/prompts/oxe-scan.prompt.md +45 -12
  59. package/.github/prompts/oxe-security.prompt.md +45 -12
  60. package/.github/prompts/oxe-session.prompt.md +33 -0
  61. package/.github/prompts/oxe-skill.prompt.md +45 -0
  62. package/.github/prompts/oxe-spec.prompt.md +45 -12
  63. package/.github/prompts/oxe-ui-review.prompt.md +45 -12
  64. package/.github/prompts/oxe-ui-spec.prompt.md +45 -12
  65. package/.github/prompts/oxe-update.prompt.md +44 -11
  66. package/.github/prompts/oxe-validate-gaps.prompt.md +45 -12
  67. package/.github/prompts/oxe-verify.prompt.md +45 -12
  68. package/.github/prompts/oxe-workstream.prompt.md +45 -12
  69. package/.github/prompts/oxe.prompt.md +45 -12
  70. package/AGENTS.md +6 -4
  71. package/CHANGELOG.md +45 -0
  72. package/README.md +38 -8
  73. package/bin/lib/oxe-agent-install.cjs +69 -55
  74. package/bin/lib/oxe-context-engine.cjs +866 -0
  75. package/bin/lib/oxe-dashboard.cjs +605 -588
  76. package/bin/lib/oxe-operational.cjs +105 -0
  77. package/bin/lib/oxe-plugins.cjs +115 -0
  78. package/bin/lib/oxe-project-health.cjs +1139 -666
  79. package/bin/lib/oxe-runtime-semantics.cjs +459 -0
  80. package/bin/lib/oxe-security.cjs +64 -0
  81. package/bin/oxe-cc.js +615 -46
  82. package/commands/oxe/ask.md +33 -0
  83. package/commands/oxe/capabilities.md +33 -0
  84. package/commands/oxe/checkpoint.md +49 -16
  85. package/commands/oxe/compact.md +43 -10
  86. package/commands/oxe/dashboard.md +33 -0
  87. package/commands/oxe/debug.md +49 -16
  88. package/commands/oxe/discuss.md +33 -0
  89. package/commands/oxe/execute.md +49 -16
  90. package/commands/oxe/forensics.md +49 -16
  91. package/commands/oxe/help.md +44 -11
  92. package/commands/oxe/loop.md +50 -17
  93. package/commands/oxe/milestone.md +49 -16
  94. package/commands/oxe/next.md +45 -12
  95. package/commands/oxe/obs.md +49 -16
  96. package/commands/oxe/oxe.md +49 -16
  97. package/commands/oxe/plan-agent.md +48 -15
  98. package/commands/oxe/plan.md +48 -15
  99. package/commands/oxe/project.md +49 -16
  100. package/commands/oxe/quick.md +49 -16
  101. package/commands/oxe/research.md +49 -16
  102. package/commands/oxe/retro.md +49 -16
  103. package/commands/oxe/review-pr.md +49 -16
  104. package/commands/oxe/route.md +44 -11
  105. package/commands/oxe/scan.md +49 -16
  106. package/commands/oxe/security.md +49 -16
  107. package/commands/oxe/session.md +33 -0
  108. package/commands/oxe/skill.md +49 -0
  109. package/commands/oxe/spec.md +47 -14
  110. package/commands/oxe/ui-review.md +49 -16
  111. package/commands/oxe/ui-spec.md +49 -16
  112. package/commands/oxe/update.md +49 -16
  113. package/commands/oxe/validate-gaps.md +49 -16
  114. package/commands/oxe/verify.md +48 -15
  115. package/commands/oxe/workstream.md +49 -16
  116. package/lib/sdk/index.cjs +140 -7
  117. package/lib/sdk/index.d.ts +266 -1
  118. package/oxe/templates/HYPOTHESES.template.md +33 -0
  119. package/oxe/templates/PLAN.template.md +53 -22
  120. package/oxe/templates/SESSION.template.md +2 -0
  121. package/oxe/templates/SKILL.template.md +26 -0
  122. package/oxe/templates/WORKFLOW_AUTHORING.md +18 -2
  123. package/oxe/templates/config.template.json +16 -14
  124. package/oxe/workflows/ask.md +28 -7
  125. package/oxe/workflows/capabilities.md +2 -0
  126. package/oxe/workflows/dashboard.md +12 -2
  127. package/oxe/workflows/debug.md +9 -4
  128. package/oxe/workflows/discuss.md +12 -6
  129. package/oxe/workflows/execute.md +34 -12
  130. package/oxe/workflows/forensics.md +14 -9
  131. package/oxe/workflows/help.md +20 -9
  132. package/oxe/workflows/loop.md +13 -7
  133. package/oxe/workflows/next.md +6 -4
  134. package/oxe/workflows/plan-agent.md +3 -2
  135. package/oxe/workflows/plan.md +26 -3
  136. package/oxe/workflows/quick.md +10 -3
  137. package/oxe/workflows/references/reasoning-discovery.md +28 -0
  138. package/oxe/workflows/references/reasoning-execution.md +29 -0
  139. package/oxe/workflows/references/reasoning-planning.md +32 -0
  140. package/oxe/workflows/references/reasoning-review.md +29 -0
  141. package/oxe/workflows/references/reasoning-status.md +24 -0
  142. package/oxe/workflows/references/workflow-runtime-contracts.json +879 -0
  143. package/oxe/workflows/research.md +8 -2
  144. package/oxe/workflows/retro.md +7 -2
  145. package/oxe/workflows/review-pr.md +12 -8
  146. package/oxe/workflows/route.md +16 -13
  147. package/oxe/workflows/security.md +3 -2
  148. package/oxe/workflows/session.md +44 -0
  149. package/oxe/workflows/skill.md +44 -0
  150. package/oxe/workflows/spec.md +21 -18
  151. package/oxe/workflows/ui-review.md +13 -7
  152. package/oxe/workflows/update.md +3 -1
  153. package/oxe/workflows/validate-gaps.md +12 -6
  154. package/oxe/workflows/verify-audit.md +73 -0
  155. package/oxe/workflows/verify.md +40 -16
  156. package/package.json +4 -3
@@ -647,6 +647,110 @@ function applyRuntimeAction(projectRoot, activeSession, input = {}) {
647
647
  return saved;
648
648
  }
649
649
 
650
+ /**
651
+ * Reconstrói a timeline de eventos de OXE-EVENTS.ndjson com deltas entre transições.
652
+ * @param {string} projectRoot
653
+ * @param {string|null} activeSession
654
+ * @param {{ fromEventId?: string, runId?: string, waveId?: number, limit?: number, writeReport?: boolean }} [options]
655
+ */
656
+ function replayEvents(projectRoot, activeSession, options = {}) {
657
+ let events = readEvents(projectRoot, activeSession);
658
+
659
+ if (options.runId) {
660
+ events = events.filter((e) => e.run_id === options.runId);
661
+ }
662
+ if (options.fromEventId) {
663
+ const idx = events.findIndex((e) => e.event_id === options.fromEventId);
664
+ if (idx >= 0) events = events.slice(idx);
665
+ }
666
+ if (options.waveId != null) {
667
+ const waveTag = `wave-${options.waveId}`;
668
+ events = events.filter((e) => e.wave_id === waveTag || String(e.wave_id) === String(options.waveId));
669
+ }
670
+ if (options.limit && options.limit > 0) {
671
+ events = events.slice(0, options.limit);
672
+ }
673
+
674
+ // Ordenar por timestamp
675
+ events.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
676
+
677
+ // Calcular deltas
678
+ for (let i = 0; i < events.length; i++) {
679
+ if (i === 0) {
680
+ events[i]._delta_ms = 0;
681
+ } else {
682
+ const prev = new Date(events[i - 1].timestamp).getTime();
683
+ const curr = new Date(events[i].timestamp).getTime();
684
+ events[i]._delta_ms = curr - prev;
685
+ }
686
+ }
687
+
688
+ const firstTs = events.length ? new Date(events[0].timestamp).getTime() : null;
689
+ const lastTs = events.length ? new Date(events[events.length - 1].timestamp).getTime() : null;
690
+ const duration_ms = firstTs != null && lastTs != null ? lastTs - firstTs : null;
691
+
692
+ const waveIds = [...new Set(
693
+ events
694
+ .filter((e) => e.wave_id != null)
695
+ .map((e) => {
696
+ const m = String(e.wave_id).match(/^wave-(\d+)$/);
697
+ return m ? Number(m[1]) : null;
698
+ })
699
+ .filter((n) => n != null)
700
+ )].sort((a, b) => a - b);
701
+
702
+ const taskSequence = [...new Set(events.filter((e) => e.task_id).map((e) => e.task_id))];
703
+ const checkpointSequence = events
704
+ .filter((e) => String(e.type).includes('checkpoint'))
705
+ .map((e) => e.event_id);
706
+ const failureEvents = events.filter((e) =>
707
+ String(e.type).includes('fail') || String(e.type).includes('error')
708
+ );
709
+
710
+ const report = {
711
+ events,
712
+ totalEvents: events.length,
713
+ duration_ms,
714
+ runId: options.runId || (events.length ? events[0].run_id : null),
715
+ waveIds,
716
+ taskSequence,
717
+ checkpointSequence,
718
+ failureEvents,
719
+ };
720
+
721
+ if (options.writeReport) {
722
+ const p = operationalPaths(projectRoot, activeSession);
723
+ const scopeRoot = path.dirname(p.events);
724
+ const reportPath = path.join(scopeRoot, 'REPLAY-SESSION.md');
725
+ const lines = [
726
+ '# OXE — Replay Session',
727
+ '',
728
+ `- **Data:** ${new Date().toISOString().slice(0, 10)}`,
729
+ `- **Run:** ${report.runId || '—'}`,
730
+ `- **Total eventos:** ${report.totalEvents}`,
731
+ `- **Duração:** ${report.duration_ms != null ? `${(report.duration_ms / 1000).toFixed(1)}s` : '—'}`,
732
+ `- **Ondas:** ${report.waveIds.join(', ') || '—'}`,
733
+ `- **Tarefas:** ${report.taskSequence.join(', ') || '—'}`,
734
+ `- **Falhas:** ${report.failureEvents.length}`,
735
+ '',
736
+ '## Timeline',
737
+ '',
738
+ '| # | Tipo | Wave | Task | Delta | Timestamp |',
739
+ '|---|------|------|------|-------|-----------|',
740
+ ];
741
+ for (let i = 0; i < events.length; i++) {
742
+ const e = events[i];
743
+ const delta = i > 0 ? `+${(e._delta_ms / 1000).toFixed(1)}s` : '—';
744
+ lines.push(`| ${i + 1} | ${e.type} | ${e.wave_id || '—'} | ${e.task_id || '—'} | ${delta} | ${e.timestamp} |`);
745
+ }
746
+ ensureDirForFile(reportPath);
747
+ fs.writeFileSync(reportPath, lines.join('\n') + '\n', 'utf8');
748
+ report._reportPath = reportPath;
749
+ }
750
+
751
+ return report;
752
+ }
753
+
650
754
  module.exports = {
651
755
  VALID_RUN_STATUSES,
652
756
  VALID_APPROVAL_POLICIES,
@@ -667,4 +771,5 @@ module.exports = {
667
771
  buildMemoryLayers,
668
772
  buildOperationalGraph,
669
773
  applyRuntimeAction,
774
+ replayEvents,
670
775
  };
@@ -99,6 +99,35 @@ function loadPlugins(projectRoot) {
99
99
  }
100
100
  }
101
101
 
102
+ // Carregar plugins de sources externas (config.json → plugins[])
103
+ const configPath = path.join(projectRoot, '.oxe', 'config.json');
104
+ if (fs.existsSync(configPath)) {
105
+ try {
106
+ const cfg = JSON.parse(fs.readFileSync(configPath, 'utf8'));
107
+ if (Array.isArray(cfg.plugins)) {
108
+ const { resolved, errors: srcErrors } = resolvePluginSources(projectRoot, cfg.plugins);
109
+ for (const se of srcErrors) {
110
+ errors.push({ file: se.source, error: se.error });
111
+ }
112
+ for (const absPath of resolved) {
113
+ try {
114
+ // eslint-disable-next-line no-undef
115
+ const mod = require(absPath);
116
+ if (mod && typeof mod === 'object' && typeof mod.name === 'string' && mod.hooks && typeof mod.hooks === 'object') {
117
+ if (!plugins.some((existing) => existing.name === mod.name)) {
118
+ plugins.push(mod);
119
+ }
120
+ } else {
121
+ errors.push({ file: absPath, error: 'Plugin externo não tem name (string) ou hooks (objeto) válidos' });
122
+ }
123
+ } catch (e) {
124
+ errors.push({ file: absPath, error: String(e) });
125
+ }
126
+ }
127
+ }
128
+ } catch { /* ignore config parse errors — validados em outro lugar */ }
129
+ }
130
+
102
131
  return { plugins, errors };
103
132
  }
104
133
 
@@ -218,9 +247,95 @@ Ver documentação completa: \`oxe/templates/PLUGINS.md\` (no pacote npm).
218
247
  }
219
248
  }
220
249
 
250
+ /**
251
+ * Resolve sources de plugins definidas no config.json.
252
+ * Suporta: "path:./file.cjs", "./relative.cjs" (atalho), "npm:<pkg>".
253
+ * @param {string} projectRoot
254
+ * @param {Array<string | { source: string, version?: string }>} pluginsSources
255
+ * @returns {{ resolved: string[], errors: Array<{ source: string, error: string }> }}
256
+ */
257
+ function resolvePluginSources(projectRoot, pluginsSources) {
258
+ const resolved = [];
259
+ const errors = [];
260
+ if (!Array.isArray(pluginsSources)) return { resolved, errors };
261
+
262
+ for (const entry of pluginsSources) {
263
+ // Legado: string simples (nome de arquivo local)
264
+ if (typeof entry === 'string') {
265
+ const abs = path.resolve(projectRoot, '.oxe', 'plugins', entry);
266
+ if (fs.existsSync(abs)) {
267
+ resolved.push(abs);
268
+ } else {
269
+ errors.push({ source: entry, error: `arquivo não encontrado: ${abs}` });
270
+ }
271
+ continue;
272
+ }
273
+ if (!entry || typeof entry !== 'object' || !entry.source) {
274
+ errors.push({ source: String(entry), error: 'entrada inválida — esperado { source: string }' });
275
+ continue;
276
+ }
277
+ const src = String(entry.source);
278
+
279
+ if (src.startsWith('path:') || src.startsWith('./') || src.startsWith('../')) {
280
+ const rel = src.startsWith('path:') ? src.slice(5) : src;
281
+ const abs = path.resolve(projectRoot, rel);
282
+ if (!fs.existsSync(abs)) {
283
+ errors.push({ source: src, error: `arquivo não encontrado: ${abs}` });
284
+ } else {
285
+ resolved.push(abs);
286
+ }
287
+ } else if (src.startsWith('npm:')) {
288
+ const pkg = src.slice(4);
289
+ const npmDir = path.join(projectRoot, '.oxe', 'plugins', '_npm', 'node_modules', pkg);
290
+ if (!fs.existsSync(npmDir)) {
291
+ errors.push({
292
+ source: src,
293
+ error: `pacote não instalado. Execute: npx oxe-cc plugins install ${src}`,
294
+ });
295
+ } else {
296
+ try {
297
+ const pkgJsonPath = path.join(npmDir, 'package.json');
298
+ const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
299
+ const main = pkgJson.main || 'index.js';
300
+ resolved.push(path.join(npmDir, main));
301
+ } catch (e) {
302
+ errors.push({ source: src, error: `falha ao resolver main do pacote: ${e.message}` });
303
+ }
304
+ }
305
+ } else {
306
+ errors.push({ source: src, error: 'prefixo desconhecido — use "path:" ou "npm:"' });
307
+ }
308
+ }
309
+ return { resolved, errors };
310
+ }
311
+
312
+ /**
313
+ * Instala um plugin npm em .oxe/plugins/_npm/.
314
+ * @param {string} projectRoot
315
+ * @param {string} pkgName
316
+ * @param {string} [version]
317
+ * @returns {{ ok: boolean, path: string, error: string }}
318
+ */
319
+ function installNpmPlugin(projectRoot, pkgName, version) {
320
+ const npmDir = path.join(projectRoot, '.oxe', 'plugins', '_npm');
321
+ try {
322
+ if (!fs.existsSync(npmDir)) {
323
+ fs.mkdirSync(npmDir, { recursive: true });
324
+ }
325
+ const spec = version ? `${pkgName}@${version}` : pkgName;
326
+ const { execSync } = require('child_process');
327
+ execSync(`npm install --prefix "${npmDir}" ${spec}`, { stdio: 'pipe', timeout: 60000 });
328
+ return { ok: true, path: path.join(npmDir, 'node_modules', pkgName), error: '' };
329
+ } catch (e) {
330
+ return { ok: false, path: '', error: e.message || String(e) };
331
+ }
332
+ }
333
+
221
334
  module.exports = {
222
335
  loadPlugins,
223
336
  runHook,
224
337
  validatePlugins,
225
338
  initPluginsDir,
339
+ resolvePluginSources,
340
+ installNpmPlugin,
226
341
  };