olympus-ai 3.2.3 → 3.4.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 (212) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +2 -0
  4. package/dist/__tests__/ascent-checkpoint.test.d.ts +2 -0
  5. package/dist/__tests__/ascent-checkpoint.test.d.ts.map +1 -0
  6. package/dist/__tests__/ascent-checkpoint.test.js +261 -0
  7. package/dist/__tests__/ascent-checkpoint.test.js.map +1 -0
  8. package/dist/__tests__/config-ascent.test.d.ts +2 -0
  9. package/dist/__tests__/config-ascent.test.d.ts.map +1 -0
  10. package/dist/__tests__/config-ascent.test.js +134 -0
  11. package/dist/__tests__/config-ascent.test.js.map +1 -0
  12. package/dist/__tests__/hook-blocking.test.d.ts +8 -0
  13. package/dist/__tests__/hook-blocking.test.d.ts.map +1 -0
  14. package/dist/__tests__/hook-blocking.test.js +277 -0
  15. package/dist/__tests__/hook-blocking.test.js.map +1 -0
  16. package/dist/__tests__/installer.test.js +1 -1
  17. package/dist/__tests__/learning/aggregation.test.d.ts +2 -0
  18. package/dist/__tests__/learning/aggregation.test.d.ts.map +1 -0
  19. package/dist/__tests__/learning/aggregation.test.js +282 -0
  20. package/dist/__tests__/learning/aggregation.test.js.map +1 -0
  21. package/dist/__tests__/learning/anomaly.test.d.ts +2 -0
  22. package/dist/__tests__/learning/anomaly.test.d.ts.map +1 -0
  23. package/dist/__tests__/learning/anomaly.test.js +107 -0
  24. package/dist/__tests__/learning/anomaly.test.js.map +1 -0
  25. package/dist/__tests__/learning/baselines.test.d.ts +2 -0
  26. package/dist/__tests__/learning/baselines.test.d.ts.map +1 -0
  27. package/dist/__tests__/learning/baselines.test.js +155 -0
  28. package/dist/__tests__/learning/baselines.test.js.map +1 -0
  29. package/dist/__tests__/learning/efficiency.test.d.ts +2 -0
  30. package/dist/__tests__/learning/efficiency.test.d.ts.map +1 -0
  31. package/dist/__tests__/learning/efficiency.test.js +94 -0
  32. package/dist/__tests__/learning/efficiency.test.js.map +1 -0
  33. package/dist/__tests__/learning/feedback-loop-injection.test.d.ts +6 -0
  34. package/dist/__tests__/learning/feedback-loop-injection.test.d.ts.map +1 -0
  35. package/dist/__tests__/learning/feedback-loop-injection.test.js +288 -0
  36. package/dist/__tests__/learning/feedback-loop-injection.test.js.map +1 -0
  37. package/dist/__tests__/learning/learning-capture-integration.test.d.ts +6 -0
  38. package/dist/__tests__/learning/learning-capture-integration.test.d.ts.map +1 -0
  39. package/dist/__tests__/learning/learning-capture-integration.test.js +151 -0
  40. package/dist/__tests__/learning/learning-capture-integration.test.js.map +1 -0
  41. package/dist/__tests__/learning/token-metrics.test.d.ts +2 -0
  42. package/dist/__tests__/learning/token-metrics.test.d.ts.map +1 -0
  43. package/dist/__tests__/learning/token-metrics.test.js +308 -0
  44. package/dist/__tests__/learning/token-metrics.test.js.map +1 -0
  45. package/dist/__tests__/metrics-cli.test.d.ts +5 -0
  46. package/dist/__tests__/metrics-cli.test.d.ts.map +1 -0
  47. package/dist/__tests__/metrics-cli.test.js +24 -0
  48. package/dist/__tests__/metrics-cli.test.js.map +1 -0
  49. package/dist/__tests__/skill-auto-detection.test.d.ts +2 -0
  50. package/dist/__tests__/skill-auto-detection.test.d.ts.map +1 -0
  51. package/dist/__tests__/skill-auto-detection.test.js +255 -0
  52. package/dist/__tests__/skill-auto-detection.test.js.map +1 -0
  53. package/dist/__tests__/token-estimator.test.d.ts +5 -0
  54. package/dist/__tests__/token-estimator.test.d.ts.map +1 -0
  55. package/dist/__tests__/token-estimator.test.js +192 -0
  56. package/dist/__tests__/token-estimator.test.js.map +1 -0
  57. package/dist/__tests__/token-tracking-integration.test.d.ts +8 -0
  58. package/dist/__tests__/token-tracking-integration.test.d.ts.map +1 -0
  59. package/dist/__tests__/token-tracking-integration.test.js +669 -0
  60. package/dist/__tests__/token-tracking-integration.test.js.map +1 -0
  61. package/dist/agents/definitions.d.ts.map +1 -1
  62. package/dist/agents/definitions.js +83 -1
  63. package/dist/agents/definitions.js.map +1 -1
  64. package/dist/agents/document-writer.d.ts.map +1 -1
  65. package/dist/agents/document-writer.js +38 -0
  66. package/dist/agents/document-writer.js.map +1 -1
  67. package/dist/agents/frontend-engineer.d.ts.map +1 -1
  68. package/dist/agents/frontend-engineer.js +16 -0
  69. package/dist/agents/frontend-engineer.js.map +1 -1
  70. package/dist/agents/olympian.d.ts.map +1 -1
  71. package/dist/agents/olympian.js +15 -0
  72. package/dist/agents/olympian.js.map +1 -1
  73. package/dist/cli/commands/metrics.d.ts +39 -0
  74. package/dist/cli/commands/metrics.d.ts.map +1 -0
  75. package/dist/cli/commands/metrics.js +52 -0
  76. package/dist/cli/commands/metrics.js.map +1 -0
  77. package/dist/cli/index.js +235 -1
  78. package/dist/cli/index.js.map +1 -1
  79. package/dist/config/loader.d.ts.map +1 -1
  80. package/dist/config/loader.js +30 -0
  81. package/dist/config/loader.js.map +1 -1
  82. package/dist/features/ascent-checkpoint/index.d.ts +48 -0
  83. package/dist/features/ascent-checkpoint/index.d.ts.map +1 -0
  84. package/dist/features/ascent-checkpoint/index.js +144 -0
  85. package/dist/features/ascent-checkpoint/index.js.map +1 -0
  86. package/dist/features/hook-logging/index.d.ts +37 -0
  87. package/dist/features/hook-logging/index.d.ts.map +1 -0
  88. package/dist/features/hook-logging/index.js +120 -0
  89. package/dist/features/hook-logging/index.js.map +1 -0
  90. package/dist/features/hook-logging/index.test.d.ts +5 -0
  91. package/dist/features/hook-logging/index.test.d.ts.map +1 -0
  92. package/dist/features/hook-logging/index.test.js +268 -0
  93. package/dist/features/hook-logging/index.test.js.map +1 -0
  94. package/dist/features/index.d.ts +3 -0
  95. package/dist/features/index.d.ts.map +1 -1
  96. package/dist/features/index.js +8 -0
  97. package/dist/features/index.js.map +1 -1
  98. package/dist/features/magic-keywords.d.ts +51 -0
  99. package/dist/features/magic-keywords.d.ts.map +1 -1
  100. package/dist/features/magic-keywords.js +172 -0
  101. package/dist/features/magic-keywords.js.map +1 -1
  102. package/dist/features/session-state/index.d.ts +50 -0
  103. package/dist/features/session-state/index.d.ts.map +1 -0
  104. package/dist/features/session-state/index.js +64 -0
  105. package/dist/features/session-state/index.js.map +1 -0
  106. package/dist/features/session-state/index.test.d.ts +5 -0
  107. package/dist/features/session-state/index.test.d.ts.map +1 -0
  108. package/dist/features/session-state/index.test.js +221 -0
  109. package/dist/features/session-state/index.test.js.map +1 -0
  110. package/dist/features/token-metrics/index.d.ts +6 -0
  111. package/dist/features/token-metrics/index.d.ts.map +1 -0
  112. package/dist/features/token-metrics/index.js +5 -0
  113. package/dist/features/token-metrics/index.js.map +1 -0
  114. package/dist/features/token-metrics/storage.d.ts +16 -0
  115. package/dist/features/token-metrics/storage.d.ts.map +1 -0
  116. package/dist/features/token-metrics/storage.js +144 -0
  117. package/dist/features/token-metrics/storage.js.map +1 -0
  118. package/dist/features/token-metrics/token-estimator.d.ts +66 -0
  119. package/dist/features/token-metrics/token-estimator.d.ts.map +1 -0
  120. package/dist/features/token-metrics/token-estimator.js +230 -0
  121. package/dist/features/token-metrics/token-estimator.js.map +1 -0
  122. package/dist/features/token-metrics/types.d.ts +63 -0
  123. package/dist/features/token-metrics/types.d.ts.map +1 -0
  124. package/dist/features/token-metrics/types.js +5 -0
  125. package/dist/features/token-metrics/types.js.map +1 -0
  126. package/dist/hooks/olympus-orchestrator/constants.d.ts +2 -0
  127. package/dist/hooks/olympus-orchestrator/constants.d.ts.map +1 -1
  128. package/dist/hooks/olympus-orchestrator/constants.js +41 -0
  129. package/dist/hooks/olympus-orchestrator/constants.js.map +1 -1
  130. package/dist/hooks/olympus-orchestrator/index.d.ts +10 -1
  131. package/dist/hooks/olympus-orchestrator/index.d.ts.map +1 -1
  132. package/dist/hooks/olympus-orchestrator/index.js +108 -14
  133. package/dist/hooks/olympus-orchestrator/index.js.map +1 -1
  134. package/dist/hooks/registrations/budget-warning.d.ts +8 -0
  135. package/dist/hooks/registrations/budget-warning.d.ts.map +1 -0
  136. package/dist/hooks/registrations/budget-warning.js +63 -0
  137. package/dist/hooks/registrations/budget-warning.js.map +1 -0
  138. package/dist/hooks/registrations/index.d.ts +3 -1
  139. package/dist/hooks/registrations/index.d.ts.map +1 -1
  140. package/dist/hooks/registrations/index.js +5 -1
  141. package/dist/hooks/registrations/index.js.map +1 -1
  142. package/dist/hooks/registrations/learning-capture.d.ts +19 -0
  143. package/dist/hooks/registrations/learning-capture.d.ts.map +1 -0
  144. package/dist/hooks/registrations/learning-capture.js +220 -0
  145. package/dist/hooks/registrations/learning-capture.js.map +1 -0
  146. package/dist/hooks/registrations/session-start.d.ts.map +1 -1
  147. package/dist/hooks/registrations/session-start.js +13 -0
  148. package/dist/hooks/registrations/session-start.js.map +1 -1
  149. package/dist/hooks/registrations/token-metrics.d.ts +19 -0
  150. package/dist/hooks/registrations/token-metrics.d.ts.map +1 -0
  151. package/dist/hooks/registrations/token-metrics.js +133 -0
  152. package/dist/hooks/registrations/token-metrics.js.map +1 -0
  153. package/dist/installer/index.d.ts +2 -2
  154. package/dist/installer/index.d.ts.map +1 -1
  155. package/dist/installer/index.js +390 -9
  156. package/dist/installer/index.js.map +1 -1
  157. package/dist/learning/aggregation.d.ts +39 -0
  158. package/dist/learning/aggregation.d.ts.map +1 -0
  159. package/dist/learning/aggregation.js +101 -0
  160. package/dist/learning/aggregation.js.map +1 -0
  161. package/dist/learning/anomaly.d.ts +30 -0
  162. package/dist/learning/anomaly.d.ts.map +1 -0
  163. package/dist/learning/anomaly.js +102 -0
  164. package/dist/learning/anomaly.js.map +1 -0
  165. package/dist/learning/baselines.d.ts +44 -0
  166. package/dist/learning/baselines.d.ts.map +1 -0
  167. package/dist/learning/baselines.js +126 -0
  168. package/dist/learning/baselines.js.map +1 -0
  169. package/dist/learning/efficiency.d.ts +23 -0
  170. package/dist/learning/efficiency.d.ts.map +1 -0
  171. package/dist/learning/efficiency.js +67 -0
  172. package/dist/learning/efficiency.js.map +1 -0
  173. package/dist/learning/hooks/learned-context.d.ts.map +1 -1
  174. package/dist/learning/hooks/learned-context.js +46 -0
  175. package/dist/learning/hooks/learned-context.js.map +1 -1
  176. package/dist/learning/pricing.d.ts +30 -0
  177. package/dist/learning/pricing.d.ts.map +1 -0
  178. package/dist/learning/pricing.js +98 -0
  179. package/dist/learning/pricing.js.map +1 -0
  180. package/dist/learning/session-state.d.ts +12 -2
  181. package/dist/learning/session-state.d.ts.map +1 -1
  182. package/dist/learning/session-state.js +72 -3
  183. package/dist/learning/session-state.js.map +1 -1
  184. package/dist/learning/storage.d.ts +21 -1
  185. package/dist/learning/storage.d.ts.map +1 -1
  186. package/dist/learning/storage.js +84 -0
  187. package/dist/learning/storage.js.map +1 -1
  188. package/dist/learning/token-estimator.d.ts +41 -0
  189. package/dist/learning/token-estimator.d.ts.map +1 -0
  190. package/dist/learning/token-estimator.js +111 -0
  191. package/dist/learning/token-estimator.js.map +1 -0
  192. package/dist/learning/types.d.ts +32 -0
  193. package/dist/learning/types.d.ts.map +1 -1
  194. package/dist/learning/utils.d.ts +42 -0
  195. package/dist/learning/utils.d.ts.map +1 -0
  196. package/dist/learning/utils.js +76 -0
  197. package/dist/learning/utils.js.map +1 -0
  198. package/dist/shared/types.d.ts +45 -0
  199. package/dist/shared/types.d.ts.map +1 -1
  200. package/package.json +3 -3
  201. package/scripts/.olympus/token-metrics.jsonl +1 -0
  202. package/scripts/dist/hooks/olympus-hooks.cjs +128 -127
  203. package/scripts/esbuild.hooks.mjs +1 -1
  204. package/.claude/CLAUDE.md +0 -66
  205. package/scripts/generate-logo-hybrid-v2.mjs +0 -213
  206. package/scripts/generate-logo-hybrid.mjs +0 -209
  207. package/scripts/generate-logo-infinity.mjs +0 -239
  208. package/scripts/generate-logo-mythology.mjs +0 -190
  209. package/scripts/generate-logo-orchestration.mjs +0 -228
  210. package/scripts/generate-logo-recraft.mjs +0 -147
  211. package/scripts/generate-logo-simple.mjs +0 -154
  212. package/scripts/generate-logo.mjs +0 -117
