olympus-ai 2.5.2 → 2.6.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 (126) hide show
  1. package/dist/__tests__/learning/agent-evaluator.test.d.ts +2 -0
  2. package/dist/__tests__/learning/agent-evaluator.test.d.ts.map +1 -0
  3. package/dist/__tests__/learning/agent-evaluator.test.js +29 -0
  4. package/dist/__tests__/learning/agent-evaluator.test.js.map +1 -0
  5. package/dist/__tests__/learning/discovery.test.d.ts +2 -0
  6. package/dist/__tests__/learning/discovery.test.d.ts.map +1 -0
  7. package/dist/__tests__/learning/discovery.test.js +70 -0
  8. package/dist/__tests__/learning/discovery.test.js.map +1 -0
  9. package/dist/__tests__/learning/fixtures/mock-feedback.d.ts +14 -0
  10. package/dist/__tests__/learning/fixtures/mock-feedback.d.ts.map +1 -0
  11. package/dist/__tests__/learning/fixtures/mock-feedback.js +146 -0
  12. package/dist/__tests__/learning/fixtures/mock-feedback.js.map +1 -0
  13. package/dist/__tests__/learning/pattern-extractor.test.d.ts +2 -0
  14. package/dist/__tests__/learning/pattern-extractor.test.d.ts.map +1 -0
  15. package/dist/__tests__/learning/pattern-extractor.test.js +30 -0
  16. package/dist/__tests__/learning/pattern-extractor.test.js.map +1 -0
  17. package/dist/__tests__/learning/revision-detector.test.d.ts +2 -0
  18. package/dist/__tests__/learning/revision-detector.test.d.ts.map +1 -0
  19. package/dist/__tests__/learning/revision-detector.test.js +54 -0
  20. package/dist/__tests__/learning/revision-detector.test.js.map +1 -0
  21. package/dist/cli/index.js +264 -0
  22. package/dist/cli/index.js.map +1 -1
  23. package/dist/hooks/agent-usage-reminder/index.d.ts +1 -0
  24. package/dist/hooks/agent-usage-reminder/index.d.ts.map +1 -1
  25. package/dist/hooks/agent-usage-reminder/index.js +107 -0
  26. package/dist/hooks/agent-usage-reminder/index.js.map +1 -1
  27. package/dist/hooks/agent-usage-reminder/index.test.d.ts +5 -0
  28. package/dist/hooks/agent-usage-reminder/index.test.d.ts.map +1 -0
  29. package/dist/hooks/agent-usage-reminder/index.test.js +141 -0
  30. package/dist/hooks/agent-usage-reminder/index.test.js.map +1 -0
  31. package/dist/hooks/bridge.d.ts.map +1 -1
  32. package/dist/hooks/bridge.js +14 -2
  33. package/dist/hooks/bridge.js.map +1 -1
  34. package/dist/hooks/keyword-detector/index.d.ts +1 -1
  35. package/dist/hooks/keyword-detector/index.d.ts.map +1 -1
  36. package/dist/hooks/keyword-detector/index.js +2 -1
  37. package/dist/hooks/keyword-detector/index.js.map +1 -1
  38. package/dist/hooks/olympus-hooks.cjs +162 -67
  39. package/dist/hooks/olympus-state/index.d.ts +69 -0
  40. package/dist/hooks/olympus-state/index.d.ts.map +1 -0
  41. package/dist/hooks/olympus-state/index.js +226 -0
  42. package/dist/hooks/olympus-state/index.js.map +1 -0
  43. package/dist/hooks/persistent-mode/index.d.ts +7 -6
  44. package/dist/hooks/persistent-mode/index.d.ts.map +1 -1
  45. package/dist/hooks/persistent-mode/index.js +94 -5
  46. package/dist/hooks/persistent-mode/index.js.map +1 -1
  47. package/dist/hooks/registrations/session-start.d.ts.map +1 -1
  48. package/dist/hooks/registrations/session-start.js +26 -0
  49. package/dist/hooks/registrations/session-start.js.map +1 -1
  50. package/dist/hooks/registrations/stop.d.ts.map +1 -1
  51. package/dist/hooks/registrations/stop.js +25 -0
  52. package/dist/hooks/registrations/stop.js.map +1 -1
  53. package/dist/hooks/registrations/user-prompt-submit.d.ts.map +1 -1
  54. package/dist/hooks/registrations/user-prompt-submit.js +34 -0
  55. package/dist/hooks/registrations/user-prompt-submit.js.map +1 -1
  56. package/dist/installer/hooks.d.ts +7 -1
  57. package/dist/installer/hooks.d.ts.map +1 -1
  58. package/dist/installer/hooks.js +61 -2
  59. package/dist/installer/hooks.js.map +1 -1
  60. package/dist/installer/index.d.ts +1 -1
  61. package/dist/installer/index.d.ts.map +1 -1
  62. package/dist/installer/index.js +40 -14
  63. package/dist/installer/index.js.map +1 -1
  64. package/dist/learning/agent-evaluator.d.ts +6 -0
  65. package/dist/learning/agent-evaluator.d.ts.map +1 -0
  66. package/dist/learning/agent-evaluator.js +116 -0
  67. package/dist/learning/agent-evaluator.js.map +1 -0
  68. package/dist/learning/discovery-validator.d.ts +21 -0
  69. package/dist/learning/discovery-validator.d.ts.map +1 -0
  70. package/dist/learning/discovery-validator.js +75 -0
  71. package/dist/learning/discovery-validator.js.map +1 -0
  72. package/dist/learning/discovery.d.ts +20 -0
  73. package/dist/learning/discovery.d.ts.map +1 -0
  74. package/dist/learning/discovery.js +141 -0
  75. package/dist/learning/discovery.js.map +1 -0
  76. package/dist/learning/hooks/cancellation-detector.d.ts +8 -0
  77. package/dist/learning/hooks/cancellation-detector.d.ts.map +1 -0
  78. package/dist/learning/hooks/cancellation-detector.js +64 -0
  79. package/dist/learning/hooks/cancellation-detector.js.map +1 -0
  80. package/dist/learning/hooks/learned-context.d.ts +6 -0
  81. package/dist/learning/hooks/learned-context.d.ts.map +1 -0
  82. package/dist/learning/hooks/learned-context.js +104 -0
  83. package/dist/learning/hooks/learned-context.js.map +1 -0
  84. package/dist/learning/hooks/revision-detector.d.ts +9 -0
  85. package/dist/learning/hooks/revision-detector.d.ts.map +1 -0
  86. package/dist/learning/hooks/revision-detector.js +92 -0
  87. package/dist/learning/hooks/revision-detector.js.map +1 -0
  88. package/dist/learning/hooks/success-detector.d.ts +4 -0
  89. package/dist/learning/hooks/success-detector.d.ts.map +1 -0
  90. package/dist/learning/hooks/success-detector.js +58 -0
  91. package/dist/learning/hooks/success-detector.js.map +1 -0
  92. package/dist/learning/index.d.ts +10 -0
  93. package/dist/learning/index.d.ts.map +1 -0
  94. package/dist/learning/index.js +17 -0
  95. package/dist/learning/index.js.map +1 -0
  96. package/dist/learning/migrate-notepads.d.ts +6 -0
  97. package/dist/learning/migrate-notepads.d.ts.map +1 -0
  98. package/dist/learning/migrate-notepads.js +77 -0
  99. package/dist/learning/migrate-notepads.js.map +1 -0
  100. package/dist/learning/pattern-extractor.d.ts +6 -0
  101. package/dist/learning/pattern-extractor.d.ts.map +1 -0
  102. package/dist/learning/pattern-extractor.js +106 -0
  103. package/dist/learning/pattern-extractor.js.map +1 -0
  104. package/dist/learning/preference-learner.d.ts +6 -0
  105. package/dist/learning/preference-learner.d.ts.map +1 -0
  106. package/dist/learning/preference-learner.js +96 -0
  107. package/dist/learning/preference-learner.js.map +1 -0
  108. package/dist/learning/prompt-patcher.d.ts +24 -0
  109. package/dist/learning/prompt-patcher.d.ts.map +1 -0
  110. package/dist/learning/prompt-patcher.js +120 -0
  111. package/dist/learning/prompt-patcher.js.map +1 -0
  112. package/dist/learning/session-state.d.ts +18 -0
  113. package/dist/learning/session-state.d.ts.map +1 -0
  114. package/dist/learning/session-state.js +78 -0
  115. package/dist/learning/session-state.js.map +1 -0
  116. package/dist/learning/storage.d.ts +18 -0
  117. package/dist/learning/storage.d.ts.map +1 -0
  118. package/dist/learning/storage.js +74 -0
  119. package/dist/learning/storage.js.map +1 -0
  120. package/dist/learning/types.d.ts +138 -0
  121. package/dist/learning/types.d.ts.map +1 -0
  122. package/dist/learning/types.js +6 -0
  123. package/dist/learning/types.js.map +1 -0
  124. package/dist/shared/types.d.ts +12 -0
  125. package/dist/shared/types.d.ts.map +1 -1
  126. package/package.json +4 -3
