@ai-devkit/agent-manager 0.32.0 → 0.33.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 (572) hide show
  1. package/dist/AgentManager.d.ts +13 -4
  2. package/dist/AgentManager.d.ts.map +1 -1
  3. package/dist/AgentManager.js +116 -84
  4. package/dist/AgentManager.js.map +1 -1
  5. package/dist/__tests__/AgentManager.test.js +623 -391
  6. package/dist/__tests__/AgentManager.test.js.map +1 -1
  7. package/dist/__tests__/adapters/ClaudeCodeAdapter.test.js +642 -642
  8. package/dist/__tests__/adapters/ClaudeCodeAdapter.test.js.map +1 -1
  9. package/dist/__tests__/adapters/CodexAdapter.test.js +322 -2321
  10. package/dist/__tests__/adapters/CodexAdapter.test.js.map +1 -1
  11. package/dist/__tests__/adapters/GrokCliAdapter.test.js +114 -114
  12. package/dist/__tests__/adapters/GrokCliAdapter.test.js.map +1 -1
  13. package/dist/__tests__/adapters/OpenCodeAdapter.test.js +170 -169
  14. package/dist/__tests__/adapters/OpenCodeAdapter.test.js.map +1 -1
  15. package/dist/__tests__/capacity/codex.test.js +93 -93
  16. package/dist/__tests__/capacity/codex.test.js.map +1 -1
  17. package/dist/__tests__/capacity/index.test.js +17 -17
  18. package/dist/__tests__/capacity/index.test.js.map +1 -1
  19. package/dist/__tests__/durable/CodexCliProbe.test.js +60 -60
  20. package/dist/__tests__/durable/CodexCliProbe.test.js.map +1 -1
  21. package/dist/__tests__/durable/CodexDurableAgentRepository.test.js +28 -28
  22. package/dist/__tests__/durable/CodexDurableAgentRepository.test.js.map +1 -1
  23. package/dist/__tests__/durable/CodexPrintAgent.integration.test.js +30 -30
  24. package/dist/__tests__/durable/CodexPrintAgent.integration.test.js.map +1 -1
  25. package/dist/__tests__/durable/CodexPrintAgentService.test.js +71 -71
  26. package/dist/__tests__/durable/CodexPrintAgentService.test.js.map +1 -1
  27. package/dist/__tests__/durable/CodexPrintRunner.test.js +125 -125
  28. package/dist/__tests__/durable/CodexPrintRunner.test.js.map +1 -1
  29. package/dist/__tests__/print/ClaudeCliProbe.test.js +20 -20
  30. package/dist/__tests__/print/ClaudeCliProbe.test.js.map +1 -1
  31. package/dist/__tests__/print/ClaudePrintAgent.integration.test.js +20 -20
  32. package/dist/__tests__/print/ClaudePrintAgent.integration.test.js.map +1 -1
  33. package/dist/__tests__/print/ClaudePrintAgentService.test.js +58 -58
  34. package/dist/__tests__/print/ClaudePrintAgentService.test.js.map +1 -1
  35. package/dist/__tests__/print/ClaudePrintRunner.test.js +55 -55
  36. package/dist/__tests__/print/ClaudePrintRunner.test.js.map +1 -1
  37. package/dist/__tests__/print/DurableAgent.test.js +9 -9
  38. package/dist/__tests__/print/DurableAgent.test.js.map +1 -1
  39. package/dist/__tests__/print/DurableAgentRepository.sqlite.test.js +40 -40
  40. package/dist/__tests__/print/DurableAgentRepository.sqlite.test.js.map +1 -1
  41. package/dist/__tests__/print/DurableAgentRepository.test.js +66 -66
  42. package/dist/__tests__/print/DurableAgentRepository.test.js.map +1 -1
  43. package/dist/__tests__/providers/claude/ClaudeAgentMapper.test.js +34 -34
  44. package/dist/__tests__/providers/claude/ClaudeAgentMapper.test.js.map +1 -1
  45. package/dist/__tests__/providers/claude/ClaudeSessionLocator.test.js +132 -132
  46. package/dist/__tests__/providers/claude/ClaudeSessionLocator.test.js.map +1 -1
  47. package/dist/__tests__/providers/codex/CodexSessionLocator.test.js +194 -0
  48. package/dist/__tests__/providers/codex/CodexSessionLocator.test.js.map +1 -0
  49. package/dist/__tests__/providers/codex/CodexSessionMapping.test.js +86 -0
  50. package/dist/__tests__/providers/codex/CodexSessionMapping.test.js.map +1 -0
  51. package/dist/__tests__/providers/codex/CodexSessionParser.test.js +254 -0
  52. package/dist/__tests__/providers/codex/CodexSessionParser.test.js.map +1 -0
  53. package/dist/__tests__/providers/copilot/CopilotAdapter.test.js +641 -0
  54. package/dist/__tests__/providers/copilot/CopilotAdapter.test.js.map +1 -0
  55. package/dist/__tests__/providers/gemini/GeminiCliAdapter.test.js +1398 -0
  56. package/dist/__tests__/providers/gemini/GeminiCliAdapter.test.js.map +1 -0
  57. package/dist/__tests__/providers/pi/PiAdapter.test.js +337 -0
  58. package/dist/__tests__/providers/pi/PiAdapter.test.js.map +1 -0
  59. package/dist/__tests__/providers/pi/PiSessionParser.test.js +246 -0
  60. package/dist/__tests__/providers/pi/PiSessionParser.test.js.map +1 -0
  61. package/dist/__tests__/providers/pi/PiSessionTracker.test.js +108 -0
  62. package/dist/__tests__/providers/pi/PiSessionTracker.test.js.map +1 -0
  63. package/dist/__tests__/providers/pi/durable/PiCliProbe.test.js +33 -33
  64. package/dist/__tests__/providers/pi/durable/PiCliProbe.test.js.map +1 -1
  65. package/dist/__tests__/providers/pi/durable/PiDurableAgentRepository.test.js +16 -16
  66. package/dist/__tests__/providers/pi/durable/PiDurableAgentRepository.test.js.map +1 -1
  67. package/dist/__tests__/providers/pi/durable/PiPrintAgentService.test.js +52 -52
  68. package/dist/__tests__/providers/pi/durable/PiPrintAgentService.test.js.map +1 -1
  69. package/dist/__tests__/providers/pi/durable/PiPrintProtocol.test.js +44 -44
  70. package/dist/__tests__/providers/pi/durable/PiPrintProtocol.test.js.map +1 -1
  71. package/dist/__tests__/providers/pi/durable/PiPrintRunner.test.js +126 -126
  72. package/dist/__tests__/providers/pi/durable/PiPrintRunner.test.js.map +1 -1
  73. package/dist/__tests__/providers/pi/durable/PiStreamParser.test.js +14 -14
  74. package/dist/__tests__/providers/pi/durable/PiStreamParser.test.js.map +1 -1
  75. package/dist/__tests__/readiness/AgentReadiness.test.js +134 -134
  76. package/dist/__tests__/readiness/AgentReadiness.test.js.map +1 -1
  77. package/dist/__tests__/runtime/AgentRuntime.test.js +13 -0
  78. package/dist/__tests__/runtime/AgentRuntime.test.js.map +1 -0
  79. package/dist/__tests__/runtime/HerdrAgentDiscovery.test.js +164 -0
  80. package/dist/__tests__/runtime/HerdrAgentDiscovery.test.js.map +1 -0
  81. package/dist/__tests__/runtime/HerdrAgentRuntime.test.js +488 -0
  82. package/dist/__tests__/runtime/HerdrAgentRuntime.test.js.map +1 -0
  83. package/dist/__tests__/runtime/ManagedAgentRuntime.test.js +588 -0
  84. package/dist/__tests__/runtime/ManagedAgentRuntime.test.js.map +1 -0
  85. package/dist/__tests__/terminal/TerminalFocusManager.test.js +100 -100
  86. package/dist/__tests__/terminal/TerminalFocusManager.test.js.map +1 -1
  87. package/dist/__tests__/terminal/TmuxManager.test.js +101 -101
  88. package/dist/__tests__/terminal/TmuxManager.test.js.map +1 -1
  89. package/dist/__tests__/terminal/TtyWriter.test.js +185 -185
  90. package/dist/__tests__/terminal/TtyWriter.test.js.map +1 -1
  91. package/dist/__tests__/utils/AgentRegistry.test.js +343 -218
  92. package/dist/__tests__/utils/AgentRegistry.test.js.map +1 -1
  93. package/dist/__tests__/utils/ClaudeSessionParser.test.js +103 -101
  94. package/dist/__tests__/utils/ClaudeSessionParser.test.js.map +1 -1
  95. package/dist/__tests__/utils/agent-requests.test.js +43 -43
  96. package/dist/__tests__/utils/agent-requests.test.js.map +1 -1
  97. package/dist/__tests__/utils/agents.test.js +17 -17
  98. package/dist/__tests__/utils/agents.test.js.map +1 -1
  99. package/dist/__tests__/utils/matching.test.js +92 -92
  100. package/dist/__tests__/utils/matching.test.js.map +1 -1
  101. package/dist/__tests__/utils/process.test.js +108 -108
  102. package/dist/__tests__/utils/process.test.js.map +1 -1
  103. package/dist/__tests__/utils/session.test.js +53 -53
  104. package/dist/__tests__/utils/session.test.js.map +1 -1
  105. package/dist/adapters/AgentAdapter.d.ts +2 -2
  106. package/dist/adapters/AgentAdapter.d.ts.map +1 -1
  107. package/dist/adapters/AgentAdapter.js +1 -1
  108. package/dist/adapters/AgentAdapter.js.map +1 -1
  109. package/dist/adapters/GrokCliAdapter.d.ts +1 -1
  110. package/dist/adapters/GrokCliAdapter.d.ts.map +1 -1
  111. package/dist/adapters/GrokCliAdapter.js +80 -80
  112. package/dist/adapters/GrokCliAdapter.js.map +1 -1
  113. package/dist/adapters/OpenCodeAdapter.d.ts +2 -1
  114. package/dist/adapters/OpenCodeAdapter.d.ts.map +1 -1
  115. package/dist/adapters/OpenCodeAdapter.js +41 -37
  116. package/dist/adapters/OpenCodeAdapter.js.map +1 -1
  117. package/dist/adapters/index.d.ts +9 -9
  118. package/dist/adapters/index.d.ts.map +1 -1
  119. package/dist/adapters/index.js +8 -8
  120. package/dist/adapters/index.js.map +1 -1
  121. package/dist/capacity/codex.d.ts +3 -3
  122. package/dist/capacity/codex.d.ts.map +1 -1
  123. package/dist/capacity/codex.js +57 -57
  124. package/dist/capacity/codex.js.map +1 -1
  125. package/dist/capacity/index.d.ts +3 -3
  126. package/dist/capacity/index.d.ts.map +1 -1
  127. package/dist/capacity/index.js +8 -8
  128. package/dist/capacity/index.js.map +1 -1
  129. package/dist/capacity/types.d.ts +1 -1
  130. package/dist/capacity/types.js.map +1 -1
  131. package/dist/database/connection.d.ts +1 -1
  132. package/dist/database/connection.d.ts.map +1 -1
  133. package/dist/database/connection.js +15 -15
  134. package/dist/database/connection.js.map +1 -1
  135. package/dist/database/index.d.ts +3 -3
  136. package/dist/database/index.d.ts.map +1 -1
  137. package/dist/database/index.js +2 -2
  138. package/dist/database/index.js.map +1 -1
  139. package/dist/database/migrations/005_agent_runtime.sql +2 -0
  140. package/dist/database/schema.d.ts +1 -1
  141. package/dist/database/schema.d.ts.map +1 -1
  142. package/dist/database/schema.js +7 -7
  143. package/dist/database/schema.js.map +1 -1
  144. package/dist/durable/DurableAgent.d.ts +9 -9
  145. package/dist/durable/DurableAgent.d.ts.map +1 -1
  146. package/dist/durable/DurableAgent.js +16 -16
  147. package/dist/durable/DurableAgent.js.map +1 -1
  148. package/dist/durable/DurableAgentRepository.d.ts +4 -4
  149. package/dist/durable/DurableAgentRepository.d.ts.map +1 -1
  150. package/dist/durable/DurableAgentRepository.js +49 -48
  151. package/dist/durable/DurableAgentRepository.js.map +1 -1
  152. package/dist/durable/process.d.ts +1 -1
  153. package/dist/durable/process.d.ts.map +1 -1
  154. package/dist/durable/process.js +14 -14
  155. package/dist/durable/process.js.map +1 -1
  156. package/dist/durable/run.d.ts +2 -2
  157. package/dist/durable/run.d.ts.map +1 -1
  158. package/dist/durable/run.js +6 -6
  159. package/dist/durable/run.js.map +1 -1
  160. package/dist/durable/utils.d.ts +1 -1
  161. package/dist/durable/utils.d.ts.map +1 -1
  162. package/dist/durable/utils.js +4 -4
  163. package/dist/durable/utils.js.map +1 -1
  164. package/dist/index.d.ts +48 -43
  165. package/dist/index.d.ts.map +1 -1
  166. package/dist/index.js +28 -26
  167. package/dist/index.js.map +1 -1
  168. package/dist/providers/claude/ClaudeAgentMapper.d.ts +4 -4
  169. package/dist/providers/claude/ClaudeAgentMapper.d.ts.map +1 -1
  170. package/dist/providers/claude/ClaudeAgentMapper.js +10 -10
  171. package/dist/providers/claude/ClaudeAgentMapper.js.map +1 -1
  172. package/dist/providers/claude/ClaudeCodeAdapter.d.ts +1 -1
  173. package/dist/providers/claude/ClaudeCodeAdapter.d.ts.map +1 -1
  174. package/dist/providers/claude/ClaudeCodeAdapter.js +14 -14
  175. package/dist/providers/claude/ClaudeCodeAdapter.js.map +1 -1
  176. package/dist/providers/claude/ClaudeSessionLocator.d.ts +4 -4
  177. package/dist/providers/claude/ClaudeSessionLocator.d.ts.map +1 -1
  178. package/dist/providers/claude/ClaudeSessionLocator.js +79 -79
  179. package/dist/providers/claude/ClaudeSessionLocator.js.map +1 -1
  180. package/dist/providers/claude/ClaudeSessionParser.d.ts +2 -2
  181. package/dist/providers/claude/ClaudeSessionParser.d.ts.map +1 -1
  182. package/dist/providers/claude/ClaudeSessionParser.js +99 -99
  183. package/dist/providers/claude/ClaudeSessionParser.js.map +1 -1
  184. package/dist/providers/claude/durable/ClaudeCliProbe.d.ts.map +1 -1
  185. package/dist/providers/claude/durable/ClaudeCliProbe.js +16 -16
  186. package/dist/providers/claude/durable/ClaudeCliProbe.js.map +1 -1
  187. package/dist/providers/claude/durable/ClaudePrintAgentService.d.ts +5 -5
  188. package/dist/providers/claude/durable/ClaudePrintAgentService.d.ts.map +1 -1
  189. package/dist/providers/claude/durable/ClaudePrintAgentService.js +10 -10
  190. package/dist/providers/claude/durable/ClaudePrintAgentService.js.map +1 -1
  191. package/dist/providers/claude/durable/ClaudePrintRunner.d.ts +4 -4
  192. package/dist/providers/claude/durable/ClaudePrintRunner.d.ts.map +1 -1
  193. package/dist/providers/claude/durable/ClaudePrintRunner.js +18 -18
  194. package/dist/providers/claude/durable/ClaudePrintRunner.js.map +1 -1
  195. package/dist/providers/claude/durable/ClaudeStreamParser.d.ts +2 -2
  196. package/dist/providers/claude/durable/ClaudeStreamParser.d.ts.map +1 -1
  197. package/dist/providers/claude/durable/ClaudeStreamParser.js +17 -17
  198. package/dist/providers/claude/durable/ClaudeStreamParser.js.map +1 -1
  199. package/dist/providers/codex/CodexAdapter.d.ts +27 -0
  200. package/dist/providers/codex/CodexAdapter.d.ts.map +1 -0
  201. package/dist/providers/codex/CodexAdapter.js +162 -0
  202. package/dist/providers/codex/CodexAdapter.js.map +1 -0
  203. package/dist/providers/codex/CodexAgentMapper.d.ts +9 -0
  204. package/dist/providers/codex/CodexAgentMapper.d.ts.map +1 -0
  205. package/dist/providers/codex/CodexAgentMapper.js +35 -0
  206. package/dist/providers/codex/CodexAgentMapper.js.map +1 -0
  207. package/dist/providers/codex/CodexSessionLocator.d.ts +44 -0
  208. package/dist/providers/codex/CodexSessionLocator.d.ts.map +1 -0
  209. package/dist/providers/codex/CodexSessionLocator.js +207 -0
  210. package/dist/providers/codex/CodexSessionLocator.js.map +1 -0
  211. package/dist/providers/codex/CodexSessionMapping.d.ts +23 -0
  212. package/dist/providers/codex/CodexSessionMapping.d.ts.map +1 -0
  213. package/dist/providers/codex/CodexSessionMapping.js +68 -0
  214. package/dist/providers/codex/CodexSessionMapping.js.map +1 -0
  215. package/dist/providers/codex/CodexSessionParser.d.ts +58 -0
  216. package/dist/providers/codex/CodexSessionParser.d.ts.map +1 -0
  217. package/dist/providers/codex/CodexSessionParser.js +262 -0
  218. package/dist/providers/codex/CodexSessionParser.js.map +1 -0
  219. package/dist/providers/codex/durable/CodexCliProbe.d.ts.map +1 -1
  220. package/dist/providers/codex/durable/CodexCliProbe.js +22 -22
  221. package/dist/providers/codex/durable/CodexCliProbe.js.map +1 -1
  222. package/dist/providers/codex/durable/CodexPrintAgentService.d.ts +6 -6
  223. package/dist/providers/codex/durable/CodexPrintAgentService.d.ts.map +1 -1
  224. package/dist/providers/codex/durable/CodexPrintAgentService.js +10 -10
  225. package/dist/providers/codex/durable/CodexPrintAgentService.js.map +1 -1
  226. package/dist/providers/codex/durable/CodexPrintRunner.d.ts +4 -4
  227. package/dist/providers/codex/durable/CodexPrintRunner.d.ts.map +1 -1
  228. package/dist/providers/codex/durable/CodexPrintRunner.js +20 -20
  229. package/dist/providers/codex/durable/CodexPrintRunner.js.map +1 -1
  230. package/dist/providers/codex/durable/CodexStreamParser.d.ts +2 -2
  231. package/dist/providers/codex/durable/CodexStreamParser.d.ts.map +1 -1
  232. package/dist/providers/codex/durable/CodexStreamParser.js +21 -21
  233. package/dist/providers/codex/durable/CodexStreamParser.js.map +1 -1
  234. package/dist/{adapters → providers/copilot}/CopilotAdapter.d.ts +11 -25
  235. package/dist/providers/copilot/CopilotAdapter.d.ts.map +1 -0
  236. package/dist/providers/copilot/CopilotAdapter.js +108 -0
  237. package/dist/providers/copilot/CopilotAdapter.js.map +1 -0
  238. package/dist/providers/copilot/CopilotAgentMapper.d.ts +9 -0
  239. package/dist/providers/copilot/CopilotAgentMapper.d.ts.map +1 -0
  240. package/dist/providers/copilot/CopilotAgentMapper.js +37 -0
  241. package/dist/providers/copilot/CopilotAgentMapper.js.map +1 -0
  242. package/dist/providers/copilot/CopilotSessionLocator.d.ts +19 -0
  243. package/dist/providers/copilot/CopilotSessionLocator.d.ts.map +1 -0
  244. package/dist/providers/copilot/CopilotSessionLocator.js +41 -0
  245. package/dist/providers/copilot/CopilotSessionLocator.js.map +1 -0
  246. package/dist/providers/copilot/CopilotSessionParser.d.ts +30 -0
  247. package/dist/providers/copilot/CopilotSessionParser.d.ts.map +1 -0
  248. package/dist/providers/copilot/CopilotSessionParser.js +181 -0
  249. package/dist/providers/copilot/CopilotSessionParser.js.map +1 -0
  250. package/dist/providers/gemini/GeminiAgentMapper.d.ts +9 -0
  251. package/dist/providers/gemini/GeminiAgentMapper.d.ts.map +1 -0
  252. package/dist/providers/gemini/GeminiAgentMapper.js +37 -0
  253. package/dist/providers/gemini/GeminiAgentMapper.js.map +1 -0
  254. package/dist/providers/gemini/GeminiCliAdapter.d.ts +52 -0
  255. package/dist/providers/gemini/GeminiCliAdapter.d.ts.map +1 -0
  256. package/dist/providers/gemini/GeminiCliAdapter.js +188 -0
  257. package/dist/providers/gemini/GeminiCliAdapter.js.map +1 -0
  258. package/dist/providers/gemini/GeminiSessionLocator.d.ts +30 -0
  259. package/dist/providers/gemini/GeminiSessionLocator.d.ts.map +1 -0
  260. package/dist/providers/gemini/GeminiSessionLocator.js +142 -0
  261. package/dist/providers/gemini/GeminiSessionLocator.js.map +1 -0
  262. package/dist/providers/gemini/GeminiSessionParser.d.ts +94 -0
  263. package/dist/providers/gemini/GeminiSessionParser.d.ts.map +1 -0
  264. package/dist/providers/gemini/GeminiSessionParser.js +166 -0
  265. package/dist/providers/gemini/GeminiSessionParser.js.map +1 -0
  266. package/dist/providers/pi/PiAdapter.d.ts +28 -0
  267. package/dist/providers/pi/PiAdapter.d.ts.map +1 -0
  268. package/dist/providers/pi/PiAdapter.js +153 -0
  269. package/dist/providers/pi/PiAdapter.js.map +1 -0
  270. package/dist/providers/pi/PiAgentMapper.d.ts +9 -0
  271. package/dist/providers/pi/PiAgentMapper.d.ts.map +1 -0
  272. package/dist/providers/pi/PiAgentMapper.js +37 -0
  273. package/dist/providers/pi/PiAgentMapper.js.map +1 -0
  274. package/dist/providers/pi/PiSessionLocator.d.ts +23 -0
  275. package/dist/providers/pi/PiSessionLocator.d.ts.map +1 -0
  276. package/dist/providers/pi/PiSessionLocator.js +79 -0
  277. package/dist/providers/pi/PiSessionLocator.js.map +1 -0
  278. package/dist/providers/pi/PiSessionParser.d.ts +36 -0
  279. package/dist/providers/pi/PiSessionParser.d.ts.map +1 -0
  280. package/dist/providers/pi/PiSessionParser.js +191 -0
  281. package/dist/providers/pi/PiSessionParser.js.map +1 -0
  282. package/dist/providers/pi/PiSessionTracker.d.ts +23 -0
  283. package/dist/providers/pi/PiSessionTracker.d.ts.map +1 -0
  284. package/dist/providers/pi/PiSessionTracker.js +69 -0
  285. package/dist/providers/pi/PiSessionTracker.js.map +1 -0
  286. package/dist/providers/pi/durable/PiCliProbe.d.ts.map +1 -1
  287. package/dist/providers/pi/durable/PiCliProbe.js +15 -15
  288. package/dist/providers/pi/durable/PiCliProbe.js.map +1 -1
  289. package/dist/providers/pi/durable/PiPrintAgentService.d.ts +6 -6
  290. package/dist/providers/pi/durable/PiPrintAgentService.d.ts.map +1 -1
  291. package/dist/providers/pi/durable/PiPrintAgentService.js +10 -10
  292. package/dist/providers/pi/durable/PiPrintAgentService.js.map +1 -1
  293. package/dist/providers/pi/durable/PiPrintProtocol.d.ts.map +1 -1
  294. package/dist/providers/pi/durable/PiPrintProtocol.js +18 -18
  295. package/dist/providers/pi/durable/PiPrintProtocol.js.map +1 -1
  296. package/dist/providers/pi/durable/PiPrintRunner.d.ts +4 -4
  297. package/dist/providers/pi/durable/PiPrintRunner.d.ts.map +1 -1
  298. package/dist/providers/pi/durable/PiPrintRunner.js +15 -15
  299. package/dist/providers/pi/durable/PiPrintRunner.js.map +1 -1
  300. package/dist/providers/pi/durable/PiStreamParser.d.ts +1 -1
  301. package/dist/providers/pi/durable/PiStreamParser.d.ts.map +1 -1
  302. package/dist/providers/pi/durable/PiStreamParser.js +16 -16
  303. package/dist/providers/pi/durable/PiStreamParser.js.map +1 -1
  304. package/dist/readiness/AgentReadiness.d.ts +6 -6
  305. package/dist/readiness/AgentReadiness.d.ts.map +1 -1
  306. package/dist/readiness/AgentReadiness.js +130 -130
  307. package/dist/readiness/AgentReadiness.js.map +1 -1
  308. package/dist/runtime/ManagedAgentRuntime.d.ts +69 -0
  309. package/dist/runtime/ManagedAgentRuntime.d.ts.map +1 -0
  310. package/dist/runtime/ManagedAgentRuntime.js +156 -0
  311. package/dist/runtime/ManagedAgentRuntime.js.map +1 -0
  312. package/dist/runtime/RuntimeFactory.d.ts +4 -0
  313. package/dist/runtime/RuntimeFactory.d.ts.map +1 -0
  314. package/dist/runtime/RuntimeFactory.js +11 -0
  315. package/dist/runtime/RuntimeFactory.js.map +1 -0
  316. package/dist/runtime/errors.d.ts +27 -0
  317. package/dist/runtime/errors.d.ts.map +1 -0
  318. package/dist/runtime/errors.js +42 -0
  319. package/dist/runtime/errors.js.map +1 -0
  320. package/dist/runtime/herdr/HerdrAgentDiscovery.d.ts +18 -0
  321. package/dist/runtime/herdr/HerdrAgentDiscovery.d.ts.map +1 -0
  322. package/dist/runtime/herdr/HerdrAgentDiscovery.js +183 -0
  323. package/dist/runtime/herdr/HerdrAgentDiscovery.js.map +1 -0
  324. package/dist/runtime/herdr/HerdrAgentRuntime.d.ts +36 -0
  325. package/dist/runtime/herdr/HerdrAgentRuntime.d.ts.map +1 -0
  326. package/dist/runtime/herdr/HerdrAgentRuntime.js +202 -0
  327. package/dist/runtime/herdr/HerdrAgentRuntime.js.map +1 -0
  328. package/dist/runtime/herdr/HerdrCliClient.d.ts +13 -0
  329. package/dist/runtime/herdr/HerdrCliClient.d.ts.map +1 -0
  330. package/dist/runtime/herdr/HerdrCliClient.js +60 -0
  331. package/dist/runtime/herdr/HerdrCliClient.js.map +1 -0
  332. package/dist/runtime/herdr/HerdrErrors.d.ts +7 -0
  333. package/dist/runtime/herdr/HerdrErrors.d.ts.map +1 -0
  334. package/dist/runtime/herdr/HerdrErrors.js +10 -0
  335. package/dist/runtime/herdr/HerdrErrors.js.map +1 -0
  336. package/dist/runtime/herdr/HerdrResponseParsers.d.ts +16 -0
  337. package/dist/runtime/herdr/HerdrResponseParsers.d.ts.map +1 -0
  338. package/dist/runtime/herdr/HerdrResponseParsers.js +107 -0
  339. package/dist/runtime/herdr/HerdrResponseParsers.js.map +1 -0
  340. package/dist/runtime/herdr/HerdrRuntimeRef.d.ts +9 -0
  341. package/dist/runtime/herdr/HerdrRuntimeRef.d.ts.map +1 -0
  342. package/dist/runtime/herdr/HerdrRuntimeRef.js +33 -0
  343. package/dist/runtime/herdr/HerdrRuntimeRef.js.map +1 -0
  344. package/dist/runtime/tmux/PidPolling.d.ts +5 -0
  345. package/dist/runtime/tmux/PidPolling.d.ts.map +1 -0
  346. package/dist/runtime/tmux/PidPolling.js +24 -0
  347. package/dist/runtime/tmux/PidPolling.js.map +1 -0
  348. package/dist/runtime/tmux/TmuxAgentRuntime.d.ts +17 -0
  349. package/dist/runtime/tmux/TmuxAgentRuntime.d.ts.map +1 -0
  350. package/dist/runtime/tmux/TmuxAgentRuntime.js +80 -0
  351. package/dist/runtime/tmux/TmuxAgentRuntime.js.map +1 -0
  352. package/dist/runtime/tmux/TmuxRuntimeRef.d.ts +5 -0
  353. package/dist/runtime/tmux/TmuxRuntimeRef.d.ts.map +1 -0
  354. package/dist/runtime/tmux/TmuxRuntimeRef.js +9 -0
  355. package/dist/runtime/tmux/TmuxRuntimeRef.js.map +1 -0
  356. package/dist/runtime/types.d.ts +54 -0
  357. package/dist/runtime/types.d.ts.map +1 -0
  358. package/dist/runtime/types.js +3 -0
  359. package/dist/runtime/types.js.map +1 -0
  360. package/dist/terminal/TerminalFocusManager.d.ts.map +1 -1
  361. package/dist/terminal/TerminalFocusManager.js +50 -50
  362. package/dist/terminal/TerminalFocusManager.js.map +1 -1
  363. package/dist/terminal/TmuxManager.d.ts.map +1 -1
  364. package/dist/terminal/TmuxManager.js +47 -47
  365. package/dist/terminal/TmuxManager.js.map +1 -1
  366. package/dist/terminal/TtyWriter.d.ts +1 -1
  367. package/dist/terminal/TtyWriter.d.ts.map +1 -1
  368. package/dist/terminal/TtyWriter.js +89 -89
  369. package/dist/terminal/TtyWriter.js.map +1 -1
  370. package/dist/terminal/index.d.ts +4 -4
  371. package/dist/terminal/index.js +3 -3
  372. package/dist/terminal/index.js.map +1 -1
  373. package/dist/utils/AgentRegistry.d.ts +10 -2
  374. package/dist/utils/AgentRegistry.d.ts.map +1 -1
  375. package/dist/utils/AgentRegistry.js +59 -26
  376. package/dist/utils/AgentRegistry.js.map +1 -1
  377. package/dist/utils/agent-requests.d.ts.map +1 -1
  378. package/dist/utils/agent-requests.js +5 -5
  379. package/dist/utils/agent-requests.js.map +1 -1
  380. package/dist/utils/agents.d.ts +2 -2
  381. package/dist/utils/agents.d.ts.map +1 -1
  382. package/dist/utils/agents.js +15 -15
  383. package/dist/utils/agents.js.map +1 -1
  384. package/dist/utils/applescript.js +1 -1
  385. package/dist/utils/applescript.js.map +1 -1
  386. package/dist/utils/index.d.ts +6 -6
  387. package/dist/utils/index.d.ts.map +1 -1
  388. package/dist/utils/index.js +4 -4
  389. package/dist/utils/index.js.map +1 -1
  390. package/dist/utils/matching.d.ts +2 -2
  391. package/dist/utils/matching.d.ts.map +1 -1
  392. package/dist/utils/matching.js +4 -4
  393. package/dist/utils/matching.js.map +1 -1
  394. package/dist/utils/process.d.ts +1 -1
  395. package/dist/utils/process.d.ts.map +1 -1
  396. package/dist/utils/process.js +74 -74
  397. package/dist/utils/process.js.map +1 -1
  398. package/dist/utils/session.d.ts +1 -1
  399. package/dist/utils/session.d.ts.map +1 -1
  400. package/dist/utils/session.js +7 -7
  401. package/dist/utils/session.js.map +1 -1
  402. package/dist/utils/sortAgents.d.ts +2 -2
  403. package/dist/utils/sortAgents.d.ts.map +1 -1
  404. package/dist/utils/sortAgents.js +5 -5
  405. package/dist/utils/sortAgents.js.map +1 -1
  406. package/package.json +18 -19
  407. package/src/AgentManager.ts +338 -274
  408. package/src/__tests__/AgentManager.test.ts +1143 -907
  409. package/src/__tests__/adapters/ClaudeCodeAdapter.test.ts +1657 -1368
  410. package/src/__tests__/adapters/CodexAdapter.test.ts +365 -1698
  411. package/src/__tests__/adapters/GrokCliAdapter.test.ts +325 -272
  412. package/src/__tests__/adapters/OpenCodeAdapter.test.ts +511 -455
  413. package/src/__tests__/capacity/codex.test.ts +178 -91
  414. package/src/__tests__/capacity/index.test.ts +27 -18
  415. package/src/__tests__/durable/CodexCliProbe.test.ts +75 -53
  416. package/src/__tests__/durable/CodexDurableAgentRepository.test.ts +51 -40
  417. package/src/__tests__/durable/CodexPrintAgent.integration.test.ts +89 -64
  418. package/src/__tests__/durable/CodexPrintAgentService.test.ts +196 -118
  419. package/src/__tests__/durable/CodexPrintRunner.test.ts +282 -162
  420. package/src/__tests__/fixtures/fake-claude.cjs +20 -13
  421. package/src/__tests__/fixtures/fake-codex.cjs +41 -30
  422. package/src/__tests__/print/ClaudeCliProbe.test.ts +27 -21
  423. package/src/__tests__/print/ClaudePrintAgent.integration.test.ts +48 -40
  424. package/src/__tests__/print/ClaudePrintAgentService.test.ts +118 -67
  425. package/src/__tests__/print/ClaudePrintRunner.test.ts +136 -83
  426. package/src/__tests__/print/DurableAgent.test.ts +19 -16
  427. package/src/__tests__/print/DurableAgentRepository.sqlite.test.ts +109 -86
  428. package/src/__tests__/print/DurableAgentRepository.test.ts +170 -137
  429. package/src/__tests__/providers/claude/ClaudeAgentMapper.test.ts +65 -65
  430. package/src/__tests__/providers/claude/ClaudeSessionLocator.test.ts +400 -377
  431. package/src/__tests__/providers/codex/CodexSessionLocator.test.ts +182 -0
  432. package/src/__tests__/providers/codex/CodexSessionMapping.test.ts +63 -0
  433. package/src/__tests__/providers/codex/CodexSessionParser.test.ts +192 -0
  434. package/src/__tests__/providers/copilot/CopilotAdapter.test.ts +602 -0
  435. package/src/__tests__/providers/gemini/GeminiCliAdapter.test.ts +1299 -0
  436. package/src/__tests__/providers/pi/PiAdapter.test.ts +310 -0
  437. package/src/__tests__/providers/pi/PiSessionParser.test.ts +190 -0
  438. package/src/__tests__/providers/pi/PiSessionTracker.test.ts +79 -0
  439. package/src/__tests__/providers/pi/durable/PiCliProbe.test.ts +48 -32
  440. package/src/__tests__/providers/pi/durable/PiDurableAgentRepository.test.ts +24 -23
  441. package/src/__tests__/providers/pi/durable/PiPrintAgentService.test.ts +131 -59
  442. package/src/__tests__/providers/pi/durable/PiPrintProtocol.test.ts +66 -28
  443. package/src/__tests__/providers/pi/durable/PiPrintRunner.test.ts +236 -90
  444. package/src/__tests__/providers/pi/durable/PiStreamParser.test.ts +20 -18
  445. package/src/__tests__/readiness/AgentReadiness.test.ts +217 -169
  446. package/src/__tests__/runtime/AgentRuntime.test.ts +8 -0
  447. package/src/__tests__/runtime/HerdrAgentDiscovery.test.ts +131 -0
  448. package/src/__tests__/runtime/HerdrAgentRuntime.test.ts +377 -0
  449. package/src/__tests__/runtime/ManagedAgentRuntime.test.ts +555 -0
  450. package/src/__tests__/terminal/TerminalFocusManager.test.ts +254 -253
  451. package/src/__tests__/terminal/TmuxManager.test.ts +157 -157
  452. package/src/__tests__/terminal/TtyWriter.test.ts +423 -419
  453. package/src/__tests__/utils/AgentRegistry.test.ts +516 -402
  454. package/src/__tests__/utils/ClaudeSessionParser.test.ts +276 -242
  455. package/src/__tests__/utils/agent-requests.test.ts +76 -56
  456. package/src/__tests__/utils/agents.test.ts +20 -20
  457. package/src/__tests__/utils/matching.test.ts +206 -171
  458. package/src/__tests__/utils/process.test.ts +276 -262
  459. package/src/__tests__/utils/session.test.ts +133 -139
  460. package/src/adapters/AgentAdapter.ts +134 -126
  461. package/src/adapters/GrokCliAdapter.ts +353 -342
  462. package/src/adapters/OpenCodeAdapter.ts +289 -259
  463. package/src/adapters/index.ts +15 -9
  464. package/src/capacity/codex.ts +137 -84
  465. package/src/capacity/index.ts +18 -13
  466. package/src/capacity/types.ts +1 -1
  467. package/src/database/connection.ts +73 -68
  468. package/src/database/index.ts +6 -6
  469. package/src/database/migrations/005_agent_runtime.sql +2 -0
  470. package/src/database/schema.ts +40 -38
  471. package/src/durable/DurableAgent.ts +85 -85
  472. package/src/durable/DurableAgentRepository.ts +409 -260
  473. package/src/durable/process.ts +22 -21
  474. package/src/durable/run.ts +61 -51
  475. package/src/durable/utils.ts +46 -41
  476. package/src/index.ts +151 -103
  477. package/src/providers/claude/ClaudeAgentMapper.ts +51 -50
  478. package/src/providers/claude/ClaudeCodeAdapter.ts +144 -136
  479. package/src/providers/claude/ClaudeSessionLocator.ts +291 -293
  480. package/src/providers/claude/ClaudeSessionParser.ts +322 -338
  481. package/src/providers/claude/durable/ClaudeCliProbe.ts +42 -37
  482. package/src/providers/claude/durable/ClaudePrintAgentService.ts +63 -50
  483. package/src/providers/claude/durable/ClaudePrintRunner.ts +79 -69
  484. package/src/providers/claude/durable/ClaudeStreamParser.ts +91 -62
  485. package/src/providers/codex/CodexAdapter.ts +205 -0
  486. package/src/providers/codex/CodexAgentMapper.ts +35 -0
  487. package/src/providers/codex/CodexSessionLocator.ts +279 -0
  488. package/src/providers/codex/CodexSessionMapping.ts +89 -0
  489. package/src/providers/codex/CodexSessionParser.ts +385 -0
  490. package/src/providers/codex/durable/CodexCliProbe.ts +50 -42
  491. package/src/providers/codex/durable/CodexPrintAgentService.ts +63 -49
  492. package/src/providers/codex/durable/CodexPrintRunner.ts +79 -69
  493. package/src/providers/codex/durable/CodexStreamParser.ts +97 -84
  494. package/src/providers/copilot/CopilotAdapter.ts +145 -0
  495. package/src/providers/copilot/CopilotAgentMapper.ts +36 -0
  496. package/src/providers/copilot/CopilotSessionLocator.ts +57 -0
  497. package/src/providers/copilot/CopilotSessionParser.ts +289 -0
  498. package/src/providers/gemini/GeminiAgentMapper.ts +36 -0
  499. package/src/providers/gemini/GeminiCliAdapter.ts +266 -0
  500. package/src/providers/gemini/GeminiSessionLocator.ts +183 -0
  501. package/src/providers/gemini/GeminiSessionParser.ts +271 -0
  502. package/src/providers/pi/PiAdapter.ts +183 -0
  503. package/src/providers/pi/PiAgentMapper.ts +36 -0
  504. package/src/providers/pi/PiSessionLocator.ts +95 -0
  505. package/src/providers/pi/PiSessionParser.ts +284 -0
  506. package/src/providers/pi/PiSessionTracker.ts +87 -0
  507. package/src/providers/pi/durable/PiCliProbe.ts +42 -34
  508. package/src/providers/pi/durable/PiPrintAgentService.ts +61 -53
  509. package/src/providers/pi/durable/PiPrintProtocol.ts +31 -29
  510. package/src/providers/pi/durable/PiPrintRunner.ts +75 -68
  511. package/src/providers/pi/durable/PiStreamParser.ts +82 -72
  512. package/src/readiness/AgentReadiness.ts +585 -513
  513. package/src/runtime/ManagedAgentRuntime.ts +266 -0
  514. package/src/runtime/RuntimeFactory.ts +13 -0
  515. package/src/runtime/errors.ts +50 -0
  516. package/src/runtime/herdr/HerdrAgentDiscovery.ts +178 -0
  517. package/src/runtime/herdr/HerdrAgentRuntime.ts +216 -0
  518. package/src/runtime/herdr/HerdrCliClient.ts +78 -0
  519. package/src/runtime/herdr/HerdrErrors.ts +9 -0
  520. package/src/runtime/herdr/HerdrResponseParsers.ts +86 -0
  521. package/src/runtime/herdr/HerdrRuntimeRef.ts +41 -0
  522. package/src/runtime/tmux/PidPolling.ts +34 -0
  523. package/src/runtime/tmux/TmuxAgentRuntime.ts +113 -0
  524. package/src/runtime/tmux/TmuxRuntimeRef.ts +9 -0
  525. package/src/runtime/types.ts +56 -0
  526. package/src/terminal/TerminalFocusManager.ts +215 -212
  527. package/src/terminal/TmuxManager.ts +99 -92
  528. package/src/terminal/TtyWriter.ts +203 -194
  529. package/src/terminal/index.ts +4 -4
  530. package/src/utils/AgentRegistry.ts +301 -238
  531. package/src/utils/agent-requests.ts +16 -16
  532. package/src/utils/agents.ts +41 -38
  533. package/src/utils/applescript.ts +4 -4
  534. package/src/utils/index.ts +12 -6
  535. package/src/utils/matching.ts +43 -43
  536. package/src/utils/process.ts +261 -258
  537. package/src/utils/session.ts +66 -66
  538. package/src/utils/sortAgents.ts +35 -33
  539. package/tsconfig.json +2 -8
  540. package/vitest.config.ts +16 -16
  541. package/.eslintrc.json +0 -31
  542. package/dist/__tests__/adapters/CopilotAdapter.test.js +0 -630
  543. package/dist/__tests__/adapters/CopilotAdapter.test.js.map +0 -1
  544. package/dist/__tests__/adapters/GeminiCliAdapter.test.js +0 -1384
  545. package/dist/__tests__/adapters/GeminiCliAdapter.test.js.map +0 -1
  546. package/dist/__tests__/adapters/PiAdapter.test.js +0 -618
  547. package/dist/__tests__/adapters/PiAdapter.test.js.map +0 -1
  548. package/dist/__tests__/database/DurableAgentsDatabase.test.js +0 -128
  549. package/dist/__tests__/database/DurableAgentsDatabase.test.js.map +0 -1
  550. package/dist/adapters/CodexAdapter.d.ts +0 -109
  551. package/dist/adapters/CodexAdapter.d.ts.map +0 -1
  552. package/dist/adapters/CodexAdapter.js +0 -710
  553. package/dist/adapters/CodexAdapter.js.map +0 -1
  554. package/dist/adapters/CopilotAdapter.d.ts.map +0 -1
  555. package/dist/adapters/CopilotAdapter.js +0 -329
  556. package/dist/adapters/CopilotAdapter.js.map +0 -1
  557. package/dist/adapters/GeminiCliAdapter.d.ts +0 -98
  558. package/dist/adapters/GeminiCliAdapter.d.ts.map +0 -1
  559. package/dist/adapters/GeminiCliAdapter.js +0 -513
  560. package/dist/adapters/GeminiCliAdapter.js.map +0 -1
  561. package/dist/adapters/PiAdapter.d.ts +0 -63
  562. package/dist/adapters/PiAdapter.d.ts.map +0 -1
  563. package/dist/adapters/PiAdapter.js +0 -453
  564. package/dist/adapters/PiAdapter.js.map +0 -1
  565. package/src/__tests__/adapters/CopilotAdapter.test.ts +0 -510
  566. package/src/__tests__/adapters/GeminiCliAdapter.test.ts +0 -1259
  567. package/src/__tests__/adapters/PiAdapter.test.ts +0 -458
  568. package/src/__tests__/database/DurableAgentsDatabase.test.ts +0 -102
  569. package/src/adapters/CodexAdapter.ts +0 -923
  570. package/src/adapters/CopilotAdapter.ts +0 -473
  571. package/src/adapters/GeminiCliAdapter.ts +0 -701
  572. package/src/adapters/PiAdapter.ts +0 -598
