olympus-ai 4.1.0 → 4.2.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/.claude-plugin/plugin.json +1 -1
- package/dist/cli/index.js +196 -53
- package/dist/cli/index.js.map +1 -1
- package/dist/features/workflow-engine/construction/decomposition.d.ts +7 -7
- package/dist/features/workflow-engine/construction/decomposition.d.ts.map +1 -1
- package/dist/features/workflow-engine/construction/decomposition.js +15 -14
- package/dist/features/workflow-engine/construction/decomposition.js.map +1 -1
- package/dist/hooks/olympus-hooks.cjs +219 -219
- package/dist/installer/index.d.ts +1 -1
- package/dist/installer/index.js +1 -1
- package/dist/learning/__tests__/cli-operations.test.d.ts +2 -0
- package/dist/learning/__tests__/cli-operations.test.d.ts.map +1 -0
- package/dist/learning/__tests__/cli-operations.test.js +164 -0
- package/dist/learning/__tests__/cli-operations.test.js.map +1 -0
- package/dist/learning/__tests__/intelligence.test.d.ts +2 -0
- package/dist/learning/__tests__/intelligence.test.d.ts.map +1 -0
- package/dist/learning/__tests__/intelligence.test.js +233 -0
- package/dist/learning/__tests__/intelligence.test.js.map +1 -0
- package/dist/learning/__tests__/session-insights.test.d.ts +2 -0
- package/dist/learning/__tests__/session-insights.test.d.ts.map +1 -0
- package/dist/learning/__tests__/session-insights.test.js +176 -0
- package/dist/learning/__tests__/session-insights.test.js.map +1 -0
- package/dist/learning/aggregation.d.ts +1 -11
- package/dist/learning/aggregation.d.ts.map +1 -1
- package/dist/learning/aggregation.js +28 -11
- package/dist/learning/aggregation.js.map +1 -1
- package/dist/learning/baselines.d.ts +2 -32
- package/dist/learning/baselines.d.ts.map +1 -1
- package/dist/learning/baselines.js +3 -70
- package/dist/learning/baselines.js.map +1 -1
- package/dist/learning/cleanup.d.ts +9 -0
- package/dist/learning/cleanup.d.ts.map +1 -1
- package/dist/learning/cleanup.js +96 -3
- package/dist/learning/cleanup.js.map +1 -1
- package/dist/learning/hooks/learned-context.d.ts.map +1 -1
- package/dist/learning/hooks/learned-context.js +12 -5
- package/dist/learning/hooks/learned-context.js.map +1 -1
- package/dist/learning/pattern-extractor.d.ts +2 -1
- package/dist/learning/pattern-extractor.d.ts.map +1 -1
- package/dist/learning/pattern-extractor.js +7 -4
- package/dist/learning/pattern-extractor.js.map +1 -1
- package/dist/learning/routing.d.ts +2 -7
- package/dist/learning/routing.d.ts.map +1 -1
- package/dist/learning/routing.js +18 -17
- package/dist/learning/routing.js.map +1 -1
- package/dist/learning/session-insights.d.ts +3 -0
- package/dist/learning/session-insights.d.ts.map +1 -0
- package/dist/learning/session-insights.js +98 -0
- package/dist/learning/session-insights.js.map +1 -0
- package/dist/learning/session-state.js +3 -3
- package/dist/learning/session-state.js.map +1 -1
- package/dist/learning/types.d.ts +31 -0
- package/dist/learning/types.d.ts.map +1 -1
- package/package.json +100 -100
- package/resources/rules/inception/units-generation.md +218 -204
- package/resources/skills/continue/SKILL.md +1 -1
- package/resources/skills/plan/SKILL.md +18 -11
package/dist/cli/index.js
CHANGED
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
import { Command } from 'commander';
|
|
13
13
|
import chalk from 'chalk';
|
|
14
14
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
|
|
15
|
-
import { join, dirname } from 'path';
|
|
15
|
+
import { join, dirname, resolve } from 'path';
|
|
16
16
|
import { fileURLToPath } from 'url';
|
|
17
17
|
import { loadConfig, getConfigPaths, generateConfigSchema } from '../config/loader.js';
|
|
18
18
|
import { createOlympusSession } from '../index.js';
|
|
19
19
|
import { checkForUpdates, performUpdate, formatUpdateNotification, getInstalledVersion } from '../features/auto-update.js';
|
|
20
20
|
import { install as installOlympus, uninstall as uninstallOlympus, isInstalled, getInstallInfo } from '../installer/index.js';
|
|
21
|
-
import { readFeedbackLog, readJsonFile, getLearningDir, writeJsonFile, appendFeedback, updateAgentPerformance, loadSessionSummaries,
|
|
21
|
+
import { readFeedbackLog, readJsonFile, getLearningDir, writeJsonFile, appendFeedback, updateAgentPerformance, loadSessionSummaries, readAgentPerformance, } from '../learning/storage.js';
|
|
22
22
|
import { extractPatterns } from '../learning/pattern-extractor.js';
|
|
23
23
|
import { extractPatterns as extractTaskPatterns, computePatternConfidence } from '../learning/pattern-matcher.js';
|
|
24
24
|
import { updatePreferences, createDefaultPreferences } from '../learning/preference-learner.js';
|
|
@@ -27,13 +27,14 @@ import { generatePromptPatches, previewPatches, applyPromptPatches } from '../le
|
|
|
27
27
|
import { readDiscoveries, recordDiscovery } from '../learning/discovery.js';
|
|
28
28
|
import { migrateNotepads } from '../learning/migrate-notepads.js';
|
|
29
29
|
import { generateLearningStats, formatLearningStats } from '../learning/stats.js';
|
|
30
|
-
import { cleanupLearning, formatCleanupResult } from '../learning/cleanup.js';
|
|
30
|
+
import { cleanupLearning, formatCleanupResult, collectProjectDirStats } from '../learning/cleanup.js';
|
|
31
|
+
import { resolveProjectRoot, deriveProjectSlug, getProjectScopedDir } from '../learning/project-resolver.js';
|
|
31
32
|
import { getWarningThreshold } from '../learning/baselines.js';
|
|
32
33
|
import { calculateCost, DEFAULT_PRICING } from '../learning/pricing.js';
|
|
33
34
|
import { getTokenUsage, hasEfficiencyMetrics, safeTokenTotal } from '../learning/utils.js';
|
|
34
35
|
import { getSessionStatePath } from '../learning/session-state.js';
|
|
35
36
|
import { randomUUID } from 'crypto';
|
|
36
|
-
import { rmSync, appendFileSync } from 'fs';
|
|
37
|
+
import { rmSync, appendFileSync, readdirSync, statSync } from 'fs';
|
|
37
38
|
import { showMetrics, exportMetrics, analyzeMetrics, cleanMetrics } from './commands/metrics.js';
|
|
38
39
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
39
40
|
// Try to load package.json for version
|
|
@@ -574,18 +575,72 @@ program
|
|
|
574
575
|
.option('--suggest', 'Show suggested prompt improvements')
|
|
575
576
|
.option('--apply', 'Apply suggested improvements')
|
|
576
577
|
.option('-f, --forget', 'Forget all learnings')
|
|
577
|
-
.option('-p, --project', '
|
|
578
|
-
.option('-e, --export', 'Export
|
|
578
|
+
.option('-p, --project [slug]', 'Project slug for --forget; omit value to use current project')
|
|
579
|
+
.option('-e, --export [file]', 'Export current project data to file or stdout')
|
|
579
580
|
.option('-i, --import <file>', 'Import learnings from JSON')
|
|
580
581
|
.option('--efficiency', 'Show agent efficiency rankings and token metrics')
|
|
581
582
|
.option('--show-costs', 'Show cost breakdown by model and agent')
|
|
582
583
|
.option('--budget-status', 'Show current session token budget status')
|
|
583
584
|
.option('--last-session', 'Show last session summary')
|
|
584
585
|
.option('--sessions [n]', 'Show last N sessions (default: 10)')
|
|
586
|
+
.option('--global', 'Show global learning data, bypassing project scoping')
|
|
587
|
+
.option('--all-projects', 'List all project directories with stats')
|
|
588
|
+
.option('--confirm', 'Confirm destructive operations (required for --forget)')
|
|
585
589
|
.action(async (options) => {
|
|
586
590
|
const learningDir = getLearningDir();
|
|
591
|
+
function resolveProjectContext() {
|
|
592
|
+
if (options.global) {
|
|
593
|
+
return { projectPath: null, isInProject: false };
|
|
594
|
+
}
|
|
595
|
+
try {
|
|
596
|
+
const resolved = resolveProjectRoot(process.cwd());
|
|
597
|
+
const cwd = resolve(process.cwd());
|
|
598
|
+
if (resolved === cwd) {
|
|
599
|
+
return { projectPath: null, isInProject: false };
|
|
600
|
+
}
|
|
601
|
+
return { projectPath: resolved, isInProject: true };
|
|
602
|
+
}
|
|
603
|
+
catch {
|
|
604
|
+
return { projectPath: null, isInProject: false };
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
if (options.allProjects) {
|
|
608
|
+
try {
|
|
609
|
+
const projectsDir = join(getLearningDir(), 'projects');
|
|
610
|
+
const stats = collectProjectDirStats(projectsDir);
|
|
611
|
+
if (stats.length === 0) {
|
|
612
|
+
console.log('No project directories found.');
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
const slugW = 40, dateW = 22, sizeW = 10, feedW = 10, sessW = 8;
|
|
616
|
+
const header = 'Project'.padEnd(slugW) + 'Last Modified'.padEnd(dateW) + 'Size'.padStart(sizeW) + 'Feedback'.padStart(feedW) + 'Sessions'.padStart(sessW);
|
|
617
|
+
const divider = '-'.repeat(slugW + dateW + sizeW + feedW + sessW);
|
|
618
|
+
console.log(header);
|
|
619
|
+
console.log(divider);
|
|
620
|
+
for (const s of stats) {
|
|
621
|
+
const sizeKb = (s.sizeBytes / 1024).toFixed(0) + ' KB';
|
|
622
|
+
const dateStr = s.lastModified.toISOString().replace('T', ' ').substring(0, 16);
|
|
623
|
+
const line = s.slug.substring(0, slugW).padEnd(slugW)
|
|
624
|
+
+ dateStr.padEnd(dateW)
|
|
625
|
+
+ sizeKb.padStart(sizeW)
|
|
626
|
+
+ String(s.feedbackCount).padStart(feedW)
|
|
627
|
+
+ String(s.sessionCount).padStart(sessW);
|
|
628
|
+
console.log(line);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
catch (err) {
|
|
632
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
633
|
+
console.error(`[Olympus] Failed to list project directories: ${msg}`);
|
|
634
|
+
}
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
587
637
|
if (options.lastSession) {
|
|
588
|
-
const
|
|
638
|
+
const { projectPath: lsProjectPath } = resolveProjectContext();
|
|
639
|
+
if (!lsProjectPath && !options.global) {
|
|
640
|
+
console.log('Not inside a recognized project directory. Showing global data.');
|
|
641
|
+
}
|
|
642
|
+
const lsSummaries = loadSessionSummaries(lsProjectPath ?? undefined);
|
|
643
|
+
const summary = lsSummaries.length > 0 ? lsSummaries[lsSummaries.length - 1] : null;
|
|
589
644
|
if (!summary) {
|
|
590
645
|
console.log(chalk.yellow('No session summaries recorded yet. Complete a session first.'));
|
|
591
646
|
return;
|
|
@@ -615,9 +670,13 @@ program
|
|
|
615
670
|
return;
|
|
616
671
|
}
|
|
617
672
|
if (options.sessions !== undefined) {
|
|
673
|
+
const { projectPath: sessProjectPath } = resolveProjectContext();
|
|
674
|
+
if (!sessProjectPath && !options.global) {
|
|
675
|
+
console.log('Not inside a recognized project directory. Showing global data.');
|
|
676
|
+
}
|
|
618
677
|
const n = typeof options.sessions === 'string' ? parseInt(options.sessions) : 10;
|
|
619
678
|
const count = isNaN(n) ? 10 : n;
|
|
620
|
-
const allSummaries = loadSessionSummaries();
|
|
679
|
+
const allSummaries = loadSessionSummaries(sessProjectPath ?? undefined);
|
|
621
680
|
if (allSummaries.length === 0) {
|
|
622
681
|
console.log(chalk.yellow('No session summaries recorded yet. Complete a session first.'));
|
|
623
682
|
return;
|
|
@@ -669,6 +728,24 @@ program
|
|
|
669
728
|
if (options.stats) {
|
|
670
729
|
const stats = generateLearningStats(process.cwd());
|
|
671
730
|
console.log(formatLearningStats(stats));
|
|
731
|
+
try {
|
|
732
|
+
const projectsDir = join(getLearningDir(), 'projects');
|
|
733
|
+
const projStats = collectProjectDirStats(projectsDir);
|
|
734
|
+
if (projStats.length > 0) {
|
|
735
|
+
console.log('\nPer-Project Storage:');
|
|
736
|
+
let totalBytes = 0;
|
|
737
|
+
for (const ps of projStats) {
|
|
738
|
+
const sizeKb = (ps.sizeBytes / 1024).toFixed(0) + ' KB';
|
|
739
|
+
console.log(` ${ps.slug.padEnd(40)} ${sizeKb.padStart(8)}`);
|
|
740
|
+
totalBytes += ps.sizeBytes;
|
|
741
|
+
}
|
|
742
|
+
const totalKb = (totalBytes / 1024).toFixed(0) + ' KB';
|
|
743
|
+
console.log(` ${'-'.repeat(49)}`);
|
|
744
|
+
console.log(` Total (${projStats.length} project${projStats.length === 1 ? '' : 's'}):${' '.repeat(Math.max(0, 33 - String(projStats.length).length - 10))} ${totalKb.padStart(8)}`);
|
|
745
|
+
console.log(`\nGlobal learning directory: ${getLearningDir()} (${totalKb})`);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
catch { }
|
|
672
749
|
return;
|
|
673
750
|
}
|
|
674
751
|
if (options.cleanup) {
|
|
@@ -682,10 +759,14 @@ program
|
|
|
682
759
|
return;
|
|
683
760
|
}
|
|
684
761
|
if (options.show) {
|
|
762
|
+
const { projectPath: showProjectPath, isInProject: showIsInProject } = resolveProjectContext();
|
|
763
|
+
if (!showIsInProject && !options.global) {
|
|
764
|
+
console.log('Not inside a recognized project directory. Showing global data.');
|
|
765
|
+
}
|
|
685
766
|
console.log(chalk.blue.bold('\n╭─────────────────────────────────────────────────────────────╮'));
|
|
686
767
|
console.log(chalk.blue.bold('│ OLYMPUS LEARNING STATUS │'));
|
|
687
768
|
console.log(chalk.blue.bold('╰─────────────────────────────────────────────────────────────╯\n'));
|
|
688
|
-
const feedback = readFeedbackLog();
|
|
769
|
+
const feedback = readFeedbackLog(showProjectPath ?? undefined);
|
|
689
770
|
const revisions = feedback.filter(f => f.event_type === 'revision').length;
|
|
690
771
|
const cancellations = feedback.filter(f => f.event_type === 'cancellation').length;
|
|
691
772
|
const successes = feedback.filter(f => f.event_type === 'success').length;
|
|
@@ -698,8 +779,18 @@ program
|
|
|
698
779
|
console.log(` • Verbosity: ${prefs.verbosity}`);
|
|
699
780
|
if (prefs.autonomy !== 'unknown')
|
|
700
781
|
console.log(` • Autonomy: ${prefs.autonomy}`);
|
|
701
|
-
|
|
702
|
-
|
|
782
|
+
const filteredRules = prefs.explicit_rules.filter((r) => {
|
|
783
|
+
if (typeof r === 'object' && r !== null && 'rule' in r) {
|
|
784
|
+
const rObj = r;
|
|
785
|
+
return !showProjectPath || !rObj.project_path || rObj.project_path === showProjectPath;
|
|
786
|
+
}
|
|
787
|
+
return true;
|
|
788
|
+
});
|
|
789
|
+
for (const rule of filteredRules.slice(0, 3)) {
|
|
790
|
+
const ruleText = typeof rule === 'object' && rule !== null && 'rule' in rule
|
|
791
|
+
? rule.rule
|
|
792
|
+
: String(rule);
|
|
793
|
+
console.log(` * ${ruleText}`);
|
|
703
794
|
}
|
|
704
795
|
console.log('');
|
|
705
796
|
}
|
|
@@ -710,7 +801,7 @@ program
|
|
|
710
801
|
}
|
|
711
802
|
console.log('');
|
|
712
803
|
}
|
|
713
|
-
const agentPerf =
|
|
804
|
+
const agentPerf = readAgentPerformance(showProjectPath ?? undefined);
|
|
714
805
|
if (Object.keys(agentPerf).length > 0) {
|
|
715
806
|
console.log(chalk.white('🤖 Agent Performance:'));
|
|
716
807
|
for (const [name, perf] of Object.entries(agentPerf)) {
|
|
@@ -719,7 +810,16 @@ program
|
|
|
719
810
|
}
|
|
720
811
|
console.log('');
|
|
721
812
|
}
|
|
722
|
-
|
|
813
|
+
const showSummaries = loadSessionSummaries(showProjectPath ?? undefined);
|
|
814
|
+
if (showSummaries.length > 0) {
|
|
815
|
+
console.log(chalk.white('📅 Sessions:'));
|
|
816
|
+
console.log(` • Total recorded: ${showSummaries.length}`);
|
|
817
|
+
const lastS = showSummaries[showSummaries.length - 1];
|
|
818
|
+
if (lastS) {
|
|
819
|
+
console.log(` • Last: ${new Date(lastS.started_at).toLocaleString()}`);
|
|
820
|
+
}
|
|
821
|
+
console.log('');
|
|
822
|
+
}
|
|
723
823
|
const discoveries = readDiscoveries(process.cwd());
|
|
724
824
|
if (discoveries.total_discoveries > 0) {
|
|
725
825
|
console.log(chalk.white('💡 Discoveries:'));
|
|
@@ -734,7 +834,6 @@ program
|
|
|
734
834
|
}
|
|
735
835
|
console.log('');
|
|
736
836
|
}
|
|
737
|
-
// Show auto-discovery configuration status
|
|
738
837
|
try {
|
|
739
838
|
const { loadDiscoveryConfig } = await import('../learning/config.js');
|
|
740
839
|
const discoveryConfig = loadDiscoveryConfig(process.cwd());
|
|
@@ -743,7 +842,6 @@ program
|
|
|
743
842
|
console.log(` • Min Confidence: ${discoveryConfig.minConfidence}`);
|
|
744
843
|
console.log(` • Limits: ${discoveryConfig.maxPerSession}/session, ${discoveryConfig.maxPerDay}/day`);
|
|
745
844
|
console.log(` • Dedup Window: ${discoveryConfig.deduplicationWindowDays} days`);
|
|
746
|
-
// Show recent auto-discoveries with confidence scores
|
|
747
845
|
if (discoveries.total_discoveries > 0) {
|
|
748
846
|
const recentAuto = [...discoveries.project_discoveries]
|
|
749
847
|
.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
|
|
@@ -760,29 +858,31 @@ program
|
|
|
760
858
|
console.log('');
|
|
761
859
|
}
|
|
762
860
|
catch {
|
|
763
|
-
// Silent failure - auto-discovery status is non-critical
|
|
764
861
|
}
|
|
765
862
|
return;
|
|
766
863
|
}
|
|
767
864
|
if (options.analyze) {
|
|
865
|
+
const { projectPath: analyzeProjectPath } = resolveProjectContext();
|
|
866
|
+
if (!analyzeProjectPath && !options.global) {
|
|
867
|
+
console.log('Not inside a recognized project directory. Showing global data.');
|
|
868
|
+
}
|
|
768
869
|
console.log(chalk.blue('Analyzing feedback...\n'));
|
|
769
|
-
const feedback = readFeedbackLog();
|
|
770
|
-
const patterns = extractPatterns(feedback);
|
|
870
|
+
const feedback = readFeedbackLog(analyzeProjectPath ?? undefined);
|
|
871
|
+
const patterns = extractPatterns(feedback, undefined, undefined, analyzeProjectPath ?? undefined);
|
|
771
872
|
console.log(chalk.white(`Found ${patterns.length} patterns:\n`));
|
|
772
873
|
for (const p of patterns) {
|
|
773
874
|
console.log(` [${(p.confidence * 100).toFixed(0)}%] ${p.pattern.substring(0, 60)}...`);
|
|
774
875
|
console.log(chalk.gray(` Seen ${p.evidence_count}x, scope: ${p.scope}, category: ${p.category}`));
|
|
775
876
|
}
|
|
776
|
-
// Update preferences
|
|
777
877
|
const currentPrefs = readJsonFile(join(learningDir, 'user-preferences.json'), createDefaultPreferences());
|
|
778
|
-
const updatedPrefs = updatePreferences(currentPrefs, feedback, patterns);
|
|
878
|
+
const updatedPrefs = updatePreferences(currentPrefs, feedback, patterns, analyzeProjectPath ?? undefined);
|
|
779
879
|
writeJsonFile(join(learningDir, 'user-preferences.json'), updatedPrefs);
|
|
780
|
-
// Update agent performance
|
|
781
880
|
const agentPerf = evaluateAgentPerformance(feedback);
|
|
782
|
-
// Extract task patterns for routing recommendations
|
|
783
881
|
const agentPerfObj = Object.fromEntries(agentPerf);
|
|
784
|
-
|
|
785
|
-
|
|
882
|
+
const agentPerfWritePath = analyzeProjectPath
|
|
883
|
+
? join(getProjectScopedDir(analyzeProjectPath), 'agent-performance.json')
|
|
884
|
+
: join(learningDir, 'agent-performance.json');
|
|
885
|
+
const existingPerf = readJsonFile(agentPerfWritePath, {});
|
|
786
886
|
// Analyze task patterns per agent
|
|
787
887
|
for (const [agentName, perf] of Object.entries(agentPerfObj)) {
|
|
788
888
|
const agentFeedback = feedback.filter(f => f.agent_used === agentName);
|
|
@@ -815,15 +915,13 @@ program
|
|
|
815
915
|
});
|
|
816
916
|
}
|
|
817
917
|
if (taskPatterns.length > 0) {
|
|
818
|
-
perf.task_patterns = taskPatterns.slice(0, 10);
|
|
918
|
+
perf.task_patterns = taskPatterns.slice(0, 10);
|
|
819
919
|
}
|
|
820
920
|
else if (existingPerf[agentName]?.task_patterns) {
|
|
821
|
-
// Preserve existing patterns if no new ones found
|
|
822
921
|
perf.task_patterns = existingPerf[agentName].task_patterns;
|
|
823
922
|
}
|
|
824
923
|
}
|
|
825
|
-
|
|
826
|
-
writeJsonFile(join(learningDir, 'agent-performance.json'), agentPerfObj);
|
|
924
|
+
writeJsonFile(agentPerfWritePath, agentPerfObj);
|
|
827
925
|
const totalPatterns = Object.values(agentPerfObj).reduce((sum, p) => sum + (p.task_patterns?.length || 0), 0);
|
|
828
926
|
if (totalPatterns > 0) {
|
|
829
927
|
console.log(chalk.green(`✓ ${totalPatterns} task patterns extracted for routing optimization.`));
|
|
@@ -867,19 +965,42 @@ program
|
|
|
867
965
|
}
|
|
868
966
|
if (options.forget) {
|
|
869
967
|
if (options.project) {
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
968
|
+
try {
|
|
969
|
+
const targetSlug = typeof options.project === 'string'
|
|
970
|
+
? options.project
|
|
971
|
+
: deriveProjectSlug(resolveProjectRoot(process.cwd()));
|
|
972
|
+
const targetPath = join(getLearningDir(), 'projects', targetSlug);
|
|
973
|
+
if (!options.confirm) {
|
|
974
|
+
if (!existsSync(targetPath)) {
|
|
975
|
+
console.log(`Project directory not found: ${targetSlug}`);
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
978
|
+
const files = readdirSync(targetPath);
|
|
979
|
+
console.log(`Would delete: ${targetPath}`);
|
|
980
|
+
for (const f of files) {
|
|
981
|
+
const fp = join(targetPath, f);
|
|
982
|
+
let sz = 0;
|
|
983
|
+
try {
|
|
984
|
+
sz = statSync(fp).size;
|
|
985
|
+
}
|
|
986
|
+
catch { }
|
|
987
|
+
console.log(` ${f} (${sz} bytes)`);
|
|
988
|
+
}
|
|
989
|
+
console.log('Run with --confirm to delete.');
|
|
990
|
+
}
|
|
991
|
+
else {
|
|
992
|
+
if (!existsSync(targetPath)) {
|
|
993
|
+
console.log(`Project directory not found: ${targetSlug}`);
|
|
994
|
+
return;
|
|
995
|
+
}
|
|
996
|
+
const fileCount = readdirSync(targetPath).length;
|
|
997
|
+
rmSync(targetPath, { recursive: true, force: true });
|
|
998
|
+
console.log(chalk.green(`Deleted project data for ${targetSlug} (${fileCount} files removed).`));
|
|
999
|
+
}
|
|
877
1000
|
}
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
rmSync(sessionStatePath);
|
|
882
|
-
console.log(chalk.green('✓ Session state deleted.'));
|
|
1001
|
+
catch (err) {
|
|
1002
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1003
|
+
console.error(`[Olympus] Failed to forget project: ${msg}`);
|
|
883
1004
|
}
|
|
884
1005
|
}
|
|
885
1006
|
else {
|
|
@@ -894,15 +1015,35 @@ program
|
|
|
894
1015
|
}
|
|
895
1016
|
return;
|
|
896
1017
|
}
|
|
897
|
-
if (options.export) {
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
1018
|
+
if (options.export !== undefined) {
|
|
1019
|
+
try {
|
|
1020
|
+
const { projectPath: exportProjectPath, isInProject: exportIsInProject } = resolveProjectContext();
|
|
1021
|
+
if (!exportIsInProject) {
|
|
1022
|
+
console.log('Not inside a recognized project directory. Showing global data.');
|
|
1023
|
+
return;
|
|
1024
|
+
}
|
|
1025
|
+
const exportProjDir = getProjectScopedDir(exportProjectPath);
|
|
1026
|
+
const readRaw = (file) => {
|
|
1027
|
+
const p = join(exportProjDir, file);
|
|
1028
|
+
return existsSync(p) ? readFileSync(p, 'utf-8') : null;
|
|
1029
|
+
};
|
|
1030
|
+
const output = JSON.stringify({
|
|
1031
|
+
feedback_log: readRaw('feedback-log.jsonl'),
|
|
1032
|
+
agent_performance: readRaw('agent-performance.json'),
|
|
1033
|
+
session_insights: readRaw('session-insights.json'),
|
|
1034
|
+
}, null, 2);
|
|
1035
|
+
if (typeof options.export === 'string' && options.export.length > 0) {
|
|
1036
|
+
writeFileSync(options.export, output, 'utf-8');
|
|
1037
|
+
console.log(chalk.green(`✓ Exported to ${options.export}`));
|
|
1038
|
+
}
|
|
1039
|
+
else {
|
|
1040
|
+
console.log(output);
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
catch (err) {
|
|
1044
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1045
|
+
console.error(`[Olympus] Failed to export: ${msg}`);
|
|
1046
|
+
}
|
|
906
1047
|
return;
|
|
907
1048
|
}
|
|
908
1049
|
if (options.import) {
|
|
@@ -932,9 +1073,12 @@ program
|
|
|
932
1073
|
return;
|
|
933
1074
|
}
|
|
934
1075
|
if (options.efficiency) {
|
|
935
|
-
const
|
|
936
|
-
|
|
937
|
-
|
|
1076
|
+
const { projectPath: effProjectPath } = resolveProjectContext();
|
|
1077
|
+
if (!effProjectPath && !options.global) {
|
|
1078
|
+
console.log('Not inside a recognized project directory. Showing global data.');
|
|
1079
|
+
}
|
|
1080
|
+
const feedback = readFeedbackLog(effProjectPath ?? undefined);
|
|
1081
|
+
const agentPerfRaw = readAgentPerformance(effProjectPath ?? undefined);
|
|
938
1082
|
const agentPerf = {};
|
|
939
1083
|
const agentNames = new Set(feedback.filter(f => f.agent_used).map(f => f.agent_used));
|
|
940
1084
|
for (const agentName of agentNames) {
|
|
@@ -943,7 +1087,6 @@ program
|
|
|
943
1087
|
agentPerf[agentName] = perf;
|
|
944
1088
|
}
|
|
945
1089
|
}
|
|
946
|
-
// Merge with existing performance data
|
|
947
1090
|
Object.assign(agentPerf, agentPerfRaw);
|
|
948
1091
|
const agents = Object.values(agentPerf).filter(p => hasEfficiencyMetrics(p));
|
|
949
1092
|
if (agents.length === 0) {
|