@ai-devkit/agent-manager 0.36.0 → 0.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1046) hide show
  1. package/dist/AgentManager.d.ts +9 -8
  2. package/dist/AgentManager.d.ts.map +1 -1
  3. package/dist/AgentManager.js +23 -4
  4. package/dist/AgentManager.js.map +1 -1
  5. package/dist/__tests__/AgentManager.test.js +151 -3
  6. package/dist/__tests__/AgentManager.test.js.map +1 -1
  7. package/dist/__tests__/adapters/IncrementalSessionRefresh.test.js +486 -0
  8. package/dist/__tests__/adapters/IncrementalSessionRefresh.test.js.map +1 -0
  9. package/dist/__tests__/adapters/adapterProcessImports.test.js +52 -0
  10. package/dist/__tests__/adapters/adapterProcessImports.test.js.map +1 -0
  11. package/dist/__tests__/adapters/adapterSnapshotCandidates.test.js +247 -0
  12. package/dist/__tests__/adapters/adapterSnapshotCandidates.test.js.map +1 -0
  13. package/dist/__tests__/capacity/anthropic.test.js +115 -0
  14. package/dist/__tests__/capacity/anthropic.test.js.map +1 -0
  15. package/dist/__tests__/capacity/boundaries.test.js +45 -0
  16. package/dist/__tests__/capacity/boundaries.test.js.map +1 -0
  17. package/dist/__tests__/capacity/claude.test.js +3 -3
  18. package/dist/__tests__/capacity/claude.test.js.map +1 -1
  19. package/dist/__tests__/capacity/codex.test.js +3 -1
  20. package/dist/__tests__/capacity/codex.test.js.map +1 -1
  21. package/dist/__tests__/capacity/openai.test.js +32 -25
  22. package/dist/__tests__/capacity/openai.test.js.map +1 -1
  23. package/dist/__tests__/capacity/wham.test.js +1 -1
  24. package/dist/__tests__/capacity/wham.test.js.map +1 -1
  25. package/dist/__tests__/capacity/zai.test.js +7 -8
  26. package/dist/__tests__/capacity/zai.test.js.map +1 -1
  27. package/dist/__tests__/harnesses/BoundedSummarySkip.test.js +568 -0
  28. package/dist/__tests__/harnesses/BoundedSummarySkip.test.js.map +1 -0
  29. package/dist/__tests__/harnesses/SessionSummaryEquivalence.test.js +1089 -0
  30. package/dist/__tests__/harnesses/SessionSummaryEquivalence.test.js.map +1 -0
  31. package/dist/__tests__/harnesses/antigravity/AntigravityCliAdapter.subprocess.test.js +143 -0
  32. package/dist/__tests__/harnesses/antigravity/AntigravityCliAdapter.subprocess.test.js.map +1 -0
  33. package/dist/__tests__/harnesses/antigravity/AntigravityCliAdapter.test.js +462 -0
  34. package/dist/__tests__/harnesses/antigravity/AntigravityCliAdapter.test.js.map +1 -0
  35. package/dist/__tests__/harnesses/builtinAdapters.test.js +33 -0
  36. package/dist/__tests__/harnesses/builtinAdapters.test.js.map +1 -0
  37. package/dist/__tests__/harnesses/claude/ClaudeAgentMapper.test.js +79 -0
  38. package/dist/__tests__/harnesses/claude/ClaudeAgentMapper.test.js.map +1 -0
  39. package/dist/__tests__/harnesses/claude/ClaudeCodeAdapter.test.js +1881 -0
  40. package/dist/__tests__/harnesses/claude/ClaudeCodeAdapter.test.js.map +1 -0
  41. package/dist/__tests__/harnesses/claude/ClaudeSessionLocator.test.js +425 -0
  42. package/dist/__tests__/harnesses/claude/ClaudeSessionLocator.test.js.map +1 -0
  43. package/dist/__tests__/harnesses/claude/ClaudeSessionParser.test.js +314 -0
  44. package/dist/__tests__/harnesses/claude/ClaudeSessionParser.test.js.map +1 -0
  45. package/dist/__tests__/harnesses/claude/durable/ClaudeCliProbe.test.js +49 -0
  46. package/dist/__tests__/harnesses/claude/durable/ClaudeCliProbe.test.js.map +1 -0
  47. package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.js +76 -0
  48. package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.js.map +1 -0
  49. package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgentService.test.js +173 -0
  50. package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgentService.test.js.map +1 -0
  51. package/dist/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.js +181 -0
  52. package/dist/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.js.map +1 -0
  53. package/dist/__tests__/harnesses/codex/CodexAdapter.test.js +685 -0
  54. package/dist/__tests__/harnesses/codex/CodexAdapter.test.js.map +1 -0
  55. package/dist/__tests__/harnesses/codex/CodexSessionLocator.test.js +463 -0
  56. package/dist/__tests__/harnesses/codex/CodexSessionLocator.test.js.map +1 -0
  57. package/dist/__tests__/harnesses/codex/CodexSessionMapping.test.js +86 -0
  58. package/dist/__tests__/harnesses/codex/CodexSessionMapping.test.js.map +1 -0
  59. package/dist/__tests__/harnesses/codex/CodexSessionParser.test.js +254 -0
  60. package/dist/__tests__/harnesses/codex/CodexSessionParser.test.js.map +1 -0
  61. package/dist/__tests__/harnesses/codex/durable/CodexCliProbe.test.js +121 -0
  62. package/dist/__tests__/harnesses/codex/durable/CodexCliProbe.test.js.map +1 -0
  63. package/dist/__tests__/harnesses/codex/durable/CodexDurableAgentRepository.test.js +84 -0
  64. package/dist/__tests__/harnesses/codex/durable/CodexDurableAgentRepository.test.js.map +1 -0
  65. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.js +128 -0
  66. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.js.map +1 -0
  67. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.js +246 -0
  68. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.js.map +1 -0
  69. package/dist/__tests__/harnesses/codex/durable/CodexPrintRunner.test.js +384 -0
  70. package/dist/__tests__/harnesses/codex/durable/CodexPrintRunner.test.js.map +1 -0
  71. package/dist/__tests__/harnesses/copilot/CopilotAdapter.test.js +659 -0
  72. package/dist/__tests__/harnesses/copilot/CopilotAdapter.test.js.map +1 -0
  73. package/dist/__tests__/harnesses/copilot/CopilotRefreshIO.test.js +290 -0
  74. package/dist/__tests__/harnesses/copilot/CopilotRefreshIO.test.js.map +1 -0
  75. package/dist/__tests__/harnesses/gemini/GeminiCliAdapter.test.js +1443 -0
  76. package/dist/__tests__/harnesses/gemini/GeminiCliAdapter.test.js.map +1 -0
  77. package/dist/__tests__/harnesses/gemini/GeminiSessionJsonl.test.js +491 -0
  78. package/dist/__tests__/harnesses/gemini/GeminiSessionJsonl.test.js.map +1 -0
  79. package/dist/__tests__/harnesses/gemini/GeminiSessionLocator.test.js +399 -0
  80. package/dist/__tests__/harnesses/gemini/GeminiSessionLocator.test.js.map +1 -0
  81. package/dist/__tests__/harnesses/grok/GrokAgentMapper.test.js +56 -0
  82. package/dist/__tests__/harnesses/grok/GrokAgentMapper.test.js.map +1 -0
  83. package/dist/__tests__/harnesses/grok/GrokCliAdapter.test.js +421 -0
  84. package/dist/__tests__/harnesses/grok/GrokCliAdapter.test.js.map +1 -0
  85. package/dist/__tests__/harnesses/grok/GrokIncrementalRefresh.test.js +167 -0
  86. package/dist/__tests__/harnesses/grok/GrokIncrementalRefresh.test.js.map +1 -0
  87. package/dist/__tests__/harnesses/grok/GrokSessionLocator.test.js +133 -0
  88. package/dist/__tests__/harnesses/grok/GrokSessionLocator.test.js.map +1 -0
  89. package/dist/__tests__/harnesses/grok/GrokSessionParser.test.js +301 -0
  90. package/dist/__tests__/harnesses/grok/GrokSessionParser.test.js.map +1 -0
  91. package/dist/__tests__/harnesses/kiro/KiroAdapter.test.js +662 -0
  92. package/dist/__tests__/harnesses/kiro/KiroAdapter.test.js.map +1 -0
  93. package/dist/__tests__/harnesses/opencode/OpenCodeAdapter.test.js +213 -0
  94. package/dist/__tests__/harnesses/opencode/OpenCodeAdapter.test.js.map +1 -0
  95. package/dist/__tests__/harnesses/opencode/OpenCodeAgentMapper.test.js +89 -0
  96. package/dist/__tests__/harnesses/opencode/OpenCodeAgentMapper.test.js.map +1 -0
  97. package/dist/__tests__/harnesses/opencode/OpenCodeSessionLocator.test.js +94 -0
  98. package/dist/__tests__/harnesses/opencode/OpenCodeSessionLocator.test.js.map +1 -0
  99. package/dist/__tests__/harnesses/opencode/OpenCodeSessionParser.test.js +147 -0
  100. package/dist/__tests__/harnesses/opencode/OpenCodeSessionParser.test.js.map +1 -0
  101. package/dist/__tests__/harnesses/pi/PiAdapter.test.js +367 -0
  102. package/dist/__tests__/harnesses/pi/PiAdapter.test.js.map +1 -0
  103. package/dist/__tests__/harnesses/pi/PiDiscoveryIO.test.js +382 -0
  104. package/dist/__tests__/harnesses/pi/PiDiscoveryIO.test.js.map +1 -0
  105. package/dist/__tests__/harnesses/pi/PiSessionParser.test.js +416 -0
  106. package/dist/__tests__/harnesses/pi/PiSessionParser.test.js.map +1 -0
  107. package/dist/__tests__/harnesses/pi/PiSessionTracker.test.js +108 -0
  108. package/dist/__tests__/harnesses/pi/PiSessionTracker.test.js.map +1 -0
  109. package/dist/__tests__/harnesses/pi/durable/PiCliProbe.test.js +70 -0
  110. package/dist/__tests__/harnesses/pi/durable/PiCliProbe.test.js.map +1 -0
  111. package/dist/__tests__/harnesses/pi/durable/PiDurableAgentRepository.test.js.map +1 -0
  112. package/dist/__tests__/harnesses/pi/durable/PiPrintAgentService.test.js +192 -0
  113. package/dist/__tests__/harnesses/pi/durable/PiPrintAgentService.test.js.map +1 -0
  114. package/dist/__tests__/harnesses/pi/durable/PiPrintProtocol.test.js +119 -0
  115. package/dist/__tests__/harnesses/pi/durable/PiPrintProtocol.test.js.map +1 -0
  116. package/dist/__tests__/harnesses/pi/durable/PiPrintRunner.test.js +382 -0
  117. package/dist/__tests__/harnesses/pi/durable/PiPrintRunner.test.js.map +1 -0
  118. package/dist/__tests__/harnesses/pi/durable/PiStreamParser.test.js +34 -0
  119. package/dist/__tests__/harnesses/pi/durable/PiStreamParser.test.js.map +1 -0
  120. package/dist/__tests__/harnesses/readiness/AgentReadiness.test.js +342 -0
  121. package/dist/__tests__/harnesses/readiness/AgentReadiness.test.js.map +1 -0
  122. package/dist/__tests__/harnesses/runtimeProfiles.test.js +89 -0
  123. package/dist/__tests__/harnesses/runtimeProfiles.test.js.map +1 -0
  124. package/dist/__tests__/print/DurableAgent.test.js +4 -6
  125. package/dist/__tests__/print/DurableAgent.test.js.map +1 -1
  126. package/dist/__tests__/print/DurableAgentRepository.test.js +1 -12
  127. package/dist/__tests__/print/DurableAgentRepository.test.js.map +1 -1
  128. package/dist/__tests__/runtime/ManagedAgentRuntime.test.js +49 -0
  129. package/dist/__tests__/runtime/ManagedAgentRuntime.test.js.map +1 -1
  130. package/dist/__tests__/terminal/TmuxManager.test.js +1 -1
  131. package/dist/__tests__/terminal/TmuxManager.test.js.map +1 -1
  132. package/dist/__tests__/utils/IncrementalJsonlSummary.test.js +650 -0
  133. package/dist/__tests__/utils/IncrementalJsonlSummary.test.js.map +1 -0
  134. package/dist/__tests__/utils/conversationTail.bench.test.js +258 -0
  135. package/dist/__tests__/utils/conversationTail.bench.test.js.map +1 -0
  136. package/dist/__tests__/utils/conversationTailParity.test.js +588 -0
  137. package/dist/__tests__/utils/conversationTailParity.test.js.map +1 -0
  138. package/dist/__tests__/utils/jsonlTail.test.js +360 -0
  139. package/dist/__tests__/utils/jsonlTail.test.js.map +1 -0
  140. package/dist/__tests__/utils/matchingConstants.test.js +35 -0
  141. package/dist/__tests__/utils/matchingConstants.test.js.map +1 -0
  142. package/dist/__tests__/utils/process.test.js +436 -2
  143. package/dist/__tests__/utils/process.test.js.map +1 -1
  144. package/dist/adapters/AgentAdapter.d.ts +25 -6
  145. package/dist/adapters/AgentAdapter.d.ts.map +1 -1
  146. package/dist/adapters/AgentAdapter.js +12 -3
  147. package/dist/adapters/AgentAdapter.js.map +1 -1
  148. package/dist/capacity/index.d.ts +9 -19
  149. package/dist/capacity/index.d.ts.map +1 -1
  150. package/dist/capacity/index.js +11 -4
  151. package/dist/capacity/index.js.map +1 -1
  152. package/dist/capacity/providers/anthropic.d.ts +9 -0
  153. package/dist/capacity/providers/anthropic.d.ts.map +1 -0
  154. package/dist/capacity/providers/anthropic.js +153 -0
  155. package/dist/capacity/providers/anthropic.js.map +1 -0
  156. package/dist/capacity/providers/openai-platform.d.ts +14 -0
  157. package/dist/capacity/providers/openai-platform.d.ts.map +1 -0
  158. package/dist/capacity/providers/openai-platform.js +120 -0
  159. package/dist/capacity/providers/openai-platform.js.map +1 -0
  160. package/dist/capacity/providers/openai-subscription.d.ts +20 -0
  161. package/dist/capacity/providers/openai-subscription.d.ts.map +1 -0
  162. package/dist/capacity/providers/openai-subscription.js +129 -0
  163. package/dist/capacity/providers/openai-subscription.js.map +1 -0
  164. package/dist/capacity/providers/zai.d.ts +8 -0
  165. package/dist/capacity/providers/zai.d.ts.map +1 -0
  166. package/dist/capacity/providers/zai.js +158 -0
  167. package/dist/capacity/providers/zai.js.map +1 -0
  168. package/dist/capacity/sources/claude.d.ts +9 -0
  169. package/dist/capacity/sources/claude.d.ts.map +1 -0
  170. package/dist/capacity/sources/claude.js +17 -0
  171. package/dist/capacity/sources/claude.js.map +1 -0
  172. package/dist/capacity/sources/codex.d.ts +32 -0
  173. package/dist/capacity/sources/codex.d.ts.map +1 -0
  174. package/dist/capacity/sources/codex.js +227 -0
  175. package/dist/capacity/sources/codex.js.map +1 -0
  176. package/dist/capacity/sources/pi.d.ts +30 -0
  177. package/dist/capacity/sources/pi.d.ts.map +1 -0
  178. package/dist/capacity/sources/pi.js +81 -0
  179. package/dist/capacity/sources/pi.js.map +1 -0
  180. package/dist/capacity/types.d.ts +2 -0
  181. package/dist/capacity/types.d.ts.map +1 -1
  182. package/dist/capacity/types.js +1 -1
  183. package/dist/capacity/types.js.map +1 -1
  184. package/dist/harnesses/antigravity/AntigravityAgentMapper.d.ts +13 -0
  185. package/dist/harnesses/antigravity/AntigravityAgentMapper.d.ts.map +1 -0
  186. package/dist/harnesses/antigravity/AntigravityAgentMapper.js +30 -0
  187. package/dist/harnesses/antigravity/AntigravityAgentMapper.js.map +1 -0
  188. package/dist/harnesses/antigravity/AntigravityCliAdapter.d.ts +32 -0
  189. package/dist/harnesses/antigravity/AntigravityCliAdapter.d.ts.map +1 -0
  190. package/dist/harnesses/antigravity/AntigravityCliAdapter.js +97 -0
  191. package/dist/harnesses/antigravity/AntigravityCliAdapter.js.map +1 -0
  192. package/dist/harnesses/antigravity/AntigravitySessionLocator.d.ts +30 -0
  193. package/dist/harnesses/antigravity/AntigravitySessionLocator.d.ts.map +1 -0
  194. package/dist/harnesses/antigravity/AntigravitySessionLocator.js +56 -0
  195. package/dist/harnesses/antigravity/AntigravitySessionLocator.js.map +1 -0
  196. package/dist/harnesses/antigravity/AntigravitySessionParser.d.ts +75 -0
  197. package/dist/harnesses/antigravity/AntigravitySessionParser.d.ts.map +1 -0
  198. package/dist/harnesses/antigravity/AntigravitySessionParser.js +174 -0
  199. package/dist/harnesses/antigravity/AntigravitySessionParser.js.map +1 -0
  200. package/dist/harnesses/claude/ClaudeAgentMapper.d.ts.map +1 -0
  201. package/dist/harnesses/claude/ClaudeAgentMapper.js +36 -0
  202. package/dist/harnesses/claude/ClaudeAgentMapper.js.map +1 -0
  203. package/dist/harnesses/claude/ClaudeCodeAdapter.d.ts +30 -0
  204. package/dist/harnesses/claude/ClaudeCodeAdapter.d.ts.map +1 -0
  205. package/dist/harnesses/claude/ClaudeCodeAdapter.js +134 -0
  206. package/dist/harnesses/claude/ClaudeCodeAdapter.js.map +1 -0
  207. package/dist/harnesses/claude/ClaudeSessionLocator.d.ts.map +1 -0
  208. package/dist/harnesses/claude/ClaudeSessionLocator.js +260 -0
  209. package/dist/harnesses/claude/ClaudeSessionLocator.js.map +1 -0
  210. package/dist/harnesses/claude/ClaudeSessionParser.d.ts +148 -0
  211. package/dist/harnesses/claude/ClaudeSessionParser.d.ts.map +1 -0
  212. package/dist/harnesses/claude/ClaudeSessionParser.js +365 -0
  213. package/dist/harnesses/claude/ClaudeSessionParser.js.map +1 -0
  214. package/dist/harnesses/claude/credentials.d.ts +10 -0
  215. package/dist/harnesses/claude/credentials.d.ts.map +1 -0
  216. package/dist/harnesses/claude/credentials.js +112 -0
  217. package/dist/harnesses/claude/credentials.js.map +1 -0
  218. package/dist/harnesses/claude/durable/ClaudeCliProbe.d.ts.map +1 -0
  219. package/dist/harnesses/claude/durable/ClaudeCliProbe.js.map +1 -0
  220. package/dist/harnesses/claude/durable/ClaudePrintAgentService.d.ts.map +1 -0
  221. package/dist/harnesses/claude/durable/ClaudePrintAgentService.js.map +1 -0
  222. package/dist/harnesses/claude/durable/ClaudePrintRunner.d.ts.map +1 -0
  223. package/dist/harnesses/claude/durable/ClaudePrintRunner.js.map +1 -0
  224. package/dist/harnesses/claude/durable/ClaudeStreamParser.d.ts.map +1 -0
  225. package/dist/harnesses/claude/durable/ClaudeStreamParser.js.map +1 -0
  226. package/dist/harnesses/claude/readiness.d.ts +3 -0
  227. package/dist/harnesses/claude/readiness.d.ts.map +1 -0
  228. package/dist/harnesses/claude/readiness.js +63 -0
  229. package/dist/harnesses/claude/readiness.js.map +1 -0
  230. package/dist/harnesses/codex/CodexAdapter.d.ts +29 -0
  231. package/dist/harnesses/codex/CodexAdapter.d.ts.map +1 -0
  232. package/dist/harnesses/codex/CodexAdapter.js +290 -0
  233. package/dist/harnesses/codex/CodexAdapter.js.map +1 -0
  234. package/dist/harnesses/codex/CodexAgentMapper.d.ts.map +1 -0
  235. package/dist/harnesses/codex/CodexAgentMapper.js +28 -0
  236. package/dist/harnesses/codex/CodexAgentMapper.js.map +1 -0
  237. package/dist/harnesses/codex/CodexSessionLocator.d.ts +74 -0
  238. package/dist/harnesses/codex/CodexSessionLocator.d.ts.map +1 -0
  239. package/dist/harnesses/codex/CodexSessionLocator.js +359 -0
  240. package/dist/harnesses/codex/CodexSessionLocator.js.map +1 -0
  241. package/dist/harnesses/codex/CodexSessionMapping.d.ts.map +1 -0
  242. package/dist/harnesses/codex/CodexSessionMapping.js +68 -0
  243. package/dist/harnesses/codex/CodexSessionMapping.js.map +1 -0
  244. package/dist/harnesses/codex/CodexSessionParser.d.ts +89 -0
  245. package/dist/harnesses/codex/CodexSessionParser.d.ts.map +1 -0
  246. package/dist/harnesses/codex/CodexSessionParser.js +308 -0
  247. package/dist/harnesses/codex/CodexSessionParser.js.map +1 -0
  248. package/dist/harnesses/codex/credentials.d.ts +15 -0
  249. package/dist/harnesses/codex/credentials.d.ts.map +1 -0
  250. package/dist/harnesses/codex/credentials.js +58 -0
  251. package/dist/harnesses/codex/credentials.js.map +1 -0
  252. package/dist/harnesses/codex/durable/CodexCliProbe.d.ts.map +1 -0
  253. package/dist/harnesses/codex/durable/CodexCliProbe.js.map +1 -0
  254. package/dist/harnesses/codex/durable/CodexPrintAgentService.d.ts.map +1 -0
  255. package/dist/harnesses/codex/durable/CodexPrintAgentService.js.map +1 -0
  256. package/dist/harnesses/codex/durable/CodexPrintRunner.d.ts.map +1 -0
  257. package/dist/harnesses/codex/durable/CodexPrintRunner.js.map +1 -0
  258. package/dist/harnesses/codex/durable/CodexStreamParser.d.ts.map +1 -0
  259. package/dist/harnesses/codex/durable/CodexStreamParser.js.map +1 -0
  260. package/dist/harnesses/codex/readiness.d.ts +3 -0
  261. package/dist/harnesses/codex/readiness.d.ts.map +1 -0
  262. package/dist/harnesses/codex/readiness.js +60 -0
  263. package/dist/harnesses/codex/readiness.js.map +1 -0
  264. package/dist/harnesses/copilot/CopilotAdapter.d.ts +36 -0
  265. package/dist/harnesses/copilot/CopilotAdapter.d.ts.map +1 -0
  266. package/dist/harnesses/copilot/CopilotAdapter.js +128 -0
  267. package/dist/harnesses/copilot/CopilotAdapter.js.map +1 -0
  268. package/dist/harnesses/copilot/CopilotAgentMapper.d.ts.map +1 -0
  269. package/dist/harnesses/copilot/CopilotAgentMapper.js +30 -0
  270. package/dist/harnesses/copilot/CopilotAgentMapper.js.map +1 -0
  271. package/dist/harnesses/copilot/CopilotSessionLocator.d.ts +42 -0
  272. package/dist/harnesses/copilot/CopilotSessionLocator.d.ts.map +1 -0
  273. package/dist/harnesses/copilot/CopilotSessionLocator.js +126 -0
  274. package/dist/harnesses/copilot/CopilotSessionLocator.js.map +1 -0
  275. package/dist/harnesses/copilot/CopilotSessionParser.d.ts +62 -0
  276. package/dist/harnesses/copilot/CopilotSessionParser.d.ts.map +1 -0
  277. package/dist/harnesses/copilot/CopilotSessionParser.js +236 -0
  278. package/dist/harnesses/copilot/CopilotSessionParser.js.map +1 -0
  279. package/dist/harnesses/copilot/readiness.d.ts +3 -0
  280. package/dist/harnesses/copilot/readiness.d.ts.map +1 -0
  281. package/dist/harnesses/copilot/readiness.js +39 -0
  282. package/dist/harnesses/copilot/readiness.js.map +1 -0
  283. package/dist/harnesses/gemini/GeminiAgentMapper.d.ts.map +1 -0
  284. package/dist/harnesses/gemini/GeminiAgentMapper.js +30 -0
  285. package/dist/harnesses/gemini/GeminiAgentMapper.js.map +1 -0
  286. package/dist/harnesses/gemini/GeminiCliAdapter.d.ts +52 -0
  287. package/dist/harnesses/gemini/GeminiCliAdapter.d.ts.map +1 -0
  288. package/dist/harnesses/gemini/GeminiCliAdapter.js +196 -0
  289. package/dist/harnesses/gemini/GeminiCliAdapter.js.map +1 -0
  290. package/dist/harnesses/gemini/GeminiSessionLocator.d.ts +72 -0
  291. package/dist/harnesses/gemini/GeminiSessionLocator.d.ts.map +1 -0
  292. package/dist/harnesses/gemini/GeminiSessionLocator.js +300 -0
  293. package/dist/harnesses/gemini/GeminiSessionLocator.js.map +1 -0
  294. package/dist/harnesses/gemini/GeminiSessionParser.d.ts +121 -0
  295. package/dist/harnesses/gemini/GeminiSessionParser.d.ts.map +1 -0
  296. package/dist/harnesses/gemini/GeminiSessionParser.js +272 -0
  297. package/dist/harnesses/gemini/GeminiSessionParser.js.map +1 -0
  298. package/dist/harnesses/gemini/fileSignature.d.ts +8 -0
  299. package/dist/harnesses/gemini/fileSignature.d.ts.map +1 -0
  300. package/dist/harnesses/gemini/fileSignature.js +9 -0
  301. package/dist/harnesses/gemini/fileSignature.js.map +1 -0
  302. package/dist/harnesses/grok/GrokAgentMapper.d.ts.map +1 -0
  303. package/dist/harnesses/grok/GrokAgentMapper.js +30 -0
  304. package/dist/harnesses/grok/GrokAgentMapper.js.map +1 -0
  305. package/dist/harnesses/grok/GrokCliAdapter.d.ts +36 -0
  306. package/dist/harnesses/grok/GrokCliAdapter.d.ts.map +1 -0
  307. package/dist/harnesses/grok/GrokCliAdapter.js +102 -0
  308. package/dist/harnesses/grok/GrokCliAdapter.js.map +1 -0
  309. package/dist/harnesses/grok/GrokSessionLocator.d.ts.map +1 -0
  310. package/dist/harnesses/grok/GrokSessionLocator.js +140 -0
  311. package/dist/harnesses/grok/GrokSessionLocator.js.map +1 -0
  312. package/dist/harnesses/grok/GrokSessionParser.d.ts +87 -0
  313. package/dist/harnesses/grok/GrokSessionParser.d.ts.map +1 -0
  314. package/dist/harnesses/grok/GrokSessionParser.js +185 -0
  315. package/dist/harnesses/grok/GrokSessionParser.js.map +1 -0
  316. package/dist/harnesses/index.d.ts +7 -0
  317. package/dist/harnesses/index.d.ts.map +1 -0
  318. package/dist/harnesses/index.js +27 -0
  319. package/dist/harnesses/index.js.map +1 -0
  320. package/dist/harnesses/kiro/KiroAdapter.d.ts +31 -0
  321. package/dist/harnesses/kiro/KiroAdapter.d.ts.map +1 -0
  322. package/dist/harnesses/kiro/KiroAdapter.js +125 -0
  323. package/dist/harnesses/kiro/KiroAdapter.js.map +1 -0
  324. package/dist/harnesses/kiro/KiroAgentMapper.d.ts +13 -0
  325. package/dist/harnesses/kiro/KiroAgentMapper.d.ts.map +1 -0
  326. package/dist/harnesses/kiro/KiroAgentMapper.js +29 -0
  327. package/dist/harnesses/kiro/KiroAgentMapper.js.map +1 -0
  328. package/dist/harnesses/kiro/KiroSessionLocator.d.ts +38 -0
  329. package/dist/harnesses/kiro/KiroSessionLocator.d.ts.map +1 -0
  330. package/dist/harnesses/kiro/KiroSessionLocator.js +95 -0
  331. package/dist/harnesses/kiro/KiroSessionLocator.js.map +1 -0
  332. package/dist/harnesses/kiro/KiroSessionParser.d.ts +81 -0
  333. package/dist/harnesses/kiro/KiroSessionParser.d.ts.map +1 -0
  334. package/dist/harnesses/kiro/KiroSessionParser.js +251 -0
  335. package/dist/harnesses/kiro/KiroSessionParser.js.map +1 -0
  336. package/dist/harnesses/opencode/OpenCodeAdapter.d.ts +29 -0
  337. package/dist/harnesses/opencode/OpenCodeAdapter.d.ts.map +1 -0
  338. package/dist/harnesses/opencode/OpenCodeAdapter.js +86 -0
  339. package/dist/harnesses/opencode/OpenCodeAdapter.js.map +1 -0
  340. package/dist/harnesses/opencode/OpenCodeAgentMapper.d.ts.map +1 -0
  341. package/dist/harnesses/opencode/OpenCodeAgentMapper.js +42 -0
  342. package/dist/harnesses/opencode/OpenCodeAgentMapper.js.map +1 -0
  343. package/dist/harnesses/opencode/OpenCodeSessionLocator.d.ts.map +1 -0
  344. package/dist/harnesses/opencode/OpenCodeSessionLocator.js +118 -0
  345. package/dist/harnesses/opencode/OpenCodeSessionLocator.js.map +1 -0
  346. package/dist/harnesses/opencode/OpenCodeSessionParser.d.ts +16 -0
  347. package/dist/harnesses/opencode/OpenCodeSessionParser.d.ts.map +1 -0
  348. package/dist/harnesses/opencode/OpenCodeSessionParser.js +105 -0
  349. package/dist/harnesses/opencode/OpenCodeSessionParser.js.map +1 -0
  350. package/dist/harnesses/opencode/readiness.d.ts +3 -0
  351. package/dist/harnesses/opencode/readiness.d.ts.map +1 -0
  352. package/dist/harnesses/opencode/readiness.js +50 -0
  353. package/dist/harnesses/opencode/readiness.js.map +1 -0
  354. package/dist/harnesses/pi/PiAdapter.d.ts +30 -0
  355. package/dist/harnesses/pi/PiAdapter.d.ts.map +1 -0
  356. package/dist/harnesses/pi/PiAdapter.js +167 -0
  357. package/dist/harnesses/pi/PiAdapter.js.map +1 -0
  358. package/dist/harnesses/pi/PiAgentMapper.d.ts.map +1 -0
  359. package/dist/harnesses/pi/PiAgentMapper.js +30 -0
  360. package/dist/harnesses/pi/PiAgentMapper.js.map +1 -0
  361. package/dist/harnesses/pi/PiSessionLocator.d.ts +61 -0
  362. package/dist/harnesses/pi/PiSessionLocator.d.ts.map +1 -0
  363. package/dist/harnesses/pi/PiSessionLocator.js +212 -0
  364. package/dist/harnesses/pi/PiSessionLocator.js.map +1 -0
  365. package/dist/harnesses/pi/PiSessionParser.d.ts +88 -0
  366. package/dist/harnesses/pi/PiSessionParser.d.ts.map +1 -0
  367. package/dist/harnesses/pi/PiSessionParser.js +318 -0
  368. package/dist/harnesses/pi/PiSessionParser.js.map +1 -0
  369. package/dist/harnesses/pi/PiSessionTracker.d.ts.map +1 -0
  370. package/dist/harnesses/pi/PiSessionTracker.js +69 -0
  371. package/dist/harnesses/pi/PiSessionTracker.js.map +1 -0
  372. package/dist/harnesses/pi/credentials.d.ts +22 -0
  373. package/dist/harnesses/pi/credentials.d.ts.map +1 -0
  374. package/dist/harnesses/pi/credentials.js +98 -0
  375. package/dist/harnesses/pi/credentials.js.map +1 -0
  376. package/dist/harnesses/pi/durable/PiCliProbe.d.ts.map +1 -0
  377. package/dist/harnesses/pi/durable/PiCliProbe.js.map +1 -0
  378. package/dist/harnesses/pi/durable/PiPrintAgentService.d.ts.map +1 -0
  379. package/dist/harnesses/pi/durable/PiPrintAgentService.js.map +1 -0
  380. package/dist/harnesses/pi/durable/PiPrintProtocol.d.ts.map +1 -0
  381. package/dist/harnesses/pi/durable/PiPrintProtocol.js.map +1 -0
  382. package/dist/harnesses/pi/durable/PiPrintRunner.d.ts.map +1 -0
  383. package/dist/harnesses/pi/durable/PiPrintRunner.js.map +1 -0
  384. package/dist/harnesses/pi/durable/PiStreamParser.d.ts.map +1 -0
  385. package/dist/harnesses/pi/durable/PiStreamParser.js.map +1 -0
  386. package/dist/harnesses/pi/readiness.d.ts +3 -0
  387. package/dist/harnesses/pi/readiness.d.ts.map +1 -0
  388. package/dist/harnesses/pi/readiness.js +96 -0
  389. package/dist/harnesses/pi/readiness.js.map +1 -0
  390. package/dist/harnesses/readiness/AgentReadiness.d.ts +6 -0
  391. package/dist/harnesses/readiness/AgentReadiness.d.ts.map +1 -0
  392. package/dist/harnesses/readiness/AgentReadiness.js +68 -0
  393. package/dist/harnesses/readiness/AgentReadiness.js.map +1 -0
  394. package/dist/harnesses/readiness/checks.d.ts +31 -0
  395. package/dist/harnesses/readiness/checks.d.ts.map +1 -0
  396. package/dist/harnesses/readiness/checks.js +270 -0
  397. package/dist/harnesses/readiness/checks.js.map +1 -0
  398. package/dist/harnesses/readiness/types.d.ts +76 -0
  399. package/dist/harnesses/readiness/types.d.ts.map +1 -0
  400. package/dist/harnesses/readiness/types.js +4 -0
  401. package/dist/harnesses/readiness/types.js.map +1 -0
  402. package/dist/harnesses/runtimeProfiles.d.ts +11 -0
  403. package/dist/harnesses/runtimeProfiles.d.ts.map +1 -0
  404. package/dist/harnesses/runtimeProfiles.js +99 -0
  405. package/dist/harnesses/runtimeProfiles.js.map +1 -0
  406. package/dist/harnesses/shared.d.ts +41 -0
  407. package/dist/harnesses/shared.d.ts.map +1 -0
  408. package/dist/harnesses/shared.js +71 -0
  409. package/dist/harnesses/shared.js.map +1 -0
  410. package/dist/index.d.ts +21 -46
  411. package/dist/index.d.ts.map +1 -1
  412. package/dist/index.js +14 -27
  413. package/dist/index.js.map +1 -1
  414. package/dist/runtime/ManagedAgentRuntime.d.ts +3 -3
  415. package/dist/runtime/ManagedAgentRuntime.d.ts.map +1 -1
  416. package/dist/runtime/ManagedAgentRuntime.js +6 -20
  417. package/dist/runtime/ManagedAgentRuntime.js.map +1 -1
  418. package/dist/runtime/herdr/HerdrAgentDiscovery.d.ts.map +1 -1
  419. package/dist/runtime/herdr/HerdrAgentDiscovery.js +2 -43
  420. package/dist/runtime/herdr/HerdrAgentDiscovery.js.map +1 -1
  421. package/dist/runtime/tmux/PidPolling.d.ts +1 -1
  422. package/dist/runtime/tmux/PidPolling.d.ts.map +1 -1
  423. package/dist/runtime/tmux/PidPolling.js.map +1 -1
  424. package/dist/runtime/tmux/TmuxAgentRuntime.d.ts +1 -1
  425. package/dist/runtime/tmux/TmuxAgentRuntime.d.ts.map +1 -1
  426. package/dist/runtime/tmux/TmuxAgentRuntime.js +1 -1
  427. package/dist/runtime/tmux/TmuxAgentRuntime.js.map +1 -1
  428. package/dist/runtime/tmux/TmuxManager.d.ts +12 -0
  429. package/dist/runtime/tmux/TmuxManager.d.ts.map +1 -0
  430. package/dist/runtime/tmux/TmuxManager.js +116 -0
  431. package/dist/runtime/tmux/TmuxManager.js.map +1 -0
  432. package/dist/runtime/types.d.ts +1 -1
  433. package/dist/runtime/types.d.ts.map +1 -1
  434. package/dist/runtime/types.js.map +1 -1
  435. package/dist/terminal/TerminalFocusManager.d.ts +4 -32
  436. package/dist/terminal/TerminalFocusManager.d.ts.map +1 -1
  437. package/dist/terminal/TerminalFocusManager.js +17 -267
  438. package/dist/terminal/TerminalFocusManager.js.map +1 -1
  439. package/dist/terminal/TtyWriter.d.ts +1 -44
  440. package/dist/terminal/TtyWriter.d.ts.map +1 -1
  441. package/dist/terminal/TtyWriter.js +11 -347
  442. package/dist/terminal/TtyWriter.js.map +1 -1
  443. package/dist/terminal/backends/index.d.ts +5 -0
  444. package/dist/terminal/backends/index.d.ts.map +1 -0
  445. package/dist/terminal/backends/index.js +19 -0
  446. package/dist/terminal/backends/index.js.map +1 -0
  447. package/dist/terminal/backends/iterm2.d.ts +3 -0
  448. package/dist/terminal/backends/iterm2.d.ts.map +1 -0
  449. package/dist/terminal/backends/iterm2.js +135 -0
  450. package/dist/terminal/backends/iterm2.js.map +1 -0
  451. package/dist/terminal/backends/shared.d.ts +7 -0
  452. package/dist/terminal/backends/shared.d.ts.map +1 -0
  453. package/dist/terminal/backends/shared.js +35 -0
  454. package/dist/terminal/backends/shared.js.map +1 -0
  455. package/dist/terminal/backends/terminal-app.d.ts +3 -0
  456. package/dist/terminal/backends/terminal-app.d.ts.map +1 -0
  457. package/dist/terminal/backends/terminal-app.js +129 -0
  458. package/dist/terminal/backends/terminal-app.js.map +1 -0
  459. package/dist/terminal/backends/tmux.d.ts +3 -0
  460. package/dist/terminal/backends/tmux.d.ts.map +1 -0
  461. package/dist/terminal/backends/tmux.js +76 -0
  462. package/dist/terminal/backends/tmux.js.map +1 -0
  463. package/dist/terminal/backends/wezterm.d.ts +3 -0
  464. package/dist/terminal/backends/wezterm.d.ts.map +1 -0
  465. package/dist/terminal/backends/wezterm.js +71 -0
  466. package/dist/terminal/backends/wezterm.js.map +1 -0
  467. package/dist/terminal/types.d.ts +21 -0
  468. package/dist/terminal/types.d.ts.map +1 -0
  469. package/dist/terminal/types.js +10 -0
  470. package/dist/terminal/types.js.map +1 -0
  471. package/dist/utils/IncrementalJsonlSummary.d.ts +100 -0
  472. package/dist/utils/IncrementalJsonlSummary.d.ts.map +1 -0
  473. package/dist/utils/IncrementalJsonlSummary.js +209 -0
  474. package/dist/utils/IncrementalJsonlSummary.js.map +1 -0
  475. package/dist/utils/jsonlTail.d.ts +73 -0
  476. package/dist/utils/jsonlTail.d.ts.map +1 -0
  477. package/dist/utils/jsonlTail.js +238 -0
  478. package/dist/utils/jsonlTail.js.map +1 -0
  479. package/dist/utils/matching.d.ts +2 -0
  480. package/dist/utils/matching.d.ts.map +1 -1
  481. package/dist/utils/matching.js +3 -2
  482. package/dist/utils/matching.js.map +1 -1
  483. package/dist/utils/matchingConstants.d.ts +15 -0
  484. package/dist/utils/matchingConstants.d.ts.map +1 -0
  485. package/dist/utils/matchingConstants.js +14 -0
  486. package/dist/utils/matchingConstants.js.map +1 -0
  487. package/dist/utils/process.d.ts +38 -2
  488. package/dist/utils/process.d.ts.map +1 -1
  489. package/dist/utils/process.js +131 -43
  490. package/dist/utils/process.js.map +1 -1
  491. package/package.json +2 -1
  492. package/scripts/benchmark-cold-start.mjs +350 -0
  493. package/src/AgentManager.ts +27 -6
  494. package/src/__tests__/AgentManager.test.ts +141 -3
  495. package/src/__tests__/adapters/IncrementalSessionRefresh.test.ts +437 -0
  496. package/src/__tests__/adapters/adapterProcessImports.test.ts +58 -0
  497. package/src/__tests__/adapters/adapterSnapshotCandidates.test.ts +243 -0
  498. package/src/__tests__/capacity/anthropic.test.ts +105 -0
  499. package/src/__tests__/capacity/boundaries.test.ts +36 -0
  500. package/src/__tests__/capacity/claude.test.ts +3 -8
  501. package/src/__tests__/capacity/codex.test.ts +12 -35
  502. package/src/__tests__/capacity/fixtures/openai-codex-auth.json +1 -1
  503. package/src/__tests__/capacity/openai.test.ts +20 -30
  504. package/src/__tests__/capacity/wham.test.ts +1 -1
  505. package/src/__tests__/capacity/zai.test.ts +27 -62
  506. package/src/__tests__/harnesses/BoundedSummarySkip.test.ts +496 -0
  507. package/src/__tests__/harnesses/SessionSummaryEquivalence.test.ts +726 -0
  508. package/src/__tests__/harnesses/antigravity/AntigravityCliAdapter.subprocess.test.ts +133 -0
  509. package/src/__tests__/harnesses/antigravity/AntigravityCliAdapter.test.ts +396 -0
  510. package/src/__tests__/harnesses/builtinAdapters.test.ts +33 -0
  511. package/src/__tests__/harnesses/claude/ClaudeAgentMapper.test.ts +84 -0
  512. package/src/__tests__/harnesses/claude/ClaudeCodeAdapter.test.ts +1793 -0
  513. package/src/__tests__/harnesses/claude/ClaudeSessionLocator.test.ts +423 -0
  514. package/src/__tests__/harnesses/claude/ClaudeSessionParser.test.ts +300 -0
  515. package/src/__tests__/harnesses/claude/durable/ClaudeCliProbe.test.ts +34 -0
  516. package/src/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.ts +61 -0
  517. package/src/__tests__/harnesses/claude/durable/ClaudePrintAgentService.test.ts +129 -0
  518. package/src/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.ts +152 -0
  519. package/src/__tests__/harnesses/codex/CodexAdapter.test.ts +652 -0
  520. package/src/__tests__/harnesses/codex/CodexSessionLocator.test.ts +419 -0
  521. package/src/__tests__/harnesses/codex/CodexSessionMapping.test.ts +63 -0
  522. package/src/__tests__/harnesses/codex/CodexSessionParser.test.ts +192 -0
  523. package/src/__tests__/harnesses/codex/durable/CodexCliProbe.test.ts +80 -0
  524. package/src/__tests__/harnesses/codex/durable/CodexDurableAgentRepository.test.ts +65 -0
  525. package/src/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.ts +104 -0
  526. package/src/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.ts +201 -0
  527. package/src/__tests__/harnesses/codex/durable/CodexPrintRunner.test.ts +299 -0
  528. package/src/__tests__/harnesses/copilot/CopilotAdapter.test.ts +614 -0
  529. package/src/__tests__/harnesses/copilot/CopilotRefreshIO.test.ts +270 -0
  530. package/src/__tests__/harnesses/gemini/GeminiCliAdapter.test.ts +1324 -0
  531. package/src/__tests__/harnesses/gemini/GeminiSessionJsonl.test.ts +402 -0
  532. package/src/__tests__/harnesses/gemini/GeminiSessionLocator.test.ts +396 -0
  533. package/src/__tests__/harnesses/grok/GrokAgentMapper.test.ts +57 -0
  534. package/src/__tests__/harnesses/grok/GrokCliAdapter.test.ts +376 -0
  535. package/src/__tests__/harnesses/grok/GrokIncrementalRefresh.test.ts +170 -0
  536. package/src/__tests__/harnesses/grok/GrokSessionLocator.test.ts +106 -0
  537. package/src/__tests__/harnesses/grok/GrokSessionParser.test.ts +230 -0
  538. package/src/__tests__/harnesses/kiro/KiroAdapter.test.ts +552 -0
  539. package/src/__tests__/harnesses/opencode/OpenCodeAdapter.test.ts +215 -0
  540. package/src/__tests__/harnesses/opencode/OpenCodeAgentMapper.test.ts +83 -0
  541. package/src/__tests__/harnesses/opencode/OpenCodeSessionLocator.test.ts +84 -0
  542. package/src/__tests__/harnesses/opencode/OpenCodeSessionParser.test.ts +148 -0
  543. package/src/__tests__/harnesses/pi/PiAdapter.test.ts +325 -0
  544. package/src/__tests__/harnesses/pi/PiDiscoveryIO.test.ts +337 -0
  545. package/src/__tests__/harnesses/pi/PiSessionParser.test.ts +280 -0
  546. package/src/__tests__/harnesses/pi/PiSessionTracker.test.ts +79 -0
  547. package/src/__tests__/harnesses/pi/durable/PiCliProbe.test.ts +50 -0
  548. package/src/__tests__/harnesses/pi/durable/PiPrintAgentService.test.ts +138 -0
  549. package/src/__tests__/harnesses/pi/durable/PiPrintProtocol.test.ts +71 -0
  550. package/src/__tests__/harnesses/pi/durable/PiPrintRunner.test.ts +252 -0
  551. package/src/__tests__/harnesses/pi/durable/PiStreamParser.test.ts +26 -0
  552. package/src/__tests__/harnesses/readiness/AgentReadiness.test.ts +285 -0
  553. package/src/__tests__/harnesses/runtimeProfiles.test.ts +110 -0
  554. package/src/__tests__/print/DurableAgent.test.ts +4 -13
  555. package/src/__tests__/print/DurableAgentRepository.test.ts +1 -13
  556. package/src/__tests__/runtime/ManagedAgentRuntime.test.ts +31 -1
  557. package/src/__tests__/terminal/TmuxManager.test.ts +1 -1
  558. package/src/__tests__/utils/IncrementalJsonlSummary.test.ts +414 -0
  559. package/src/__tests__/utils/conversationTail.bench.test.ts +193 -0
  560. package/src/__tests__/utils/conversationTailParity.test.ts +365 -0
  561. package/src/__tests__/utils/jsonlTail.test.ts +317 -0
  562. package/src/__tests__/utils/matchingConstants.test.ts +40 -0
  563. package/src/__tests__/utils/process.test.ts +254 -0
  564. package/src/adapters/AgentAdapter.ts +37 -14
  565. package/src/capacity/index.ts +29 -23
  566. package/src/capacity/providers/anthropic.ts +198 -0
  567. package/src/capacity/providers/openai-platform.ts +150 -0
  568. package/src/capacity/providers/openai-subscription.ts +162 -0
  569. package/src/capacity/providers/zai.ts +155 -0
  570. package/src/capacity/sources/claude.ts +30 -0
  571. package/src/capacity/sources/codex.ts +262 -0
  572. package/src/capacity/sources/pi.ts +131 -0
  573. package/src/capacity/types.ts +3 -0
  574. package/src/harnesses/antigravity/AntigravityAgentMapper.ts +34 -0
  575. package/src/harnesses/antigravity/AntigravityCliAdapter.ts +126 -0
  576. package/src/harnesses/antigravity/AntigravitySessionLocator.ts +75 -0
  577. package/src/harnesses/antigravity/AntigravitySessionParser.ts +252 -0
  578. package/src/harnesses/claude/ClaudeAgentMapper.ts +55 -0
  579. package/src/harnesses/claude/ClaudeCodeAdapter.ts +175 -0
  580. package/src/harnesses/claude/ClaudeSessionLocator.ts +358 -0
  581. package/src/harnesses/claude/ClaudeSessionParser.ts +524 -0
  582. package/src/harnesses/claude/credentials.ts +122 -0
  583. package/src/harnesses/claude/readiness.ts +69 -0
  584. package/src/harnesses/codex/CodexAdapter.ts +337 -0
  585. package/src/harnesses/codex/CodexAgentMapper.ts +26 -0
  586. package/src/harnesses/codex/CodexSessionLocator.ts +509 -0
  587. package/src/harnesses/codex/CodexSessionMapping.ts +89 -0
  588. package/src/harnesses/codex/CodexSessionParser.ts +462 -0
  589. package/src/harnesses/codex/credentials.ts +81 -0
  590. package/src/harnesses/codex/readiness.ts +72 -0
  591. package/src/harnesses/copilot/CopilotAdapter.ts +161 -0
  592. package/src/harnesses/copilot/CopilotAgentMapper.ts +27 -0
  593. package/src/harnesses/copilot/CopilotSessionLocator.ts +161 -0
  594. package/src/harnesses/copilot/CopilotSessionParser.ts +380 -0
  595. package/src/harnesses/copilot/readiness.ts +33 -0
  596. package/src/harnesses/gemini/GeminiAgentMapper.ts +27 -0
  597. package/src/harnesses/gemini/GeminiCliAdapter.ts +272 -0
  598. package/src/harnesses/gemini/GeminiSessionLocator.ts +394 -0
  599. package/src/harnesses/gemini/GeminiSessionParser.ts +395 -0
  600. package/src/harnesses/gemini/fileSignature.ts +10 -0
  601. package/src/harnesses/grok/GrokAgentMapper.ts +32 -0
  602. package/src/harnesses/grok/GrokCliAdapter.ts +126 -0
  603. package/src/harnesses/grok/GrokSessionLocator.ts +179 -0
  604. package/src/harnesses/grok/GrokSessionParser.ts +251 -0
  605. package/src/harnesses/index.ts +28 -0
  606. package/src/harnesses/kiro/KiroAdapter.ts +143 -0
  607. package/src/harnesses/kiro/KiroAgentMapper.ts +34 -0
  608. package/src/harnesses/kiro/KiroSessionLocator.ts +143 -0
  609. package/src/harnesses/kiro/KiroSessionParser.ts +376 -0
  610. package/src/harnesses/opencode/OpenCodeAdapter.ts +110 -0
  611. package/src/harnesses/opencode/OpenCodeAgentMapper.ts +51 -0
  612. package/src/harnesses/opencode/OpenCodeSessionLocator.ts +151 -0
  613. package/src/harnesses/opencode/OpenCodeSessionParser.ts +146 -0
  614. package/src/harnesses/opencode/readiness.ts +48 -0
  615. package/src/harnesses/pi/PiAdapter.ts +197 -0
  616. package/src/harnesses/pi/PiAgentMapper.ts +27 -0
  617. package/src/harnesses/pi/PiSessionLocator.ts +288 -0
  618. package/src/harnesses/pi/PiSessionParser.ts +488 -0
  619. package/src/harnesses/pi/PiSessionTracker.ts +87 -0
  620. package/src/harnesses/pi/credentials.ts +129 -0
  621. package/src/harnesses/pi/readiness.ts +104 -0
  622. package/src/harnesses/readiness/AgentReadiness.ts +87 -0
  623. package/src/harnesses/readiness/checks.ts +336 -0
  624. package/src/harnesses/readiness/types.ts +90 -0
  625. package/src/harnesses/runtimeProfiles.ts +103 -0
  626. package/src/harnesses/shared.ts +119 -0
  627. package/src/index.ts +20 -131
  628. package/src/runtime/ManagedAgentRuntime.ts +7 -22
  629. package/src/runtime/herdr/HerdrAgentDiscovery.ts +3 -19
  630. package/src/runtime/tmux/PidPolling.ts +1 -1
  631. package/src/runtime/tmux/TmuxAgentRuntime.ts +1 -1
  632. package/src/runtime/tmux/TmuxManager.ts +102 -0
  633. package/src/runtime/types.ts +1 -1
  634. package/src/terminal/TerminalFocusManager.ts +19 -292
  635. package/src/terminal/TtyWriter.ts +16 -336
  636. package/src/terminal/backends/index.ts +21 -0
  637. package/src/terminal/backends/iterm2.ts +126 -0
  638. package/src/terminal/backends/shared.ts +42 -0
  639. package/src/terminal/backends/terminal-app.ts +122 -0
  640. package/src/terminal/backends/tmux.ts +62 -0
  641. package/src/terminal/backends/wezterm.ts +65 -0
  642. package/src/terminal/types.ts +22 -0
  643. package/src/utils/IncrementalJsonlSummary.ts +306 -0
  644. package/src/utils/jsonlTail.ts +349 -0
  645. package/src/utils/matching.ts +3 -3
  646. package/src/utils/matchingConstants.ts +15 -0
  647. package/src/utils/process.ts +189 -45
  648. package/dist/__tests__/adapters/AntigravityCliAdapter.test.js +0 -381
  649. package/dist/__tests__/adapters/AntigravityCliAdapter.test.js.map +0 -1
  650. package/dist/__tests__/adapters/ClaudeCodeAdapter.test.js +0 -1853
  651. package/dist/__tests__/adapters/ClaudeCodeAdapter.test.js.map +0 -1
  652. package/dist/__tests__/adapters/CodexAdapter.test.js +0 -391
  653. package/dist/__tests__/adapters/CodexAdapter.test.js.map +0 -1
  654. package/dist/__tests__/adapters/KiroAdapter.test.js +0 -607
  655. package/dist/__tests__/adapters/KiroAdapter.test.js.map +0 -1
  656. package/dist/__tests__/durable/CodexCliProbe.test.js +0 -129
  657. package/dist/__tests__/durable/CodexCliProbe.test.js.map +0 -1
  658. package/dist/__tests__/durable/CodexDurableAgentRepository.test.js +0 -84
  659. package/dist/__tests__/durable/CodexDurableAgentRepository.test.js.map +0 -1
  660. package/dist/__tests__/durable/CodexPrintAgent.integration.test.js +0 -126
  661. package/dist/__tests__/durable/CodexPrintAgent.integration.test.js.map +0 -1
  662. package/dist/__tests__/durable/CodexPrintAgentService.test.js +0 -271
  663. package/dist/__tests__/durable/CodexPrintAgentService.test.js.map +0 -1
  664. package/dist/__tests__/durable/CodexPrintRunner.test.js +0 -393
  665. package/dist/__tests__/durable/CodexPrintRunner.test.js.map +0 -1
  666. package/dist/__tests__/print/ClaudeCliProbe.test.js +0 -49
  667. package/dist/__tests__/print/ClaudeCliProbe.test.js.map +0 -1
  668. package/dist/__tests__/print/ClaudePrintAgent.integration.test.js +0 -75
  669. package/dist/__tests__/print/ClaudePrintAgent.integration.test.js.map +0 -1
  670. package/dist/__tests__/print/ClaudePrintAgentService.test.js +0 -173
  671. package/dist/__tests__/print/ClaudePrintAgentService.test.js.map +0 -1
  672. package/dist/__tests__/print/ClaudePrintRunner.test.js +0 -181
  673. package/dist/__tests__/print/ClaudePrintRunner.test.js.map +0 -1
  674. package/dist/__tests__/providers/claude/ClaudeAgentMapper.test.js +0 -79
  675. package/dist/__tests__/providers/claude/ClaudeAgentMapper.test.js.map +0 -1
  676. package/dist/__tests__/providers/claude/ClaudeSessionLocator.test.js +0 -436
  677. package/dist/__tests__/providers/claude/ClaudeSessionLocator.test.js.map +0 -1
  678. package/dist/__tests__/providers/codex/CodexSessionLocator.test.js +0 -194
  679. package/dist/__tests__/providers/codex/CodexSessionLocator.test.js.map +0 -1
  680. package/dist/__tests__/providers/codex/CodexSessionMapping.test.js +0 -86
  681. package/dist/__tests__/providers/codex/CodexSessionMapping.test.js.map +0 -1
  682. package/dist/__tests__/providers/codex/CodexSessionParser.test.js +0 -254
  683. package/dist/__tests__/providers/codex/CodexSessionParser.test.js.map +0 -1
  684. package/dist/__tests__/providers/copilot/CopilotAdapter.test.js +0 -659
  685. package/dist/__tests__/providers/copilot/CopilotAdapter.test.js.map +0 -1
  686. package/dist/__tests__/providers/gemini/GeminiCliAdapter.test.js +0 -1434
  687. package/dist/__tests__/providers/gemini/GeminiCliAdapter.test.js.map +0 -1
  688. package/dist/__tests__/providers/grok/GrokAgentMapper.test.js +0 -56
  689. package/dist/__tests__/providers/grok/GrokAgentMapper.test.js.map +0 -1
  690. package/dist/__tests__/providers/grok/GrokCliAdapter.test.js +0 -421
  691. package/dist/__tests__/providers/grok/GrokCliAdapter.test.js.map +0 -1
  692. package/dist/__tests__/providers/grok/GrokSessionLocator.test.js +0 -133
  693. package/dist/__tests__/providers/grok/GrokSessionLocator.test.js.map +0 -1
  694. package/dist/__tests__/providers/opencode/OpenCodeAdapter.test.js +0 -213
  695. package/dist/__tests__/providers/opencode/OpenCodeAdapter.test.js.map +0 -1
  696. package/dist/__tests__/providers/opencode/OpenCodeAgentMapper.test.js +0 -89
  697. package/dist/__tests__/providers/opencode/OpenCodeAgentMapper.test.js.map +0 -1
  698. package/dist/__tests__/providers/opencode/OpenCodeSessionLocator.test.js +0 -94
  699. package/dist/__tests__/providers/opencode/OpenCodeSessionLocator.test.js.map +0 -1
  700. package/dist/__tests__/providers/opencode/OpenCodeSessionParser.test.js +0 -147
  701. package/dist/__tests__/providers/opencode/OpenCodeSessionParser.test.js.map +0 -1
  702. package/dist/__tests__/providers/pi/PiAdapter.test.js +0 -367
  703. package/dist/__tests__/providers/pi/PiAdapter.test.js.map +0 -1
  704. package/dist/__tests__/providers/pi/PiSessionParser.test.js +0 -246
  705. package/dist/__tests__/providers/pi/PiSessionParser.test.js.map +0 -1
  706. package/dist/__tests__/providers/pi/PiSessionTracker.test.js +0 -108
  707. package/dist/__tests__/providers/pi/PiSessionTracker.test.js.map +0 -1
  708. package/dist/__tests__/providers/pi/durable/PiCliProbe.test.js +0 -76
  709. package/dist/__tests__/providers/pi/durable/PiCliProbe.test.js.map +0 -1
  710. package/dist/__tests__/providers/pi/durable/PiDurableAgentRepository.test.js.map +0 -1
  711. package/dist/__tests__/providers/pi/durable/PiPrintAgentService.test.js +0 -202
  712. package/dist/__tests__/providers/pi/durable/PiPrintAgentService.test.js.map +0 -1
  713. package/dist/__tests__/providers/pi/durable/PiPrintProtocol.test.js +0 -119
  714. package/dist/__tests__/providers/pi/durable/PiPrintProtocol.test.js.map +0 -1
  715. package/dist/__tests__/providers/pi/durable/PiPrintRunner.test.js +0 -386
  716. package/dist/__tests__/providers/pi/durable/PiPrintRunner.test.js.map +0 -1
  717. package/dist/__tests__/providers/pi/durable/PiStreamParser.test.js +0 -34
  718. package/dist/__tests__/providers/pi/durable/PiStreamParser.test.js.map +0 -1
  719. package/dist/__tests__/readiness/AgentReadiness.test.js +0 -301
  720. package/dist/__tests__/readiness/AgentReadiness.test.js.map +0 -1
  721. package/dist/__tests__/utils/ClaudeSessionParser.test.js +0 -314
  722. package/dist/__tests__/utils/ClaudeSessionParser.test.js.map +0 -1
  723. package/dist/__tests__/utils/agents.test.js +0 -29
  724. package/dist/__tests__/utils/agents.test.js.map +0 -1
  725. package/dist/adapters/AntigravityCliAdapter.d.ts +0 -57
  726. package/dist/adapters/AntigravityCliAdapter.d.ts.map +0 -1
  727. package/dist/adapters/AntigravityCliAdapter.js +0 -273
  728. package/dist/adapters/AntigravityCliAdapter.js.map +0 -1
  729. package/dist/adapters/KiroAdapter.d.ts +0 -46
  730. package/dist/adapters/KiroAdapter.d.ts.map +0 -1
  731. package/dist/adapters/KiroAdapter.js +0 -344
  732. package/dist/adapters/KiroAdapter.js.map +0 -1
  733. package/dist/adapters/index.d.ts +0 -12
  734. package/dist/adapters/index.d.ts.map +0 -1
  735. package/dist/adapters/index.js +0 -12
  736. package/dist/adapters/index.js.map +0 -1
  737. package/dist/capacity/claude.d.ts +0 -17
  738. package/dist/capacity/claude.d.ts.map +0 -1
  739. package/dist/capacity/claude.js +0 -271
  740. package/dist/capacity/claude.js.map +0 -1
  741. package/dist/capacity/codex.d.ts +0 -36
  742. package/dist/capacity/codex.d.ts.map +0 -1
  743. package/dist/capacity/codex.js +0 -280
  744. package/dist/capacity/codex.js.map +0 -1
  745. package/dist/capacity/openai.d.ts +0 -48
  746. package/dist/capacity/openai.d.ts.map +0 -1
  747. package/dist/capacity/openai.js +0 -312
  748. package/dist/capacity/openai.js.map +0 -1
  749. package/dist/capacity/wham.d.ts +0 -16
  750. package/dist/capacity/wham.d.ts.map +0 -1
  751. package/dist/capacity/wham.js +0 -66
  752. package/dist/capacity/wham.js.map +0 -1
  753. package/dist/capacity/zai.d.ts +0 -14
  754. package/dist/capacity/zai.d.ts.map +0 -1
  755. package/dist/capacity/zai.js +0 -203
  756. package/dist/capacity/zai.js.map +0 -1
  757. package/dist/providers/claude/ClaudeAgentMapper.d.ts.map +0 -1
  758. package/dist/providers/claude/ClaudeAgentMapper.js +0 -42
  759. package/dist/providers/claude/ClaudeAgentMapper.js.map +0 -1
  760. package/dist/providers/claude/ClaudeCodeAdapter.d.ts +0 -31
  761. package/dist/providers/claude/ClaudeCodeAdapter.d.ts.map +0 -1
  762. package/dist/providers/claude/ClaudeCodeAdapter.js +0 -132
  763. package/dist/providers/claude/ClaudeCodeAdapter.js.map +0 -1
  764. package/dist/providers/claude/ClaudeSessionLocator.d.ts.map +0 -1
  765. package/dist/providers/claude/ClaudeSessionLocator.js +0 -260
  766. package/dist/providers/claude/ClaudeSessionLocator.js.map +0 -1
  767. package/dist/providers/claude/ClaudeSessionParser.d.ts +0 -114
  768. package/dist/providers/claude/ClaudeSessionParser.d.ts.map +0 -1
  769. package/dist/providers/claude/ClaudeSessionParser.js +0 -309
  770. package/dist/providers/claude/ClaudeSessionParser.js.map +0 -1
  771. package/dist/providers/claude/durable/ClaudeCliProbe.d.ts.map +0 -1
  772. package/dist/providers/claude/durable/ClaudeCliProbe.js.map +0 -1
  773. package/dist/providers/claude/durable/ClaudePrintAgentService.d.ts.map +0 -1
  774. package/dist/providers/claude/durable/ClaudePrintAgentService.js.map +0 -1
  775. package/dist/providers/claude/durable/ClaudePrintRunner.d.ts.map +0 -1
  776. package/dist/providers/claude/durable/ClaudePrintRunner.js.map +0 -1
  777. package/dist/providers/claude/durable/ClaudeStreamParser.d.ts.map +0 -1
  778. package/dist/providers/claude/durable/ClaudeStreamParser.js.map +0 -1
  779. package/dist/providers/codex/CodexAdapter.d.ts +0 -28
  780. package/dist/providers/codex/CodexAdapter.d.ts.map +0 -1
  781. package/dist/providers/codex/CodexAdapter.js +0 -170
  782. package/dist/providers/codex/CodexAdapter.js.map +0 -1
  783. package/dist/providers/codex/CodexAgentMapper.d.ts.map +0 -1
  784. package/dist/providers/codex/CodexAgentMapper.js +0 -35
  785. package/dist/providers/codex/CodexAgentMapper.js.map +0 -1
  786. package/dist/providers/codex/CodexSessionLocator.d.ts +0 -44
  787. package/dist/providers/codex/CodexSessionLocator.d.ts.map +0 -1
  788. package/dist/providers/codex/CodexSessionLocator.js +0 -207
  789. package/dist/providers/codex/CodexSessionLocator.js.map +0 -1
  790. package/dist/providers/codex/CodexSessionMapping.d.ts.map +0 -1
  791. package/dist/providers/codex/CodexSessionMapping.js +0 -68
  792. package/dist/providers/codex/CodexSessionMapping.js.map +0 -1
  793. package/dist/providers/codex/CodexSessionParser.d.ts +0 -58
  794. package/dist/providers/codex/CodexSessionParser.d.ts.map +0 -1
  795. package/dist/providers/codex/CodexSessionParser.js +0 -262
  796. package/dist/providers/codex/CodexSessionParser.js.map +0 -1
  797. package/dist/providers/codex/durable/CodexCliProbe.d.ts.map +0 -1
  798. package/dist/providers/codex/durable/CodexCliProbe.js.map +0 -1
  799. package/dist/providers/codex/durable/CodexPrintAgentService.d.ts.map +0 -1
  800. package/dist/providers/codex/durable/CodexPrintAgentService.js.map +0 -1
  801. package/dist/providers/codex/durable/CodexPrintRunner.d.ts.map +0 -1
  802. package/dist/providers/codex/durable/CodexPrintRunner.js.map +0 -1
  803. package/dist/providers/codex/durable/CodexStreamParser.d.ts.map +0 -1
  804. package/dist/providers/codex/durable/CodexStreamParser.js.map +0 -1
  805. package/dist/providers/copilot/CopilotAdapter.d.ts +0 -35
  806. package/dist/providers/copilot/CopilotAdapter.d.ts.map +0 -1
  807. package/dist/providers/copilot/CopilotAdapter.js +0 -123
  808. package/dist/providers/copilot/CopilotAdapter.js.map +0 -1
  809. package/dist/providers/copilot/CopilotAgentMapper.d.ts.map +0 -1
  810. package/dist/providers/copilot/CopilotAgentMapper.js +0 -37
  811. package/dist/providers/copilot/CopilotAgentMapper.js.map +0 -1
  812. package/dist/providers/copilot/CopilotSessionLocator.d.ts +0 -20
  813. package/dist/providers/copilot/CopilotSessionLocator.d.ts.map +0 -1
  814. package/dist/providers/copilot/CopilotSessionLocator.js +0 -49
  815. package/dist/providers/copilot/CopilotSessionLocator.js.map +0 -1
  816. package/dist/providers/copilot/CopilotSessionParser.d.ts +0 -30
  817. package/dist/providers/copilot/CopilotSessionParser.d.ts.map +0 -1
  818. package/dist/providers/copilot/CopilotSessionParser.js +0 -181
  819. package/dist/providers/copilot/CopilotSessionParser.js.map +0 -1
  820. package/dist/providers/gemini/GeminiAgentMapper.d.ts.map +0 -1
  821. package/dist/providers/gemini/GeminiAgentMapper.js +0 -37
  822. package/dist/providers/gemini/GeminiAgentMapper.js.map +0 -1
  823. package/dist/providers/gemini/GeminiCliAdapter.d.ts +0 -53
  824. package/dist/providers/gemini/GeminiCliAdapter.d.ts.map +0 -1
  825. package/dist/providers/gemini/GeminiCliAdapter.js +0 -197
  826. package/dist/providers/gemini/GeminiCliAdapter.js.map +0 -1
  827. package/dist/providers/gemini/GeminiSessionLocator.d.ts +0 -30
  828. package/dist/providers/gemini/GeminiSessionLocator.d.ts.map +0 -1
  829. package/dist/providers/gemini/GeminiSessionLocator.js +0 -142
  830. package/dist/providers/gemini/GeminiSessionLocator.js.map +0 -1
  831. package/dist/providers/gemini/GeminiSessionParser.d.ts +0 -94
  832. package/dist/providers/gemini/GeminiSessionParser.d.ts.map +0 -1
  833. package/dist/providers/gemini/GeminiSessionParser.js +0 -166
  834. package/dist/providers/gemini/GeminiSessionParser.js.map +0 -1
  835. package/dist/providers/grok/GrokAgentMapper.d.ts.map +0 -1
  836. package/dist/providers/grok/GrokAgentMapper.js +0 -36
  837. package/dist/providers/grok/GrokAgentMapper.js.map +0 -1
  838. package/dist/providers/grok/GrokCliAdapter.d.ts +0 -36
  839. package/dist/providers/grok/GrokCliAdapter.d.ts.map +0 -1
  840. package/dist/providers/grok/GrokCliAdapter.js +0 -98
  841. package/dist/providers/grok/GrokCliAdapter.js.map +0 -1
  842. package/dist/providers/grok/GrokSessionLocator.d.ts.map +0 -1
  843. package/dist/providers/grok/GrokSessionLocator.js +0 -140
  844. package/dist/providers/grok/GrokSessionLocator.js.map +0 -1
  845. package/dist/providers/grok/GrokSessionParser.d.ts +0 -54
  846. package/dist/providers/grok/GrokSessionParser.d.ts.map +0 -1
  847. package/dist/providers/grok/GrokSessionParser.js +0 -122
  848. package/dist/providers/grok/GrokSessionParser.js.map +0 -1
  849. package/dist/providers/opencode/OpenCodeAdapter.d.ts +0 -31
  850. package/dist/providers/opencode/OpenCodeAdapter.d.ts.map +0 -1
  851. package/dist/providers/opencode/OpenCodeAdapter.js +0 -89
  852. package/dist/providers/opencode/OpenCodeAdapter.js.map +0 -1
  853. package/dist/providers/opencode/OpenCodeAgentMapper.d.ts.map +0 -1
  854. package/dist/providers/opencode/OpenCodeAgentMapper.js +0 -50
  855. package/dist/providers/opencode/OpenCodeAgentMapper.js.map +0 -1
  856. package/dist/providers/opencode/OpenCodeSessionLocator.d.ts.map +0 -1
  857. package/dist/providers/opencode/OpenCodeSessionLocator.js +0 -118
  858. package/dist/providers/opencode/OpenCodeSessionLocator.js.map +0 -1
  859. package/dist/providers/opencode/OpenCodeSessionParser.d.ts +0 -18
  860. package/dist/providers/opencode/OpenCodeSessionParser.d.ts.map +0 -1
  861. package/dist/providers/opencode/OpenCodeSessionParser.js +0 -104
  862. package/dist/providers/opencode/OpenCodeSessionParser.js.map +0 -1
  863. package/dist/providers/pi/PiAdapter.d.ts +0 -29
  864. package/dist/providers/pi/PiAdapter.d.ts.map +0 -1
  865. package/dist/providers/pi/PiAdapter.js +0 -163
  866. package/dist/providers/pi/PiAdapter.js.map +0 -1
  867. package/dist/providers/pi/PiAgentMapper.d.ts.map +0 -1
  868. package/dist/providers/pi/PiAgentMapper.js +0 -37
  869. package/dist/providers/pi/PiAgentMapper.js.map +0 -1
  870. package/dist/providers/pi/PiSessionLocator.d.ts +0 -24
  871. package/dist/providers/pi/PiSessionLocator.d.ts.map +0 -1
  872. package/dist/providers/pi/PiSessionLocator.js +0 -86
  873. package/dist/providers/pi/PiSessionLocator.js.map +0 -1
  874. package/dist/providers/pi/PiSessionParser.d.ts +0 -36
  875. package/dist/providers/pi/PiSessionParser.d.ts.map +0 -1
  876. package/dist/providers/pi/PiSessionParser.js +0 -191
  877. package/dist/providers/pi/PiSessionParser.js.map +0 -1
  878. package/dist/providers/pi/PiSessionTracker.d.ts.map +0 -1
  879. package/dist/providers/pi/PiSessionTracker.js +0 -69
  880. package/dist/providers/pi/PiSessionTracker.js.map +0 -1
  881. package/dist/providers/pi/durable/PiCliProbe.d.ts.map +0 -1
  882. package/dist/providers/pi/durable/PiCliProbe.js.map +0 -1
  883. package/dist/providers/pi/durable/PiPrintAgentService.d.ts.map +0 -1
  884. package/dist/providers/pi/durable/PiPrintAgentService.js.map +0 -1
  885. package/dist/providers/pi/durable/PiPrintProtocol.d.ts.map +0 -1
  886. package/dist/providers/pi/durable/PiPrintProtocol.js.map +0 -1
  887. package/dist/providers/pi/durable/PiPrintRunner.d.ts.map +0 -1
  888. package/dist/providers/pi/durable/PiPrintRunner.js.map +0 -1
  889. package/dist/providers/pi/durable/PiStreamParser.d.ts.map +0 -1
  890. package/dist/providers/pi/durable/PiStreamParser.js.map +0 -1
  891. package/dist/readiness/AgentReadiness.d.ts +0 -67
  892. package/dist/readiness/AgentReadiness.d.ts.map +0 -1
  893. package/dist/readiness/AgentReadiness.js +0 -614
  894. package/dist/readiness/AgentReadiness.js.map +0 -1
  895. package/dist/terminal/TmuxManager.d.ts +0 -28
  896. package/dist/terminal/TmuxManager.d.ts.map +0 -1
  897. package/dist/terminal/TmuxManager.js +0 -135
  898. package/dist/terminal/TmuxManager.js.map +0 -1
  899. package/dist/terminal/index.d.ts +0 -5
  900. package/dist/terminal/index.d.ts.map +0 -1
  901. package/dist/terminal/index.js +0 -5
  902. package/dist/terminal/index.js.map +0 -1
  903. package/dist/utils/agents.d.ts +0 -15
  904. package/dist/utils/agents.d.ts.map +0 -1
  905. package/dist/utils/agents.js +0 -82
  906. package/dist/utils/agents.js.map +0 -1
  907. package/dist/utils/index.d.ts +0 -7
  908. package/dist/utils/index.d.ts.map +0 -1
  909. package/dist/utils/index.js +0 -6
  910. package/dist/utils/index.js.map +0 -1
  911. package/src/__tests__/adapters/AntigravityCliAdapter.test.ts +0 -324
  912. package/src/__tests__/adapters/ClaudeCodeAdapter.test.ts +0 -1763
  913. package/src/__tests__/adapters/CodexAdapter.test.ts +0 -387
  914. package/src/__tests__/adapters/KiroAdapter.test.ts +0 -534
  915. package/src/__tests__/durable/CodexCliProbe.test.ts +0 -85
  916. package/src/__tests__/durable/CodexDurableAgentRepository.test.ts +0 -65
  917. package/src/__tests__/durable/CodexPrintAgent.integration.test.ts +0 -104
  918. package/src/__tests__/durable/CodexPrintAgentService.test.ts +0 -217
  919. package/src/__tests__/durable/CodexPrintRunner.test.ts +0 -309
  920. package/src/__tests__/fixtures/fake-claude.cjs +0 -31
  921. package/src/__tests__/fixtures/fake-codex.cjs +0 -56
  922. package/src/__tests__/print/ClaudeCliProbe.test.ts +0 -34
  923. package/src/__tests__/print/ClaudePrintAgent.integration.test.ts +0 -61
  924. package/src/__tests__/print/ClaudePrintAgentService.test.ts +0 -129
  925. package/src/__tests__/print/ClaudePrintRunner.test.ts +0 -152
  926. package/src/__tests__/providers/claude/ClaudeAgentMapper.test.ts +0 -84
  927. package/src/__tests__/providers/claude/ClaudeSessionLocator.test.ts +0 -434
  928. package/src/__tests__/providers/codex/CodexSessionLocator.test.ts +0 -182
  929. package/src/__tests__/providers/codex/CodexSessionMapping.test.ts +0 -63
  930. package/src/__tests__/providers/codex/CodexSessionParser.test.ts +0 -192
  931. package/src/__tests__/providers/copilot/CopilotAdapter.test.ts +0 -614
  932. package/src/__tests__/providers/gemini/GeminiCliAdapter.test.ts +0 -1320
  933. package/src/__tests__/providers/grok/GrokAgentMapper.test.ts +0 -57
  934. package/src/__tests__/providers/grok/GrokCliAdapter.test.ts +0 -376
  935. package/src/__tests__/providers/grok/GrokSessionLocator.test.ts +0 -106
  936. package/src/__tests__/providers/opencode/OpenCodeAdapter.test.ts +0 -215
  937. package/src/__tests__/providers/opencode/OpenCodeAgentMapper.test.ts +0 -83
  938. package/src/__tests__/providers/opencode/OpenCodeSessionLocator.test.ts +0 -84
  939. package/src/__tests__/providers/opencode/OpenCodeSessionParser.test.ts +0 -148
  940. package/src/__tests__/providers/pi/PiAdapter.test.ts +0 -325
  941. package/src/__tests__/providers/pi/PiSessionParser.test.ts +0 -190
  942. package/src/__tests__/providers/pi/PiSessionTracker.test.ts +0 -79
  943. package/src/__tests__/providers/pi/durable/PiCliProbe.test.ts +0 -54
  944. package/src/__tests__/providers/pi/durable/PiPrintAgentService.test.ts +0 -141
  945. package/src/__tests__/providers/pi/durable/PiPrintProtocol.test.ts +0 -71
  946. package/src/__tests__/providers/pi/durable/PiPrintRunner.test.ts +0 -253
  947. package/src/__tests__/providers/pi/durable/PiStreamParser.test.ts +0 -26
  948. package/src/__tests__/readiness/AgentReadiness.test.ts +0 -242
  949. package/src/__tests__/utils/ClaudeSessionParser.test.ts +0 -300
  950. package/src/__tests__/utils/agents.test.ts +0 -31
  951. package/src/adapters/AntigravityCliAdapter.ts +0 -356
  952. package/src/adapters/KiroAdapter.ts +0 -456
  953. package/src/adapters/index.ts +0 -17
  954. package/src/capacity/claude.ts +0 -313
  955. package/src/capacity/codex.ts +0 -332
  956. package/src/capacity/openai.ts +0 -361
  957. package/src/capacity/wham.ts +0 -84
  958. package/src/capacity/zai.ts +0 -237
  959. package/src/providers/claude/ClaudeAgentMapper.ts +0 -63
  960. package/src/providers/claude/ClaudeCodeAdapter.ts +0 -173
  961. package/src/providers/claude/ClaudeSessionLocator.ts +0 -358
  962. package/src/providers/claude/ClaudeSessionParser.ts +0 -432
  963. package/src/providers/codex/CodexAdapter.ts +0 -213
  964. package/src/providers/codex/CodexAgentMapper.ts +0 -35
  965. package/src/providers/codex/CodexSessionLocator.ts +0 -279
  966. package/src/providers/codex/CodexSessionMapping.ts +0 -89
  967. package/src/providers/codex/CodexSessionParser.ts +0 -385
  968. package/src/providers/copilot/CopilotAdapter.ts +0 -161
  969. package/src/providers/copilot/CopilotAgentMapper.ts +0 -36
  970. package/src/providers/copilot/CopilotSessionLocator.ts +0 -63
  971. package/src/providers/copilot/CopilotSessionParser.ts +0 -289
  972. package/src/providers/gemini/GeminiAgentMapper.ts +0 -36
  973. package/src/providers/gemini/GeminiCliAdapter.ts +0 -274
  974. package/src/providers/gemini/GeminiSessionLocator.ts +0 -183
  975. package/src/providers/gemini/GeminiSessionParser.ts +0 -271
  976. package/src/providers/grok/GrokAgentMapper.ts +0 -41
  977. package/src/providers/grok/GrokCliAdapter.ts +0 -125
  978. package/src/providers/grok/GrokSessionLocator.ts +0 -179
  979. package/src/providers/grok/GrokSessionParser.ts +0 -166
  980. package/src/providers/opencode/OpenCodeAdapter.ts +0 -116
  981. package/src/providers/opencode/OpenCodeAgentMapper.ts +0 -61
  982. package/src/providers/opencode/OpenCodeSessionLocator.ts +0 -151
  983. package/src/providers/opencode/OpenCodeSessionParser.ts +0 -145
  984. package/src/providers/pi/PiAdapter.ts +0 -195
  985. package/src/providers/pi/PiAgentMapper.ts +0 -36
  986. package/src/providers/pi/PiSessionLocator.ts +0 -110
  987. package/src/providers/pi/PiSessionParser.ts +0 -284
  988. package/src/providers/pi/PiSessionTracker.ts +0 -87
  989. package/src/readiness/AgentReadiness.ts +0 -730
  990. package/src/terminal/TmuxManager.ts +0 -123
  991. package/src/terminal/index.ts +0 -4
  992. package/src/utils/agents.ts +0 -75
  993. package/src/utils/index.ts +0 -12
  994. /package/dist/__tests__/{providers → harnesses}/pi/durable/PiDurableAgentRepository.test.js +0 -0
  995. /package/dist/{providers → harnesses}/claude/ClaudeAgentMapper.d.ts +0 -0
  996. /package/dist/{providers → harnesses}/claude/ClaudeSessionLocator.d.ts +0 -0
  997. /package/dist/{providers → harnesses}/claude/durable/ClaudeCliProbe.d.ts +0 -0
  998. /package/dist/{providers → harnesses}/claude/durable/ClaudeCliProbe.js +0 -0
  999. /package/dist/{providers → harnesses}/claude/durable/ClaudePrintAgentService.d.ts +0 -0
  1000. /package/dist/{providers → harnesses}/claude/durable/ClaudePrintAgentService.js +0 -0
  1001. /package/dist/{providers → harnesses}/claude/durable/ClaudePrintRunner.d.ts +0 -0
  1002. /package/dist/{providers → harnesses}/claude/durable/ClaudePrintRunner.js +0 -0
  1003. /package/dist/{providers → harnesses}/claude/durable/ClaudeStreamParser.d.ts +0 -0
  1004. /package/dist/{providers → harnesses}/claude/durable/ClaudeStreamParser.js +0 -0
  1005. /package/dist/{providers → harnesses}/codex/CodexAgentMapper.d.ts +0 -0
  1006. /package/dist/{providers → harnesses}/codex/CodexSessionMapping.d.ts +0 -0
  1007. /package/dist/{providers → harnesses}/codex/durable/CodexCliProbe.d.ts +0 -0
  1008. /package/dist/{providers → harnesses}/codex/durable/CodexCliProbe.js +0 -0
  1009. /package/dist/{providers → harnesses}/codex/durable/CodexPrintAgentService.d.ts +0 -0
  1010. /package/dist/{providers → harnesses}/codex/durable/CodexPrintAgentService.js +0 -0
  1011. /package/dist/{providers → harnesses}/codex/durable/CodexPrintRunner.d.ts +0 -0
  1012. /package/dist/{providers → harnesses}/codex/durable/CodexPrintRunner.js +0 -0
  1013. /package/dist/{providers → harnesses}/codex/durable/CodexStreamParser.d.ts +0 -0
  1014. /package/dist/{providers → harnesses}/codex/durable/CodexStreamParser.js +0 -0
  1015. /package/dist/{providers → harnesses}/copilot/CopilotAgentMapper.d.ts +0 -0
  1016. /package/dist/{providers → harnesses}/gemini/GeminiAgentMapper.d.ts +0 -0
  1017. /package/dist/{providers → harnesses}/grok/GrokAgentMapper.d.ts +0 -0
  1018. /package/dist/{providers → harnesses}/grok/GrokSessionLocator.d.ts +0 -0
  1019. /package/dist/{providers → harnesses}/opencode/OpenCodeAgentMapper.d.ts +0 -0
  1020. /package/dist/{providers → harnesses}/opencode/OpenCodeSessionLocator.d.ts +0 -0
  1021. /package/dist/{providers → harnesses}/pi/PiAgentMapper.d.ts +0 -0
  1022. /package/dist/{providers → harnesses}/pi/PiSessionTracker.d.ts +0 -0
  1023. /package/dist/{providers → harnesses}/pi/durable/PiCliProbe.d.ts +0 -0
  1024. /package/dist/{providers → harnesses}/pi/durable/PiCliProbe.js +0 -0
  1025. /package/dist/{providers → harnesses}/pi/durable/PiPrintAgentService.d.ts +0 -0
  1026. /package/dist/{providers → harnesses}/pi/durable/PiPrintAgentService.js +0 -0
  1027. /package/dist/{providers → harnesses}/pi/durable/PiPrintProtocol.d.ts +0 -0
  1028. /package/dist/{providers → harnesses}/pi/durable/PiPrintProtocol.js +0 -0
  1029. /package/dist/{providers → harnesses}/pi/durable/PiPrintRunner.d.ts +0 -0
  1030. /package/dist/{providers → harnesses}/pi/durable/PiPrintRunner.js +0 -0
  1031. /package/dist/{providers → harnesses}/pi/durable/PiStreamParser.d.ts +0 -0
  1032. /package/dist/{providers → harnesses}/pi/durable/PiStreamParser.js +0 -0
  1033. /package/src/__tests__/{providers → harnesses}/pi/durable/PiDurableAgentRepository.test.ts +0 -0
  1034. /package/src/{providers → harnesses}/claude/durable/ClaudeCliProbe.ts +0 -0
  1035. /package/src/{providers → harnesses}/claude/durable/ClaudePrintAgentService.ts +0 -0
  1036. /package/src/{providers → harnesses}/claude/durable/ClaudePrintRunner.ts +0 -0
  1037. /package/src/{providers → harnesses}/claude/durable/ClaudeStreamParser.ts +0 -0
  1038. /package/src/{providers → harnesses}/codex/durable/CodexCliProbe.ts +0 -0
  1039. /package/src/{providers → harnesses}/codex/durable/CodexPrintAgentService.ts +0 -0
  1040. /package/src/{providers → harnesses}/codex/durable/CodexPrintRunner.ts +0 -0
  1041. /package/src/{providers → harnesses}/codex/durable/CodexStreamParser.ts +0 -0
  1042. /package/src/{providers → harnesses}/pi/durable/PiCliProbe.ts +0 -0
  1043. /package/src/{providers → harnesses}/pi/durable/PiPrintAgentService.ts +0 -0
  1044. /package/src/{providers → harnesses}/pi/durable/PiPrintProtocol.ts +0 -0
  1045. /package/src/{providers → harnesses}/pi/durable/PiPrintRunner.ts +0 -0
  1046. /package/src/{providers → harnesses}/pi/durable/PiStreamParser.ts +0 -0