@@ -1,20 +1,20 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
3
- import type { ConversationMessage } from '../../adapters/AgentAdapter.js';
4
- import { AgentStatus } from '../../adapters/AgentAdapter.js';
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import type { ConversationMessage } from "../../adapters/AgentAdapter.js";
4
+ import { AgentStatus } from "../../adapters/AgentAdapter.js";
5
5
 
6
6
  /**
7
7
  * Content block within a Claude Code JSONL message entry.
8
8
  * Handles text, tool_use, and tool_result block types.
9
9
  */
10
10
  export interface ContentBlock {
11
- type?: string;
12
- text?: string;
13
- content?: string;
14
- name?: string;
15
- input?: Record<string, unknown>;
16
- tool_use_id?: string;
17
- is_error?: boolean;
11
+ type?: string;
12
+ text?: string;
13
+ content?: string;
14
+ name?: string;
15
+ input?: Record<string, unknown>;
16
+ tool_use_id?: string;
17
+ is_error?: boolean;
18
18
  }
19
19
 
20
20
  /**
@@ -26,12 +26,12 @@ export interface ContentBlock {
26
26
  * - "last-prompt" / "file-history-snapshot" — metadata (not conversation state)
27
27
  */
28
28
  export interface SessionEntry {
29
- type?: string;
30
- timestamp?: string;
31
- cwd?: string;
32
- message?: {
33
- content?: string | ContentBlock[];
34
- };
29
+ type?: string;
30
+ timestamp?: string;
31
+ cwd?: string;
32
+ message?: {
33
+ content?: string | ContentBlock[];
34
+ };
35
35
  }
