olympus-ai 3.2.3 → 3.3.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/.claude-plugin/plugin.json +1 -1
  2. package/dist/__tests__/ascent-checkpoint.test.d.ts +2 -0
  3. package/dist/__tests__/ascent-checkpoint.test.d.ts.map +1 -0
  4. package/dist/__tests__/ascent-checkpoint.test.js +261 -0
  5. package/dist/__tests__/ascent-checkpoint.test.js.map +1 -0
  6. package/dist/__tests__/config-ascent.test.d.ts +2 -0
  7. package/dist/__tests__/config-ascent.test.d.ts.map +1 -0
  8. package/dist/__tests__/config-ascent.test.js +134 -0
  9. package/dist/__tests__/config-ascent.test.js.map +1 -0
  10. package/dist/__tests__/hook-blocking.test.d.ts +8 -0
  11. package/dist/__tests__/hook-blocking.test.d.ts.map +1 -0
  12. package/dist/__tests__/hook-blocking.test.js +277 -0
  13. package/dist/__tests__/hook-blocking.test.js.map +1 -0
  14. package/dist/__tests__/installer.test.js +1 -1
  15. package/dist/__tests__/metrics-cli.test.d.ts +5 -0
  16. package/dist/__tests__/metrics-cli.test.d.ts.map +1 -0
  17. package/dist/__tests__/metrics-cli.test.js +24 -0
  18. package/dist/__tests__/metrics-cli.test.js.map +1 -0
  19. package/dist/__tests__/skill-auto-detection.test.d.ts +2 -0
  20. package/dist/__tests__/skill-auto-detection.test.d.ts.map +1 -0
  21. package/dist/__tests__/skill-auto-detection.test.js +255 -0
  22. package/dist/__tests__/skill-auto-detection.test.js.map +1 -0
  23. package/dist/__tests__/token-estimator.test.d.ts +5 -0
  24. package/dist/__tests__/token-estimator.test.d.ts.map +1 -0
  25. package/dist/__tests__/token-estimator.test.js +192 -0
  26. package/dist/__tests__/token-estimator.test.js.map +1 -0
  27. package/dist/agents/definitions.d.ts.map +1 -1
  28. package/dist/agents/definitions.js +83 -1
  29. package/dist/agents/definitions.js.map +1 -1
  30. package/dist/agents/document-writer.d.ts.map +1 -1
  31. package/dist/agents/document-writer.js +38 -0
  32. package/dist/agents/document-writer.js.map +1 -1
  33. package/dist/agents/frontend-engineer.d.ts.map +1 -1
  34. package/dist/agents/frontend-engineer.js +16 -0
  35. package/dist/agents/frontend-engineer.js.map +1 -1
  36. package/dist/agents/olympian.d.ts.map +1 -1
  37. package/dist/agents/olympian.js +15 -0
  38. package/dist/agents/olympian.js.map +1 -1
  39. package/dist/cli/commands/metrics.d.ts +31 -0
  40. package/dist/cli/commands/metrics.d.ts.map +1 -0
  41. package/dist/cli/commands/metrics.js +266 -0
  42. package/dist/cli/commands/metrics.js.map +1 -0
  43. package/dist/cli/index.js +39 -0
  44. package/dist/cli/index.js.map +1 -1
  45. package/dist/config/loader.d.ts.map +1 -1
  46. package/dist/config/loader.js +16 -0
  47. package/dist/config/loader.js.map +1 -1
  48. package/dist/features/ascent-checkpoint/index.d.ts +48 -0
  49. package/dist/features/ascent-checkpoint/index.d.ts.map +1 -0
  50. package/dist/features/ascent-checkpoint/index.js +144 -0
  51. package/dist/features/ascent-checkpoint/index.js.map +1 -0
  52. package/dist/features/hook-logging/index.d.ts +37 -0
  53. package/dist/features/hook-logging/index.d.ts.map +1 -0
  54. package/dist/features/hook-logging/index.js +120 -0
  55. package/dist/features/hook-logging/index.js.map +1 -0
  56. package/dist/features/hook-logging/index.test.d.ts +5 -0
  57. package/dist/features/hook-logging/index.test.d.ts.map +1 -0
  58. package/dist/features/hook-logging/index.test.js +268 -0
  59. package/dist/features/hook-logging/index.test.js.map +1 -0
  60. package/dist/features/index.d.ts +3 -0
  61. package/dist/features/index.d.ts.map +1 -1
  62. package/dist/features/index.js +8 -0
  63. package/dist/features/index.js.map +1 -1
  64. package/dist/features/magic-keywords.d.ts +51 -0
  65. package/dist/features/magic-keywords.d.ts.map +1 -1
  66. package/dist/features/magic-keywords.js +172 -0
  67. package/dist/features/magic-keywords.js.map +1 -1
  68. package/dist/features/session-state/index.d.ts +50 -0
  69. package/dist/features/session-state/index.d.ts.map +1 -0
  70. package/dist/features/session-state/index.js +64 -0
  71. package/dist/features/session-state/index.js.map +1 -0
  72. package/dist/features/session-state/index.test.d.ts +5 -0
  73. package/dist/features/session-state/index.test.d.ts.map +1 -0
  74. package/dist/features/session-state/index.test.js +221 -0
  75. package/dist/features/session-state/index.test.js.map +1 -0
  76. package/dist/features/token-metrics/index.d.ts +6 -0
  77. package/dist/features/token-metrics/index.d.ts.map +1 -0
  78. package/dist/features/token-metrics/index.js +5 -0
  79. package/dist/features/token-metrics/index.js.map +1 -0
  80. package/dist/features/token-metrics/storage.d.ts +16 -0
  81. package/dist/features/token-metrics/storage.d.ts.map +1 -0
  82. package/dist/features/token-metrics/storage.js +144 -0
  83. package/dist/features/token-metrics/storage.js.map +1 -0
  84. package/dist/features/token-metrics/token-estimator.d.ts +66 -0
  85. package/dist/features/token-metrics/token-estimator.d.ts.map +1 -0
  86. package/dist/features/token-metrics/token-estimator.js +230 -0
  87. package/dist/features/token-metrics/token-estimator.js.map +1 -0
  88. package/dist/features/token-metrics/types.d.ts +63 -0
  89. package/dist/features/token-metrics/types.d.ts.map +1 -0
  90. package/dist/features/token-metrics/types.js +5 -0
  91. package/dist/features/token-metrics/types.js.map +1 -0
  92. package/dist/hooks/olympus-orchestrator/constants.d.ts +2 -0
  93. package/dist/hooks/olympus-orchestrator/constants.d.ts.map +1 -1
  94. package/dist/hooks/olympus-orchestrator/constants.js +41 -0
  95. package/dist/hooks/olympus-orchestrator/constants.js.map +1 -1
  96. package/dist/hooks/olympus-orchestrator/index.d.ts +10 -1
  97. package/dist/hooks/olympus-orchestrator/index.d.ts.map +1 -1
  98. package/dist/hooks/olympus-orchestrator/index.js +108 -14
  99. package/dist/hooks/olympus-orchestrator/index.js.map +1 -1
  100. package/dist/hooks/registrations/index.d.ts +2 -1
  101. package/dist/hooks/registrations/index.d.ts.map +1 -1
  102. package/dist/hooks/registrations/index.js +3 -1
  103. package/dist/hooks/registrations/index.js.map +1 -1
  104. package/dist/hooks/registrations/token-metrics.d.ts +11 -0
  105. package/dist/hooks/registrations/token-metrics.d.ts.map +1 -0
  106. package/dist/hooks/registrations/token-metrics.js +119 -0
  107. package/dist/hooks/registrations/token-metrics.js.map +1 -0
  108. package/dist/installer/index.d.ts +1 -1
  109. package/dist/installer/index.d.ts.map +1 -1
  110. package/dist/installer/index.js +334 -9
  111. package/dist/installer/index.js.map +1 -1
  112. package/dist/shared/types.d.ts +16 -0
  113. package/dist/shared/types.d.ts.map +1 -1
  114. package/package.json +3 -3
  115. package/scripts/.olympus/token-metrics.jsonl +1 -0
  116. package/scripts/dist/hooks/olympus-hooks.cjs +127 -128
  117. package/scripts/esbuild.hooks.mjs +1 -1
  118. package/.claude/CLAUDE.md +0 -66
  119. package/scripts/generate-logo-hybrid-v2.mjs +0 -213
  120. package/scripts/generate-logo-hybrid.mjs +0 -209
  121. package/scripts/generate-logo-infinity.mjs +0 -239
  122. package/scripts/generate-logo-mythology.mjs +0 -190
  123. package/scripts/generate-logo-orchestration.mjs +0 -228
  124. package/scripts/generate-logo-recraft.mjs +0 -147
  125. package/scripts/generate-logo-simple.mjs +0 -154
  126. package/scripts/generate-logo.mjs +0 -117
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Tests for Session State Tracking
3
+ */
4
+ import { describe, it, expect, beforeEach } from 'vitest';
5
+ import { SessionState } from './index.js';
6
+ describe('SessionState', () => {
7
+ let state;
8
+ beforeEach(() => {
9
+ state = new SessionState();
10
+ });
11
+ describe('recordTaskCompletion', () => {
12
+ it('should record a single task completion', () => {
13
+ const completion = {
14
+ timestamp: Date.now(),
15
+ filesModified: ['src/index.ts'],
16
+ taskId: 'task-1',
17
+ };
18
+ state.recordTaskCompletion(completion);
19
+ expect(state.trackedCount).toBe(1);
20
+ expect(state.getRecentTasks()).toEqual([completion]);
21
+ });
22
+ it('should record multiple task completions', () => {
23
+ const completion1 = {
24
+ timestamp: Date.now(),
25
+ filesModified: ['src/index.ts'],
26
+ taskId: 'task-1',
27
+ };
28
+ const completion2 = {
29
+ timestamp: Date.now() + 1000,
30
+ filesModified: ['src/utils.ts'],
31
+ taskId: 'task-2',
32
+ };
33
+ state.recordTaskCompletion(completion1);
34
+ state.recordTaskCompletion(completion2);
35
+ expect(state.trackedCount).toBe(2);
36
+ expect(state.getRecentTasks()).toEqual([completion2, completion1]);
37
+ });
38
+ it('should maintain maximum of 3 tasks', () => {
39
+ const tasks = [
40
+ { timestamp: 1, filesModified: ['file1.ts'], taskId: 'task-1' },
41
+ { timestamp: 2, filesModified: ['file2.ts'], taskId: 'task-2' },
42
+ { timestamp: 3, filesModified: ['file3.ts'], taskId: 'task-3' },
43
+ { timestamp: 4, filesModified: ['file4.ts'], taskId: 'task-4' },
44
+ ];
45
+ for (const task of tasks) {
46
+ state.recordTaskCompletion(task);
47
+ }
48
+ expect(state.trackedCount).toBe(3);
49
+ const recent = state.getRecentTasks();
50
+ expect(recent).toHaveLength(3);
51
+ expect(recent[0].taskId).toBe('task-4'); // Most recent
52
+ expect(recent[1].taskId).toBe('task-3');
53
+ expect(recent[2].taskId).toBe('task-2');
54
+ // task-1 should be evicted
55
+ });
56
+ it('should add new tasks to the front', () => {
57
+ const task1 = {
58
+ timestamp: 1,
59
+ filesModified: ['file1.ts'],
60
+ taskId: 'task-1',
61
+ };
62
+ const task2 = {
63
+ timestamp: 2,
64
+ filesModified: ['file2.ts'],
65
+ taskId: 'task-2',
66
+ };
67
+ state.recordTaskCompletion(task1);
68
+ state.recordTaskCompletion(task2);
69
+ const recent = state.getRecentTasks();
70
+ expect(recent[0]).toEqual(task2); // Most recent first
71
+ expect(recent[1]).toEqual(task1);
72
+ });
73
+ });
74
+ describe('isVerificationEdit', () => {
75
+ beforeEach(() => {
76
+ state.recordTaskCompletion({
77
+ timestamp: Date.now(),
78
+ filesModified: ['src/index.ts', 'src/utils.ts'],
79
+ taskId: 'task-1',
80
+ });
81
+ });
82
+ it('should return true for small edit on recent task file', () => {
83
+ expect(state.isVerificationEdit('src/index.ts', 5)).toBe(true);
84
+ expect(state.isVerificationEdit('src/utils.ts', 9)).toBe(true);
85
+ });
86
+ it('should return false for large edit on recent task file', () => {
87
+ expect(state.isVerificationEdit('src/index.ts', 10)).toBe(false);
88
+ expect(state.isVerificationEdit('src/index.ts', 100)).toBe(false);
89
+ });
90
+ it('should return false for small edit on non-recent file', () => {
91
+ expect(state.isVerificationEdit('src/other.ts', 5)).toBe(false);
92
+ });
93
+ it('should return false for file not modified by any task', () => {
94
+ expect(state.isVerificationEdit('new-file.ts', 3)).toBe(false);
95
+ });
96
+ it('should check across multiple recent tasks', () => {
97
+ state.recordTaskCompletion({
98
+ timestamp: Date.now() + 1000,
99
+ filesModified: ['src/components.ts'],
100
+ taskId: 'task-2',
101
+ });
102
+ state.recordTaskCompletion({
103
+ timestamp: Date.now() + 2000,
104
+ filesModified: ['src/hooks.ts'],
105
+ taskId: 'task-3',
106
+ });
107
+ // All files from last 3 tasks should be considered
108
+ expect(state.isVerificationEdit('src/hooks.ts', 5)).toBe(true);
109
+ expect(state.isVerificationEdit('src/components.ts', 5)).toBe(true);
110
+ expect(state.isVerificationEdit('src/index.ts', 5)).toBe(true);
111
+ });
112
+ it('should not consider files from evicted tasks', () => {
113
+ // Add 3 more tasks, pushing task-1 out
114
+ state.recordTaskCompletion({
115
+ timestamp: Date.now() + 1000,
116
+ filesModified: ['file2.ts'],
117
+ taskId: 'task-2',
118
+ });
119
+ state.recordTaskCompletion({
120
+ timestamp: Date.now() + 2000,
121
+ filesModified: ['file3.ts'],
122
+ taskId: 'task-3',
123
+ });
124
+ state.recordTaskCompletion({
125
+ timestamp: Date.now() + 3000,
126
+ filesModified: ['file4.ts'],
127
+ taskId: 'task-4',
128
+ });
129
+ // Original files should no longer be considered
130
+ expect(state.isVerificationEdit('src/index.ts', 5)).toBe(false);
131
+ expect(state.isVerificationEdit('src/utils.ts', 5)).toBe(false);
132
+ // New files should be considered
133
+ expect(state.isVerificationEdit('file2.ts', 5)).toBe(true);
134
+ expect(state.isVerificationEdit('file3.ts', 5)).toBe(true);
135
+ expect(state.isVerificationEdit('file4.ts', 5)).toBe(true);
136
+ });
137
+ it('should handle boundary case of exactly 10 lines', () => {
138
+ expect(state.isVerificationEdit('src/index.ts', 9)).toBe(true);
139
+ expect(state.isVerificationEdit('src/index.ts', 10)).toBe(false);
140
+ });
141
+ });
142
+ describe('getRecentTaskFiles', () => {
143
+ it('should return empty array when no tasks', () => {
144
+ expect(state.getRecentTaskFiles()).toEqual([]);
145
+ });
146
+ it('should return files from single task', () => {
147
+ state.recordTaskCompletion({
148
+ timestamp: Date.now(),
149
+ filesModified: ['file1.ts', 'file2.ts'],
150
+ taskId: 'task-1',
151
+ });
152
+ const files = state.getRecentTaskFiles();
153
+ expect(files).toContain('file1.ts');
154
+ expect(files).toContain('file2.ts');
155
+ });
156
+ it('should return deduplicated files from multiple tasks', () => {
157
+ state.recordTaskCompletion({
158
+ timestamp: 1,
159
+ filesModified: ['file1.ts', 'file2.ts'],
160
+ taskId: 'task-1',
161
+ });
162
+ state.recordTaskCompletion({
163
+ timestamp: 2,
164
+ filesModified: ['file2.ts', 'file3.ts'], // file2.ts repeated
165
+ taskId: 'task-2',
166
+ });
167
+ const files = state.getRecentTaskFiles();
168
+ expect(files).toHaveLength(3);
169
+ expect(files).toContain('file1.ts');
170
+ expect(files).toContain('file2.ts');
171
+ expect(files).toContain('file3.ts');
172
+ });
173
+ it('should only include files from last 3 tasks', () => {
174
+ state.recordTaskCompletion({
175
+ timestamp: 1,
176
+ filesModified: ['old-file.ts'],
177
+ taskId: 'task-1',
178
+ });
179
+ state.recordTaskCompletion({
180
+ timestamp: 2,
181
+ filesModified: ['file2.ts'],
182
+ taskId: 'task-2',
183
+ });
184
+ state.recordTaskCompletion({
185
+ timestamp: 3,
186
+ filesModified: ['file3.ts'],
187
+ taskId: 'task-3',
188
+ });
189
+ state.recordTaskCompletion({
190
+ timestamp: 4,
191
+ filesModified: ['file4.ts'],
192
+ taskId: 'task-4',
193
+ });
194
+ const files = state.getRecentTaskFiles();
195
+ expect(files).not.toContain('old-file.ts');
196
+ expect(files).toContain('file2.ts');
197
+ expect(files).toContain('file3.ts');
198
+ expect(files).toContain('file4.ts');
199
+ });
200
+ });
201
+ describe('clear', () => {
202
+ it('should clear all tracked tasks', () => {
203
+ state.recordTaskCompletion({
204
+ timestamp: Date.now(),
205
+ filesModified: ['file1.ts'],
206
+ taskId: 'task-1',
207
+ });
208
+ state.recordTaskCompletion({
209
+ timestamp: Date.now(),
210
+ filesModified: ['file2.ts'],
211
+ taskId: 'task-2',
212
+ });
213
+ expect(state.trackedCount).toBe(2);
214
+ state.clear();
215
+ expect(state.trackedCount).toBe(0);
216
+ expect(state.getRecentTasks()).toEqual([]);
217
+ expect(state.getRecentTaskFiles()).toEqual([]);
218
+ });
219
+ });
220
+ });
221
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../../src/features/session-state/index.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Token metrics system for Olympus analytics
3
+ */
4
+ export { estimateTokens, estimateTokensDetailed, estimateTokensFromToolOutput, estimateContextSize, estimateTokensSync } from './token-estimator.js';
5
+ export type { TokenEstimate, ConversationMetrics } from './types.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/features/token-metrics/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACrJ,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Token metrics system for Olympus analytics
3
+ */
4
+ export { estimateTokens, estimateTokensDetailed, estimateTokensFromToolOutput, estimateContextSize, estimateTokensSync } from './token-estimator.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/features/token-metrics/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { TokenMetricsEntry } from './types.js';
2
+ /** Get token metrics storage directory (project-specific) */
3
+ export declare function getTokenMetricsDir(projectPath: string): string;
4
+ /** Get token metrics archive directory */
5
+ export declare function getTokenMetricsArchiveDir(projectPath: string): string;
6
+ /** Ensure token metrics directories exist */
7
+ export declare function ensureTokenMetricsDirs(projectPath: string): void;
8
+ /** Log a token metric entry */
9
+ export declare function logTokenMetric(entry: TokenMetricsEntry, projectPath?: string): Promise<void>;
10
+ /** Read token metrics from JSONL file */
11
+ export declare function readTokenMetrics(projectPath?: string, limit?: number): Promise<TokenMetricsEntry[]>;
12
+ /** Read all token metrics including archived files */
13
+ export declare function readAllTokenMetrics(projectPath?: string): Promise<TokenMetricsEntry[]>;
14
+ /** Clean up old metrics files beyond retention period */
15
+ export declare function cleanupOldMetrics(daysToKeep: number, projectPath?: string): Promise<void>;
16
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/features/token-metrics/storage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAKpD,6DAA6D;AAC7D,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,0CAA0C;AAC1C,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAErE;AAED,6CAA6C;AAC7C,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAUhE;AAwBD,+BAA+B;AAC/B,wBAAsB,cAAc,CAAC,KAAK,EAAE,iBAAiB,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWlG;AAED,yCAAyC;AACzC,wBAAsB,gBAAgB,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAsBzG;AAED,sDAAsD;AACtD,wBAAsB,mBAAmB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAmC5F;AAED,yDAAyD;AACzD,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkC/F"}
@@ -0,0 +1,144 @@
1
+ import { join } from 'path';
2
+ import { existsSync, mkdirSync, appendFileSync, readFileSync, renameSync, readdirSync, unlinkSync, statSync } from 'fs';
3
+ /** Maximum lines before rotating JSONL files */
4
+ const MAX_JSONL_LINES = 10000;
5
+ /** Get token metrics storage directory (project-specific) */
6
+ export function getTokenMetricsDir(projectPath) {
7
+ return join(projectPath, '.olympus');
8
+ }
9
+ /** Get token metrics archive directory */
10
+ export function getTokenMetricsArchiveDir(projectPath) {
11
+ return join(projectPath, '.olympus', 'archives');
12
+ }
13
+ /** Ensure token metrics directories exist */
14
+ export function ensureTokenMetricsDirs(projectPath) {
15
+ const metricsDir = getTokenMetricsDir(projectPath);
16
+ if (!existsSync(metricsDir)) {
17
+ mkdirSync(metricsDir, { recursive: true });
18
+ }
19
+ const archiveDir = getTokenMetricsArchiveDir(projectPath);
20
+ if (!existsSync(archiveDir)) {
21
+ mkdirSync(archiveDir, { recursive: true });
22
+ }
23
+ }
24
+ /** Rotate JSONL file if it exceeds size threshold */
25
+ function rotateIfNeeded(filePath, projectPath, maxLines = MAX_JSONL_LINES) {
26
+ if (!existsSync(filePath))
27
+ return;
28
+ try {
29
+ const content = readFileSync(filePath, 'utf-8');
30
+ const lineCount = content.split('\n').filter(l => l.trim()).length;
31
+ if (lineCount >= maxLines) {
32
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
33
+ const archiveDir = getTokenMetricsArchiveDir(projectPath);
34
+ const archivePath = join(archiveDir, `token-metrics-${timestamp}.jsonl`);
35
+ renameSync(filePath, archivePath);
36
+ console.log(`[Olympus Token Metrics] Archived ${lineCount} entries to ${archivePath}`);
37
+ }
38
+ }
39
+ catch (error) {
40
+ console.error(`[Olympus Token Metrics] Failed to rotate ${filePath}:`, error);
41
+ // Don't throw - rotation failures should not block appending
42
+ }
43
+ }
44
+ /** Log a token metric entry */
45
+ export async function logTokenMetric(entry, projectPath) {
46
+ // Use project path from entry if not provided
47
+ const path = projectPath || entry.project_path || process.cwd();
48
+ ensureTokenMetricsDirs(path);
49
+ const logPath = join(getTokenMetricsDir(path), 'token-metrics.jsonl');
50
+ // Rotate before appending
51
+ rotateIfNeeded(logPath, path);
52
+ appendFileSync(logPath, JSON.stringify(entry) + '\n', 'utf-8');
53
+ }
54
+ /** Read token metrics from JSONL file */
55
+ export async function readTokenMetrics(projectPath, limit) {
56
+ const path = projectPath || process.cwd();
57
+ const logPath = join(getTokenMetricsDir(path), 'token-metrics.jsonl');
58
+ if (!existsSync(logPath))
59
+ return [];
60
+ try {
61
+ const content = readFileSync(logPath, 'utf-8');
62
+ const entries = content
63
+ .split('\n')
64
+ .filter(line => line.trim())
65
+ .map(line => JSON.parse(line));
66
+ if (limit && limit > 0) {
67
+ return entries.slice(-limit); // Return last N entries
68
+ }
69
+ return entries;
70
+ }
71
+ catch (error) {
72
+ console.error(`[Olympus Token Metrics] Failed to read ${logPath}:`, error);
73
+ return [];
74
+ }
75
+ }
76
+ /** Read all token metrics including archived files */
77
+ export async function readAllTokenMetrics(projectPath) {
78
+ const path = projectPath || process.cwd();
79
+ const allEntries = [];
80
+ // Read current file
81
+ const currentEntries = await readTokenMetrics(path);
82
+ allEntries.push(...currentEntries);
83
+ // Read archived files
84
+ const archiveDir = getTokenMetricsArchiveDir(path);
85
+ if (existsSync(archiveDir)) {
86
+ try {
87
+ const archiveFiles = readdirSync(archiveDir)
88
+ .filter(f => f.startsWith('token-metrics-') && f.endsWith('.jsonl'))
89
+ .sort(); // Chronological order
90
+ for (const file of archiveFiles) {
91
+ const archivePath = join(archiveDir, file);
92
+ try {
93
+ const content = readFileSync(archivePath, 'utf-8');
94
+ const entries = content
95
+ .split('\n')
96
+ .filter(line => line.trim())
97
+ .map(line => JSON.parse(line));
98
+ allEntries.push(...entries);
99
+ }
100
+ catch (error) {
101
+ console.error(`[Olympus Token Metrics] Failed to read archive ${file}:`, error);
102
+ }
103
+ }
104
+ }
105
+ catch (error) {
106
+ console.error(`[Olympus Token Metrics] Failed to read archive directory:`, error);
107
+ }
108
+ }
109
+ return allEntries;
110
+ }
111
+ /** Clean up old metrics files beyond retention period */
112
+ export async function cleanupOldMetrics(daysToKeep, projectPath) {
113
+ const path = projectPath || process.cwd();
114
+ const archiveDir = getTokenMetricsArchiveDir(path);
115
+ if (!existsSync(archiveDir))
116
+ return;
117
+ const cutoffDate = new Date();
118
+ cutoffDate.setDate(cutoffDate.getDate() - daysToKeep);
119
+ try {
120
+ const archiveFiles = readdirSync(archiveDir)
121
+ .filter(f => f.startsWith('token-metrics-') && f.endsWith('.jsonl'));
122
+ let deletedCount = 0;
123
+ for (const file of archiveFiles) {
124
+ const filePath = join(archiveDir, file);
125
+ try {
126
+ const stats = statSync(filePath);
127
+ if (stats.mtime < cutoffDate) {
128
+ unlinkSync(filePath);
129
+ deletedCount++;
130
+ }
131
+ }
132
+ catch (error) {
133
+ console.error(`[Olympus Token Metrics] Failed to process ${file}:`, error);
134
+ }
135
+ }
136
+ if (deletedCount > 0) {
137
+ console.log(`[Olympus Token Metrics] Cleaned up ${deletedCount} old archive files`);
138
+ }
139
+ }
140
+ catch (error) {
141
+ console.error(`[Olympus Token Metrics] Failed to cleanup old metrics:`, error);
142
+ }
143
+ }
144
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/features/token-metrics/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Token estimation utilities for Olympus metrics
3
+ *
4
+ * Uses gpt-tokenizer for accurate token counting with fallback to character-based estimation.
5
+ * Token counts are approximations for tracking trends, not exact billing calculations.
6
+ */
7
+ import type { TokenEstimate, ConversationMetrics } from './types.js';
8
+ /**
9
+ * Main token estimation function
10
+ *
11
+ * @param text - Text to estimate tokens for
12
+ * @returns Estimated token count
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * const tokens = await estimateTokens("Hello, world!");
17
+ * console.log(tokens); // ~4 tokens
18
+ * ```
19
+ */
20
+ export declare function estimateTokens(text: string): Promise<number>;
21
+ /**
22
+ * Estimate tokens with detailed metadata
23
+ *
24
+ * @param input - Input to estimate (string, object, array, etc.)
25
+ * @returns Token estimate with method and input type
26
+ */
27
+ export declare function estimateTokensDetailed(input: unknown): Promise<TokenEstimate>;
28
+ /**
29
+ * Estimate tokens from tool output (handles various result formats)
30
+ *
31
+ * @param output - Tool output object (from Claude Code SDK)
32
+ * @returns Estimated token count
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * const readResult = { content: "file contents..." };
37
+ * const tokens = await estimateTokensFromToolOutput(readResult);
38
+ * ```
39
+ */
40
+ export declare function estimateTokensFromToolOutput(output: unknown): Promise<number>;
41
+ /**
42
+ * Estimate total context size from conversation messages
43
+ *
44
+ * @param messages - Array of message objects (any format with text content)
45
+ * @returns Conversation metrics with total tokens and averages
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * const messages = [
50
+ * { role: "user", content: "Hello" },
51
+ * { role: "assistant", content: "Hi there!" }
52
+ * ];
53
+ * const metrics = await estimateContextSize(messages);
54
+ * console.log(metrics.totalTokens); // ~8 tokens
55
+ * ```
56
+ */
57
+ export declare function estimateContextSize(messages: unknown[]): Promise<ConversationMetrics>;
58
+ /**
59
+ * Synchronous version of estimateTokens using only character-based estimation
60
+ * Useful when async operations aren't possible
61
+ *
62
+ * @param text - Text to estimate tokens for
63
+ * @returns Estimated token count (character-based)
64
+ */
65
+ export declare function estimateTokensSync(text: string): number;
66
+ //# sourceMappingURL=token-estimator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-estimator.d.ts","sourceRoot":"","sources":["../../../src/features/token-metrics/token-estimator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAqDrE;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBlE;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CA+BnF;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,4BAA4B,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BnF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAgD3F;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKvD"}