@@ -1,1853 +0,0 @@
1
- /**
2
- * Tests for ClaudeCodeAdapter
3
- */ import * as fs from "fs";
4
- import * as path from "path";
5
- import { ClaudeCodeAdapter } from "../../providers/claude/ClaudeCodeAdapter.js";
6
- import { AgentStatus } from "../../adapters/AgentAdapter.js";
7
- import { listAgentProcesses, enrichProcesses, captureProcessSnapshot } from "../../utils/process.js";
8
- import { batchGetSessionFileBirthtimes } from "../../utils/session.js";
9
- import { matchProcessesToSessions, generateAgentName } from "../../utils/matching.js";
10
- import * as os from "os";
11
- vi.mock("../../utils/process.js", async (importOriginal)=>{
12
- const actual = await importOriginal();
13
- return {
14
- ...actual,
15
- listAgentProcesses: vi.fn(),
16
- enrichProcesses: vi.fn(),
17
- captureProcessSnapshot: vi.fn()
18
- };
19
- });
20
- vi.mock("../../utils/session.js", async ()=>{
21
- const actual = await vi.importActual("../../utils/session");
22
- return {
23
- ...actual,
24
- batchGetSessionFileBirthtimes: vi.fn()
25
- };
26
- });
27
- vi.mock("../../utils/matching.js", ()=>({
28
- matchProcessesToSessions: vi.fn(),
29
- generateAgentName: vi.fn()
30
- }));
31
- const mockedListAgentProcesses = listAgentProcesses;
32
- const mockedEnrichProcesses = enrichProcesses;
33
- const mockedCaptureProcessSnapshot = captureProcessSnapshot;
34
- const mockedBatchGetSessionFileBirthtimes = batchGetSessionFileBirthtimes;
35
- const mockedMatchProcessesToSessions = matchProcessesToSessions;
36
- const mockedGenerateAgentName = generateAgentName;
37
- describe("ClaudeCodeAdapter", ()=>{
38
- let adapter;
39
- beforeEach(()=>{
40
- adapter = new ClaudeCodeAdapter();
41
- mockedListAgentProcesses.mockReset();
42
- mockedEnrichProcesses.mockReset();
43
- mockedCaptureProcessSnapshot.mockReset();
44
- mockedBatchGetSessionFileBirthtimes.mockReset();
45
- mockedMatchProcessesToSessions.mockReset();
46
- mockedGenerateAgentName.mockReset();
47
- // Default: enrichProcesses returns what it receives
48
- mockedEnrichProcesses.mockImplementation((procs)=>procs);
49
- // Compatibility shim for standalone adapter discovery; the manager captures once and slices by name.
50
- mockedCaptureProcessSnapshot.mockImplementation(async (names)=>enrichProcesses(names.flatMap((name)=>listAgentProcesses(name))));
51
- // Default: generateAgentName returns "folder (pid)"
52
- mockedGenerateAgentName.mockImplementation((cwd, pid)=>{
53
- const folder = path.basename(cwd) || "unknown";
54
- return `${folder} (${pid})`;
55
- });
56
- });
57
- describe("initialization", ()=>{
58
- it("should create adapter with correct type", ()=>{
59
- expect(adapter.type).toBe("claude");
60
- });
61
- });
62
- describe("canHandle", ()=>{
63
- it("should return true for claude processes", ()=>{
64
- const processInfo = {
65
- pid: 12345,
66
- command: "claude",
67
- cwd: "/test",
68
- tty: "ttys001"
69
- };
70
- expect(adapter.canHandle(processInfo)).toBe(true);
71
- });
72
- it("should return true for claude executable with full path", ()=>{
73
- const processInfo = {
74
- pid: 12345,
75
- command: "/usr/local/bin/claude --some-flag",
76
- cwd: "/test",
77
- tty: "ttys001"
78
- };
79
- expect(adapter.canHandle(processInfo)).toBe(true);
80
- });
81
- it("should return true for CLAUDE (case-insensitive)", ()=>{
82
- const processInfo = {
83
- pid: 12345,
84
- command: "/usr/local/bin/CLAUDE --continue",
85
- cwd: "/test",
86
- tty: "ttys001"
87
- };
88
- expect(adapter.canHandle(processInfo)).toBe(true);
89
- });
90
- it("should return false for non-claude processes", ()=>{
91
- const processInfo = {
92
- pid: 12345,
93
- command: "node",
94
- cwd: "/test",
95
- tty: "ttys001"
96
- };
97
- expect(adapter.canHandle(processInfo)).toBe(false);
98
- });
99
- it('should return false for processes with "claude" only in path arguments', ()=>{
100
- const processInfo = {
101
- pid: 12345,
102
- command: "/usr/local/bin/node /path/to/claude-worktree/node_modules/nx/start.js",
103
- cwd: "/test",
104
- tty: "ttys001"
105
- };
106
- expect(adapter.canHandle(processInfo)).toBe(false);
107
- });
108
- });
109
- describe("detectAgents", ()=>{
110
- it("should return empty array if no claude processes running", async ()=>{
111
- mockedListAgentProcesses.mockReturnValue([]);
112
- const agents = await adapter.detectAgents();
113
- expect(agents).toEqual([]);
114
- expect(mockedListAgentProcesses).toHaveBeenCalledWith("claude");
115
- });
116
- it("should return process-only agents when no sessions discovered", async ()=>{
117
- const processes = [
118
- {
119
- pid: 777,
120
- command: "claude",
121
- cwd: "/project/app",
122
- tty: "ttys001"
123
- }
124
- ];
125
- mockedListAgentProcesses.mockReturnValue(processes);
126
- mockedEnrichProcesses.mockReturnValue(processes);
127
- // No projects dir → discoverSessions returns []
128
- adapter.projectsDir = "/nonexistent/path";
129
- const agents = await adapter.detectAgents();
130
- expect(agents).toHaveLength(1);
131
- expect(agents[0]).toMatchObject({
132
- type: "claude",
133
- status: AgentStatus.IDLE,
134
- pid: 777,
135
- projectPath: "/project/app",
136
- sessionId: "pid-777",
137
- summary: "Unknown"
138
- });
139
- });
140
- it("should detect agents with matched sessions", async ()=>{
141
- const processes = [
142
- {
143
- pid: 12345,
144
- command: "claude",
145
- cwd: "/Users/test/my-project",
146
- tty: "ttys001",
147
- startTime: new Date("2026-03-18T23:18:01.000Z")
148
- }
149
- ];
150
- mockedListAgentProcesses.mockReturnValue(processes);
151
- mockedEnrichProcesses.mockReturnValue(processes);
152
- // Set up projects dir with encoded directory name
153
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "claude-test-"));
154
- const projectsDir = path.join(tmpDir, "projects");
155
- // Claude encodes /Users/test/my-project → -Users-test-my-project
156
- const projDir = path.join(projectsDir, "-Users-test-my-project");
157
- fs.mkdirSync(projDir, {
158
- recursive: true
159
- });
160
- // Create session file
161
- const sessionFile = path.join(projDir, "session-1.jsonl");
162
- fs.writeFileSync(sessionFile, [
163
- JSON.stringify({
164
- type: "user",
165
- timestamp: "2026-03-18T23:18:44Z",
166
- cwd: "/Users/test/my-project",
167
- message: {
168
- content: "Investigate failing tests"
169
- }
170
- }),
171
- JSON.stringify({
172
- type: "assistant",
173
- timestamp: "2026-03-18T23:19:00Z"
174
- })
175
- ].join("\n"));
176
- adapter.projectsDir = projectsDir;
177
- const sessionFiles = [
178
- {
179
- sessionId: "session-1",
180
- filePath: sessionFile,
181
- projectDir: projDir,
182
- birthtimeMs: new Date("2026-03-18T23:18:44Z").getTime(),
183
- resolvedCwd: ""
184
- }
185
- ];
186
- mockedBatchGetSessionFileBirthtimes.mockReturnValue(sessionFiles);
187
- const matches = [
188
- {
189
- process: processes[0],
190
- session: {
191
- ...sessionFiles[0],
192
- resolvedCwd: "/Users/test/my-project"
193
- },
194
- deltaMs: 43000
195
- }
196
- ];
197
- mockedMatchProcessesToSessions.mockReturnValue(matches);
198
- const agents = await adapter.detectAgents();
199
- expect(agents).toHaveLength(1);
200
- expect(agents[0]).toMatchObject({
201
- type: "claude",
202
- status: AgentStatus.WAITING,
203
- pid: 12345,
204
- projectPath: "/Users/test/my-project",
205
- sessionId: "session-1"
206
- });
207
- expect(agents[0].summary).toContain("Investigate failing tests");
208
- fs.rmSync(tmpDir, {
209
- recursive: true,
210
- force: true
211
- });
212
- });
213
- it("should fall back to process-only for unmatched processes", async ()=>{
214
- const processes = [
215
- {
216
- pid: 100,
217
- command: "claude",
218
- cwd: "/project-a",
219
- tty: "ttys001",
220
- startTime: new Date()
221
- },
222
- {
223
- pid: 200,
224
- command: "claude",
225
- cwd: "/project-b",
226
- tty: "ttys002",
227
- startTime: new Date()
228
- }
229
- ];
230
- mockedListAgentProcesses.mockReturnValue(processes);
231
- mockedEnrichProcesses.mockReturnValue(processes);
232
- // Set up projects dir with encoded directory names
233
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "claude-test-"));
234
- const projectsDir = path.join(tmpDir, "projects");
235
- // /project-a → -project-a, /project-b → -project-b
236
- const projDirA = path.join(projectsDir, "-project-a");
237
- const projDirB = path.join(projectsDir, "-project-b");
238
- fs.mkdirSync(projDirA, {
239
- recursive: true
240
- });
241
- fs.mkdirSync(projDirB, {
242
- recursive: true
243
- });
244
- const sessionFile = path.join(projDirA, "only-session.jsonl");
245
- fs.writeFileSync(sessionFile, JSON.stringify({
246
- type: "assistant",
247
- timestamp: "2026-03-18T23:19:00Z"
248
- }));
249
- adapter.projectsDir = projectsDir;
250
- const sessionFiles = [
251
- {
252
- sessionId: "only-session",
253
- filePath: sessionFile,
254
- projectDir: projDirA,
255
- birthtimeMs: Date.now(),
256
- resolvedCwd: ""
257
- }
258
- ];
259
- mockedBatchGetSessionFileBirthtimes.mockReturnValue(sessionFiles);
260
- // Only process 100 matches
261
- const matches = [
262
- {
263
- process: processes[0],
264
- session: {
265
- ...sessionFiles[0],
266
- resolvedCwd: "/project-a"
267
- },
268
- deltaMs: 5000
269
- }
270
- ];
271
- mockedMatchProcessesToSessions.mockReturnValue(matches);
272
- const agents = await adapter.detectAgents();
273
- expect(agents).toHaveLength(2);
274
- const matched = agents.find((a)=>a.pid === 100);
275
- const unmatched = agents.find((a)=>a.pid === 200);
276
- expect(matched?.sessionId).toBe("only-session");
277
- expect(unmatched?.sessionId).toBe("pid-200");
278
- expect(unmatched?.status).toBe(AgentStatus.IDLE);
279
- fs.rmSync(tmpDir, {
280
- recursive: true,
281
- force: true
282
- });
283
- });
284
- it("should handle process with empty cwd in process-only fallback", async ()=>{
285
- const processes = [
286
- {
287
- pid: 300,
288
- command: "claude",
289
- cwd: "",
290
- tty: "ttys003"
291
- }
292
- ];
293
- mockedListAgentProcesses.mockReturnValue(processes);
294
- mockedEnrichProcesses.mockReturnValue(processes);
295
- adapter.projectsDir = "/nonexistent";
296
- const agents = await adapter.detectAgents();
297
- expect(agents).toHaveLength(1);
298
- expect(agents[0]).toMatchObject({
299
- pid: 300,
300
- sessionId: "pid-300",
301
- summary: "Unknown",
302
- projectPath: ""
303
- });
304
- });
305
- it("should match via --resume <uuid> in command line and skip PID-file/legacy", async ()=>{
306
- const sessionId = "0555f803-7eca-4fc6-a1e0-34dbf86b33b2";
307
- const processes = [
308
- {
309
- pid: 41920,
310
- command: `claude --resume ${sessionId}`,
311
- cwd: "/project/resumed",
312
- tty: "ttys001",
313
- startTime: new Date()
314
- }
315
- ];
316
- mockedListAgentProcesses.mockReturnValue(processes);
317
- mockedEnrichProcesses.mockReturnValue(processes);
318
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "claude-resume-"));
319
- const projectsDir = path.join(tmpDir, "projects");
320
- const projDir = path.join(projectsDir, "-project-resumed");
321
- fs.mkdirSync(projDir, {
322
- recursive: true
323
- });
324
- const jsonlPath = path.join(projDir, `${sessionId}.jsonl`);
325
- fs.writeFileSync(jsonlPath, [
326
- JSON.stringify({
327
- type: "user",
328
- timestamp: new Date().toISOString(),
329
- cwd: "/project/resumed",
330
- message: {
331
- content: "resumed conversation"
332
- }
333
- }),
334
- JSON.stringify({
335
- type: "assistant",
336
- timestamp: new Date().toISOString()
337
- })
338
- ].join("\n"));
339
- adapter.projectsDir = projectsDir;
340
- adapter.sessionsDir = path.join(tmpDir, "sessions"); // empty — no PID file
341
- const agents = await adapter.detectAgents();
342
- // Legacy matching helpers must NOT have been consulted — resume match was authoritative
343
- expect(mockedBatchGetSessionFileBirthtimes).not.toHaveBeenCalled();
344
- expect(mockedMatchProcessesToSessions).not.toHaveBeenCalled();
345
- expect(agents).toHaveLength(1);
346
- expect(agents[0]).toMatchObject({
347
- type: "claude",
348
- pid: 41920,
349
- sessionId,
350
- projectPath: "/project/resumed"
351
- });
352
- expect(agents[0].summary).toContain("resumed conversation");
353
- fs.rmSync(tmpDir, {
354
- recursive: true,
355
- force: true
356
- });
357
- });
358
- it("should fall through when --resume points to a JSONL that does not exist", async ()=>{
359
- const processes = [
360
- {
361
- pid: 41921,
362
- command: "claude --resume aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
363
- cwd: "/project/missing",
364
- tty: "ttys001",
365
- startTime: new Date()
366
- }
367
- ];
368
- mockedListAgentProcesses.mockReturnValue(processes);
369
- mockedEnrichProcesses.mockReturnValue(processes);
370
- // No projects dir, no PID file → both matchers fail → process-only
371
- adapter.projectsDir = "/nonexistent";
372
- adapter.sessionsDir = "/nonexistent";
373
- const agents = await adapter.detectAgents();
374
- expect(agents).toHaveLength(1);
375
- expect(agents[0].sessionId).toBe("pid-41921");
376
- expect(agents[0].status).toBe(AgentStatus.IDLE);
377
- });
378
- it("should use PID file for direct match and skip legacy matching for that process", async ()=>{
379
- const startTime = new Date();
380
- const processes = [
381
- {
382
- pid: 55001,
383
- command: "claude",
384
- cwd: "/project/direct",
385
- tty: "ttys001",
386
- startTime
387
- }
388
- ];
389
- mockedListAgentProcesses.mockReturnValue(processes);
390
- mockedEnrichProcesses.mockReturnValue(processes);
391
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "claude-pid-test-"));
392
- const sessionsDir = path.join(tmpDir, "sessions");
393
- const projectsDir = path.join(tmpDir, "projects");
394
- const projDir = path.join(projectsDir, "-project-direct");
395
- fs.mkdirSync(sessionsDir, {
396
- recursive: true
397
- });
398
- fs.mkdirSync(projDir, {
399
- recursive: true
400
- });
401
- const sessionId = "pid-file-session";
402
- const jsonlPath = path.join(projDir, `${sessionId}.jsonl`);
403
- fs.writeFileSync(jsonlPath, [
404
- JSON.stringify({
405
- type: "user",
406
- timestamp: new Date().toISOString(),
407
- cwd: "/project/direct",
408
- message: {
409
- content: "hello from pid file"
410
- }
411
- }),
412
- JSON.stringify({
413
- type: "assistant",
414
- timestamp: new Date().toISOString()
415
- })
416
- ].join("\n"));
417
- fs.writeFileSync(path.join(sessionsDir, "55001.json"), JSON.stringify({
418
- pid: 55001,
419
- sessionId,
420
- cwd: "/project/direct",
421
- startedAt: startTime.getTime(),
422
- kind: "interactive",
423
- entrypoint: "cli"
424
- }));
425
- adapter.sessionsDir = sessionsDir;
426
- adapter.projectsDir = projectsDir;
427
- const agents = await adapter.detectAgents();
428
- // Legacy matching utilities should NOT have been called (all processes matched via PID file)
429
- expect(mockedBatchGetSessionFileBirthtimes).not.toHaveBeenCalled();
430
- expect(mockedMatchProcessesToSessions).not.toHaveBeenCalled();
431
- expect(agents).toHaveLength(1);
432
- expect(agents[0]).toMatchObject({
433
- type: "claude",
434
- pid: 55001,
435
- sessionId,
436
- projectPath: "/project/direct",
437
- status: AgentStatus.WAITING
438
- });
439
- expect(agents[0].summary).toContain("hello from pid file");
440
- fs.rmSync(tmpDir, {
441
- recursive: true,
442
- force: true
443
- });
444
- });
445
- it("should prefer PID-file live status over JSONL-derived status and surface waitingFor in summary", async ()=>{
446
- const startTime = new Date();
447
- const processes = [
448
- {
449
- pid: 55050,
450
- command: "claude",
451
- cwd: "/project/wait",
452
- tty: "ttys001",
453
- startTime
454
- }
455
- ];
456
- mockedListAgentProcesses.mockReturnValue(processes);
457
- mockedEnrichProcesses.mockReturnValue(processes);
458
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "claude-pid-wait-"));
459
- const sessionsDir = path.join(tmpDir, "sessions");
460
- const projectsDir = path.join(tmpDir, "projects");
461
- const projDir = path.join(projectsDir, "-project-wait");
462
- fs.mkdirSync(sessionsDir, {
463
- recursive: true
464
- });
465
- fs.mkdirSync(projDir, {
466
- recursive: true
467
- });
468
- const sessionId = "wait-session";
469
- const jsonlPath = path.join(projDir, `${sessionId}.jsonl`);
470
- // PID file's live status must win over JSONL-derived status.
471
- fs.writeFileSync(jsonlPath, [
472
- JSON.stringify({
473
- type: "user",
474
- timestamp: new Date().toISOString(),
475
- cwd: "/project/wait",
476
- message: {
477
- content: "/reddit-commenter"
478
- }
479
- }),
480
- JSON.stringify({
481
- type: "permission-mode",
482
- timestamp: new Date().toISOString(),
483
- permissionMode: "default"
484
- })
485
- ].join("\n"));
486
- fs.writeFileSync(path.join(sessionsDir, "55050.json"), JSON.stringify({
487
- pid: 55050,
488
- sessionId,
489
- cwd: "/project/wait",
490
- startedAt: startTime.getTime(),
491
- kind: "interactive",
492
- entrypoint: "cli",
493
- status: "waiting",
494
- waitingFor: "approve Read"
495
- }));
496
- adapter.sessionsDir = sessionsDir;
497
- adapter.projectsDir = projectsDir;
498
- const agents = await adapter.detectAgents();
499
- expect(agents).toHaveLength(1);
500
- expect(agents[0].status).toBe(AgentStatus.WAITING);
501
- expect(agents[0].summary).toContain("/reddit-commenter");
502
- expect(agents[0].summary).toContain("waiting for approve Read");
503
- fs.rmSync(tmpDir, {
504
- recursive: true,
505
- force: true
506
- });
507
- });
508
- it('should resolve PID-file status: "idle" to AgentStatus.IDLE even when JSONL would say UNKNOWN', async ()=>{
509
- const startTime = new Date();
510
- const processes = [
511
- {
512
- pid: 55051,
513
- command: "claude",
514
- cwd: "/project/idle",
515
- tty: "ttys001",
516
- startTime
517
- }
518
- ];
519
- mockedListAgentProcesses.mockReturnValue(processes);
520
- mockedEnrichProcesses.mockReturnValue(processes);
521
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "claude-pid-idle-"));
522
- const sessionsDir = path.join(tmpDir, "sessions");
523
- const projectsDir = path.join(tmpDir, "projects");
524
- const projDir = path.join(projectsDir, "-project-idle");
525
- fs.mkdirSync(sessionsDir, {
526
- recursive: true
527
- });
528
- fs.mkdirSync(projDir, {
529
- recursive: true
530
- });
531
- const sessionId = "idle-session";
532
- const jsonlPath = path.join(projDir, `${sessionId}.jsonl`);
533
- fs.writeFileSync(jsonlPath, [
534
- JSON.stringify({
535
- type: "user",
536
- timestamp: new Date().toISOString(),
537
- cwd: "/project/idle",
538
- message: {
539
- content: "hello"
540
- }
541
- }),
542
- JSON.stringify({
543
- type: "permission-mode",
544
- timestamp: new Date().toISOString(),
545
- permissionMode: "default"
546
- })
547
- ].join("\n"));
548
- fs.writeFileSync(path.join(sessionsDir, "55051.json"), JSON.stringify({
549
- pid: 55051,
550
- sessionId,
551
- cwd: "/project/idle",
552
- startedAt: startTime.getTime(),
553
- kind: "interactive",
554
- entrypoint: "cli",
555
- status: "idle"
556
- }));
557
- adapter.sessionsDir = sessionsDir;
558
- adapter.projectsDir = projectsDir;
559
- const agents = await adapter.detectAgents();
560
- expect(agents).toHaveLength(1);
561
- expect(agents[0].status).toBe(AgentStatus.IDLE);
562
- // No waitingFor in PID file → summary is just the last user message
563
- expect(agents[0].summary).toBe("hello");
564
- fs.rmSync(tmpDir, {
565
- recursive: true,
566
- force: true
567
- });
568
- });
569
- it("should fall back to JSONL-derived status when PID-file status is missing or unrecognized", async ()=>{
570
- const startTime = new Date();
571
- const processes = [
572
- {
573
- pid: 55052,
574
- command: "claude",
575
- cwd: "/project/legacy",
576
- tty: "ttys001",
577
- startTime
578
- }
579
- ];
580
- mockedListAgentProcesses.mockReturnValue(processes);
581
- mockedEnrichProcesses.mockReturnValue(processes);
582
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "claude-pid-nostat-"));
583
- const sessionsDir = path.join(tmpDir, "sessions");
584
- const projectsDir = path.join(tmpDir, "projects");
585
- const projDir = path.join(projectsDir, "-project-legacy");
586
- fs.mkdirSync(sessionsDir, {
587
- recursive: true
588
- });
589
- fs.mkdirSync(projDir, {
590
- recursive: true
591
- });
592
- const sessionId = "legacy-session";
593
- const jsonlPath = path.join(projDir, `${sessionId}.jsonl`);
594
- // Last entry is assistant → JSONL parser yields WAITING.
595
- fs.writeFileSync(jsonlPath, [
596
- JSON.stringify({
597
- type: "user",
598
- timestamp: new Date().toISOString(),
599
- cwd: "/project/legacy",
600
- message: {
601
- content: "do the thing"
602
- }
603
- }),
604
- JSON.stringify({
605
- type: "assistant",
606
- timestamp: new Date().toISOString()
607
- })
608
- ].join("\n"));
609
- // PID file with unrecognized status string — adapter must ignore it and use parser
610
- fs.writeFileSync(path.join(sessionsDir, "55052.json"), JSON.stringify({
611
- pid: 55052,
612
- sessionId,
613
- cwd: "/project/legacy",
614
- startedAt: startTime.getTime(),
615
- kind: "interactive",
616
- entrypoint: "cli",
617
- status: "fantastical-future-state"
618
- }));
619
- adapter.sessionsDir = sessionsDir;
620
- adapter.projectsDir = projectsDir;
621
- const agents = await adapter.detectAgents();
622
- expect(agents).toHaveLength(1);
623
- expect(agents[0].status).toBe(AgentStatus.WAITING);
624
- fs.rmSync(tmpDir, {
625
- recursive: true,
626
- force: true
627
- });
628
- });
629
- it("should pick up live status from PID file even when matched via --resume", async ()=>{
630
- const sessionId = "aaaaaaaa-1111-2222-3333-444444444444";
631
- const startTime = new Date();
632
- const processes = [
633
- {
634
- pid: 55053,
635
- command: `claude --resume ${sessionId}`,
636
- cwd: "/project/resume-wait",
637
- tty: "ttys001",
638
- startTime
639
- }
640
- ];
641
- mockedListAgentProcesses.mockReturnValue(processes);
642
- mockedEnrichProcesses.mockReturnValue(processes);
643
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "claude-resume-wait-"));
644
- const sessionsDir = path.join(tmpDir, "sessions");
645
- const projectsDir = path.join(tmpDir, "projects");
646
- const projDir = path.join(projectsDir, "-project-resume-wait");
647
- fs.mkdirSync(sessionsDir, {
648
- recursive: true
649
- });
650
- fs.mkdirSync(projDir, {
651
- recursive: true
652
- });
653
- const jsonlPath = path.join(projDir, `${sessionId}.jsonl`);
654
- fs.writeFileSync(jsonlPath, [
655
- JSON.stringify({
656
- type: "user",
657
- timestamp: new Date().toISOString(),
658
- cwd: "/project/resume-wait",
659
- message: {
660
- content: "resumed work"
661
- }
662
- }),
663
- JSON.stringify({
664
- type: "permission-mode",
665
- timestamp: new Date().toISOString(),
666
- permissionMode: "default"
667
- })
668
- ].join("\n"));
669
- fs.writeFileSync(path.join(sessionsDir, "55053.json"), JSON.stringify({
670
- pid: 55053,
671
- sessionId,
672
- cwd: "/project/resume-wait",
673
- startedAt: startTime.getTime(),
674
- kind: "interactive",
675
- entrypoint: "cli",
676
- status: "waiting",
677
- waitingFor: "approve Bash"
678
- }));
679
- adapter.sessionsDir = sessionsDir;
680
- adapter.projectsDir = projectsDir;
681
- const agents = await adapter.detectAgents();
682
- expect(agents).toHaveLength(1);
683
- expect(agents[0].status).toBe(AgentStatus.WAITING);
684
- expect(agents[0].summary).toContain("resumed work");
685
- expect(agents[0].summary).toContain("waiting for approve Bash");
686
- fs.rmSync(tmpDir, {
687
- recursive: true,
688
- force: true
689
- });
690
- });
691
- it("should fall back to process-only when direct-matched JSONL becomes unreadable", async ()=>{
692
- const startTime = new Date();
693
- const processes = [
694
- {
695
- pid: 66001,
696
- command: "claude",
697
- cwd: "/project/gone",
698
- tty: "ttys001",
699
- startTime
700
- }
701
- ];
702
- mockedListAgentProcesses.mockReturnValue(processes);
703
- mockedEnrichProcesses.mockReturnValue(processes);
704
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "claude-gone-"));
705
- const sessionsDir = path.join(tmpDir, "sessions");
706
- const projectsDir = path.join(tmpDir, "projects");
707
- const projDir = path.join(projectsDir, "-project-gone");
708
- fs.mkdirSync(sessionsDir, {
709
- recursive: true
710
- });
711
- fs.mkdirSync(projDir, {
712
- recursive: true
713
- });
714
- const sessionId = "gone-session";
715
- const jsonlPath = path.join(projDir, `${sessionId}.jsonl`);
716
- fs.writeFileSync(jsonlPath, JSON.stringify({
717
- type: "assistant",
718
- timestamp: new Date().toISOString()
719
- }));
720
- fs.writeFileSync(path.join(sessionsDir, "66001.json"), JSON.stringify({
721
- pid: 66001,
722
- sessionId,
723
- cwd: "/project/gone",
724
- startedAt: startTime.getTime(),
725
- kind: "interactive",
726
- entrypoint: "cli"
727
- }));
728
- adapter.sessionsDir = sessionsDir;
729
- adapter.projectsDir = projectsDir;
730
- // Simulate JSONL disappearing between existence check and read
731
- vi.spyOn(adapter.parser, "readSession").mockReturnValueOnce(null);
732
- const agents = await adapter.detectAgents();
733
- // matchedPids.delete called → process falls back to IDLE
734
- expect(agents).toHaveLength(1);
735
- expect(agents[0].sessionId).toBe("pid-66001");
736
- expect(agents[0].status).toBe(AgentStatus.IDLE);
737
- fs.rmSync(tmpDir, {
738
- recursive: true,
739
- force: true
740
- });
741
- vi.restoreAllMocks();
742
- });
743
- it("should fall back to process-only when legacy-matched JSONL becomes unreadable", async ()=>{
744
- const startTime = new Date();
745
- const processes = [
746
- {
747
- pid: 66002,
748
- command: "claude",
749
- cwd: "/project/legacy-gone",
750
- tty: "ttys001",
751
- startTime
752
- }
753
- ];
754
- mockedListAgentProcesses.mockReturnValue(processes);
755
- mockedEnrichProcesses.mockReturnValue(processes);
756
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "claude-lgone-"));
757
- const projectsDir = path.join(tmpDir, "projects");
758
- const projDir = path.join(projectsDir, "-project-legacy-gone");
759
- fs.mkdirSync(projDir, {
760
- recursive: true
761
- });
762
- const sessionId = "legacy-gone-session";
763
- const jsonlPath = path.join(projDir, `${sessionId}.jsonl`);
764
- fs.writeFileSync(jsonlPath, JSON.stringify({
765
- type: "assistant",
766
- timestamp: new Date().toISOString()
767
- }));
768
- // No PID file → process goes to legacy fallback
769
- adapter.sessionsDir = path.join(tmpDir, "no-sessions");
770
- adapter.projectsDir = projectsDir;
771
- const legacySessionFile = {
772
- sessionId,
773
- filePath: jsonlPath,
774
- projectDir: projDir,
775
- birthtimeMs: startTime.getTime(),
776
- resolvedCwd: "/project/legacy-gone"
777
- };
778
- mockedBatchGetSessionFileBirthtimes.mockReturnValue([
779
- legacySessionFile
780
- ]);
781
- mockedMatchProcessesToSessions.mockReturnValue([
782
- {
783
- process: processes[0],
784
- session: legacySessionFile,
785
- deltaMs: 500
786
- }
787
- ]);
788
- // Simulate JSONL disappearing between match and read
789
- vi.spyOn(adapter.parser, "readSession").mockReturnValueOnce(null);
790
- const agents = await adapter.detectAgents();
791
- expect(agents).toHaveLength(1);
792
- expect(agents[0].sessionId).toBe("pid-66002");
793
- expect(agents[0].status).toBe(AgentStatus.IDLE);
794
- fs.rmSync(tmpDir, {
795
- recursive: true,
796
- force: true
797
- });
798
- vi.restoreAllMocks();
799
- });
800
- it("should mix direct PID-file matches and legacy matches across processes", async ()=>{
801
- const startTime = new Date();
802
- const processes = [
803
- {
804
- pid: 55002,
805
- command: "claude",
806
- cwd: "/project/alpha",
807
- tty: "ttys001",
808
- startTime
809
- },
810
- {
811
- pid: 55003,
812
- command: "claude",
813
- cwd: "/project/beta",
814
- tty: "ttys002",
815
- startTime
816
- }
817
- ];
818
- mockedListAgentProcesses.mockReturnValue(processes);
819
- mockedEnrichProcesses.mockReturnValue(processes);
820
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "claude-mix-test-"));
821
- const sessionsDir = path.join(tmpDir, "sessions");
822
- const projectsDir = path.join(tmpDir, "projects");
823
- const projAlpha = path.join(projectsDir, "-project-alpha");
824
- const projBeta = path.join(projectsDir, "-project-beta");
825
- fs.mkdirSync(sessionsDir, {
826
- recursive: true
827
- });
828
- fs.mkdirSync(projAlpha, {
829
- recursive: true
830
- });
831
- fs.mkdirSync(projBeta, {
832
- recursive: true
833
- });
834
- // PID file only for process 55002
835
- const directSessionId = "direct-session";
836
- const directJsonl = path.join(projAlpha, `${directSessionId}.jsonl`);
837
- fs.writeFileSync(directJsonl, [
838
- JSON.stringify({
839
- type: "user",
840
- timestamp: new Date().toISOString(),
841
- cwd: "/project/alpha",
842
- message: {
843
- content: "direct question"
844
- }
845
- }),
846
- JSON.stringify({
847
- type: "assistant",
848
- timestamp: new Date().toISOString()
849
- })
850
- ].join("\n"));
851
- fs.writeFileSync(path.join(sessionsDir, "55002.json"), JSON.stringify({
852
- pid: 55002,
853
- sessionId: directSessionId,
854
- cwd: "/project/alpha",
855
- startedAt: startTime.getTime(),
856
- kind: "interactive",
857
- entrypoint: "cli"
858
- }));
859
- // Legacy session file for process 55003
860
- const legacySessionId = "legacy-session";
861
- const legacyJsonl = path.join(projBeta, `${legacySessionId}.jsonl`);
862
- fs.writeFileSync(legacyJsonl, [
863
- JSON.stringify({
864
- type: "user",
865
- timestamp: new Date().toISOString(),
866
- cwd: "/project/beta",
867
- message: {
868
- content: "legacy question"
869
- }
870
- }),
871
- JSON.stringify({
872
- type: "assistant",
873
- timestamp: new Date().toISOString()
874
- })
875
- ].join("\n"));
876
- adapter.sessionsDir = sessionsDir;
877
- adapter.projectsDir = projectsDir;
878
- // Mock legacy matching for process 55003
879
- const legacySessionFile = {
880
- sessionId: legacySessionId,
881
- filePath: legacyJsonl,
882
- projectDir: projBeta,
883
- birthtimeMs: startTime.getTime(),
884
- resolvedCwd: "/project/beta"
885
- };
886
- mockedBatchGetSessionFileBirthtimes.mockReturnValue([
887
- legacySessionFile
888
- ]);
889
- mockedMatchProcessesToSessions.mockReturnValue([
890
- {
891
- process: processes[1],
892
- session: legacySessionFile,
893
- deltaMs: 1000
894
- }
895
- ]);
896
- const agents = await adapter.detectAgents();
897
- // Legacy matching called only for fallback process (55003)
898
- expect(mockedMatchProcessesToSessions).toHaveBeenCalledTimes(1);
899
- expect(mockedMatchProcessesToSessions.mock.calls[0][0]).toEqual([
900
- processes[1]
901
- ]);
902
- expect(agents).toHaveLength(2);
903
- const alpha = agents.find((a)=>a.pid === 55002);
904
- const beta = agents.find((a)=>a.pid === 55003);
905
- expect(alpha?.sessionId).toBe(directSessionId);
906
- expect(beta?.sessionId).toBe(legacySessionId);
907
- fs.rmSync(tmpDir, {
908
- recursive: true,
909
- force: true
910
- });
911
- });
912
- });
913
- describe("helper methods", ()=>{
914
- describe("determineStatus", ()=>{
915
- it('should return "unknown" for sessions with no last entry type', ()=>{
916
- const determineStatus = adapter.parser.determineStatus.bind(adapter.parser);
917
- const session = {
918
- sessionId: "test",
919
- projectPath: "/test",
920
- sessionStart: new Date(),
921
- lastActive: new Date(),
922
- isInterrupted: false
923
- };
924
- expect(determineStatus(session)).toBe(AgentStatus.UNKNOWN);
925
- });
926
- it('should return "waiting" for assistant entries', ()=>{
927
- const determineStatus = adapter.parser.determineStatus.bind(adapter.parser);
928
- const session = {
929
- sessionId: "test",
930
- projectPath: "/test",
931
- sessionStart: new Date(),
932
- lastActive: new Date(),
933
- lastEntryType: "assistant",
934
- isInterrupted: false
935
- };
936
- expect(determineStatus(session)).toBe(AgentStatus.WAITING);
937
- });
938
- it('should return "waiting" for user interruption', ()=>{
939
- const determineStatus = adapter.parser.determineStatus.bind(adapter.parser);
940
- const session = {
941
- sessionId: "test",
942
- projectPath: "/test",
943
- sessionStart: new Date(),
944
- lastActive: new Date(),
945
- lastEntryType: "user",
946
- isInterrupted: true
947
- };
948
- expect(determineStatus(session)).toBe(AgentStatus.WAITING);
949
- });
950
- it('should return "running" for user/progress entries', ()=>{
951
- const determineStatus = adapter.parser.determineStatus.bind(adapter.parser);
952
- const session = {
953
- sessionId: "test",
954
- projectPath: "/test",
955
- sessionStart: new Date(),
956
- lastActive: new Date(),
957
- lastEntryType: "user",
958
- isInterrupted: false
959
- };
960
- expect(determineStatus(session)).toBe(AgentStatus.RUNNING);
961
- });
962
- it("should not override status based on age (process is running)", ()=>{
963
- const determineStatus = adapter.parser.determineStatus.bind(adapter.parser);
964
- const oldDate = new Date(Date.now() - 10 * 60 * 1000);
965
- const session = {
966
- sessionId: "test",
967
- projectPath: "/test",
968
- sessionStart: oldDate,
969
- lastActive: oldDate,
970
- lastEntryType: "assistant",
971
- isInterrupted: false
972
- };
973
- expect(determineStatus(session)).toBe(AgentStatus.WAITING);
974
- });
975
- it('should return "idle" for system entries', ()=>{
976
- const determineStatus = adapter.parser.determineStatus.bind(adapter.parser);
977
- const session = {
978
- sessionId: "test",
979
- projectPath: "/test",
980
- sessionStart: new Date(),
981
- lastActive: new Date(),
982
- lastEntryType: "system",
983
- isInterrupted: false
984
- };
985
- expect(determineStatus(session)).toBe(AgentStatus.IDLE);
986
- });
987
- it('should return "running" for thinking entries', ()=>{
988
- const determineStatus = adapter.parser.determineStatus.bind(adapter.parser);
989
- const session = {
990
- sessionId: "test",
991
- projectPath: "/test",
992
- sessionStart: new Date(),
993
- lastActive: new Date(),
994
- lastEntryType: "thinking",
995
- isInterrupted: false
996
- };
997
- expect(determineStatus(session)).toBe(AgentStatus.RUNNING);
998
- });
999
- it('should return "running" for progress entries', ()=>{
1000
- const determineStatus = adapter.parser.determineStatus.bind(adapter.parser);
1001
- const session = {
1002
- sessionId: "test",
1003
- projectPath: "/test",
1004
- sessionStart: new Date(),
1005
- lastActive: new Date(),
1006
- lastEntryType: "progress",
1007
- isInterrupted: false
1008
- };
1009
- expect(determineStatus(session)).toBe(AgentStatus.RUNNING);
1010
- });
1011
- it('should return "unknown" for unrecognized entry types', ()=>{
1012
- const determineStatus = adapter.parser.determineStatus.bind(adapter.parser);
1013
- const session = {
1014
- sessionId: "test",
1015
- projectPath: "/test",
1016
- sessionStart: new Date(),
1017
- lastActive: new Date(),
1018
- lastEntryType: "some_other_type",
1019
- isInterrupted: false
1020
- };
1021
- expect(determineStatus(session)).toBe(AgentStatus.UNKNOWN);
1022
- });
1023
- });
1024
- describe("extractUserMessageText", ()=>{
1025
- it("should extract plain string content", ()=>{
1026
- const extract = adapter.parser["extractUserMessageText"].bind(adapter.parser);
1027
- expect(extract("hello world")).toBe("hello world");
1028
- });
1029
- it("should extract text from array content blocks", ()=>{
1030
- const extract = adapter.parser["extractUserMessageText"].bind(adapter.parser);
1031
- const content = [
1032
- {
1033
- type: "tool_result",
1034
- content: "some result"
1035
- },
1036
- {
1037
- type: "text",
1038
- text: "user question"
1039
- }
1040
- ];
1041
- expect(extract(content)).toBe("user question");
1042
- });
1043
- it("should return undefined for empty/null content", ()=>{
1044
- const extract = adapter.parser["extractUserMessageText"].bind(adapter.parser);
1045
- expect(extract(undefined)).toBeUndefined();
1046
- expect(extract("")).toBeUndefined();
1047
- expect(extract([])).toBeUndefined();
1048
- });
1049
- it("should parse command-message tags", ()=>{
1050
- const extract = adapter.parser["extractUserMessageText"].bind(adapter.parser);
1051
- const msg = "<command-message><command-name>commit</command-name><command-args>fix bug</command-args></command-message>";
1052
- expect(extract(msg)).toBe("commit fix bug");
1053
- });
1054
- it("should parse command-message without args", ()=>{
1055
- const extract = adapter.parser["extractUserMessageText"].bind(adapter.parser);
1056
- const msg = "<command-message><command-name>help</command-name></command-message>";
1057
- expect(extract(msg)).toBe("help");
1058
- });
1059
- it("should extract ARGUMENTS from skill expansion", ()=>{
1060
- const extract = adapter.parser["extractUserMessageText"].bind(adapter.parser);
1061
- const msg = "Base directory for this skill: /some/path\n\nSome instructions\n\nARGUMENTS: implement the feature";
1062
- expect(extract(msg)).toBe("implement the feature");
1063
- });
1064
- it("should return undefined for skill expansion without ARGUMENTS", ()=>{
1065
- const extract = adapter.parser["extractUserMessageText"].bind(adapter.parser);
1066
- const msg = "Base directory for this skill: /some/path\n\nSome instructions only";
1067
- expect(extract(msg)).toBeUndefined();
1068
- });
1069
- it("should filter noise messages", ()=>{
1070
- const extract = adapter.parser["extractUserMessageText"].bind(adapter.parser);
1071
- expect(extract("[Request interrupted by user]")).toBeUndefined();
1072
- expect(extract("Tool loaded.")).toBeUndefined();
1073
- expect(extract("This session is being continued from a previous conversation")).toBeUndefined();
1074
- });
1075
- });
1076
- describe("parseCommandMessage", ()=>{
1077
- it("should return undefined for malformed command-message", ()=>{
1078
- const parse = adapter.parser["parseCommandMessage"].bind(adapter.parser);
1079
- expect(parse("<command-message>no tags</command-message>")).toBeUndefined();
1080
- });
1081
- });
1082
- });
1083
- describe("file I/O methods", ()=>{
1084
- let tmpDir;
1085
- beforeEach(()=>{
1086
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "claude-test-"));
1087
- adapter.projectsDir = path.join(tmpDir, "projects");
1088
- });
1089
- afterEach(()=>{
1090
- fs.rmSync(tmpDir, {
1091
- recursive: true,
1092
- force: true
1093
- });
1094
- });
1095
- describe("readSession", ()=>{
1096
- it("should parse session file with timestamps, cwd, and entry type", ()=>{
1097
- const readSession = adapter.parser.readSession.bind(adapter.parser);
1098
- const filePath = path.join(tmpDir, "test-session.jsonl");
1099
- const lines = [
1100
- JSON.stringify({
1101
- type: "user",
1102
- timestamp: "2026-03-10T10:00:00Z",
1103
- cwd: "/my/project"
1104
- }),
1105
- JSON.stringify({
1106
- type: "assistant",
1107
- timestamp: "2026-03-10T10:01:00Z"
1108
- })
1109
- ];
1110
- fs.writeFileSync(filePath, lines.join("\n"));
1111
- const session = readSession(filePath, "/my/project");
1112
- expect(session).toMatchObject({
1113
- sessionId: "test-session",
1114
- projectPath: "/my/project",
1115
- lastCwd: "/my/project",
1116
- lastEntryType: "assistant",
1117
- isInterrupted: false
1118
- });
1119
- expect(session.sessionStart.toISOString()).toBe("2026-03-10T10:00:00.000Z");
1120
- expect(session.lastActive.toISOString()).toBe("2026-03-10T10:01:00.000Z");
1121
- });
1122
- it("should detect user interruption", ()=>{
1123
- const readSession = adapter.parser.readSession.bind(adapter.parser);
1124
- const filePath = path.join(tmpDir, "interrupted.jsonl");
1125
- const lines = [
1126
- JSON.stringify({
1127
- type: "user",
1128
- timestamp: "2026-03-10T10:00:00Z",
1129
- message: {
1130
- content: [
1131
- {
1132
- type: "text",
1133
- text: "[Request interrupted by user for tool use]"
1134
- }
1135
- ]
1136
- }
1137
- })
1138
- ];
1139
- fs.writeFileSync(filePath, lines.join("\n"));
1140
- const session = readSession(filePath, "/test");
1141
- expect(session.isInterrupted).toBe(true);
1142
- expect(session.lastEntryType).toBe("user");
1143
- });
1144
- it("should return session with defaults for empty file", ()=>{
1145
- const readSession = adapter.parser.readSession.bind(adapter.parser);
1146
- const filePath = path.join(tmpDir, "empty.jsonl");
1147
- fs.writeFileSync(filePath, "");
1148
- const session = readSession(filePath, "/test");
1149
- expect(session).not.toBeNull();
1150
- expect(session.lastEntryType).toBeUndefined();
1151
- });
1152
- it("should return null for non-existent file", ()=>{
1153
- const readSession = adapter.parser.readSession.bind(adapter.parser);
1154
- expect(readSession(path.join(tmpDir, "nonexistent.jsonl"), "/test")).toBeNull();
1155
- });
1156
- it("should skip metadata entry types for lastEntryType", ()=>{
1157
- const readSession = adapter.parser.readSession.bind(adapter.parser);
1158
- const filePath = path.join(tmpDir, "metadata-test.jsonl");
1159
- const lines = [
1160
- JSON.stringify({
1161
- type: "user",
1162
- timestamp: "2026-03-10T10:00:00Z",
1163
- message: {
1164
- content: "hello"
1165
- }
1166
- }),
1167
- JSON.stringify({
1168
- type: "assistant",
1169
- timestamp: "2026-03-10T10:01:00Z"
1170
- }),
1171
- JSON.stringify({
1172
- type: "last-prompt",
1173
- timestamp: "2026-03-10T10:02:00Z"
1174
- }),
1175
- JSON.stringify({
1176
- type: "file-history-snapshot",
1177
- timestamp: "2026-03-10T10:03:00Z"
1178
- })
1179
- ];
1180
- fs.writeFileSync(filePath, lines.join("\n"));
1181
- const session = readSession(filePath, "/test");
1182
- expect(session.lastEntryType).toBe("assistant");
1183
- });
1184
- it("should parse snapshot.timestamp from file-history-snapshot first entry", ()=>{
1185
- const readSession = adapter.parser.readSession.bind(adapter.parser);
1186
- const filePath = path.join(tmpDir, "snapshot-ts.jsonl");
1187
- const lines = [
1188
- JSON.stringify({
1189
- type: "file-history-snapshot",
1190
- snapshot: {
1191
- timestamp: "2026-03-10T09:55:00Z",
1192
- files: []
1193
- }
1194
- }),
1195
- JSON.stringify({
1196
- type: "user",
1197
- timestamp: "2026-03-10T10:00:00Z",
1198
- message: {
1199
- content: "test"
1200
- }
1201
- }),
1202
- JSON.stringify({
1203
- type: "assistant",
1204
- timestamp: "2026-03-10T10:01:00Z"
1205
- })
1206
- ];
1207
- fs.writeFileSync(filePath, lines.join("\n"));
1208
- const session = readSession(filePath, "/test");
1209
- expect(session.sessionStart.toISOString()).toBe("2026-03-10T09:55:00.000Z");
1210
- expect(session.lastActive.toISOString()).toBe("2026-03-10T10:01:00.000Z");
1211
- });
1212
- it("should extract lastUserMessage from session entries", ()=>{
1213
- const readSession = adapter.parser.readSession.bind(adapter.parser);
1214
- const filePath = path.join(tmpDir, "user-msg.jsonl");
1215
- const lines = [
1216
- JSON.stringify({
1217
- type: "user",
1218
- timestamp: "2026-03-10T10:00:00Z",
1219
- message: {
1220
- content: "first question"
1221
- }
1222
- }),
1223
- JSON.stringify({
1224
- type: "assistant",
1225
- timestamp: "2026-03-10T10:01:00Z"
1226
- }),
1227
- JSON.stringify({
1228
- type: "user",
1229
- timestamp: "2026-03-10T10:02:00Z",
1230
- message: {
1231
- content: [
1232
- {
1233
- type: "text",
1234
- text: "second question"
1235
- }
1236
- ]
1237
- }
1238
- }),
1239
- JSON.stringify({
1240
- type: "assistant",
1241
- timestamp: "2026-03-10T10:03:00Z"
1242
- })
1243
- ];
1244
- fs.writeFileSync(filePath, lines.join("\n"));
1245
- const session = readSession(filePath, "/test");
1246
- expect(session.lastUserMessage).toBe("second question");
1247
- });
1248
- it("should use lastCwd as projectPath when projectPath is empty", ()=>{
1249
- const readSession = adapter.parser.readSession.bind(adapter.parser);
1250
- const filePath = path.join(tmpDir, "no-project.jsonl");
1251
- const lines = [
1252
- JSON.stringify({
1253
- type: "user",
1254
- timestamp: "2026-03-10T10:00:00Z",
1255
- cwd: "/derived/path",
1256
- message: {
1257
- content: "test"
1258
- }
1259
- })
1260
- ];
1261
- fs.writeFileSync(filePath, lines.join("\n"));
1262
- const session = readSession(filePath, "");
1263
- expect(session.projectPath).toBe("/derived/path");
1264
- });
1265
- it("should handle malformed JSON lines gracefully", ()=>{
1266
- const readSession = adapter.parser.readSession.bind(adapter.parser);
1267
- const filePath = path.join(tmpDir, "malformed.jsonl");
1268
- const lines = [
1269
- "not json",
1270
- JSON.stringify({
1271
- type: "assistant",
1272
- timestamp: "2026-03-10T10:00:00Z"
1273
- })
1274
- ];
1275
- fs.writeFileSync(filePath, lines.join("\n"));
1276
- const session = readSession(filePath, "/test");
1277
- expect(session).not.toBeNull();
1278
- expect(session.lastEntryType).toBe("assistant");
1279
- });
1280
- });
1281
- });
1282
- describe("getConversation", ()=>{
1283
- let tmpDir;
1284
- beforeEach(()=>{
1285
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "claude-conv-"));
1286
- });
1287
- afterEach(()=>{
1288
- fs.rmSync(tmpDir, {
1289
- recursive: true,
1290
- force: true
1291
- });
1292
- });
1293
- function writeJsonl(lines) {
1294
- const filePath = path.join(tmpDir, "session.jsonl");
1295
- fs.writeFileSync(filePath, lines.map((l)=>JSON.stringify(l)).join("\n"));
1296
- return filePath;
1297
- }
1298
- it("should parse user and assistant text messages", ()=>{
1299
- const filePath = writeJsonl([
1300
- {
1301
- type: "user",
1302
- timestamp: "2026-03-27T10:00:00Z",
1303
- message: {
1304
- content: "Hello"
1305
- }
1306
- },
1307
- {
1308
- type: "assistant",
1309
- timestamp: "2026-03-27T10:00:05Z",
1310
- message: {
1311
- content: [
1312
- {
1313
- type: "text",
1314
- text: "Hi there!"
1315
- }
1316
- ]
1317
- }
1318
- }
1319
- ]);
1320
- const messages = adapter.getConversation(filePath);
1321
- expect(messages).toHaveLength(2);
1322
- expect(messages[0]).toEqual({
1323
- role: "user",
1324
- content: "Hello",
1325
- timestamp: "2026-03-27T10:00:00Z"
1326
- });
1327
- expect(messages[1]).toEqual({
1328
- role: "assistant",
1329
- content: "Hi there!",
1330
- timestamp: "2026-03-27T10:00:05Z"
1331
- });
1332
- });
1333
- it("should skip metadata entry types", ()=>{
1334
- const filePath = writeJsonl([
1335
- {
1336
- type: "file-history-snapshot",
1337
- timestamp: "2026-03-27T10:00:00Z",
1338
- snapshot: {}
1339
- },
1340
- {
1341
- type: "last-prompt",
1342
- timestamp: "2026-03-27T10:00:00Z"
1343
- },
1344
- {
1345
- type: "user",
1346
- timestamp: "2026-03-27T10:00:01Z",
1347
- message: {
1348
- content: "Fix bug"
1349
- }
1350
- }
1351
- ]);
1352
- const messages = adapter.getConversation(filePath);
1353
- expect(messages).toHaveLength(1);
1354
- expect(messages[0].content).toBe("Fix bug");
1355
- });
1356
- it("should skip progress and thinking entries", ()=>{
1357
- const filePath = writeJsonl([
1358
- {
1359
- type: "user",
1360
- timestamp: "2026-03-27T10:00:00Z",
1361
- message: {
1362
- content: "Hello"
1363
- }
1364
- },
1365
- {
1366
- type: "progress",
1367
- timestamp: "2026-03-27T10:00:01Z",
1368
- data: {}
1369
- },
1370
- {
1371
- type: "thinking",
1372
- timestamp: "2026-03-27T10:00:02Z"
1373
- },
1374
- {
1375
- type: "assistant",
1376
- timestamp: "2026-03-27T10:00:03Z",
1377
- message: {
1378
- content: [
1379
- {
1380
- type: "text",
1381
- text: "Done"
1382
- }
1383
- ]
1384
- }
1385
- }
1386
- ]);
1387
- const messages = adapter.getConversation(filePath);
1388
- expect(messages).toHaveLength(2);
1389
- expect(messages[0].role).toBe("user");
1390
- expect(messages[1].role).toBe("assistant");
1391
- });
1392
- it("should include system messages", ()=>{
1393
- const filePath = writeJsonl([
1394
- {
1395
- type: "system",
1396
- timestamp: "2026-03-27T10:00:00Z",
1397
- message: {
1398
- content: "System initialized"
1399
- }
1400
- }
1401
- ]);
1402
- const messages = adapter.getConversation(filePath);
1403
- expect(messages).toHaveLength(1);
1404
- expect(messages[0]).toEqual({
1405
- role: "system",
1406
- content: "System initialized",
1407
- timestamp: "2026-03-27T10:00:00Z"
1408
- });
1409
- });
1410
- it("should skip tool_use and tool_result blocks in default mode", ()=>{
1411
- const filePath = writeJsonl([
1412
- {
1413
- type: "assistant",
1414
- timestamp: "2026-03-27T10:00:00Z",
1415
- message: {
1416
- content: [
1417
- {
1418
- type: "text",
1419
- text: "Let me read the file."
1420
- },
1421
- {
1422
- type: "tool_use",
1423
- name: "Read",
1424
- input: {
1425
- file_path: "/src/app.ts"
1426
- }
1427
- }
1428
- ]
1429
- }
1430
- },
1431
- {
1432
- type: "user",
1433
- timestamp: "2026-03-27T10:00:01Z",
1434
- message: {
1435
- content: [
1436
- {
1437
- type: "tool_result",
1438
- tool_use_id: "toolu_1",
1439
- content: "file contents here"
1440
- }
1441
- ]
1442
- }
1443
- }
1444
- ]);
1445
- const messages = adapter.getConversation(filePath);
1446
- expect(messages).toHaveLength(1);
1447
- expect(messages[0].content).toBe("Let me read the file.");
1448
- });
1449
- it("should include tool_use and tool_result blocks in verbose mode", ()=>{
1450
- const filePath = writeJsonl([
1451
- {
1452
- type: "assistant",
1453
- timestamp: "2026-03-27T10:00:00Z",
1454
- message: {
1455
- content: [
1456
- {
1457
- type: "text",
1458
- text: "Let me read the file."
1459
- },
1460
- {
1461
- type: "tool_use",
1462
- name: "Read",
1463
- input: {
1464
- file_path: "/src/app.ts"
1465
- }
1466
- }
1467
- ]
1468
- }
1469
- },
1470
- {
1471
- type: "user",
1472
- timestamp: "2026-03-27T10:00:01Z",
1473
- message: {
1474
- content: [
1475
- {
1476
- type: "tool_result",
1477
- tool_use_id: "toolu_1",
1478
- content: "file contents here"
1479
- }
1480
- ]
1481
- }
1482
- }
1483
- ]);
1484
- const messages = adapter.getConversation(filePath, {
1485
- verbose: true
1486
- });
1487
- expect(messages).toHaveLength(2);
1488
- expect(messages[0].content).toContain("[Tool: Read]");
1489
- expect(messages[0].content).toContain("/src/app.ts");
1490
- expect(messages[1].content).toContain("[Tool Result]");
1491
- });
1492
- it("should handle tool_result errors in verbose mode", ()=>{
1493
- const filePath = writeJsonl([
1494
- {
1495
- type: "user",
1496
- timestamp: "2026-03-27T10:00:00Z",
1497
- message: {
1498
- content: [
1499
- {
1500
- type: "tool_result",
1501
- tool_use_id: "toolu_1",
1502
- content: "Something went wrong",
1503
- is_error: true
1504
- }
1505
- ]
1506
- }
1507
- }
1508
- ]);
1509
- const messages = adapter.getConversation(filePath, {
1510
- verbose: true
1511
- });
1512
- expect(messages).toHaveLength(1);
1513
- expect(messages[0].content).toContain("[Tool Error]");
1514
- });
1515
- it("should handle malformed JSON lines gracefully", ()=>{
1516
- const filePath = path.join(tmpDir, "malformed.jsonl");
1517
- fs.writeFileSync(filePath, [
1518
- JSON.stringify({
1519
- type: "user",
1520
- timestamp: "2026-03-27T10:00:00Z",
1521
- message: {
1522
- content: "Hello"
1523
- }
1524
- }),
1525
- "this is not valid json",
1526
- JSON.stringify({
1527
- type: "assistant",
1528
- timestamp: "2026-03-27T10:00:01Z",
1529
- message: {
1530
- content: [
1531
- {
1532
- type: "text",
1533
- text: "World"
1534
- }
1535
- ]
1536
- }
1537
- })
1538
- ].join("\n"));
1539
- const messages = adapter.getConversation(filePath);
1540
- expect(messages).toHaveLength(2);
1541
- });
1542
- it("should return empty array for missing file", ()=>{
1543
- const messages = adapter.getConversation("/nonexistent/path.jsonl");
1544
- expect(messages).toEqual([]);
1545
- });
1546
- it("should return empty array for empty file", ()=>{
1547
- const filePath = path.join(tmpDir, "empty.jsonl");
1548
- fs.writeFileSync(filePath, "");
1549
- const messages = adapter.getConversation(filePath);
1550
- expect(messages).toEqual([]);
1551
- });
1552
- it("should filter noise messages from user entries", ()=>{
1553
- const filePath = writeJsonl([
1554
- {
1555
- type: "user",
1556
- timestamp: "2026-03-27T10:00:00Z",
1557
- message: {
1558
- content: [
1559
- {
1560
- type: "text",
1561
- text: "[Request interrupted by user]"
1562
- }
1563
- ]
1564
- }
1565
- },
1566
- {
1567
- type: "user",
1568
- timestamp: "2026-03-27T10:00:01Z",
1569
- message: {
1570
- content: "Tool loaded."
1571
- }
1572
- },
1573
- {
1574
- type: "user",
1575
- timestamp: "2026-03-27T10:00:02Z",
1576
- message: {
1577
- content: "Real question"
1578
- }
1579
- }
1580
- ]);
1581
- const messages = adapter.getConversation(filePath);
1582
- expect(messages).toHaveLength(1);
1583
- expect(messages[0].content).toBe("Real question");
1584
- });
1585
- });
1586
- describe("listSessions", ()=>{
1587
- let tmpDir;
1588
- let projectsDir;
1589
- beforeEach(()=>{
1590
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "claude-list-"));
1591
- projectsDir = path.join(tmpDir, "projects");
1592
- fs.mkdirSync(projectsDir, {
1593
- recursive: true
1594
- });
1595
- adapter.projectsDir = projectsDir;
1596
- });
1597
- afterEach(()=>{
1598
- fs.rmSync(tmpDir, {
1599
- recursive: true,
1600
- force: true
1601
- });
1602
- });
1603
- function writeSession(projectDir, sessionId, lines) {
1604
- fs.mkdirSync(projectDir, {
1605
- recursive: true
1606
- });
1607
- const filePath = path.join(projectDir, `${sessionId}.jsonl`);
1608
- fs.writeFileSync(filePath, lines.map((l)=>JSON.stringify(l)).join("\n"));
1609
- return filePath;
1610
- }
1611
- it("returns empty when projects dir does not exist", async ()=>{
1612
- fs.rmSync(projectsDir, {
1613
- recursive: true,
1614
- force: true
1615
- });
1616
- const result = await adapter.listSessions();
1617
- expect(result).toEqual([]);
1618
- });
1619
- it("returns sessions from a single cwd-scoped project dir", async ()=>{
1620
- const cwd = "/Users/test/proj";
1621
- const projDir = path.join(projectsDir, "-Users-test-proj");
1622
- const filePath = writeSession(projDir, "sess-1", [
1623
- {
1624
- type: "user",
1625
- timestamp: "2025-01-01T00:00:00Z",
1626
- cwd,
1627
- message: {
1628
- content: "first prompt"
1629
- }
1630
- },
1631
- {
1632
- type: "assistant",
1633
- timestamp: "2025-01-01T00:01:00Z"
1634
- }
1635
- ]);
1636
- const result = await adapter.listSessions({
1637
- cwd
1638
- });
1639
- expect(result).toHaveLength(1);
1640
- expect(result[0]).toMatchObject({
1641
- type: "claude",
1642
- sessionId: "sess-1",
1643
- cwd,
1644
- firstUserMessage: "first prompt",
1645
- sessionFilePath: filePath
1646
- });
1647
- expect(result[0].lastActive).toBeInstanceOf(Date);
1648
- expect(result[0].startedAt).toBeInstanceOf(Date);
1649
- });
1650
- it("lists sessions from all project dirs when no cwd filter", async ()=>{
1651
- const cwdA = "/Users/test/proj-a";
1652
- const cwdB = "/Users/test/proj-b";
1653
- writeSession(path.join(projectsDir, "-Users-test-proj-a"), "a", [
1654
- {
1655
- type: "user",
1656
- timestamp: "2025-01-01T00:00:00Z",
1657
- cwd: cwdA,
1658
- message: {
1659
- content: "msg-a"
1660
- }
1661
- }
1662
- ]);
1663
- writeSession(path.join(projectsDir, "-Users-test-proj-b"), "b", [
1664
- {
1665
- type: "user",
1666
- timestamp: "2025-01-02T00:00:00Z",
1667
- cwd: cwdB,
1668
- message: {
1669
- content: "msg-b"
1670
- }
1671
- }
1672
- ]);
1673
- const result = await adapter.listSessions();
1674
- expect(result).toHaveLength(2);
1675
- expect(result.map((r)=>r.sessionId).sort()).toEqual([
1676
- "a",
1677
- "b"
1678
- ]);
1679
- const cwds = result.map((r)=>r.cwd).sort();
1680
- expect(cwds).toEqual([
1681
- cwdA,
1682
- cwdB
1683
- ]);
1684
- });
1685
- it("finds an exact session ID without returning other project sessions", async ()=>{
1686
- const wantedPath = writeSession(path.join(projectsDir, "-repo-a"), "wanted", [
1687
- {
1688
- type: "user",
1689
- timestamp: "2025-01-01T00:00:00Z",
1690
- cwd: "/repo-a",
1691
- message: {
1692
- content: "wanted prompt"
1693
- }
1694
- }
1695
- ]);
1696
- writeSession(path.join(projectsDir, "-repo-b"), "other", [
1697
- {
1698
- type: "user",
1699
- timestamp: "2025-01-01T00:00:00Z",
1700
- cwd: "/repo-b",
1701
- message: {
1702
- content: "other prompt"
1703
- }
1704
- }
1705
- ]);
1706
- await expect(adapter.findSessionsById("wanted")).resolves.toEqual([
1707
- expect.objectContaining({
1708
- sessionId: "wanted",
1709
- sessionFilePath: wantedPath
1710
- })
1711
- ]);
1712
- });
1713
- it("drops sessions whose recorded cwd does not match opts.cwd (strict equality)", async ()=>{
1714
- const cwdReal = "/Users/test/foo";
1715
- const cwdRequested = "/Users/test/foo/sub";
1716
- writeSession(path.join(projectsDir, "-Users-test-foo"), "s", [
1717
- {
1718
- type: "user",
1719
- timestamp: "2025-01-01T00:00:00Z",
1720
- cwd: cwdReal,
1721
- message: {
1722
- content: "hi"
1723
- }
1724
- }
1725
- ]);
1726
- // Encoded dir for the requested cwd doesn't exist → return []
1727
- const result = await adapter.listSessions({
1728
- cwd: cwdRequested
1729
- });
1730
- expect(result).toEqual([]);
1731
- });
1732
- it("drops sessions whose recorded cwd disagrees with the encoded dir", async ()=>{
1733
- // Edge case: encoded dir lookup matches, but session content
1734
- // records a different cwd. Strict-equality filter must reject.
1735
- const requested = "/Users/test/proj";
1736
- const projDir = path.join(projectsDir, "-Users-test-proj");
1737
- writeSession(projDir, "s", [
1738
- {
1739
- type: "user",
1740
- timestamp: "2025-01-01T00:00:00Z",
1741
- cwd: "/different/path",
1742
- message: {
1743
- content: "mismatch"
1744
- }
1745
- }
1746
- ]);
1747
- const result = await adapter.listSessions({
1748
- cwd: requested
1749
- });
1750
- expect(result).toEqual([]);
1751
- });
1752
- it("finds sessions whose recorded cwd lives in a different encoded dir (worktree case)", async ()=>{
1753
- // Real-world case: Claude Code is launched in /repo, then chdirs into
1754
- // /repo/.worktrees/feature. The session file is stored under the
1755
- // ENCODED launch dir, but its content records the worktree path.
1756
- // listSessions({ cwd: worktree }) must still find it.
1757
- const launchDir = path.join(projectsDir, "-repo");
1758
- const worktreeCwd = "/repo/.worktrees/feature";
1759
- writeSession(launchDir, "wt", [
1760
- {
1761
- type: "user",
1762
- timestamp: "2025-01-01T00:00:00Z",
1763
- cwd: worktreeCwd,
1764
- message: {
1765
- content: "in worktree"
1766
- }
1767
- }
1768
- ]);
1769
- const result = await adapter.listSessions({
1770
- cwd: worktreeCwd
1771
- });
1772
- expect(result).toHaveLength(1);
1773
- expect(result[0]).toMatchObject({
1774
- sessionId: "wt",
1775
- cwd: worktreeCwd,
1776
- firstUserMessage: "in worktree"
1777
- });
1778
- });
1779
- it("skips malformed session files", async ()=>{
1780
- const cwd = "/Users/test/p";
1781
- const projDir = path.join(projectsDir, "-Users-test-p");
1782
- fs.mkdirSync(projDir, {
1783
- recursive: true
1784
- });
1785
- fs.writeFileSync(path.join(projDir, "bad.jsonl"), "not valid json");
1786
- writeSession(projDir, "good", [
1787
- {
1788
- type: "user",
1789
- timestamp: "2025-01-01T00:00:00Z",
1790
- cwd,
1791
- message: {
1792
- content: "ok"
1793
- }
1794
- }
1795
- ]);
1796
- const result = await adapter.listSessions({
1797
- cwd
1798
- });
1799
- expect(result).toHaveLength(1);
1800
- expect(result[0].sessionId).toBe("good");
1801
- });
1802
- it("captures first user message after filtering noise", async ()=>{
1803
- const cwd = "/Users/test/q";
1804
- writeSession(path.join(projectsDir, "-Users-test-q"), "s", [
1805
- {
1806
- type: "user",
1807
- timestamp: "2025-01-01T00:00:00Z",
1808
- cwd,
1809
- message: {
1810
- content: "Tool loaded."
1811
- }
1812
- },
1813
- {
1814
- type: "user",
1815
- timestamp: "2025-01-01T00:00:01Z",
1816
- cwd,
1817
- message: {
1818
- content: "real first prompt"
1819
- }
1820
- },
1821
- {
1822
- type: "user",
1823
- timestamp: "2025-01-01T00:00:02Z",
1824
- cwd,
1825
- message: {
1826
- content: "second prompt"
1827
- }
1828
- }
1829
- ]);
1830
- const result = await adapter.listSessions({
1831
- cwd
1832
- });
1833
- expect(result).toHaveLength(1);
1834
- expect(result[0].firstUserMessage).toBe("real first prompt");
1835
- });
1836
- it("returns empty firstUserMessage when no user message exists", async ()=>{
1837
- const cwd = "/Users/test/empty";
1838
- writeSession(path.join(projectsDir, "-Users-test-empty"), "s", [
1839
- {
1840
- type: "assistant",
1841
- timestamp: "2025-01-01T00:00:00Z"
1842
- }
1843
- ]);
1844
- const result = await adapter.listSessions({
1845
- cwd
1846
- });
1847
- expect(result).toHaveLength(1);
1848
- expect(result[0].firstUserMessage).toBe("");
1849
- });
1850
- });
1851
- });
1852
-
1853
- //# sourceMappingURL=ClaudeCodeAdapter.test.js.map