36
36
 
37
37
  /**
@@ -39,16 +39,16 @@ export interface SessionEntry {
39
39
  * Aggregates data from all entries into a single summary.
40
40
  */
41
41
  export interface ClaudeSession {
42
- sessionId: string;
43
- projectPath: string;
44
- lastCwd?: string;
45
- sessionStart: Date;
46
- lastActive: Date;
47
- lastEntryType?: string;
48
- isInterrupted: boolean;
49
- lastUserMessage?: string;
50
- /** First meaningful user prompt in the session (post noise filter) */
51
- firstUserMessage?: string;
42
+ sessionId: string;
43
+ projectPath: string;
44
+ lastCwd?: string;
45
+ sessionStart: Date;
46
+ lastActive: Date;
47
+ lastEntryType?: string;
48
+ isInterrupted: boolean;
49
+ lastUserMessage?: string;
50
+ /** First meaningful user prompt in the session (post noise filter) */
51
+ firstUserMessage?: string;
52
52
  }
53
53
 
54
54
  /**
@@ -61,13 +61,7 @@ export interface ClaudeSession {
61
61
  * last conversation turn — otherwise polling between writes lands on a
62
62
  * UI-state entry and `determineStatus` falls through to UNKNOWN.
63
63
  */
64
- const CONVERSATION_ENTRY_TYPES = new Set([
65
- 'user',
66
- 'assistant',
67
- 'system',
68
- 'progress',
69
- 'thinking',
70
- ]);
64
+ const CONVERSATION_ENTRY_TYPES = new Set(["user", "assistant", "system", "progress", "thinking"]);
71
65
 
