oh-my-claude-sisyphus 3.6.3 → 3.7.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 (119) hide show
  1. package/README.md +16 -0
  2. package/dist/__tests__/delegation-enforcement-levels.test.d.ts +9 -0
  3. package/dist/__tests__/delegation-enforcement-levels.test.d.ts.map +1 -0
  4. package/dist/__tests__/delegation-enforcement-levels.test.js +550 -0
  5. package/dist/__tests__/delegation-enforcement-levels.test.js.map +1 -0
  6. package/dist/__tests__/installer.test.js +1 -1
  7. package/dist/__tests__/rate-limit-wait/daemon.test.d.ts +5 -0
  8. package/dist/__tests__/rate-limit-wait/daemon.test.d.ts.map +1 -0
  9. package/dist/__tests__/rate-limit-wait/daemon.test.js +313 -0
  10. package/dist/__tests__/rate-limit-wait/daemon.test.js.map +1 -0
  11. package/dist/__tests__/rate-limit-wait/integration.test.d.ts +8 -0
  12. package/dist/__tests__/rate-limit-wait/integration.test.d.ts.map +1 -0
  13. package/dist/__tests__/rate-limit-wait/integration.test.js +329 -0
  14. package/dist/__tests__/rate-limit-wait/integration.test.js.map +1 -0
  15. package/dist/__tests__/rate-limit-wait/rate-limit-monitor.test.d.ts +5 -0
  16. package/dist/__tests__/rate-limit-wait/rate-limit-monitor.test.d.ts.map +1 -0
  17. package/dist/__tests__/rate-limit-wait/rate-limit-monitor.test.js +167 -0
  18. package/dist/__tests__/rate-limit-wait/rate-limit-monitor.test.js.map +1 -0
  19. package/dist/__tests__/rate-limit-wait/tmux-detector.test.d.ts +5 -0
  20. package/dist/__tests__/rate-limit-wait/tmux-detector.test.d.ts.map +1 -0
  21. package/dist/__tests__/rate-limit-wait/tmux-detector.test.js +295 -0
  22. package/dist/__tests__/rate-limit-wait/tmux-detector.test.js.map +1 -0
  23. package/dist/cli/commands/wait.d.ts +52 -0
  24. package/dist/cli/commands/wait.d.ts.map +1 -0
  25. package/dist/cli/commands/wait.js +229 -0
  26. package/dist/cli/commands/wait.js.map +1 -0
  27. package/dist/cli/index.js +54 -0
  28. package/dist/cli/index.js.map +1 -1
  29. package/dist/features/rate-limit-wait/daemon.d.ts +52 -0
  30. package/dist/features/rate-limit-wait/daemon.d.ts.map +1 -0
  31. package/dist/features/rate-limit-wait/daemon.js +545 -0
  32. package/dist/features/rate-limit-wait/daemon.js.map +1 -0
  33. package/dist/features/rate-limit-wait/index.d.ts +16 -0
  34. package/dist/features/rate-limit-wait/index.d.ts.map +1 -0
  35. package/dist/features/rate-limit-wait/index.js +18 -0
  36. package/dist/features/rate-limit-wait/index.js.map +1 -0
  37. package/dist/features/rate-limit-wait/rate-limit-monitor.d.ts +22 -0
  38. package/dist/features/rate-limit-wait/rate-limit-monitor.d.ts.map +1 -0
  39. package/dist/features/rate-limit-wait/rate-limit-monitor.js +99 -0
  40. package/dist/features/rate-limit-wait/rate-limit-monitor.js.map +1 -0
  41. package/dist/features/rate-limit-wait/tmux-detector.d.ts +59 -0
  42. package/dist/features/rate-limit-wait/tmux-detector.d.ts.map +1 -0
  43. package/dist/features/rate-limit-wait/tmux-detector.js +304 -0
  44. package/dist/features/rate-limit-wait/tmux-detector.js.map +1 -0
  45. package/dist/features/rate-limit-wait/types.d.ts +121 -0
  46. package/dist/features/rate-limit-wait/types.d.ts.map +1 -0
  47. package/dist/features/rate-limit-wait/types.js +8 -0
  48. package/dist/features/rate-limit-wait/types.js.map +1 -0
  49. package/dist/hooks/bridge.d.ts +1 -1
  50. package/dist/hooks/bridge.d.ts.map +1 -1
  51. package/dist/hooks/bridge.js +50 -4
  52. package/dist/hooks/bridge.js.map +1 -1
  53. package/dist/hooks/index.d.ts +5 -0
  54. package/dist/hooks/index.d.ts.map +1 -1
  55. package/dist/hooks/index.js +15 -0
  56. package/dist/hooks/index.js.map +1 -1
  57. package/dist/hooks/omc-orchestrator/audit.d.ts +2 -1
  58. package/dist/hooks/omc-orchestrator/audit.d.ts.map +1 -1
  59. package/dist/hooks/omc-orchestrator/audit.js.map +1 -1
  60. package/dist/hooks/omc-orchestrator/index.d.ts +7 -0
  61. package/dist/hooks/omc-orchestrator/index.d.ts.map +1 -1
  62. package/dist/hooks/omc-orchestrator/index.js +95 -8
  63. package/dist/hooks/omc-orchestrator/index.js.map +1 -1
  64. package/dist/hooks/permission-handler/__tests__/index.test.d.ts +2 -0
  65. package/dist/hooks/permission-handler/__tests__/index.test.d.ts.map +1 -0
  66. package/dist/hooks/permission-handler/__tests__/index.test.js +244 -0
  67. package/dist/hooks/permission-handler/__tests__/index.test.js.map +1 -0
  68. package/dist/hooks/permission-handler/index.d.ts +42 -0
  69. package/dist/hooks/permission-handler/index.d.ts.map +1 -0
  70. package/dist/hooks/permission-handler/index.js +111 -0
  71. package/dist/hooks/permission-handler/index.js.map +1 -0
  72. package/dist/hooks/pre-compact/index.d.ts +82 -0
  73. package/dist/hooks/pre-compact/index.d.ts.map +1 -0
  74. package/dist/hooks/pre-compact/index.js +265 -0
  75. package/dist/hooks/pre-compact/index.js.map +1 -0
  76. package/dist/hooks/session-end/index.d.ts +50 -0
  77. package/dist/hooks/session-end/index.d.ts.map +1 -0
  78. package/dist/hooks/session-end/index.js +207 -0
  79. package/dist/hooks/session-end/index.js.map +1 -0
  80. package/dist/hooks/setup/index.d.ts +66 -0
  81. package/dist/hooks/setup/index.d.ts.map +1 -0
  82. package/dist/hooks/setup/index.js +299 -0
  83. package/dist/hooks/setup/index.js.map +1 -0
  84. package/dist/hooks/setup/types.d.ts +25 -0
  85. package/dist/hooks/setup/types.d.ts.map +1 -0
  86. package/dist/hooks/setup/types.js +5 -0
  87. package/dist/hooks/setup/types.js.map +1 -0
  88. package/dist/hooks/subagent-tracker/index.d.ts +68 -29
  89. package/dist/hooks/subagent-tracker/index.d.ts.map +1 -1
  90. package/dist/hooks/subagent-tracker/index.js +301 -131
  91. package/dist/hooks/subagent-tracker/index.js.map +1 -1
  92. package/dist/installer/index.d.ts +1 -1
  93. package/dist/installer/index.js +1 -1
  94. package/hooks/hooks.json +83 -1
  95. package/package.json +3 -1
  96. package/scripts/permission-handler.mjs +23 -0
  97. package/scripts/pre-compact.mjs +23 -0
  98. package/scripts/session-end.mjs +23 -0
  99. package/scripts/setup-init.mjs +23 -0
  100. package/scripts/setup-maintenance.mjs +23 -0
  101. package/scripts/subagent-tracker.mjs +35 -0
  102. package/templates/hooks/keyword-detector.mjs +198 -0
  103. package/templates/hooks/keyword-detector.sh +102 -0
  104. package/templates/hooks/persistent-mode.mjs +249 -0
  105. package/templates/hooks/persistent-mode.sh +187 -0
  106. package/templates/hooks/post-tool-use.mjs +133 -0
  107. package/templates/hooks/post-tool-use.sh +90 -0
  108. package/templates/hooks/pre-tool-use.mjs +145 -0
  109. package/templates/hooks/pre-tool-use.sh +113 -0
  110. package/templates/hooks/session-start.mjs +100 -0
  111. package/templates/hooks/session-start.sh +62 -0
  112. package/templates/hooks/stop-continuation.mjs +80 -0
  113. package/templates/hooks/stop-continuation.sh +40 -0
  114. package/templates/rules/README.md +40 -0
  115. package/templates/rules/coding-style.md +74 -0
  116. package/templates/rules/git-workflow.md +41 -0
  117. package/templates/rules/performance.md +40 -0
  118. package/templates/rules/security.md +41 -0
  119. package/templates/rules/testing.md +42 -0
