@ai-devkit/agent-manager 0.35.0 → 0.37.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 (651) hide show
  1. package/dist/AgentManager.d.ts +9 -4
  2. package/dist/AgentManager.d.ts.map +1 -1
  3. package/dist/AgentManager.js +21 -2
  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/claude.test.js +485 -0
  14. package/dist/__tests__/capacity/claude.test.js.map +1 -0
  15. package/dist/__tests__/capacity/openai.test.js +670 -0
  16. package/dist/__tests__/capacity/openai.test.js.map +1 -0
  17. package/dist/__tests__/capacity/wham.test.js +144 -0
  18. package/dist/__tests__/capacity/wham.test.js.map +1 -0
  19. package/dist/__tests__/harnesses/BoundedSummarySkip.test.js +568 -0
  20. package/dist/__tests__/harnesses/BoundedSummarySkip.test.js.map +1 -0
  21. package/dist/__tests__/harnesses/SessionSummaryEquivalence.test.js +1089 -0
  22. package/dist/__tests__/harnesses/SessionSummaryEquivalence.test.js.map +1 -0
  23. package/dist/__tests__/harnesses/antigravity/AntigravityCliAdapter.subprocess.test.js +143 -0
  24. package/dist/__tests__/harnesses/antigravity/AntigravityCliAdapter.subprocess.test.js.map +1 -0
  25. package/dist/__tests__/harnesses/antigravity/AntigravityCliAdapter.test.js +462 -0
  26. package/dist/__tests__/harnesses/antigravity/AntigravityCliAdapter.test.js.map +1 -0
  27. package/dist/__tests__/harnesses/builtinAdapters.test.js +33 -0
  28. package/dist/__tests__/harnesses/builtinAdapters.test.js.map +1 -0
  29. package/dist/__tests__/{providers → harnesses}/claude/ClaudeAgentMapper.test.js +4 -4
  30. package/dist/__tests__/harnesses/claude/ClaudeAgentMapper.test.js.map +1 -0
  31. package/dist/__tests__/{adapters → harnesses/claude}/ClaudeCodeAdapter.test.js +47 -19
  32. package/dist/__tests__/harnesses/claude/ClaudeCodeAdapter.test.js.map +1 -0
  33. package/dist/__tests__/{providers → harnesses}/claude/ClaudeSessionLocator.test.js +1 -12
  34. package/dist/__tests__/{providers → harnesses}/claude/ClaudeSessionLocator.test.js.map +1 -1
  35. package/dist/__tests__/{utils → harnesses/claude}/ClaudeSessionParser.test.js +2 -2
  36. package/dist/__tests__/harnesses/claude/ClaudeSessionParser.test.js.map +1 -0
  37. package/dist/__tests__/{print → harnesses/claude/durable}/ClaudeCliProbe.test.js +1 -1
  38. package/dist/__tests__/harnesses/claude/durable/ClaudeCliProbe.test.js.map +1 -0
  39. package/dist/__tests__/{print → harnesses/claude/durable}/ClaudePrintAgent.integration.test.js +1 -1
  40. package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.js.map +1 -0
  41. package/dist/__tests__/{print → harnesses/claude/durable}/ClaudePrintAgentService.test.js +4 -4
  42. package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgentService.test.js.map +1 -0
  43. package/dist/__tests__/{print → harnesses/claude/durable}/ClaudePrintRunner.test.js +1 -1
  44. package/dist/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.js.map +1 -0
  45. package/dist/__tests__/{adapters → harnesses/codex}/CodexAdapter.test.js +304 -10
  46. package/dist/__tests__/harnesses/codex/CodexAdapter.test.js.map +1 -0
  47. package/dist/__tests__/harnesses/codex/CodexSessionLocator.test.js +463 -0
  48. package/dist/__tests__/harnesses/codex/CodexSessionLocator.test.js.map +1 -0
  49. package/dist/__tests__/{providers → harnesses}/codex/CodexSessionMapping.test.js +1 -1
  50. package/dist/__tests__/{providers → harnesses}/codex/CodexSessionMapping.test.js.map +1 -1
  51. package/dist/__tests__/{providers → harnesses}/codex/CodexSessionParser.test.js +1 -1
  52. package/dist/__tests__/{providers → harnesses}/codex/CodexSessionParser.test.js.map +1 -1
  53. package/dist/__tests__/{durable → harnesses/codex/durable}/CodexCliProbe.test.js +4 -4
  54. package/dist/__tests__/harnesses/codex/durable/CodexCliProbe.test.js.map +1 -0
  55. package/dist/__tests__/{durable → harnesses/codex/durable}/CodexDurableAgentRepository.test.js +1 -1
  56. package/dist/__tests__/harnesses/codex/durable/CodexDurableAgentRepository.test.js.map +1 -0
  57. package/dist/__tests__/{durable → harnesses/codex/durable}/CodexPrintAgent.integration.test.js +1 -1
  58. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.js.map +1 -0
  59. package/dist/__tests__/{durable → harnesses/codex/durable}/CodexPrintAgentService.test.js +8 -18
  60. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.js.map +1 -0
  61. package/dist/__tests__/{durable → harnesses/codex/durable}/CodexPrintRunner.test.js +2 -7
  62. package/dist/__tests__/harnesses/codex/durable/CodexPrintRunner.test.js.map +1 -0
  63. package/dist/__tests__/{providers → harnesses}/copilot/CopilotAdapter.test.js +1 -1
  64. package/dist/__tests__/{providers → harnesses}/copilot/CopilotAdapter.test.js.map +1 -1
  65. package/dist/__tests__/harnesses/copilot/CopilotRefreshIO.test.js +290 -0
  66. package/dist/__tests__/harnesses/copilot/CopilotRefreshIO.test.js.map +1 -0
  67. package/dist/__tests__/{providers → harnesses}/gemini/GeminiCliAdapter.test.js +34 -25
  68. package/dist/__tests__/harnesses/gemini/GeminiCliAdapter.test.js.map +1 -0
  69. package/dist/__tests__/harnesses/gemini/GeminiSessionJsonl.test.js +491 -0
  70. package/dist/__tests__/harnesses/gemini/GeminiSessionJsonl.test.js.map +1 -0
  71. package/dist/__tests__/harnesses/gemini/GeminiSessionLocator.test.js +399 -0
  72. package/dist/__tests__/harnesses/gemini/GeminiSessionLocator.test.js.map +1 -0
  73. package/dist/__tests__/{providers → harnesses}/grok/GrokAgentMapper.test.js +1 -1
  74. package/dist/__tests__/{providers → harnesses}/grok/GrokAgentMapper.test.js.map +1 -1
  75. package/dist/__tests__/{providers → harnesses}/grok/GrokCliAdapter.test.js +1 -1
  76. package/dist/__tests__/{providers → harnesses}/grok/GrokCliAdapter.test.js.map +1 -1
  77. package/dist/__tests__/harnesses/grok/GrokIncrementalRefresh.test.js +167 -0
  78. package/dist/__tests__/harnesses/grok/GrokIncrementalRefresh.test.js.map +1 -0
  79. package/dist/__tests__/{providers → harnesses}/grok/GrokSessionLocator.test.js +1 -1
  80. package/dist/__tests__/{providers → harnesses}/grok/GrokSessionLocator.test.js.map +1 -1
  81. package/dist/__tests__/harnesses/grok/GrokSessionParser.test.js +301 -0
  82. package/dist/__tests__/harnesses/grok/GrokSessionParser.test.js.map +1 -0
  83. package/dist/__tests__/harnesses/kiro/KiroAdapter.test.js +662 -0
  84. package/dist/__tests__/harnesses/kiro/KiroAdapter.test.js.map +1 -0
  85. package/dist/__tests__/{providers → harnesses}/opencode/OpenCodeAdapter.test.js +1 -1
  86. package/dist/__tests__/{providers → harnesses}/opencode/OpenCodeAdapter.test.js.map +1 -1
  87. package/dist/__tests__/{providers → harnesses}/opencode/OpenCodeAgentMapper.test.js +1 -1
  88. package/dist/__tests__/{providers → harnesses}/opencode/OpenCodeAgentMapper.test.js.map +1 -1
  89. package/dist/__tests__/{providers → harnesses}/opencode/OpenCodeSessionLocator.test.js +2 -2
  90. package/dist/__tests__/{providers → harnesses}/opencode/OpenCodeSessionLocator.test.js.map +1 -1
  91. package/dist/__tests__/{providers → harnesses}/opencode/OpenCodeSessionParser.test.js +1 -1
  92. package/dist/__tests__/{providers → harnesses}/opencode/OpenCodeSessionParser.test.js.map +1 -1
  93. package/dist/__tests__/{providers → harnesses}/pi/PiAdapter.test.js +1 -1
  94. package/dist/__tests__/{providers → harnesses}/pi/PiAdapter.test.js.map +1 -1
  95. package/dist/__tests__/harnesses/pi/PiDiscoveryIO.test.js +382 -0
  96. package/dist/__tests__/harnesses/pi/PiDiscoveryIO.test.js.map +1 -0
  97. package/dist/__tests__/{providers → harnesses}/pi/PiSessionParser.test.js +171 -1
  98. package/dist/__tests__/harnesses/pi/PiSessionParser.test.js.map +1 -0
  99. package/dist/__tests__/{providers → harnesses}/pi/PiSessionTracker.test.js +1 -1
  100. package/dist/__tests__/{providers → harnesses}/pi/PiSessionTracker.test.js.map +1 -1
  101. package/dist/__tests__/{providers → harnesses}/pi/durable/PiCliProbe.test.js.map +1 -1
  102. package/dist/__tests__/{providers → harnesses}/pi/durable/PiDurableAgentRepository.test.js.map +1 -1
  103. package/dist/__tests__/{providers → harnesses}/pi/durable/PiPrintAgentService.test.js.map +1 -1
  104. package/dist/__tests__/{providers → harnesses}/pi/durable/PiPrintProtocol.test.js +1 -1
  105. package/dist/__tests__/{providers → harnesses}/pi/durable/PiPrintProtocol.test.js.map +1 -1
  106. package/dist/__tests__/{providers → harnesses}/pi/durable/PiPrintRunner.test.js.map +1 -1
  107. package/dist/__tests__/{providers → harnesses}/pi/durable/PiStreamParser.test.js +1 -1
  108. package/dist/__tests__/{providers → harnesses}/pi/durable/PiStreamParser.test.js.map +1 -1
  109. package/dist/__tests__/readiness/AgentReadiness.test.js +20 -0
  110. package/dist/__tests__/readiness/AgentReadiness.test.js.map +1 -1
  111. package/dist/__tests__/runtime/ManagedAgentRuntime.test.js +49 -0
  112. package/dist/__tests__/runtime/ManagedAgentRuntime.test.js.map +1 -1
  113. package/dist/__tests__/utils/IncrementalJsonlSummary.test.js +650 -0
  114. package/dist/__tests__/utils/IncrementalJsonlSummary.test.js.map +1 -0
  115. package/dist/__tests__/utils/agents.test.js +72 -2
  116. package/dist/__tests__/utils/agents.test.js.map +1 -1
  117. package/dist/__tests__/utils/conversationTail.bench.test.js +258 -0
  118. package/dist/__tests__/utils/conversationTail.bench.test.js.map +1 -0
  119. package/dist/__tests__/utils/conversationTailParity.test.js +588 -0
  120. package/dist/__tests__/utils/conversationTailParity.test.js.map +1 -0
  121. package/dist/__tests__/utils/jsonlTail.test.js +360 -0
  122. package/dist/__tests__/utils/jsonlTail.test.js.map +1 -0
  123. package/dist/__tests__/utils/matchingConstants.test.js +35 -0
  124. package/dist/__tests__/utils/matchingConstants.test.js.map +1 -0
  125. package/dist/__tests__/utils/process.test.js +436 -2
  126. package/dist/__tests__/utils/process.test.js.map +1 -1
  127. package/dist/adapters/AgentAdapter.d.ts +25 -6
  128. package/dist/adapters/AgentAdapter.d.ts.map +1 -1
  129. package/dist/adapters/AgentAdapter.js +12 -3
  130. package/dist/adapters/AgentAdapter.js.map +1 -1
  131. package/dist/capacity/claude.d.ts +17 -0
  132. package/dist/capacity/claude.d.ts.map +1 -0
  133. package/dist/capacity/claude.js +271 -0
  134. package/dist/capacity/claude.js.map +1 -0
  135. package/dist/capacity/codex.d.ts +1 -2
  136. package/dist/capacity/codex.d.ts.map +1 -1
  137. package/dist/capacity/codex.js +5 -47
  138. package/dist/capacity/codex.js.map +1 -1
  139. package/dist/capacity/index.d.ts +11 -0
  140. package/dist/capacity/index.d.ts.map +1 -1
  141. package/dist/capacity/index.js +17 -0
  142. package/dist/capacity/index.js.map +1 -1
  143. package/dist/capacity/openai.d.ts +47 -0
  144. package/dist/capacity/openai.d.ts.map +1 -0
  145. package/dist/capacity/openai.js +307 -0
  146. package/dist/capacity/openai.js.map +1 -0
  147. package/dist/capacity/wham.d.ts +16 -0
  148. package/dist/capacity/wham.d.ts.map +1 -0
  149. package/dist/capacity/wham.js +66 -0
  150. package/dist/capacity/wham.js.map +1 -0
  151. package/dist/harnesses/antigravity/AntigravityAgentMapper.d.ts +13 -0
  152. package/dist/harnesses/antigravity/AntigravityAgentMapper.d.ts.map +1 -0
  153. package/dist/harnesses/antigravity/AntigravityAgentMapper.js +30 -0
  154. package/dist/harnesses/antigravity/AntigravityAgentMapper.js.map +1 -0
  155. package/dist/harnesses/antigravity/AntigravityCliAdapter.d.ts +32 -0
  156. package/dist/harnesses/antigravity/AntigravityCliAdapter.d.ts.map +1 -0
  157. package/dist/harnesses/antigravity/AntigravityCliAdapter.js +97 -0
  158. package/dist/harnesses/antigravity/AntigravityCliAdapter.js.map +1 -0
  159. package/dist/harnesses/antigravity/AntigravitySessionLocator.d.ts +30 -0
  160. package/dist/harnesses/antigravity/AntigravitySessionLocator.d.ts.map +1 -0
  161. package/dist/harnesses/antigravity/AntigravitySessionLocator.js +56 -0
  162. package/dist/harnesses/antigravity/AntigravitySessionLocator.js.map +1 -0
  163. package/dist/harnesses/antigravity/AntigravitySessionParser.d.ts +75 -0
  164. package/dist/harnesses/antigravity/AntigravitySessionParser.d.ts.map +1 -0
  165. package/dist/harnesses/antigravity/AntigravitySessionParser.js +174 -0
  166. package/dist/harnesses/antigravity/AntigravitySessionParser.js.map +1 -0
  167. package/dist/{providers → harnesses}/claude/ClaudeAgentMapper.d.ts.map +1 -1
  168. package/dist/{providers → harnesses}/claude/ClaudeAgentMapper.js +4 -10
  169. package/dist/harnesses/claude/ClaudeAgentMapper.js.map +1 -0
  170. package/dist/{providers → harnesses}/claude/ClaudeCodeAdapter.d.ts +5 -6
  171. package/dist/harnesses/claude/ClaudeCodeAdapter.d.ts.map +1 -0
  172. package/dist/{providers → harnesses}/claude/ClaudeCodeAdapter.js +17 -15
  173. package/dist/harnesses/claude/ClaudeCodeAdapter.js.map +1 -0
  174. package/dist/{providers → harnesses}/claude/ClaudeSessionLocator.d.ts.map +1 -1
  175. package/dist/{providers → harnesses}/claude/ClaudeSessionLocator.js +3 -3
  176. package/dist/harnesses/claude/ClaudeSessionLocator.js.map +1 -0
  177. package/dist/{providers → harnesses}/claude/ClaudeSessionParser.d.ts +40 -6
  178. package/dist/harnesses/claude/ClaudeSessionParser.d.ts.map +1 -0
  179. package/dist/{providers → harnesses}/claude/ClaudeSessionParser.js +141 -85
  180. package/dist/harnesses/claude/ClaudeSessionParser.js.map +1 -0
  181. package/dist/{providers → harnesses}/claude/durable/ClaudeCliProbe.d.ts.map +1 -1
  182. package/dist/{providers → harnesses}/claude/durable/ClaudeCliProbe.js.map +1 -1
  183. package/dist/{providers → harnesses}/claude/durable/ClaudePrintAgentService.d.ts.map +1 -1
  184. package/dist/{providers → harnesses}/claude/durable/ClaudePrintAgentService.js.map +1 -1
  185. package/dist/{providers → harnesses}/claude/durable/ClaudePrintRunner.d.ts.map +1 -1
  186. package/dist/{providers → harnesses}/claude/durable/ClaudePrintRunner.js.map +1 -1
  187. package/dist/{providers → harnesses}/claude/durable/ClaudeStreamParser.d.ts.map +1 -1
  188. package/dist/{providers → harnesses}/claude/durable/ClaudeStreamParser.js.map +1 -1
  189. package/dist/{providers → harnesses}/codex/CodexAdapter.d.ts +5 -4
  190. package/dist/harnesses/codex/CodexAdapter.d.ts.map +1 -0
  191. package/dist/{providers → harnesses}/codex/CodexAdapter.js +139 -19
  192. package/dist/harnesses/codex/CodexAdapter.js.map +1 -0
  193. package/dist/{providers → harnesses}/codex/CodexAgentMapper.d.ts.map +1 -1
  194. package/dist/{providers → harnesses}/codex/CodexAgentMapper.js +4 -11
  195. package/dist/harnesses/codex/CodexAgentMapper.js.map +1 -0
  196. package/dist/harnesses/codex/CodexSessionLocator.d.ts +74 -0
  197. package/dist/harnesses/codex/CodexSessionLocator.d.ts.map +1 -0
  198. package/dist/harnesses/codex/CodexSessionLocator.js +359 -0
  199. package/dist/harnesses/codex/CodexSessionLocator.js.map +1 -0
  200. package/dist/{providers → harnesses}/codex/CodexSessionMapping.d.ts.map +1 -1
  201. package/dist/{providers → harnesses}/codex/CodexSessionMapping.js +3 -3
  202. package/dist/harnesses/codex/CodexSessionMapping.js.map +1 -0
  203. package/dist/harnesses/codex/CodexSessionParser.d.ts +89 -0
  204. package/dist/harnesses/codex/CodexSessionParser.d.ts.map +1 -0
  205. package/dist/{providers → harnesses}/codex/CodexSessionParser.js +124 -78
  206. package/dist/harnesses/codex/CodexSessionParser.js.map +1 -0
  207. package/dist/{providers → harnesses}/codex/durable/CodexCliProbe.d.ts.map +1 -1
  208. package/dist/{providers → harnesses}/codex/durable/CodexCliProbe.js.map +1 -1
  209. package/dist/{providers → harnesses}/codex/durable/CodexPrintAgentService.d.ts.map +1 -1
  210. package/dist/{providers → harnesses}/codex/durable/CodexPrintAgentService.js.map +1 -1
  211. package/dist/{providers → harnesses}/codex/durable/CodexPrintRunner.d.ts.map +1 -1
  212. package/dist/{providers → harnesses}/codex/durable/CodexPrintRunner.js.map +1 -1
  213. package/dist/{providers → harnesses}/codex/durable/CodexStreamParser.d.ts.map +1 -1
  214. package/dist/{providers → harnesses}/codex/durable/CodexStreamParser.js.map +1 -1
  215. package/dist/{providers → harnesses}/copilot/CopilotAdapter.d.ts +7 -6
  216. package/dist/harnesses/copilot/CopilotAdapter.d.ts.map +1 -0
  217. package/dist/{providers → harnesses}/copilot/CopilotAdapter.js +19 -14
  218. package/dist/harnesses/copilot/CopilotAdapter.js.map +1 -0
  219. package/dist/{providers → harnesses}/copilot/CopilotAgentMapper.d.ts.map +1 -1
  220. package/dist/{providers → harnesses}/copilot/CopilotAgentMapper.js +4 -11
  221. package/dist/harnesses/copilot/CopilotAgentMapper.js.map +1 -0
  222. package/dist/harnesses/copilot/CopilotSessionLocator.d.ts +42 -0
  223. package/dist/harnesses/copilot/CopilotSessionLocator.d.ts.map +1 -0
  224. package/dist/harnesses/copilot/CopilotSessionLocator.js +126 -0
  225. package/dist/harnesses/copilot/CopilotSessionLocator.js.map +1 -0
  226. package/dist/harnesses/copilot/CopilotSessionParser.d.ts +62 -0
  227. package/dist/harnesses/copilot/CopilotSessionParser.d.ts.map +1 -0
  228. package/dist/harnesses/copilot/CopilotSessionParser.js +236 -0
  229. package/dist/harnesses/copilot/CopilotSessionParser.js.map +1 -0
  230. package/dist/{providers → harnesses}/gemini/GeminiAgentMapper.d.ts.map +1 -1
  231. package/dist/{providers → harnesses}/gemini/GeminiAgentMapper.js +4 -11
  232. package/dist/harnesses/gemini/GeminiAgentMapper.js.map +1 -0
  233. package/dist/{providers → harnesses}/gemini/GeminiCliAdapter.d.ts +4 -5
  234. package/dist/harnesses/gemini/GeminiCliAdapter.d.ts.map +1 -0
  235. package/dist/{providers → harnesses}/gemini/GeminiCliAdapter.js +6 -7
  236. package/dist/harnesses/gemini/GeminiCliAdapter.js.map +1 -0
  237. package/dist/harnesses/gemini/GeminiSessionLocator.d.ts +72 -0
  238. package/dist/harnesses/gemini/GeminiSessionLocator.d.ts.map +1 -0
  239. package/dist/harnesses/gemini/GeminiSessionLocator.js +300 -0
  240. package/dist/harnesses/gemini/GeminiSessionLocator.js.map +1 -0
  241. package/dist/{providers → harnesses}/gemini/GeminiSessionParser.d.ts +34 -7
  242. package/dist/harnesses/gemini/GeminiSessionParser.d.ts.map +1 -0
  243. package/dist/harnesses/gemini/GeminiSessionParser.js +272 -0
  244. package/dist/harnesses/gemini/GeminiSessionParser.js.map +1 -0
  245. package/dist/harnesses/gemini/fileSignature.d.ts +8 -0
  246. package/dist/harnesses/gemini/fileSignature.d.ts.map +1 -0
  247. package/dist/harnesses/gemini/fileSignature.js +9 -0
  248. package/dist/harnesses/gemini/fileSignature.js.map +1 -0
  249. package/dist/{providers → harnesses}/grok/GrokAgentMapper.d.ts.map +1 -1
  250. package/dist/{providers → harnesses}/grok/GrokAgentMapper.js +4 -10
  251. package/dist/harnesses/grok/GrokAgentMapper.js.map +1 -0
  252. package/dist/{providers → harnesses}/grok/GrokCliAdapter.d.ts +5 -5
  253. package/dist/harnesses/grok/GrokCliAdapter.d.ts.map +1 -0
  254. package/dist/{providers → harnesses}/grok/GrokCliAdapter.js +14 -10
  255. package/dist/harnesses/grok/GrokCliAdapter.js.map +1 -0
  256. package/dist/{providers → harnesses}/grok/GrokSessionLocator.d.ts.map +1 -1
  257. package/dist/{providers → harnesses}/grok/GrokSessionLocator.js +2 -2
  258. package/dist/harnesses/grok/GrokSessionLocator.js.map +1 -0
  259. package/dist/harnesses/grok/GrokSessionParser.d.ts +87 -0
  260. package/dist/harnesses/grok/GrokSessionParser.d.ts.map +1 -0
  261. package/dist/harnesses/grok/GrokSessionParser.js +185 -0
  262. package/dist/harnesses/grok/GrokSessionParser.js.map +1 -0
  263. package/dist/harnesses/index.d.ts +7 -0
  264. package/dist/harnesses/index.d.ts.map +1 -0
  265. package/dist/harnesses/index.js +27 -0
  266. package/dist/harnesses/index.js.map +1 -0
  267. package/dist/harnesses/kiro/KiroAdapter.d.ts +31 -0
  268. package/dist/harnesses/kiro/KiroAdapter.d.ts.map +1 -0
  269. package/dist/harnesses/kiro/KiroAdapter.js +125 -0
  270. package/dist/harnesses/kiro/KiroAdapter.js.map +1 -0
  271. package/dist/harnesses/kiro/KiroAgentMapper.d.ts +13 -0
  272. package/dist/harnesses/kiro/KiroAgentMapper.d.ts.map +1 -0
  273. package/dist/harnesses/kiro/KiroAgentMapper.js +29 -0
  274. package/dist/harnesses/kiro/KiroAgentMapper.js.map +1 -0
  275. package/dist/harnesses/kiro/KiroSessionLocator.d.ts +38 -0
  276. package/dist/harnesses/kiro/KiroSessionLocator.d.ts.map +1 -0
  277. package/dist/harnesses/kiro/KiroSessionLocator.js +95 -0
  278. package/dist/harnesses/kiro/KiroSessionLocator.js.map +1 -0
  279. package/dist/harnesses/kiro/KiroSessionParser.d.ts +81 -0
  280. package/dist/harnesses/kiro/KiroSessionParser.d.ts.map +1 -0
  281. package/dist/harnesses/kiro/KiroSessionParser.js +251 -0
  282. package/dist/harnesses/kiro/KiroSessionParser.js.map +1 -0
  283. package/dist/{providers → harnesses}/opencode/OpenCodeAdapter.d.ts +2 -4
  284. package/dist/harnesses/opencode/OpenCodeAdapter.d.ts.map +1 -0
  285. package/dist/{providers → harnesses}/opencode/OpenCodeAdapter.js +4 -7
  286. package/dist/harnesses/opencode/OpenCodeAdapter.js.map +1 -0
  287. package/dist/{providers → harnesses}/opencode/OpenCodeAgentMapper.d.ts.map +1 -1
  288. package/dist/{providers → harnesses}/opencode/OpenCodeAgentMapper.js +5 -13
  289. package/dist/harnesses/opencode/OpenCodeAgentMapper.js.map +1 -0
  290. package/dist/{providers → harnesses}/opencode/OpenCodeSessionLocator.d.ts.map +1 -1
  291. package/dist/{providers → harnesses}/opencode/OpenCodeSessionLocator.js +2 -2
  292. package/dist/harnesses/opencode/OpenCodeSessionLocator.js.map +1 -0
  293. package/dist/{providers → harnesses}/opencode/OpenCodeSessionParser.d.ts +2 -4
  294. package/dist/harnesses/opencode/OpenCodeSessionParser.d.ts.map +1 -0
  295. package/dist/{providers → harnesses}/opencode/OpenCodeSessionParser.js +2 -1
  296. package/dist/harnesses/opencode/OpenCodeSessionParser.js.map +1 -0
  297. package/dist/{providers → harnesses}/pi/PiAdapter.d.ts +5 -4
  298. package/dist/harnesses/pi/PiAdapter.d.ts.map +1 -0
  299. package/dist/{providers → harnesses}/pi/PiAdapter.js +16 -12
  300. package/dist/harnesses/pi/PiAdapter.js.map +1 -0
  301. package/dist/{providers → harnesses}/pi/PiAgentMapper.d.ts.map +1 -1
  302. package/dist/{providers → harnesses}/pi/PiAgentMapper.js +4 -11
  303. package/dist/harnesses/pi/PiAgentMapper.js.map +1 -0
  304. package/dist/harnesses/pi/PiSessionLocator.d.ts +61 -0
  305. package/dist/harnesses/pi/PiSessionLocator.d.ts.map +1 -0
  306. package/dist/harnesses/pi/PiSessionLocator.js +212 -0
  307. package/dist/harnesses/pi/PiSessionLocator.js.map +1 -0
  308. package/dist/harnesses/pi/PiSessionParser.d.ts +88 -0
  309. package/dist/harnesses/pi/PiSessionParser.d.ts.map +1 -0
  310. package/dist/harnesses/pi/PiSessionParser.js +318 -0
  311. package/dist/harnesses/pi/PiSessionParser.js.map +1 -0
  312. package/dist/{providers → harnesses}/pi/PiSessionTracker.d.ts.map +1 -1
  313. package/dist/{providers → harnesses}/pi/PiSessionTracker.js +2 -2
  314. package/dist/harnesses/pi/PiSessionTracker.js.map +1 -0
  315. package/dist/{providers → harnesses}/pi/durable/PiCliProbe.d.ts.map +1 -1
  316. package/dist/{providers → harnesses}/pi/durable/PiCliProbe.js.map +1 -1
  317. package/dist/{providers → harnesses}/pi/durable/PiPrintAgentService.d.ts.map +1 -1
  318. package/dist/{providers → harnesses}/pi/durable/PiPrintAgentService.js.map +1 -1
  319. package/dist/{providers → harnesses}/pi/durable/PiPrintProtocol.d.ts.map +1 -1
  320. package/dist/{providers → harnesses}/pi/durable/PiPrintProtocol.js.map +1 -1
  321. package/dist/{providers → harnesses}/pi/durable/PiPrintRunner.d.ts.map +1 -1
  322. package/dist/{providers → harnesses}/pi/durable/PiPrintRunner.js.map +1 -1
  323. package/dist/{providers → harnesses}/pi/durable/PiStreamParser.d.ts.map +1 -1
  324. package/dist/{providers → harnesses}/pi/durable/PiStreamParser.js.map +1 -1
  325. package/dist/harnesses/shared.d.ts +41 -0
  326. package/dist/harnesses/shared.d.ts.map +1 -0
  327. package/dist/harnesses/shared.js +71 -0
  328. package/dist/harnesses/shared.js.map +1 -0
  329. package/dist/index.d.ts +28 -25
  330. package/dist/index.d.ts.map +1 -1
  331. package/dist/index.js +19 -16
  332. package/dist/index.js.map +1 -1
  333. package/dist/readiness/AgentReadiness.d.ts +1 -1
  334. package/dist/readiness/AgentReadiness.d.ts.map +1 -1
  335. package/dist/readiness/AgentReadiness.js.map +1 -1
  336. package/dist/runtime/ManagedAgentRuntime.js +3 -1
  337. package/dist/runtime/ManagedAgentRuntime.js.map +1 -1
  338. package/dist/runtime/herdr/HerdrAgentDiscovery.js +10 -0
  339. package/dist/runtime/herdr/HerdrAgentDiscovery.js.map +1 -1
  340. package/dist/utils/IncrementalJsonlSummary.d.ts +100 -0
  341. package/dist/utils/IncrementalJsonlSummary.d.ts.map +1 -0
  342. package/dist/utils/IncrementalJsonlSummary.js +209 -0
  343. package/dist/utils/IncrementalJsonlSummary.js.map +1 -0
  344. package/dist/utils/agents.d.ts +3 -2
  345. package/dist/utils/agents.d.ts.map +1 -1
  346. package/dist/utils/agents.js +61 -15
  347. package/dist/utils/agents.js.map +1 -1
  348. package/dist/utils/index.d.ts +2 -1
  349. package/dist/utils/index.d.ts.map +1 -1
  350. package/dist/utils/index.js +1 -1
  351. package/dist/utils/index.js.map +1 -1
  352. package/dist/utils/jsonlTail.d.ts +73 -0
  353. package/dist/utils/jsonlTail.d.ts.map +1 -0
  354. package/dist/utils/jsonlTail.js +238 -0
  355. package/dist/utils/jsonlTail.js.map +1 -0
  356. package/dist/utils/matching.d.ts +2 -0
  357. package/dist/utils/matching.d.ts.map +1 -1
  358. package/dist/utils/matching.js +3 -2
  359. package/dist/utils/matching.js.map +1 -1
  360. package/dist/utils/matchingConstants.d.ts +15 -0
  361. package/dist/utils/matchingConstants.d.ts.map +1 -0
  362. package/dist/utils/matchingConstants.js +14 -0
  363. package/dist/utils/matchingConstants.js.map +1 -0
  364. package/dist/utils/process.d.ts +38 -2
  365. package/dist/utils/process.d.ts.map +1 -1
  366. package/dist/utils/process.js +131 -43
  367. package/dist/utils/process.js.map +1 -1
  368. package/package.json +2 -1
  369. package/scripts/benchmark-cold-start.mjs +350 -0
  370. package/src/AgentManager.ts +26 -5
  371. package/src/__tests__/AgentManager.test.ts +141 -3
  372. package/src/__tests__/adapters/IncrementalSessionRefresh.test.ts +437 -0
  373. package/src/__tests__/adapters/adapterProcessImports.test.ts +58 -0
  374. package/src/__tests__/adapters/adapterSnapshotCandidates.test.ts +243 -0
  375. package/src/__tests__/capacity/claude.test.ts +467 -0
  376. package/src/__tests__/capacity/fixtures/claude-credentials.json +7 -0
  377. package/src/__tests__/capacity/fixtures/claude-usage-malformed.json +1 -0
  378. package/src/__tests__/capacity/fixtures/claude-usage-partial.json +15 -0
  379. package/src/__tests__/capacity/fixtures/claude-usage.json +63 -0
  380. package/src/__tests__/capacity/fixtures/openai-auth.json +6 -0
  381. package/src/__tests__/capacity/fixtures/openai-codex-auth.json +9 -0
  382. package/src/__tests__/capacity/fixtures/openai-usage-completions.json +67 -0
  383. package/src/__tests__/capacity/fixtures/openai-usage-responses.json +20 -0
  384. package/src/__tests__/capacity/fixtures/wham-usage.json +32 -0
  385. package/src/__tests__/capacity/openai.test.ts +560 -0
  386. package/src/__tests__/capacity/wham.test.ts +104 -0
  387. package/src/__tests__/harnesses/BoundedSummarySkip.test.ts +496 -0
  388. package/src/__tests__/harnesses/SessionSummaryEquivalence.test.ts +726 -0
  389. package/src/__tests__/harnesses/antigravity/AntigravityCliAdapter.subprocess.test.ts +133 -0
  390. package/src/__tests__/harnesses/antigravity/AntigravityCliAdapter.test.ts +396 -0
  391. package/src/__tests__/harnesses/builtinAdapters.test.ts +33 -0
  392. package/src/__tests__/{providers → harnesses}/claude/ClaudeAgentMapper.test.ts +5 -5
  393. package/src/__tests__/{adapters → harnesses/claude}/ClaudeCodeAdapter.test.ts +54 -24
  394. package/src/__tests__/{providers → harnesses}/claude/ClaudeSessionLocator.test.ts +1 -12
  395. package/src/__tests__/{utils → harnesses/claude}/ClaudeSessionParser.test.ts +2 -2
  396. package/src/__tests__/{print → harnesses/claude/durable}/ClaudeCliProbe.test.ts +1 -1
  397. package/src/__tests__/{print → harnesses/claude/durable}/ClaudePrintAgent.integration.test.ts +1 -1
  398. package/src/__tests__/{print → harnesses/claude/durable}/ClaudePrintAgentService.test.ts +4 -4
  399. package/src/__tests__/{print → harnesses/claude/durable}/ClaudePrintRunner.test.ts +2 -2
  400. package/src/__tests__/{adapters → harnesses/codex}/CodexAdapter.test.ts +277 -12
  401. package/src/__tests__/harnesses/codex/CodexSessionLocator.test.ts +419 -0
  402. package/src/__tests__/{providers → harnesses}/codex/CodexSessionMapping.test.ts +1 -1
  403. package/src/__tests__/{providers → harnesses}/codex/CodexSessionParser.test.ts +1 -1
  404. package/src/__tests__/{durable → harnesses/codex/durable}/CodexCliProbe.test.ts +4 -4
  405. package/src/__tests__/{durable → harnesses/codex/durable}/CodexDurableAgentRepository.test.ts +1 -1
  406. package/src/__tests__/{durable → harnesses/codex/durable}/CodexPrintAgent.integration.test.ts +1 -1
  407. package/src/__tests__/{durable → harnesses/codex/durable}/CodexPrintAgentService.test.ts +8 -18
  408. package/src/__tests__/{durable → harnesses/codex/durable}/CodexPrintRunner.test.ts +3 -9
  409. package/src/__tests__/{providers → harnesses}/copilot/CopilotAdapter.test.ts +1 -1
  410. package/src/__tests__/harnesses/copilot/CopilotRefreshIO.test.ts +270 -0
  411. package/src/__tests__/{providers → harnesses}/gemini/GeminiCliAdapter.test.ts +27 -23
  412. package/src/__tests__/harnesses/gemini/GeminiSessionJsonl.test.ts +402 -0
  413. package/src/__tests__/harnesses/gemini/GeminiSessionLocator.test.ts +396 -0
  414. package/src/__tests__/{providers → harnesses}/grok/GrokAgentMapper.test.ts +2 -2
  415. package/src/__tests__/{providers → harnesses}/grok/GrokCliAdapter.test.ts +1 -1
  416. package/src/__tests__/harnesses/grok/GrokIncrementalRefresh.test.ts +170 -0
  417. package/src/__tests__/{providers → harnesses}/grok/GrokSessionLocator.test.ts +1 -1
  418. package/src/__tests__/harnesses/grok/GrokSessionParser.test.ts +230 -0
  419. package/src/__tests__/harnesses/kiro/KiroAdapter.test.ts +552 -0
  420. package/src/__tests__/{providers → harnesses}/opencode/OpenCodeAdapter.test.ts +1 -1
  421. package/src/__tests__/{providers → harnesses}/opencode/OpenCodeAgentMapper.test.ts +1 -1
  422. package/src/__tests__/{providers → harnesses}/opencode/OpenCodeSessionLocator.test.ts +2 -2
  423. package/src/__tests__/{providers → harnesses}/opencode/OpenCodeSessionParser.test.ts +1 -1
  424. package/src/__tests__/{providers → harnesses}/pi/PiAdapter.test.ts +1 -1
  425. package/src/__tests__/harnesses/pi/PiDiscoveryIO.test.ts +337 -0
  426. package/src/__tests__/{providers → harnesses}/pi/PiSessionParser.test.ts +91 -1
  427. package/src/__tests__/{providers → harnesses}/pi/PiSessionTracker.test.ts +1 -1
  428. package/src/__tests__/{providers → harnesses}/pi/durable/PiPrintProtocol.test.ts +1 -1
  429. package/src/__tests__/{providers → harnesses}/pi/durable/PiStreamParser.test.ts +1 -1
  430. package/src/__tests__/readiness/AgentReadiness.test.ts +16 -0
  431. package/src/__tests__/runtime/ManagedAgentRuntime.test.ts +30 -0
  432. package/src/__tests__/utils/IncrementalJsonlSummary.test.ts +414 -0
  433. package/src/__tests__/utils/agents.test.ts +83 -2
  434. package/src/__tests__/utils/conversationTail.bench.test.ts +193 -0
  435. package/src/__tests__/utils/conversationTailParity.test.ts +365 -0
  436. package/src/__tests__/utils/jsonlTail.test.ts +317 -0
  437. package/src/__tests__/utils/matchingConstants.test.ts +40 -0
  438. package/src/__tests__/utils/process.test.ts +254 -0
  439. package/src/adapters/AgentAdapter.ts +37 -12
  440. package/src/capacity/claude.ts +313 -0
  441. package/src/capacity/codex.ts +25 -134
  442. package/src/capacity/index.ts +33 -4
  443. package/src/capacity/openai.ts +355 -0
  444. package/src/capacity/wham.ts +84 -0
  445. package/src/harnesses/antigravity/AntigravityAgentMapper.ts +34 -0
  446. package/src/harnesses/antigravity/AntigravityCliAdapter.ts +126 -0
  447. package/src/harnesses/antigravity/AntigravitySessionLocator.ts +75 -0
  448. package/src/harnesses/antigravity/AntigravitySessionParser.ts +252 -0
  449. package/src/{providers → harnesses}/claude/ClaudeAgentMapper.ts +2 -10
  450. package/src/{providers → harnesses}/claude/ClaudeCodeAdapter.ts +22 -20
  451. package/src/{providers → harnesses}/claude/ClaudeSessionLocator.ts +3 -3
  452. package/src/{providers → harnesses}/claude/ClaudeSessionParser.ts +189 -97
  453. package/src/{providers → harnesses}/codex/CodexAdapter.ts +153 -29
  454. package/src/{providers → harnesses}/codex/CodexAgentMapper.ts +2 -11
  455. package/src/harnesses/codex/CodexSessionLocator.ts +509 -0
  456. package/src/{providers → harnesses}/codex/CodexSessionMapping.ts +3 -3
  457. package/src/{providers → harnesses}/codex/CodexSessionParser.ts +169 -92
  458. package/src/{providers → harnesses}/copilot/CopilotAdapter.ts +22 -22
  459. package/src/{providers → harnesses}/copilot/CopilotAgentMapper.ts +2 -11
  460. package/src/harnesses/copilot/CopilotSessionLocator.ts +161 -0
  461. package/src/harnesses/copilot/CopilotSessionParser.ts +380 -0
  462. package/src/{providers → harnesses}/gemini/GeminiAgentMapper.ts +2 -11
  463. package/src/{providers → harnesses}/gemini/GeminiCliAdapter.ts +7 -9
  464. package/src/harnesses/gemini/GeminiSessionLocator.ts +394 -0
  465. package/src/{providers → harnesses}/gemini/GeminiSessionParser.ts +155 -31
  466. package/src/harnesses/gemini/fileSignature.ts +10 -0
  467. package/src/{providers → harnesses}/grok/GrokAgentMapper.ts +2 -11
  468. package/src/{providers → harnesses}/grok/GrokCliAdapter.ts +16 -15
  469. package/src/{providers → harnesses}/grok/GrokSessionLocator.ts +2 -2
  470. package/src/harnesses/grok/GrokSessionParser.ts +251 -0
  471. package/src/harnesses/index.ts +28 -0
  472. package/src/harnesses/kiro/KiroAdapter.ts +143 -0
  473. package/src/harnesses/kiro/KiroAgentMapper.ts +34 -0
  474. package/src/harnesses/kiro/KiroSessionLocator.ts +143 -0
  475. package/src/harnesses/kiro/KiroSessionParser.ts +376 -0
  476. package/src/{providers → harnesses}/opencode/OpenCodeAdapter.ts +5 -11
  477. package/src/{providers → harnesses}/opencode/OpenCodeAgentMapper.ts +3 -13
  478. package/src/{providers → harnesses}/opencode/OpenCodeSessionLocator.ts +2 -2
  479. package/src/{providers → harnesses}/opencode/OpenCodeSessionParser.ts +4 -3
  480. package/src/{providers → harnesses}/pi/PiAdapter.ts +20 -18
  481. package/src/{providers → harnesses}/pi/PiAgentMapper.ts +2 -11
  482. package/src/harnesses/pi/PiSessionLocator.ts +288 -0
  483. package/src/harnesses/pi/PiSessionParser.ts +488 -0
  484. package/src/{providers → harnesses}/pi/PiSessionTracker.ts +2 -2
  485. package/src/harnesses/shared.ts +119 -0
  486. package/src/index.ts +34 -23
  487. package/src/readiness/AgentReadiness.ts +4 -1
  488. package/src/runtime/ManagedAgentRuntime.ts +2 -0
  489. package/src/runtime/herdr/HerdrAgentDiscovery.ts +5 -1
  490. package/src/utils/IncrementalJsonlSummary.ts +306 -0
  491. package/src/utils/agents.ts +62 -20
  492. package/src/utils/index.ts +2 -0
  493. package/src/utils/jsonlTail.ts +349 -0
  494. package/src/utils/matching.ts +3 -3
  495. package/src/utils/matchingConstants.ts +15 -0
  496. package/src/utils/process.ts +189 -45
  497. package/dist/__tests__/adapters/ClaudeCodeAdapter.test.js.map +0 -1
  498. package/dist/__tests__/adapters/CodexAdapter.test.js.map +0 -1
  499. package/dist/__tests__/durable/CodexCliProbe.test.js.map +0 -1
  500. package/dist/__tests__/durable/CodexDurableAgentRepository.test.js.map +0 -1
  501. package/dist/__tests__/durable/CodexPrintAgent.integration.test.js.map +0 -1
  502. package/dist/__tests__/durable/CodexPrintAgentService.test.js.map +0 -1
  503. package/dist/__tests__/durable/CodexPrintRunner.test.js.map +0 -1
  504. package/dist/__tests__/print/ClaudeCliProbe.test.js.map +0 -1
  505. package/dist/__tests__/print/ClaudePrintAgent.integration.test.js.map +0 -1
  506. package/dist/__tests__/print/ClaudePrintAgentService.test.js.map +0 -1
  507. package/dist/__tests__/print/ClaudePrintRunner.test.js.map +0 -1
  508. package/dist/__tests__/providers/claude/ClaudeAgentMapper.test.js.map +0 -1
  509. package/dist/__tests__/providers/codex/CodexSessionLocator.test.js +0 -194
  510. package/dist/__tests__/providers/codex/CodexSessionLocator.test.js.map +0 -1
  511. package/dist/__tests__/providers/gemini/GeminiCliAdapter.test.js.map +0 -1
  512. package/dist/__tests__/providers/pi/PiSessionParser.test.js.map +0 -1
  513. package/dist/__tests__/utils/ClaudeSessionParser.test.js.map +0 -1
  514. package/dist/adapters/index.d.ts +0 -10
  515. package/dist/adapters/index.d.ts.map +0 -1
  516. package/dist/adapters/index.js +0 -10
  517. package/dist/adapters/index.js.map +0 -1
  518. package/dist/providers/claude/ClaudeAgentMapper.js.map +0 -1
  519. package/dist/providers/claude/ClaudeCodeAdapter.d.ts.map +0 -1
  520. package/dist/providers/claude/ClaudeCodeAdapter.js.map +0 -1
  521. package/dist/providers/claude/ClaudeSessionLocator.js.map +0 -1
  522. package/dist/providers/claude/ClaudeSessionParser.d.ts.map +0 -1
  523. package/dist/providers/claude/ClaudeSessionParser.js.map +0 -1
  524. package/dist/providers/codex/CodexAdapter.d.ts.map +0 -1
  525. package/dist/providers/codex/CodexAdapter.js.map +0 -1
  526. package/dist/providers/codex/CodexAgentMapper.js.map +0 -1
  527. package/dist/providers/codex/CodexSessionLocator.d.ts +0 -44
  528. package/dist/providers/codex/CodexSessionLocator.d.ts.map +0 -1
  529. package/dist/providers/codex/CodexSessionLocator.js +0 -207
  530. package/dist/providers/codex/CodexSessionLocator.js.map +0 -1
  531. package/dist/providers/codex/CodexSessionMapping.js.map +0 -1
  532. package/dist/providers/codex/CodexSessionParser.d.ts +0 -58
  533. package/dist/providers/codex/CodexSessionParser.d.ts.map +0 -1
  534. package/dist/providers/codex/CodexSessionParser.js.map +0 -1
  535. package/dist/providers/copilot/CopilotAdapter.d.ts.map +0 -1
  536. package/dist/providers/copilot/CopilotAdapter.js.map +0 -1
  537. package/dist/providers/copilot/CopilotAgentMapper.js.map +0 -1
  538. package/dist/providers/copilot/CopilotSessionLocator.d.ts +0 -20
  539. package/dist/providers/copilot/CopilotSessionLocator.d.ts.map +0 -1
  540. package/dist/providers/copilot/CopilotSessionLocator.js +0 -49
  541. package/dist/providers/copilot/CopilotSessionLocator.js.map +0 -1
  542. package/dist/providers/copilot/CopilotSessionParser.d.ts +0 -30
  543. package/dist/providers/copilot/CopilotSessionParser.d.ts.map +0 -1
  544. package/dist/providers/copilot/CopilotSessionParser.js +0 -181
  545. package/dist/providers/copilot/CopilotSessionParser.js.map +0 -1
  546. package/dist/providers/gemini/GeminiAgentMapper.js.map +0 -1
  547. package/dist/providers/gemini/GeminiCliAdapter.d.ts.map +0 -1
  548. package/dist/providers/gemini/GeminiCliAdapter.js.map +0 -1
  549. package/dist/providers/gemini/GeminiSessionLocator.d.ts +0 -30
  550. package/dist/providers/gemini/GeminiSessionLocator.d.ts.map +0 -1
  551. package/dist/providers/gemini/GeminiSessionLocator.js +0 -142
  552. package/dist/providers/gemini/GeminiSessionLocator.js.map +0 -1
  553. package/dist/providers/gemini/GeminiSessionParser.d.ts.map +0 -1
  554. package/dist/providers/gemini/GeminiSessionParser.js +0 -166
  555. package/dist/providers/gemini/GeminiSessionParser.js.map +0 -1
  556. package/dist/providers/grok/GrokAgentMapper.js.map +0 -1
  557. package/dist/providers/grok/GrokCliAdapter.d.ts.map +0 -1
  558. package/dist/providers/grok/GrokCliAdapter.js.map +0 -1
  559. package/dist/providers/grok/GrokSessionLocator.js.map +0 -1
  560. package/dist/providers/grok/GrokSessionParser.d.ts +0 -54
  561. package/dist/providers/grok/GrokSessionParser.d.ts.map +0 -1
  562. package/dist/providers/grok/GrokSessionParser.js +0 -122
  563. package/dist/providers/grok/GrokSessionParser.js.map +0 -1
  564. package/dist/providers/opencode/OpenCodeAdapter.d.ts.map +0 -1
  565. package/dist/providers/opencode/OpenCodeAdapter.js.map +0 -1
  566. package/dist/providers/opencode/OpenCodeAgentMapper.js.map +0 -1
  567. package/dist/providers/opencode/OpenCodeSessionLocator.js.map +0 -1
  568. package/dist/providers/opencode/OpenCodeSessionParser.d.ts.map +0 -1
  569. package/dist/providers/opencode/OpenCodeSessionParser.js.map +0 -1
  570. package/dist/providers/pi/PiAdapter.d.ts.map +0 -1
  571. package/dist/providers/pi/PiAdapter.js.map +0 -1
  572. package/dist/providers/pi/PiAgentMapper.js.map +0 -1
  573. package/dist/providers/pi/PiSessionLocator.d.ts +0 -24
  574. package/dist/providers/pi/PiSessionLocator.d.ts.map +0 -1
  575. package/dist/providers/pi/PiSessionLocator.js +0 -86
  576. package/dist/providers/pi/PiSessionLocator.js.map +0 -1
  577. package/dist/providers/pi/PiSessionParser.d.ts +0 -36
  578. package/dist/providers/pi/PiSessionParser.d.ts.map +0 -1
  579. package/dist/providers/pi/PiSessionParser.js +0 -191
  580. package/dist/providers/pi/PiSessionParser.js.map +0 -1
  581. package/dist/providers/pi/PiSessionTracker.js.map +0 -1
  582. package/src/__tests__/fixtures/fake-claude.cjs +0 -31
  583. package/src/__tests__/fixtures/fake-codex.cjs +0 -56
  584. package/src/__tests__/providers/codex/CodexSessionLocator.test.ts +0 -182
  585. package/src/adapters/index.ts +0 -15
  586. package/src/providers/codex/CodexSessionLocator.ts +0 -279
  587. package/src/providers/copilot/CopilotSessionLocator.ts +0 -63
  588. package/src/providers/copilot/CopilotSessionParser.ts +0 -289
  589. package/src/providers/gemini/GeminiSessionLocator.ts +0 -183
  590. package/src/providers/grok/GrokSessionParser.ts +0 -166
  591. package/src/providers/pi/PiSessionLocator.ts +0 -110
  592. package/src/providers/pi/PiSessionParser.ts +0 -284
  593. /package/dist/__tests__/{providers → harnesses}/pi/durable/PiCliProbe.test.js +0 -0
  594. /package/dist/__tests__/{providers → harnesses}/pi/durable/PiDurableAgentRepository.test.js +0 -0
  595. /package/dist/__tests__/{providers → harnesses}/pi/durable/PiPrintAgentService.test.js +0 -0
  596. /package/dist/__tests__/{providers → harnesses}/pi/durable/PiPrintRunner.test.js +0 -0
  597. /package/dist/{providers → harnesses}/claude/ClaudeAgentMapper.d.ts +0 -0
  598. /package/dist/{providers → harnesses}/claude/ClaudeSessionLocator.d.ts +0 -0
  599. /package/dist/{providers → harnesses}/claude/durable/ClaudeCliProbe.d.ts +0 -0
  600. /package/dist/{providers → harnesses}/claude/durable/ClaudeCliProbe.js +0 -0
  601. /package/dist/{providers → harnesses}/claude/durable/ClaudePrintAgentService.d.ts +0 -0
  602. /package/dist/{providers → harnesses}/claude/durable/ClaudePrintAgentService.js +0 -0
  603. /package/dist/{providers → harnesses}/claude/durable/ClaudePrintRunner.d.ts +0 -0
  604. /package/dist/{providers → harnesses}/claude/durable/ClaudePrintRunner.js +0 -0
  605. /package/dist/{providers → harnesses}/claude/durable/ClaudeStreamParser.d.ts +0 -0
  606. /package/dist/{providers → harnesses}/claude/durable/ClaudeStreamParser.js +0 -0
  607. /package/dist/{providers → harnesses}/codex/CodexAgentMapper.d.ts +0 -0
  608. /package/dist/{providers → harnesses}/codex/CodexSessionMapping.d.ts +0 -0
  609. /package/dist/{providers → harnesses}/codex/durable/CodexCliProbe.d.ts +0 -0
  610. /package/dist/{providers → harnesses}/codex/durable/CodexCliProbe.js +0 -0
  611. /package/dist/{providers → harnesses}/codex/durable/CodexPrintAgentService.d.ts +0 -0
  612. /package/dist/{providers → harnesses}/codex/durable/CodexPrintAgentService.js +0 -0
  613. /package/dist/{providers → harnesses}/codex/durable/CodexPrintRunner.d.ts +0 -0
  614. /package/dist/{providers → harnesses}/codex/durable/CodexPrintRunner.js +0 -0
  615. /package/dist/{providers → harnesses}/codex/durable/CodexStreamParser.d.ts +0 -0
  616. /package/dist/{providers → harnesses}/codex/durable/CodexStreamParser.js +0 -0
  617. /package/dist/{providers → harnesses}/copilot/CopilotAgentMapper.d.ts +0 -0
  618. /package/dist/{providers → harnesses}/gemini/GeminiAgentMapper.d.ts +0 -0
  619. /package/dist/{providers → harnesses}/grok/GrokAgentMapper.d.ts +0 -0
  620. /package/dist/{providers → harnesses}/grok/GrokSessionLocator.d.ts +0 -0
  621. /package/dist/{providers → harnesses}/opencode/OpenCodeAgentMapper.d.ts +0 -0
  622. /package/dist/{providers → harnesses}/opencode/OpenCodeSessionLocator.d.ts +0 -0
  623. /package/dist/{providers → harnesses}/pi/PiAgentMapper.d.ts +0 -0
  624. /package/dist/{providers → harnesses}/pi/PiSessionTracker.d.ts +0 -0
  625. /package/dist/{providers → harnesses}/pi/durable/PiCliProbe.d.ts +0 -0
  626. /package/dist/{providers → harnesses}/pi/durable/PiCliProbe.js +0 -0
  627. /package/dist/{providers → harnesses}/pi/durable/PiPrintAgentService.d.ts +0 -0
  628. /package/dist/{providers → harnesses}/pi/durable/PiPrintAgentService.js +0 -0
  629. /package/dist/{providers → harnesses}/pi/durable/PiPrintProtocol.d.ts +0 -0
  630. /package/dist/{providers → harnesses}/pi/durable/PiPrintProtocol.js +0 -0
  631. /package/dist/{providers → harnesses}/pi/durable/PiPrintRunner.d.ts +0 -0
  632. /package/dist/{providers → harnesses}/pi/durable/PiPrintRunner.js +0 -0
  633. /package/dist/{providers → harnesses}/pi/durable/PiStreamParser.d.ts +0 -0
  634. /package/dist/{providers → harnesses}/pi/durable/PiStreamParser.js +0 -0
  635. /package/src/__tests__/{providers → harnesses}/pi/durable/PiCliProbe.test.ts +0 -0
  636. /package/src/__tests__/{providers → harnesses}/pi/durable/PiDurableAgentRepository.test.ts +0 -0
  637. /package/src/__tests__/{providers → harnesses}/pi/durable/PiPrintAgentService.test.ts +0 -0
  638. /package/src/__tests__/{providers → harnesses}/pi/durable/PiPrintRunner.test.ts +0 -0
  639. /package/src/{providers → harnesses}/claude/durable/ClaudeCliProbe.ts +0 -0
  640. /package/src/{providers → harnesses}/claude/durable/ClaudePrintAgentService.ts +0 -0
  641. /package/src/{providers → harnesses}/claude/durable/ClaudePrintRunner.ts +0 -0
  642. /package/src/{providers → harnesses}/claude/durable/ClaudeStreamParser.ts +0 -0
  643. /package/src/{providers → harnesses}/codex/durable/CodexCliProbe.ts +0 -0
  644. /package/src/{providers → harnesses}/codex/durable/CodexPrintAgentService.ts +0 -0
  645. /package/src/{providers → harnesses}/codex/durable/CodexPrintRunner.ts +0 -0
  646. /package/src/{providers → harnesses}/codex/durable/CodexStreamParser.ts +0 -0
  647. /package/src/{providers → harnesses}/pi/durable/PiCliProbe.ts +0 -0
  648. /package/src/{providers → harnesses}/pi/durable/PiPrintAgentService.ts +0 -0
  649. /package/src/{providers → harnesses}/pi/durable/PiPrintProtocol.ts +0 -0
  650. /package/src/{providers → harnesses}/pi/durable/PiPrintRunner.ts +0 -0
  651. /package/src/{providers → harnesses}/pi/durable/PiStreamParser.ts +0 -0
