@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
@@ -0,0 +1,74 @@
1
+ import type { ProcessInfo } from "../../adapters/AgentAdapter.js";
2
+ import { type MatchResult } from "../../utils/matching.js";
3
+ import { type SessionFile } from "../../utils/session.js";
4
+ import { CodexSessionParser } from "./CodexSessionParser.js";
5
+ export interface CodexDirectMatch {
6
+ process: ProcessInfo;
7
+ sessionFile: SessionFile;
8
+ }
9
+ export interface CodexProcessSessionMatches {
10
+ direct: CodexDirectMatch[];
11
+ legacyMatches: MatchResult[];
12
+ fallback: ProcessInfo[];
13
+ }
14
+ export interface CodexDiscoveredSessions {
15
+ sessions: SessionFile[];
16
+ }
17
+ export interface CodexSessionLocatorOptions {
18
+ sessionsDir?: string;
19
+ /** Clock used for negative-cache re-checks. Defaults to `Date.now`. */
20
+ now?: () => number;
21
+ }
22
+ /** Upper bound of bytes read from a session file to find its `session_meta` line. */
23
+ export declare const SESSION_META_HEAD_MAX_BYTES: number;
24
+ /** Unmatched processes are re-scanned at least this often, even when their date dirs are unchanged. */
25
+ export declare const UNMATCHED_PROCESS_RECHECK_MS = 30000;
26
+ export declare class CodexSessionLocator {
27
+ private readonly parser;
28
+ private readonly sessionsDir;
29
+ private readonly now;
30
+ /** `session_meta` is written once at the head of an append-only file, so it is cached by path + inode. */
31
+ private readonly sessionMetaCache;
32
+ /** `(pid, startTime)` of processes that matched no session, keyed to their date-dir mtimes. */
33
+ private readonly unmatchedProcesses;
34
+ constructor(options?: CodexSessionLocatorOptions, parser?: CodexSessionParser);
35
+ matchRunningProcesses(processes: ProcessInfo[]): CodexProcessSessionMatches;
36
+ tryResumeMatching(processes: ProcessInfo[]): {
37
+ direct: CodexDirectMatch[];
38
+ fallback: ProcessInfo[];
39
+ };
40
+ discoverLiveSessions(processes: ProcessInfo[]): CodexDiscoveredSessions;
41
+ discoverSessionFilesInDateDirs(dateDirs: string[]): CodexDiscoveredSessions;
42
+ discoverHistoricalSessionFiles(): string[];
43
+ findSessionFileById(sessionId: string): SessionFile | null;
44
+ collectAllSessionFiles(): string[];
45
+ private extractResumeSessionId;
46
+ private getCandidateSessionFiles;
47
+ /**
48
+ * Read `session_meta` from at most {@link SESSION_META_HEAD_MAX_BYTES} of the
49
+ * file head. Cached per path while the inode is unchanged and the file has
50
+ * not shrunk below the parsed head, so growing session files are not re-read.
51
+ */
52
+ private readSessionMeta;
53
+ private isSessionMetaCacheValid;
54
+ private parseSessionMetaHead;
55
+ /**
56
+ * Best-effort extraction for a `session_meta` line longer than the head limit
57
+ * (e.g. large embedded instructions). `id`, `timestamp` and `cwd` precede the
58
+ * bulky payload fields, so they are read from the payload prefix.
59
+ */
60
+ private parseTruncatedSessionMeta;
61
+ private pruneSessionMetaCache;
62
+ private isKnownUnmatched;
63
+ private updateUnmatchedProcesses;
64
+ private toProcessKey;
65
+ /** Day-window directories with their mtimes; changes when session files are added or removed. */
66
+ private getDateDirSignature;
67
+ private getProcessDayKeys;
68
+ private getDateDirs;
69
+ private getDateDirsAroundDate;
70
+ private toSessionDayKey;
71
+ private tryParseUuidV7Date;
72
+ private collectSessionFilesInDateDirs;
73
+ }
74
+ //# sourceMappingURL=CodexSessionLocator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodexSessionLocator.d.ts","sourceRoot":"","sources":["../../../src/harnesses/codex/CodexSessionLocator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAA4B,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAKL,KAAK,WAAW,EACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,kBAAkB,EAAwB,MAAM,yBAAyB,CAAC;AAGnF,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,WAAW,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,aAAa,EAAE,WAAW,EAAE,CAAC;IAC7B,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,0BAA0B;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAGD,qFAAqF;AACrF,eAAO,MAAM,2BAA2B,QAAY,CAAC;AAErD,uGAAuG;AACvG,eAAO,MAAM,4BAA4B,QAAS,CAAC;AAiCnD,qBAAa,mBAAmB;IAU5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IATzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,0GAA0G;IAC1G,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA4C;IAC7E,+FAA+F;IAC/F,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA4C;gBAG7E,OAAO,GAAE,0BAA+B,EACvB,MAAM,GAAE,kBAA6C;IAMxE,qBAAqB,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,0BAA0B;IAqB3E,iBAAiB,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG;QAC3C,MAAM,EAAE,gBAAgB,EAAE,CAAC;QAC3B,QAAQ,EAAE,WAAW,EAAE,CAAC;KACzB;IAuBD,oBAAoB,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,uBAAuB;IAWvE,8BAA8B,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,uBAAuB;IAiB3E,8BAA8B,IAAI,MAAM,EAAE;IAI1C,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAsB1D,sBAAsB,IAAI,MAAM,EAAE;IA0BlC,OAAO,CAAC,sBAAsB;IAK9B,OAAO,CAAC,wBAAwB;IAShC;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,uBAAuB;IAK/B,OAAO,CAAC,oBAAoB;IAiB5B;;;;OAIG;IACH,OAAO,CAAC,yBAAyB;IAcjC,OAAO,CAAC,qBAAqB;IAU7B,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,wBAAwB;IA0BhC,OAAO,CAAC,YAAY;IAIpB,iGAAiG;IACjG,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,WAAW;IAwBnB,OAAO,CAAC,qBAAqB;IAe7B,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,6BAA6B;CAYtC"}
@@ -0,0 +1,359 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import { matchProcessesToSessions } from "../../utils/matching.js";
4
+ import { batchGetSessionFileBirthtimes, isDirectory, safeReaddir, safeStat } from "../../utils/session.js";
5
+ import { CodexSessionParser } from "./CodexSessionParser.js";
6
+ import { homeDir } from "../shared.js";
7
+ const PROCESS_START_DAY_WINDOW_DAYS = 1;
8
+ /** Upper bound of bytes read from a session file to find its `session_meta` line. */ export const SESSION_META_HEAD_MAX_BYTES = 64 * 1024;
9
+ const SESSION_META_HEAD_CHUNK_BYTES = 16 * 1024;
10
+ /** Unmatched processes are re-scanned at least this often, even when their date dirs are unchanged. */ export const UNMATCHED_PROCESS_RECHECK_MS = 30_000;
11
+ export class CodexSessionLocator {
12
+ parser;
13
+ sessionsDir;
14
+ now;
15
+ /** `session_meta` is written once at the head of an append-only file, so it is cached by path + inode. */ sessionMetaCache = new Map();
16
+ /** `(pid, startTime)` of processes that matched no session, keyed to their date-dir mtimes. */ unmatchedProcesses = new Map();
17
+ constructor(options = {}, parser = new CodexSessionParser()){
18
+ this.parser = parser;
19
+ this.sessionsDir = options.sessionsDir ?? path.join(homeDir(), ".codex", "sessions");
20
+ this.now = options.now ?? Date.now;
21
+ }
22
+ matchRunningProcesses(processes) {
23
+ const { direct, fallback } = this.tryResumeMatching(processes);
24
+ const nowMs = this.now();
25
+ const signatures = new Map(fallback.map((proc)=>[
26
+ proc,
27
+ this.getDateDirSignature(proc)
28
+ ]));
29
+ const candidates = fallback.filter((proc)=>!this.isKnownUnmatched(proc, signatures.get(proc) ?? "", nowMs));
30
+ const { sessions } = this.discoverLiveSessions(candidates);
31
+ const legacyMatches = candidates.length > 0 && sessions.length > 0 ? matchProcessesToSessions(candidates, sessions) : [];
32
+ this.updateUnmatchedProcesses(fallback, candidates, legacyMatches, signatures, nowMs);
33
+ return {
34
+ direct,
35
+ legacyMatches,
36
+ fallback
37
+ };
38
+ }
39
+ tryResumeMatching(processes) {
40
+ const direct = [];
41
+ const fallback = [];
42
+ for (const proc of processes){
43
+ const sessionId = this.extractResumeSessionId(proc.command);
44
+ if (!sessionId) {
45
+ fallback.push(proc);
46
+ continue;
47
+ }
48
+ const sessionFile = this.findSessionFileById(sessionId);
49
+ if (!sessionFile) {
50
+ fallback.push(proc);
51
+ continue;
52
+ }
53
+ direct.push({
54
+ process: proc,
55
+ sessionFile
56
+ });
57
+ }
58
+ return {
59
+ direct,
60
+ fallback
61
+ };
62
+ }
63
+ discoverLiveSessions(processes) {
64
+ const empty = {
65
+ sessions: []
66
+ };
67
+ if (processes.length === 0) return empty;
68
+ if (!fs.existsSync(this.sessionsDir)) return empty;
69
+ const dateDirs = this.getDateDirs(processes);
70
+ if (dateDirs.length === 0) return empty;
71
+ return this.discoverSessionFilesInDateDirs(dateDirs);
72
+ }
73
+ discoverSessionFilesInDateDirs(dateDirs) {
74
+ const files = batchGetSessionFileBirthtimes(dateDirs);
75
+ this.pruneSessionMetaCache(dateDirs, files);
76
+ for (const file of files){
77
+ const meta = this.readSessionMeta(file.filePath);
78
+ if (!meta) continue;
79
+ file.resolvedCwd = meta.cwd;
80
+ if (meta.timestampMs !== null) {
81
+ file.birthtimeMs = meta.timestampMs;
82
+ }
83
+ }
84
+ return {
85
+ sessions: files
86
+ };
87
+ }
88
+ discoverHistoricalSessionFiles() {
89
+ return this.collectAllSessionFiles();
90
+ }
91
+ findSessionFileById(sessionId) {
92
+ for (const filePath of this.getCandidateSessionFiles(sessionId)){
93
+ if (!path.basename(filePath).includes(sessionId)) continue;
94
+ const meta = this.readSessionMeta(filePath);
95
+ if (!meta || meta.id !== sessionId) continue;
96
+ const stat = safeStat(filePath);
97
+ if (!stat) continue;
98
+ return {
99
+ sessionId,
100
+ filePath,
101
+ projectDir: path.dirname(filePath),
102
+ birthtimeMs: meta.timestampMs ?? stat.birthtimeMs,
103
+ resolvedCwd: meta.cwd
104
+ };
105
+ }
106
+ return null;
107
+ }
108
+ collectAllSessionFiles() {
109
+ const out = [];
110
+ for (const yearEntry of safeReaddir(this.sessionsDir)){
111
+ const yearDir = path.join(this.sessionsDir, yearEntry);
112
+ if (!isDirectory(yearDir)) continue;
113
+ for (const monthEntry of safeReaddir(yearDir)){
114
+ const monthDir = path.join(yearDir, monthEntry);
115
+ if (!isDirectory(monthDir)) continue;
116
+ for (const dayEntry of safeReaddir(monthDir)){
117
+ const dayDir = path.join(monthDir, dayEntry);
118
+ if (!isDirectory(dayDir)) continue;
119
+ for (const fileEntry of safeReaddir(dayDir)){
120
+ if (!fileEntry.endsWith(".jsonl")) continue;
121
+ out.push(path.join(dayDir, fileEntry));
122
+ }
123
+ }
124
+ }
125
+ }
126
+ return out;
127
+ }
128
+ extractResumeSessionId(command) {
129
+ const match = command.match(/(?:^|\s)resume\s+([0-9a-f-]{36})(?:\s|$)/i);
130
+ return match?.[1] ?? null;
131
+ }
132
+ getCandidateSessionFiles(sessionId) {
133
+ const sessionDate = this.tryParseUuidV7Date(sessionId);
134
+ if (!sessionDate) return this.collectAllSessionFiles();
135
+ return this.collectSessionFilesInDateDirs(this.getDateDirsAroundDate(sessionDate, PROCESS_START_DAY_WINDOW_DAYS));
136
+ }
137
+ /**
138
+ * Read `session_meta` from at most {@link SESSION_META_HEAD_MAX_BYTES} of the
139
+ * file head. Cached per path while the inode is unchanged and the file has
140
+ * not shrunk below the parsed head, so growing session files are not re-read.
141
+ */ readSessionMeta(filePath) {
142
+ const stat = safeStat(filePath);
143
+ if (!stat) return null;
144
+ const cached = this.sessionMetaCache.get(filePath);
145
+ if (cached && this.isSessionMetaCacheValid(cached, stat)) return cached.meta;
146
+ const head = readFileHead(filePath, SESSION_META_HEAD_MAX_BYTES);
147
+ if (!head) {
148
+ this.sessionMetaCache.delete(filePath);
149
+ return null;
150
+ }
151
+ const meta = this.parseSessionMetaHead(head);
152
+ this.sessionMetaCache.set(filePath, {
153
+ dev: stat.dev,
154
+ ino: stat.ino,
155
+ headBytes: head.bytes,
156
+ headFinal: head.complete || head.truncated,
157
+ meta
158
+ });
159
+ return meta;
160
+ }
161
+ isSessionMetaCacheValid(entry, stat) {
162
+ if (entry.dev !== stat.dev || entry.ino !== stat.ino) return false;
163
+ return entry.headFinal ? stat.size >= entry.headBytes : stat.size === entry.headBytes;
164
+ }
165
+ parseSessionMetaHead(head) {
166
+ const line = head.text.trim();
167
+ if (!line) return null;
168
+ try {
169
+ const parsed = JSON.parse(line);
170
+ if (parsed.type !== "session_meta") return null;
171
+ return {
172
+ id: parsed.payload?.id,
173
+ cwd: parsed.payload?.cwd || "",
174
+ timestampMs: this.parser.parseMetaTimestampMs(parsed.payload?.timestamp)
175
+ };
176
+ } catch {
177
+ return head.truncated ? this.parseTruncatedSessionMeta(line) : null;
178
+ }
179
+ }
180
+ /**
181
+ * Best-effort extraction for a `session_meta` line longer than the head limit
182
+ * (e.g. large embedded instructions). `id`, `timestamp` and `cwd` precede the
183
+ * bulky payload fields, so they are read from the payload prefix.
184
+ */ parseTruncatedSessionMeta(line) {
185
+ if (!/"type"\s*:\s*"session_meta"/.test(line)) return null;
186
+ const payloadStart = line.search(/"payload"\s*:\s*\{/);
187
+ if (payloadStart < 0) return null;
188
+ const payload = line.slice(payloadStart);
189
+ return {
190
+ id: extractJsonStringField(payload, "id"),
191
+ cwd: extractJsonStringField(payload, "cwd") || "",
192
+ timestampMs: this.parser.parseMetaTimestampMs(extractJsonStringField(payload, "timestamp"))
193
+ };
194
+ }
195
+ pruneSessionMetaCache(dateDirs, files) {
196
+ const scannedDirs = new Set(dateDirs);
197
+ const present = new Set(files.map((file)=>file.filePath));
198
+ for (const filePath of this.sessionMetaCache.keys()){
199
+ if (scannedDirs.has(path.dirname(filePath)) && !present.has(filePath)) {
200
+ this.sessionMetaCache.delete(filePath);
201
+ }
202
+ }
203
+ }
204
+ isKnownUnmatched(proc, dateDirSignature, nowMs) {
205
+ const entry = this.unmatchedProcesses.get(this.toProcessKey(proc));
206
+ if (!entry) return false;
207
+ if (nowMs - entry.checkedAtMs >= UNMATCHED_PROCESS_RECHECK_MS) return false;
208
+ return entry.dateDirSignature === dateDirSignature;
209
+ }
210
+ updateUnmatchedProcesses(fallback, scanned, legacyMatches, signatures, nowMs) {
211
+ const liveKeys = new Set(fallback.map((proc)=>this.toProcessKey(proc)));
212
+ for (const key of this.unmatchedProcesses.keys()){
213
+ if (!liveKeys.has(key)) this.unmatchedProcesses.delete(key);
214
+ }
215
+ const matchedPids = new Set(legacyMatches.map((match)=>match.process.pid));
216
+ for (const proc of scanned){
217
+ const key = this.toProcessKey(proc);
218
+ if (matchedPids.has(proc.pid)) {
219
+ this.unmatchedProcesses.delete(key);
220
+ } else {
221
+ this.unmatchedProcesses.set(key, {
222
+ checkedAtMs: nowMs,
223
+ dateDirSignature: signatures.get(proc) ?? ""
224
+ });
225
+ }
226
+ }
227
+ }
228
+ toProcessKey(proc) {
229
+ return `${proc.pid}:${proc.startTime?.getTime() ?? "unknown"}`;
230
+ }
231
+ /** Day-window directories with their mtimes; changes when session files are added or removed. */ getDateDirSignature(proc) {
232
+ return this.getProcessDayKeys(proc).map((dayKey)=>{
233
+ const stat = safeStat(path.join(this.sessionsDir, dayKey));
234
+ return `${dayKey}=${stat?.isDirectory() ? stat.mtimeMs : "-"}`;
235
+ }).join("|");
236
+ }
237
+ getProcessDayKeys(proc) {
238
+ const startTime = proc.startTime || new Date();
239
+ const dayKeys = [];
240
+ for(let offset = -PROCESS_START_DAY_WINDOW_DAYS; offset <= PROCESS_START_DAY_WINDOW_DAYS; offset++){
241
+ const day = new Date(startTime.getTime());
242
+ day.setDate(day.getDate() + offset);
243
+ dayKeys.push(this.toSessionDayKey(day));
244
+ }
245
+ return dayKeys;
246
+ }
247
+ getDateDirs(processes) {
248
+ const dayKeys = new Set();
249
+ for (const proc of processes){
250
+ for (const dayKey of this.getProcessDayKeys(proc)){
251
+ dayKeys.add(dayKey);
252
+ }
253
+ }
254
+ const dirs = [];
255
+ for (const dayKey of dayKeys){
256
+ const dayDir = path.join(this.sessionsDir, dayKey);
257
+ try {
258
+ if (fs.statSync(dayDir).isDirectory()) {
259
+ dirs.push(dayDir);
260
+ }
261
+ } catch {
262
+ continue;
263
+ }
264
+ }
265
+ return dirs;
266
+ }
267
+ getDateDirsAroundDate(date, windowDays) {
268
+ const dirs = [];
269
+ for(let offset = -windowDays; offset <= windowDays; offset++){
270
+ const day = new Date(date.getTime());
271
+ day.setDate(day.getDate() + offset);
272
+ const dayDir = path.join(this.sessionsDir, this.toSessionDayKey(day));
273
+ if (isDirectory(dayDir)) {
274
+ dirs.push(dayDir);
275
+ }
276
+ }
277
+ return dirs;
278
+ }
279
+ toSessionDayKey(date) {
280
+ const yyyy = String(date.getFullYear()).padStart(4, "0");
281
+ const mm = String(date.getMonth() + 1).padStart(2, "0");
282
+ const dd = String(date.getDate()).padStart(2, "0");
283
+ return path.join(yyyy, mm, dd);
284
+ }
285
+ tryParseUuidV7Date(sessionId) {
286
+ const match = sessionId.match(/^([0-9a-f]{8})-([0-9a-f]{4})-7[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$/i);
287
+ if (!match) return null;
288
+ const timestampMs = Number.parseInt(`${match[1]}${match[2]}`, 16);
289
+ if (!Number.isSafeInteger(timestampMs) || timestampMs <= 0) return null;
290
+ const date = new Date(timestampMs);
291
+ return Number.isNaN(date.getTime()) ? null : date;
292
+ }
293
+ collectSessionFilesInDateDirs(dateDirs) {
294
+ const out = [];
295
+ for (const dayDir of dateDirs){
296
+ for (const fileEntry of safeReaddir(dayDir)){
297
+ if (!fileEntry.endsWith(".jsonl")) continue;
298
+ out.push(path.join(dayDir, fileEntry));
299
+ }
300
+ }
301
+ return out;
302
+ }
303
+ }
304
+ /**
305
+ * Read the first line of a file, consuming at most `maxBytes`.
306
+ * Returns `null` when the file cannot be opened or read.
307
+ */ function readFileHead(filePath, maxBytes) {
308
+ let fd;
309
+ try {
310
+ fd = fs.openSync(filePath, "r");
311
+ } catch {
312
+ return null;
313
+ }
314
+ try {
315
+ const buffer = Buffer.alloc(maxBytes);
316
+ let total = 0;
317
+ while(total < maxBytes){
318
+ const length = Math.min(SESSION_META_HEAD_CHUNK_BYTES, maxBytes - total);
319
+ const read = fs.readSync(fd, buffer, total, length, total);
320
+ if (read <= 0) break;
321
+ const newlineIndex = buffer.indexOf(0x0a, total);
322
+ total += read;
323
+ if (newlineIndex >= 0 && newlineIndex < total) {
324
+ return {
325
+ text: buffer.toString("utf-8", 0, newlineIndex),
326
+ bytes: newlineIndex + 1,
327
+ complete: true,
328
+ truncated: false
329
+ };
330
+ }
331
+ }
332
+ return {
333
+ text: buffer.toString("utf-8", 0, total),
334
+ bytes: total,
335
+ complete: false,
336
+ truncated: total >= maxBytes
337
+ };
338
+ } catch {
339
+ return null;
340
+ } finally{
341
+ try {
342
+ fs.closeSync(fd);
343
+ } catch {
344
+ // Ignore close errors
345
+ }
346
+ }
347
+ }
348
+ /** Extract the first `"field": "<json string>"` value from a JSON fragment. */ function extractJsonStringField(fragment, field) {
349
+ const match = fragment.match(new RegExp(`"${field}"\\s*:\\s*("(?:[^"\\\\]|\\\\.)*")`));
350
+ if (!match) return undefined;
351
+ try {
352
+ const value = JSON.parse(match[1]);
353
+ return typeof value === "string" ? value : undefined;
354
+ } catch {
355
+ return undefined;
356
+ }
357
+ }
358
+
359
+ //# sourceMappingURL=CodexSessionLocator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/harnesses/codex/CodexSessionLocator.ts"],"sourcesContent":["import * as fs from \"fs\";\nimport * as path from \"path\";\nimport type { ProcessInfo } from \"../../adapters/AgentAdapter.js\";\nimport { matchProcessesToSessions, type MatchResult } from \"../../utils/matching.js\";\nimport {\n batchGetSessionFileBirthtimes,\n isDirectory,\n safeReaddir,\n safeStat,\n type SessionFile,\n} from \"../../utils/session.js\";\nimport { CodexSessionParser, type CodexEventEntry } from \"./CodexSessionParser.js\";\nimport { homeDir } from \"../shared.js\";\n\nexport interface CodexDirectMatch {\n process: ProcessInfo;\n sessionFile: SessionFile;\n}\n\nexport interface CodexProcessSessionMatches {\n direct: CodexDirectMatch[];\n legacyMatches: MatchResult[];\n fallback: ProcessInfo[];\n}\n\nexport interface CodexDiscoveredSessions {\n sessions: SessionFile[];\n}\n\nexport interface CodexSessionLocatorOptions {\n sessionsDir?: string;\n /** Clock used for negative-cache re-checks. Defaults to `Date.now`. */\n now?: () => number;\n}\n\nconst PROCESS_START_DAY_WINDOW_DAYS = 1;\n/** Upper bound of bytes read from a session file to find its `session_meta` line. */\nexport const SESSION_META_HEAD_MAX_BYTES = 64 * 1024;\nconst SESSION_META_HEAD_CHUNK_BYTES = 16 * 1024;\n/** Unmatched processes are re-scanned at least this often, even when their date dirs are unchanged. */\nexport const UNMATCHED_PROCESS_RECHECK_MS = 30_000;\n\ninterface SessionMetaHead {\n id?: string;\n cwd: string;\n timestampMs: number | null;\n}\n\ninterface SessionMetaCacheEntry {\n dev: number;\n ino: number;\n /** Bytes of the file head the metadata was parsed from. */\n headBytes: number;\n /** True once the head can no longer change (newline seen or byte limit reached). */\n headFinal: boolean;\n meta: SessionMetaHead | null;\n}\n\ninterface UnmatchedProcessEntry {\n checkedAtMs: number;\n dateDirSignature: string;\n}\n\ninterface FileHead {\n text: string;\n /** Bytes consumed by the first line (including its newline), or all bytes read. */\n bytes: number;\n /** A newline terminated the first line. */\n complete: boolean;\n /** The byte limit was reached before a newline. */\n truncated: boolean;\n}\n\nexport class CodexSessionLocator {\n private readonly sessionsDir: string;\n private readonly now: () => number;\n /** `session_meta` is written once at the head of an append-only file, so it is cached by path + inode. */\n private readonly sessionMetaCache = new Map<string, SessionMetaCacheEntry>();\n /** `(pid, startTime)` of processes that matched no session, keyed to their date-dir mtimes. */\n private readonly unmatchedProcesses = new Map<string, UnmatchedProcessEntry>();\n\n constructor(\n options: CodexSessionLocatorOptions = {},\n private readonly parser: CodexSessionParser = new CodexSessionParser(),\n ) {\n this.sessionsDir = options.sessionsDir ?? path.join(homeDir(), \".codex\", \"sessions\");\n this.now = options.now ?? Date.now;\n }\n\n matchRunningProcesses(processes: ProcessInfo[]): CodexProcessSessionMatches {\n const { direct, fallback } = this.tryResumeMatching(processes);\n const nowMs = this.now();\n const signatures = new Map(\n fallback.map((proc) => [proc, this.getDateDirSignature(proc)] as const),\n );\n const candidates = fallback.filter(\n (proc) => !this.isKnownUnmatched(proc, signatures.get(proc) ?? \"\", nowMs),\n );\n\n const { sessions } = this.discoverLiveSessions(candidates);\n const legacyMatches =\n candidates.length > 0 && sessions.length > 0\n ? matchProcessesToSessions(candidates, sessions)\n : [];\n\n this.updateUnmatchedProcesses(fallback, candidates, legacyMatches, signatures, nowMs);\n\n return { direct, legacyMatches, fallback };\n }\n\n tryResumeMatching(processes: ProcessInfo[]): {\n direct: CodexDirectMatch[];\n fallback: ProcessInfo[];\n } {\n const direct: CodexDirectMatch[] = [];\n const fallback: ProcessInfo[] = [];\n\n for (const proc of processes) {\n const sessionId = this.extractResumeSessionId(proc.command);\n if (!sessionId) {\n fallback.push(proc);\n continue;\n }\n\n const sessionFile = this.findSessionFileById(sessionId);\n if (!sessionFile) {\n fallback.push(proc);\n continue;\n }\n\n direct.push({ process: proc, sessionFile });\n }\n\n return { direct, fallback };\n }\n\n discoverLiveSessions(processes: ProcessInfo[]): CodexDiscoveredSessions {\n const empty = { sessions: [] };\n if (processes.length === 0) return empty;\n if (!fs.existsSync(this.sessionsDir)) return empty;\n\n const dateDirs = this.getDateDirs(processes);\n if (dateDirs.length === 0) return empty;\n\n return this.discoverSessionFilesInDateDirs(dateDirs);\n }\n\n discoverSessionFilesInDateDirs(dateDirs: string[]): CodexDiscoveredSessions {\n const files = batchGetSessionFileBirthtimes(dateDirs);\n this.pruneSessionMetaCache(dateDirs, files);\n\n for (const file of files) {\n const meta = this.readSessionMeta(file.filePath);\n if (!meta) continue;\n\n file.resolvedCwd = meta.cwd;\n if (meta.timestampMs !== null) {\n file.birthtimeMs = meta.timestampMs;\n }\n }\n\n return { sessions: files };\n }\n\n discoverHistoricalSessionFiles(): string[] {\n return this.collectAllSessionFiles();\n }\n\n findSessionFileById(sessionId: string): SessionFile | null {\n for (const filePath of this.getCandidateSessionFiles(sessionId)) {\n if (!path.basename(filePath).includes(sessionId)) continue;\n\n const meta = this.readSessionMeta(filePath);\n if (!meta || meta.id !== sessionId) continue;\n\n const stat = safeStat(filePath);\n if (!stat) continue;\n\n return {\n sessionId,\n filePath,\n projectDir: path.dirname(filePath),\n birthtimeMs: meta.timestampMs ?? stat.birthtimeMs,\n resolvedCwd: meta.cwd,\n };\n }\n\n return null;\n }\n\n collectAllSessionFiles(): string[] {\n const out: string[] = [];\n\n for (const yearEntry of safeReaddir(this.sessionsDir)) {\n const yearDir = path.join(this.sessionsDir, yearEntry);\n if (!isDirectory(yearDir)) continue;\n\n for (const monthEntry of safeReaddir(yearDir)) {\n const monthDir = path.join(yearDir, monthEntry);\n if (!isDirectory(monthDir)) continue;\n\n for (const dayEntry of safeReaddir(monthDir)) {\n const dayDir = path.join(monthDir, dayEntry);\n if (!isDirectory(dayDir)) continue;\n\n for (const fileEntry of safeReaddir(dayDir)) {\n if (!fileEntry.endsWith(\".jsonl\")) continue;\n out.push(path.join(dayDir, fileEntry));\n }\n }\n }\n }\n\n return out;\n }\n\n private extractResumeSessionId(command: string): string | null {\n const match = command.match(/(?:^|\\s)resume\\s+([0-9a-f-]{36})(?:\\s|$)/i);\n return match?.[1] ?? null;\n }\n\n private getCandidateSessionFiles(sessionId: string): string[] {\n const sessionDate = this.tryParseUuidV7Date(sessionId);\n if (!sessionDate) return this.collectAllSessionFiles();\n\n return this.collectSessionFilesInDateDirs(\n this.getDateDirsAroundDate(sessionDate, PROCESS_START_DAY_WINDOW_DAYS),\n );\n }\n\n /**\n * Read `session_meta` from at most {@link SESSION_META_HEAD_MAX_BYTES} of the\n * file head. Cached per path while the inode is unchanged and the file has\n * not shrunk below the parsed head, so growing session files are not re-read.\n */\n private readSessionMeta(filePath: string): SessionMetaHead | null {\n const stat = safeStat(filePath);\n if (!stat) return null;\n\n const cached = this.sessionMetaCache.get(filePath);\n if (cached && this.isSessionMetaCacheValid(cached, stat)) return cached.meta;\n\n const head = readFileHead(filePath, SESSION_META_HEAD_MAX_BYTES);\n if (!head) {\n this.sessionMetaCache.delete(filePath);\n return null;\n }\n\n const meta = this.parseSessionMetaHead(head);\n this.sessionMetaCache.set(filePath, {\n dev: stat.dev,\n ino: stat.ino,\n headBytes: head.bytes,\n headFinal: head.complete || head.truncated,\n meta,\n });\n return meta;\n }\n\n private isSessionMetaCacheValid(entry: SessionMetaCacheEntry, stat: fs.Stats): boolean {\n if (entry.dev !== stat.dev || entry.ino !== stat.ino) return false;\n return entry.headFinal ? stat.size >= entry.headBytes : stat.size === entry.headBytes;\n }\n\n private parseSessionMetaHead(head: FileHead): SessionMetaHead | null {\n const line = head.text.trim();\n if (!line) return null;\n\n try {\n const parsed = JSON.parse(line) as CodexEventEntry;\n if (parsed.type !== \"session_meta\") return null;\n return {\n id: parsed.payload?.id,\n cwd: parsed.payload?.cwd || \"\",\n timestampMs: this.parser.parseMetaTimestampMs(parsed.payload?.timestamp),\n };\n } catch {\n return head.truncated ? this.parseTruncatedSessionMeta(line) : null;\n }\n }\n\n /**\n * Best-effort extraction for a `session_meta` line longer than the head limit\n * (e.g. large embedded instructions). `id`, `timestamp` and `cwd` precede the\n * bulky payload fields, so they are read from the payload prefix.\n */\n private parseTruncatedSessionMeta(line: string): SessionMetaHead | null {\n if (!/\"type\"\\s*:\\s*\"session_meta\"/.test(line)) return null;\n\n const payloadStart = line.search(/\"payload\"\\s*:\\s*\\{/);\n if (payloadStart < 0) return null;\n const payload = line.slice(payloadStart);\n\n return {\n id: extractJsonStringField(payload, \"id\"),\n cwd: extractJsonStringField(payload, \"cwd\") || \"\",\n timestampMs: this.parser.parseMetaTimestampMs(extractJsonStringField(payload, \"timestamp\")),\n };\n }\n\n private pruneSessionMetaCache(dateDirs: string[], files: SessionFile[]): void {\n const scannedDirs = new Set(dateDirs);\n const present = new Set(files.map((file) => file.filePath));\n for (const filePath of this.sessionMetaCache.keys()) {\n if (scannedDirs.has(path.dirname(filePath)) && !present.has(filePath)) {\n this.sessionMetaCache.delete(filePath);\n }\n }\n }\n\n private isKnownUnmatched(proc: ProcessInfo, dateDirSignature: string, nowMs: number): boolean {\n const entry = this.unmatchedProcesses.get(this.toProcessKey(proc));\n if (!entry) return false;\n if (nowMs - entry.checkedAtMs >= UNMATCHED_PROCESS_RECHECK_MS) return false;\n return entry.dateDirSignature === dateDirSignature;\n }\n\n private updateUnmatchedProcesses(\n fallback: ProcessInfo[],\n scanned: ProcessInfo[],\n legacyMatches: MatchResult[],\n signatures: Map<ProcessInfo, string>,\n nowMs: number,\n ): void {\n const liveKeys = new Set(fallback.map((proc) => this.toProcessKey(proc)));\n for (const key of this.unmatchedProcesses.keys()) {\n if (!liveKeys.has(key)) this.unmatchedProcesses.delete(key);\n }\n\n const matchedPids = new Set(legacyMatches.map((match) => match.process.pid));\n for (const proc of scanned) {\n const key = this.toProcessKey(proc);\n if (matchedPids.has(proc.pid)) {\n this.unmatchedProcesses.delete(key);\n } else {\n this.unmatchedProcesses.set(key, {\n checkedAtMs: nowMs,\n dateDirSignature: signatures.get(proc) ?? \"\",\n });\n }\n }\n }\n\n private toProcessKey(proc: ProcessInfo): string {\n return `${proc.pid}:${proc.startTime?.getTime() ?? \"unknown\"}`;\n }\n\n /** Day-window directories with their mtimes; changes when session files are added or removed. */\n private getDateDirSignature(proc: ProcessInfo): string {\n return this.getProcessDayKeys(proc)\n .map((dayKey) => {\n const stat = safeStat(path.join(this.sessionsDir, dayKey));\n return `${dayKey}=${stat?.isDirectory() ? stat.mtimeMs : \"-\"}`;\n })\n .join(\"|\");\n }\n\n private getProcessDayKeys(proc: ProcessInfo): string[] {\n const startTime = proc.startTime || new Date();\n const dayKeys: string[] = [];\n\n for (\n let offset = -PROCESS_START_DAY_WINDOW_DAYS;\n offset <= PROCESS_START_DAY_WINDOW_DAYS;\n offset++\n ) {\n const day = new Date(startTime.getTime());\n day.setDate(day.getDate() + offset);\n dayKeys.push(this.toSessionDayKey(day));\n }\n\n return dayKeys;\n }\n\n private getDateDirs(processes: ProcessInfo[]): string[] {\n const dayKeys = new Set<string>();\n\n for (const proc of processes) {\n for (const dayKey of this.getProcessDayKeys(proc)) {\n dayKeys.add(dayKey);\n }\n }\n\n const dirs: string[] = [];\n for (const dayKey of dayKeys) {\n const dayDir = path.join(this.sessionsDir, dayKey);\n try {\n if (fs.statSync(dayDir).isDirectory()) {\n dirs.push(dayDir);\n }\n } catch {\n continue;\n }\n }\n\n return dirs;\n }\n\n private getDateDirsAroundDate(date: Date, windowDays: number): string[] {\n const dirs: string[] = [];\n\n for (let offset = -windowDays; offset <= windowDays; offset++) {\n const day = new Date(date.getTime());\n day.setDate(day.getDate() + offset);\n const dayDir = path.join(this.sessionsDir, this.toSessionDayKey(day));\n if (isDirectory(dayDir)) {\n dirs.push(dayDir);\n }\n }\n\n return dirs;\n }\n\n private toSessionDayKey(date: Date): string {\n const yyyy = String(date.getFullYear()).padStart(4, \"0\");\n const mm = String(date.getMonth() + 1).padStart(2, \"0\");\n const dd = String(date.getDate()).padStart(2, \"0\");\n return path.join(yyyy, mm, dd);\n }\n\n private tryParseUuidV7Date(sessionId: string): Date | null {\n const match = sessionId.match(\n /^([0-9a-f]{8})-([0-9a-f]{4})-7[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$/i,\n );\n if (!match) return null;\n\n const timestampMs = Number.parseInt(`${match[1]}${match[2]}`, 16);\n if (!Number.isSafeInteger(timestampMs) || timestampMs <= 0) return null;\n\n const date = new Date(timestampMs);\n return Number.isNaN(date.getTime()) ? null : date;\n }\n\n private collectSessionFilesInDateDirs(dateDirs: string[]): string[] {\n const out: string[] = [];\n\n for (const dayDir of dateDirs) {\n for (const fileEntry of safeReaddir(dayDir)) {\n if (!fileEntry.endsWith(\".jsonl\")) continue;\n out.push(path.join(dayDir, fileEntry));\n }\n }\n\n return out;\n }\n}\n\n/**\n * Read the first line of a file, consuming at most `maxBytes`.\n * Returns `null` when the file cannot be opened or read.\n */\nfunction readFileHead(filePath: string, maxBytes: number): FileHead | null {\n let fd: number;\n try {\n fd = fs.openSync(filePath, \"r\");\n } catch {\n return null;\n }\n\n try {\n const buffer = Buffer.alloc(maxBytes);\n let total = 0;\n\n while (total < maxBytes) {\n const length = Math.min(SESSION_META_HEAD_CHUNK_BYTES, maxBytes - total);\n const read = fs.readSync(fd, buffer, total, length, total);\n if (read <= 0) break;\n\n const newlineIndex = buffer.indexOf(0x0a, total);\n total += read;\n if (newlineIndex >= 0 && newlineIndex < total) {\n return {\n text: buffer.toString(\"utf-8\", 0, newlineIndex),\n bytes: newlineIndex + 1,\n complete: true,\n truncated: false,\n };\n }\n }\n\n return {\n text: buffer.toString(\"utf-8\", 0, total),\n bytes: total,\n complete: false,\n truncated: total >= maxBytes,\n };\n } catch {\n return null;\n } finally {\n try {\n fs.closeSync(fd);\n } catch {\n // Ignore close errors\n }\n }\n}\n\n/** Extract the first `\"field\": \"<json string>\"` value from a JSON fragment. */\nfunction extractJsonStringField(fragment: string, field: string): string | undefined {\n const match = fragment.match(new RegExp(`\"${field}\"\\\\s*:\\\\s*(\"(?:[^\"\\\\\\\\]|\\\\\\\\.)*\")`));\n if (!match) return undefined;\n\n try {\n const value = JSON.parse(match[1]) as unknown;\n return typeof value === \"string\" ? value : undefined;\n } catch {\n return undefined;\n }\n}\n"],"names":["fs","path","matchProcessesToSessions","batchGetSessionFileBirthtimes","isDirectory","safeReaddir","safeStat","CodexSessionParser","homeDir","PROCESS_START_DAY_WINDOW_DAYS","SESSION_META_HEAD_MAX_BYTES","SESSION_META_HEAD_CHUNK_BYTES","UNMATCHED_PROCESS_RECHECK_MS","CodexSessionLocator","sessionsDir","now","sessionMetaCache","Map","unmatchedProcesses","options","parser","join","Date","matchRunningProcesses","processes","direct","fallback","tryResumeMatching","nowMs","signatures","map","proc","getDateDirSignature","candidates","filter","isKnownUnmatched","get","sessions","discoverLiveSessions","legacyMatches","length","updateUnmatchedProcesses","sessionId","extractResumeSessionId","command","push","sessionFile","findSessionFileById","process","empty","existsSync","dateDirs","getDateDirs","discoverSessionFilesInDateDirs","files","pruneSessionMetaCache","file","meta","readSessionMeta","filePath","resolvedCwd","cwd","timestampMs","birthtimeMs","discoverHistoricalSessionFiles","collectAllSessionFiles","getCandidateSessionFiles","basename","includes","id","stat","projectDir","dirname","out","yearEntry","yearDir","monthEntry","monthDir","dayEntry","dayDir","fileEntry","endsWith","match","sessionDate","tryParseUuidV7Date","collectSessionFilesInDateDirs","getDateDirsAroundDate","cached","isSessionMetaCacheValid","head","readFileHead","delete","parseSessionMetaHead","set","dev","ino","headBytes","bytes","headFinal","complete","truncated","entry","size","line","text","trim","parsed","JSON","parse","type","payload","parseMetaTimestampMs","timestamp","parseTruncatedSessionMeta","test","payloadStart","search","slice","extractJsonStringField","scannedDirs","Set","present","keys","has","dateDirSignature","toProcessKey","checkedAtMs","scanned","liveKeys","key","matchedPids","pid","startTime","getTime","getProcessDayKeys","dayKey","mtimeMs","dayKeys","offset","day","setDate","getDate","toSessionDayKey","add","dirs","statSync","date","windowDays","yyyy","String","getFullYear","padStart","mm","getMonth","dd","Number","parseInt","isSafeInteger","isNaN","maxBytes","fd","openSync","buffer","Buffer","alloc","total","Math","min","read","readSync","newlineIndex","indexOf","toString","closeSync","fragment","field","RegExp","undefined","value"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CodexSessionMapping.d.ts","sourceRoot":"","sources":["../../../src/providers/codex/CodexSessionMapping.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAGlE,MAAM,WAAW,0BAA0B;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,wBAAwB,EAAE,CAAC;IACpC,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,OAAO,GAAE,0BAA+B;IAOpD,KAAK,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,yBAAyB;IAoB1D,OAAO,CAAC,IAAI;IAwBZ,OAAO,CAAC,KAAK;IAQb,OAAO,CAAC,oBAAoB;CAK7B"}
1
+ {"version":3,"file":"CodexSessionMapping.d.ts","sourceRoot":"","sources":["../../../src/harnesses/codex/CodexSessionMapping.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAIlE,MAAM,WAAW,0BAA0B;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,wBAAwB,EAAE,CAAC;IACpC,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,OAAO,GAAE,0BAA+B;IAMpD,KAAK,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,yBAAyB;IAoB1D,OAAO,CAAC,IAAI;IAwBZ,OAAO,CAAC,KAAK;IAQb,OAAO,CAAC,oBAAoB;CAK7B"}
@@ -1,13 +1,13 @@
1
1
  import * as fs from "fs";
2
2
  import * as path from "path";
3
3
  import { safeReadFile } from "../../utils/session.js";
4
+ import { homeDir } from "../shared.js";
4
5
  export class CodexSessionMapping {
5
6
  mappingPath;
6
7
  sessionsDir;
7
8
  constructor(options = {}){
8
- const homeDir = process.env.HOME || process.env.USERPROFILE || "";
9
- this.mappingPath = options.mappingPath ?? path.join(homeDir, ".codex", "ai-devkit", "sessions.json");
10
- this.sessionsDir = options.sessionsDir ?? path.join(homeDir, ".codex", "sessions");
9
+ this.mappingPath = options.mappingPath ?? path.join(homeDir(), ".codex", "ai-devkit", "sessions.json");
10
+ this.sessionsDir = options.sessionsDir ?? path.join(homeDir(), ".codex", "sessions");
11
11
  }
12
12
  match(processes) {
13
13
  const mapping = this.read();
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/harnesses/codex/CodexSessionMapping.ts"],"sourcesContent":["import * as fs from \"fs\";\nimport * as path from \"path\";\nimport type { ProcessInfo } from \"../../adapters/AgentAdapter.js\";\nimport { safeReadFile } from \"../../utils/session.js\";\nimport { homeDir } from \"../shared.js\";\n\nexport interface CodexSessionMappingOptions {\n mappingPath?: string;\n sessionsDir?: string;\n}\n\nexport interface CodexSessionMappingMatch {\n process: ProcessInfo;\n filePath: string;\n}\n\nexport interface CodexSessionMappingResult {\n matches: CodexSessionMappingMatch[];\n fallback: ProcessInfo[];\n}\n\nexport class CodexSessionMapping {\n private readonly mappingPath: string;\n private readonly sessionsDir: string;\n\n constructor(options: CodexSessionMappingOptions = {}) {\n this.mappingPath =\n options.mappingPath ?? path.join(homeDir(), \".codex\", \"ai-devkit\", \"sessions.json\");\n this.sessionsDir = options.sessionsDir ?? path.join(homeDir(), \".codex\", \"sessions\");\n }\n\n match(processes: ProcessInfo[]): CodexSessionMappingResult {\n const mapping = this.read();\n if (mapping.size === 0) return { matches: [], fallback: processes };\n\n const matches: CodexSessionMappingMatch[] = [];\n const fallback: ProcessInfo[] = [];\n\n for (const processInfo of processes) {\n const filePath = mapping.get(processInfo.pid);\n if (!filePath || !this.isTrustedSessionPath(filePath) || !fs.existsSync(filePath)) {\n fallback.push(processInfo);\n continue;\n }\n\n matches.push({ process: processInfo, filePath });\n }\n\n return { matches, fallback };\n }\n\n private read(): Map<number, string> {\n const content = safeReadFile(this.mappingPath);\n if (content === undefined) return new Map();\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n return new Map();\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) return new Map();\n\n const map = new Map<number, string>();\n for (const [key, value] of Object.entries(parsed)) {\n const pid = this.toPid(key);\n if (pid !== null && typeof value === \"string\" && value) {\n map.set(pid, value);\n }\n }\n\n return map;\n }\n\n private toPid(value: unknown): number | null {\n if (typeof value === \"number\" && Number.isInteger(value) && value > 0) return value;\n if (typeof value !== \"string\" || !/^\\d+$/.test(value)) return null;\n\n const parsed = Number(value);\n return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;\n }\n\n private isTrustedSessionPath(filePath: string): boolean {\n const resolvedRoot = path.resolve(this.sessionsDir);\n const resolvedPath = path.resolve(filePath);\n return resolvedPath === resolvedRoot || resolvedPath.startsWith(`${resolvedRoot}${path.sep}`);\n }\n}\n"],"names":["fs","path","safeReadFile","homeDir","CodexSessionMapping","mappingPath","sessionsDir","options","join","match","processes","mapping","read","size","matches","fallback","processInfo","filePath","get","pid","isTrustedSessionPath","existsSync","push","process","content","undefined","Map","parsed","JSON","parse","Array","isArray","map","key","value","Object","entries","toPid","set","Number","isInteger","test","isSafeInteger","resolvedRoot","resolve","resolvedPath","startsWith","sep"],"mappings":"AAAA,YAAYA,QAAQ,KAAK;AACzB,YAAYC,UAAU,OAAO;AAE7B,SAASC,YAAY,QAAQ,yBAAyB;AACtD,SAASC,OAAO,QAAQ,eAAe;AAiBvC,OAAO,MAAMC;IACMC,YAAoB;IACpBC,YAAoB;IAErC,YAAYC,UAAsC,CAAC,CAAC,CAAE;QACpD,IAAI,CAACF,WAAW,GACdE,QAAQF,WAAW,IAAIJ,KAAKO,IAAI,CAACL,WAAW,UAAU,aAAa;QACrE,IAAI,CAACG,WAAW,GAAGC,QAAQD,WAAW,IAAIL,KAAKO,IAAI,CAACL,WAAW,UAAU;IAC3E;IAEAM,MAAMC,SAAwB,EAA6B;QACzD,MAAMC,UAAU,IAAI,CAACC,IAAI;QACzB,IAAID,QAAQE,IAAI,KAAK,GAAG,OAAO;YAAEC,SAAS,EAAE;YAAEC,UAAUL;QAAU;QAElE,MAAMI,UAAsC,EAAE;QAC9C,MAAMC,WAA0B,EAAE;QAElC,KAAK,MAAMC,eAAeN,UAAW;YACnC,MAAMO,WAAWN,QAAQO,GAAG,CAACF,YAAYG,GAAG;YAC5C,IAAI,CAACF,YAAY,CAAC,IAAI,CAACG,oBAAoB,CAACH,aAAa,CAACjB,GAAGqB,UAAU,CAACJ,WAAW;gBACjFF,SAASO,IAAI,CAACN;gBACd;YACF;YAEAF,QAAQQ,IAAI,CAAC;gBAAEC,SAASP;gBAAaC;YAAS;QAChD;QAEA,OAAO;YAAEH;YAASC;QAAS;IAC7B;IAEQH,OAA4B;QAClC,MAAMY,UAAUtB,aAAa,IAAI,CAACG,WAAW;QAC7C,IAAImB,YAAYC,WAAW,OAAO,IAAIC;QAEtC,IAAIC;QACJ,IAAI;YACFA,SAASC,KAAKC,KAAK,CAACL;QACtB,EAAE,OAAM;YACN,OAAO,IAAIE;QACb;QAEA,IAAI,CAACC,UAAU,OAAOA,WAAW,YAAYG,MAAMC,OAAO,CAACJ,SAAS,OAAO,IAAID;QAE/E,MAAMM,MAAM,IAAIN;QAChB,KAAK,MAAM,CAACO,KAAKC,MAAM,IAAIC,OAAOC,OAAO,CAACT,QAAS;YACjD,MAAMR,MAAM,IAAI,CAACkB,KAAK,CAACJ;YACvB,IAAId,QAAQ,QAAQ,OAAOe,UAAU,YAAYA,OAAO;gBACtDF,IAAIM,GAAG,CAACnB,KAAKe;YACf;QACF;QAEA,OAAOF;IACT;IAEQK,MAAMH,KAAc,EAAiB;QAC3C,IAAI,OAAOA,UAAU,YAAYK,OAAOC,SAAS,CAACN,UAAUA,QAAQ,GAAG,OAAOA;QAC9E,IAAI,OAAOA,UAAU,YAAY,CAAC,QAAQO,IAAI,CAACP,QAAQ,OAAO;QAE9D,MAAMP,SAASY,OAAOL;QACtB,OAAOK,OAAOG,aAAa,CAACf,WAAWA,SAAS,IAAIA,SAAS;IAC/D;IAEQP,qBAAqBH,QAAgB,EAAW;QACtD,MAAM0B,eAAe1C,KAAK2C,OAAO,CAAC,IAAI,CAACtC,WAAW;QAClD,MAAMuC,eAAe5C,KAAK2C,OAAO,CAAC3B;QAClC,OAAO4B,iBAAiBF,gBAAgBE,aAAaC,UAAU,CAAC,GAAGH,eAAe1C,KAAK8C,GAAG,EAAE;IAC9F;AACF"}
@@ -0,0 +1,89 @@
1
+ import type { ConversationMessage, ConversationOptions, SessionSummary } from "../../adapters/AgentAdapter.js";
2
+ import { AgentStatus } from "../../adapters/AgentAdapter.js";
3
+ import { type JsonlSummaryBounds } from "../../utils/IncrementalJsonlSummary.js";
4
+ export interface CodexEventEntry {
5
+ timestamp?: string;
6
+ type?: string;
7
+ payload?: {
8
+ type?: string;
9
+ message?: string;
10
+ id?: string;
11
+ cwd?: string;
12
+ timestamp?: string;
13
+ role?: string;
14
+ content?: CodexContent[];
15
+ item?: CodexItem;
16
+ turn_id?: string;
17
+ internal_chat_message_metadata_passthrough?: {
18
+ turn_id?: string;
19
+ };
20
+ };
21
+ }
22
+ export interface CodexContent {
23
+ type?: string;
24
+ text?: string;
25
+ }
26
+ export interface CodexItem {
27
+ type?: string;
28
+ content?: string | CodexContent[];
29
+ }
30
+ export interface CodexSession {
31
+ sessionId: string;
32
+ projectPath: string;
33
+ summary: string;
34
+ sessionStart: Date;
35
+ lastActive: Date;
36
+ lastPayloadType?: string;
37
+ }
38
+ export interface CodexSessionParserOptions {
39
+ /** Cold-start scan bounds for `readSessionIncremental` (see IncrementalJsonlSummary). */
40
+ summaryBounds?: JsonlSummaryBounds | false;
41
+ }
42
+ export declare class CodexSessionParser {
43
+ /** Incremental reader backing `getConversation({ tail })`. */
44
+ private readonly tailReader;
45
+ private readonly sessionCache;
46
+ constructor(options?: CodexSessionParserOptions);
47
+ readSession(filePath: string, cachedContent?: string): CodexSession | null;
48
+ /**
49
+ * Same result as `readSession`, but backed by a per-instance incremental
50
+ * cache so repeated refreshes only parse bytes appended since the last call.
51
+ * Call `pruneSessionCache()` once per refresh to evict files no longer read.
52
+ *
53
+ * The first read of a large transcript is a bounded head + tail scan (see
54
+ * `summaryReducer.skip`); fields whose entries lie only in the skipped
55
+ * middle fall back to their defaults instead of forcing a full parse.
56
+ */
57
+ readSessionIncremental(filePath: string): CodexSession | null;
58
+ /** Evict cached summaries for files not read since the previous prune. */
59
+ pruneSessionCache(): void;
60
+ /**
61
+ * Fold one JSONL entry into the O(1) session summary. The first line must
62
+ * be a `session_meta` entry; the rest track the last typed entry and the
63
+ * last entry with displayable text.
64
+ *
65
+ * `skip` (bounded cold start) keeps the head's `session_meta` and clears the
66
+ * "latest" fields, so those come from the tail only. Without a typed tail
67
+ * entry lastActive falls back to the meta timestamp, then the file mtime;
68
+ * without tail text the summary is the "Codex session active" default. A
69
+ * `session_meta` line longer than the head window yields no session (null).
70
+ */
71
+ private readonly summaryReducer;
72
+ private toSession;
73
+ determineStatus(session: CodexSession): AgentStatus;
74
+ getConversation(sessionFilePath: string, options?: ConversationOptions): ConversationMessage[];
75
+ private lineToConversationItem;
76
+ /** Drop event_msg messages mirrored by a response_item with the same turn/role/content. */
77
+ private dedupeMirroredMessages;
78
+ fileToSessionSummary(filePath: string): SessionSummary | null;
79
+ parseMetaTimestampMs(value?: string): number | null;
80
+ private normalizedPayloadType;
81
+ private extractEntryText;
82
+ private toConversationMessage;
83
+ private mapCodexRole;
84
+ private mapCodexItemRole;
85
+ private mirroredMessageKey;
86
+ private extractContentText;
87
+ private isSyntheticUserMessage;
88
+ }
89
+ //# sourceMappingURL=CodexSessionParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodexSessionParser.d.ts","sourceRoot":"","sources":["../../../src/harnesses/codex/CodexSessionParser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACf,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAG7D,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,wCAAwC,CAAC;AAGhD,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;QACzB,IAAI,CAAC,EAAE,SAAS,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,0CAA0C,CAAC,EAAE;YAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;SAClB,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,IAAI,CAAC;IACnB,UAAU,EAAE,IAAI,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAsBD,MAAM,WAAW,yBAAyB;IACxC,yFAAyF;IACzF,aAAa,CAAC,EAAE,kBAAkB,GAAG,KAAK,CAAC;CAC5C;AAED,qBAAa,kBAAkB;IAC7B,8DAA8D;IAC9D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyB;IAEpD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6C;gBAE9D,OAAO,GAAE,yBAA8B;IAMnD,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAkB1E;;;;;;;;OAQG;IACH,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAK7D,0EAA0E;IAC1E,iBAAiB,IAAI,IAAI;IAIzB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CA6B7B;IAEF,OAAO,CAAC,SAAS;IAkBjB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,WAAW;IAgBnD,eAAe,CAAC,eAAe,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,mBAAmB,EAAE;IA0B9F,OAAO,CAAC,sBAAsB;IAc9B,2FAA2F;IAC3F,OAAO,CAAC,sBAAsB;IAsB9B,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAkE7D,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAUnD,OAAO,CAAC,qBAAqB;IAmB7B,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,qBAAqB;IA2C7B,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,sBAAsB;CAK/B"}