aicodeman 0.2.9 → 0.3.1

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 (374) hide show
  1. package/README.md +118 -4
  2. package/dist/ai-idle-checker.d.ts.map +1 -1
  3. package/dist/ai-idle-checker.js +3 -2
  4. package/dist/ai-idle-checker.js.map +1 -1
  5. package/dist/ai-plan-checker.d.ts.map +1 -1
  6. package/dist/ai-plan-checker.js +3 -2
  7. package/dist/ai-plan-checker.js.map +1 -1
  8. package/dist/bash-tool-parser.d.ts +2 -3
  9. package/dist/bash-tool-parser.d.ts.map +1 -1
  10. package/dist/bash-tool-parser.js +14 -31
  11. package/dist/bash-tool-parser.js.map +1 -1
  12. package/dist/config/ai-defaults.d.ts +16 -0
  13. package/dist/config/ai-defaults.d.ts.map +1 -0
  14. package/dist/config/ai-defaults.js +16 -0
  15. package/dist/config/ai-defaults.js.map +1 -0
  16. package/dist/config/auth-config.d.ts +19 -0
  17. package/dist/config/auth-config.d.ts.map +1 -0
  18. package/dist/config/auth-config.js +28 -0
  19. package/dist/config/auth-config.js.map +1 -0
  20. package/dist/config/exec-timeout.d.ts +10 -0
  21. package/dist/config/exec-timeout.d.ts.map +1 -0
  22. package/dist/config/exec-timeout.js +10 -0
  23. package/dist/config/exec-timeout.js.map +1 -0
  24. package/dist/config/map-limits.d.ts +4 -0
  25. package/dist/config/map-limits.d.ts.map +1 -1
  26. package/dist/config/map-limits.js +7 -0
  27. package/dist/config/map-limits.js.map +1 -1
  28. package/dist/config/server-timing.d.ts +42 -0
  29. package/dist/config/server-timing.d.ts.map +1 -0
  30. package/dist/config/server-timing.js +57 -0
  31. package/dist/config/server-timing.js.map +1 -0
  32. package/dist/config/team-config.d.ts +16 -0
  33. package/dist/config/team-config.d.ts.map +1 -0
  34. package/dist/config/team-config.js +16 -0
  35. package/dist/config/team-config.js.map +1 -0
  36. package/dist/config/terminal-limits.d.ts +18 -0
  37. package/dist/config/terminal-limits.d.ts.map +1 -0
  38. package/dist/config/terminal-limits.js +18 -0
  39. package/dist/config/terminal-limits.js.map +1 -0
  40. package/dist/config/tunnel-config.d.ts +27 -0
  41. package/dist/config/tunnel-config.d.ts.map +1 -0
  42. package/dist/config/tunnel-config.js +36 -0
  43. package/dist/config/tunnel-config.js.map +1 -0
  44. package/dist/hooks-config.d.ts +21 -6
  45. package/dist/hooks-config.d.ts.map +1 -1
  46. package/dist/hooks-config.js +28 -12
  47. package/dist/hooks-config.js.map +1 -1
  48. package/dist/image-watcher.d.ts +4 -4
  49. package/dist/image-watcher.d.ts.map +1 -1
  50. package/dist/image-watcher.js +17 -30
  51. package/dist/image-watcher.js.map +1 -1
  52. package/dist/index.js +1 -2
  53. package/dist/index.js.map +1 -1
  54. package/dist/plan-orchestrator.d.ts +2 -24
  55. package/dist/plan-orchestrator.d.ts.map +1 -1
  56. package/dist/plan-orchestrator.js.map +1 -1
  57. package/dist/prompts/planner.d.ts +7 -8
  58. package/dist/prompts/planner.d.ts.map +1 -1
  59. package/dist/prompts/planner.js +7 -8
  60. package/dist/prompts/planner.js.map +1 -1
  61. package/dist/prompts/research-agent.d.ts +6 -4
  62. package/dist/prompts/research-agent.d.ts.map +1 -1
  63. package/dist/prompts/research-agent.js +6 -4
  64. package/dist/prompts/research-agent.js.map +1 -1
  65. package/dist/push-store.d.ts +1 -1
  66. package/dist/push-store.d.ts.map +1 -1
  67. package/dist/push-store.js +4 -12
  68. package/dist/push-store.js.map +1 -1
  69. package/dist/ralph-fix-plan-watcher.d.ts +91 -0
  70. package/dist/ralph-fix-plan-watcher.d.ts.map +1 -0
  71. package/dist/ralph-fix-plan-watcher.js +326 -0
  72. package/dist/ralph-fix-plan-watcher.js.map +1 -0
  73. package/dist/ralph-loop.d.ts +14 -4
  74. package/dist/ralph-loop.d.ts.map +1 -1
  75. package/dist/ralph-loop.js +14 -4
  76. package/dist/ralph-loop.js.map +1 -1
  77. package/dist/ralph-plan-tracker.d.ts +201 -0
  78. package/dist/ralph-plan-tracker.d.ts.map +1 -0
  79. package/dist/ralph-plan-tracker.js +325 -0
  80. package/dist/ralph-plan-tracker.js.map +1 -0
  81. package/dist/ralph-stall-detector.d.ts +84 -0
  82. package/dist/ralph-stall-detector.d.ts.map +1 -0
  83. package/dist/ralph-stall-detector.js +139 -0
  84. package/dist/ralph-stall-detector.js.map +1 -0
  85. package/dist/ralph-status-parser.d.ts +141 -0
  86. package/dist/ralph-status-parser.d.ts.map +1 -0
  87. package/dist/ralph-status-parser.js +478 -0
  88. package/dist/ralph-status-parser.js.map +1 -0
  89. package/dist/ralph-tracker.d.ts +218 -692
  90. package/dist/ralph-tracker.d.ts.map +1 -1
  91. package/dist/ralph-tracker.js +389 -1723
  92. package/dist/ralph-tracker.js.map +1 -1
  93. package/dist/respawn-adaptive-timing.d.ts +61 -0
  94. package/dist/respawn-adaptive-timing.d.ts.map +1 -0
  95. package/dist/respawn-adaptive-timing.js +105 -0
  96. package/dist/respawn-adaptive-timing.js.map +1 -0
  97. package/dist/respawn-controller.d.ts +35 -115
  98. package/dist/respawn-controller.d.ts.map +1 -1
  99. package/dist/respawn-controller.js +167 -607
  100. package/dist/respawn-controller.js.map +1 -1
  101. package/dist/respawn-health.d.ts +54 -0
  102. package/dist/respawn-health.d.ts.map +1 -0
  103. package/dist/respawn-health.js +183 -0
  104. package/dist/respawn-health.js.map +1 -0
  105. package/dist/respawn-metrics.d.ts +81 -0
  106. package/dist/respawn-metrics.d.ts.map +1 -0
  107. package/dist/respawn-metrics.js +198 -0
  108. package/dist/respawn-metrics.js.map +1 -0
  109. package/dist/respawn-patterns.d.ts +45 -0
  110. package/dist/respawn-patterns.d.ts.map +1 -0
  111. package/dist/respawn-patterns.js +125 -0
  112. package/dist/respawn-patterns.js.map +1 -0
  113. package/dist/session-auto-ops.d.ts +89 -0
  114. package/dist/session-auto-ops.d.ts.map +1 -0
  115. package/dist/session-auto-ops.js +224 -0
  116. package/dist/session-auto-ops.js.map +1 -0
  117. package/dist/session-cli-builder.d.ts +62 -0
  118. package/dist/session-cli-builder.d.ts.map +1 -0
  119. package/dist/session-cli-builder.js +121 -0
  120. package/dist/session-cli-builder.js.map +1 -0
  121. package/dist/session-manager.d.ts +17 -5
  122. package/dist/session-manager.d.ts.map +1 -1
  123. package/dist/session-manager.js +17 -5
  124. package/dist/session-manager.js.map +1 -1
  125. package/dist/session-task-cache.d.ts +52 -0
  126. package/dist/session-task-cache.d.ts.map +1 -0
  127. package/dist/session-task-cache.js +90 -0
  128. package/dist/session-task-cache.js.map +1 -0
  129. package/dist/session.d.ts +23 -41
  130. package/dist/session.d.ts.map +1 -1
  131. package/dist/session.js +79 -317
  132. package/dist/session.js.map +1 -1
  133. package/dist/state-store.d.ts +19 -9
  134. package/dist/state-store.d.ts.map +1 -1
  135. package/dist/state-store.js +29 -30
  136. package/dist/state-store.js.map +1 -1
  137. package/dist/subagent-watcher.d.ts +26 -7
  138. package/dist/subagent-watcher.d.ts.map +1 -1
  139. package/dist/subagent-watcher.js +47 -64
  140. package/dist/subagent-watcher.js.map +1 -1
  141. package/dist/team-watcher.d.ts.map +1 -1
  142. package/dist/team-watcher.js +2 -5
  143. package/dist/team-watcher.js.map +1 -1
  144. package/dist/tmux-manager.d.ts.map +1 -1
  145. package/dist/tmux-manager.js +1 -2
  146. package/dist/tmux-manager.js.map +1 -1
  147. package/dist/tunnel-manager.d.ts +26 -0
  148. package/dist/tunnel-manager.d.ts.map +1 -1
  149. package/dist/tunnel-manager.js +126 -7
  150. package/dist/tunnel-manager.js.map +1 -1
  151. package/dist/types/api.d.ts +108 -0
  152. package/dist/types/api.d.ts.map +1 -0
  153. package/dist/types/api.js +98 -0
  154. package/dist/types/api.js.map +1 -0
  155. package/dist/types/app-state.d.ts +117 -0
  156. package/dist/types/app-state.d.ts.map +1 -0
  157. package/dist/types/app-state.js +76 -0
  158. package/dist/types/app-state.js.map +1 -0
  159. package/dist/types/common.d.ts +79 -0
  160. package/dist/types/common.d.ts.map +1 -0
  161. package/dist/types/common.js +17 -0
  162. package/dist/types/common.js.map +1 -0
  163. package/dist/types/index.d.ts +66 -0
  164. package/dist/types/index.d.ts.map +1 -0
  165. package/dist/types/index.js +66 -0
  166. package/dist/types/index.js.map +1 -0
  167. package/dist/types/lifecycle.d.ts +28 -0
  168. package/dist/types/lifecycle.d.ts.map +1 -0
  169. package/dist/types/lifecycle.js +16 -0
  170. package/dist/types/lifecycle.js.map +1 -0
  171. package/dist/types/plan.d.ts +45 -0
  172. package/dist/types/plan.d.ts.map +1 -0
  173. package/dist/types/plan.js +18 -0
  174. package/dist/types/plan.js.map +1 -0
  175. package/dist/types/push.d.ts +36 -0
  176. package/dist/types/push.d.ts.map +1 -0
  177. package/dist/types/push.js +18 -0
  178. package/dist/types/push.js.map +1 -0
  179. package/dist/types/ralph.d.ts +262 -0
  180. package/dist/types/ralph.d.ts.map +1 -0
  181. package/dist/types/ralph.js +70 -0
  182. package/dist/types/ralph.js.map +1 -0
  183. package/dist/types/respawn.d.ts +271 -0
  184. package/dist/types/respawn.d.ts.map +1 -0
  185. package/dist/types/respawn.js +26 -0
  186. package/dist/types/respawn.js.map +1 -0
  187. package/dist/types/run-summary.d.ts +96 -0
  188. package/dist/types/run-summary.d.ts.map +1 -0
  189. package/dist/types/run-summary.js +37 -0
  190. package/dist/types/run-summary.js.map +1 -0
  191. package/dist/types/session.d.ts +152 -0
  192. package/dist/types/session.d.ts.map +1 -0
  193. package/dist/types/session.js +27 -0
  194. package/dist/types/session.js.map +1 -0
  195. package/dist/types/task.d.ts +72 -0
  196. package/dist/types/task.d.ts.map +1 -0
  197. package/dist/types/task.js +19 -0
  198. package/dist/types/task.js.map +1 -0
  199. package/dist/types/teams.d.ts +73 -0
  200. package/dist/types/teams.d.ts.map +1 -0
  201. package/dist/types/teams.js +23 -0
  202. package/dist/types/teams.js.map +1 -0
  203. package/dist/types/tools.d.ts +61 -0
  204. package/dist/types/tools.d.ts.map +1 -0
  205. package/dist/types/tools.js +20 -0
  206. package/dist/types/tools.js.map +1 -0
  207. package/dist/types.d.ts +8 -1134
  208. package/dist/types.d.ts.map +1 -1
  209. package/dist/types.js +8 -210
  210. package/dist/types.js.map +1 -1
  211. package/dist/utils/claude-cli-resolver.d.ts.map +1 -1
  212. package/dist/utils/claude-cli-resolver.js +1 -2
  213. package/dist/utils/claude-cli-resolver.js.map +1 -1
  214. package/dist/utils/debouncer.d.ts +111 -0
  215. package/dist/utils/debouncer.d.ts.map +1 -0
  216. package/dist/utils/debouncer.js +162 -0
  217. package/dist/utils/debouncer.js.map +1 -0
  218. package/dist/utils/index.d.ts +3 -2
  219. package/dist/utils/index.d.ts.map +1 -1
  220. package/dist/utils/index.js +3 -2
  221. package/dist/utils/index.js.map +1 -1
  222. package/dist/utils/opencode-cli-resolver.d.ts.map +1 -1
  223. package/dist/utils/opencode-cli-resolver.js +1 -2
  224. package/dist/utils/opencode-cli-resolver.js.map +1 -1
  225. package/dist/utils/string-similarity.d.ts +0 -57
  226. package/dist/utils/string-similarity.d.ts.map +1 -1
  227. package/dist/utils/string-similarity.js +3 -18
  228. package/dist/utils/string-similarity.js.map +1 -1
  229. package/dist/web/middleware/auth.d.ts +31 -0
  230. package/dist/web/middleware/auth.d.ts.map +1 -0
  231. package/dist/web/middleware/auth.js +154 -0
  232. package/dist/web/middleware/auth.js.map +1 -0
  233. package/dist/web/ports/auth-port.d.ts +18 -0
  234. package/dist/web/ports/auth-port.d.ts.map +1 -0
  235. package/dist/web/ports/auth-port.js +6 -0
  236. package/dist/web/ports/auth-port.js.map +1 -0
  237. package/dist/web/ports/config-port.d.ts +28 -0
  238. package/dist/web/ports/config-port.d.ts.map +1 -0
  239. package/dist/web/ports/config-port.js +6 -0
  240. package/dist/web/ports/config-port.js.map +1 -0
  241. package/dist/web/ports/event-port.d.ts +13 -0
  242. package/dist/web/ports/event-port.d.ts.map +1 -0
  243. package/dist/web/ports/event-port.js +6 -0
  244. package/dist/web/ports/event-port.js.map +1 -0
  245. package/dist/web/ports/index.d.ts +14 -0
  246. package/dist/web/ports/index.d.ts.map +1 -0
  247. package/dist/web/ports/index.js +9 -0
  248. package/dist/web/ports/index.js.map +1 -0
  249. package/dist/web/ports/infra-port.d.ts +36 -0
  250. package/dist/web/ports/infra-port.d.ts.map +1 -0
  251. package/dist/web/ports/infra-port.js +6 -0
  252. package/dist/web/ports/infra-port.js.map +1 -0
  253. package/dist/web/ports/respawn-port.d.ts +20 -0
  254. package/dist/web/ports/respawn-port.d.ts.map +1 -0
  255. package/dist/web/ports/respawn-port.js +6 -0
  256. package/dist/web/ports/respawn-port.js.map +1 -0
  257. package/dist/web/ports/session-port.d.ts +15 -0
  258. package/dist/web/ports/session-port.d.ts.map +1 -0
  259. package/dist/web/ports/session-port.js +6 -0
  260. package/dist/web/ports/session-port.js.map +1 -0
  261. package/dist/web/public/api-client.js +82 -0
  262. package/dist/web/public/api-client.js.br +0 -0
  263. package/dist/web/public/api-client.js.gz +0 -0
  264. package/dist/web/public/app.js +117 -201
  265. package/dist/web/public/app.js.br +0 -0
  266. package/dist/web/public/app.js.gz +0 -0
  267. package/dist/web/public/constants.js +365 -0
  268. package/dist/web/public/constants.js.br +0 -0
  269. package/dist/web/public/constants.js.gz +0 -0
  270. package/dist/web/public/index.html +15 -3
  271. package/dist/web/public/index.html.br +0 -0
  272. package/dist/web/public/index.html.gz +0 -0
  273. package/dist/web/public/keyboard-accessory.js +302 -0
  274. package/dist/web/public/keyboard-accessory.js.br +0 -0
  275. package/dist/web/public/keyboard-accessory.js.gz +0 -0
  276. package/dist/web/public/mobile-handlers.js +491 -0
  277. package/dist/web/public/mobile-handlers.js.br +0 -0
  278. package/dist/web/public/mobile-handlers.js.gz +0 -0
  279. package/dist/web/public/mobile.css.gz +0 -0
  280. package/dist/web/public/notification-manager.js +472 -0
  281. package/dist/web/public/notification-manager.js.br +0 -0
  282. package/dist/web/public/notification-manager.js.gz +0 -0
  283. package/dist/web/public/ralph-wizard.js +33 -9
  284. package/dist/web/public/ralph-wizard.js.br +0 -0
  285. package/dist/web/public/ralph-wizard.js.gz +0 -0
  286. package/dist/web/public/styles.css.gz +0 -0
  287. package/dist/web/public/subagent-windows.js +1149 -0
  288. package/dist/web/public/subagent-windows.js.br +0 -0
  289. package/dist/web/public/subagent-windows.js.gz +0 -0
  290. package/dist/web/public/sw.js +15 -0
  291. package/dist/web/public/sw.js.br +0 -0
  292. package/dist/web/public/sw.js.gz +0 -0
  293. package/dist/web/public/upload.html.gz +0 -0
  294. package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
  295. package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
  296. package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
  297. package/dist/web/public/vendor/xterm-zerolag-input.js +4 -0
  298. package/dist/web/public/vendor/xterm-zerolag-input.js.br +0 -0
  299. package/dist/web/public/vendor/xterm-zerolag-input.js.gz +0 -0
  300. package/dist/web/public/vendor/xterm.css.gz +0 -0
  301. package/dist/web/public/vendor/xterm.min.js.gz +0 -0
  302. package/dist/web/public/voice-input.js +882 -0
  303. package/dist/web/public/voice-input.js.br +0 -0
  304. package/dist/web/public/voice-input.js.gz +0 -0
  305. package/dist/web/route-helpers.d.ts +38 -0
  306. package/dist/web/route-helpers.d.ts.map +1 -0
  307. package/dist/web/route-helpers.js +144 -0
  308. package/dist/web/route-helpers.js.map +1 -0
  309. package/dist/web/routes/case-routes.d.ts +9 -0
  310. package/dist/web/routes/case-routes.d.ts.map +1 -0
  311. package/dist/web/routes/case-routes.js +426 -0
  312. package/dist/web/routes/case-routes.js.map +1 -0
  313. package/dist/web/routes/file-routes.d.ts +8 -0
  314. package/dist/web/routes/file-routes.d.ts.map +1 -0
  315. package/dist/web/routes/file-routes.js +337 -0
  316. package/dist/web/routes/file-routes.js.map +1 -0
  317. package/dist/web/routes/hook-event-routes.d.ts +9 -0
  318. package/dist/web/routes/hook-event-routes.d.ts.map +1 -0
  319. package/dist/web/routes/hook-event-routes.js +57 -0
  320. package/dist/web/routes/hook-event-routes.js.map +1 -0
  321. package/dist/web/routes/index.d.ts +16 -0
  322. package/dist/web/routes/index.d.ts.map +1 -0
  323. package/dist/web/routes/index.js +16 -0
  324. package/dist/web/routes/index.js.map +1 -0
  325. package/dist/web/routes/mux-routes.d.ts +8 -0
  326. package/dist/web/routes/mux-routes.d.ts.map +1 -0
  327. package/dist/web/routes/mux-routes.js +32 -0
  328. package/dist/web/routes/mux-routes.js.map +1 -0
  329. package/dist/web/routes/plan-routes.d.ts +9 -0
  330. package/dist/web/routes/plan-routes.d.ts.map +1 -0
  331. package/dist/web/routes/plan-routes.js +385 -0
  332. package/dist/web/routes/plan-routes.js.map +1 -0
  333. package/dist/web/routes/push-routes.d.ts +8 -0
  334. package/dist/web/routes/push-routes.d.ts.map +1 -0
  335. package/dist/web/routes/push-routes.js +49 -0
  336. package/dist/web/routes/push-routes.js.map +1 -0
  337. package/dist/web/routes/ralph-routes.d.ts +9 -0
  338. package/dist/web/routes/ralph-routes.d.ts.map +1 -0
  339. package/dist/web/routes/ralph-routes.js +485 -0
  340. package/dist/web/routes/ralph-routes.js.map +1 -0
  341. package/dist/web/routes/respawn-routes.d.ts +8 -0
  342. package/dist/web/routes/respawn-routes.d.ts.map +1 -0
  343. package/dist/web/routes/respawn-routes.js +270 -0
  344. package/dist/web/routes/respawn-routes.js.map +1 -0
  345. package/dist/web/routes/scheduled-routes.d.ts +8 -0
  346. package/dist/web/routes/scheduled-routes.d.ts.map +1 -0
  347. package/dist/web/routes/scheduled-routes.js +51 -0
  348. package/dist/web/routes/scheduled-routes.js.map +1 -0
  349. package/dist/web/routes/session-routes.d.ts +9 -0
  350. package/dist/web/routes/session-routes.d.ts.map +1 -0
  351. package/dist/web/routes/session-routes.js +751 -0
  352. package/dist/web/routes/session-routes.js.map +1 -0
  353. package/dist/web/routes/system-routes.d.ts +9 -0
  354. package/dist/web/routes/system-routes.d.ts.map +1 -0
  355. package/dist/web/routes/system-routes.js +699 -0
  356. package/dist/web/routes/system-routes.js.map +1 -0
  357. package/dist/web/routes/team-routes.d.ts +8 -0
  358. package/dist/web/routes/team-routes.d.ts.map +1 -0
  359. package/dist/web/routes/team-routes.js +14 -0
  360. package/dist/web/routes/team-routes.js.map +1 -0
  361. package/dist/web/schemas.d.ts +43 -3
  362. package/dist/web/schemas.d.ts.map +1 -1
  363. package/dist/web/schemas.js +6 -2
  364. package/dist/web/schemas.js.map +1 -1
  365. package/dist/web/server.d.ts +35 -15
  366. package/dist/web/server.d.ts.map +1 -1
  367. package/dist/web/server.js +563 -3971
  368. package/dist/web/server.js.map +1 -1
  369. package/dist/web/sse-events.d.ts +361 -0
  370. package/dist/web/sse-events.d.ts.map +1 -0
  371. package/dist/web/sse-events.js +396 -0
  372. package/dist/web/sse-events.js.map +1 -0
  373. package/package.json +2 -1
  374. package/scripts/postinstall.js +58 -0