72
66
  /**
73
67
  * Parses Claude Code session JSONL files into structured data.
@@ -77,314 +71,307 @@ const CONVERSATION_ENTRY_TYPES = new Set([
77
71
  * event (user turn, assistant response, tool call, etc.).
78
72
  */
79
73
  export class ClaudeSessionParser {
80
- /**
81
- * Parse a session JSONL file into a ClaudeSession summary.
82
- *
83
- * Iterates all lines to extract: session start time (from first entry),
84
- * last activity timestamp, last entry type (for status), whether the
85
- * session was interrupted, and the last meaningful user message.
86
- *
87
- * Returns null if the file is unreadable or empty.
88
- */
89
- readSession(filePath: string, projectPath: string): ClaudeSession | null {
90
- const sessionId = path.basename(filePath, '.jsonl');
91
-
92
- let content: string;
93
- try {
94
- content = fs.readFileSync(filePath, 'utf-8');
95
- } catch {
96
- return null;
97
- }
98
-
99
- const allLines = content.trim().split('\n');
100
- if (allLines.length === 0) {
101
- return null;
102
- }
103
-
104
- const sessionStart = this.parseSessionStart(allLines[0]);
105
-
106
- let lastEntryType: string | undefined;
107
- let lastActive: Date | undefined;
108
- let lastCwd: string | undefined;
109
- let isInterrupted = false;
110
- let lastUserMessage: string | undefined;
111
- let firstUserMessage: string | undefined;
112
-
113
- for (const line of allLines) {
114
- try {
115
- const entry: SessionEntry = JSON.parse(line);
116
-
117
- if (entry.timestamp) {
118
- const ts = new Date(entry.timestamp);
119
- if (!Number.isNaN(ts.getTime())) {
120
- lastActive = ts;
121
- }
122
- }
123
-
124
- if (typeof entry.cwd === 'string' && entry.cwd.trim().length > 0) {
125
- lastCwd = entry.cwd;
126
- }
127
-
128
- if (entry.type && CONVERSATION_ENTRY_TYPES.has(entry.type)) {
129
- lastEntryType = entry.type;
130
-
131
- if (entry.type === 'user') {
132
- const msgContent = entry.message?.content;
133
- isInterrupted =
134
- Array.isArray(msgContent) &&
135
- msgContent.some(
136
- (c) =>
137
- (c.type === 'text' &&
138
- c.text?.includes('[Request interrupted')) ||
139
- (c.type === 'tool_result' &&
140
- c.content?.includes('[Request interrupted')),
141
- );
142
-
143
- const text = this.extractUserMessageText(msgContent);
144
- if (text) {
145
- lastUserMessage = text;
146
- if (!firstUserMessage) {
147
- firstUserMessage = text;
148
- }
149
- }
150
- } else {
151
- isInterrupted = false;
152
- }
153
- }
154
- } catch {
155
- continue;
156
- }
157
- }
74
+ /**
75
+ * Parse a session JSONL file into a ClaudeSession summary.
76
+ *
77
+ * Iterates all lines to extract: session start time (from first entry),
78
+ * last activity timestamp, last entry type (for status), whether the
79
+ * session was interrupted, and the last meaningful user message.
80
+ *
81
+ * Returns null if the file is unreadable or empty.
82
+ */
83
+ readSession(filePath: string, projectPath: string): ClaudeSession | null {
84
+ const sessionId = path.basename(filePath, ".jsonl");
85
+
86
+ let content: string;
87
+ try {
88
+ content = fs.readFileSync(filePath, "utf-8");
89
+ } catch {
90
+ return null;
91
+ }
158
92
 
159
- return {
160
- sessionId,
161
- projectPath: projectPath || lastCwd || '',
162
- lastCwd,
163
- sessionStart: sessionStart || lastActive || new Date(),
164
- lastActive: lastActive || new Date(),
165
- lastEntryType,
166
- isInterrupted,
167
- lastUserMessage,
168
- firstUserMessage,
169
- };
93
+ const allLines = content.trim().split("\n");
94
+ if (allLines.length === 0) {
95
+ return null;
170
96
  }
171
97
 
172
- /**
173
- * Determine agent status from parsed session state.
174
- *
175
- * Status mapping:
176
- * - "user" + interrupted → WAITING (agent finished, awaiting new input)
177
- * - "user" + not interrupted → RUNNING (agent is processing)
178
- * - "progress" / "thinking" → RUNNING
179
- * - "assistant" → WAITING (agent responded, awaiting user)
180
- * - "system" → IDLE
181
- */
182
- determineStatus(session: ClaudeSession): AgentStatus {
183
- if (!session.lastEntryType) {
184
- return AgentStatus.UNKNOWN;
185
- }
98
+ const sessionStart = this.parseSessionStart(allLines[0]);
186
99
 
187
- if (session.lastEntryType === 'user') {
188
- return session.isInterrupted
189
- ? AgentStatus.WAITING
190
- : AgentStatus.RUNNING;
191
- }
100
+ let lastEntryType: string | undefined;
101
+ let lastActive: Date | undefined;
102
+ let lastCwd: string | undefined;
103
+ let isInterrupted = false;
104
+ let lastUserMessage: string | undefined;
105
+ let firstUserMessage: string | undefined;
192
106
 
193
- if (
194
- session.lastEntryType === 'progress' ||
195
- session.lastEntryType === 'thinking'
196
- ) {
197
- return AgentStatus.RUNNING;
198
- }
107
+ for (const line of allLines) {
108
+ try {
109
+ const entry: SessionEntry = JSON.parse(line);
199
110
 
200
- if (session.lastEntryType === 'assistant') {
201
- return AgentStatus.WAITING;
111
+ if (entry.timestamp) {
112
+ const ts = new Date(entry.timestamp);
113
+ if (!Number.isNaN(ts.getTime())) {
114
+ lastActive = ts;
115
+ }
202
116
  }
203
117
 
204
- if (session.lastEntryType === 'system') {
205
- return AgentStatus.IDLE;
118
+ if (typeof entry.cwd === "string" && entry.cwd.trim().length > 0) {
119
+ lastCwd = entry.cwd;
206
120
  }
207
121
 
208
- return AgentStatus.UNKNOWN;
209
- }
210
-
211
- /**
212
- * Read the full conversation from a session JSONL file.
213
- *
214
- * Default mode returns only text content from user/assistant/system messages.
215
- * Verbose mode also includes tool_use and tool_result blocks.
216
- */
217
- getConversation(sessionFilePath: string, options?: { verbose?: boolean }): ConversationMessage[] {
218
- const verbose = options?.verbose ?? false;
219
-
220
- let content: string;
221
- try {
222
- content = fs.readFileSync(sessionFilePath, 'utf-8');
223
- } catch {
224
- return [];
225
- }
226
-
227
- const lines = content.trim().split('\n');
228
- const messages: ConversationMessage[] = [];
229
-
230
- for (const line of lines) {
231
- let entry: SessionEntry;
232
- try {
233
- entry = JSON.parse(line);
234
- } catch {
235
- continue;
236
- }
237
-
238
- let role: ConversationMessage['role'];
239
- if (entry.type === 'user') {
240
- role = 'user';
241
- } else if (entry.type === 'assistant') {
242
- role = 'assistant';
243
- } else if (entry.type === 'system') {
244
- role = 'system';
245
- } else {
246
- continue;
122
+ if (entry.type && CONVERSATION_ENTRY_TYPES.has(entry.type)) {
123
+ lastEntryType = entry.type;
124
+
125
+ if (entry.type === "user") {
126
+ const msgContent = entry.message?.content;
127
+ isInterrupted =
128
+ Array.isArray(msgContent) &&
129
+ msgContent.some(
130
+ (c) =>
131
+ (c.type === "text" && c.text?.includes("[Request interrupted")) ||
132
+ (c.type === "tool_result" && c.content?.includes("[Request interrupted")),
133
+ );
134
+
135
+ const text = this.extractUserMessageText(msgContent);
136
+ if (text) {
137
+ lastUserMessage = text;
138
+ if (!firstUserMessage) {
139
+ firstUserMessage = text;
140
+ }
247
141
  }
142
+ } else {
143
+ isInterrupted = false;
144
+ }
145
+ }
146
+ } catch {
147
+ continue;
148
+ }
149
+ }
248
150
 
249
- const text = this.extractConversationContent(entry.message?.content, role, verbose);
250
- if (!text) continue;
151
+ return {
152
+ sessionId,
153
+ projectPath: projectPath || lastCwd || "",
154
+ lastCwd,
155
+ sessionStart: sessionStart || lastActive || new Date(),
156
+ lastActive: lastActive || new Date(),
157
+ lastEntryType,
158
+ isInterrupted,
159
+ lastUserMessage,
160
+ firstUserMessage,
161
+ };
162
+ }
163
+
164
+ /**
165
+ * Determine agent status from parsed session state.
166
+ *
167
+ * Status mapping:
168
+ * - "user" + interrupted → WAITING (agent finished, awaiting new input)
169
+ * - "user" + not interrupted → RUNNING (agent is processing)
170
+ * - "progress" / "thinking" → RUNNING
171
+ * - "assistant" → WAITING (agent responded, awaiting user)
172
+ * - "system" → IDLE
173
+ */
174
+ determineStatus(session: ClaudeSession): AgentStatus {
175
+ if (!session.lastEntryType) {
176
+ return AgentStatus.UNKNOWN;
177
+ }
251
178
 
252
- messages.push({
253
- role,
254
- content: text,
255
- timestamp: entry.timestamp,
256
- });
257
- }
179
+ if (session.lastEntryType === "user") {
180
+ return session.isInterrupted ? AgentStatus.WAITING : AgentStatus.RUNNING;
181
+ }
258
182
 
259
- return messages;
183
+ if (session.lastEntryType === "progress" || session.lastEntryType === "thinking") {
184
+ return AgentStatus.RUNNING;
260
185
  }
261
186
 
262
- /**
263
- * Parse session start time from the first JSONL line.
264
- *
265
- * Claude Code may emit a "file-history-snapshot" as the first entry,
266
- * which stores its timestamp inside "snapshot.timestamp" rather than
267
- * at the root level.
268
- */
269
- private parseSessionStart(firstLine: string): Date | null {
270
- try {
271
- const firstEntry = JSON.parse(firstLine);
272
- const rawTs: string | undefined =
273
- firstEntry.timestamp || firstEntry.snapshot?.timestamp;
274
- if (rawTs) {
275
- const ts = new Date(rawTs);
276
- if (!Number.isNaN(ts.getTime())) {
277
- return ts;
278
- }
279
- }
280
- } catch {
281
- /* malformed first line */
282
- }
283
- return null;
187
+ if (session.lastEntryType === "assistant") {
188
+ return AgentStatus.WAITING;
284
189
  }
285
190
 
286
- /**
287
- * Extract meaningful text from a user message content field.
288
- *
289
- * Handles multiple formats:
290
- * - Plain string content
291
- * - Array of content blocks (extracts first text block)
292
- * - Skill slash-commands (<command-message> tags)
293
- * - Expanded skill content (extracts ARGUMENTS line)
294
- * - Filters noise messages (interruptions, tool loaded, session continued)
295
- */
296
- private extractUserMessageText(
297
- content: string | Array<{ type?: string; text?: string }> | undefined,
298
- ): string | undefined {
299
- if (!content) {
300
- return undefined;
301
- }
191
+ if (session.lastEntryType === "system") {
192
+ return AgentStatus.IDLE;
193
+ }
302
194
 
303
- let raw: string | undefined;
195
+ return AgentStatus.UNKNOWN;
196
+ }
197
+
198
+ /**
199
+ * Read the full conversation from a session JSONL file.
200
+ *
201
+ * Default mode returns only text content from user/assistant/system messages.
202
+ * Verbose mode also includes tool_use and tool_result blocks.
203
+ */
204
+ getConversation(sessionFilePath: string, options?: { verbose?: boolean }): ConversationMessage[] {
205
+ const verbose = options?.verbose ?? false;
206
+
207
+ let content: string;
208
+ try {
209
+ content = fs.readFileSync(sessionFilePath, "utf-8");
210
+ } catch {
211
+ return [];
212
+ }
304
213
 
305
- if (typeof content === 'string') {
306
- raw = content.trim();
307
- } else if (Array.isArray(content)) {
308
- for (const block of content) {
309
- if (block.type === 'text' && block.text?.trim()) {
310
- raw = block.text.trim();
311
- break;
312
- }
313
- }
314
- }
214
+ const lines = content.trim().split("\n");
215
+ const messages: ConversationMessage[] = [];
216
+
217
+ for (const line of lines) {
218
+ let entry: SessionEntry;
219
+ try {
220
+ entry = JSON.parse(line);
221
+ } catch {
222
+ continue;
223
+ }
224
+
225
+ let role: ConversationMessage["role"];
226
+ if (entry.type === "user") {
227
+ role = "user";
228
+ } else if (entry.type === "assistant") {
229
+ role = "assistant";
230
+ } else if (entry.type === "system") {
231
+ role = "system";
232
+ } else {
233
+ continue;
234
+ }
235
+
236
+ const text = this.extractConversationContent(entry.message?.content, role, verbose);
237
+ if (!text) continue;
238
+
239
+ messages.push({
240
+ role,
241
+ content: text,
242
+ timestamp: entry.timestamp,
243
+ });
244
+ }
315
245
 
316
- if (!raw) {
317
- return undefined;
246
+ return messages;
247
+ }
248
+
249
+ /**
250
+ * Parse session start time from the first JSONL line.
251
+ *
252
+ * Claude Code may emit a "file-history-snapshot" as the first entry,
253
+ * which stores its timestamp inside "snapshot.timestamp" rather than
254
+ * at the root level.
255
+ */
256
+ private parseSessionStart(firstLine: string): Date | null {
257
+ try {
258
+ const firstEntry = JSON.parse(firstLine);
259
+ const rawTs: string | undefined = firstEntry.timestamp || firstEntry.snapshot?.timestamp;
260
+ if (rawTs) {
261
+ const ts = new Date(rawTs);
262
+ if (!Number.isNaN(ts.getTime())) {
263
+ return ts;
318
264
  }
265
+ }
266
+ } catch {
267
+ /* malformed first line */
268
+ }
269
+ return null;
270
+ }
271
+
272
+ /**
273
+ * Extract meaningful text from a user message content field.
274
+ *
275
+ * Handles multiple formats:
276
+ * - Plain string content
277
+ * - Array of content blocks (extracts first text block)
278
+ * - Skill slash-commands (<command-message> tags)
279
+ * - Expanded skill content (extracts ARGUMENTS line)
280
+ * - Filters noise messages (interruptions, tool loaded, session continued)
281
+ */
282
+ private extractUserMessageText(
283
+ content: string | Array<{ type?: string; text?: string }> | undefined,
284
+ ): string | undefined {
285
+ if (!content) {
286
+ return undefined;
287
+ }
319
288
 
320
- if (raw.startsWith('<command-message>')) {
321
- return this.parseCommandMessage(raw);
322
- }
289
+ let raw: string | undefined;
323
290
 
324
- if (raw.startsWith('Base directory for this skill:')) {
325
- const argsMatch = raw.match(/\nARGUMENTS:\s*(.+)/);
326
- return argsMatch?.[1]?.trim() || undefined;
291
+ if (typeof content === "string") {
292
+ raw = content.trim();
293
+ } else if (Array.isArray(content)) {
294
+ for (const block of content) {
295
+ if (block.type === "text" && block.text?.trim()) {
296
+ raw = block.text.trim();
297
+ break;
327
298
  }
299
+ }
300
+ }
328
301
 
329
- if (isNoiseMessage(raw)) {
330
- return undefined;
331
- }
302
+ if (!raw) {
303
+ return undefined;
304
+ }
332
305
 
333
- return raw;
306
+ if (raw.startsWith("<command-message>")) {
307
+ return this.parseCommandMessage(raw);
334
308
  }
335
309
 
336
- /**
337
- * Parse a <command-message> string into "/command args" format.
338
- */
339
- private parseCommandMessage(raw: string): string | undefined {
340
- const nameMatch = raw.match(/<command-name>([^<]+)<\/command-name>/);
341
- const argsMatch = raw.match(/<command-args>([^<]+)<\/command-args>/);
342
- const name = nameMatch?.[1]?.trim();
343
- if (!name) {
344
- return undefined;
345
- }
346
- const args = argsMatch?.[1]?.trim();
347
- return args ? `${name} ${args}` : name;
310
+ if (raw.startsWith("Base directory for this skill:")) {
311
+ const argsMatch = raw.match(/\nARGUMENTS:\s*(.+)/);
312
+ return argsMatch?.[1]?.trim() || undefined;
348
313
  }
349
314
 
350
- /**
351
- * Extract displayable content from a message content field for conversation output.
352
- */
353
- private extractConversationContent(
354
- content: string | ContentBlock[] | undefined,
355
- role: ConversationMessage['role'],
356
- verbose: boolean,
357
- ): string | undefined {
358
- if (!content) return undefined;
359
-
360
- if (typeof content === 'string') {
361
- const cleaned = stripHarnessTags(content);
362
- if (role === 'user' && isNoiseMessage(cleaned)) return undefined;
363
- return cleaned || undefined;
364
- }
315
+ if (isNoiseMessage(raw)) {
316
+ return undefined;
317
+ }
365
318
 
366
- if (!Array.isArray(content)) return undefined;
367
-
368
- const parts: string[] = [];
369
-
370
- for (const block of content) {
371
- if (block.type === 'text' && block.text?.trim()) {
372
- const cleaned = stripHarnessTags(block.text);
373
- if (!cleaned) continue;
374
- if (role === 'user' && isNoiseMessage(cleaned)) continue;
375
- parts.push(cleaned);
376
- } else if (block.type === 'tool_use' && verbose) {
377
- const inputSummary = block.input?.file_path || block.input?.pattern || block.input?.command || '';
378
- parts.push(`[Tool: ${block.name}]${inputSummary ? ' ' + inputSummary : ''}`);
379
- } else if (block.type === 'tool_result' && verbose) {
380
- const truncated = truncateToolResult(block.content || '');
381
- const prefix = block.is_error ? '[Tool Error]' : '[Tool Result]';
382
- parts.push(`${prefix} ${truncated}`);
383
- }
384
- }
319
+ return raw;
320
+ }
321
+
322
+ /**
323
+ * Parse a <command-message> string into "/command args" format.
324
+ */
325
+ private parseCommandMessage(raw: string): string | undefined {
326
+ const nameMatch = raw.match(/<command-name>([^<]+)<\/command-name>/);
327
+ const argsMatch = raw.match(/<command-args>([^<]+)<\/command-args>/);
328
+ const name = nameMatch?.[1]?.trim();
329
+ if (!name) {
330
+ return undefined;
331
+ }
332
+ const args = argsMatch?.[1]?.trim();
333
+ return args ? `${name} ${args}` : name;
334
+ }
335
+
336
+ /**
337
+ * Extract displayable content from a message content field for conversation output.
338
+ */
339
+ private extractConversationContent(
340
+ content: string | ContentBlock[] | undefined,
341
+ role: ConversationMessage["role"],
342
+ verbose: boolean,
343
+ ): string | undefined {
344
+ if (!content) return undefined;
345
+
346
+ if (typeof content === "string") {
347
+ const cleaned = stripHarnessTags(content);
348
+ if (role === "user" && isNoiseMessage(cleaned)) return undefined;
349
+ return cleaned || undefined;
350
+ }
385
351
 
386
- return parts.length > 0 ? parts.join('\n') : undefined;
352
+ if (!Array.isArray(content)) return undefined;
353
+
354
+ const parts: string[] = [];
355
+
356
+ for (const block of content) {
357
+ if (block.type === "text" && block.text?.trim()) {
358
+ const cleaned = stripHarnessTags(block.text);
359
+ if (!cleaned) continue;
360
+ if (role === "user" && isNoiseMessage(cleaned)) continue;
361
+ parts.push(cleaned);
362
+ } else if (block.type === "tool_use" && verbose) {
363
+ const inputSummary =
364
+ block.input?.file_path || block.input?.pattern || block.input?.command || "";
365
+ parts.push(`[Tool: ${block.name}]${inputSummary ? " " + inputSummary : ""}`);
366
+ } else if (block.type === "tool_result" && verbose) {
367
+ const truncated = truncateToolResult(block.content || "");
368
+ const prefix = block.is_error ? "[Tool Error]" : "[Tool Result]";
369
+ parts.push(`${prefix} ${truncated}`);
370
+ }
387
371
  }
372
+
373
+ return parts.length > 0 ? parts.join("\n") : undefined;
374
+ }
388
375
  }
389
376
 
390
377
  /**
@@ -393,25 +380,22 @@ export class ClaudeSessionParser {
393
380
  * stdout), not meaningful conversation content.
394
381
  */
395
382
  const HARNESS_DROP_TAGS = [
396
- 'system-reminder',
397
- 'local-command-stdout',
398
- 'local-command-stderr',
399
- 'user-prompt-submit-hook',
400
- 'command-stdout',
401
- 'command-stderr',
402
- 'bash-input',
403
- 'bash-stdout',
404
- 'bash-stderr',
405
- 'command-message',
383
+ "system-reminder",
384
+ "local-command-stdout",
385
+ "local-command-stderr",
386
+ "user-prompt-submit-hook",
387
+ "command-stdout",
388
+ "command-stderr",
389
+ "bash-input",
390
+ "bash-stdout",
391
+ "bash-stderr",
392
+ "command-message",
406
393
  ] as const;
407
394
 
408
- const HARNESS_DROP_RE = new RegExp(
409
- `<(${HARNESS_DROP_TAGS.join('|')})>[\\s\\S]*?</\\1>`,
410
- 'g',
411
- );
395
+ const HARNESS_DROP_RE = new RegExp(`<(${HARNESS_DROP_TAGS.join("|")})>[\\s\\S]*?</\\1>`, "g");
412
396
 
413
397
  const COMMAND_INVOCATION_RE =
414
- /<command-name>([^<]+)<\/command-name>(?:\s*<command-args>([\s\S]*?)<\/command-args>)?/g;
398
+ /<command-name>([^<]+)<\/command-name>(?:\s*<command-args>([\s\S]*?)<\/command-args>)?/g;
415
399
 
416
400
  /**
417
401
  * Remove harness-injected XML blocks from message text and collapse
@@ -421,28 +405,28 @@ const COMMAND_INVOCATION_RE =
421
405
  * survives stripping.
422
406
  */
423
407
  function stripHarnessTags(text: string): string {
424
- let out = text.replace(HARNESS_DROP_RE, '');
408
+ let out = text.replace(HARNESS_DROP_RE, "");
425
409
 
426
- out = out.replace(COMMAND_INVOCATION_RE, (_match, rawName: string, rawArgs?: string) => {
427
- const name = rawName.trim();
428
- const args = rawArgs?.trim();
429
- return args ? `${name} ${args}` : name;
430
- });
410
+ out = out.replace(COMMAND_INVOCATION_RE, (_match, rawName: string, rawArgs?: string) => {
411
+ const name = rawName.trim();
412
+ const args = rawArgs?.trim();
413
+ return args ? `${name} ${args}` : name;
414
+ });
431
415
 
432
- return out.replace(/\n{3,}/g, '\n\n').trim();
416
+ return out.replace(/\n{3,}/g, "\n\n").trim();
433
417
  }
434
418
 
435
419
  /** Check if a message is noise (not a meaningful user intent). */
436
420
  function isNoiseMessage(text: string): boolean {
437
- return (
438
- text.startsWith('[Request interrupted') ||
439
- text === 'Tool loaded.' ||
440
- text.startsWith('This session is being continued')
441
- );
421
+ return (
422
+ text.startsWith("[Request interrupted") ||
423
+ text === "Tool loaded." ||
424
+ text.startsWith("This session is being continued")
425
+ );
442
426
  }
443
427
 
444
428
  function truncateToolResult(content: string, maxLength = 200): string {
445
- const firstLine = content.split('\n')[0] || '';
446
- if (firstLine.length <= maxLength) return firstLine;
447
- return firstLine.slice(0, maxLength - 3) + '...';
429
+ const firstLine = content.split("\n")[0] || "";
430
+ if (firstLine.length <= maxLength) return firstLine;
431
+ return firstLine.slice(0, maxLength - 3) + "...";
448
432
  }