@@ -1,7 +1,19 @@
1
1
  import * as fs from "fs";
2
- import type { ConversationMessage, SessionSummary } from "../../adapters/AgentAdapter.js";
2
+ import type {
3
+ ConversationMessage,
4
+ ConversationOptions,
5
+ SessionSummary,
6
+ } from "../../adapters/AgentAdapter.js";
3
7
  import { AgentStatus } from "../../adapters/AgentAdapter.js";
8
+ import { JsonlTailReader, normalizeTail, type JsonlTailSource } from "../../utils/jsonlTail.js";
4
9
  import { safeReadFile, safeStat } from "../../utils/session.js";
10
+ import {
11
+ IncrementalJsonlSummary,
12
+ reduceJsonlContent,
13
+ type JsonlSummaryBounds,
14
+ type JsonlSummaryReducer,
15
+ } from "../../utils/IncrementalJsonlSummary.js";
16
+ import { isIdle, parseTimestamp, SUMMARY_MAX_LENGTH, truncate } from "../shared.js";
5
17
 
6
18
  export interface CodexEventEntry {
7
19
  timestamp?: string;
@@ -41,9 +53,43 @@ export interface CodexSession {
41
53
  lastPayloadType?: string;
42
54
  }
43
55
 
44
- const IDLE_THRESHOLD_MINUTES = 5;
56
+ /** O(1) running summary folded from session entries; `toSession` builds a `CodexSession`. */
57
+ interface CodexSummaryState {
58
+ seenFirstLine: boolean;
59
+ /** Set only when the first line is a valid `session_meta` entry. */
60
+ meta?: { id: string; cwd?: string; timestamp?: string };
61
+ lastEntryTimestamp?: string;
62
+ lastPayloadType?: string;
63
+ /** Truncated text of the last entry with displayable content. */
64
+ summary?: string;
65
+ }
66
+
67
+ /** A candidate conversation message plus what is needed to de-duplicate mirrors. */
68
+ interface CodexConversationItem {
69
+ entryType?: string;
70
+ mirrorKey: string | null;
71
+ message: ConversationMessage;
72
+ }
73
+
74
+ const MIRROR_OVERSCAN = 8;
75
+
76
+ export interface CodexSessionParserOptions {
77
+ /** Cold-start scan bounds for `readSessionIncremental` (see IncrementalJsonlSummary). */
78
+ summaryBounds?: JsonlSummaryBounds | false;
79
+ }
45
80
 
46
81
  export class CodexSessionParser {
82
+ /** Incremental reader backing `getConversation({ tail })`. */
83
+ private readonly tailReader = new JsonlTailReader();
84
+
85
+ private readonly sessionCache: IncrementalJsonlSummary<CodexSummaryState>;
86
+
87
+ constructor(options: CodexSessionParserOptions = {}) {
88
+ this.sessionCache = new IncrementalJsonlSummary(this.summaryReducer, {
89
+ bounds: options.summaryBounds,
90
+ });
91
+ }
92
+
47
93
  readSession(filePath: string, cachedContent?: string): CodexSession | null {
48
94
  let content: string;
49
95
  if (cachedContent !== undefined) {
@@ -56,53 +102,93 @@ export class CodexSessionParser {
56
102
  }
57
103
  }
58
104
 
59
- const allLines = content.trim().split("\n");
60
- if (!allLines[0]) return null;
105
+ return this.toSession(
106
+ reduceJsonlContent(this.summaryReducer, content),
107
+ () => fs.statSync(filePath).mtime,
108
+ );
109
+ }
61
110
 
62
- let metaEntry: CodexEventEntry;
63
- try {
64
- metaEntry = JSON.parse(allLines[0]);
65
- } catch {
66
- return null;
67
- }
111
+ /**
112
+ * Same result as `readSession`, but backed by a per-instance incremental
113
+ * cache so repeated refreshes only parse bytes appended since the last call.
114
+ * Call `pruneSessionCache()` once per refresh to evict files no longer read.
115
+ *
116
+ * The first read of a large transcript is a bounded head + tail scan (see
117
+ * `summaryReducer.skip`); fields whose entries lie only in the skipped
118
+ * middle fall back to their defaults instead of forcing a full parse.
119
+ */
120
+ readSessionIncremental(filePath: string): CodexSession | null {
121
+ const result = this.sessionCache.read(filePath);
122
+ return result ? this.toSession(result.state, () => result.mtime) : null;
123
+ }
68
124
 
69
- if (metaEntry.type !== "session_meta" || !metaEntry.payload?.id) {
70
- return null;
71
- }
125
+ /** Evict cached summaries for files not read since the previous prune. */
126
+ pruneSessionCache(): void {
127
+ this.sessionCache.prune();
128
+ }
72
129
 
73
- const entries: CodexEventEntry[] = [];
74
- for (const line of allLines) {
75
- try {
76
- entries.push(JSON.parse(line));
77
- } catch {
78
- continue;
130
+ /**
131
+ * Fold one JSONL entry into the O(1) session summary. The first line must
132
+ * be a `session_meta` entry; the rest track the last typed entry and the
133
+ * last entry with displayable text.
134
+ *
135
+ * `skip` (bounded cold start) keeps the head's `session_meta` and clears the
136
+ * "latest" fields, so those come from the tail only. Without a typed tail
137
+ * entry lastActive falls back to the meta timestamp, then the file mtime;
138
+ * without tail text the summary is the "Codex session active" default. A
139
+ * `session_meta` line longer than the head window yields no session (null).
140
+ */
141
+ private readonly summaryReducer: JsonlSummaryReducer<CodexSummaryState> = {
142
+ initial: () => ({ seenFirstLine: false }),
143
+ reduce: (state, value) => {
144
+ const entry = value && typeof value === "object" ? (value as CodexEventEntry) : undefined;
145
+ const next: CodexSummaryState = { ...state, seenFirstLine: true };
146
+
147
+ if (!state.seenFirstLine) {
148
+ if (entry?.type === "session_meta" && entry.payload?.id) {
149
+ next.meta = {
150
+ id: entry.payload.id,
151
+ cwd: entry.payload.cwd,
152
+ timestamp: entry.payload.timestamp,
153
+ };
154
+ }
155
+ }
156
+ // Without a leading session_meta the file is not a Codex session; skip the work
157
+ if (!entry || !next.meta) return next;
158
+
159
+ if (typeof entry.type === "string") {
160
+ next.lastEntryTimestamp = entry.timestamp;
161
+ next.lastPayloadType = this.normalizedPayloadType(entry);
79
162
  }
80
- }
81
163
 
82
- const lastEntry = this.findLastEventEntry(entries);
83
- const lastPayloadType = lastEntry ? this.normalizedPayloadType(lastEntry) : undefined;
164
+ const text = this.extractEntryText(entry);
165
+ if (text) next.summary = truncate(text, SUMMARY_MAX_LENGTH);
166
+
167
+ return next;
168
+ },
169
+ skip: (state) => ({ seenFirstLine: true, meta: state.meta }),
170
+ };
171
+
172
+ private toSession(state: CodexSummaryState, fileMtime: () => Date): CodexSession | null {
173
+ const meta = state.meta;
174
+ if (!meta) return null;
84
175
 
85
176
  const lastActive =
86
- this.parseTimestamp(lastEntry?.timestamp) ||
87
- this.parseTimestamp(metaEntry.payload.timestamp) ||
88
- fs.statSync(filePath).mtime;
89
- const sessionStart = this.parseTimestamp(metaEntry.payload.timestamp) || lastActive;
177
+ parseTimestamp(state.lastEntryTimestamp) || parseTimestamp(meta.timestamp) || fileMtime();
178
+ const sessionStart = parseTimestamp(meta.timestamp) || lastActive;
90
179
 
91
180
  return {
92
- sessionId: metaEntry.payload.id,
93
- projectPath: metaEntry.payload.cwd || "",
94
- summary: this.extractSummary(entries),
181
+ sessionId: meta.id,
182
+ projectPath: meta.cwd || "",
183
+ summary: state.summary ?? "Codex session active",
95
184
  sessionStart,
96
185
  lastActive,
97
- lastPayloadType,
186
+ lastPayloadType: state.lastPayloadType,
98
187
  };
99
188
  }
100
189
 
101
190
  determineStatus(session: CodexSession): AgentStatus {
102
- const diffMs = Date.now() - session.lastActive.getTime();
103
- const diffMinutes = diffMs / 60000;
104
-
105
- if (diffMinutes > IDLE_THRESHOLD_MINUTES) {
191
+ if (isIdle(session.lastActive)) {
106
192
  return AgentStatus.IDLE;
107
193
  }
108
194
 
@@ -117,45 +203,66 @@ export class CodexSessionParser {
117
203
  return AgentStatus.RUNNING;
118
204
  }
119
205
 
120
- getConversation(sessionFilePath: string, options?: { verbose?: boolean }): ConversationMessage[] {
206
+ getConversation(sessionFilePath: string, options?: ConversationOptions): ConversationMessage[] {
121
207
  const verbose = options?.verbose ?? false;
208
+ const source: JsonlTailSource<CodexConversationItem> = {
209
+ parseLine: (line) => this.lineToConversationItem(line, verbose),
210
+ finalize: (items) => this.dedupeMirroredMessages(items),
211
+ };
212
+
213
+ const tail = normalizeTail(options?.tail);
214
+ if (tail !== undefined) {
215
+ // Mirrored pairs sit next to each other, so a few extra messages of
216
+ // look-behind keep de-duplication exact for the returned tail.
217
+ return this.tailReader.read(sessionFilePath, tail, source, String(verbose), MIRROR_OVERSCAN);
218
+ }
122
219
 
123
220
  const content = safeReadFile(sessionFilePath);
124
221
  if (content === undefined) return [];
125
222
 
126
- const lines = content.trim().split("\n");
127
- const entries: CodexEventEntry[] = [];
128
- const messages: ConversationMessage[] = [];
129
-
130
- for (const line of lines) {
131
- try {
132
- entries.push(JSON.parse(line));
133
- } catch {
134
- continue;
135
- }
223
+ const items: CodexConversationItem[] = [];
224
+ for (const line of content.trim().split("\n")) {
225
+ const item = source.parseLine(line);
226
+ if (item) items.push(item);
136
227
  }
137
228
 
138
- const responseItemMirrorKeys = new Set<string>();
139
- for (const entry of entries) {
140
- if (entry.type !== "response_item") continue;
229
+ return this.dedupeMirroredMessages(items);
230
+ }
141
231
 
142
- const message = this.toConversationMessage(entry, verbose);
143
- const mirrorKey = message ? this.mirroredMessageKey(entry, message) : null;
144
- if (mirrorKey) responseItemMirrorKeys.add(mirrorKey);
232
+ private lineToConversationItem(line: string, verbose: boolean): CodexConversationItem | null {
233
+ let entry: CodexEventEntry;
234
+ try {
235
+ entry = JSON.parse(line);
236
+ } catch {
237
+ return null;
145
238
  }
146
239
 
147
- for (const entry of entries) {
148
- const message = this.toConversationMessage(entry, verbose);
149
- if (!message) continue;
240
+ const message = this.toConversationMessage(entry, verbose);
241
+ if (!message) return null;
150
242
 
151
- const mirrorKey = this.mirroredMessageKey(entry, message);
152
- if (entry.type === "event_msg" && mirrorKey && responseItemMirrorKeys.has(mirrorKey)) {
153
- continue;
154
- }
243
+ return { entryType: entry.type, mirrorKey: this.mirroredMessageKey(entry, message), message };
244
+ }
155
245
 
156
- messages.push(message);
246
+ /** Drop event_msg messages mirrored by a response_item with the same turn/role/content. */
247
+ private dedupeMirroredMessages(items: CodexConversationItem[]): ConversationMessage[] {
248
+ const responseItemMirrorKeys = new Set<string>();
249
+ for (const item of items) {
250
+ if (item.entryType === "response_item" && item.mirrorKey) {
251
+ responseItemMirrorKeys.add(item.mirrorKey);
252
+ }
157
253
  }
158
254
 
255
+ const messages: ConversationMessage[] = [];
256
+ for (const item of items) {
257
+ if (
258
+ item.entryType === "event_msg" &&
259
+ item.mirrorKey &&
260
+ responseItemMirrorKeys.has(item.mirrorKey)
261
+ ) {
262
+ continue;
263
+ }
264
+ messages.push(item.message);
265
+ }
159
266
  return messages;
160
267
  }
161
268
 
@@ -188,7 +295,7 @@ export class CodexSessionParser {
188
295
  continue;
189
296
  }
190
297
 
191
- const ts = this.parseTimestamp(entry.timestamp);
298
+ const ts = parseTimestamp(entry.timestamp);
192
299
  if (ts) lastTimestamp = ts;
193
300
 
194
301
  if (!firstUserMessage) {
@@ -207,7 +314,7 @@ export class CodexSessionParser {
207
314
  const stat = safeStat(filePath);
208
315
 
209
316
  const startedAt =
210
- this.parseTimestamp(metaEntry.payload.timestamp) ||
317
+ parseTimestamp(metaEntry.payload.timestamp) ||
211
318
  lastTimestamp ||
212
319
  stat?.birthtime ||
213
320
  stat?.mtime ||
@@ -225,41 +332,16 @@ export class CodexSessionParser {
225
332
  };
226
333
  }
227
334
 
228
- parseTimestamp(value?: string): Date | null {
229
- if (!value) return null;
230
- const timestamp = new Date(value);
231
- return Number.isNaN(timestamp.getTime()) ? null : timestamp;
232
- }
233
-
234
335
  parseMetaTimestampMs(value?: string): number | null {
235
336
  if (typeof value !== "string") return null;
236
337
 
237
- const timestamp = this.parseTimestamp(value);
338
+ const timestamp = parseTimestamp(value);
238
339
  if (!timestamp) return null;
239
340
 
240
341
  const timestampMs = timestamp.getTime();
241
342
  return Number.isFinite(timestampMs) ? timestampMs : null;
242
343
  }
243
344
 
244
- private findLastEventEntry(entries: CodexEventEntry[]): CodexEventEntry | undefined {
245
- for (let i = entries.length - 1; i >= 0; i--) {
246
- const entry = entries[i];
247
- if (entry && typeof entry.type === "string") {
248
- return entry;
249
- }
250
- }
251
- return undefined;
252
- }
253
-
254
- private extractSummary(entries: CodexEventEntry[]): string {
255
- for (let i = entries.length - 1; i >= 0; i--) {
256
- const message = this.extractEntryText(entries[i]);
257
- if (message) return this.truncate(message, 120);
258
- }
259
-
260
- return "Codex session active";
261
- }
262
-
263
345
  private normalizedPayloadType(entry: CodexEventEntry): string | undefined {
264
346
  const payloadType = entry.payload?.type;
265
347
 
@@ -291,11 +373,6 @@ export class CodexSessionParser {
291
373
  return conversationMessage?.content.trim() ?? "";
292
374
  }
293
375
 
294
- private truncate(value: string, maxLength: number): string {
295
- if (value.length <= maxLength) return value;
296
- return `${value.slice(0, maxLength - 3)}...`;
297
- }
298
-
299
376
  private toConversationMessage(
300
377
  entry: CodexEventEntry,
301
378
  verbose: boolean,
@@ -5,7 +5,10 @@
5
5
  * 1. Filtering Copilot processes from a shared asynchronous process snapshot
6
6
  * 2. Using snapshot CWD and start-time enrichment
7
7
  * 3. Mapping active ~/.copilot/session-state/{sessionId}/inuse.{pid}.lock files to processes
8
- * 4. Reading events.jsonl as the primary session/conversation source
8
+ * (only directories modified since the process started are listed, and a
9
+ * known lock is re-validated with one stat on later refreshes)
10
+ * 4. Reading events.jsonl as the primary session/conversation source (incrementally
11
+ * cached across refreshes, so unchanged files are not re-read)
9
12
  * 5. Reading workspace.yaml as a flat fallback metadata source
10
13
  */
11
14
 
@@ -14,22 +17,18 @@ import type {
14
17
  AgentAdapter,
15
18
  AgentInfo,
16
19
  ConversationMessage,
20
+ ConversationOptions,
17
21
  ListSessionsOptions,
18
22
  ProcessInfo,
19
23
  SessionSummary,
20
24
  AgentDetectionContext,
21
25
  } from "../../adapters/AgentAdapter.js";
22
- import {
23
- captureProcessSnapshot,
24
- executableBasename,
25
- filterByProcessNames,
26
- findWrapperProcess,
27
- findWrapperProcessPids,
28
- } from "../../utils/process.js";
26
+ import { findWrapperProcess, findWrapperProcessPids } from "../../utils/process.js";
29
27
  import { AgentRegistry, type RegistryEntry } from "../../utils/AgentRegistry.js";
30
28
  import { CopilotAgentMapper } from "./CopilotAgentMapper.js";
31
29
  import { CopilotSessionLocator } from "./CopilotSessionLocator.js";
32
30
  import { CopilotSessionParser, type CopilotSession } from "./CopilotSessionParser.js";
31
+ import { findHarnessProcesses, homeDir, matchesExecutable } from "../shared.js";
33
32
 
34
33
  export interface CopilotAdapterOptions {
35
34
  sessionStateDir?: string;
@@ -48,23 +47,29 @@ export class CopilotAdapter implements AgentAdapter {
48
47
  registry: AgentRegistry = AgentRegistry.default(),
49
48
  options: CopilotAdapterOptions = {},
50
49
  ) {
51
- const homeDir = process.env.HOME || process.env.USERPROFILE || "";
52
50
  this.registry = registry;
53
51
  this.parser = new CopilotSessionParser();
54
52
  this.mapper = new CopilotAgentMapper(this.parser);
55
53
  this.locator = new CopilotSessionLocator({
56
- sessionStateDir: options.sessionStateDir ?? path.join(homeDir, ".copilot", "session-state"),
54
+ sessionStateDir: options.sessionStateDir ?? path.join(homeDir(), ".copilot", "session-state"),
57
55
  });
58
56
  }
59
57
 
60
58
  canHandle(processInfo: ProcessInfo): boolean {
61
- return this.isCopilotExecutable(processInfo.command);
59
+ return matchesExecutable(processInfo.command, "copilot");
62
60
  }
63
61
 
64
62
  async detectAgents(context?: AgentDetectionContext): Promise<AgentInfo[]> {
65
- const snapshot = context?.processes ?? (await captureProcessSnapshot(this.processNames));
66
- const relevant = filterByProcessNames(snapshot, this.processNames);
67
- const processes = relevant.filter((process) => this.canHandle(process));
63
+ try {
64
+ return await this.detectRunningAgents(context);
65
+ } finally {
66
+ // Drop cached event summaries for sessions that were not part of this refresh
67
+ this.parser.pruneSessionCache();
68
+ }
69
+ }
70
+
71
+ private async detectRunningAgents(context?: AgentDetectionContext): Promise<AgentInfo[]> {
72
+ const { processes } = await findHarnessProcesses(this, context);
68
73
  if (processes.length === 0) return [];
69
74
 
70
75
  const processByPid = new Map(processes.map((proc) => [proc.pid, proc]));
@@ -73,11 +78,11 @@ export class CopilotAdapter implements AgentAdapter {
73
78
  const matchedProcesses: ProcessInfo[] = [];
74
79
  const agents: AgentInfo[] = [];
75
80
 
76
- for (const lock of this.locator.discoverActiveLocks()) {
81
+ for (const lock of this.locator.discoverActiveLocks(processes)) {
77
82
  const proc = processByPid.get(lock.pid);
78
83
  if (!proc) continue;
79
84
 
80
- const session = this.parser.readSessionDir(lock.sessionDir, lock.sessionId);
85
+ const session = this.parser.readSessionDirIncremental(lock.sessionDir, lock.sessionId);
81
86
  if (!session) continue;
82
87
 
83
88
  const agent = this.mapper.mapSessionToAgent(session, proc);
@@ -99,7 +104,7 @@ export class CopilotAdapter implements AgentAdapter {
99
104
  return agents;
100
105
  }
101
106
 
102
- getConversation(sessionFilePath: string, options?: { verbose?: boolean }): ConversationMessage[] {
107
+ getConversation(sessionFilePath: string, options?: ConversationOptions): ConversationMessage[] {
103
108
  return this.parser.getConversation(sessionFilePath, options);
104
109
  }
105
110
 
@@ -153,9 +158,4 @@ export class CopilotAdapter implements AgentAdapter {
153
158
  agent.name = wrapperEntry.name;
154
159
  }
155
160
  }
156
-
157
- private isCopilotExecutable(command: string): boolean {
158
- const base = executableBasename(command);
159
- return base === "copilot" || base === "copilot.exe";
160
- }
161
161
  }
@@ -1,7 +1,7 @@
1
1
  import type { AgentInfo, ProcessInfo } from "../../adapters/AgentAdapter.js";
2
- import { AgentStatus } from "../../adapters/AgentAdapter.js";
3
2
  import { generateAgentName } from "../../utils/matching.js";
4
3
  import { CopilotSessionParser, type CopilotSession } from "./CopilotSessionParser.js";
4
+ import { processOnlyAgent } from "../shared.js";
5
5
 
6
6
  export class CopilotAgentMapper {
7
7
  constructor(private readonly parser: CopilotSessionParser = new CopilotSessionParser()) {}
@@ -22,15 +22,6 @@ export class CopilotAgentMapper {
22
22
  }
23
23
 
24
24
  mapProcessOnlyAgent(processInfo: ProcessInfo): AgentInfo {
25
- return {
26
- name: generateAgentName(processInfo.cwd || "", processInfo.pid),
27
- type: "copilot",
28
- status: AgentStatus.RUNNING,
29
- summary: "Copilot process running",
30
- pid: processInfo.pid,
31
- projectPath: processInfo.cwd || "",
32
- sessionId: `pid-${processInfo.pid}`,
33
- lastActive: new Date(),
34
- };
25
+ return processOnlyAgent("copilot", processInfo, { summary: "Copilot process running" });
35
26
  }
36
27
  }
@@ -0,0 +1,161 @@
1
+ import * as path from "path";
2
+ import { isDirectory, isSafePathSegment, safeReaddir, safeStat } from "../../utils/session.js";
3
+ import { homeDir } from "../shared.js";
4
+
5
+ export interface CopilotLock {
6
+ sessionDir: string;
7
+ sessionId: string;
8
+ pid: number;
9
+ }
10
+
11
+ export interface CopilotSessionDir {
12
+ sessionDir: string;
13
+ sessionId: string;
14
+ }
15
+
16
+ /** A live Copilot process whose `inuse.<pid>.lock` file should be located. */
17
+ export interface CopilotLockProcess {
18
+ pid: number;
19
+ startTime?: Date;
20
+ }
21
+
22
+ export interface CopilotSessionLocatorOptions {
23
+ sessionStateDir?: string;
24
+ }
25
+
26
+ interface KnownLock extends CopilotSessionDir {
27
+ startTimeMs: number;
28
+ }
29
+
30
+ /**
31
+ * Tolerance between a reported process start time and its lock directory's
32
+ * mtime: `ps lstart` has 1 s resolution, Linux start times derive from an
33
+ * estimated boot time, and some filesystems store coarse mtimes.
34
+ */
35
+ const START_TIME_SLACK_MS = 5 * 60 * 1000;
36
+
37
+ const LOCK_FILE_PATTERN = /^inuse\.(\d+)\.lock$/;
38
+
39
+ export class CopilotSessionLocator {
40
+ private readonly sessionStateDir: string;
41
+ /** Lock location per PID, trusted only while that PID's start time is unchanged. */
42
+ private readonly knownLocks = new Map<number, KnownLock>();
43
+
44
+ constructor(options: CopilotSessionLocatorOptions = {}) {
45
+ this.sessionStateDir =
46
+ options.sessionStateDir ?? path.join(homeDir(), ".copilot", "session-state");
47
+ }
48
+
49
+ listSessionDirs(): CopilotSessionDir[] {
50
+ if (!isDirectory(this.sessionStateDir)) return [];
51
+
52
+ const sessionDirs: CopilotSessionDir[] = [];
53
+ for (const sessionId of safeReaddir(this.sessionStateDir)) {
54
+ const sessionDir = path.join(this.sessionStateDir, sessionId);
55
+ if (!isDirectory(sessionDir)) continue;
56
+
57
+ sessionDirs.push({ sessionDir, sessionId });
58
+ }
59
+
60
+ return sessionDirs;
61
+ }
62
+
63
+ findSessionDirById(sessionId: string): CopilotSessionDir | null {
64
+ if (!isSafePathSegment(sessionId)) return null;
65
+ const sessionDir = path.join(this.sessionStateDir, sessionId);
66
+ return isDirectory(sessionDir) ? { sessionDir, sessionId } : null;
67
+ }
68
+
69
+ /**
70
+ * Find `inuse.<pid>.lock` files.
71
+ *
72
+ * Without `processes`, every session directory is scanned and all locks are
73
+ * returned. With `processes`, only locks of those PIDs are returned and the
74
+ * search is bounded:
75
+ * - a lock found earlier for the same (pid, startTime) is re-validated with
76
+ * a single `stat` (a reused PID has a different start time and misses);
77
+ * - otherwise only session directories whose mtime is at or after the
78
+ * earliest unresolved process start time (minus slack) are listed, since
79
+ * creating the lock file bumps its directory's mtime;
80
+ * - if an unresolved process has no start time, every directory is listed.
81
+ */
82
+ discoverActiveLocks(processes?: readonly CopilotLockProcess[]): CopilotLock[] {
83
+ if (!processes) {
84
+ return this.scanLocks(undefined, () => true);
85
+ }
86
+
87
+ const startTimes = new Map(processes.map((proc) => [proc.pid, proc.startTime?.getTime()]));
88
+ for (const [pid, known] of this.knownLocks) {
89
+ if (startTimes.get(pid) !== known.startTimeMs) {
90
+ this.knownLocks.delete(pid);
91
+ }
92
+ }
93
+
94
+ const locks: CopilotLock[] = [];
95
+ const unresolved = new Set<number>();
96
+ for (const pid of startTimes.keys()) {
97
+ const known = this.knownLocks.get(pid);
98
+ if (known && safeStat(path.join(known.sessionDir, lockFileName(pid)))?.isFile()) {
99
+ locks.push({ sessionDir: known.sessionDir, sessionId: known.sessionId, pid });
100
+ continue;
101
+ }
102
+ this.knownLocks.delete(pid);
103
+ unresolved.add(pid);
104
+ }
105
+ if (unresolved.size === 0) return locks;
106
+
107
+ const unresolvedStarts = [...unresolved].map((pid) => startTimes.get(pid));
108
+ const minMtimeMs = unresolvedStarts.every((start): start is number => start !== undefined)
109
+ ? Math.min(...unresolvedStarts) - START_TIME_SLACK_MS
110
+ : undefined;
111
+
112
+ const found = this.scanLocks(minMtimeMs, (pid) => unresolved.has(pid));
113
+
114
+ const lockCounts = new Map<number, number>();
115
+ for (const lock of found) {
116
+ lockCounts.set(lock.pid, (lockCounts.get(lock.pid) ?? 0) + 1);
117
+ }
118
+ for (const lock of found) {
119
+ const startTimeMs = startTimes.get(lock.pid);
120
+ // Only remember unambiguous locks of processes with a known start time
121
+ if (startTimeMs !== undefined && lockCounts.get(lock.pid) === 1) {
122
+ this.knownLocks.set(lock.pid, {
123
+ sessionDir: lock.sessionDir,
124
+ sessionId: lock.sessionId,
125
+ startTimeMs,
126
+ });
127
+ }
128
+ }
129
+
130
+ return locks.concat(found);
131
+ }
132
+
133
+ /** List lock files in session directories with mtime >= `minMtimeMs` (all when undefined). */
134
+ private scanLocks(
135
+ minMtimeMs: number | undefined,
136
+ includePid: (pid: number) => boolean,
137
+ ): CopilotLock[] {
138
+ const locks: CopilotLock[] = [];
139
+ for (const sessionId of safeReaddir(this.sessionStateDir)) {
140
+ const sessionDir = path.join(this.sessionStateDir, sessionId);
141
+ const stat = safeStat(sessionDir);
142
+ if (!stat?.isDirectory()) continue;
143
+ if (minMtimeMs !== undefined && stat.mtimeMs < minMtimeMs) continue;
144
+
145
+ for (const entry of safeReaddir(sessionDir)) {
146
+ const match = entry.match(LOCK_FILE_PATTERN);
147
+ if (!match) continue;
148
+
149
+ const pid = Number.parseInt(match[1], 10);
150
+ if (!Number.isFinite(pid) || !includePid(pid)) continue;
151
+ locks.push({ sessionDir, sessionId, pid });
152
+ }
153
+ }
154
+
155
+ return locks;
156
+ }
157
+ }
158
+
159
+ function lockFileName(pid: number): string {
160
+ return `inuse.${pid}.lock`;
161
+ }