package/dist/session.js CHANGED
@@ -1,16 +1,29 @@
1
1
  /**
2
2
  * @fileoverview Core PTY session wrapper for Claude CLI interactions.
3
3
  *
4
- * This module provides the Session class which manages a PTY (pseudo-terminal)
5
- * process running the Claude CLI. It supports three operation modes:
4
+ * Manages a PTY (pseudo-terminal) process running Claude CLI or OpenCode CLI.
5
+ * Three operation modes:
6
+ * 1. **One-shot** (`runPrompt`): Single prompt → JSON response
7
+ * 2. **Interactive** (`startInteractive`): Persistent interactive session
8
+ * 3. **Shell** (`startShell`): Plain bash shell for debugging
6
9
  *
7
- * 1. **One-shot mode** (`runPrompt`): Execute a single prompt and get JSON response
8
- * 2. **Interactive mode** (`startInteractive`): Start an interactive Claude session
9
- * 3. **Shell mode**: Run a plain bash shell for debugging/testing
10
+ * Optionally wraps in a tmux session for persistence across disconnects.
11
+ * Tracks tokens, costs, background tasks, and auto-compact/clear.
10
12
  *
11
- * The session can optionally run inside a tmux session for persistence across disconnects.
12
- * It tracks tokens, costs, background tasks, and supports
13
- * auto-clear/auto-compact functionality when token limits are approached.
13
+ * Key exports:
14
+ * - `Session` class main entity, extends EventEmitter
15
+ * - `ClaudeMessage` interface parsed JSON messages from Claude output
16
+ * - `SessionEvents` interface — typed event map
17
+ *
18
+ * Key methods: `runPrompt()`, `startInteractive()`, `startShell()`,
19
+ * `writeViaMux()`, `toState()`, `stop()`, `resize()`, `isIdle()`,
20
+ * `setAutoCompact()`, `findTaskDescriptionNear()`, `getTerminalBuffer()`
21
+ *
22
+ * @dependencies session-cli-builder (args/env), session-auto-ops (auto-compact/clear),
23
+ * ralph-tracker (todo/completion parsing), bash-tool-parser (tool invocation tracking),
24
+ * task-tracker (background tasks), mux-interface (tmux abstraction)
25
+ * @consumedby session-manager, web/server, respawn-controller
26
+ * @emits session:terminal, session:idle, session:working, session:completion, session:exit
14
27
  *
15
28
  * @module session
16
29
  */