@@ -0,0 +1,77 @@
1
+ import { readdirSync, readFileSync, existsSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { recordDiscovery } from './discovery.js';
4
+ /**
5
+ * Migrate existing notepad content to discoveries.
6
+ * This is a one-time migration utility.
7
+ */
8
+ export async function migrateNotepads(projectPath) {
9
+ const notepadsDir = join(projectPath, '.olympus', 'notepads');
10
+ if (!existsSync(notepadsDir)) {
11
+ return 0;
12
+ }
13
+ let migratedCount = 0;
14
+ // Recursively find all .md files
15
+ const planDirs = readdirSync(notepadsDir, { withFileTypes: true })
16
+ .filter(d => d.isDirectory())
17
+ .map(d => d.name);
18
+ for (const planDir of planDirs) {
19
+ const planPath = join(notepadsDir, planDir);
20
+ const files = readdirSync(planPath).filter(f => f.endsWith('.md'));
21
+ for (const file of files) {
22
+ const content = readFileSync(join(planPath, file), 'utf-8');
23
+ // Parse markdown sections into discoveries
24
+ const discoveries = parseNotepadContent(content, planDir);
25
+ for (const d of discoveries) {
26
+ recordDiscovery({
27
+ ...d,
28
+ session_id: 'migration',
29
+ project_path: projectPath,
30
+ agent_name: 'migration',
31
+ confidence: 0.7, // Lower confidence for migrated content
32
+ scope: 'project',
33
+ });
34
+ migratedCount++;
35
+ }
36
+ }
37
+ }
38
+ return migratedCount;
39
+ }
40
+ function parseNotepadContent(content, taskContext) {
41
+ // Simple parsing: each H3 (###) becomes a discovery
42
+ const sections = content.split(/^### /m).slice(1);
43
+ return sections.map(section => {
44
+ const lines = section.split('\n');
45
+ const summary = lines[0].trim().slice(0, 100);
46
+ const details = lines.slice(1).join('\n').trim();
47
+ return {
48
+ category: inferCategory(summary, details),
49
+ summary,
50
+ details: details || summary,
51
+ task_context: taskContext,
52
+ };
53
+ }).filter(d => d.summary.length >= 10 && d.details.length >= 20);
54
+ }
55
+ function inferCategory(summary, details) {
56
+ const text = (summary + ' ' + details).toLowerCase();
57
+ if (text.includes('performance') || text.includes('slow') || text.includes('optimize')) {
58
+ return 'performance';
59
+ }
60
+ if (text.includes('workaround') || text.includes('hack') || text.includes('fix')) {
61
+ return 'workaround';
62
+ }
63
+ if (text.includes('pattern') || text.includes('convention') || text.includes('style')) {
64
+ return 'pattern';
65
+ }
66
+ if (text.includes('gotcha') || text.includes('careful') || text.includes('warning')) {
67
+ return 'gotcha';
68
+ }
69
+ if (text.includes('dependency') || text.includes('package') || text.includes('install')) {
70
+ return 'dependency';
71
+ }
72
+ if (text.includes('config') || text.includes('environment') || text.includes('setting')) {
73
+ return 'configuration';
74
+ }
75
+ return 'technical_insight';
76
+ }
77
+ //# sourceMappingURL=migrate-notepads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate-notepads.js","sourceRoot":"","sources":["../../src/learning/migrate-notepads.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { FeedbackEntry, ExtractedPattern } from './types.js';
2
+ /** Calculate Jaccard similarity between two texts (exported for reuse) */
3
+ export declare function jaccardSimilarity(text1: string, text2: string): number;
4
+ /** Extract patterns from feedback log */
5
+ export declare function extractPatterns(feedbackLog: FeedbackEntry[], minOccurrences?: number): ExtractedPattern[];
6
+ //# sourceMappingURL=pattern-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-extractor.d.ts","sourceRoot":"","sources":["../../src/learning/pattern-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAkBlE,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQtE;AAgCD,yCAAyC;AACzC,wBAAgB,eAAe,CAC7B,WAAW,EAAE,aAAa,EAAE,EAC5B,cAAc,GAAE,MAAU,GACzB,gBAAgB,EAAE,CAqCpB"}
@@ -0,0 +1,106 @@
1
+ /** Extract n-grams from text for similarity comparison */
2
+ function extractNgrams(text, n = 3) {
3
+ const normalized = text.toLowerCase().replace(/[^\w\s]/g, '');
4
+ const words = normalized.split(/\s+/).filter(w => w.length > 0);
5
+ if (words.length < n) {
6
+ return new Set([normalized]);
7
+ }
8
+ const ngrams = new Set();
9
+ for (let i = 0; i <= words.length - n; i++) {
10
+ ngrams.add(words.slice(i, i + n).join(' '));
11
+ }
12
+ return ngrams;
13
+ }
14
+ /** Calculate Jaccard similarity between two texts (exported for reuse) */
15
+ export function jaccardSimilarity(text1, text2) {
16
+ const ngrams1 = extractNgrams(text1);
17
+ const ngrams2 = extractNgrams(text2);
18
+ const intersection = new Set([...ngrams1].filter(x => ngrams2.has(x)));
19
+ const union = new Set([...ngrams1, ...ngrams2]);
20
+ return union.size > 0 ? intersection.size / union.size : 0;
21
+ }
22
+ /** Group similar feedback entries */
23
+ function clusterFeedback(entries, similarityThreshold = 0.3) {
24
+ const clusters = [];
25
+ const assigned = new Set();
26
+ for (const entry of entries) {
27
+ if (assigned.has(entry.id))
28
+ continue;
29
+ const cluster = [entry];
30
+ assigned.add(entry.id);
31
+ for (const other of entries) {
32
+ if (assigned.has(other.id))
33
+ continue;
34
+ const similarity = jaccardSimilarity(entry.user_message, other.user_message);
35
+ if (similarity >= similarityThreshold) {
36
+ cluster.push(other);
37
+ assigned.add(other.id);
38
+ }
39
+ }
40
+ clusters.push(cluster);
41
+ }
42
+ return clusters;
43
+ }
44
+ /** Extract patterns from feedback log */
45
+ export function extractPatterns(feedbackLog, minOccurrences = 3) {
46
+ // Only analyze corrections and clarifications
47
+ const relevantFeedback = feedbackLog.filter(e => e.feedback_category === 'correction' ||
48
+ e.feedback_category === 'clarification' ||
49
+ e.feedback_category === 'explicit_preference');
50
+ const clusters = clusterFeedback(relevantFeedback);
51
+ return clusters
52
+ .filter(cluster => cluster.length >= minOccurrences)
53
+ .map(cluster => {
54
+ // Use the most recent entry as the pattern description
55
+ const mostRecent = cluster.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())[0];
56
+ // Calculate average confidence
57
+ const avgConfidence = cluster.reduce((sum, e) => sum + e.confidence, 0) / cluster.length;
58
+ // Determine scope
59
+ const projectPaths = new Set(cluster.map(e => e.project_path));
60
+ const scope = projectPaths.size === 1 ? 'project' : 'global';
61
+ // Categorize
62
+ const category = categorizePattern(cluster);
63
+ return {
64
+ pattern: generatePatternDescription(cluster),
65
+ confidence: avgConfidence,
66
+ evidence_count: cluster.length,
67
+ evidence_examples: cluster.slice(0, 3).map(e => e.user_message),
68
+ scope,
69
+ category,
70
+ };
71
+ });
72
+ }
73
+ /** Generate human-readable pattern description */
74
+ function generatePatternDescription(cluster) {
75
+ // Find common keywords in the cluster
76
+ const allWords = new Map();
77
+ for (const entry of cluster) {
78
+ const words = entry.user_message.toLowerCase()
79
+ .replace(/[^\w\s]/g, '')
80
+ .split(/\s+/)
81
+ .filter(w => w.length > 3);
82
+ for (const word of words) {
83
+ allWords.set(word, (allWords.get(word) || 0) + 1);
84
+ }
85
+ }
86
+ // Get top 3 most common words
87
+ const topWords = [...allWords.entries()]
88
+ .sort((a, b) => b[1] - a[1])
89
+ .slice(0, 3)
90
+ .map(([word]) => word);
91
+ // Return most recent message as base, with common themes noted
92
+ const mostRecent = cluster[0].user_message.substring(0, 100);
93
+ return mostRecent + (topWords.length > 0 ? ` [themes: ${topWords.join(', ')}]` : '');
94
+ }
95
+ /** Categorize pattern based on content */
96
+ function categorizePattern(cluster) {
97
+ const text = cluster.map(e => e.user_message).join(' ').toLowerCase();
98
+ if (/typescript|eslint|prettier|format|indent|naming/i.test(text))
99
+ return 'style';
100
+ if (/test|build|npm|yarn|run|command|install/i.test(text))
101
+ return 'tooling';
102
+ if (/verbose|brief|explain|detail|ask|confirm/i.test(text))
103
+ return 'communication';
104
+ return 'behavior';
105
+ }
106
+ //# sourceMappingURL=pattern-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-extractor.js","sourceRoot":"","sources":["../../src/learning/pattern-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { FeedbackEntry, UserPreferences, ExtractedPattern } from './types.js';
2
+ /** Update preferences based on new feedback */
3
+ export declare function updatePreferences(currentPrefs: UserPreferences, newFeedback: FeedbackEntry[], extractedPatterns: ExtractedPattern[]): UserPreferences;
4
+ /** Create default preferences object */
5
+ export declare function createDefaultPreferences(): UserPreferences;
6
+ //# sourceMappingURL=preference-learner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preference-learner.d.ts","sourceRoot":"","sources":["../../src/learning/preference-learner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAgEnF,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,eAAe,EAC7B,WAAW,EAAE,aAAa,EAAE,EAC5B,iBAAiB,EAAE,gBAAgB,EAAE,GACpC,eAAe,CAgDjB;AAED,wCAAwC;AACxC,wBAAgB,wBAAwB,IAAI,eAAe,CAE1D"}
@@ -0,0 +1,96 @@
1
+ import { jaccardSimilarity } from './pattern-extractor.js';
2
+ const DEFAULT_PREFERENCES = {
3
+ verbosity: 'unknown',
4
+ autonomy: 'unknown',
5
+ explanation_depth: 'unknown',
6
+ explicit_rules: [],
7
+ inferred_preferences: [],
8
+ recurring_corrections: [],
9
+ last_updated: new Date().toISOString(),
10
+ };
11
+ /** Preference decay factor - old preferences lose weight over time */
12
+ const DECAY_DAYS = 30;
13
+ /** Extract explicit preferences from "always/never" statements */
14
+ function extractExplicitPreferences(feedback) {
15
+ const explicit = feedback.filter(e => e.feedback_category === 'explicit_preference');
16
+ const rules = [];
17
+ for (const entry of explicit) {
18
+ // Extract the rule from statements like "always use TypeScript"
19
+ const alwaysMatch = entry.user_message.match(/always\s+(.+?)(?:\.|$)/i);
20
+ const neverMatch = entry.user_message.match(/never\s+(.+?)(?:\.|$)/i);
21
+ if (alwaysMatch)
22
+ rules.push(`Always: ${alwaysMatch[1].trim()}`);
23
+ if (neverMatch)
24
+ rules.push(`Never: ${neverMatch[1].trim()}`);
25
+ }
26
+ return [...new Set(rules)]; // Deduplicate
27
+ }
28
+ /** Infer verbosity preference from feedback patterns */
29
+ function inferVerbosity(feedback) {
30
+ const verboseComplaints = feedback.filter(e => /too (long|verbose|much|wordy)/i.test(e.user_message)).length;
31
+ const briefComplaints = feedback.filter(e => /more (detail|info|explanation)|too (brief|short)/i.test(e.user_message)).length;
32
+ if (verboseComplaints >= 3 && verboseComplaints > briefComplaints)
33
+ return 'concise';
34
+ if (briefComplaints >= 3 && briefComplaints > verboseComplaints)
35
+ return 'detailed';
36
+ return 'unknown';
37
+ }
38
+ /** Infer autonomy preference from feedback patterns */
39
+ function inferAutonomy(feedback) {
40
+ const askFirst = feedback.filter(e => /ask (me )?(first|before)|don't assume|confirm/i.test(e.user_message)).length;
41
+ const justDoIt = feedback.filter(e => /just (do|make|fix)|don't ask|stop asking/i.test(e.user_message)).length;
42
+ if (askFirst >= 3 && askFirst > justDoIt)
43
+ return 'ask_first';
44
+ if (justDoIt >= 3 && justDoIt > askFirst)
45
+ return 'just_do_it';
46
+ if (askFirst >= 2 && justDoIt >= 2)
47
+ return 'balanced';
48
+ return 'unknown';
49
+ }
50
+ /** Update preferences based on new feedback */
51
+ export function updatePreferences(currentPrefs, newFeedback, extractedPatterns) {
52
+ // Start with current preferences
53
+ const updated = { ...currentPrefs };
54
+ // Add new explicit rules
55
+ const newRules = extractExplicitPreferences(newFeedback);
56
+ updated.explicit_rules = [...new Set([...updated.explicit_rules, ...newRules])];
57
+ // Update verbosity if we have enough signal
58
+ const newVerbosity = inferVerbosity(newFeedback);
59
+ if (newVerbosity !== 'unknown') {
60
+ updated.verbosity = newVerbosity;
61
+ }
62
+ // Update autonomy if we have enough signal
63
+ const newAutonomy = inferAutonomy(newFeedback);
64
+ if (newAutonomy !== 'unknown') {
65
+ updated.autonomy = newAutonomy;
66
+ }
67
+ // Add inferred preferences from patterns
68
+ const inferred = extractedPatterns
69
+ .filter(p => p.confidence > 0.7 && p.scope === 'global')
70
+ .map(p => p.pattern);
71
+ updated.inferred_preferences = [...new Set([...updated.inferred_preferences, ...inferred])];
72
+ // Update recurring corrections
73
+ for (const pattern of extractedPatterns) {
74
+ const existing = updated.recurring_corrections.find(c => jaccardSimilarity(c.pattern, pattern.pattern) > 0.5);
75
+ if (existing) {
76
+ existing.count = pattern.evidence_count;
77
+ existing.last_seen = new Date().toISOString();
78
+ existing.examples = pattern.evidence_examples;
79
+ }
80
+ else {
81
+ updated.recurring_corrections.push({
82
+ pattern: pattern.pattern,
83
+ count: pattern.evidence_count,
84
+ last_seen: new Date().toISOString(),
85
+ examples: pattern.evidence_examples,
86
+ });
87
+ }
88
+ }
89
+ updated.last_updated = new Date().toISOString();
90
+ return updated;
91
+ }
92
+ /** Create default preferences object */
93
+ export function createDefaultPreferences() {
94
+ return { ...DEFAULT_PREFERENCES, last_updated: new Date().toISOString() };
95
+ }
96
+ //# sourceMappingURL=preference-learner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preference-learner.js","sourceRoot":"","sources":["../../src/learning/preference-learner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { AgentPerformance, UserPreferences } from './types.js';
2
+ export interface PromptPatch {
3
+ agent_name: string;
4
+ patch_type: 'append' | 'prepend';
5
+ content: string;
6
+ reason: string;
7
+ confidence: number;
8
+ evidence_count: number;
9
+ }
10
+ export interface PatchResult {
11
+ agent_name: string;
12
+ success: boolean;
13
+ backup_path?: string;
14
+ error?: string;
15
+ }
16
+ /** Generate prompt patches based on learnings */
17
+ export declare function generatePromptPatches(agentPerformance: Map<string, AgentPerformance>, userPreferences: UserPreferences): PromptPatch[];
18
+ /** Preview patches (dry run) */
19
+ export declare function previewPatches(patches: PromptPatch[]): string;
20
+ /** Apply patches to agent prompt files */
21
+ export declare function applyPromptPatches(patches: PromptPatch[], agentsDir?: string): PatchResult[];
22
+ /** Revert a patch using backup file */
23
+ export declare function revertPatch(backupPath: string): boolean;
24
+ //# sourceMappingURL=prompt-patcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-patcher.d.ts","sourceRoot":"","sources":["../../src/learning/prompt-patcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAKpE,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,QAAQ,GAAG,SAAS,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,iDAAiD;AACjD,wBAAgB,qBAAqB,CACnC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAC/C,eAAe,EAAE,eAAe,GAC/B,WAAW,EAAE,CA2Cf;AAED,gCAAgC;AAChC,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,CAa7D;AAED,0CAA0C;AAC1C,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,WAAW,EAAE,EACtB,SAAS,GAAE,MAA6C,GACvD,WAAW,EAAE,CAiDf;AAED,uCAAuC;AACvC,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAQvD"}
@@ -0,0 +1,120 @@
1
+ import { existsSync, readFileSync, writeFileSync, copyFileSync, readdirSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+ /** Generate prompt patches based on learnings */
5
+ export function generatePromptPatches(agentPerformance, userPreferences) {
6
+ const patches = [];
7
+ // Generate patches from agent failure patterns
8
+ for (const [agent, perf] of agentPerformance) {
9
+ for (const failure of perf.failure_patterns) {
10
+ if (failure.count >= 3) {
11
+ patches.push({
12
+ agent_name: agent,
13
+ patch_type: 'append',
14
+ content: `\n\n## Learned: ${failure.pattern}\nBe extra careful with: ${failure.pattern}. This has been flagged ${failure.count} times.`,
15
+ reason: `Agent failed on "${failure.pattern}" ${failure.count} times`,
16
+ confidence: Math.min(0.5 + failure.count * 0.1, 0.95),
17
+ evidence_count: failure.count,
18
+ });
19
+ }
20
+ }
21
+ }
22
+ // Generate patches from user preferences
23
+ if (userPreferences.verbosity === 'concise') {
24
+ patches.push({
25
+ agent_name: '*', // All agents
26
+ patch_type: 'append',
27
+ content: '\n\n## User Preference\nKeep responses concise. Avoid unnecessary verbosity.',
28
+ reason: 'User prefers concise responses',
29
+ confidence: 0.85,
30
+ evidence_count: 3,
31
+ });
32
+ }
33
+ for (const rule of userPreferences.explicit_rules) {
34
+ patches.push({
35
+ agent_name: '*',
36
+ patch_type: 'append',
37
+ content: `\n\n## User Rule\n${rule}`,
38
+ reason: 'Explicit user preference',
39
+ confidence: 0.95,
40
+ evidence_count: 1,
41
+ });
42
+ }
43
+ return patches;
44
+ }
45
+ /** Preview patches (dry run) */
46
+ export function previewPatches(patches) {
47
+ const lines = ['Suggested Prompt Patches:', ''];
48
+ for (const patch of patches) {
49
+ lines.push(`Agent: ${patch.agent_name}`);
50
+ lines.push(`Type: ${patch.patch_type}`);
51
+ lines.push(`Reason: ${patch.reason}`);
52
+ lines.push(`Confidence: ${(patch.confidence * 100).toFixed(0)}%`);
53
+ lines.push(`Content: ${patch.content.substring(0, 100)}...`);
54
+ lines.push('---');
55
+ }
56
+ return lines.join('\n');
57
+ }
58
+ /** Apply patches to agent prompt files */
59
+ export function applyPromptPatches(patches, agentsDir = join(homedir(), '.claude', 'agents')) {
60
+ const results = [];
61
+ for (const patch of patches) {
62
+ const agentFiles = patch.agent_name === '*'
63
+ ? getAllAgentFiles(agentsDir)
64
+ : [join(agentsDir, `${patch.agent_name}.md`)];
65
+ for (const filePath of agentFiles) {
66
+ if (!existsSync(filePath)) {
67
+ results.push({
68
+ agent_name: patch.agent_name,
69
+ success: false,
70
+ error: `File not found: ${filePath}`,
71
+ });
72
+ continue;
73
+ }
74
+ try {
75
+ // Create backup
76
+ const backupPath = `${filePath}.backup.${Date.now()}`;
77
+ copyFileSync(filePath, backupPath);
78
+ // Read current content
79
+ const content = readFileSync(filePath, 'utf-8');
80
+ // Apply patch
81
+ const newContent = patch.patch_type === 'prepend'
82
+ ? patch.content + '\n\n' + content
83
+ : content + '\n' + patch.content;
84
+ writeFileSync(filePath, newContent, 'utf-8');
85
+ results.push({
86
+ agent_name: patch.agent_name,
87
+ success: true,
88
+ backup_path: backupPath,
89
+ });
90
+ }
91
+ catch (error) {
92
+ results.push({
93
+ agent_name: patch.agent_name,
94
+ success: false,
95
+ error: error instanceof Error ? error.message : String(error),
96
+ });
97
+ }
98
+ }
99
+ }
100
+ return results;
101
+ }
102
+ /** Revert a patch using backup file */
103
+ export function revertPatch(backupPath) {
104
+ const originalPath = backupPath.replace(/\.backup\.\d+$/, '');
105
+ try {
106
+ copyFileSync(backupPath, originalPath);
107
+ return true;
108
+ }
109
+ catch {
110
+ return false;
111
+ }
112
+ }
113
+ function getAllAgentFiles(agentsDir) {
114
+ if (!existsSync(agentsDir))
115
+ return [];
116
+ return readdirSync(agentsDir)
117
+ .filter((f) => f.endsWith('.md'))
118
+ .map((f) => join(agentsDir, f));
119
+ }
120
+ //# sourceMappingURL=prompt-patcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-patcher.js","sourceRoot":"","sources":["../../src/learning/prompt-patcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { SessionState, FeedbackCategory } from './types.js';
2
+ /** Get session state file path */
3
+ export declare function getSessionStatePath(directory: string): string;
4
+ /** Create fresh session state */
5
+ export declare function createSessionState(sessionId?: string): SessionState;
6
+ /** Load or create session state */
7
+ export declare function loadSessionState(directory: string, sessionId?: string): SessionState;
8
+ /** Save session state */
9
+ export declare function saveSessionState(directory: string, state: SessionState): void;
10
+ /** Add prompt to session state */
11
+ export declare function addPromptToSession(state: SessionState, prompt: string, detectedFeedback?: FeedbackCategory): SessionState;
12
+ /** Mark a completion claim */
13
+ export declare function markCompletionClaim(state: SessionState, taskDescription: string, agentUsed?: string): SessionState;
14
+ /** Clear completion claim (on success or explicit reset) */
15
+ export declare function clearCompletionClaim(state: SessionState): SessionState;
16
+ /** Check if there's a pending completion claim */
17
+ export declare function hasPendingCompletion(state: SessionState): boolean;
18
+ //# sourceMappingURL=session-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-state.d.ts","sourceRoot":"","sources":["../../src/learning/session-state.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAO5D,kCAAkC;AAClC,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,iCAAiC;AACjC,wBAAgB,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,CASnE;AAED,mCAAmC;AACnC,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,CAgBpF;AAED,yBAAyB;AACzB,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAI7E;AAED,kCAAkC;AAClC,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,MAAM,EACd,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,YAAY,CAWd;AAED,8BAA8B;AAC9B,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EACnB,eAAe,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,MAAM,GACjB,YAAY,CAQd;AAED,4DAA4D;AAC5D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,CAItE;AAED,kDAAkD;AAClD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAOjE"}
@@ -0,0 +1,78 @@
1
+ import { join } from 'path';
2
+ import { readJsonFile, writeJsonFile } from './storage.js';
3
+ import { randomUUID } from 'crypto';
4
+ const MAX_RECENT_PROMPTS = 10;
5
+ const SESSION_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes
6
+ /** Get session state file path */
7
+ export function getSessionStatePath(directory) {
8
+ return join(directory, '.olympus', 'session-state.json');
9
+ }
10
+ /** Create fresh session state */
11
+ export function createSessionState(sessionId) {
12
+ return {
13
+ session_id: sessionId || randomUUID(),
14
+ started_at: new Date().toISOString(),
15
+ last_updated: new Date().toISOString(),
16
+ recent_prompts: [],
17
+ pending_completion: null,
18
+ todo_snapshot: null,
19
+ };
20
+ }
21
+ /** Load or create session state */
22
+ export function loadSessionState(directory, sessionId) {
23
+ const path = getSessionStatePath(directory);
24
+ const state = readJsonFile(path, null);
25
+ if (!state) {
26
+ return createSessionState(sessionId);
27
+ }
28
+ // Check for session timeout
29
+ const lastUpdate = new Date(state.last_updated).getTime();
30
+ const now = Date.now();
31
+ if (now - lastUpdate > SESSION_TIMEOUT_MS) {
32
+ return createSessionState(sessionId);
33
+ }
34
+ return state;
35
+ }
36
+ /** Save session state */
37
+ export function saveSessionState(directory, state) {
38
+ const path = getSessionStatePath(directory);
39
+ state.last_updated = new Date().toISOString();
40
+ writeJsonFile(path, state);
41
+ }
42
+ /** Add prompt to session state */
43
+ export function addPromptToSession(state, prompt, detectedFeedback) {
44
+ const entry = {
45
+ prompt,
46
+ timestamp: new Date().toISOString(),
47
+ detected_feedback: detectedFeedback,
48
+ };
49
+ state.recent_prompts = [entry, ...state.recent_prompts].slice(0, MAX_RECENT_PROMPTS);
50
+ state.last_updated = new Date().toISOString();
51
+ return state;
52
+ }
53
+ /** Mark a completion claim */
54
+ export function markCompletionClaim(state, taskDescription, agentUsed) {
55
+ state.pending_completion = {
56
+ claimed_at: new Date().toISOString(),
57
+ task_description: taskDescription,
58
+ agent_used: agentUsed,
59
+ };
60
+ state.last_updated = new Date().toISOString();
61
+ return state;
62
+ }
63
+ /** Clear completion claim (on success or explicit reset) */
64
+ export function clearCompletionClaim(state) {
65
+ state.pending_completion = null;
66
+ state.last_updated = new Date().toISOString();
67
+ return state;
68
+ }
69
+ /** Check if there's a pending completion claim */
70
+ export function hasPendingCompletion(state) {
71
+ if (!state.pending_completion?.claimed_at)
72
+ return false;
73
+ // Consider completion stale after 5 minutes
74
+ const claimedAt = new Date(state.pending_completion.claimed_at).getTime();
75
+ const now = Date.now();
76
+ return now - claimedAt < 5 * 60 * 1000;
77
+ }
78
+ //# sourceMappingURL=session-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-state.js","sourceRoot":"","sources":["../../src/learning/session-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAC9B,MAAM,kBAAkB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAE,aAAa;AAEzD,kCAAkC;AAClC,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,OAAO,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,oBAAoB,CAAC,CAAC;AAC3D,CAAC;AAED,iCAAiC;AACjC,MAAM,UAAU,kBAAkB,CAAC,SAAkB;IACnD,OAAO;QACL,UAAU,EAAE,SAAS,IAAI,UAAU,EAAE;QACrC,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACtC,cAAc,EAAE,EAAE;QAClB,kBAAkB,EAAE,IAAI;QACxB,aAAa,EAAE,IAAI;KACpB,CAAC;AACJ,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,gBAAgB,CAAC,SAAiB,EAAE,SAAkB;IACpE,MAAM,IAAI,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,YAAY,CAAsB,IAAI,EAAE,IAAI,CAAC,CAAC;IAE5D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;IAED,4BAA4B;IAC5B,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,GAAG,GAAG,UAAU,GAAG,kBAAkB,EAAE,CAAC;QAC1C,OAAO,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,yBAAyB;AACzB,MAAM,UAAU,gBAAgB,CAAC,SAAiB,EAAE,KAAmB;IACrE,MAAM,IAAI,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAC5C,KAAK,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,kBAAkB,CAChC,KAAmB,EACnB,MAAc,EACd,gBAAmC;IAEnC,MAAM,KAAK,GAAG;QACZ,MAAM;QACN,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,iBAAiB,EAAE,gBAAgB;KACpC,CAAC;IAEF,KAAK,CAAC,cAAc,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;IACrF,KAAK,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE9C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8BAA8B;AAC9B,MAAM,UAAU,mBAAmB,CACjC,KAAmB,EACnB,eAAuB,EACvB,SAAkB;IAElB,KAAK,CAAC,kBAAkB,GAAG;QACzB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,gBAAgB,EAAE,eAAe;QACjC,UAAU,EAAE,SAAS;KACtB,CAAC;IACF,KAAK,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,oBAAoB,CAAC,KAAmB;IACtD,KAAK,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAChC,KAAK,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,oBAAoB,CAAC,KAAmB;IACtD,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,UAAU;QAAE,OAAO,KAAK,CAAC;IAExD,4CAA4C;IAC5C,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC;IAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,OAAO,GAAG,GAAG,SAAS,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AACzC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { FeedbackEntry } from './types.js';
2
+ /** Get learning storage directory (cross-platform) */
3
+ export declare function getLearningDir(): string;
4
+ /** Get project-specific learning directory */
5
+ export declare function getProjectLearningDir(projectPath: string): string;
6
+ /** Generate deterministic hash for project path */
7
+ export declare function getProjectHash(projectPath: string): string;
8
+ /** Ensure learning directories exist */
9
+ export declare function ensureLearningDirs(projectPath?: string): void;
10
+ /** Append feedback entry to JSONL log */
11
+ export declare function appendFeedback(entry: FeedbackEntry): void;
12
+ /** Read feedback log */
13
+ export declare function readFeedbackLog(): FeedbackEntry[];
14
+ /** Read JSON file with type safety and error handling */
15
+ export declare function readJsonFile<T>(path: string, defaultValue: T): T;
16
+ /** Write JSON file with error handling */
17
+ export declare function writeJsonFile<T>(filePath: string, data: T): void;
18
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/learning/storage.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,sDAAsD;AACtD,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,8CAA8C;AAC9C,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,mDAAmD;AACnD,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED,wCAAwC;AACxC,wBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAY7D;AAED,yCAAyC;AACzC,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAIzD;AAED,wBAAwB;AACxB,wBAAgB,eAAe,IAAI,aAAa,EAAE,CASjD;AAED,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,CAQhE;AAED,0CAA0C;AAC1C,wBAAgB,aAAa,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAWhE"}