aicodeman 0.2.8

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 (246) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +403 -0
  3. package/dist/ai-checker-base.d.ts +175 -0
  4. package/dist/ai-checker-base.d.ts.map +1 -0
  5. package/dist/ai-checker-base.js +424 -0
  6. package/dist/ai-checker-base.js.map +1 -0
  7. package/dist/ai-idle-checker.d.ts +53 -0
  8. package/dist/ai-idle-checker.d.ts.map +1 -0
  9. package/dist/ai-idle-checker.js +141 -0
  10. package/dist/ai-idle-checker.js.map +1 -0
  11. package/dist/ai-plan-checker.d.ts +52 -0
  12. package/dist/ai-plan-checker.d.ts.map +1 -0
  13. package/dist/ai-plan-checker.js +103 -0
  14. package/dist/ai-plan-checker.js.map +1 -0
  15. package/dist/bash-tool-parser.d.ts +191 -0
  16. package/dist/bash-tool-parser.d.ts.map +1 -0
  17. package/dist/bash-tool-parser.js +598 -0
  18. package/dist/bash-tool-parser.js.map +1 -0
  19. package/dist/cli.d.ts +12 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +460 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/config/buffer-limits.d.ts +59 -0
  24. package/dist/config/buffer-limits.d.ts.map +1 -0
  25. package/dist/config/buffer-limits.js +74 -0
  26. package/dist/config/buffer-limits.js.map +1 -0
  27. package/dist/config/map-limits.d.ts +40 -0
  28. package/dist/config/map-limits.d.ts.map +1 -0
  29. package/dist/config/map-limits.js +52 -0
  30. package/dist/config/map-limits.js.map +1 -0
  31. package/dist/file-stream-manager.d.ts +148 -0
  32. package/dist/file-stream-manager.d.ts.map +1 -0
  33. package/dist/file-stream-manager.js +351 -0
  34. package/dist/file-stream-manager.js.map +1 -0
  35. package/dist/hooks-config.d.ts +31 -0
  36. package/dist/hooks-config.d.ts.map +1 -0
  37. package/dist/hooks-config.js +115 -0
  38. package/dist/hooks-config.js.map +1 -0
  39. package/dist/image-watcher.d.ts +86 -0
  40. package/dist/image-watcher.d.ts.map +1 -0
  41. package/dist/image-watcher.js +275 -0
  42. package/dist/image-watcher.js.map +1 -0
  43. package/dist/index.d.ts +11 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +54 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/mux-factory.d.ts +13 -0
  48. package/dist/mux-factory.d.ts.map +1 -0
  49. package/dist/mux-factory.js +19 -0
  50. package/dist/mux-factory.js.map +1 -0
  51. package/dist/mux-interface.d.ts +145 -0
  52. package/dist/mux-interface.d.ts.map +1 -0
  53. package/dist/mux-interface.js +9 -0
  54. package/dist/mux-interface.js.map +1 -0
  55. package/dist/plan-orchestrator.d.ts +123 -0
  56. package/dist/plan-orchestrator.d.ts.map +1 -0
  57. package/dist/plan-orchestrator.js +500 -0
  58. package/dist/plan-orchestrator.js.map +1 -0
  59. package/dist/prompts/index.d.ts +9 -0
  60. package/dist/prompts/index.d.ts.map +1 -0
  61. package/dist/prompts/index.js +9 -0
  62. package/dist/prompts/index.js.map +1 -0
  63. package/dist/prompts/planner.d.ts +14 -0
  64. package/dist/prompts/planner.d.ts.map +1 -0
  65. package/dist/prompts/planner.js +83 -0
  66. package/dist/prompts/planner.js.map +1 -0
  67. package/dist/prompts/research-agent.d.ts +10 -0
  68. package/dist/prompts/research-agent.d.ts.map +1 -0
  69. package/dist/prompts/research-agent.js +143 -0
  70. package/dist/prompts/research-agent.js.map +1 -0
  71. package/dist/push-store.d.ts +41 -0
  72. package/dist/push-store.d.ts.map +1 -0
  73. package/dist/push-store.js +168 -0
  74. package/dist/push-store.js.map +1 -0
  75. package/dist/ralph-config.d.ts +67 -0
  76. package/dist/ralph-config.d.ts.map +1 -0
  77. package/dist/ralph-config.js +134 -0
  78. package/dist/ralph-config.js.map +1 -0
  79. package/dist/ralph-loop.d.ts +124 -0
  80. package/dist/ralph-loop.d.ts.map +1 -0
  81. package/dist/ralph-loop.js +418 -0
  82. package/dist/ralph-loop.js.map +1 -0
  83. package/dist/ralph-tracker.d.ts +1081 -0
  84. package/dist/ralph-tracker.d.ts.map +1 -0
  85. package/dist/ralph-tracker.js +3343 -0
  86. package/dist/ralph-tracker.js.map +1 -0
  87. package/dist/respawn-controller.d.ts +1182 -0
  88. package/dist/respawn-controller.d.ts.map +1 -0
  89. package/dist/respawn-controller.js +2754 -0
  90. package/dist/respawn-controller.js.map +1 -0
  91. package/dist/run-summary.d.ts +123 -0
  92. package/dist/run-summary.d.ts.map +1 -0
  93. package/dist/run-summary.js +325 -0
  94. package/dist/run-summary.js.map +1 -0
  95. package/dist/session-lifecycle-log.d.ts +36 -0
  96. package/dist/session-lifecycle-log.d.ts.map +1 -0
  97. package/dist/session-lifecycle-log.js +101 -0
  98. package/dist/session-lifecycle-log.js.map +1 -0
  99. package/dist/session-manager.d.ts +97 -0
  100. package/dist/session-manager.d.ts.map +1 -0
  101. package/dist/session-manager.js +224 -0
  102. package/dist/session-manager.js.map +1 -0
  103. package/dist/session.d.ts +686 -0
  104. package/dist/session.d.ts.map +1 -0
  105. package/dist/session.js +2025 -0
  106. package/dist/session.js.map +1 -0
  107. package/dist/state-store.d.ts +189 -0
  108. package/dist/state-store.d.ts.map +1 -0
  109. package/dist/state-store.js +730 -0
  110. package/dist/state-store.js.map +1 -0
  111. package/dist/subagent-watcher.d.ts +345 -0
  112. package/dist/subagent-watcher.d.ts.map +1 -0
  113. package/dist/subagent-watcher.js +1469 -0
  114. package/dist/subagent-watcher.js.map +1 -0
  115. package/dist/task-queue.d.ts +108 -0
  116. package/dist/task-queue.d.ts.map +1 -0
  117. package/dist/task-queue.js +235 -0
  118. package/dist/task-queue.js.map +1 -0
  119. package/dist/task-tracker.d.ts +306 -0
  120. package/dist/task-tracker.d.ts.map +1 -0
  121. package/dist/task-tracker.js +488 -0
  122. package/dist/task-tracker.js.map +1 -0
  123. package/dist/task.d.ts +73 -0
  124. package/dist/task.d.ts.map +1 -0
  125. package/dist/task.js +177 -0
  126. package/dist/task.js.map +1 -0
  127. package/dist/team-watcher.d.ts +53 -0
  128. package/dist/team-watcher.d.ts.map +1 -0
  129. package/dist/team-watcher.js +313 -0
  130. package/dist/team-watcher.js.map +1 -0
  131. package/dist/templates/case-template.md +461 -0
  132. package/dist/templates/claude-md.d.ts +26 -0
  133. package/dist/templates/claude-md.d.ts.map +1 -0
  134. package/dist/templates/claude-md.js +74 -0
  135. package/dist/templates/claude-md.js.map +1 -0
  136. package/dist/tmux-manager.d.ts +181 -0
  137. package/dist/tmux-manager.d.ts.map +1 -0
  138. package/dist/tmux-manager.js +1405 -0
  139. package/dist/tmux-manager.js.map +1 -0
  140. package/dist/transcript-watcher.d.ts +110 -0
  141. package/dist/transcript-watcher.d.ts.map +1 -0
  142. package/dist/transcript-watcher.js +338 -0
  143. package/dist/transcript-watcher.js.map +1 -0
  144. package/dist/tunnel-manager.d.ts +54 -0
  145. package/dist/tunnel-manager.d.ts.map +1 -0
  146. package/dist/tunnel-manager.js +251 -0
  147. package/dist/tunnel-manager.js.map +1 -0
  148. package/dist/types.d.ts +1139 -0
  149. package/dist/types.d.ts.map +1 -0
  150. package/dist/types.js +215 -0
  151. package/dist/types.js.map +1 -0
  152. package/dist/utils/buffer-accumulator.d.ts +111 -0
  153. package/dist/utils/buffer-accumulator.d.ts.map +1 -0
  154. package/dist/utils/buffer-accumulator.js +172 -0
  155. package/dist/utils/buffer-accumulator.js.map +1 -0
  156. package/dist/utils/claude-cli-resolver.d.ts +26 -0
  157. package/dist/utils/claude-cli-resolver.d.ts.map +1 -0
  158. package/dist/utils/claude-cli-resolver.js +78 -0
  159. package/dist/utils/claude-cli-resolver.js.map +1 -0
  160. package/dist/utils/cleanup-manager.d.ts +165 -0
  161. package/dist/utils/cleanup-manager.d.ts.map +1 -0
  162. package/dist/utils/cleanup-manager.js +274 -0
  163. package/dist/utils/cleanup-manager.js.map +1 -0
  164. package/dist/utils/index.d.ts +19 -0
  165. package/dist/utils/index.d.ts.map +1 -0
  166. package/dist/utils/index.js +19 -0
  167. package/dist/utils/index.js.map +1 -0
  168. package/dist/utils/lru-map.d.ts +140 -0
  169. package/dist/utils/lru-map.d.ts.map +1 -0
  170. package/dist/utils/lru-map.js +234 -0
  171. package/dist/utils/lru-map.js.map +1 -0
  172. package/dist/utils/nice-wrapper.d.ts +13 -0
  173. package/dist/utils/nice-wrapper.d.ts.map +1 -0
  174. package/dist/utils/nice-wrapper.js +17 -0
  175. package/dist/utils/nice-wrapper.js.map +1 -0
  176. package/dist/utils/opencode-cli-resolver.d.ts +21 -0
  177. package/dist/utils/opencode-cli-resolver.d.ts.map +1 -0
  178. package/dist/utils/opencode-cli-resolver.js +67 -0
  179. package/dist/utils/opencode-cli-resolver.js.map +1 -0
  180. package/dist/utils/regex-patterns.d.ts +64 -0
  181. package/dist/utils/regex-patterns.d.ts.map +1 -0
  182. package/dist/utils/regex-patterns.js +74 -0
  183. package/dist/utils/regex-patterns.js.map +1 -0
  184. package/dist/utils/stale-expiration-map.d.ts +159 -0
  185. package/dist/utils/stale-expiration-map.d.ts.map +1 -0
  186. package/dist/utils/stale-expiration-map.js +277 -0
  187. package/dist/utils/stale-expiration-map.js.map +1 -0
  188. package/dist/utils/string-similarity.d.ts +108 -0
  189. package/dist/utils/string-similarity.d.ts.map +1 -0
  190. package/dist/utils/string-similarity.js +189 -0
  191. package/dist/utils/string-similarity.js.map +1 -0
  192. package/dist/utils/token-validation.d.ts +39 -0
  193. package/dist/utils/token-validation.d.ts.map +1 -0
  194. package/dist/utils/token-validation.js +59 -0
  195. package/dist/utils/token-validation.js.map +1 -0
  196. package/dist/utils/type-safety.d.ts +33 -0
  197. package/dist/utils/type-safety.d.ts.map +1 -0
  198. package/dist/utils/type-safety.js +35 -0
  199. package/dist/utils/type-safety.js.map +1 -0
  200. package/dist/web/public/app.js +491 -0
  201. package/dist/web/public/app.js.br +0 -0
  202. package/dist/web/public/app.js.gz +0 -0
  203. package/dist/web/public/index.html +1675 -0
  204. package/dist/web/public/index.html.br +0 -0
  205. package/dist/web/public/index.html.gz +0 -0
  206. package/dist/web/public/manifest.json +8 -0
  207. package/dist/web/public/mobile.css +1 -0
  208. package/dist/web/public/mobile.css.br +0 -0
  209. package/dist/web/public/mobile.css.gz +0 -0
  210. package/dist/web/public/ralph-wizard.js +1037 -0
  211. package/dist/web/public/ralph-wizard.js.br +0 -0
  212. package/dist/web/public/ralph-wizard.js.gz +0 -0
  213. package/dist/web/public/styles.css +1 -0
  214. package/dist/web/public/styles.css.br +0 -0
  215. package/dist/web/public/styles.css.gz +0 -0
  216. package/dist/web/public/sw.js +67 -0
  217. package/dist/web/public/sw.js.br +0 -0
  218. package/dist/web/public/sw.js.gz +0 -0
  219. package/dist/web/public/upload.html +155 -0
  220. package/dist/web/public/upload.html.br +0 -0
  221. package/dist/web/public/upload.html.gz +0 -0
  222. package/dist/web/public/vendor/xterm-addon-fit.min.js +1 -0
  223. package/dist/web/public/vendor/xterm-addon-fit.min.js.br +0 -0
  224. package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
  225. package/dist/web/public/vendor/xterm-addon-unicode11.min.js +1 -0
  226. package/dist/web/public/vendor/xterm-addon-unicode11.min.js.br +0 -0
  227. package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
  228. package/dist/web/public/vendor/xterm-addon-webgl.min.js +2 -0
  229. package/dist/web/public/vendor/xterm-addon-webgl.min.js.br +0 -0
  230. package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
  231. package/dist/web/public/vendor/xterm.css +209 -0
  232. package/dist/web/public/vendor/xterm.css.br +0 -0
  233. package/dist/web/public/vendor/xterm.css.gz +0 -0
  234. package/dist/web/public/vendor/xterm.min.js +9 -0
  235. package/dist/web/public/vendor/xterm.min.js.br +0 -0
  236. package/dist/web/public/vendor/xterm.min.js.gz +0 -0
  237. package/dist/web/schemas.d.ts +479 -0
  238. package/dist/web/schemas.d.ts.map +1 -0
  239. package/dist/web/schemas.js +448 -0
  240. package/dist/web/schemas.js.map +1 -0
  241. package/dist/web/server.d.ts +207 -0
  242. package/dist/web/server.d.ts.map +1 -0
  243. package/dist/web/server.js +5784 -0
  244. package/dist/web/server.js.map +1 -0
  245. package/package.json +110 -0
  246. package/scripts/postinstall.js +390 -0