@@ -0,0 +1,545 @@
1
+ /**
2
+ * Rate Limit Wait Daemon
3
+ *
4
+ * Background daemon that monitors rate limits and auto-resumes
5
+ * Claude Code sessions when rate limits reset.
6
+ *
7
+ * Security considerations:
8
+ * - State/PID/log files use restrictive permissions (0600)
9
+ * - No sensitive data (tokens, credentials) is logged or stored
10
+ * - Input validation for tmux pane IDs
11
+ *
12
+ * Reference: https://github.com/EvanOman/cc-wait
13
+ */
14
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, chmodSync, statSync } from 'fs';
15
+ import { join, dirname } from 'path';
16
+ import { homedir } from 'os';
17
+ import { spawn } from 'child_process';
18
+ import { checkRateLimitStatus, formatRateLimitStatus } from './rate-limit-monitor.js';
19
+ import { isTmuxAvailable, scanForBlockedPanes, sendResumeSequence, formatBlockedPanesSummary, } from './tmux-detector.js';
20
+ /** Default configuration */
21
+ const DEFAULT_CONFIG = {
22
+ pollIntervalMs: 60 * 1000, // 1 minute
23
+ paneLinesToCapture: 15,
24
+ verbose: false,
25
+ stateFilePath: join(homedir(), '.omc', 'state', 'rate-limit-daemon.json'),
26
+ pidFilePath: join(homedir(), '.omc', 'state', 'rate-limit-daemon.pid'),
27
+ logFilePath: join(homedir(), '.omc', 'state', 'rate-limit-daemon.log'),
28
+ };
29
+ /** Maximum log file size before rotation (1MB) */
30
+ const MAX_LOG_SIZE_BYTES = 1 * 1024 * 1024;
31
+ /** Restrictive file permissions (owner read/write only) */
32
+ const SECURE_FILE_MODE = 0o600;
33
+ /**
34
+ * Get effective configuration by merging with defaults
35
+ */
36
+ function getConfig(config) {
37
+ return { ...DEFAULT_CONFIG, ...config };
38
+ }
39
+ /**
40
+ * Ensure state directory exists with secure permissions
41
+ */
42
+ function ensureStateDir(config) {
43
+ const stateDir = dirname(config.stateFilePath);
44
+ if (!existsSync(stateDir)) {
45
+ mkdirSync(stateDir, { recursive: true, mode: 0o700 });
46
+ }
47
+ }
48
+ /**
49
+ * Write file with secure permissions (0600 - owner read/write only)
50
+ */
51
+ function writeSecureFile(filePath, content) {
52
+ writeFileSync(filePath, content, { mode: SECURE_FILE_MODE });
53
+ // Ensure permissions are set even if file existed
54
+ try {
55
+ chmodSync(filePath, SECURE_FILE_MODE);
56
+ }
57
+ catch {
58
+ // Ignore permission errors (e.g., on Windows)
59
+ }
60
+ }
61
+ /**
62
+ * Rotate log file if it exceeds maximum size
63
+ */
64
+ function rotateLogIfNeeded(logPath) {
65
+ try {
66
+ if (!existsSync(logPath))
67
+ return;
68
+ const stats = statSync(logPath);
69
+ if (stats.size > MAX_LOG_SIZE_BYTES) {
70
+ const backupPath = `${logPath}.old`;
71
+ // Remove old backup if exists
72
+ if (existsSync(backupPath)) {
73
+ unlinkSync(backupPath);
74
+ }
75
+ // Rename current to backup
76
+ const { renameSync } = require('fs');
77
+ renameSync(logPath, backupPath);
78
+ }
79
+ }
80
+ catch {
81
+ // Ignore rotation errors
82
+ }
83
+ }
84
+ /**
85
+ * Read daemon state from disk
86
+ */
87
+ export function readDaemonState(config) {
88
+ const cfg = getConfig(config);
89
+ try {
90
+ if (!existsSync(cfg.stateFilePath)) {
91
+ return null;
92
+ }
93
+ const content = readFileSync(cfg.stateFilePath, 'utf-8');
94
+ const state = JSON.parse(content);
95
+ // Restore Date objects
96
+ if (state.startedAt)
97
+ state.startedAt = new Date(state.startedAt);
98
+ if (state.lastPollAt)
99
+ state.lastPollAt = new Date(state.lastPollAt);
100
+ if (state.rateLimitStatus?.lastCheckedAt) {
101
+ state.rateLimitStatus.lastCheckedAt = new Date(state.rateLimitStatus.lastCheckedAt);
102
+ }
103
+ if (state.rateLimitStatus?.fiveHourResetsAt) {
104
+ state.rateLimitStatus.fiveHourResetsAt = new Date(state.rateLimitStatus.fiveHourResetsAt);
105
+ }
106
+ if (state.rateLimitStatus?.weeklyResetsAt) {
107
+ state.rateLimitStatus.weeklyResetsAt = new Date(state.rateLimitStatus.weeklyResetsAt);
108
+ }
109
+ if (state.rateLimitStatus?.nextResetAt) {
110
+ state.rateLimitStatus.nextResetAt = new Date(state.rateLimitStatus.nextResetAt);
111
+ }
112
+ for (const pane of state.blockedPanes || []) {
113
+ if (pane.firstDetectedAt)
114
+ pane.firstDetectedAt = new Date(pane.firstDetectedAt);
115
+ }
116
+ return state;
117
+ }
118
+ catch {
119
+ return null;
120
+ }
121
+ }
122
+ /**
123
+ * Write daemon state to disk with secure permissions
124
+ * Note: State file contains only non-sensitive operational data
125
+ */
126
+ function writeDaemonState(state, config) {
127
+ ensureStateDir(config);
128
+ writeSecureFile(config.stateFilePath, JSON.stringify(state, null, 2));
129
+ }
130
+ /**
131
+ * Read PID file
132
+ */
133
+ function readPidFile(config) {
134
+ try {
135
+ if (!existsSync(config.pidFilePath)) {
136
+ return null;
137
+ }
138
+ const content = readFileSync(config.pidFilePath, 'utf-8');
139
+ return parseInt(content.trim(), 10);
140
+ }
141
+ catch {
142
+ return null;
143
+ }
144
+ }
145
+ /**
146
+ * Write PID file with secure permissions
147
+ */
148
+ function writePidFile(pid, config) {
149
+ ensureStateDir(config);
150
+ writeSecureFile(config.pidFilePath, String(pid));
151
+ }
152
+ /**
153
+ * Remove PID file
154
+ */
155
+ function removePidFile(config) {
156
+ if (existsSync(config.pidFilePath)) {
157
+ unlinkSync(config.pidFilePath);
158
+ }
159
+ }
160
+ /**
161
+ * Check if a process is running
162
+ */
163
+ function isProcessRunning(pid) {
164
+ try {
165
+ // Signal 0 doesn't actually send a signal, just checks if process exists
166
+ process.kill(pid, 0);
167
+ return true;
168
+ }
169
+ catch {
170
+ return false;
171
+ }
172
+ }
173
+ /**
174
+ * Check if daemon is currently running
175
+ */
176
+ export function isDaemonRunning(config) {
177
+ const cfg = getConfig(config);
178
+ const pid = readPidFile(cfg);
179
+ if (pid === null) {
180
+ return false;
181
+ }
182
+ if (!isProcessRunning(pid)) {
183
+ // Stale PID file, clean up
184
+ removePidFile(cfg);
185
+ return false;
186
+ }
187
+ return true;
188
+ }
189
+ /**
190
+ * Log message to daemon log file with rotation
191
+ * Note: Only operational messages are logged, never credentials or tokens
192
+ */
193
+ function log(message, config) {
194
+ if (config.verbose) {
195
+ console.log(`[${new Date().toISOString()}] ${message}`);
196
+ }
197
+ try {
198
+ ensureStateDir(config);
199
+ // Rotate log if needed (prevents unbounded growth)
200
+ rotateLogIfNeeded(config.logFilePath);
201
+ const timestamp = new Date().toISOString();
202
+ const logLine = `[${timestamp}] ${message}\n`;
203
+ // Append to log file with secure permissions
204
+ const { appendFileSync } = require('fs');
205
+ appendFileSync(config.logFilePath, logLine, { mode: SECURE_FILE_MODE });
206
+ }
207
+ catch {
208
+ // Ignore log write errors
209
+ }
210
+ }
211
+ /**
212
+ * Create initial daemon state
213
+ */
214
+ function createInitialState() {
215
+ return {
216
+ isRunning: true,
217
+ pid: process.pid,
218
+ startedAt: new Date(),
219
+ lastPollAt: null,
220
+ rateLimitStatus: null,
221
+ blockedPanes: [],
222
+ resumedPaneIds: [],
223
+ totalResumeAttempts: 0,
224
+ successfulResumes: 0,
225
+ errorCount: 0,
226
+ };
227
+ }
228
+ /**
229
+ * Main daemon polling loop
230
+ */
231
+ async function pollLoop(config) {
232
+ const state = readDaemonState(config) || createInitialState();
233
+ state.isRunning = true;
234
+ state.pid = process.pid;
235
+ log('Starting poll loop', config);
236
+ while (state.isRunning) {
237
+ try {
238
+ state.lastPollAt = new Date();
239
+ // Check rate limit status
240
+ const rateLimitStatus = await checkRateLimitStatus();
241
+ const wasLimited = state.rateLimitStatus?.isLimited ?? false;
242
+ const isNowLimited = rateLimitStatus?.isLimited ?? false;
243
+ state.rateLimitStatus = rateLimitStatus;
244
+ if (rateLimitStatus) {
245
+ log(`Rate limit status: ${formatRateLimitStatus(rateLimitStatus)}`, config);
246
+ }
247
+ else {
248
+ log('Rate limit status unavailable (no OAuth credentials?)', config);
249
+ }
250
+ // If currently rate limited, scan for blocked panes
251
+ if (isNowLimited && isTmuxAvailable()) {
252
+ log('Rate limited - scanning for blocked panes', config);
253
+ const blockedPanes = scanForBlockedPanes(config.paneLinesToCapture);
254
+ // Add newly detected blocked panes
255
+ for (const pane of blockedPanes) {
256
+ const existing = state.blockedPanes.find((p) => p.id === pane.id);
257
+ if (!existing) {
258
+ state.blockedPanes.push(pane);
259
+ log(`Detected blocked pane: ${pane.id} in ${pane.session}:${pane.windowIndex}`, config);
260
+ }
261
+ }
262
+ // Remove panes that are no longer blocked
263
+ state.blockedPanes = state.blockedPanes.filter((tracked) => blockedPanes.some((current) => current.id === tracked.id));
264
+ }
265
+ // If rate limit just cleared (was limited, now not), attempt resume
266
+ if (wasLimited && !isNowLimited && state.blockedPanes.length > 0) {
267
+ log('Rate limit cleared! Attempting to resume blocked panes', config);
268
+ for (const pane of state.blockedPanes) {
269
+ if (state.resumedPaneIds.includes(pane.id)) {
270
+ log(`Skipping already resumed pane: ${pane.id}`, config);
271
+ continue;
272
+ }
273
+ state.totalResumeAttempts++;
274
+ log(`Attempting resume for pane: ${pane.id}`, config);
275
+ const success = sendResumeSequence(pane.id);
276
+ pane.resumeAttempted = true;
277
+ pane.resumeSuccessful = success;
278
+ if (success) {
279
+ state.successfulResumes++;
280
+ state.resumedPaneIds.push(pane.id);
281
+ log(`Successfully sent resume to pane: ${pane.id}`, config);
282
+ }
283
+ else {
284
+ state.errorCount++;
285
+ log(`Failed to send resume to pane: ${pane.id}`, config);
286
+ }
287
+ }
288
+ // Clear blocked panes after resume attempt
289
+ state.blockedPanes = [];
290
+ }
291
+ // If rate limit cleared and no blocked panes, clear resumed list
292
+ if (!isNowLimited && state.blockedPanes.length === 0) {
293
+ state.resumedPaneIds = [];
294
+ }
295
+ writeDaemonState(state, config);
296
+ }
297
+ catch (error) {
298
+ state.errorCount++;
299
+ state.lastError = error instanceof Error ? error.message : String(error);
300
+ log(`Poll error: ${state.lastError}`, config);
301
+ writeDaemonState(state, config);
302
+ }
303
+ // Wait for next poll
304
+ await new Promise((resolve) => setTimeout(resolve, config.pollIntervalMs));
305
+ }
306
+ }
307
+ /**
308
+ * Start the daemon
309
+ */
310
+ export function startDaemon(config) {
311
+ const cfg = getConfig(config);
312
+ // Check if already running
313
+ if (isDaemonRunning(cfg)) {
314
+ const state = readDaemonState(cfg);
315
+ return {
316
+ success: false,
317
+ message: 'Daemon is already running',
318
+ state: state ?? undefined,
319
+ };
320
+ }
321
+ // Check for tmux
322
+ if (!isTmuxAvailable()) {
323
+ console.warn('[RateLimitDaemon] tmux not available - resume functionality will be limited');
324
+ }
325
+ ensureStateDir(cfg);
326
+ // Fork a new process for the daemon
327
+ const daemonScript = `
328
+ const { pollLoop } = require('${__filename.replace(/\.ts$/, '.js')}');
329
+ const config = ${JSON.stringify(cfg)};
330
+ pollLoop(config).catch(console.error);
331
+ `;
332
+ try {
333
+ // Use node to run the daemon in background
334
+ const child = spawn('node', ['-e', daemonScript], {
335
+ detached: true,
336
+ stdio: 'ignore',
337
+ cwd: process.cwd(),
338
+ env: process.env,
339
+ });
340
+ child.unref();
341
+ const pid = child.pid;
342
+ if (pid) {
343
+ writePidFile(pid, cfg);
344
+ const state = createInitialState();
345
+ state.pid = pid;
346
+ writeDaemonState(state, cfg);
347
+ return {
348
+ success: true,
349
+ message: `Daemon started with PID ${pid}`,
350
+ state,
351
+ };
352
+ }
353
+ return {
354
+ success: false,
355
+ message: 'Failed to start daemon process',
356
+ };
357
+ }
358
+ catch (error) {
359
+ return {
360
+ success: false,
361
+ message: 'Failed to start daemon',
362
+ error: error instanceof Error ? error.message : String(error),
363
+ };
364
+ }
365
+ }
366
+ /**
367
+ * Run daemon in foreground (for direct execution)
368
+ */
369
+ export async function runDaemonForeground(config) {
370
+ const cfg = getConfig(config);
371
+ // Check if already running
372
+ if (isDaemonRunning(cfg)) {
373
+ console.error('Daemon is already running. Use "omc wait daemon stop" first.');
374
+ process.exit(1);
375
+ }
376
+ // Write PID file
377
+ writePidFile(process.pid, cfg);
378
+ // Handle shutdown
379
+ const shutdown = () => {
380
+ console.log('\nShutting down daemon...');
381
+ removePidFile(cfg);
382
+ const state = readDaemonState(cfg);
383
+ if (state) {
384
+ state.isRunning = false;
385
+ writeDaemonState(state, cfg);
386
+ }
387
+ process.exit(0);
388
+ };
389
+ process.on('SIGINT', shutdown);
390
+ process.on('SIGTERM', shutdown);
391
+ console.log('Rate Limit Wait daemon starting in foreground mode...');
392
+ console.log('Press Ctrl+C to stop.\n');
393
+ // Run poll loop
394
+ await pollLoop(cfg);
395
+ }
396
+ /**
397
+ * Stop the daemon
398
+ */
399
+ export function stopDaemon(config) {
400
+ const cfg = getConfig(config);
401
+ const pid = readPidFile(cfg);
402
+ if (pid === null) {
403
+ return {
404
+ success: true,
405
+ message: 'Daemon is not running',
406
+ };
407
+ }
408
+ if (!isProcessRunning(pid)) {
409
+ removePidFile(cfg);
410
+ return {
411
+ success: true,
412
+ message: 'Daemon was not running (cleaned up stale PID file)',
413
+ };
414
+ }
415
+ try {
416
+ process.kill(pid, 'SIGTERM');
417
+ removePidFile(cfg);
418
+ // Update state
419
+ const state = readDaemonState(cfg);
420
+ if (state) {
421
+ state.isRunning = false;
422
+ state.pid = null;
423
+ writeDaemonState(state, cfg);
424
+ }
425
+ return {
426
+ success: true,
427
+ message: `Daemon stopped (PID ${pid})`,
428
+ state: state ?? undefined,
429
+ };
430
+ }
431
+ catch (error) {
432
+ return {
433
+ success: false,
434
+ message: 'Failed to stop daemon',
435
+ error: error instanceof Error ? error.message : String(error),
436
+ };
437
+ }
438
+ }
439
+ /**
440
+ * Get daemon status
441
+ */
442
+ export function getDaemonStatus(config) {
443
+ const cfg = getConfig(config);
444
+ const state = readDaemonState(cfg);
445
+ const running = isDaemonRunning(cfg);
446
+ if (!running && !state) {
447
+ return {
448
+ success: true,
449
+ message: 'Daemon has never been started',
450
+ };
451
+ }
452
+ if (!running && state) {
453
+ return {
454
+ success: true,
455
+ message: 'Daemon is not running',
456
+ state: { ...state, isRunning: false, pid: null },
457
+ };
458
+ }
459
+ return {
460
+ success: true,
461
+ message: 'Daemon is running',
462
+ state: state ?? undefined,
463
+ };
464
+ }
465
+ /**
466
+ * Detect blocked panes (one-time scan)
467
+ */
468
+ export async function detectBlockedPanes(config) {
469
+ const cfg = getConfig(config);
470
+ if (!isTmuxAvailable()) {
471
+ return {
472
+ success: false,
473
+ message: 'tmux is not available',
474
+ };
475
+ }
476
+ const rateLimitStatus = await checkRateLimitStatus();
477
+ const blockedPanes = scanForBlockedPanes(cfg.paneLinesToCapture);
478
+ return {
479
+ success: true,
480
+ message: formatBlockedPanesSummary(blockedPanes),
481
+ state: {
482
+ isRunning: isDaemonRunning(cfg),
483
+ pid: readPidFile(cfg),
484
+ startedAt: null,
485
+ lastPollAt: new Date(),
486
+ rateLimitStatus,
487
+ blockedPanes,
488
+ resumedPaneIds: [],
489
+ totalResumeAttempts: 0,
490
+ successfulResumes: 0,
491
+ errorCount: 0,
492
+ },
493
+ };
494
+ }
495
+ /**
496
+ * Format daemon state for CLI display
497
+ */
498
+ export function formatDaemonState(state) {
499
+ const lines = [];
500
+ // Status header
501
+ if (state.isRunning) {
502
+ lines.push(`✓ Daemon running (PID: ${state.pid})`);
503
+ }
504
+ else {
505
+ lines.push('✗ Daemon not running');
506
+ }
507
+ // Timing info
508
+ if (state.startedAt) {
509
+ lines.push(` Started: ${state.startedAt.toLocaleString()}`);
510
+ }
511
+ if (state.lastPollAt) {
512
+ lines.push(` Last poll: ${state.lastPollAt.toLocaleString()}`);
513
+ }
514
+ // Rate limit status
515
+ lines.push('');
516
+ if (state.rateLimitStatus) {
517
+ if (state.rateLimitStatus.isLimited) {
518
+ lines.push(`⚠ ${formatRateLimitStatus(state.rateLimitStatus)}`);
519
+ }
520
+ else {
521
+ lines.push('✓ Not rate limited');
522
+ }
523
+ }
524
+ else {
525
+ lines.push('? Rate limit status unavailable');
526
+ }
527
+ // Blocked panes
528
+ if (state.blockedPanes.length > 0) {
529
+ lines.push('');
530
+ lines.push(formatBlockedPanesSummary(state.blockedPanes));
531
+ }
532
+ // Statistics
533
+ lines.push('');
534
+ lines.push('Statistics:');
535
+ lines.push(` Resume attempts: ${state.totalResumeAttempts}`);
536
+ lines.push(` Successful: ${state.successfulResumes}`);
537
+ lines.push(` Errors: ${state.errorCount}`);
538
+ if (state.lastError) {
539
+ lines.push(` Last error: ${state.lastError}`);
540
+ }
541
+ return lines.join('\n');
542
+ }
543
+ // Export pollLoop for use by the daemon subprocess
544
+ export { pollLoop };
545
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../../src/features/rate-limit-wait/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Rate Limit Wait Feature
3
+ *
4
+ * Auto-resume Claude Code sessions when rate limits reset.
5
+ *
6
+ * Usage:
7
+ * omc wait status - Show current rate limit status
8
+ * omc wait daemon start - Start the background daemon
9
+ * omc wait daemon stop - Stop the daemon
10
+ * omc wait detect - Scan for blocked Claude Code sessions
11
+ */
12
+ export type { RateLimitStatus, TmuxPane, PaneAnalysisResult, BlockedPane, DaemonState, DaemonConfig, ResumeResult, DaemonCommand, DaemonResponse, } from './types.js';
13
+ export { checkRateLimitStatus, formatTimeUntilReset, formatRateLimitStatus, } from './rate-limit-monitor.js';
14
+ export { isTmuxAvailable, isInsideTmux, listTmuxPanes, capturePaneContent, analyzePaneContent, scanForBlockedPanes, sendResumeSequence, sendToPane, formatBlockedPanesSummary, } from './tmux-detector.js';
15
+ export { readDaemonState, isDaemonRunning, startDaemon, runDaemonForeground, stopDaemon, getDaemonStatus, detectBlockedPanes, formatDaemonState, } from './daemon.js';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/features/rate-limit-wait/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,YAAY,EACV,eAAe,EACf,QAAQ,EACR,kBAAkB,EAClB,WAAW,EACX,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,cAAc,GACf,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACL,eAAe,EACf,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,EACV,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,eAAe,EACf,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,aAAa,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Rate Limit Wait Feature
3
+ *
4
+ * Auto-resume Claude Code sessions when rate limits reset.
5
+ *
6
+ * Usage:
7
+ * omc wait status - Show current rate limit status
8
+ * omc wait daemon start - Start the background daemon
9
+ * omc wait daemon stop - Stop the daemon
10
+ * omc wait detect - Scan for blocked Claude Code sessions
11
+ */
12
+ // Rate limit monitor exports
13
+ export { checkRateLimitStatus, formatTimeUntilReset, formatRateLimitStatus, } from './rate-limit-monitor.js';
14
+ // tmux detector exports
15
+ export { isTmuxAvailable, isInsideTmux, listTmuxPanes, capturePaneContent, analyzePaneContent, scanForBlockedPanes, sendResumeSequence, sendToPane, formatBlockedPanesSummary, } from './tmux-detector.js';
16
+ // Daemon exports
17
+ export { readDaemonState, isDaemonRunning, startDaemon, runDaemonForeground, stopDaemon, getDaemonStatus, detectBlockedPanes, formatDaemonState, } from './daemon.js';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/features/rate-limit-wait/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAeH,6BAA6B;AAC7B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,yBAAyB,CAAC;AAEjC,wBAAwB;AACxB,OAAO,EACL,eAAe,EACf,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,EACV,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAE5B,iBAAiB;AACjB,OAAO,EACL,eAAe,EACf,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,aAAa,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Rate Limit Monitor
3
+ *
4
+ * Wraps the existing usage-api.ts to provide rate limit status monitoring.
5
+ * Uses the OAuth API to check utilization percentages.
6
+ */
7
+ import type { RateLimitStatus } from './types.js';
8
+ /**
9
+ * Check current rate limit status using the OAuth API
10
+ *
11
+ * @returns Rate limit status or null if API unavailable
12
+ */
13
+ export declare function checkRateLimitStatus(): Promise<RateLimitStatus | null>;
14
+ /**
15
+ * Format time until reset for display
16
+ */
17
+ export declare function formatTimeUntilReset(ms: number): string;
18
+ /**
19
+ * Get a human-readable rate limit status message
20
+ */
21
+ export declare function formatRateLimitStatus(status: RateLimitStatus): string;
22
+ //# sourceMappingURL=rate-limit-monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit-monitor.d.ts","sourceRoot":"","sources":["../../../src/features/rate-limit-wait/rate-limit-monitor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAKlD;;;;GAIG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAoD5E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAevD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAqBrE"}