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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=agent-evaluator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-evaluator.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/learning/agent-evaluator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { evaluateAgentPerformance } from '../../learning/agent-evaluator.js';
3
+ import { MOCK_FEEDBACK_AGENTS } from './fixtures/mock-feedback.js';
4
+ describe('AgentEvaluator', () => {
5
+ it('calculates success rate per agent', () => {
6
+ const performance = evaluateAgentPerformance(MOCK_FEEDBACK_AGENTS);
7
+ const oracle = performance.get('oracle');
8
+ expect(oracle).toBeDefined();
9
+ expect(oracle?.total_invocations).toBe(2);
10
+ expect(oracle?.success_count).toBe(1);
11
+ expect(oracle?.revision_count).toBe(1);
12
+ expect(oracle?.success_rate).toBe(0.5);
13
+ });
14
+ it('handles agents with no failures', () => {
15
+ const performance = evaluateAgentPerformance(MOCK_FEEDBACK_AGENTS);
16
+ const olympian = performance.get('olympian');
17
+ expect(olympian).toBeDefined();
18
+ expect(olympian?.success_rate).toBe(1);
19
+ expect(olympian?.failure_patterns).toHaveLength(0);
20
+ });
21
+ it('ignores feedback without agent_used', () => {
22
+ const feedbackWithoutAgent = [
23
+ { id: '1', timestamp: '', session_id: '', project_path: '', event_type: 'success', user_message: 'Thanks', feedback_category: 'praise', confidence: 0.9 },
24
+ ];
25
+ const performance = evaluateAgentPerformance(feedbackWithoutAgent);
26
+ expect(performance.size).toBe(0);
27
+ });
28
+ });
29
+ //# sourceMappingURL=agent-evaluator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-evaluator.test.js","sourceRoot":"","sources":["../../../src/__tests__/learning/agent-evaluator.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,WAAW,GAAG,wBAAwB,CAAC,oBAAoB,CAAC,CAAC;QAEnE,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,WAAW,GAAG,wBAAwB,CAAC,oBAAoB,CAAC,CAAC;QAEnE,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAC/B,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,oBAAoB,GAAG;YAC3B,EAAE,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,UAAU,EAAE,SAAkB,EAAE,YAAY,EAAE,QAAQ,EAAE,iBAAiB,EAAE,QAAiB,EAAE,UAAU,EAAE,GAAG,EAAE;SAC5K,CAAC;QAEF,MAAM,WAAW,GAAG,wBAAwB,CAAC,oBAAoB,CAAC,CAAC;QACnE,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=discovery.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/learning/discovery.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,70 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { mkdtempSync, rmSync, existsSync } from 'fs';
3
+ import { tmpdir } from 'os';
4
+ import { join } from 'path';
5
+ // Hoisted mock
6
+ const mockHomedir = vi.hoisted(() => {
7
+ return { value: '' };
8
+ });
9
+ vi.mock('os', async () => {
10
+ const actual = await vi.importActual('os');
11
+ return {
12
+ ...actual,
13
+ homedir: () => mockHomedir.value,
14
+ };
15
+ });
16
+ import { recordDiscovery, readDiscoveries, } from '../../learning/discovery.js';
17
+ describe('discovery', () => {
18
+ let tempDir;
19
+ beforeEach(() => {
20
+ tempDir = mkdtempSync(join(tmpdir(), 'olympus-discovery-test-'));
21
+ mockHomedir.value = tempDir;
22
+ });
23
+ afterEach(() => {
24
+ rmSync(tempDir, { recursive: true });
25
+ });
26
+ it('records a discovery to project storage', () => {
27
+ const discovery = recordDiscovery({
28
+ category: 'gotcha',
29
+ summary: 'Test discovery summary',
30
+ details: 'Detailed explanation of the discovery',
31
+ agent_name: 'test-agent',
32
+ session_id: 'test-session',
33
+ project_path: tempDir,
34
+ confidence: 0.9,
35
+ scope: 'project',
36
+ });
37
+ expect(discovery.id).toBeDefined();
38
+ expect(discovery.timestamp).toBeDefined();
39
+ const filePath = join(tempDir, '.olympus', 'learning', 'discoveries.jsonl');
40
+ expect(existsSync(filePath)).toBe(true);
41
+ });
42
+ it('reads discoveries for a project', () => {
43
+ recordDiscovery({
44
+ category: 'pattern',
45
+ summary: 'Uses kebab-case for files',
46
+ details: 'All files in src/ use kebab-case naming',
47
+ agent_name: 'test',
48
+ session_id: 'test',
49
+ project_path: tempDir,
50
+ confidence: 0.8,
51
+ scope: 'project',
52
+ });
53
+ recordDiscovery({
54
+ category: 'workaround',
55
+ summary: 'Build requires NODE_ENV',
56
+ details: 'Must set NODE_ENV=development for local builds',
57
+ agent_name: 'test',
58
+ session_id: 'test',
59
+ project_path: tempDir,
60
+ confidence: 0.9,
61
+ scope: 'project',
62
+ });
63
+ const summary = readDiscoveries(tempDir);
64
+ expect(summary.total_discoveries).toBe(2);
65
+ expect(summary.project_discoveries).toHaveLength(2);
66
+ expect(summary.categories.pattern).toBe(1);
67
+ expect(summary.categories.workaround).toBe(1);
68
+ });
69
+ });
70
+ //# sourceMappingURL=discovery.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.test.js","sourceRoot":"","sources":["../../../src/__tests__/learning/discovery.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { FeedbackEntry } from '../../../learning/types.js';
2
+ /**
3
+ * Mock feedback for testing clustering - contains 3+ similar TypeScript-related entries
4
+ */
5
+ export declare const MOCK_FEEDBACK_FOR_CLUSTERING: FeedbackEntry[];
6
+ /**
7
+ * Mock feedback with insufficient entries for pattern extraction (only 2 similar)
8
+ */
9
+ export declare const MOCK_FEEDBACK_INSUFFICIENT: FeedbackEntry[];
10
+ /**
11
+ * Mock feedback for agent performance testing
12
+ */
13
+ export declare const MOCK_FEEDBACK_AGENTS: FeedbackEntry[];
14
+ //# sourceMappingURL=mock-feedback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-feedback.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/learning/fixtures/mock-feedback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE;;GAEG;AACH,eAAO,MAAM,4BAA4B,EAAE,aAAa,EAmDvD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,0BAA0B,EAAE,aAAa,EAqBrD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,aAAa,EA6D/C,CAAC"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Mock feedback for testing clustering - contains 3+ similar TypeScript-related entries
3
+ */
4
+ export const MOCK_FEEDBACK_FOR_CLUSTERING = [
5
+ {
6
+ id: 'test-1',
7
+ timestamp: '2025-01-20T10:00:00Z',
8
+ session_id: 'session-1',
9
+ project_path: '/test/project',
10
+ event_type: 'revision',
11
+ user_message: "No, that's wrong. Use TypeScript types.",
12
+ feedback_category: 'correction',
13
+ confidence: 0.9,
14
+ },
15
+ {
16
+ id: 'test-2',
17
+ timestamp: '2025-01-20T11:00:00Z',
18
+ session_id: 'session-1',
19
+ project_path: '/test/project',
20
+ event_type: 'revision',
21
+ user_message: "Add TypeScript types to this function.",
22
+ feedback_category: 'correction',
23
+ confidence: 0.85,
24
+ },
25
+ {
26
+ id: 'test-3',
27
+ timestamp: '2025-01-20T12:00:00Z',
28
+ session_id: 'session-1',
29
+ project_path: '/test/project',
30
+ event_type: 'revision',
31
+ user_message: "Missing TypeScript type annotations here.",
32
+ feedback_category: 'correction',
33
+ confidence: 0.88,
34
+ },
35
+ {
36
+ id: 'test-4',
37
+ timestamp: '2025-01-20T13:00:00Z',
38
+ session_id: 'session-1',
39
+ project_path: '/test/project',
40
+ event_type: 'success',
41
+ user_message: "Perfect, that's exactly what I wanted!",
42
+ feedback_category: 'praise',
43
+ confidence: 0.9,
44
+ },
45
+ {
46
+ id: 'test-5',
47
+ timestamp: '2025-01-21T10:00:00Z',
48
+ session_id: 'session-2',
49
+ project_path: '/test/project',
50
+ event_type: 'explicit_preference',
51
+ user_message: "Always use TypeScript strict mode.",
52
+ feedback_category: 'explicit_preference',
53
+ confidence: 0.95,
54
+ },
55
+ ];
56
+ /**
57
+ * Mock feedback with insufficient entries for pattern extraction (only 2 similar)
58
+ */
59
+ export const MOCK_FEEDBACK_INSUFFICIENT = [
60
+ {
61
+ id: 'insuf-1',
62
+ timestamp: '2025-01-20T10:00:00Z',
63
+ session_id: 'session-1',
64
+ project_path: '/test/project',
65
+ event_type: 'revision',
66
+ user_message: "Add error handling here.",
67
+ feedback_category: 'correction',
68
+ confidence: 0.85,
69
+ },
70
+ {
71
+ id: 'insuf-2',
72
+ timestamp: '2025-01-20T11:00:00Z',
73
+ session_id: 'session-1',
74
+ project_path: '/test/project',
75
+ event_type: 'revision',
76
+ user_message: "Missing error handling.",
77
+ feedback_category: 'correction',
78
+ confidence: 0.82,
79
+ },
80
+ ];
81
+ /**
82
+ * Mock feedback for agent performance testing
83
+ */
84
+ export const MOCK_FEEDBACK_AGENTS = [
85
+ {
86
+ id: 'agent-1',
87
+ timestamp: '2025-01-20T10:00:00Z',
88
+ session_id: 'session-1',
89
+ project_path: '/test/project',
90
+ event_type: 'success',
91
+ original_task: 'Refactor the auth module',
92
+ agent_used: 'oracle',
93
+ user_message: 'Great work!',
94
+ feedback_category: 'praise',
95
+ confidence: 0.85,
96
+ },
97
+ {
98
+ id: 'agent-2',
99
+ timestamp: '2025-01-20T11:00:00Z',
100
+ session_id: 'session-1',
101
+ project_path: '/test/project',
102
+ event_type: 'revision',
103
+ original_task: 'Fix React component',
104
+ agent_used: 'oracle',
105
+ user_message: 'The React state handling is wrong.',
106
+ feedback_category: 'correction',
107
+ confidence: 0.88,
108
+ },
109
+ {
110
+ id: 'agent-3',
111
+ timestamp: '2025-01-20T12:00:00Z',
112
+ session_id: 'session-1',
113
+ project_path: '/test/project',
114
+ event_type: 'success',
115
+ original_task: 'Add tests',
116
+ agent_used: 'olympian',
117
+ user_message: 'Perfect!',
118
+ feedback_category: 'praise',
119
+ confidence: 0.9,
120
+ },
121
+ {
122
+ id: 'agent-4',
123
+ timestamp: '2025-01-20T13:00:00Z',
124
+ session_id: 'session-1',
125
+ project_path: '/test/project',
126
+ event_type: 'revision',
127
+ original_task: 'Build UI component',
128
+ agent_used: 'frontend-engineer',
129
+ user_message: 'Need to run shadcn add first.',
130
+ feedback_category: 'correction',
131
+ confidence: 0.85,
132
+ },
133
+ {
134
+ id: 'agent-5',
135
+ timestamp: '2025-01-20T14:00:00Z',
136
+ session_id: 'session-1',
137
+ project_path: '/test/project',
138
+ event_type: 'revision',
139
+ original_task: 'Style the form',
140
+ agent_used: 'frontend-engineer',
141
+ user_message: 'Forgot to install shadcn component.',
142
+ feedback_category: 'correction',
143
+ confidence: 0.82,
144
+ },
145
+ ];
146
+ //# sourceMappingURL=mock-feedback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-feedback.js","sourceRoot":"","sources":["../../../../src/__tests__/learning/fixtures/mock-feedback.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pattern-extractor.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-extractor.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/learning/pattern-extractor.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,30 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { extractPatterns, jaccardSimilarity } from '../../learning/pattern-extractor.js';
3
+ import { MOCK_FEEDBACK_FOR_CLUSTERING, MOCK_FEEDBACK_INSUFFICIENT } from './fixtures/mock-feedback.js';
4
+ describe('PatternExtractor', () => {
5
+ describe('jaccardSimilarity', () => {
6
+ it('returns 1 for identical texts', () => {
7
+ const similarity = jaccardSimilarity('hello world', 'hello world');
8
+ expect(similarity).toBe(1);
9
+ });
10
+ it('returns 0 for completely different texts', () => {
11
+ const similarity = jaccardSimilarity('hello world', 'foo bar baz');
12
+ expect(similarity).toBe(0);
13
+ });
14
+ });
15
+ describe('extractPatterns', () => {
16
+ it('groups similar feedback using Jaccard similarity', () => {
17
+ const patterns = extractPatterns(MOCK_FEEDBACK_FOR_CLUSTERING);
18
+ expect(patterns.length).toBeGreaterThan(0);
19
+ });
20
+ it('requires minimum 3 occurrences by default', () => {
21
+ const patterns = extractPatterns(MOCK_FEEDBACK_INSUFFICIENT);
22
+ expect(patterns).toHaveLength(0);
23
+ });
24
+ it('allows custom minimum occurrences', () => {
25
+ const patterns = extractPatterns(MOCK_FEEDBACK_INSUFFICIENT, 2);
26
+ expect(patterns.length).toBeGreaterThan(0);
27
+ });
28
+ });
29
+ });
30
+ //# sourceMappingURL=pattern-extractor.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-extractor.test.js","sourceRoot":"","sources":["../../../src/__tests__/learning/pattern-extractor.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACzF,OAAO,EAAE,4BAA4B,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAEvG,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;YACvC,MAAM,UAAU,GAAG,iBAAiB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;YACnE,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,UAAU,GAAG,iBAAiB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;YACnE,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,MAAM,QAAQ,GAAG,eAAe,CAAC,4BAA4B,CAAC,CAAC;YAC/D,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,QAAQ,GAAG,eAAe,CAAC,0BAA0B,CAAC,CAAC;YAC7D,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,QAAQ,GAAG,eAAe,CAAC,0BAA0B,EAAE,CAAC,CAAC,CAAC;YAChE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=revision-detector.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revision-detector.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/learning/revision-detector.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,54 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { detectFeedbackCategory } from '../../learning/hooks/revision-detector.js';
3
+ describe('RevisionDetector', () => {
4
+ describe('correction detection', () => {
5
+ it('detects direct corrections', () => {
6
+ const result = detectFeedbackCategory("No, that's wrong. I wanted X.");
7
+ expect(result?.category).toBe('correction');
8
+ expect(result?.confidence).toBeGreaterThan(0.8);
9
+ });
10
+ it('detects misunderstanding', () => {
11
+ const result = detectFeedbackCategory("You misunderstood the requirements.");
12
+ expect(result?.category).toBe('correction');
13
+ });
14
+ });
15
+ describe('explicit preference detection', () => {
16
+ it('detects "always" statements', () => {
17
+ const result = detectFeedbackCategory("Always use TypeScript strict mode.");
18
+ expect(result?.category).toBe('explicit_preference');
19
+ expect(result?.confidence).toBeGreaterThanOrEqual(0.95);
20
+ });
21
+ it('detects "never" statements', () => {
22
+ const result = detectFeedbackCategory("Never use var, use const or let.");
23
+ expect(result?.category).toBe('explicit_preference');
24
+ });
25
+ });
26
+ describe('rejection detection', () => {
27
+ it('detects stop command', () => {
28
+ const result = detectFeedbackCategory("Stop, I need to rethink this.");
29
+ expect(result?.category).toBe('rejection');
30
+ });
31
+ it('detects cancel command', () => {
32
+ const result = detectFeedbackCategory("Cancel that request.");
33
+ expect(result?.category).toBe('rejection');
34
+ });
35
+ });
36
+ describe('praise detection', () => {
37
+ it('detects perfect', () => {
38
+ const result = detectFeedbackCategory("Perfect, exactly what I needed!");
39
+ expect(result?.category).toBe('praise');
40
+ });
41
+ });
42
+ describe('edge cases', () => {
43
+ it('ignores non-feedback messages', () => {
44
+ const result = detectFeedbackCategory("Can you help me with React?");
45
+ expect(result).toBeNull();
46
+ });
47
+ it('removes code blocks before matching', () => {
48
+ const result = detectFeedbackCategory("Run this: ```stop``` then continue.");
49
+ // 'stop' is in a code block, should not trigger rejection
50
+ expect(result?.category).not.toBe('rejection');
51
+ });
52
+ });
53
+ });
54
+ //# sourceMappingURL=revision-detector.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revision-detector.test.js","sourceRoot":"","sources":["../../../src/__tests__/learning/revision-detector.test.ts"],"names":[],"mappings":"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"}