oh-my-claude-sisyphus 3.6.3 → 3.7.2

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 (163) hide show
  1. package/README.md +40 -1
  2. package/commands/hud.md +37 -5
  3. package/commands/omc-setup.md +105 -0
  4. package/dist/__tests__/delegation-enforcement-levels.test.d.ts +9 -0
  5. package/dist/__tests__/delegation-enforcement-levels.test.d.ts.map +1 -0
  6. package/dist/__tests__/delegation-enforcement-levels.test.js +550 -0
  7. package/dist/__tests__/delegation-enforcement-levels.test.js.map +1 -0
  8. package/dist/__tests__/hud/analytics-display.test.js +137 -1
  9. package/dist/__tests__/hud/analytics-display.test.js.map +1 -1
  10. package/dist/__tests__/hud-windows.test.d.ts +2 -0
  11. package/dist/__tests__/hud-windows.test.d.ts.map +1 -0
  12. package/dist/__tests__/hud-windows.test.js +91 -0
  13. package/dist/__tests__/hud-windows.test.js.map +1 -0
  14. package/dist/__tests__/installer.test.js +1 -1
  15. package/dist/__tests__/rate-limit-wait/daemon.test.d.ts +5 -0
  16. package/dist/__tests__/rate-limit-wait/daemon.test.d.ts.map +1 -0
  17. package/dist/__tests__/rate-limit-wait/daemon.test.js +313 -0
  18. package/dist/__tests__/rate-limit-wait/daemon.test.js.map +1 -0
  19. package/dist/__tests__/rate-limit-wait/integration.test.d.ts +8 -0
  20. package/dist/__tests__/rate-limit-wait/integration.test.d.ts.map +1 -0
  21. package/dist/__tests__/rate-limit-wait/integration.test.js +329 -0
  22. package/dist/__tests__/rate-limit-wait/integration.test.js.map +1 -0
  23. package/dist/__tests__/rate-limit-wait/rate-limit-monitor.test.d.ts +5 -0
  24. package/dist/__tests__/rate-limit-wait/rate-limit-monitor.test.d.ts.map +1 -0
  25. package/dist/__tests__/rate-limit-wait/rate-limit-monitor.test.js +167 -0
  26. package/dist/__tests__/rate-limit-wait/rate-limit-monitor.test.js.map +1 -0
  27. package/dist/__tests__/rate-limit-wait/tmux-detector.test.d.ts +5 -0
  28. package/dist/__tests__/rate-limit-wait/tmux-detector.test.d.ts.map +1 -0
  29. package/dist/__tests__/rate-limit-wait/tmux-detector.test.js +295 -0
  30. package/dist/__tests__/rate-limit-wait/tmux-detector.test.js.map +1 -0
  31. package/dist/cli/commands/wait.d.ts +52 -0
  32. package/dist/cli/commands/wait.d.ts.map +1 -0
  33. package/dist/cli/commands/wait.js +229 -0
  34. package/dist/cli/commands/wait.js.map +1 -0
  35. package/dist/cli/index.js +54 -0
  36. package/dist/cli/index.js.map +1 -1
  37. package/dist/features/rate-limit-wait/daemon.d.ts +52 -0
  38. package/dist/features/rate-limit-wait/daemon.d.ts.map +1 -0
  39. package/dist/features/rate-limit-wait/daemon.js +585 -0
  40. package/dist/features/rate-limit-wait/daemon.js.map +1 -0
  41. package/dist/features/rate-limit-wait/index.d.ts +16 -0
  42. package/dist/features/rate-limit-wait/index.d.ts.map +1 -0
  43. package/dist/features/rate-limit-wait/index.js +18 -0
  44. package/dist/features/rate-limit-wait/index.js.map +1 -0
  45. package/dist/features/rate-limit-wait/rate-limit-monitor.d.ts +22 -0
  46. package/dist/features/rate-limit-wait/rate-limit-monitor.d.ts.map +1 -0
  47. package/dist/features/rate-limit-wait/rate-limit-monitor.js +99 -0
  48. package/dist/features/rate-limit-wait/rate-limit-monitor.js.map +1 -0
  49. package/dist/features/rate-limit-wait/tmux-detector.d.ts +59 -0
  50. package/dist/features/rate-limit-wait/tmux-detector.d.ts.map +1 -0
  51. package/dist/features/rate-limit-wait/tmux-detector.js +304 -0
  52. package/dist/features/rate-limit-wait/tmux-detector.js.map +1 -0
  53. package/dist/features/rate-limit-wait/types.d.ts +121 -0
  54. package/dist/features/rate-limit-wait/types.d.ts.map +1 -0
  55. package/dist/features/rate-limit-wait/types.js +8 -0
  56. package/dist/features/rate-limit-wait/types.js.map +1 -0
  57. package/dist/features/state-manager/index.d.ts.map +1 -1
  58. package/dist/features/state-manager/index.js +4 -1
  59. package/dist/features/state-manager/index.js.map +1 -1
  60. package/dist/hooks/bridge.d.ts +1 -1
  61. package/dist/hooks/bridge.d.ts.map +1 -1
  62. package/dist/hooks/bridge.js +50 -4
  63. package/dist/hooks/bridge.js.map +1 -1
  64. package/dist/hooks/index.d.ts +5 -0
  65. package/dist/hooks/index.d.ts.map +1 -1
  66. package/dist/hooks/index.js +15 -0
  67. package/dist/hooks/index.js.map +1 -1
  68. package/dist/hooks/omc-orchestrator/audit.d.ts +2 -1
  69. package/dist/hooks/omc-orchestrator/audit.d.ts.map +1 -1
  70. package/dist/hooks/omc-orchestrator/audit.js.map +1 -1
  71. package/dist/hooks/omc-orchestrator/index.d.ts +7 -0
  72. package/dist/hooks/omc-orchestrator/index.d.ts.map +1 -1
  73. package/dist/hooks/omc-orchestrator/index.js +95 -8
  74. package/dist/hooks/omc-orchestrator/index.js.map +1 -1
  75. package/dist/hooks/permission-handler/__tests__/index.test.d.ts +2 -0
  76. package/dist/hooks/permission-handler/__tests__/index.test.d.ts.map +1 -0
  77. package/dist/hooks/permission-handler/__tests__/index.test.js +291 -0
  78. package/dist/hooks/permission-handler/__tests__/index.test.js.map +1 -0
  79. package/dist/hooks/permission-handler/index.d.ts +42 -0
  80. package/dist/hooks/permission-handler/index.d.ts.map +1 -0
  81. package/dist/hooks/permission-handler/index.js +107 -0
  82. package/dist/hooks/permission-handler/index.js.map +1 -0
  83. package/dist/hooks/plugin-patterns/index.d.ts +5 -0
  84. package/dist/hooks/plugin-patterns/index.d.ts.map +1 -1
  85. package/dist/hooks/plugin-patterns/index.js +26 -1
  86. package/dist/hooks/plugin-patterns/index.js.map +1 -1
  87. package/dist/hooks/pre-compact/index.d.ts +82 -0
  88. package/dist/hooks/pre-compact/index.d.ts.map +1 -0
  89. package/dist/hooks/pre-compact/index.js +265 -0
  90. package/dist/hooks/pre-compact/index.js.map +1 -0
  91. package/dist/hooks/session-end/index.d.ts +42 -0
  92. package/dist/hooks/session-end/index.d.ts.map +1 -0
  93. package/dist/hooks/session-end/index.js +200 -0
  94. package/dist/hooks/session-end/index.js.map +1 -0
  95. package/dist/hooks/setup/index.d.ts +66 -0
  96. package/dist/hooks/setup/index.d.ts.map +1 -0
  97. package/dist/hooks/setup/index.js +299 -0
  98. package/dist/hooks/setup/index.js.map +1 -0
  99. package/dist/hooks/setup/types.d.ts +25 -0
  100. package/dist/hooks/setup/types.d.ts.map +1 -0
  101. package/dist/hooks/setup/types.js +5 -0
  102. package/dist/hooks/setup/types.js.map +1 -0
  103. package/dist/hooks/subagent-tracker/index.d.ts +68 -29
  104. package/dist/hooks/subagent-tracker/index.d.ts.map +1 -1
  105. package/dist/hooks/subagent-tracker/index.js +316 -131
  106. package/dist/hooks/subagent-tracker/index.js.map +1 -1
  107. package/dist/hud/analytics-display.d.ts +16 -0
  108. package/dist/hud/analytics-display.d.ts.map +1 -1
  109. package/dist/hud/analytics-display.js +35 -9
  110. package/dist/hud/analytics-display.js.map +1 -1
  111. package/dist/hud/render.d.ts.map +1 -1
  112. package/dist/hud/render.js +49 -18
  113. package/dist/hud/render.js.map +1 -1
  114. package/dist/hud/types.d.ts +2 -0
  115. package/dist/hud/types.d.ts.map +1 -1
  116. package/dist/hud/types.js +14 -0
  117. package/dist/hud/types.js.map +1 -1
  118. package/dist/installer/index.d.ts +1 -1
  119. package/dist/installer/index.d.ts.map +1 -1
  120. package/dist/installer/index.js +4 -3
  121. package/dist/installer/index.js.map +1 -1
  122. package/hooks/hooks.json +83 -1
  123. package/hooks/keyword-detector.sh +4 -4
  124. package/hooks/persistent-mode.sh +10 -10
  125. package/hooks/session-start.sh +4 -4
  126. package/package.json +3 -1
  127. package/scripts/keyword-detector.mjs +4 -4
  128. package/scripts/permission-handler.mjs +23 -0
  129. package/scripts/persistent-mode.mjs +6 -6
  130. package/scripts/persistent-mode.sh +10 -10
  131. package/scripts/pre-compact.mjs +23 -0
  132. package/scripts/session-end.mjs +23 -0
  133. package/scripts/session-start.mjs +4 -4
  134. package/scripts/setup-init.mjs +23 -0
  135. package/scripts/setup-maintenance.mjs +23 -0
  136. package/scripts/subagent-tracker.mjs +35 -0
  137. package/skills/hud/SKILL.md +37 -5
  138. package/skills/omc-setup/SKILL.md +162 -4
  139. package/skills/writer-memory/SKILL.md +443 -0
  140. package/skills/writer-memory/lib/character-tracker.ts +338 -0
  141. package/skills/writer-memory/lib/memory-manager.ts +804 -0
  142. package/skills/writer-memory/lib/relationship-graph.ts +400 -0
  143. package/skills/writer-memory/lib/scene-organizer.ts +544 -0
  144. package/skills/writer-memory/lib/synopsis-builder.ts +339 -0
  145. package/skills/writer-memory/templates/synopsis-template.md +46 -0
  146. package/templates/hooks/keyword-detector.mjs +198 -0
  147. package/templates/hooks/keyword-detector.sh +102 -0
  148. package/templates/hooks/persistent-mode.mjs +249 -0
  149. package/templates/hooks/persistent-mode.sh +187 -0
  150. package/templates/hooks/post-tool-use.mjs +133 -0
  151. package/templates/hooks/post-tool-use.sh +90 -0
  152. package/templates/hooks/pre-tool-use.mjs +145 -0
  153. package/templates/hooks/pre-tool-use.sh +113 -0
  154. package/templates/hooks/session-start.mjs +100 -0
  155. package/templates/hooks/session-start.sh +62 -0
  156. package/templates/hooks/stop-continuation.mjs +80 -0
  157. package/templates/hooks/stop-continuation.sh +40 -0
  158. package/templates/rules/README.md +40 -0
  159. package/templates/rules/coding-style.md +74 -0
  160. package/templates/rules/git-workflow.md +41 -0
  161. package/templates/rules/performance.md +40 -0
  162. package/templates/rules/security.md +41 -0
  163. package/templates/rules/testing.md +42 -0