@@ -22,9 +35,11 @@ import { TaskTracker } from './task-tracker.js';
22
35
  import { RalphTracker } from './ralph-tracker.js';
23
36
  import { BashToolParser } from './bash-tool-parser.js';
24
37
  import { BufferAccumulator } from './utils/buffer-accumulator.js';
25
- import { LRUMap } from './utils/lru-map.js';
26
38
  import { ANSI_ESCAPE_PATTERN_FULL, TOKEN_PATTERN, SPINNER_PATTERN, MAX_SESSION_TOKENS } from './utils/index.js';
27
39
  import { MAX_TERMINAL_BUFFER_SIZE, TRIM_TERMINAL_TO as TERMINAL_BUFFER_TRIM_SIZE, MAX_TEXT_OUTPUT_SIZE, TRIM_TEXT_TO as TEXT_OUTPUT_TRIM_SIZE, MAX_MESSAGES, MAX_LINE_BUFFER_SIZE, } from './config/buffer-limits.js';
40
+ import { buildInteractiveArgs, buildPromptArgs, buildClaudeEnv, buildMuxAttachEnv, buildShellEnv, } from './session-cli-builder.js';
41
+ import { SessionAutoOps } from './session-auto-ops.js';
42
+ import { SessionTaskCache } from './session-task-cache.js';
28
43
  /** Line buffer flush interval (100ms) - forces processing of partial lines */