@@ -0,0 +1,107 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { detectAnomaly } from '../../learning/anomaly.js';
3
+ describe('detectAnomaly', () => {
4
+ const defaultThresholds = {
5
+ warning: 1.5,
6
+ critical: 2.5
7
+ };
8
+ it('should detect no anomaly for normal usage', () => {
9
+ const result = detectAnomaly(10000, 10000, defaultThresholds);
10
+ expect(result.is_anomaly).toBe(false);
11
+ expect(result.severity).toBe('info');
12
+ expect(result.ratio).toBe(1.0);
13
+ expect(result.message).toContain('10.0k');
14
+ expect(result.message).toContain('100%');
15
+ });
16
+ it('should detect warning anomaly at 1.5x threshold', () => {
17
+ const result = detectAnomaly(15000, 10000, defaultThresholds);
18
+ expect(result.is_anomaly).toBe(true);
19
+ expect(result.severity).toBe('warning');
20
+ expect(result.ratio).toBe(1.5);
21
+ expect(result.message).toContain('15.0k');
22
+ expect(result.message).toContain('150%');
23
+ expect(result.message).toContain('above typical usage');
24
+ });
25
+ it('should detect critical anomaly at 2.5x threshold', () => {
26
+ const result = detectAnomaly(25000, 10000, defaultThresholds);
27
+ expect(result.is_anomaly).toBe(true);
28
+ expect(result.severity).toBe('critical');
29
+ expect(result.ratio).toBe(2.5);
30
+ expect(result.message).toContain('25.0k');
31
+ expect(result.message).toContain('250%');
32
+ expect(result.message).toContain('unusually high');
33
+ });
34
+ it('should handle first session (baseline = 0)', () => {
35
+ const result = detectAnomaly(10000, 0, defaultThresholds);
36
+ expect(result.is_anomaly).toBe(false);
37
+ expect(result.severity).toBe('info');
38
+ expect(result.ratio).toBe(0);
39
+ expect(result.message).toContain('No baseline data');
40
+ });
41
+ it('should use custom thresholds', () => {
42
+ const customThresholds = {
43
+ warning: 2.0,
44
+ critical: 3.0
45
+ };
46
+ const result = detectAnomaly(18000, 10000, customThresholds);
47
+ // 1.8x is below 2.0 warning threshold
48
+ expect(result.is_anomaly).toBe(false);
49
+ expect(result.severity).toBe('info');
50
+ });
51
+ it('should detect warning with custom thresholds', () => {
52
+ const customThresholds = {
53
+ warning: 2.0,
54
+ critical: 3.0
55
+ };
56
+ const result = detectAnomaly(20000, 10000, customThresholds);
57
+ expect(result.is_anomaly).toBe(true);
58
+ expect(result.severity).toBe('warning');
59
+ });
60
+ it('should format small token counts without k suffix', () => {
61
+ const result = detectAnomaly(500, 500, defaultThresholds);
62
+ expect(result.message).toContain('500');
63
+ expect(result.message).not.toContain('k');
64
+ });
65
+ it('should format large token counts with k suffix', () => {
66
+ const result = detectAnomaly(15000, 10000, defaultThresholds);
67
+ expect(result.message).toContain('15.0k');
68
+ expect(result.message).toContain('10.0k');
69
+ });
70
+ it('should throw on negative current tokens', () => {
71
+ expect(() => detectAnomaly(-5000, 10000, defaultThresholds)).toThrow('Token counts cannot be negative');
72
+ });
73
+ it('should throw on negative baseline', () => {
74
+ expect(() => detectAnomaly(10000, -5000, defaultThresholds)).toThrow('Token counts cannot be negative');
75
+ });
76
+ it('should throw on negative threshold values', () => {
77
+ expect(() => detectAnomaly(10000, 10000, { warning: -1.5, critical: 2.5 }))
78
+ .toThrow('Thresholds cannot be negative');
79
+ });
80
+ it('should throw when critical <= warning', () => {
81
+ expect(() => detectAnomaly(10000, 10000, { warning: 2.5, critical: 2.5 }))
82
+ .toThrow('Critical threshold must be greater than warning threshold');
83
+ expect(() => detectAnomaly(10000, 10000, { warning: 3.0, critical: 2.5 }))
84
+ .toThrow('Critical threshold must be greater than warning threshold');
85
+ });
86
+ it('should detect anomaly just below critical threshold', () => {
87
+ const result = detectAnomaly(24999, 10000, defaultThresholds);
88
+ expect(result.is_anomaly).toBe(true);
89
+ expect(result.severity).toBe('warning');
90
+ });
91
+ it('should detect critical at exact threshold', () => {
92
+ const result = detectAnomaly(25000, 10000, defaultThresholds);
93
+ expect(result.is_anomaly).toBe(true);
94
+ expect(result.severity).toBe('critical');
95
+ });
96
+ it('should include actionable recommendations in critical message', () => {
97
+ const result = detectAnomaly(25000, 10000, defaultThresholds);
98
+ expect(result.message).toContain('delegate');
99
+ expect(result.message).toContain('smaller tasks');
100
+ });
101
+ it('should include actionable recommendations in warning message', () => {
102
+ const result = detectAnomaly(15000, 10000, defaultThresholds);
103
+ expect(result.message).toContain('delegating');
104
+ expect(result.message).toContain('completion');
105
+ });
106
+ });
107
+ //# sourceMappingURL=anomaly.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anomaly.test.js","sourceRoot":"","sources":["../../../src/__tests__/learning/anomaly.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=baselines.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baselines.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/learning/baselines.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,155 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { getSessionBaseline, updateSessionBaseline, getWarningThreshold } from '../../learning/baselines.js';
3
+ describe('getSessionBaseline', () => {
4
+ it('should return default 10k when no baseline data', () => {
5
+ expect(getSessionBaseline()).toBe(10000);
6
+ });
7
+ it('should return default 10k when sample count < 5', () => {
8
+ const baseline = {
9
+ overall_avg: 8000,
10
+ by_task_type: {},
11
+ by_project: {},
12
+ sample_count: 4,
13
+ last_updated: new Date().toISOString()
14
+ };
15
+ expect(getSessionBaseline(undefined, undefined, baseline)).toBe(10000);
16
+ });
17
+ it('should return project-specific baseline when available', () => {
18
+ const baseline = {
19
+ overall_avg: 10000,
20
+ by_task_type: {},
21
+ by_project: { '/path/to/project': 7500 },
22
+ sample_count: 10,
23
+ last_updated: new Date().toISOString()
24
+ };
25
+ expect(getSessionBaseline('/path/to/project', undefined, baseline)).toBe(7500);
26
+ });
27
+ it('should return task-type baseline when project not available', () => {
28
+ const baseline = {
29
+ overall_avg: 10000,
30
+ by_task_type: { debugging: 6000 },
31
+ by_project: {},
32
+ sample_count: 10,
33
+ last_updated: new Date().toISOString()
34
+ };
35
+ expect(getSessionBaseline(undefined, 'debugging', baseline)).toBe(6000);
36
+ });
37
+ it('should prefer project baseline over task-type baseline', () => {
38
+ const baseline = {
39
+ overall_avg: 10000,
40
+ by_task_type: { debugging: 6000 },
41
+ by_project: { '/path/to/project': 7500 },
42
+ sample_count: 10,
43
+ last_updated: new Date().toISOString()
44
+ };
45
+ expect(getSessionBaseline('/path/to/project', 'debugging', baseline)).toBe(7500);
46
+ });
47
+ it('should fall back to overall average when no specific baseline', () => {
48
+ const baseline = {
49
+ overall_avg: 9200,
50
+ by_task_type: {},
51
+ by_project: {},
52
+ sample_count: 10,
53
+ last_updated: new Date().toISOString()
54
+ };
55
+ expect(getSessionBaseline('/unknown/project', 'unknown-task', baseline)).toBe(9200);
56
+ });
57
+ });
58
+ describe('updateSessionBaseline', () => {
59
+ it('should initialize baseline for first session', () => {
60
+ const result = updateSessionBaseline(8000, '/path/to/project', 'debugging', undefined);
61
+ expect(result.overall_avg).toBe(8000);
62
+ expect(result.by_project['/path/to/project']).toBe(8000);
63
+ expect(result.by_task_type['debugging']).toBe(8000);
64
+ expect(result.sample_count).toBe(1);
65
+ });
66
+ it('should initialize baseline without task type', () => {
67
+ const result = updateSessionBaseline(8000, '/path/to/project', undefined, undefined);
68
+ expect(result.overall_avg).toBe(8000);
69
+ expect(result.by_project['/path/to/project']).toBe(8000);
70
+ expect(result.by_task_type).toEqual({});
71
+ expect(result.sample_count).toBe(1);
72
+ });
73
+ it('should update overall average correctly', () => {
74
+ const baseline = {
75
+ overall_avg: 10000,
76
+ by_task_type: {},
77
+ by_project: { '/path/to/project': 10000 },
78
+ sample_count: 1,
79
+ last_updated: new Date().toISOString()
80
+ };
81
+ const result = updateSessionBaseline(8000, '/path/to/project', undefined, baseline);
82
+ // (10000 * 1 + 8000) / 2 = 9000
83
+ expect(result.overall_avg).toBe(9000);
84
+ expect(result.sample_count).toBe(2);
85
+ });
86
+ it('should update project-specific average', () => {
87
+ const baseline = {
88
+ overall_avg: 10000,
89
+ by_task_type: {},
90
+ by_project: { '/path/to/project': 10000 },
91
+ sample_count: 1,
92
+ last_updated: new Date().toISOString()
93
+ };
94
+ const result = updateSessionBaseline(6000, '/path/to/project', undefined, baseline);
95
+ // Project avg should be updated
96
+ expect(result.by_project['/path/to/project']).toBeLessThan(10000);
97
+ });
98
+ it('should handle new project in existing baseline', () => {
99
+ const baseline = {
100
+ overall_avg: 10000,
101
+ by_task_type: {},
102
+ by_project: { '/old/project': 10000 },
103
+ sample_count: 5,
104
+ last_updated: new Date().toISOString()
105
+ };
106
+ const result = updateSessionBaseline(8000, '/new/project', undefined, baseline);
107
+ expect(result.by_project['/old/project']).toBe(10000); // unchanged
108
+ expect(result.by_project['/new/project']).toBe(8000); // new entry
109
+ });
110
+ it('should update task-type average when provided', () => {
111
+ const baseline = {
112
+ overall_avg: 10000,
113
+ by_task_type: { debugging: 8000 },
114
+ by_project: {},
115
+ sample_count: 5,
116
+ last_updated: new Date().toISOString()
117
+ };
118
+ const result = updateSessionBaseline(6000, '/path/to/project', 'debugging', baseline);
119
+ expect(result.by_task_type['debugging']).toBeLessThan(8000);
120
+ });
121
+ it('should throw on negative token counts', () => {
122
+ expect(() => updateSessionBaseline(-1000, '/path/to/project')).toThrow('Session tokens cannot be negative');
123
+ });
124
+ it('should update last_updated timestamp', () => {
125
+ const oldTimestamp = new Date('2024-01-01').toISOString();
126
+ const baseline = {
127
+ overall_avg: 10000,
128
+ by_task_type: {},
129
+ by_project: {},
130
+ sample_count: 1,
131
+ last_updated: oldTimestamp
132
+ };
133
+ const result = updateSessionBaseline(8000, '/path/to/project', undefined, baseline);
134
+ expect(result.last_updated).not.toBe(oldTimestamp);
135
+ expect(new Date(result.last_updated).getTime()).toBeGreaterThan(new Date(oldTimestamp).getTime());
136
+ });
137
+ });
138
+ describe('getWarningThreshold', () => {
139
+ it('should calculate warning threshold with default multiplier', () => {
140
+ expect(getWarningThreshold(10000)).toBe(15000); // 1.5x default
141
+ });
142
+ it('should calculate warning threshold with custom multiplier', () => {
143
+ expect(getWarningThreshold(10000, 2.0)).toBe(20000);
144
+ });
145
+ it('should handle zero baseline', () => {
146
+ expect(getWarningThreshold(0, 1.5)).toBe(0);
147
+ });
148
+ it('should throw on negative baseline', () => {
149
+ expect(() => getWarningThreshold(-10000, 1.5)).toThrow('Baseline and multiplier must be non-negative');
150
+ });
151
+ it('should throw on negative multiplier', () => {
152
+ expect(() => getWarningThreshold(10000, -1.5)).toThrow('Baseline and multiplier must be non-negative');
153
+ });
154
+ });
155
+ //# sourceMappingURL=baselines.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baselines.test.js","sourceRoot":"","sources":["../../../src/__tests__/learning/baselines.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=efficiency.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"efficiency.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/learning/efficiency.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,94 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { calculateEfficiencyScore, calculateTrend } from '../../learning/efficiency.js';
3
+ describe('calculateEfficiencyScore', () => {
4
+ it('should calculate efficiency score correctly', () => {
5
+ const score = calculateEfficiencyScore(0.9, 5000, 10000);
6
+ // successRate * (baseline / avgTokens)
7
+ // 0.9 * (10000 / 5000) = 0.9 * 2 = 1.8
8
+ expect(score).toBe(1.8);
9
+ });
10
+ it('should cap token factor at 2x', () => {
11
+ // Very low tokens should cap at 2x
12
+ const score = calculateEfficiencyScore(0.9, 1000, 10000);
13
+ // 0.9 * min(10, 2) = 0.9 * 2 = 1.8
14
+ expect(score).toBe(1.8);
15
+ });
16
+ it('should handle zero success rate', () => {
17
+ const score = calculateEfficiencyScore(0, 5000, 10000);
18
+ expect(score).toBe(0);
19
+ });
20
+ it('should handle zero tokens (return 0)', () => {
21
+ const score = calculateEfficiencyScore(0.9, 0, 10000);
22
+ expect(score).toBe(0);
23
+ });
24
+ it('should handle high token usage (low efficiency)', () => {
25
+ const score = calculateEfficiencyScore(0.9, 20000, 10000);
26
+ // 0.9 * (10000 / 20000) = 0.9 * 0.5 = 0.45
27
+ expect(score).toBe(0.45);
28
+ });
29
+ it('should throw on invalid success rate (negative)', () => {
30
+ expect(() => calculateEfficiencyScore(-0.1, 5000, 10000)).toThrow('Invalid success rate');
31
+ });
32
+ it('should throw on invalid success rate (> 1)', () => {
33
+ expect(() => calculateEfficiencyScore(1.5, 5000, 10000)).toThrow('Invalid success rate');
34
+ });
35
+ it('should throw on negative token counts', () => {
36
+ expect(() => calculateEfficiencyScore(0.9, -5000, 10000)).toThrow('Token counts cannot be negative');
37
+ expect(() => calculateEfficiencyScore(0.9, 5000, -10000)).toThrow('Token counts cannot be negative');
38
+ });
39
+ it('should handle perfect efficiency (100% success, half the tokens)', () => {
40
+ const score = calculateEfficiencyScore(1.0, 5000, 10000);
41
+ // 1.0 * (10000 / 5000) = 1.0 * 2 = 2.0
42
+ expect(score).toBe(2.0);
43
+ });
44
+ it('should handle baseline equal to average', () => {
45
+ const score = calculateEfficiencyScore(0.8, 10000, 10000);
46
+ // 0.8 * (10000 / 10000) = 0.8 * 1 = 0.8
47
+ expect(score).toBe(0.8);
48
+ });
49
+ });
50
+ describe('calculateTrend', () => {
51
+ it('should return insufficient_data when samples < 5', () => {
52
+ expect(calculateTrend(5000, 6000, 4)).toBe('insufficient_data');
53
+ expect(calculateTrend(5000, 6000, 0)).toBe('insufficient_data');
54
+ });
55
+ it('should detect improving trend (tokens decreasing)', () => {
56
+ // recentAvg is 10% lower than historical
57
+ const trend = calculateTrend(9000, 10000, 10);
58
+ expect(trend).toBe('improving');
59
+ });
60
+ it('should detect declining trend (tokens increasing)', () => {
61
+ // recentAvg is 10% higher than historical
62
+ const trend = calculateTrend(11000, 10000, 10);
63
+ expect(trend).toBe('declining');
64
+ });
65
+ it('should detect stable trend (within 10% threshold)', () => {
66
+ const trend = calculateTrend(10050, 10000, 10);
67
+ expect(trend).toBe('stable');
68
+ });
69
+ it('should handle edge case: historical avg is zero', () => {
70
+ const trend = calculateTrend(5000, 0, 10);
71
+ expect(trend).toBe('insufficient_data');
72
+ });
73
+ it('should throw on negative averages', () => {
74
+ expect(() => calculateTrend(-5000, 10000, 10)).toThrow('Average token counts cannot be negative');
75
+ expect(() => calculateTrend(5000, -10000, 10)).toThrow('Average token counts cannot be negative');
76
+ });
77
+ it('should detect improving trend at exactly -10%', () => {
78
+ const trend = calculateTrend(9000, 10000, 10);
79
+ expect(trend).toBe('improving');
80
+ });
81
+ it('should detect declining trend at exactly +10%', () => {
82
+ const trend = calculateTrend(11000, 10000, 10);
83
+ expect(trend).toBe('declining');
84
+ });
85
+ it('should detect stable at -9% (just under threshold)', () => {
86
+ const trend = calculateTrend(9100, 10000, 10);
87
+ expect(trend).toBe('stable');
88
+ });
89
+ it('should detect stable at +9% (just under threshold)', () => {
90
+ const trend = calculateTrend(10900, 10000, 10);
91
+ expect(trend).toBe('stable');
92
+ });
93
+ });
94
+ //# sourceMappingURL=efficiency.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"efficiency.test.js","sourceRoot":"","sources":["../../../src/__tests__/learning/efficiency.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Tests for Phase 2.4 Feedback Loop (Injection)
3
+ * Verifies token metrics integration into session start and budget warnings
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=feedback-loop-injection.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-loop-injection.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/learning/feedback-loop-injection.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}