@@ -0,0 +1,329 @@
1
+ /**
2
+ * Integration Tests for Rate Limit Wait Feature
3
+ *
4
+ * These tests simulate real-world scenarios without hitting actual rate limits.
5
+ * They verify the full flow from detection to resume.
6
+ */
7
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
8
+ import { mkdirSync, rmSync } from 'fs';
9
+ import { join } from 'path';
10
+ import { tmpdir } from 'os';
11
+ // Mock modules
12
+ vi.mock('../../hud/usage-api.js', () => ({
13
+ getUsage: vi.fn(),
14
+ }));
15
+ vi.mock('child_process', () => ({
16
+ execSync: vi.fn(),
17
+ spawnSync: vi.fn(),
18
+ spawn: vi.fn(),
19
+ }));
20
+ import { getUsage } from '../../hud/usage-api.js';
21
+ import { execSync, spawnSync } from 'child_process';
22
+ import { checkRateLimitStatus, analyzePaneContent, scanForBlockedPanes, formatDaemonState, } from '../../features/rate-limit-wait/index.js';
23
+ describe('Rate Limit Wait Integration Tests', () => {
24
+ const testDir = join(tmpdir(), 'omc-integration-test-' + Date.now());
25
+ beforeEach(() => {
26
+ vi.clearAllMocks();
27
+ mkdirSync(testDir, { recursive: true });
28
+ });
29
+ afterEach(() => {
30
+ try {
31
+ rmSync(testDir, { recursive: true, force: true });
32
+ }
33
+ catch {
34
+ // Ignore cleanup errors
35
+ }
36
+ });
37
+ describe('Scenario: Rate limit detection and tracking', () => {
38
+ it('should detect when 5-hour limit is reached', async () => {
39
+ // Simulate rate limit API response
40
+ vi.mocked(getUsage).mockResolvedValue({
41
+ fiveHourPercent: 100,
42
+ weeklyPercent: 75,
43
+ fiveHourResetsAt: new Date(Date.now() + 3600000),
44
+ weeklyResetsAt: null,
45
+ });
46
+ const status = await checkRateLimitStatus();
47
+ expect(status).not.toBeNull();
48
+ expect(status.isLimited).toBe(true);
49
+ expect(status.fiveHourLimited).toBe(true);
50
+ expect(status.weeklyLimited).toBe(false);
51
+ expect(status.timeUntilResetMs).toBeGreaterThan(0);
52
+ expect(status.timeUntilResetMs).toBeLessThanOrEqual(3600000);
53
+ });
54
+ it('should detect when weekly limit is reached', async () => {
55
+ vi.mocked(getUsage).mockResolvedValue({
56
+ fiveHourPercent: 50,
57
+ weeklyPercent: 100,
58
+ fiveHourResetsAt: null,
59
+ weeklyResetsAt: new Date(Date.now() + 86400000),
60
+ });
61
+ const status = await checkRateLimitStatus();
62
+ expect(status).not.toBeNull();
63
+ expect(status.isLimited).toBe(true);
64
+ expect(status.fiveHourLimited).toBe(false);
65
+ expect(status.weeklyLimited).toBe(true);
66
+ });
67
+ it('should handle transition from limited to not limited', async () => {
68
+ // First call: limited
69
+ vi.mocked(getUsage).mockResolvedValueOnce({
70
+ fiveHourPercent: 100,
71
+ weeklyPercent: 50,
72
+ fiveHourResetsAt: new Date(Date.now() + 1000),
73
+ weeklyResetsAt: null,
74
+ });
75
+ const limitedStatus = await checkRateLimitStatus();
76
+ expect(limitedStatus.isLimited).toBe(true);
77
+ // Second call: no longer limited
78
+ vi.mocked(getUsage).mockResolvedValueOnce({
79
+ fiveHourPercent: 0,
80
+ weeklyPercent: 50,
81
+ fiveHourResetsAt: null,
82
+ weeklyResetsAt: null,
83
+ });
84
+ const clearedStatus = await checkRateLimitStatus();
85
+ expect(clearedStatus.isLimited).toBe(false);
86
+ });
87
+ });
88
+ describe('Scenario: tmux pane analysis accuracy', () => {
89
+ it('should correctly identify Claude Code rate limit message', () => {
90
+ const realWorldContent = `
91
+ ╭─────────────────────────────────────────────────────────────────╮
92
+ │ Claude Code │
93
+ ╰─────────────────────────────────────────────────────────────────╯
94
+
95
+ You've reached your usage limit for the 5-hour period.
96
+ Your limit will reset at 3:45 PM.
97
+
98
+ What would you like to do?
99
+
100
+ [1] Wait and continue automatically when limit resets
101
+ [2] Switch to a different conversation
102
+ [3] Exit
103
+
104
+ > `;
105
+ const result = analyzePaneContent(realWorldContent);
106
+ expect(result.hasClaudeCode).toBe(true);
107
+ expect(result.hasRateLimitMessage).toBe(true);
108
+ expect(result.isBlocked).toBe(true);
109
+ expect(result.rateLimitType).toBe('five_hour');
110
+ expect(result.confidence).toBeGreaterThanOrEqual(0.8);
111
+ });
112
+ it('should correctly identify weekly rate limit message', () => {
113
+ const weeklyLimitContent = `
114
+ Claude Code v1.0.0
115
+
116
+ ⚠️ Weekly usage limit reached
117
+
118
+ You've used your weekly allocation of tokens.
119
+ Limit resets on Monday at 12:00 AM UTC.
120
+
121
+ Options:
122
+ [1] Continue when limit resets
123
+ [2] Exit
124
+
125
+ Enter choice: `;
126
+ const result = analyzePaneContent(weeklyLimitContent);
127
+ expect(result.hasClaudeCode).toBe(true);
128
+ expect(result.hasRateLimitMessage).toBe(true);
129
+ expect(result.isBlocked).toBe(true);
130
+ expect(result.rateLimitType).toBe('weekly');
131
+ });
132
+ it('should NOT flag normal Claude Code output as blocked', () => {
133
+ const normalContent = `
134
+ Claude Code
135
+
136
+ > What would you like to build today?
137
+
138
+ I can help you with:
139
+ - Writing code
140
+ - Debugging
141
+ - Refactoring
142
+ - Documentation
143
+
144
+ Just describe what you need!
145
+ `;
146
+ const result = analyzePaneContent(normalContent);
147
+ expect(result.hasClaudeCode).toBe(true);
148
+ expect(result.hasRateLimitMessage).toBe(false);
149
+ expect(result.isBlocked).toBe(false);
150
+ });
151
+ it('should NOT flag unrelated rate limit messages', () => {
152
+ const unrelatedContent = `
153
+ $ curl https://api.github.com/users/test
154
+ {
155
+ "message": "API rate limit exceeded for IP",
156
+ "documentation_url": "https://docs.github.com"
157
+ }
158
+ $ `;
159
+ const result = analyzePaneContent(unrelatedContent);
160
+ expect(result.hasClaudeCode).toBe(false);
161
+ expect(result.hasRateLimitMessage).toBe(true);
162
+ expect(result.isBlocked).toBe(false); // No Claude context
163
+ });
164
+ it('should handle edge case: old rate limit message scrolled up', () => {
165
+ // Only last 15 lines should be analyzed
166
+ // Rate limit message from earlier should be ignored if not in recent content
167
+ const scrolledContent = `
168
+ User: fix the bug
169
+ Assistant: I'll fix that for you.
170
+ [Edit] src/main.ts
171
+ Done! The bug is fixed.
172
+
173
+ User: thanks
174
+ Assistant: You're welcome!
175
+
176
+ User: what else?
177
+ Assistant: I can help with more tasks.
178
+
179
+ > `;
180
+ const result = analyzePaneContent(scrolledContent);
181
+ expect(result.isBlocked).toBe(false);
182
+ });
183
+ });
184
+ describe('Scenario: Full daemon state lifecycle', () => {
185
+ it('should format daemon state correctly for user display', () => {
186
+ const state = {
187
+ isRunning: true,
188
+ pid: 12345,
189
+ startedAt: new Date('2024-01-01T10:00:00Z'),
190
+ lastPollAt: new Date('2024-01-01T10:05:00Z'),
191
+ rateLimitStatus: {
192
+ fiveHourLimited: true,
193
+ weeklyLimited: false,
194
+ isLimited: true,
195
+ fiveHourResetsAt: new Date('2024-01-01T15:00:00Z'),
196
+ weeklyResetsAt: null,
197
+ nextResetAt: new Date('2024-01-01T15:00:00Z'),
198
+ timeUntilResetMs: 3600000,
199
+ lastCheckedAt: new Date('2024-01-01T10:05:00Z'),
200
+ },
201
+ blockedPanes: [
202
+ {
203
+ id: '%0',
204
+ session: 'dev',
205
+ windowIndex: 0,
206
+ windowName: 'claude',
207
+ paneIndex: 0,
208
+ isActive: true,
209
+ analysis: {
210
+ hasClaudeCode: true,
211
+ hasRateLimitMessage: true,
212
+ isBlocked: true,
213
+ rateLimitType: 'five_hour',
214
+ confidence: 0.95,
215
+ },
216
+ firstDetectedAt: new Date('2024-01-01T10:01:00Z'),
217
+ resumeAttempted: false,
218
+ },
219
+ ],
220
+ resumedPaneIds: [],
221
+ totalResumeAttempts: 0,
222
+ successfulResumes: 0,
223
+ errorCount: 0,
224
+ };
225
+ const output = formatDaemonState(state);
226
+ // Verify key information is present
227
+ expect(output).toContain('Daemon running');
228
+ expect(output).toContain('12345');
229
+ expect(output).toContain('5-hour limit');
230
+ expect(output).toContain('Found 1 blocked');
231
+ expect(output).toContain('%0');
232
+ });
233
+ it('should track resume attempts correctly', () => {
234
+ const stateAfterResume = {
235
+ isRunning: true,
236
+ pid: 12345,
237
+ startedAt: new Date(),
238
+ lastPollAt: new Date(),
239
+ rateLimitStatus: {
240
+ fiveHourLimited: false,
241
+ weeklyLimited: false,
242
+ isLimited: false,
243
+ fiveHourResetsAt: null,
244
+ weeklyResetsAt: null,
245
+ nextResetAt: null,
246
+ timeUntilResetMs: null,
247
+ lastCheckedAt: new Date(),
248
+ },
249
+ blockedPanes: [],
250
+ resumedPaneIds: ['%0', '%1'],
251
+ totalResumeAttempts: 2,
252
+ successfulResumes: 2,
253
+ errorCount: 0,
254
+ };
255
+ const output = formatDaemonState(stateAfterResume);
256
+ expect(output).toContain('Resume attempts: 2');
257
+ expect(output).toContain('Successful: 2');
258
+ expect(output).toContain('Not rate limited');
259
+ });
260
+ });
261
+ describe('Scenario: Error handling and edge cases', () => {
262
+ it('should handle OAuth credentials not available', async () => {
263
+ vi.mocked(getUsage).mockResolvedValue(null);
264
+ const status = await checkRateLimitStatus();
265
+ expect(status).toBeNull();
266
+ });
267
+ it('should handle API timeout gracefully', async () => {
268
+ vi.mocked(getUsage).mockRejectedValue(new Error('ETIMEDOUT'));
269
+ const status = await checkRateLimitStatus();
270
+ expect(status).toBeNull();
271
+ });
272
+ it('should handle tmux not installed', () => {
273
+ vi.mocked(spawnSync).mockReturnValue({
274
+ status: 1,
275
+ stdout: '',
276
+ stderr: 'tmux: command not found',
277
+ signal: null,
278
+ pid: 0,
279
+ output: [],
280
+ });
281
+ // scanForBlockedPanes should return empty array, not throw
282
+ const blocked = scanForBlockedPanes();
283
+ expect(blocked).toEqual([]);
284
+ });
285
+ it('should handle malformed tmux output', () => {
286
+ vi.mocked(spawnSync).mockReturnValue({
287
+ status: 0,
288
+ stdout: '/usr/bin/tmux',
289
+ stderr: '',
290
+ signal: null,
291
+ pid: 1234,
292
+ output: [],
293
+ });
294
+ vi.mocked(execSync).mockReturnValue('malformed output without proper format');
295
+ // Should not throw, just return empty
296
+ const blocked = scanForBlockedPanes();
297
+ expect(blocked).toEqual([]);
298
+ });
299
+ });
300
+ describe('Scenario: Confidence scoring', () => {
301
+ it('should give higher confidence for multiple indicators', () => {
302
+ const highConfidenceContent = `
303
+ Claude Code
304
+ Rate limit reached
305
+ 5-hour usage limit
306
+ [1] Continue
307
+ [2] Exit
308
+ `;
309
+ const lowConfidenceContent = `
310
+ Claude
311
+ rate limit
312
+ `;
313
+ const highResult = analyzePaneContent(highConfidenceContent);
314
+ const lowResult = analyzePaneContent(lowConfidenceContent);
315
+ expect(highResult.confidence).toBeGreaterThan(lowResult.confidence);
316
+ });
317
+ it('should require minimum confidence to mark as blocked', () => {
318
+ const ambiguousContent = `
319
+ some claude reference
320
+ limit mentioned
321
+ `;
322
+ const result = analyzePaneContent(ambiguousContent);
323
+ // Even if some patterns match, confidence should be too low
324
+ expect(result.confidence).toBeLessThan(0.6);
325
+ expect(result.isBlocked).toBe(false);
326
+ });
327
+ });
328
+ });
329
+ //# sourceMappingURL=integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/rate-limit-wait/integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for rate-limit-monitor.ts
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=rate-limit-monitor.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit-monitor.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/rate-limit-wait/rate-limit-monitor.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Tests for rate-limit-monitor.ts
3
+ */
4
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
5
+ import { checkRateLimitStatus, formatTimeUntilReset, formatRateLimitStatus, } from '../../features/rate-limit-wait/rate-limit-monitor.js';
6
+ // Mock the usage-api module
7
+ vi.mock('../../hud/usage-api.js', () => ({
8
+ getUsage: vi.fn(),
9
+ }));
10
+ import { getUsage } from '../../hud/usage-api.js';
11
+ describe('rate-limit-monitor', () => {
12
+ beforeEach(() => {
13
+ vi.clearAllMocks();
14
+ });
15
+ describe('checkRateLimitStatus', () => {
16
+ it('should return null when getUsage returns null', async () => {
17
+ vi.mocked(getUsage).mockResolvedValue(null);
18
+ const result = await checkRateLimitStatus();
19
+ expect(result).toBeNull();
20
+ });
21
+ it('should detect 5-hour rate limit', async () => {
22
+ const resetTime = new Date(Date.now() + 3600000); // 1 hour from now
23
+ vi.mocked(getUsage).mockResolvedValue({
24
+ fiveHourPercent: 100,
25
+ weeklyPercent: 50,
26
+ fiveHourResetsAt: resetTime,
27
+ weeklyResetsAt: null,
28
+ });
29
+ const result = await checkRateLimitStatus();
30
+ expect(result).not.toBeNull();
31
+ expect(result.fiveHourLimited).toBe(true);
32
+ expect(result.weeklyLimited).toBe(false);
33
+ expect(result.isLimited).toBe(true);
34
+ expect(result.nextResetAt).toEqual(resetTime);
35
+ });
36
+ it('should detect weekly rate limit', async () => {
37
+ const resetTime = new Date(Date.now() + 86400000); // 1 day from now
38
+ vi.mocked(getUsage).mockResolvedValue({
39
+ fiveHourPercent: 50,
40
+ weeklyPercent: 100,
41
+ fiveHourResetsAt: null,
42
+ weeklyResetsAt: resetTime,
43
+ });
44
+ const result = await checkRateLimitStatus();
45
+ expect(result).not.toBeNull();
46
+ expect(result.fiveHourLimited).toBe(false);
47
+ expect(result.weeklyLimited).toBe(true);
48
+ expect(result.isLimited).toBe(true);
49
+ expect(result.nextResetAt).toEqual(resetTime);
50
+ });
51
+ it('should detect both limits and return earliest reset', async () => {
52
+ const fiveHourReset = new Date(Date.now() + 3600000); // 1 hour
53
+ const weeklyReset = new Date(Date.now() + 86400000); // 1 day
54
+ vi.mocked(getUsage).mockResolvedValue({
55
+ fiveHourPercent: 100,
56
+ weeklyPercent: 100,
57
+ fiveHourResetsAt: fiveHourReset,
58
+ weeklyResetsAt: weeklyReset,
59
+ });
60
+ const result = await checkRateLimitStatus();
61
+ expect(result).not.toBeNull();
62
+ expect(result.fiveHourLimited).toBe(true);
63
+ expect(result.weeklyLimited).toBe(true);
64
+ expect(result.isLimited).toBe(true);
65
+ expect(result.nextResetAt).toEqual(fiveHourReset); // Earlier reset
66
+ });
67
+ it('should return not limited when under thresholds', async () => {
68
+ vi.mocked(getUsage).mockResolvedValue({
69
+ fiveHourPercent: 50,
70
+ weeklyPercent: 75,
71
+ fiveHourResetsAt: null,
72
+ weeklyResetsAt: null,
73
+ });
74
+ const result = await checkRateLimitStatus();
75
+ expect(result).not.toBeNull();
76
+ expect(result.fiveHourLimited).toBe(false);
77
+ expect(result.weeklyLimited).toBe(false);
78
+ expect(result.isLimited).toBe(false);
79
+ expect(result.nextResetAt).toBeNull();
80
+ expect(result.timeUntilResetMs).toBeNull();
81
+ });
82
+ it('should handle API errors gracefully', async () => {
83
+ vi.mocked(getUsage).mockRejectedValue(new Error('API error'));
84
+ const result = await checkRateLimitStatus();
85
+ expect(result).toBeNull();
86
+ });
87
+ });
88
+ describe('formatTimeUntilReset', () => {
89
+ it('should format hours and minutes', () => {
90
+ const twoHours = 2 * 60 * 60 * 1000 + 30 * 60 * 1000; // 2h 30m
91
+ expect(formatTimeUntilReset(twoHours)).toBe('2h 30m');
92
+ });
93
+ it('should format minutes and seconds', () => {
94
+ const fiveMinutes = 5 * 60 * 1000 + 45 * 1000; // 5m 45s
95
+ expect(formatTimeUntilReset(fiveMinutes)).toBe('5m 45s');
96
+ });
97
+ it('should format seconds only', () => {
98
+ const thirtySeconds = 30 * 1000;
99
+ expect(formatTimeUntilReset(thirtySeconds)).toBe('30s');
100
+ });
101
+ it('should return "now" for zero or negative', () => {
102
+ expect(formatTimeUntilReset(0)).toBe('now');
103
+ expect(formatTimeUntilReset(-1000)).toBe('now');
104
+ });
105
+ });
106
+ describe('formatRateLimitStatus', () => {
107
+ it('should format not limited status', () => {
108
+ const status = {
109
+ fiveHourLimited: false,
110
+ weeklyLimited: false,
111
+ isLimited: false,
112
+ fiveHourResetsAt: null,
113
+ weeklyResetsAt: null,
114
+ nextResetAt: null,
115
+ timeUntilResetMs: null,
116
+ lastCheckedAt: new Date(),
117
+ };
118
+ expect(formatRateLimitStatus(status)).toBe('Not rate limited');
119
+ });
120
+ it('should format 5-hour limit', () => {
121
+ const status = {
122
+ fiveHourLimited: true,
123
+ weeklyLimited: false,
124
+ isLimited: true,
125
+ fiveHourResetsAt: new Date(),
126
+ weeklyResetsAt: null,
127
+ nextResetAt: new Date(),
128
+ timeUntilResetMs: 3600000, // 1 hour
129
+ lastCheckedAt: new Date(),
130
+ };
131
+ const result = formatRateLimitStatus(status);
132
+ expect(result).toContain('5-hour limit reached');
133
+ expect(result).toContain('1h 0m');
134
+ });
135
+ it('should format weekly limit', () => {
136
+ const status = {
137
+ fiveHourLimited: false,
138
+ weeklyLimited: true,
139
+ isLimited: true,
140
+ fiveHourResetsAt: null,
141
+ weeklyResetsAt: new Date(),
142
+ nextResetAt: new Date(),
143
+ timeUntilResetMs: 86400000, // 1 day
144
+ lastCheckedAt: new Date(),
145
+ };
146
+ const result = formatRateLimitStatus(status);
147
+ expect(result).toContain('Weekly limit reached');
148
+ expect(result).toContain('24h 0m');
149
+ });
150
+ it('should format both limits', () => {
151
+ const status = {
152
+ fiveHourLimited: true,
153
+ weeklyLimited: true,
154
+ isLimited: true,
155
+ fiveHourResetsAt: new Date(),
156
+ weeklyResetsAt: new Date(),
157
+ nextResetAt: new Date(),
158
+ timeUntilResetMs: 3600000,
159
+ lastCheckedAt: new Date(),
160
+ };
161
+ const result = formatRateLimitStatus(status);
162
+ expect(result).toContain('5-hour limit reached');
163
+ expect(result).toContain('Weekly limit reached');
164
+ });
165
+ });
166
+ });
167
+ //# sourceMappingURL=rate-limit-monitor.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit-monitor.test.js","sourceRoot":"","sources":["../../../src/__tests__/rate-limit-wait/rate-limit-monitor.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tests for tmux-detector.ts
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=tmux-detector.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tmux-detector.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/rate-limit-wait/tmux-detector.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}