29
44
  const LINE_BUFFER_FLUSH_INTERVAL = 100;
30
45
  // ============================================================================
@@ -34,10 +49,7 @@ const LINE_BUFFER_FLUSH_INTERVAL = 100;
34
49
  const MUX_STARTUP_DELAY_MS = 300;
35
50
  /** Delay before declaring session idle after last output (2 seconds) */
36
51
  const IDLE_DETECTION_DELAY_MS = 2000;
37
- /** Delay for auto-compact/clear retry attempts (2 seconds) */
38
- const AUTO_RETRY_DELAY_MS = 2000;
39
- /** Delay for auto-compact/clear initial check (1 second) */
40
- const AUTO_INITIAL_DELAY_MS = 1000;
52
+ // Note: Auto-compact/clear timing constants moved to session-auto-ops.ts
41
53
  /** Graceful shutdown delay when stopping session (100ms) */
42
54
  const GRACEFUL_SHUTDOWN_DELAY_MS = 100;
43
55
  // Filter out terminal focus escape sequences (focus in/out reports)
@@ -58,8 +70,6 @@ const LEADING_ANSI_WHITESPACE_PATTERN = /^(\x1b\[\??[\d;]*[A-Za-z]|[\s\r\n])+/;
58
70
  const CTRL_L_PATTERN = /\x0c/g;
59
71
  /** Pattern to split by newlines (CR or LF) */
60
72
  const NEWLINE_SPLIT_PATTERN = /\r?\n/;
61
- // Claude CLI PATH resolution — shared utility
62
- import { getAugmentedPath } from './utils/claude-cli-resolver.js';
63
73
  /**
64
74
  * Core session class that wraps a PTY process running Claude CLI or a shell.
65
75
  *
@@ -96,9 +106,8 @@ export class Session extends EventEmitter {
96
106
  workingDir;
97
107
  createdAt;
98
108
  mode;
99
- /** Maximum number of task descriptions to keep (LRUMap handles size limit automatically) */
100
- static MAX_TASK_DESCRIPTIONS = 100;
101
- static TASK_DESCRIPTION_MAX_AGE_MS = 30000; // Keep descriptions for 30 seconds
109
+ // Task description cache (extracted to SessionTaskCache)
110
+ _taskCache = new SessionTaskCache();
102
111
  _name;
103
112
  ptyProcess = null;
104
113
  _pid = null;
@@ -125,14 +134,8 @@ export class Session extends EventEmitter {
125
134
  // Token tracking for auto-clear
126
135
  _totalInputTokens = 0;
127
136
  _totalOutputTokens = 0;
128
- _autoClearThreshold = 140000; // Default 140k tokens
129
- _autoClearEnabled = false;
130
- _isClearing = false; // Prevent recursive clearing
131
- // Auto-compact settings
132
- _autoCompactThreshold = 110000; // Default 110k tokens (lower than clear)
133
- _autoCompactEnabled = false;
134
- _autoCompactPrompt = ''; // Optional prompt for compact
135
- _isCompacting = false; // Prevent recursive compacting
137
+ // Auto-compact/auto-clear automation (extracted to SessionAutoOps)
138
+ _autoOps;
136
139
  // Image watcher setting (per-session toggle)
137
140
  _imageWatcherEnabled = false;
138
141
  // Flicker filter setting (per-session toggle, applied on frontend)
@@ -144,8 +147,6 @@ export class Session extends EventEmitter {
144
147
  _cliLatestVersion = '';
145
148
  _cliInfoParsed = false; // Only parse once per session
146
149
  // Timer tracking for cleanup (prevents memory leaks)
147
- _autoCompactTimer = null;
148
- _autoClearTimer = null;
149
150
  _promptCheckInterval = null;
150
151
  _promptCheckTimeout = null;
151
152
  _shellIdleTimer = null;
@@ -177,12 +178,7 @@ export class Session extends EventEmitter {
177
178
  // Bash tool tracking (file paths for live log viewing)
178
179
  _bashToolParser;
179
180
  _bashToolHandlers = null;
180
- // Task descriptions parsed from terminal output (e.g., "Explore(Description)")
181
- // Used to correlate with SubagentWatcher discoveries for better window titles
182
- // Uses LRUMap for automatic eviction at MAX_TASK_DESCRIPTIONS limit
183
- _recentTaskDescriptions = new LRUMap({
184
- maxSize: Session.MAX_TASK_DESCRIPTIONS,
185
- });
181
+ // Task descriptions parsed from terminal output delegated to SessionTaskCache
186
182
  // Throttle expensive PTY processing (Ralph, bash parser, task descriptions)
187
183
  // Accumulates clean data between processing windows to avoid running regex on every chunk
188
184
  _lastExpensiveProcessTime = 0;
@@ -268,6 +264,21 @@ export class Session extends EventEmitter {
268
264
  this._bashToolParser.on('toolStart', this._bashToolHandlers.toolStart);
269
265
  this._bashToolParser.on('toolEnd', this._bashToolHandlers.toolEnd);
270
266
  this._bashToolParser.on('toolsUpdate', this._bashToolHandlers.toolsUpdate);
267
+ // Initialize auto-compact/auto-clear automation and forward events
268
+ this._autoOps = new SessionAutoOps({
269
+ writeCommand: (cmd) => this.writeViaMux(cmd),
270
+ isWorking: () => this._isWorking,
271
+ isStopped: () => this._isStopped,
272
+ getTotalTokens: () => this._totalInputTokens + this._totalOutputTokens,
273
+ getSessionId: () => this.id,
274
+ });
275
+ this._autoOps.on('autoCompact', (data) => this.emit('autoCompact', data));
276
+ this._autoOps.on('autoClear', (data) => {
277
+ // Reset token counts on clear
278
+ this._totalInputTokens = 0;
279
+ this._totalOutputTokens = 0;
280
+ this.emit('autoClear', data);
281
+ });
271
282
  }
272
283
  get status() {
273
284
  return this._status;
@@ -371,25 +382,7 @@ export class Session extends EventEmitter {
371
382
  get allowedTools() {
372
383
  return this._allowedTools;
373
384
  }
374
- /**
375
- * Build Claude CLI permission flags based on the configured mode.
376
- * Returns an array of args to pass to the CLI.
377
- */
378
- _buildPermissionArgs() {
379
- switch (this._claudeMode) {
380
- case 'dangerously-skip-permissions':
381
- return ['--dangerously-skip-permissions'];
382
- case 'allowedTools':
383
- if (this._allowedTools) {
384
- return ['--allowedTools', this._allowedTools];
385
- }
386
- // Fall back to normal mode if no tools specified
387
- return [];
388
- case 'normal':
389
- default:
390
- return [];
391
- }
392
- }
385
+ // Note: _buildPermissionArgs removed — now using buildInteractiveArgs from session-cli-builder.ts
393
386
  /**
394
387
  * Set CPU priority configuration.
395
388
  * Note: This only affects new sessions; existing running processes won't be changed.
@@ -448,10 +441,10 @@ export class Session extends EventEmitter {
448
441
  this._totalCost = totalCost;
449
442
  }
450
443
  get autoClearThreshold() {
451
- return this._autoClearThreshold;
444
+ return this._autoOps.autoClearThreshold;
452
445
  }
453
446
  get autoClearEnabled() {
454
- return this._autoClearEnabled;
447
+ return this._autoOps.autoClearEnabled;
455
448
  }
456
449
  get name() {
457
450
  return this._name;
@@ -459,51 +452,20 @@ export class Session extends EventEmitter {
459
452
  set name(value) {
460
453
  this._name = value;
461
454
  }
462
- /** Minimum valid threshold for auto-clear/compact (1000 tokens) */
463
- static MIN_AUTO_THRESHOLD = 1000;
464
- /** Maximum valid threshold for auto-clear/compact (500k tokens) */
465
- static MAX_AUTO_THRESHOLD = 500_000;
466
- /** Default auto-clear threshold when invalid value provided */
467
- static DEFAULT_AUTO_CLEAR_THRESHOLD = 140_000;
468
- /** Default auto-compact threshold when invalid value provided */
469
- static DEFAULT_AUTO_COMPACT_THRESHOLD = 110_000;
470
455
  setAutoClear(enabled, threshold) {
471
- this._autoClearEnabled = enabled;
472
- if (threshold !== undefined) {
473
- // Validate threshold bounds
474
- if (threshold < Session.MIN_AUTO_THRESHOLD || threshold > Session.MAX_AUTO_THRESHOLD) {
475
- console.warn(`[Session ${this.id}] Invalid autoClear threshold ${threshold}, must be between ${Session.MIN_AUTO_THRESHOLD} and ${Session.MAX_AUTO_THRESHOLD}. Using default ${Session.DEFAULT_AUTO_CLEAR_THRESHOLD}.`);
476
- this._autoClearThreshold = Session.DEFAULT_AUTO_CLEAR_THRESHOLD;
477
- }
478
- else {
479
- this._autoClearThreshold = threshold;
480
- }
481
- }
456
+ this._autoOps.setAutoClear(enabled, threshold);
482
457
  }
483
458
  get autoCompactThreshold() {
484
- return this._autoCompactThreshold;
459
+ return this._autoOps.autoCompactThreshold;
485
460
  }
486
461
  get autoCompactEnabled() {
487
- return this._autoCompactEnabled;
462
+ return this._autoOps.autoCompactEnabled;
488
463
  }
489
464
  get autoCompactPrompt() {
490
- return this._autoCompactPrompt;
465
+ return this._autoOps.autoCompactPrompt;
491
466
  }
492
467
  setAutoCompact(enabled, threshold, prompt) {
493
- this._autoCompactEnabled = enabled;
494
- if (threshold !== undefined) {
495
- // Validate threshold bounds
496
- if (threshold < Session.MIN_AUTO_THRESHOLD || threshold > Session.MAX_AUTO_THRESHOLD) {
497
- console.warn(`[Session ${this.id}] Invalid autoCompact threshold ${threshold}, must be between ${Session.MIN_AUTO_THRESHOLD} and ${Session.MAX_AUTO_THRESHOLD}. Using default ${Session.DEFAULT_AUTO_COMPACT_THRESHOLD}.`);
498
- this._autoCompactThreshold = Session.DEFAULT_AUTO_COMPACT_THRESHOLD;
499
- }
500
- else {
501
- this._autoCompactThreshold = threshold;
502
- }
503
- }
504
- if (prompt !== undefined) {
505
- this._autoCompactPrompt = prompt;
506
- }
468
+ this._autoOps.setAutoCompact(enabled, threshold, prompt);
507
469
  }
508
470
  get imageWatcherEnabled() {
509
471
  return this._imageWatcherEnabled;
@@ -537,11 +499,11 @@ export class Session extends EventEmitter {
537
499
  lastActivityAt: this._lastActivityAt,
538
500
  name: this._name,
539
501
  mode: this.mode,
540
- autoClearEnabled: this._autoClearEnabled,
541
- autoClearThreshold: this._autoClearThreshold,
542
- autoCompactEnabled: this._autoCompactEnabled,
543
- autoCompactThreshold: this._autoCompactThreshold,
544
- autoCompactPrompt: this._autoCompactPrompt,
502
+ autoClearEnabled: this._autoOps.autoClearEnabled,
503
+ autoClearThreshold: this._autoOps.autoClearThreshold,
504
+ autoCompactEnabled: this._autoOps.autoCompactEnabled,
505
+ autoCompactThreshold: this._autoOps.autoCompactThreshold,
506
+ autoCompactPrompt: this._autoOps.autoCompactPrompt,
545
507
  imageWatcherEnabled: this._imageWatcherEnabled,
546
508
  totalCost: this._totalCost,
547
509
  inputTokens: this._totalInputTokens,
@@ -603,8 +565,8 @@ export class Session extends EventEmitter {
603
565
  total: this._totalInputTokens + this._totalOutputTokens,
604
566
  },
605
567
  autoClear: {
606
- enabled: this._autoClearEnabled,
607
- threshold: this._autoClearThreshold,
568
+ enabled: this._autoOps.autoClearEnabled,
569
+ threshold: this._autoOps.autoClearThreshold,
608
570
  },
609
571
  // CPU priority configuration
610
572
  nice: {
@@ -707,14 +669,7 @@ export class Session extends EventEmitter {
707
669
  cols: 120,
708
670
  rows: 40,
709
671
  cwd: this.workingDir,
710
- env: {
711
- ...process.env,
712
- LANG: 'en_US.UTF-8',
713
- LC_ALL: 'en_US.UTF-8',
714
- TERM: 'xterm-256color',
715
- COLORTERM: undefined,
716
- CLAUDECODE: undefined,
717
- },
672
+ env: buildMuxAttachEnv(),
718
673
  });
719
674
  // Set claudeSessionId immediately since we passed --session-id to Claude
720
675
  // The mux manager passes --session-id ${sessionId} to Claude
@@ -789,27 +744,13 @@ export class Session extends EventEmitter {
789
744
  try {
790
745
  // Pass --session-id to use the SAME ID as the Codeman session
791
746
  // This ensures subagents can be directly matched to the correct tab
792
- const args = [...this._buildPermissionArgs(), '--session-id', this.id];
793
- if (this._model)
794
- args.push('--model', this._model);
747
+ const args = buildInteractiveArgs(this.id, this._claudeMode, this._model, this._allowedTools);
795
748
  this.ptyProcess = pty.spawn('claude', args, {
796
749
  name: 'xterm-256color',
797
750
  cols: 120,
798
751
  rows: 40,
799
752
  cwd: this.workingDir,
800
- env: {
801
- ...process.env,
802
- LANG: 'en_US.UTF-8',
803
- LC_ALL: 'en_US.UTF-8',
804
- PATH: getAugmentedPath(),
805
- TERM: 'xterm-256color',
806
- COLORTERM: undefined,
807
- CLAUDECODE: undefined,
808
- // Inform Claude it's running within Codeman (helps prevent self-termination)
809
- CODEMAN_MUX: '1',
810
- CODEMAN_SESSION_ID: this.id,
811
- CODEMAN_API_URL: process.env.CODEMAN_API_URL || 'http://localhost:3000',
812
- },
753
+ env: buildClaudeEnv(this.id),
813
754
  });
814
755
  }
815
756
  catch (spawnErr) {
@@ -1078,14 +1019,7 @@ export class Session extends EventEmitter {
1078
1019
  cols: 120,
1079
1020
  rows: 40,
1080
1021
  cwd: this.workingDir,
1081
- env: {
1082
- ...process.env,
1083
- LANG: 'en_US.UTF-8',
1084
- LC_ALL: 'en_US.UTF-8',
1085
- TERM: 'xterm-256color',
1086
- COLORTERM: undefined,
1087
- CLAUDECODE: undefined,
1088
- },
1022
+ env: buildMuxAttachEnv(),
1089
1023
  });
1090
1024
  }
1091
1025
  catch (spawnErr) {
@@ -1118,15 +1052,7 @@ export class Session extends EventEmitter {
1118
1052
  cols: 120,
1119
1053
  rows: 40,
1120
1054
  cwd: this.workingDir,
1121
- env: {
1122
- ...process.env,
1123
- LANG: 'en_US.UTF-8',
1124
- LC_ALL: 'en_US.UTF-8',
1125
- TERM: 'xterm-256color',
1126
- CODEMAN_MUX: '1',
1127
- CODEMAN_SESSION_ID: this.id,
1128
- CODEMAN_API_URL: process.env.CODEMAN_API_URL || 'http://localhost:3000',
1129
- },
1055
+ env: buildShellEnv(this.id),
1130
1056
  });
1131
1057
  }
1132
1058
  catch (spawnErr) {
@@ -1219,30 +1145,14 @@ export class Session extends EventEmitter {
1219
1145
  // Spawn claude in a real PTY
1220
1146
  const model = options?.model;
1221
1147
  console.log('[Session] Spawning PTY for claude with prompt:', prompt.substring(0, 50), model ? `(model: ${model})` : '');
1222
- const args = ['-p', '--verbose', '--dangerously-skip-permissions', '--output-format', 'stream-json'];
1223
- if (model) {
1224
- args.push('--model', model);
1225
- }
1226
- args.push(prompt);
1148
+ const args = buildPromptArgs(prompt, model);
1227
1149
  try {
1228
1150
  this.ptyProcess = pty.spawn('claude', args, {
1229
1151
  name: 'xterm-256color',
1230
1152
  cols: 120,
1231
1153
  rows: 40,
1232
1154
  cwd: this.workingDir,
1233
- env: {
1234
- ...process.env,
1235
- LANG: 'en_US.UTF-8',
1236
- LC_ALL: 'en_US.UTF-8',
1237
- PATH: getAugmentedPath(),
1238
- TERM: 'xterm-256color',
1239
- COLORTERM: undefined,
1240
- CLAUDECODE: undefined,
1241
- // Inform Claude it's running within Codeman
1242
- CODEMAN_MUX: '1',
1243
- CODEMAN_SESSION_ID: this.id,
1244
- CODEMAN_API_URL: process.env.CODEMAN_API_URL || 'http://localhost:3000',
1245
- },
1155
+ env: buildClaudeEnv(this.id),
1246
1156
  });
1247
1157
  }
1248
1158
  catch (spawnErr) {
@@ -1390,8 +1300,8 @@ export class Session extends EventEmitter {
1390
1300
  this._totalOutputTokens += outputDelta;
1391
1301
  }
1392
1302
  // Check if we should auto-compact or auto-clear
1393
- this.checkAutoCompact();
1394
- this.checkAutoClear();
1303
+ this._autoOps.checkAutoCompact();
1304
+ this._autoOps.checkAutoClear();
1395
1305
  }
1396
1306
  }
1397
1307
  if (msg.type === 'result' && msg.total_cost_usd) {
@@ -1443,29 +1353,7 @@ export class Session extends EventEmitter {
1443
1353
  while ((match = TASK_TOOL_PATTERN.exec(cleanLine)) !== null) {
1444
1354
  const description = match[2].trim();
1445
1355
  if (description && description.length > 0) {
1446
- const now = Date.now();
1447
- this._recentTaskDescriptions.set(now, description);
1448
- // Cleanup old entries
1449
- this.cleanupOldTaskDescriptions();
1450
- }
1451
- }
1452
- }
1453
- /**
1454
- * Remove task descriptions older than TASK_DESCRIPTION_MAX_AGE_MS.
1455
- * Size limit is handled automatically by LRUMap eviction on set().
1456
- */
1457
- cleanupOldTaskDescriptions() {
1458
- const cutoff = Date.now() - Session.TASK_DESCRIPTION_MAX_AGE_MS;
1459
- // Keys are timestamps - iterate and delete expired entries
1460
- // LRUMap maintains insertion order, so we can break early once we find a non-expired entry
1461
- for (const timestamp of this._recentTaskDescriptions.keysInOrder()) {
1462
- if (timestamp < cutoff) {
1463
- this._recentTaskDescriptions.delete(timestamp);
1464
- }
1465
- else {
1466
- // Keys are ordered by insertion time (which is the timestamp)
1467
- // Once we find a non-expired one, all subsequent are also non-expired
1468
- break;
1356
+ this._taskCache.add(Date.now(), description);
1469
1357
  }
1470
1358
  }
1471
1359
  }
@@ -1474,12 +1362,7 @@ export class Session extends EventEmitter {
1474
1362
  * Returns descriptions sorted by timestamp (most recent first).
1475
1363
  */
1476
1364
  getRecentTaskDescriptions() {
1477
- this.cleanupOldTaskDescriptions();
1478
- const results = [];
1479
- for (const [timestamp, description] of this._recentTaskDescriptions) {
1480
- results.push({ timestamp, description });
1481
- }
1482
- return results.sort((a, b) => b.timestamp - a.timestamp);
1365
+ return this._taskCache.getAll();
1483
1366
  }
1484
1367
  /**
1485
1368
  * Find a task description that was parsed close to a given timestamp.
@@ -1490,18 +1373,7 @@ export class Session extends EventEmitter {
1490
1373
  * @returns The matching description or undefined
1491
1374
  */
1492
1375
  findTaskDescriptionNear(subagentStartTime, maxAgeMs = 10000) {
1493
- this.cleanupOldTaskDescriptions();
1494
- // Find the most recent description that was parsed before or around the subagent start time
1495
- let bestMatch;
1496
- let bestDiff = Infinity;
1497
- for (const [timestamp, description] of this._recentTaskDescriptions) {
1498
- const diff = Math.abs(subagentStartTime - timestamp);
1499
- if (diff < maxAgeMs && diff < bestDiff) {
1500
- bestMatch = { timestamp, description };
1501
- bestDiff = diff;
1502
- }
1503
- }
1504
- return bestMatch?.description;
1376
+ return this._taskCache.findNear(subagentStartTime, maxAgeMs);
1505
1377
  }
1506
1378
  // Parse token count from Claude's status line in interactive mode
1507
1379
  // Matches patterns like "123.4k tokens", "5234 tokens", "1.2M tokens"
@@ -1555,8 +1427,8 @@ export class Session extends EventEmitter {
1555
1427
  this._totalInputTokens += Math.round(delta * 0.6);
1556
1428
  this._totalOutputTokens += Math.round(delta * 0.4);
1557
1429
  // Check if we should auto-compact or auto-clear
1558
- this.checkAutoCompact();
1559
- this.checkAutoClear();
1430
+ this._autoOps.checkAutoCompact();
1431
+ this._autoOps.checkAutoClear();
1560
1432
  }
1561
1433
  }
1562
1434
  }
@@ -1629,108 +1501,7 @@ export class Session extends EventEmitter {
1629
1501
  });
1630
1502
  }
1631
1503
  }
1632
- // Check if we should auto-compact based on token threshold
1633
- checkAutoCompact() {
1634
- if (this._isStopped)
1635
- return; // Early exit check
1636
- if (!this._autoCompactEnabled || this._isCompacting || this._isClearing)
1637
- return;
1638
- const totalTokens = this._totalInputTokens + this._totalOutputTokens;
1639
- if (totalTokens >= this._autoCompactThreshold) {
1640
- this._isCompacting = true;
1641
- console.log(`[Session] Auto-compact triggered: ${totalTokens} tokens >= ${this._autoCompactThreshold} threshold`);
1642
- // Wait for Claude to be idle before compacting
1643
- const checkAndCompact = async () => {
1644
- // Check if session is still valid (not stopped) - must be first check
1645
- if (this._isStopped)
1646
- return;
1647
- if (!this._isCompacting)
1648
- return;
1649
- if (!this._isWorking) {
1650
- // Re-check stopped state after async operation might have completed
1651
- if (this._isStopped)
1652
- return;
1653
- // Send /compact command with optional prompt
1654
- const compactCmd = this._autoCompactPrompt ? `/compact ${this._autoCompactPrompt}\r` : '/compact\r';
1655
- await this.writeViaMux(compactCmd);
1656
- this.emit('autoCompact', {
1657
- tokens: totalTokens,
1658
- threshold: this._autoCompactThreshold,
1659
- prompt: this._autoCompactPrompt || undefined,
1660
- });
1661
- // Wait a moment then re-enable (longer than clear since compact takes time)
1662
- if (!this._isStopped) {
1663
- this._autoCompactTimer = setTimeout(() => {
1664
- if (this._isStopped)
1665
- return; // Check at callback start
1666
- this._autoCompactTimer = null;
1667
- this._isCompacting = false;
1668
- }, 10000);
1669
- }
1670
- }
1671
- else {
1672
- // Check again after delay
1673
- if (!this._isStopped) {
1674
- this._autoCompactTimer = setTimeout(checkAndCompact, AUTO_RETRY_DELAY_MS);
1675
- }
1676
- }
1677
- };
1678
- // Start checking after a short delay
1679
- if (!this._isStopped) {
1680
- this._autoCompactTimer = setTimeout(checkAndCompact, AUTO_INITIAL_DELAY_MS);
1681
- }
1682
- }
1683
- }
1684
- // Check if we should auto-clear based on token threshold
1685
- checkAutoClear() {
1686
- if (this._isStopped)
1687
- return; // Early exit check
1688
- if (!this._autoClearEnabled || this._isClearing || this._isCompacting)
1689
- return;
1690
- const totalTokens = this._totalInputTokens + this._totalOutputTokens;
1691
- if (totalTokens >= this._autoClearThreshold) {
1692
- this._isClearing = true;
1693
- console.log(`[Session] Auto-clear triggered: ${totalTokens} tokens >= ${this._autoClearThreshold} threshold`);
1694
- // Wait for Claude to be idle before clearing
1695
- const checkAndClear = async () => {
1696
- // Check if session is still valid (not stopped) - must be first check
1697
- if (this._isStopped)
1698
- return;
1699
- if (!this._isClearing)
1700
- return;
1701
- if (!this._isWorking) {
1702
- // Re-check stopped state after async operation might have completed
1703
- if (this._isStopped)
1704
- return;
1705
- // Send /clear command
1706
- await this.writeViaMux('/clear\r');
1707
- // Reset token counts
1708
- this._totalInputTokens = 0;
1709
- this._totalOutputTokens = 0;
1710
- this.emit('autoClear', { tokens: totalTokens, threshold: this._autoClearThreshold });
1711
- // Wait a moment then re-enable
1712
- if (!this._isStopped) {
1713
- this._autoClearTimer = setTimeout(() => {
1714
- if (this._isStopped)
1715
- return; // Check at callback start
1716
- this._autoClearTimer = null;
1717
- this._isClearing = false;
1718
- }, 5000);
1719
- }
1720
- }
1721
- else {
1722
- // Check again after delay
1723
- if (!this._isStopped) {
1724
- this._autoClearTimer = setTimeout(checkAndClear, AUTO_RETRY_DELAY_MS);
1725
- }
1726
- }
1727
- };
1728
- // Start checking after a short delay
1729
- if (!this._isStopped) {
1730
- this._autoClearTimer = setTimeout(checkAndClear, AUTO_INITIAL_DELAY_MS);
1731
- }
1732
- }
1733
- }
1504
+ // Note: checkAutoCompact/checkAutoClear moved to SessionAutoOps (this._autoOps)
1734
1505
  /**
1735
1506
  * Sends input directly to the PTY process.
1736
1507
  *
@@ -1885,17 +1656,8 @@ export class Session extends EventEmitter {
1885
1656
  clearTimeout(this._lineBufferFlushTimer);
1886
1657
  this._lineBufferFlushTimer = null;
1887
1658
  }
1888
- // Clear auto-compact/auto-clear timers to prevent memory leaks
1889
- if (this._autoCompactTimer) {
1890
- clearTimeout(this._autoCompactTimer);
1891
- this._autoCompactTimer = null;
1892
- }
1893
- this._isCompacting = false;
1894
- if (this._autoClearTimer) {
1895
- clearTimeout(this._autoClearTimer);
1896
- this._autoClearTimer = null;
1897
- }
1898
- this._isClearing = false;
1659
+ // Destroy auto-compact/auto-clear automation (clears its timers)
1660
+ this._autoOps.destroy();
1899
1661
  // Clear prompt check timers
1900
1662
  if (this._promptCheckInterval) {
1901
1663
  clearInterval(this._promptCheckInterval);
@@ -1968,7 +1730,7 @@ export class Session extends EventEmitter {
1968
1730
  this._status = killMux ? 'stopped' : 'idle';
1969
1731
  this._currentTaskId = null;
1970
1732
  // Clear task description cache and agent tree to prevent memory leak
1971
- this._recentTaskDescriptions.clear();
1733
+ this._taskCache.clear();
1972
1734
  this._childAgentIds = [];
1973
1735
  // Kill the associated mux session if requested
1974
1736
  if (killMux && this._mux) {
@@ -2019,7 +1781,7 @@ export class Session extends EventEmitter {
2019
1781
  this._messages = [];
2020
1782
  this._taskTracker.clear();
2021
1783
  this._ralphTracker.clear();
2022
- this._recentTaskDescriptions.clear();
1784
+ this._taskCache.clear();
2023
1785
  }
2024
1786
  }
2025
1787
  //# sourceMappingURL=session.js.map