@@ -0,0 +1,124 @@
1
+ /**
2
+ * @fileoverview Ralph Loop - Autonomous task execution engine
3
+ *
4
+ * The Ralph Loop orchestrates autonomous Claude sessions by:
5
+ * - Polling for available tasks from the task queue
6
+ * - Assigning tasks to idle sessions
7
+ * - Monitoring completion and handling failures
8
+ * - Auto-generating follow-up tasks when min duration not reached
9
+ *
10
+ * Named after Ralph Wiggum's persistence ("I'm in danger!"),
11
+ * this loop keeps Claude working until all tasks are done.
12
+ *
13
+ * @module ralph-loop
14
+ */
15
+ import { EventEmitter } from 'node:events';
16
+ import { RalphLoopStatus } from './types.js';
17
+ /**
18
+ * Events emitted by RalphLoop
19
+ */
20
+ export interface RalphLoopEvents {
21
+ started: () => void;
22
+ stopped: () => void;
23
+ taskAssigned: (taskId: string, sessionId: string) => void;
24
+ taskCompleted: (taskId: string) => void;
25
+ taskFailed: (taskId: string, error: string) => void;
26
+ error: (error: Error) => void;
27
+ }
28
+ /**
29
+ * Configuration options for RalphLoop
30
+ */
31
+ export interface RalphLoopOptions {
32
+ /** How often to check for new tasks (default from config) */
33
+ pollIntervalMs?: number;
34
+ /** Minimum time to run before stopping (null = no minimum) */
35
+ minDurationMs?: number;
36
+ /** Auto-generate follow-up tasks when queue is empty */
37
+ autoGenerateTasks?: boolean;
38
+ }
39
+ /**
40
+ * Autonomous task execution loop.
41
+ *
42
+ * @description
43
+ * Manages the lifecycle of task execution:
44
+ * 1. Start: Begin polling and task assignment
45
+ * 2. Run: Assign tasks to idle sessions, monitor completion
46
+ * 3. Stop: When all tasks done and min duration reached
47
+ *
48
+ * Supports time-aware loops that continue generating tasks
49
+ * until a minimum duration is reached.
50
+ *
51
+ * @extends EventEmitter
52
+ */
53
+ export declare class RalphLoop extends EventEmitter {
54
+ private sessionManager;
55
+ private taskQueue;
56
+ private store;
57
+ private pollIntervalMs;
58
+ private minDurationMs;
59
+ private autoGenerateTasks;
60
+ private loopTimer;
61
+ private _status;
62
+ private startedAt;
63
+ private tasksCompleted;
64
+ private tasksGenerated;
65
+ /** Bound event handlers for cleanup (prevents memory leaks) */
66
+ private sessionEventHandlers;
67
+ constructor(options?: RalphLoopOptions);
68
+ private setupEventHandlers;
69
+ /** Remove event listeners to prevent memory leaks */
70
+ private cleanupEventHandlers;
71
+ get status(): RalphLoopStatus;
72
+ isRunning(): boolean;
73
+ getElapsedMs(): number;
74
+ getElapsedHours(): number;
75
+ isMinDurationReached(): boolean;
76
+ getStats(): {
77
+ activeSessions: number;
78
+ idleSessions: number;
79
+ busySessions: number;
80
+ total: number;
81
+ pending: number;
82
+ running: number;
83
+ completed: number;
84
+ failed: number;
85
+ status: RalphLoopStatus;
86
+ elapsedMs: number;
87
+ elapsedHours: number;
88
+ minDurationMs: number | null;
89
+ minDurationReached: boolean;
90
+ tasksCompleted: number;
91
+ tasksGenerated: number;
92
+ };
93
+ /** Starts the task execution loop. */
94
+ start(): Promise<void>;
95
+ /** Stops the task execution loop. */
96
+ stop(): void;
97
+ /** Pauses the loop (can be resumed). */
98
+ pause(): void;
99
+ /** Resumes a paused loop. */
100
+ resume(): void;
101
+ private runLoop;
102
+ private tick;
103
+ private assignTasks;
104
+ private assignTaskToSession;
105
+ private checkTimeouts;
106
+ private handleSessionCompletion;
107
+ private handleSessionError;
108
+ private handleSessionStopped;
109
+ private handleSessionTaskError;
110
+ private shouldGenerateTasks;
111
+ private generateFollowUpTasks;
112
+ private shouldStop;
113
+ /** Sets the minimum duration in hours before the loop can stop. */
114
+ setMinDuration(hours: number): void;
115
+ /**
116
+ * Destroys the loop and cleans up all resources.
117
+ * Use this for complete cleanup (e.g., in tests or before creating a new instance).
118
+ * After calling destroy(), the instance should not be reused.
119
+ */
120
+ destroy(): void;
121
+ }
122
+ /** Gets or creates the singleton RalphLoop instance. */
123
+ export declare function getRalphLoop(options?: RalphLoopOptions): RalphLoop;
124
+ //# sourceMappingURL=ralph-loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ralph-loop.d.ts","sourceRoot":"","sources":["../src/ralph-loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAM3C,OAAO,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6DAA6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,SAAU,SAAQ,YAAY;IACzC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,iBAAiB,CAAU;IACnC,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,cAAc,CAAa;IAEnC,+DAA+D;IAC/D,OAAO,CAAC,oBAAoB,CAKZ;gBAEJ,OAAO,GAAE,gBAAqB;IA2B1C,OAAO,CAAC,kBAAkB;IAuB1B,qDAAqD;IACrD,OAAO,CAAC,oBAAoB;IAU5B,IAAI,MAAM,IAAI,eAAe,CAE5B;IAED,SAAS,IAAI,OAAO;IAIpB,YAAY,IAAI,MAAM;IAOtB,eAAe,IAAI,MAAM;IAIzB,oBAAoB,IAAI,OAAO;IAO/B,QAAQ;;;;;;;;;;;;;;;;;IAiBR,sCAAsC;IAChC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B5B,qCAAqC;IACrC,IAAI,IAAI,IAAI;IAuBZ,wCAAwC;IACxC,KAAK,IAAI,IAAI;IAeb,6BAA6B;IAC7B,MAAM,IAAI,IAAI;IAUd,OAAO,CAAC,OAAO;YAqBD,IAAI;YAoBJ,WAAW;YAiBX,mBAAmB;YAkBnB,aAAa;IAgB3B,OAAO,CAAC,uBAAuB;IA6B/B,OAAO,CAAC,kBAAkB;IAoB1B,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,mBAAmB;YASb,qBAAqB;IA6BnC,OAAO,CAAC,UAAU;IAiBlB,mEAAmE;IACnE,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKnC;;;;OAIG;IACH,OAAO,IAAI,IAAI;CAKhB;AAKD,wDAAwD;AACxD,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAKlE"}
@@ -0,0 +1,418 @@
1
+ /**
2
+ * @fileoverview Ralph Loop - Autonomous task execution engine
3
+ *
4
+ * The Ralph Loop orchestrates autonomous Claude sessions by:
5
+ * - Polling for available tasks from the task queue
6
+ * - Assigning tasks to idle sessions
7
+ * - Monitoring completion and handling failures
8
+ * - Auto-generating follow-up tasks when min duration not reached
9
+ *
10
+ * Named after Ralph Wiggum's persistence ("I'm in danger!"),
11
+ * this loop keeps Claude working until all tasks are done.
12
+ *
13
+ * @module ralph-loop
14
+ */
15
+ import { EventEmitter } from 'node:events';
16
+ import { getSessionManager } from './session-manager.js';
17
+ import { getTaskQueue } from './task-queue.js';
18
+ import { getStore } from './state-store.js';
19
+ import { getErrorMessage } from './types.js';
20
+ /**
21
+ * Autonomous task execution loop.
22
+ *
23
+ * @description
24
+ * Manages the lifecycle of task execution:
25
+ * 1. Start: Begin polling and task assignment
26
+ * 2. Run: Assign tasks to idle sessions, monitor completion
27
+ * 3. Stop: When all tasks done and min duration reached
28
+ *
29
+ * Supports time-aware loops that continue generating tasks
30
+ * until a minimum duration is reached.
31
+ *
32
+ * @extends EventEmitter
33
+ */
34
+ export class RalphLoop extends EventEmitter {
35
+ sessionManager;
36
+ taskQueue;
37
+ store;
38
+ pollIntervalMs;
39
+ minDurationMs;
40
+ autoGenerateTasks;
41
+ loopTimer = null;
42
+ _status = 'stopped';
43
+ startedAt = null;
44
+ tasksCompleted = 0;
45
+ tasksGenerated = 0;
46
+ /** Bound event handlers for cleanup (prevents memory leaks) */
47
+ sessionEventHandlers = null;
48
+ constructor(options = {}) {
49
+ super();
50
+ this.sessionManager = getSessionManager();
51
+ this.taskQueue = getTaskQueue();
52
+ this.store = getStore();
53
+ const config = this.store.getConfig();
54
+ this.pollIntervalMs = options.pollIntervalMs ?? config.pollIntervalMs;
55
+ this.minDurationMs = options.minDurationMs ?? null;
56
+ this.autoGenerateTasks = options.autoGenerateTasks ?? true;
57
+ // Load state from store
58
+ const savedState = this.store.getRalphLoopState();
59
+ if (savedState.status === 'running') {
60
+ // If we crashed while running, reset to stopped
61
+ this._status = 'stopped';
62
+ this.store.setRalphLoopState({ status: 'stopped' });
63
+ // Reset orphaned in_progress tasks back to pending
64
+ for (const task of this.taskQueue.getRunningTasks()) {
65
+ task.reset();
66
+ this.taskQueue.updateTask(task);
67
+ }
68
+ }
69
+ this.setupEventHandlers();
70
+ }
71
+ setupEventHandlers() {
72
+ // Store bound handlers for later cleanup
73
+ this.sessionEventHandlers = {
74
+ completion: (sessionId, phrase) => {
75
+ this.handleSessionCompletion(sessionId, phrase);
76
+ },
77
+ error: (sessionId, error) => {
78
+ this.handleSessionError(sessionId, error);
79
+ },
80
+ stopped: (sessionId) => {
81
+ this.handleSessionStopped(sessionId);
82
+ },
83
+ taskError: (sessionId, taskId, error) => {
84
+ this.handleSessionTaskError(sessionId, taskId, error);
85
+ },
86
+ };
87
+ this.sessionManager.on('sessionCompletion', this.sessionEventHandlers.completion);
88
+ this.sessionManager.on('sessionError', this.sessionEventHandlers.error);
89
+ this.sessionManager.on('sessionStopped', this.sessionEventHandlers.stopped);
90
+ this.sessionManager.on('sessionTaskError', this.sessionEventHandlers.taskError);
91
+ }
92
+ /** Remove event listeners to prevent memory leaks */
93
+ cleanupEventHandlers() {
94
+ if (this.sessionEventHandlers) {
95
+ this.sessionManager.off('sessionCompletion', this.sessionEventHandlers.completion);
96
+ this.sessionManager.off('sessionError', this.sessionEventHandlers.error);
97
+ this.sessionManager.off('sessionStopped', this.sessionEventHandlers.stopped);
98
+ this.sessionManager.off('sessionTaskError', this.sessionEventHandlers.taskError);
99
+ this.sessionEventHandlers = null;
100
+ }
101
+ }
102
+ get status() {
103
+ return this._status;
104
+ }
105
+ isRunning() {
106
+ return this._status === 'running';
107
+ }
108
+ getElapsedMs() {
109
+ if (!this.startedAt) {
110
+ return 0;
111
+ }
112
+ return Date.now() - this.startedAt;
113
+ }
114
+ getElapsedHours() {
115
+ return this.getElapsedMs() / (1000 * 60 * 60);
116
+ }
117
+ isMinDurationReached() {
118
+ if (!this.minDurationMs) {
119
+ return true;
120
+ }
121
+ return this.getElapsedMs() >= this.minDurationMs;
122
+ }
123
+ getStats() {
124
+ const taskCounts = this.taskQueue.getCount();
125
+ return {
126
+ status: this._status,
127
+ elapsedMs: this.getElapsedMs(),
128
+ elapsedHours: this.getElapsedHours(),
129
+ minDurationMs: this.minDurationMs,
130
+ minDurationReached: this.isMinDurationReached(),
131
+ tasksCompleted: this.tasksCompleted,
132
+ tasksGenerated: this.tasksGenerated,
133
+ ...taskCounts,
134
+ activeSessions: this.sessionManager.getSessionCount(),
135
+ idleSessions: this.sessionManager.getIdleSessions().length,
136
+ busySessions: this.sessionManager.getBusySessions().length,
137
+ };
138
+ }
139
+ /** Starts the task execution loop. */
140
+ async start() {
141
+ if (this._status === 'running') {
142
+ return;
143
+ }
144
+ this._status = 'running';
145
+ this.startedAt = Date.now();
146
+ this.tasksCompleted = 0;
147
+ this.tasksGenerated = 0;
148
+ // Re-setup event handlers if they were cleaned up during stop()
149
+ if (!this.sessionEventHandlers) {
150
+ this.setupEventHandlers();
151
+ }
152
+ this.store.setRalphLoopState({
153
+ status: 'running',
154
+ startedAt: this.startedAt,
155
+ minDurationMs: this.minDurationMs,
156
+ tasksCompleted: 0,
157
+ tasksGenerated: 0,
158
+ });
159
+ this.emit('started');
160
+ this.runLoop();
161
+ }
162
+ /** Stops the task execution loop. */
163
+ stop() {
164
+ if (this._status === 'stopped') {
165
+ return;
166
+ }
167
+ this._status = 'stopped';
168
+ if (this.loopTimer) {
169
+ clearTimeout(this.loopTimer);
170
+ this.loopTimer = null;
171
+ }
172
+ // Clean up event handlers to prevent memory leaks
173
+ this.cleanupEventHandlers();
174
+ this.store.setRalphLoopState({
175
+ status: 'stopped',
176
+ lastCheckAt: Date.now(),
177
+ });
178
+ this.emit('stopped');
179
+ }
180
+ /** Pauses the loop (can be resumed). */
181
+ pause() {
182
+ if (this._status !== 'running') {
183
+ return;
184
+ }
185
+ this._status = 'paused';
186
+ if (this.loopTimer) {
187
+ clearTimeout(this.loopTimer);
188
+ this.loopTimer = null;
189
+ }
190
+ this.store.setRalphLoopState({ status: 'paused' });
191
+ }
192
+ /** Resumes a paused loop. */
193
+ resume() {
194
+ if (this._status !== 'paused') {
195
+ return;
196
+ }
197
+ this._status = 'running';
198
+ this.store.setRalphLoopState({ status: 'running' });
199
+ this.runLoop();
200
+ }
201
+ runLoop() {
202
+ if (this._status !== 'running') {
203
+ return;
204
+ }
205
+ this.tick()
206
+ .catch((err) => {
207
+ // Only emit if still running (stop() may have been called during tick())
208
+ if (this._status === 'running') {
209
+ this.emit('error', err);
210
+ }
211
+ })
212
+ .finally(() => {
213
+ // Guard: only reschedule if still running AND no timer is pending
214
+ // (prevents race where stop() clears timer between our check and setTimeout)
215
+ if (this._status === 'running' && this.loopTimer === null) {
216
+ this.loopTimer = setTimeout(() => this.runLoop(), this.pollIntervalMs);
217
+ }
218
+ });
219
+ }
220
+ async tick() {
221
+ this.store.setRalphLoopState({ lastCheckAt: Date.now() });
222
+ // Run sequentially: timeouts first so timed-out tasks are cleaned up
223
+ // before assignTasks() picks new work (prevents race where both
224
+ // mutate the same task concurrently)
225
+ await this.checkTimeouts();
226
+ await this.assignTasks();
227
+ // Check if we should auto-generate tasks (depends on assignment results)
228
+ if (this.autoGenerateTasks && this.shouldGenerateTasks()) {
229
+ await this.generateFollowUpTasks();
230
+ }
231
+ // Check if we're done
232
+ if (this.shouldStop()) {
233
+ this.stop();
234
+ }
235
+ }
236
+ async assignTasks() {
237
+ const idleSessions = this.sessionManager.getIdleSessions();
238
+ for (const session of idleSessions) {
239
+ const task = this.taskQueue.next();
240
+ if (!task) {
241
+ break;
242
+ }
243
+ try {
244
+ await this.assignTaskToSession(task, session);
245
+ }
246
+ catch (err) {
247
+ console.error(`[RalphLoop] Failed to assign task ${task.id} to session ${session.id}:`, err);
248
+ }
249
+ }
250
+ }
251
+ async assignTaskToSession(task, session) {
252
+ try {
253
+ task.assign(session.id);
254
+ session.assignTask(task.id);
255
+ this.taskQueue.updateTask(task);
256
+ // Send the prompt to the session
257
+ await session.sendInput(task.prompt);
258
+ this.emit('taskAssigned', task.id, session.id);
259
+ }
260
+ catch (err) {
261
+ task.fail(getErrorMessage(err));
262
+ session.clearTask();
263
+ this.taskQueue.updateTask(task);
264
+ this.emit('taskFailed', task.id, getErrorMessage(err));
265
+ }
266
+ }
267
+ async checkTimeouts() {
268
+ for (const task of this.taskQueue.getRunningTasks()) {
269
+ if (task.isTimedOut()) {
270
+ task.fail('Task timed out');
271
+ this.taskQueue.updateTask(task);
272
+ const session = this.sessionManager.getSession(task.assignedSessionId);
273
+ if (session) {
274
+ session.clearTask();
275
+ }
276
+ this.emit('taskFailed', task.id, 'Task timed out');
277
+ }
278
+ }
279
+ }
280
+ handleSessionCompletion(sessionId, phrase) {
281
+ const session = this.sessionManager.getSession(sessionId);
282
+ if (!session) {
283
+ return;
284
+ }
285
+ const taskId = session.currentTaskId;
286
+ if (!taskId) {
287
+ return;
288
+ }
289
+ const task = this.taskQueue.getTask(taskId);
290
+ if (!task) {
291
+ return;
292
+ }
293
+ // Append output and check for completion
294
+ task.appendOutput(session.getOutput());
295
+ if (task.checkCompletion(session.getOutput()) || phrase) {
296
+ task.complete();
297
+ this.taskQueue.updateTask(task);
298
+ session.clearTask();
299
+ this.tasksCompleted++;
300
+ this.store.setRalphLoopState({ tasksCompleted: this.tasksCompleted });
301
+ this.emit('taskCompleted', task.id);
302
+ }
303
+ }
304
+ handleSessionError(sessionId, error) {
305
+ const session = this.sessionManager.getSession(sessionId);
306
+ if (!session) {
307
+ return;
308
+ }
309
+ const taskId = session.currentTaskId;
310
+ if (!taskId) {
311
+ return;
312
+ }
313
+ const task = this.taskQueue.getTask(taskId);
314
+ if (!task) {
315
+ return;
316
+ }
317
+ task.setError(error);
318
+ // Don't fail the task immediately on stderr - some tools write to stderr normally
319
+ }
320
+ handleSessionStopped(sessionId) {
321
+ const task = this.taskQueue.getRunningTaskForSession(sessionId);
322
+ if (task) {
323
+ task.fail('Session stopped unexpectedly');
324
+ this.taskQueue.updateTask(task);
325
+ this.emit('taskFailed', task.id, 'Session stopped unexpectedly');
326
+ }
327
+ }
328
+ handleSessionTaskError(_sessionId, taskId, error) {
329
+ const task = this.taskQueue.getTask(taskId);
330
+ if (!task) {
331
+ return;
332
+ }
333
+ task.fail(error);
334
+ this.taskQueue.updateTask(task);
335
+ this.emit('taskFailed', task.id, error);
336
+ }
337
+ shouldGenerateTasks() {
338
+ // Generate tasks if:
339
+ // 1. No pending tasks
340
+ // 2. Min duration not reached
341
+ // 3. We have idle sessions
342
+ const counts = this.taskQueue.getCount();
343
+ return counts.pending === 0 && !this.isMinDurationReached() && this.sessionManager.getIdleSessions().length > 0;
344
+ }
345
+ async generateFollowUpTasks() {
346
+ // This is a placeholder for auto-generating follow-up tasks
347
+ // In a real implementation, this could:
348
+ // - Analyze completed tasks to find optimization opportunities
349
+ // - Generate tasks for code cleanup, tests, documentation
350
+ // - Use Claude to suggest improvements
351
+ const suggestions = [
352
+ 'Review and optimize recently changed code',
353
+ 'Add tests for uncovered code paths',
354
+ 'Update documentation for changed APIs',
355
+ 'Check for security vulnerabilities',
356
+ 'Run linting and fix any issues',
357
+ ];
358
+ // Only generate one task at a time
359
+ const suggestion = suggestions[this.tasksGenerated % suggestions.length];
360
+ const defaultDir = process.cwd();
361
+ this.taskQueue.addTask({
362
+ prompt: suggestion,
363
+ workingDir: defaultDir,
364
+ priority: -1, // Lower priority than user-added tasks
365
+ });
366
+ this.tasksGenerated++;
367
+ this.store.setRalphLoopState({ tasksGenerated: this.tasksGenerated });
368
+ }
369
+ shouldStop() {
370
+ const counts = this.taskQueue.getCount();
371
+ // Don't stop if there are pending or running tasks
372
+ if (counts.pending > 0 || counts.running > 0) {
373
+ return false;
374
+ }
375
+ // Don't stop if min duration not reached and auto-generate is on
376
+ if (!this.isMinDurationReached() && this.autoGenerateTasks) {
377
+ return false;
378
+ }
379
+ // All tasks done and conditions met
380
+ return true;
381
+ }
382
+ /** Sets the minimum duration in hours before the loop can stop. */
383
+ setMinDuration(hours) {
384
+ this.minDurationMs = hours * 60 * 60 * 1000;
385
+ this.store.setRalphLoopState({ minDurationMs: this.minDurationMs });
386
+ }
387
+ /**
388
+ * Destroys the loop and cleans up all resources.
389
+ * Use this for complete cleanup (e.g., in tests or before creating a new instance).
390
+ * After calling destroy(), the instance should not be reused.
391
+ */
392
+ destroy() {
393
+ this.stop();
394
+ this.cleanupEventHandlers();
395
+ this.removeAllListeners();
396
+ }
397
+ }
398
+ // Singleton instance
399
+ let loopInstance = null;
400
+ /** Gets or creates the singleton RalphLoop instance. */
401
+ export function getRalphLoop(options) {
402
+ if (!loopInstance) {
403
+ loopInstance = new RalphLoop(options);
404
+ }
405
+ return loopInstance;
406
+ }
407
+ /** Destroys the singleton instance. Use in tests or for cleanup. */
408
+ function destroyRalphLoop() {
409
+ if (loopInstance) {
410
+ loopInstance.destroy();
411
+ loopInstance = null;
412
+ }
413
+ }
414
+ // Ensure cleanup on process exit (prevents orphaned event handlers and circular references)
415
+ process.on('exit', () => {
416
+ destroyRalphLoop();
417
+ });
418
+ //# sourceMappingURL=ralph-loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ralph-loop.js","sourceRoot":"","sources":["../src/ralph-loop.ts"],"names":[],"mappings":"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"}