farming-code 2.2.30 → 2.2.32

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 (377) hide show
  1. package/THIRD_PARTY_NOTICES.md +7 -0
  2. package/backend/acp/{client-services.js → client-services.cjs} +132 -134
  3. package/backend/acp/packaged-claude-acp.cjs +37 -0
  4. package/backend/acp/packaged-codex-acp.cjs +37 -0
  5. package/backend/acp/patch-decisions.cjs +182 -0
  6. package/backend/acp/permission-security.cjs +131 -0
  7. package/backend/{acp-checkpoint-store.js → acp-checkpoint-store.cjs} +90 -59
  8. package/backend/{acp-runtime.js → acp-runtime.cjs} +1220 -1112
  9. package/backend/acp-session-state.cjs +622 -0
  10. package/backend/acp-transcript.cjs +525 -0
  11. package/backend/agent-env.cjs +257 -0
  12. package/backend/agent-extension-discovery.cjs +452 -0
  13. package/backend/agent-extension-inventory.cjs +116 -0
  14. package/backend/agent-json-stream.cjs +283 -0
  15. package/backend/agent-lifecycle-journal.cjs +185 -0
  16. package/backend/{agent-manager.js → agent-manager.cjs} +3116 -4275
  17. package/backend/agent-order-transaction.cjs +85 -0
  18. package/backend/agent-order.cjs +159 -0
  19. package/backend/agent-provider-session.cjs +98 -0
  20. package/backend/agent-runtime-binding.cjs +179 -0
  21. package/backend/agent-session-history.cjs +1022 -0
  22. package/backend/agent-session-inventory.cjs +291 -0
  23. package/backend/async-cache.cjs +104 -0
  24. package/backend/atomic-json-store.cjs +67 -0
  25. package/backend/auth.cjs +261 -0
  26. package/backend/authoritative-inventory-cache.cjs +383 -0
  27. package/backend/business-health.cjs +68 -0
  28. package/backend/chat-runtime.cjs +50 -0
  29. package/backend/claude-settings.cjs +132 -0
  30. package/backend/cli-agents.cjs +435 -0
  31. package/backend/codex-context-window.cjs +196 -0
  32. package/backend/codex-models.cjs +228 -0
  33. package/backend/codex-session-archive.cjs +82 -0
  34. package/backend/codex-session-history.cjs +590 -0
  35. package/backend/{codex-terminal-profile.js → codex-terminal-profile.cjs} +149 -155
  36. package/backend/codex-transcript-sanitizer.cjs +130 -0
  37. package/backend/codex-transcript.cjs +2107 -0
  38. package/backend/command-runner-child.cjs +105 -0
  39. package/backend/config-manager.cjs +1263 -0
  40. package/backend/control-api.cjs +439 -0
  41. package/backend/data/LICENSE.cua +21 -0
  42. package/backend/executable-discovery.cjs +204 -0
  43. package/backend/farming-agent-bootstrap.cjs +81 -0
  44. package/backend/farming-agent-bootstrap.zh_cn.md +6 -2
  45. package/backend/{farming-app-cli.js → farming-app-cli.cjs} +441 -493
  46. package/backend/farming-cli.cjs +414 -0
  47. package/backend/farming-net-pass.cjs +319 -0
  48. package/backend/farming-net-registry.cjs +123 -0
  49. package/backend/farming-net-server.cjs +309 -0
  50. package/backend/farming-session-store.cjs +651 -0
  51. package/backend/git-worktree-info.cjs +181 -0
  52. package/backend/haiku-token.cjs +828 -0
  53. package/backend/index-html.cjs +96 -0
  54. package/backend/input-parts.cjs +68 -0
  55. package/backend/input-routing.cjs +40 -0
  56. package/backend/{local-session-engine.js → local-session-engine.cjs} +276 -282
  57. package/backend/main-agent-skills.cjs +309 -0
  58. package/backend/main-page-session.cjs +132 -0
  59. package/backend/native-pty-controller-generation.cjs +139 -0
  60. package/backend/{native-pty-host-client.js → native-pty-host-client.cjs} +338 -346
  61. package/backend/native-pty-host-identity.cjs +125 -0
  62. package/backend/native-pty-host-path.cjs +68 -0
  63. package/backend/{native-pty-host.js → native-pty-host.cjs} +480 -569
  64. package/backend/native-session-engine.cjs +296 -0
  65. package/backend/network.cjs +57 -0
  66. package/backend/npm-update-helper.cjs +399 -0
  67. package/backend/packaged-node-pty.cjs +120 -0
  68. package/backend/preview-session-manager.cjs +89 -0
  69. package/backend/provider-adapters.cjs +492 -0
  70. package/backend/provider-home-configuration.cjs +211 -0
  71. package/backend/provider-session-id.cjs +79 -0
  72. package/backend/provider-session-service.cjs +333 -0
  73. package/backend/qr-share-tickets.cjs +119 -0
  74. package/backend/resource-broadcast-protocol.cjs +50 -0
  75. package/backend/review-diff-router.cjs +202 -0
  76. package/backend/review-diff-service.cjs +1267 -0
  77. package/backend/review-session-router.cjs +93 -0
  78. package/backend/review-session-service.cjs +470 -0
  79. package/backend/review-session-store.cjs +161 -0
  80. package/backend/review-state-router.cjs +132 -0
  81. package/backend/review-state-store.cjs +299 -0
  82. package/backend/run-history-store.cjs +97 -0
  83. package/backend/runtime-dependency-manager.cjs +893 -0
  84. package/backend/runtime-executable-invocation.cjs +37 -0
  85. package/backend/runtime-observation.cjs +96 -0
  86. package/backend/server-process-identity.cjs +70 -0
  87. package/backend/server.cjs +3356 -0
  88. package/backend/session-engine-bridge.cjs +144 -0
  89. package/backend/session-engine-router.cjs +105 -0
  90. package/backend/session-engine.cjs +64 -0
  91. package/backend/session-stream-protocol.cjs +181 -0
  92. package/backend/shell-busy-integration.cjs +442 -0
  93. package/backend/slash-command-discovery.cjs +423 -0
  94. package/backend/storage-layout.cjs +263 -0
  95. package/backend/system-monitor.cjs +96 -0
  96. package/backend/terminal-attach-checkpoint.cjs +73 -0
  97. package/backend/terminal-exit-quiescence.cjs +57 -0
  98. package/backend/{terminal-reducer-flow-control.js → terminal-reducer-flow-control.cjs} +45 -22
  99. package/backend/terminal-runtime-cleanup.cjs +99 -0
  100. package/backend/{terminal-screen-state.js → terminal-screen-state.cjs} +100 -108
  101. package/backend/{terminal-screen-worker-pool.js → terminal-screen-worker-pool.cjs} +89 -79
  102. package/backend/{terminal-screen-worker-thread.js → terminal-screen-worker-thread.cjs} +64 -65
  103. package/backend/terminal-screen-worker.cjs +352 -0
  104. package/backend/terminal-state-serialization.cjs +147 -0
  105. package/backend/{terminal-status.js → terminal-status.cjs} +137 -187
  106. package/backend/theme-manager.cjs +185 -0
  107. package/backend/{update-service.js → update-service.cjs} +258 -248
  108. package/backend/usage-forecast.cjs +95 -0
  109. package/backend/{usage-history-client.js → usage-history-client.cjs} +144 -94
  110. package/backend/usage-history-smoke.cjs +85 -0
  111. package/backend/usage-history-worker.cjs +60 -0
  112. package/backend/{usage-monitor.js → usage-monitor.cjs} +363 -390
  113. package/backend/workspace-directory.cjs +239 -0
  114. package/backend/workspace-discovery.cjs +271 -0
  115. package/backend/{workspace-file-router.js → workspace-file-router.cjs} +213 -282
  116. package/backend/{workspace-file-service.js → workspace-file-service.cjs} +1139 -1318
  117. package/backend/workspace-root-registry.cjs +192 -0
  118. package/bin/farming +1 -1
  119. package/dist/acp/codex-acp-1.1.4.mjs +18 -1
  120. package/dist/assets/App-BCkdpWB6.css +1 -0
  121. package/dist/assets/App-CRjKpaGp.js +697 -0
  122. package/dist/assets/CodeSelect-Ci8sKZPU.js +1 -0
  123. package/dist/assets/CodeSelect-T2eNzrOc.css +1 -0
  124. package/dist/assets/{FileEditorMarkdownPreview-Cs9cLv8a.js → FileEditorMarkdownPreview-V06QHlAg.js} +55 -55
  125. package/dist/assets/FileEditorPane-BX-Wjg9U.js +2 -0
  126. package/dist/assets/IconGlyphs-YhV7tqd4.js +1 -0
  127. package/dist/assets/ProjectFilesSection-BDT2_r0o.js +12 -0
  128. package/dist/assets/ReviewPage-BqAs5sG1.js +3 -0
  129. package/dist/assets/code-dark-B7eM_9G9.css +1 -0
  130. package/dist/assets/{cssMode-Bdg5RpcJ.js → cssMode-ADdAlxTO.js} +1 -1
  131. package/dist/assets/{editor.api2-D74ufkbr.js → editor.api2-BFLAr0YF.js} +162 -162
  132. package/dist/assets/file-icons-BpeqWkIB.js +1 -0
  133. package/dist/assets/{freemarker2-DfMDJfnE.js → freemarker2-C90q5jrp.js} +1 -1
  134. package/dist/assets/{handlebars-BEdPtzMT.js → handlebars-BwUQcEDq.js} +1 -1
  135. package/dist/assets/{html-B1fPb1QD.js → html-1s3uPKfh.js} +1 -1
  136. package/dist/assets/{htmlMode-CY2ZjHxH.js → htmlMode-xtKD99de.js} +1 -1
  137. package/dist/assets/{index-D-zetSol.js → index-C8MchCem.js} +3 -3
  138. package/dist/assets/{javascript-BV2OsWA0.js → javascript-Ph7ijyny.js} +1 -1
  139. package/dist/assets/{jsonMode-zd07aeuX.js → jsonMode-D-jGAnFH.js} +1 -1
  140. package/dist/assets/linkComputer-CbGyI_qx.js +1 -0
  141. package/dist/assets/{liquid-BParI24X.js → liquid-0IamE_cI.js} +1 -1
  142. package/dist/assets/{lspLanguageFeatures-BzredkoV.js → lspLanguageFeatures-BxnQunWF.js} +1 -1
  143. package/dist/assets/main-CLKXa6hf.css +1 -0
  144. package/dist/assets/{mdx-vGzUJN98.js → mdx-DdNmfivn.js} +1 -1
  145. package/dist/assets/{monaco.contribution-BmaeBQEc.js → monaco.contribution-B43jsUs1.js} +2 -2
  146. package/dist/assets/{python-CUwdLgsI.js → python-IAt4X5TS.js} +1 -1
  147. package/dist/assets/{razor-BScebUxU.js → razor-DRkFYW0S.js} +1 -1
  148. package/dist/assets/review-C8-oPKXk.css +1 -0
  149. package/dist/assets/{tsMode-DzUAibXK.js → tsMode-_d_4U2gf.js} +1 -1
  150. package/dist/assets/{typescript-D9EOeM7N.js → typescript-C7zcMq9l.js} +1 -1
  151. package/dist/assets/{workers-DAiomYZM.js → workers-D0nOyJzf.js} +1 -1
  152. package/dist/assets/workspace-editor-model-DND_Y-Bj.js +1 -0
  153. package/dist/assets/workspace-editor-monaco-BPWhgcIB.js +4 -0
  154. package/dist/assets/workspace-editor-monaco-N641qPjX.js +1 -0
  155. package/dist/assets/workspace-view-state-k1bTlJ_Z.js +13 -0
  156. package/dist/assets/{xml-wWl1dhkQ.js → xml-BR-HvxT8.js} +1 -1
  157. package/dist/assets/{yaml-Dc2WDaOZ.js → yaml-YtFQwh4q.js} +1 -1
  158. package/dist/index.html +1 -1
  159. package/extensions/browser/backend/agent-browser-runtime.cjs +1040 -0
  160. package/extensions/browser/backend/agent-capability.cjs +85 -0
  161. package/extensions/browser/backend/browser-mcp-server.cjs +655 -0
  162. package/extensions/browser/backend/browser-resource-manager.cjs +1486 -0
  163. package/extensions/browser/backend/browser-resource-store.cjs +228 -0
  164. package/extensions/browser/backend/browser-router.cjs +203 -0
  165. package/extensions/browser/backend/executable-discovery.cjs +248 -0
  166. package/extensions/browser/backend/farming-browser-client.cjs +116 -0
  167. package/extensions/browser/backend/index.cjs +32 -0
  168. package/extensions/browser/backend/managed-chromium-installer.cjs +833 -0
  169. package/extensions/browser/bin/farming-browser +16 -7
  170. package/extensions/computer/backend/agent-capability.cjs +72 -0
  171. package/extensions/computer/backend/computer-constants.cjs +59 -0
  172. package/extensions/computer/backend/computer-mcp-server.cjs +182 -0
  173. package/extensions/computer/backend/computer-resource-manager.cjs +1219 -0
  174. package/extensions/computer/backend/computer-resource-store.cjs +190 -0
  175. package/extensions/computer/backend/computer-router.cjs +257 -0
  176. package/extensions/computer/backend/cua-tools.json +3067 -0
  177. package/extensions/computer/backend/farming-computer-client.cjs +84 -0
  178. package/extensions/computer/backend/index.cjs +35 -0
  179. package/extensions/computer/backend/isolated-browser-provider.cjs +157 -0
  180. package/extensions/computer/bin/farming-computer +131 -0
  181. package/frontend/farming-net/app.js +255 -262
  182. package/frontend/ghostty-loader.js +24 -20
  183. package/frontend/reading-anchor.js +210 -193
  184. package/frontend/runtime-paths.js +24 -26
  185. package/frontend/session-bridge.js +90 -111
  186. package/frontend/session-modal-bridge.js +184 -302
  187. package/frontend/skin-bridge.js +20 -23
  188. package/frontend/skins/crt/app.js +7686 -7901
  189. package/frontend/skins/crt/effects.js +7 -6
  190. package/frontend/skins/crt/index.html +6 -6
  191. package/frontend/skins/crt/styles/markdown.css +4 -4
  192. package/frontend/terminal-bridge.js +174 -181
  193. package/frontend/terminal-replay.js +320 -345
  194. package/frontend/theme-loader.js +55 -71
  195. package/package.json +64 -37
  196. package/shared/backend-connection-status.js +38 -69
  197. package/shared/browser-protocol.js +235 -110
  198. package/shared/websocket-liveness.js +40 -0
  199. package/backend/acp/packaged-claude-acp.js +0 -13
  200. package/backend/acp/packaged-codex-acp.js +0 -13
  201. package/backend/acp/patch-decisions.js +0 -153
  202. package/backend/acp/permission-security.js +0 -108
  203. package/backend/acp-session-state.js +0 -634
  204. package/backend/acp-transcript.js +0 -512
  205. package/backend/agent-env.js +0 -250
  206. package/backend/agent-json-stream.js +0 -268
  207. package/backend/agent-lifecycle-journal.js +0 -133
  208. package/backend/agent-order.js +0 -166
  209. package/backend/agent-provider-session.js +0 -76
  210. package/backend/agent-runtime-binding.js +0 -174
  211. package/backend/agent-session-history.js +0 -986
  212. package/backend/async-cache.js +0 -94
  213. package/backend/atomic-json-store.js +0 -37
  214. package/backend/auth.js +0 -251
  215. package/backend/chat-runtime.js +0 -28
  216. package/backend/claude-settings.js +0 -121
  217. package/backend/cli-agents.js +0 -486
  218. package/backend/codex-context-window.js +0 -189
  219. package/backend/codex-models.js +0 -226
  220. package/backend/codex-session-archive.js +0 -65
  221. package/backend/codex-session-history.js +0 -647
  222. package/backend/codex-transcript-sanitizer.js +0 -115
  223. package/backend/codex-transcript.js +0 -2362
  224. package/backend/command-runner-child.js +0 -67
  225. package/backend/config-manager.js +0 -1117
  226. package/backend/control-api.js +0 -455
  227. package/backend/executable-discovery.js +0 -216
  228. package/backend/farming-agent-bootstrap.js +0 -49
  229. package/backend/farming-cli.js +0 -403
  230. package/backend/farming-net-pass.js +0 -285
  231. package/backend/farming-net-registry.js +0 -112
  232. package/backend/farming-net-server.js +0 -298
  233. package/backend/farming-session-store.js +0 -677
  234. package/backend/git-worktree-info.js +0 -181
  235. package/backend/haiku-token.js +0 -772
  236. package/backend/index-html.js +0 -80
  237. package/backend/input-parts.js +0 -54
  238. package/backend/input-routing.js +0 -24
  239. package/backend/json-cli-runtime.js +0 -275
  240. package/backend/main-agent-skills.js +0 -288
  241. package/backend/main-page-session.js +0 -122
  242. package/backend/native-pty-controller-generation.js +0 -106
  243. package/backend/native-pty-host-identity.js +0 -86
  244. package/backend/native-pty-host-path.js +0 -42
  245. package/backend/native-session-engine.js +0 -268
  246. package/backend/network.js +0 -23
  247. package/backend/npm-update-helper.js +0 -374
  248. package/backend/packaged-node-pty.js +0 -99
  249. package/backend/preview-session-manager.js +0 -68
  250. package/backend/provider-adapters.js +0 -399
  251. package/backend/provider-session-id.js +0 -47
  252. package/backend/provider-session-service.js +0 -345
  253. package/backend/qr-share-tickets.js +0 -100
  254. package/backend/review-diff-router.js +0 -180
  255. package/backend/review-diff-service.js +0 -1270
  256. package/backend/review-session-router.js +0 -74
  257. package/backend/review-session-service.js +0 -446
  258. package/backend/review-session-store.js +0 -151
  259. package/backend/review-state-router.js +0 -116
  260. package/backend/review-state-store.js +0 -286
  261. package/backend/run-history-store.js +0 -67
  262. package/backend/runtime-dependency-manager.js +0 -759
  263. package/backend/runtime-executable-invocation.js +0 -20
  264. package/backend/runtime-observation.js +0 -81
  265. package/backend/server-process-identity.js +0 -47
  266. package/backend/server.js +0 -3225
  267. package/backend/session-engine-bridge.js +0 -129
  268. package/backend/session-engine-router.js +0 -66
  269. package/backend/session-engine.js +0 -39
  270. package/backend/session-stream-protocol.js +0 -185
  271. package/backend/shell-busy-integration.js +0 -472
  272. package/backend/slash-command-discovery.js +0 -433
  273. package/backend/storage-layout.js +0 -205
  274. package/backend/system-monitor.js +0 -77
  275. package/backend/terminal-attach-checkpoint.js +0 -74
  276. package/backend/terminal-exit-quiescence.js +0 -39
  277. package/backend/terminal-runtime-cleanup.js +0 -80
  278. package/backend/terminal-screen-worker.js +0 -337
  279. package/backend/terminal-state-serialization.js +0 -127
  280. package/backend/theme-manager.js +0 -163
  281. package/backend/usage-forecast.js +0 -86
  282. package/backend/usage-history-scanner.ts +0 -2718
  283. package/backend/usage-history-smoke.js +0 -64
  284. package/backend/usage-history-worker.js +0 -34
  285. package/backend/workspace-directory.js +0 -232
  286. package/backend/workspace-discovery.js +0 -311
  287. package/backend/workspace-root-registry.js +0 -166
  288. package/dist/assets/App-BKNUILuL.css +0 -1
  289. package/dist/assets/App-Z1N7T0eM.js +0 -695
  290. package/dist/assets/FileEditorPane-CNtuGjQ3.js +0 -2
  291. package/dist/assets/IconGlyphs-BClgag6E.js +0 -1
  292. package/dist/assets/ProjectFilesSection-K3GHuQ4U.js +0 -12
  293. package/dist/assets/ReviewPage-BRuxFaH5.js +0 -3
  294. package/dist/assets/code-dark-kLsQLvpf.css +0 -1
  295. package/dist/assets/file-icons-BOlcJ0ZF.js +0 -1
  296. package/dist/assets/main-DUTz-Rd2.css +0 -1
  297. package/dist/assets/review-BcnwQtJv.css +0 -1
  298. package/dist/assets/workspace-editor-model-CSGCl21x.js +0 -1
  299. package/dist/assets/workspace-editor-monaco-CJNwbpCy.js +0 -4
  300. package/dist/assets/workspace-editor-monaco-CO9w8YV0.js +0 -1
  301. package/dist/assets/workspace-view-state-BjKPYp0E.js +0 -7
  302. package/extensions/browser/backend/agent-browser-runtime.js +0 -1041
  303. package/extensions/browser/backend/agent-capability.js +0 -55
  304. package/extensions/browser/backend/browser-mcp-server.js +0 -621
  305. package/extensions/browser/backend/browser-resource-manager.js +0 -1331
  306. package/extensions/browser/backend/browser-resource-store.js +0 -190
  307. package/extensions/browser/backend/browser-router.js +0 -141
  308. package/extensions/browser/backend/executable-discovery.js +0 -238
  309. package/extensions/browser/backend/farming-browser-client.js +0 -83
  310. package/extensions/browser/backend/index.js +0 -7
  311. package/extensions/browser/backend/managed-chromium-installer.js +0 -593
  312. package/extensions/browser/frontend/BrowserSidebarPortals.tsx +0 -360
  313. package/extensions/browser/frontend/BrowserViewer.tsx +0 -500
  314. package/extensions/browser/frontend/browser-resource-state.ts +0 -60
  315. package/extensions/browser/frontend/browser.css +0 -567
  316. package/extensions/browser/frontend/types.ts +0 -38
  317. package/extensions/browser/frontend/useBrowserResources.ts +0 -166
  318. package/frontend/vendor/ghostty-web/index.d.ts +0 -1842
  319. package/shared/backend-connection-status.d.ts +0 -37
  320. package/shared/browser-protocol.d.ts +0 -5
  321. /package/dist/assets/{api-w2x5QfxB.js → api-ByCV9MEr.js} +0 -0
  322. /package/dist/assets/{core-vPkV8P_m.js → core-Czwdx12k.js} +0 -0
  323. /package/dist/assets/{fsharp-DNZNZyEE.js → fsharp-BjPpkoJe.js} +0 -0
  324. /package/dist/assets/{go-_kPJjNc_.js → go-BkIDmSUP.js} +0 -0
  325. /package/dist/assets/{graphql-4HCNVt5g.js → graphql-CCJTpqi1.js} +0 -0
  326. /package/dist/assets/{hcl-C87ymY0o.js → hcl-s4z8lUFg.js} +0 -0
  327. /package/dist/assets/{ini-BYrrGNTc.js → ini-CyUW1I7Z.js} +0 -0
  328. /package/dist/assets/{java-B211rJbk.js → java-CFCcGRiM.js} +0 -0
  329. /package/dist/assets/{julia-DVPsRtBm.js → julia-DQyH_EYb.js} +0 -0
  330. /package/dist/assets/{kotlin-BYyNerjp.js → kotlin-B8hA5O51.js} +0 -0
  331. /package/dist/assets/{less-EC9UblGE.js → less-DaVdaas0.js} +0 -0
  332. /package/dist/assets/{lexon-B1yuUdqW.js → lexon-DLBhPd3y.js} +0 -0
  333. /package/dist/assets/{lua-Bo6GFzxT.js → lua-gB1c_cif.js} +0 -0
  334. /package/dist/assets/{m3-C-Y9cBVI.js → m3-C2T3z3gB.js} +0 -0
  335. /package/dist/assets/{markdown-BHu-wLbe.js → markdown-CKq-Euj1.js} +0 -0
  336. /package/dist/assets/{mips-Dkds26rX.js → mips-Bcs5qIDX.js} +0 -0
  337. /package/dist/assets/{msdax-PU4g-8_g.js → msdax-CBP48FHF.js} +0 -0
  338. /package/dist/assets/{mysql-fPpuGpS7.js → mysql-c7tiPcFj.js} +0 -0
  339. /package/dist/assets/{objective-c-Wy1e5JUf.js → objective-c-D4BZkeEV.js} +0 -0
  340. /package/dist/assets/{pascal-BIXwvrqU.js → pascal-CJDZg0MN.js} +0 -0
  341. /package/dist/assets/{pascaligo-DwR0AtL_.js → pascaligo-Bygi8Ynl.js} +0 -0
  342. /package/dist/assets/{perl-CGHAl8my.js → perl-aS8bkf7E.js} +0 -0
  343. /package/dist/assets/{pgsql-B91M73E2.js → pgsql-CzNAYFYl.js} +0 -0
  344. /package/dist/assets/{php-C70ttrCx.js → php-DOtoEFTT.js} +0 -0
  345. /package/dist/assets/{pla-BNrXaRh0.js → pla-DugRnao1.js} +0 -0
  346. /package/dist/assets/{postiats-Dv2IAZR9.js → postiats-DsXwusKh.js} +0 -0
  347. /package/dist/assets/{powerquery-CkY5Wq7J.js → powerquery-DL3o72oD.js} +0 -0
  348. /package/dist/assets/{powershell-uGIYLU3C.js → powershell-C1qHekys.js} +0 -0
  349. /package/dist/assets/{protobuf-CavfmJu-.js → protobuf-DHgsc-cH.js} +0 -0
  350. /package/dist/assets/{pug-Drqnyitx.js → pug-FZXlE_Iu.js} +0 -0
  351. /package/dist/assets/{qrcode-7uGsTEmi.js → qrcode-DJDTdjL7.js} +0 -0
  352. /package/dist/assets/{qsharp-C7yF-Dti.js → qsharp-bLyhI3DT.js} +0 -0
  353. /package/dist/assets/{r-HXLGP0_-.js → r-DjFGXbAa.js} +0 -0
  354. /package/dist/assets/{redis-C4y6mf2p.js → redis-DSoZ_V6u.js} +0 -0
  355. /package/dist/assets/{redshift-DdQrFPrv.js → redshift-CzkdCsrg.js} +0 -0
  356. /package/dist/assets/{restructuredtext-CBrf2PNj.js → restructuredtext-B_XPrGCQ.js} +0 -0
  357. /package/dist/assets/{ruby-CVtMoX2B.js → ruby-Cry2RneJ.js} +0 -0
  358. /package/dist/assets/{rust-Ckq4sbMP.js → rust-CWzdbFq1.js} +0 -0
  359. /package/dist/assets/{sb-er66OpE3.js → sb-DmofU59h.js} +0 -0
  360. /package/dist/assets/{scala-BdWZz-hH.js → scala-BUC2l-vN.js} +0 -0
  361. /package/dist/assets/{scheme-kTV_s2kP.js → scheme-CNIB_72f.js} +0 -0
  362. /package/dist/assets/{scss-Bymy2VJQ.js → scss-DcL4-NbX.js} +0 -0
  363. /package/dist/assets/{shell-bwEP1LQ1.js → shell-CgAGvSSA.js} +0 -0
  364. /package/dist/assets/{solidity-DCddeBgL.js → solidity-DSkt6O_P.js} +0 -0
  365. /package/dist/assets/{sophia-BMN3AQig.js → sophia--5ytcjDN.js} +0 -0
  366. /package/dist/assets/{sparql-CSXOLjzi.js → sparql-C1Srr7cD.js} +0 -0
  367. /package/dist/assets/{sql-COg8ewmK.js → sql-2k_O5fj7.js} +0 -0
  368. /package/dist/assets/{st-CIaZtBS_.js → st-DCCCPqfz.js} +0 -0
  369. /package/dist/assets/{swift-DXiOhUHu.js → swift-Dd8mAfOt.js} +0 -0
  370. /package/dist/assets/{systemverilog-BTDE6Dr2.js → systemverilog-B0-aZYXu.js} +0 -0
  371. /package/dist/assets/{tcl-B0zy9NvV.js → tcl-CZAZwPVX.js} +0 -0
  372. /package/dist/assets/{twig-D594l4Z1.js → twig-D-Ag0tdS.js} +0 -0
  373. /package/dist/assets/{typespec-XKVjaPqo.js → typespec-B7kTFp0Z.js} +0 -0
  374. /package/dist/assets/{useWorkspaceMenuKeyboard-Bpy_s69Z.js → useWorkspaceMenuKeyboard-uYZpDxhU.js} +0 -0
  375. /package/dist/assets/{vb-B2wYoKRV.js → vb-20w1JPum.js} +0 -0
  376. /package/dist/assets/{wgsl-D0Yf2LbK.js → wgsl-CLJfqFt0.js} +0 -0
  377. /package/dist/assets/{workspace-working-copy-C3FSR3N6.js → workspace-working-copy-Cfz07cOd.js} +0 -0
@@ -0,0 +1,1022 @@
1
+ // Generated by scripts/build-backend-runtime.ts. Do not edit.
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+ var agent_session_history_exports = {};
31
+ __export(agent_session_history_exports, {
32
+ buildAgentSessionResumeCommand: () => buildAgentSessionResumeCommand,
33
+ compareAgentSessions: () => compareAgentSessions,
34
+ findAgentSession: () => findAgentSession,
35
+ hasTemporaryWorkspaceReference: () => import_codex_session_history.hasTemporaryWorkspaceReference,
36
+ isAgentManagedWorktree: () => isAgentManagedWorktree,
37
+ isDefaultClaudeSessionTitle: () => isDefaultClaudeSessionTitle,
38
+ isSafeSessionId: () => isSafeSessionId,
39
+ isTemporaryWorkspace: () => import_codex_session_history.isTemporaryWorkspace,
40
+ isVisibleAgentSession: () => isVisibleAgentSession,
41
+ listAgentSessions: () => listAgentSessions,
42
+ listClaudeSessions: () => listClaudeSessions,
43
+ listOpenCodeSessions: () => listOpenCodeSessions,
44
+ listQoderSessions: () => listQoderSessions,
45
+ listQwenSessions: () => listQwenSessions,
46
+ normalizeProvider: () => normalizeProvider,
47
+ paginateAgentSessions: () => paginateAgentSessions,
48
+ resolveCodexResumeModelProvider: () => resolveCodexResumeModelProvider,
49
+ searchAgentSessions: () => searchAgentSessions
50
+ });
51
+ module.exports = __toCommonJS(agent_session_history_exports);
52
+ var import_child_process = require("child_process");
53
+ var fs = __toESM(require("fs"));
54
+ var fsp = __toESM(require("fs/promises"));
55
+ var os = __toESM(require("os"));
56
+ var path = __toESM(require("path"));
57
+ var readline = __toESM(require("readline"));
58
+ var import_codex_session_history = require("./codex-session-history.cjs");
59
+ var import_provider_session_id = require("./provider-session-id.cjs");
60
+ const DEFAULT_LIMIT = 60;
61
+ const DEFAULT_SCAN_LIMIT = 500;
62
+ const MAX_AGENT_SESSION_HISTORY_LIMIT = 5e3;
63
+ const MAX_AGENT_SESSION_SCAN_LIMIT = 5e3;
64
+ const CLAUDE_HISTORY_TAIL_BYTES = 2 * 1024 * 1024;
65
+ const QODER_HISTORY_TAIL_BYTES = 2 * 1024 * 1024;
66
+ const QWEN_HISTORY_TAIL_BYTES = 2 * 1024 * 1024;
67
+ const MAX_RECENT_FILE_SCAN_DIRECTORIES = 2e3;
68
+ const PROVIDERS = /* @__PURE__ */ new Set(["codex", "claude", "opencode", "qoder", "qwen"]);
69
+ function isHistoryRecord(value) {
70
+ return typeof value === "object" && value !== null;
71
+ }
72
+ function isAgentProvider(value) {
73
+ return PROVIDERS.has(value);
74
+ }
75
+ function quoteCommandArg(value) {
76
+ return `'${String(value).replace(/'/g, `'\\''`)}'`;
77
+ }
78
+ function tomlStringAssignment(line, key) {
79
+ const match = String(line || "").match(new RegExp(`^\\s*${key}\\s*=\\s*("(?:[^"\\\\]|\\\\.)*"|'[^']*')\\s*(?:#.*)?$`));
80
+ if (!match) return "";
81
+ const literal = match[1];
82
+ if (literal.startsWith('"')) {
83
+ try {
84
+ return JSON.parse(literal).trim();
85
+ } catch {
86
+ return "";
87
+ }
88
+ }
89
+ return literal.slice(1, -1).trim();
90
+ }
91
+ function codexProfileNameForSection(section) {
92
+ const match = String(section || "").trim().match(/^profiles\.(?:"([^"]+)"|'([^']+)'|([A-Za-z0-9_-]+))$/);
93
+ return match ? match[1] || match[2] || match[3] || "" : "";
94
+ }
95
+ function resolveCodexResumeModelProvider(codexHome) {
96
+ const home = normalizePathValue(codexHome) || normalizePathValue(process.env.CODEX_HOME) || path.join(os.homedir(), ".codex");
97
+ let config = "";
98
+ try {
99
+ config = fs.readFileSync(path.join(home, "config.toml"), "utf8");
100
+ } catch {
101
+ return "openai";
102
+ }
103
+ let section = "";
104
+ let activeProfile = "";
105
+ let topLevelProvider = "";
106
+ const profileProviders = /* @__PURE__ */ new Map();
107
+ for (const line of config.split(/\r?\n/)) {
108
+ const sectionMatch = line.match(/^\s*\[([^\]]+)]\s*(?:#.*)?$/);
109
+ if (sectionMatch) {
110
+ section = sectionMatch[1].trim();
111
+ continue;
112
+ }
113
+ if (!section) {
114
+ activeProfile = tomlStringAssignment(line, "profile") || activeProfile;
115
+ topLevelProvider = tomlStringAssignment(line, "model_provider") || topLevelProvider;
116
+ continue;
117
+ }
118
+ const profileName = codexProfileNameForSection(section);
119
+ if (profileName) {
120
+ const provider = tomlStringAssignment(line, "model_provider");
121
+ if (provider) profileProviders.set(profileName, provider);
122
+ }
123
+ }
124
+ return activeProfile && profileProviders.get(activeProfile) || topLevelProvider || "openai";
125
+ }
126
+ function normalizePathValue(value) {
127
+ if (typeof value !== "string") return "";
128
+ const trimmed = value.trim();
129
+ if (!trimmed || trimmed === path.sep) return trimmed;
130
+ return trimmed.replace(/[\\/]+$/, "");
131
+ }
132
+ function timestampMs(value) {
133
+ const parsed = Date.parse(String(value || ""));
134
+ return Number.isFinite(parsed) ? parsed : 0;
135
+ }
136
+ function agentSessionIdentity(session) {
137
+ return [
138
+ String(session?.provider || ""),
139
+ String(session?.providerHomeId || "default"),
140
+ String(session?.id || "")
141
+ ].join("\0");
142
+ }
143
+ function compareAgentSessions(a, b) {
144
+ const timeDelta = timestampMs(b?.updatedAt || b?.createdAt) - timestampMs(a?.updatedAt || a?.createdAt);
145
+ return timeDelta || agentSessionIdentity(a).localeCompare(agentSessionIdentity(b));
146
+ }
147
+ function dedupeAgentSessions(sessions) {
148
+ const sessionsByIdentity = /* @__PURE__ */ new Map();
149
+ for (const session of sessions) {
150
+ const identity = agentSessionIdentity(session);
151
+ const current = sessionsByIdentity.get(identity);
152
+ if (!current || timestampMs(session?.updatedAt || session?.createdAt) > timestampMs(current?.updatedAt || current?.createdAt)) {
153
+ sessionsByIdentity.set(identity, session);
154
+ }
155
+ }
156
+ return Array.from(sessionsByIdentity.values());
157
+ }
158
+ function encodeAgentSessionCursor(session) {
159
+ if (!session?.provider || !session?.id) return "";
160
+ return Buffer.from(JSON.stringify({
161
+ version: 1,
162
+ provider: String(session.provider),
163
+ providerHomeId: String(session.providerHomeId || "default"),
164
+ id: String(session.id),
165
+ updatedAt: String(session.updatedAt || session.createdAt || "")
166
+ })).toString("base64url");
167
+ }
168
+ function decodeAgentSessionCursor(value) {
169
+ try {
170
+ const parsed = JSON.parse(Buffer.from(String(value || ""), "base64url").toString("utf8"));
171
+ if (parsed?.version !== 1 || !parsed.provider || !parsed.id) return null;
172
+ return {
173
+ provider: String(parsed.provider),
174
+ providerHomeId: String(parsed.providerHomeId || "default"),
175
+ id: String(parsed.id),
176
+ updatedAt: String(parsed.updatedAt || "")
177
+ };
178
+ } catch {
179
+ return null;
180
+ }
181
+ }
182
+ function paginateAgentSessions(sessions, options = {}) {
183
+ const limit = typeof options.limit === "number" && Number.isFinite(options.limit) ? Math.max(1, Math.min(MAX_AGENT_SESSION_HISTORY_LIMIT, Math.floor(options.limit))) : DEFAULT_LIMIT;
184
+ const cursorValue = String(options.cursor || "").trim();
185
+ let start = 0;
186
+ if (cursorValue) {
187
+ const cursor = decodeAgentSessionCursor(cursorValue);
188
+ if (!cursor) return { sessions: [], nextCursor: "", hasMore: false, invalidCursor: true };
189
+ const exactIndex = sessions.findIndex((session) => agentSessionIdentity(session) === agentSessionIdentity(cursor) && String(session.updatedAt || session.createdAt || "") === cursor.updatedAt);
190
+ if (exactIndex >= 0) {
191
+ start = exactIndex + 1;
192
+ } else {
193
+ const nextIndex = sessions.findIndex((session) => compareAgentSessions(session, cursor) > 0);
194
+ start = nextIndex >= 0 ? nextIndex : sessions.length;
195
+ }
196
+ }
197
+ const page = sessions.slice(start, start + limit);
198
+ const hasMore = start + page.length < sessions.length;
199
+ return {
200
+ sessions: page,
201
+ nextCursor: hasMore && page.length > 0 ? encodeAgentSessionCursor(page[page.length - 1]) : "",
202
+ hasMore,
203
+ invalidCursor: false
204
+ };
205
+ }
206
+ function searchAgentSessions(sessions, query, options = {}) {
207
+ const normalizedQuery = String(query || "").trim().toLowerCase();
208
+ const limit = typeof options.limit === "number" && Number.isFinite(options.limit) ? Math.max(1, Math.min(MAX_AGENT_SESSION_HISTORY_LIMIT, Math.floor(options.limit))) : DEFAULT_LIMIT;
209
+ if (!normalizedQuery) {
210
+ return { sessions: [], total: 0, query: "", scope: "id-title-project" };
211
+ }
212
+ const projectNames = options.projectNames && typeof options.projectNames === "object" ? options.projectNames : {};
213
+ const matches = sessions.filter((session) => {
214
+ const projectPaths = [session?.workspace, session?.cwd];
215
+ return [
216
+ session?.id,
217
+ session?.title,
218
+ ...projectPaths,
219
+ ...projectPaths.map((workspace) => projectNames[String(workspace || "")])
220
+ ].some((value) => String(value || "").toLowerCase().includes(normalizedQuery));
221
+ });
222
+ return {
223
+ sessions: matches.slice(0, limit),
224
+ total: matches.length,
225
+ query: normalizedQuery,
226
+ scope: "id-title-project"
227
+ };
228
+ }
229
+ function isAgentManagedWorktree(workspace) {
230
+ const value = normalizePathValue(workspace);
231
+ return value.includes(`${path.sep}.codex${path.sep}worktrees${path.sep}`) || value.includes(`${path.sep}.claude${path.sep}worktrees${path.sep}`);
232
+ }
233
+ function isDefaultClaudeSessionTitle(title) {
234
+ return String(title || "").trim().toLowerCase() === "claude session";
235
+ }
236
+ function firstTrimmedString(...values) {
237
+ for (const value of values) {
238
+ if (typeof value !== "string") continue;
239
+ const trimmed = value.trim();
240
+ if (trimmed) return trimmed;
241
+ }
242
+ return "";
243
+ }
244
+ function extractClaudeModel(event) {
245
+ return firstTrimmedString(
246
+ event?.model,
247
+ event?.message?.model,
248
+ event?.metadata?.model,
249
+ event?.message?.metadata?.model,
250
+ event?.request?.model,
251
+ event?.options?.model
252
+ );
253
+ }
254
+ function extractClaudeEffort(event) {
255
+ return firstTrimmedString(
256
+ event?.effort,
257
+ event?.message?.effort,
258
+ event?.metadata?.effort,
259
+ event?.message?.metadata?.effort,
260
+ event?.request?.effort,
261
+ event?.options?.effort
262
+ );
263
+ }
264
+ function extractQoderModel(event) {
265
+ return firstTrimmedString(
266
+ event?.model,
267
+ event?.message?.model,
268
+ event?.metadata?.model,
269
+ event?.message?.metadata?.model
270
+ );
271
+ }
272
+ function extractQoderEffort(event) {
273
+ return firstTrimmedString(
274
+ event?.reasoningEffort,
275
+ event?.reasoning_effort,
276
+ event?.effort,
277
+ event?.metadata?.reasoningEffort,
278
+ event?.metadata?.reasoning_effort,
279
+ event?.message?.metadata?.reasoningEffort,
280
+ event?.message?.metadata?.reasoning_effort
281
+ );
282
+ }
283
+ function isoTimestamp(value) {
284
+ if (typeof value === "string") {
285
+ const parsed = Date.parse(value);
286
+ return Number.isFinite(parsed) ? new Date(parsed).toISOString() : "";
287
+ }
288
+ if (typeof value === "number" && Number.isFinite(value) && value > 0) {
289
+ try {
290
+ const date = new Date(value);
291
+ return Number.isFinite(date.getTime()) ? date.toISOString() : "";
292
+ } catch {
293
+ return "";
294
+ }
295
+ }
296
+ return "";
297
+ }
298
+ function qoderTextFromMessage(message) {
299
+ if (typeof message === "string") return message.trim();
300
+ if (!isHistoryRecord(message)) return "";
301
+ const content = message.content;
302
+ if (typeof content === "string") return content.trim();
303
+ if (!Array.isArray(content)) return "";
304
+ return content.map((part) => {
305
+ if (typeof part === "string") return part;
306
+ if (!isHistoryRecord(part)) return "";
307
+ if (typeof part.text === "string") return part.text;
308
+ if (typeof part.content === "string") return part.content;
309
+ return "";
310
+ }).join("\n").trim();
311
+ }
312
+ function qwenTextFromMessage(message) {
313
+ if (typeof message === "string") return message.trim();
314
+ if (!isHistoryRecord(message)) return "";
315
+ const parts = Array.isArray(message.parts) ? message.parts : Array.isArray(message.content) ? message.content : [];
316
+ return parts.map((part) => {
317
+ if (typeof part === "string") return part;
318
+ if (!isHistoryRecord(part)) return "";
319
+ return typeof part.text === "string" ? part.text : "";
320
+ }).join("\n").trim();
321
+ }
322
+ function isVisibleAgentSession(session) {
323
+ const provider = String(session?.provider || "").trim().toLowerCase();
324
+ if (provider === "claude") {
325
+ if (isDefaultClaudeSessionTitle(session?.title)) return false;
326
+ if (isAgentManagedWorktree(session?.cwd) || isAgentManagedWorktree(session?.workspace)) return false;
327
+ }
328
+ return !(0, import_codex_session_history.isTemporaryWorkspace)(session?.cwd) && !(0, import_codex_session_history.isTemporaryWorkspace)(session?.workspace) && !(0, import_codex_session_history.hasTemporaryWorkspaceReference)(session?.title);
329
+ }
330
+ function activeScheduleFromMetadata(value, sessionId = "") {
331
+ if (!value || typeof value !== "object") return null;
332
+ const rrule = typeof value.rrule === "string" ? value.rrule.trim() : "";
333
+ if (!rrule) return null;
334
+ const targetThreadId = typeof value.target_thread_id === "string" ? value.target_thread_id.trim() : typeof value.targetThreadId === "string" ? value.targetThreadId.trim() : "";
335
+ if (targetThreadId && sessionId && targetThreadId !== sessionId) return null;
336
+ const rawStatus = typeof value.status === "string" ? value.status.trim().toUpperCase() : "";
337
+ const enabled = value.enabled !== false && value.active !== false;
338
+ if (rawStatus && !["ACTIVE", "ENABLED"].includes(rawStatus)) return null;
339
+ if (!enabled) return null;
340
+ return {
341
+ id: typeof value.id === "string" ? value.id.trim() : "",
342
+ kind: typeof value.kind === "string" ? value.kind.trim() : "",
343
+ name: typeof value.name === "string" ? value.name.trim() : "",
344
+ status: rawStatus || "ACTIVE",
345
+ rrule,
346
+ label: (0, import_codex_session_history.formatAutomationRRuleLabel)(rrule)
347
+ };
348
+ }
349
+ function scheduleFromClaudeEvent(event, sessionId) {
350
+ const candidates = [
351
+ event?.automation,
352
+ event?.schedule,
353
+ event?.metadata?.automation,
354
+ event?.metadata?.schedule,
355
+ event?.message?.metadata?.automation,
356
+ event?.message?.metadata?.schedule
357
+ ];
358
+ for (const candidate of candidates) {
359
+ const schedule = activeScheduleFromMetadata(candidate, sessionId);
360
+ if (schedule) return schedule;
361
+ }
362
+ return null;
363
+ }
364
+ async function collectRecentFiles(root, extension, limit, acceptFile = () => true, descendDirectory = () => true) {
365
+ const directories = [root];
366
+ let files = [];
367
+ let visitedDirectories = 0;
368
+ while (directories.length > 0 && visitedDirectories < MAX_RECENT_FILE_SCAN_DIRECTORIES) {
369
+ const directory = directories.pop();
370
+ if (!directory) continue;
371
+ let entries = [];
372
+ try {
373
+ entries = await fsp.readdir(directory, { withFileTypes: true });
374
+ } catch {
375
+ continue;
376
+ }
377
+ visitedDirectories += 1;
378
+ entries.sort((a, b) => {
379
+ if (a.isDirectory() !== b.isDirectory()) return a.isDirectory() ? -1 : 1;
380
+ return a.name.localeCompare(b.name);
381
+ });
382
+ for (const entry of entries) {
383
+ const fullPath = path.join(directory, entry.name);
384
+ if (entry.isDirectory()) {
385
+ if (descendDirectory(fullPath)) directories.push(fullPath);
386
+ } else if (entry.isFile() && entry.name.endsWith(extension) && acceptFile(fullPath)) {
387
+ let mtimeMs = 0;
388
+ try {
389
+ mtimeMs = (await fsp.stat(fullPath)).mtimeMs;
390
+ } catch {
391
+ mtimeMs = 0;
392
+ }
393
+ files.push({ filePath: fullPath, mtimeMs });
394
+ if (files.length > limit * 2) {
395
+ files = files.sort((a, b) => b.mtimeMs - a.mtimeMs).slice(0, limit);
396
+ }
397
+ }
398
+ }
399
+ }
400
+ return files.sort((a, b) => b.mtimeMs - a.mtimeMs).slice(0, limit);
401
+ }
402
+ async function readTextTail(filePath, maxBytes) {
403
+ let handle = null;
404
+ try {
405
+ const stat = await fsp.stat(filePath);
406
+ const start = Math.max(0, stat.size - maxBytes);
407
+ const length = stat.size - start;
408
+ const buffer = Buffer.alloc(length);
409
+ handle = await fsp.open(filePath, "r");
410
+ await handle.read(buffer, 0, length, start);
411
+ const text = buffer.toString("utf8");
412
+ return start > 0 ? text.replace(/^[^\n]*(\n|$)/, "") : text;
413
+ } catch {
414
+ return "";
415
+ } finally {
416
+ if (handle) {
417
+ await handle.close().catch(() => {
418
+ });
419
+ }
420
+ }
421
+ }
422
+ async function readClaudePromptHistory(claudeHome) {
423
+ const historyPath = path.join(claudeHome, "history.jsonl");
424
+ const entries = /* @__PURE__ */ new Map();
425
+ const lines = (await readTextTail(historyPath, CLAUDE_HISTORY_TAIL_BYTES)).split("\n").filter(Boolean);
426
+ for (const line of lines) {
427
+ try {
428
+ const entry = JSON.parse(line);
429
+ if (!entry || typeof entry.sessionId !== "string") continue;
430
+ entries.set(entry.sessionId, {
431
+ title: typeof entry.display === "string" ? entry.display.trim() : "",
432
+ workspace: typeof entry.project === "string" ? normalizePathValue(entry.project) : "",
433
+ updatedAt: typeof entry.timestamp === "string" ? entry.timestamp : ""
434
+ });
435
+ } catch {
436
+ }
437
+ }
438
+ return entries;
439
+ }
440
+ function claudeSessionIdFromFilePath(filePath) {
441
+ const match = path.basename(filePath).match(/^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i);
442
+ return match ? match[1] : "";
443
+ }
444
+ async function readClaudeSessionMetadata(filePath, promptHistory, maxLines = 160) {
445
+ const stream = fs.createReadStream(filePath, { encoding: "utf8" });
446
+ const reader = readline.createInterface({ input: stream, crlfDelay: Infinity });
447
+ const fileSessionId = claudeSessionIdFromFilePath(filePath);
448
+ const metadata = {
449
+ filePath,
450
+ id: fileSessionId,
451
+ title: "",
452
+ cwd: "",
453
+ workspace: "",
454
+ createdAt: "",
455
+ updatedAt: "",
456
+ model: "",
457
+ effort: "",
458
+ source: "",
459
+ schedule: null
460
+ };
461
+ let lineCount = 0;
462
+ try {
463
+ for await (const line of reader) {
464
+ if (!line) continue;
465
+ lineCount += 1;
466
+ try {
467
+ const event = JSON.parse(line);
468
+ if (typeof event.sessionId === "string") {
469
+ metadata.id = event.sessionId;
470
+ }
471
+ if (typeof event.timestamp === "string") {
472
+ metadata.updatedAt = event.timestamp;
473
+ metadata.createdAt = metadata.createdAt || event.timestamp;
474
+ }
475
+ if (typeof event.cwd === "string" && event.cwd.trim()) {
476
+ metadata.cwd = normalizePathValue(event.cwd);
477
+ }
478
+ if (typeof event.entrypoint === "string" && event.entrypoint.trim()) {
479
+ metadata.source = event.entrypoint.trim();
480
+ }
481
+ if (event.type === "ai-title" && typeof event.aiTitle === "string" && event.aiTitle.trim()) {
482
+ metadata.title = event.aiTitle.trim();
483
+ }
484
+ metadata.model = extractClaudeModel(event) || metadata.model;
485
+ metadata.effort = extractClaudeEffort(event) || metadata.effort;
486
+ if (!metadata.schedule) {
487
+ metadata.schedule = scheduleFromClaudeEvent(event, metadata.id || fileSessionId);
488
+ }
489
+ } catch {
490
+ }
491
+ if (lineCount >= maxLines || metadata.id && metadata.title && metadata.cwd && metadata.model) {
492
+ break;
493
+ }
494
+ }
495
+ } finally {
496
+ reader.close();
497
+ stream.destroy();
498
+ }
499
+ if (!metadata.id) return null;
500
+ const indexed = promptHistory.get(metadata.id);
501
+ metadata.title = metadata.title || indexed?.title || "Claude session";
502
+ metadata.workspace = normalizePathValue(indexed?.workspace || metadata.cwd || "");
503
+ metadata.updatedAt = metadata.updatedAt || indexed?.updatedAt || "";
504
+ metadata.source = metadata.source || "claude";
505
+ return metadata;
506
+ }
507
+ async function listClaudeSessions(options = {}) {
508
+ const claudeHome = options.claudeHome || path.join(os.homedir(), ".claude");
509
+ const limit = typeof options.limit === "number" && Number.isFinite(options.limit) ? Math.max(0, Math.min(MAX_AGENT_SESSION_HISTORY_LIMIT, Math.floor(options.limit))) : DEFAULT_LIMIT;
510
+ const scanLimit = typeof options.scanLimit === "number" && Number.isFinite(options.scanLimit) ? Math.max(limit, Math.min(MAX_AGENT_SESSION_SCAN_LIMIT, Math.floor(options.scanLimit))) : DEFAULT_SCAN_LIMIT;
511
+ const promptHistory = await readClaudePromptHistory(claudeHome);
512
+ const projectsRoot = path.join(claudeHome, "projects");
513
+ const sessionFiles = await collectRecentFiles(
514
+ projectsRoot,
515
+ ".jsonl",
516
+ scanLimit,
517
+ (filePath) => path.relative(projectsRoot, filePath).split(path.sep).length === 2,
518
+ (directoryPath) => path.relative(projectsRoot, directoryPath).split(path.sep).length === 1
519
+ );
520
+ const sessions = [];
521
+ for (const { filePath, mtimeMs } of sessionFiles) {
522
+ const metadata = await readClaudeSessionMetadata(filePath, promptHistory);
523
+ if (!metadata) continue;
524
+ const mtimeIso = mtimeMs > 0 ? new Date(mtimeMs).toISOString() : "";
525
+ const updatedAt = timestampMs(mtimeIso) > timestampMs(metadata.updatedAt) ? mtimeIso : metadata.updatedAt || mtimeIso;
526
+ const session = {
527
+ provider: "claude",
528
+ providerName: "Claude",
529
+ id: metadata.id,
530
+ title: metadata.title,
531
+ cwd: metadata.cwd,
532
+ workspace: metadata.workspace,
533
+ updatedAt,
534
+ createdAt: metadata.createdAt,
535
+ archived: false,
536
+ pinned: false,
537
+ unread: false,
538
+ projectless: !metadata.workspace,
539
+ model: metadata.model,
540
+ effort: metadata.effort,
541
+ source: metadata.source,
542
+ schedule: metadata.schedule || void 0,
543
+ capabilities: ["resume", "fork"]
544
+ };
545
+ if (isVisibleAgentSession(session)) {
546
+ sessions.push(session);
547
+ }
548
+ }
549
+ return dedupeAgentSessions(sessions).sort((a, b) => timestampMs(b.updatedAt) - timestampMs(a.updatedAt)).slice(0, limit);
550
+ }
551
+ function qoderSessionIdFromFilePath(filePath) {
552
+ const match = path.basename(filePath).match(/^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i);
553
+ return match ? match[1] : "";
554
+ }
555
+ function applyQoderSessionEvent(metadata, event, fileSessionId) {
556
+ if (!event || typeof event !== "object") return;
557
+ const eventSessionId = typeof event.sessionId === "string" ? event.sessionId : typeof event.session_id === "string" ? event.session_id : "";
558
+ if (eventSessionId && (0, import_provider_session_id.isSafeProviderSessionId)(eventSessionId)) {
559
+ metadata.id = eventSessionId;
560
+ }
561
+ const timestamp = isoTimestamp(event.timestamp);
562
+ if (timestamp) {
563
+ metadata.updatedAt = timestamp;
564
+ metadata.createdAt = metadata.createdAt || timestamp;
565
+ }
566
+ if (typeof event.cwd === "string" && event.cwd.trim()) {
567
+ metadata.cwd = normalizePathValue(event.cwd);
568
+ }
569
+ if (typeof event.entrypoint === "string" && event.entrypoint.trim()) {
570
+ metadata.source = event.entrypoint.trim();
571
+ }
572
+ if (event.type === "system" && typeof event.qodercli_version === "string") {
573
+ metadata.cliVersion = event.qodercli_version.trim();
574
+ }
575
+ if (typeof event.version === "string" && event.version.trim()) {
576
+ metadata.cliVersion = event.version.trim();
577
+ }
578
+ if (event.type === "runtime-config" && typeof event.version === "string") {
579
+ metadata.cliVersion = event.version.trim();
580
+ }
581
+ if (event.type === "ai-title" && typeof event.aiTitle === "string" && event.aiTitle.trim()) {
582
+ metadata.title = event.aiTitle.trim();
583
+ }
584
+ if (event.type === "last-prompt" && typeof event.lastPrompt === "string" && event.lastPrompt.trim()) {
585
+ metadata.lastPrompt = event.lastPrompt.trim();
586
+ }
587
+ if (!metadata.firstPrompt && event.type === "user") {
588
+ metadata.firstPrompt = qoderTextFromMessage(event.message);
589
+ }
590
+ metadata.model = extractQoderModel(event) || metadata.model;
591
+ metadata.effort = extractQoderEffort(event) || metadata.effort;
592
+ if (!metadata.id && fileSessionId) {
593
+ metadata.id = fileSessionId;
594
+ }
595
+ }
596
+ async function readQoderSessionMetadata(filePath, maxLines = 160) {
597
+ const fileSessionId = qoderSessionIdFromFilePath(filePath);
598
+ const metadata = {
599
+ filePath,
600
+ id: fileSessionId,
601
+ title: "",
602
+ lastPrompt: "",
603
+ firstPrompt: "",
604
+ cwd: "",
605
+ workspace: "",
606
+ createdAt: "",
607
+ updatedAt: "",
608
+ model: "",
609
+ effort: "",
610
+ source: "",
611
+ cliVersion: ""
612
+ };
613
+ const stream = fs.createReadStream(filePath, { encoding: "utf8" });
614
+ const reader = readline.createInterface({ input: stream, crlfDelay: Infinity });
615
+ let lineCount = 0;
616
+ try {
617
+ for await (const line of reader) {
618
+ if (!line) continue;
619
+ lineCount += 1;
620
+ try {
621
+ applyQoderSessionEvent(metadata, JSON.parse(line), fileSessionId);
622
+ } catch {
623
+ }
624
+ if (lineCount >= maxLines || metadata.id && metadata.cwd && metadata.model && metadata.title) {
625
+ break;
626
+ }
627
+ }
628
+ } finally {
629
+ reader.close();
630
+ stream.destroy();
631
+ }
632
+ const tail = await readTextTail(filePath, QODER_HISTORY_TAIL_BYTES);
633
+ for (const line of tail.split("\n").filter(Boolean)) {
634
+ try {
635
+ applyQoderSessionEvent(metadata, JSON.parse(line), fileSessionId);
636
+ } catch {
637
+ }
638
+ }
639
+ if (!metadata.id || !(0, import_provider_session_id.isSafeProviderSessionId)(metadata.id)) return null;
640
+ metadata.title = firstTrimmedString(metadata.title, metadata.lastPrompt, metadata.firstPrompt, "Qoder session");
641
+ metadata.workspace = normalizePathValue(metadata.cwd || "");
642
+ metadata.source = metadata.source || "qodercli";
643
+ return metadata;
644
+ }
645
+ async function listQoderSessions(options = {}) {
646
+ const qoderHome = options.qoderHome || path.join(os.homedir(), ".qoder");
647
+ const limit = typeof options.limit === "number" && Number.isFinite(options.limit) ? Math.max(0, Math.min(MAX_AGENT_SESSION_HISTORY_LIMIT, Math.floor(options.limit))) : DEFAULT_LIMIT;
648
+ const scanLimit = typeof options.scanLimit === "number" && Number.isFinite(options.scanLimit) ? Math.max(limit, Math.min(MAX_AGENT_SESSION_SCAN_LIMIT, Math.floor(options.scanLimit))) : DEFAULT_SCAN_LIMIT;
649
+ const projectsRoot = path.join(qoderHome, "projects");
650
+ const sessionFiles = await collectRecentFiles(
651
+ projectsRoot,
652
+ ".jsonl",
653
+ scanLimit,
654
+ (filePath) => path.relative(projectsRoot, filePath).split(path.sep).length === 2,
655
+ (directoryPath) => path.relative(projectsRoot, directoryPath).split(path.sep).length === 1
656
+ );
657
+ const sessions = [];
658
+ for (const { filePath, mtimeMs } of sessionFiles) {
659
+ const metadata = await readQoderSessionMetadata(filePath);
660
+ if (!metadata) continue;
661
+ const mtimeIso = mtimeMs > 0 ? new Date(mtimeMs).toISOString() : "";
662
+ const updatedAt = timestampMs(mtimeIso) > timestampMs(metadata.updatedAt) ? mtimeIso : metadata.updatedAt || mtimeIso;
663
+ const session = {
664
+ provider: "qoder",
665
+ providerName: "Qoder",
666
+ id: metadata.id,
667
+ title: metadata.title,
668
+ cwd: metadata.cwd,
669
+ workspace: metadata.workspace,
670
+ updatedAt,
671
+ createdAt: metadata.createdAt,
672
+ archived: false,
673
+ pinned: false,
674
+ unread: false,
675
+ projectless: !metadata.workspace,
676
+ model: metadata.model,
677
+ effort: metadata.effort,
678
+ source: metadata.source,
679
+ cliVersion: metadata.cliVersion,
680
+ capabilities: ["resume", "fork"]
681
+ };
682
+ if (isVisibleAgentSession(session)) {
683
+ sessions.push(session);
684
+ }
685
+ }
686
+ return dedupeAgentSessions(sessions).sort((a, b) => timestampMs(b.updatedAt) - timestampMs(a.updatedAt)).slice(0, limit);
687
+ }
688
+ function qwenSessionIdFromFilePath(filePath) {
689
+ const match = path.basename(filePath).match(/^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i);
690
+ return match ? match[1] : "";
691
+ }
692
+ function applyQwenSessionEvent(metadata, event, fileSessionId) {
693
+ if (!event || typeof event !== "object") return;
694
+ const eventSessionId = typeof event.sessionId === "string" ? event.sessionId : "";
695
+ if (eventSessionId && (0, import_provider_session_id.isSafeProviderSessionId)(eventSessionId)) {
696
+ metadata.id = eventSessionId;
697
+ }
698
+ const timestamp = isoTimestamp(event.timestamp);
699
+ if (timestamp) {
700
+ metadata.updatedAt = timestamp;
701
+ metadata.createdAt = metadata.createdAt || timestamp;
702
+ }
703
+ if (typeof event.cwd === "string" && event.cwd.trim()) {
704
+ metadata.cwd = normalizePathValue(event.cwd);
705
+ }
706
+ if (typeof event.version === "string" && event.version.trim()) {
707
+ metadata.cliVersion = event.version.trim();
708
+ }
709
+ if (typeof event.model === "string" && event.model.trim()) {
710
+ metadata.model = event.model.trim();
711
+ }
712
+ if (event.type === "system" && event.subtype === "custom_title" && typeof event.systemPayload?.customTitle === "string" && event.systemPayload.customTitle.trim()) {
713
+ metadata.title = event.systemPayload.customTitle.trim();
714
+ }
715
+ if (!metadata.firstPrompt && event.type === "user") {
716
+ metadata.firstPrompt = qwenTextFromMessage(event.message);
717
+ }
718
+ if (!metadata.id && fileSessionId) metadata.id = fileSessionId;
719
+ }
720
+ async function readQwenSessionMetadata(filePath, maxLines = 160) {
721
+ const fileSessionId = qwenSessionIdFromFilePath(filePath);
722
+ const metadata = {
723
+ filePath,
724
+ id: fileSessionId,
725
+ title: "",
726
+ firstPrompt: "",
727
+ cwd: "",
728
+ workspace: "",
729
+ createdAt: "",
730
+ updatedAt: "",
731
+ model: "",
732
+ source: "qwen",
733
+ cliVersion: ""
734
+ };
735
+ const stream = fs.createReadStream(filePath, { encoding: "utf8" });
736
+ const reader = readline.createInterface({ input: stream, crlfDelay: Infinity });
737
+ let lineCount = 0;
738
+ try {
739
+ for await (const line of reader) {
740
+ if (!line) continue;
741
+ lineCount += 1;
742
+ try {
743
+ applyQwenSessionEvent(metadata, JSON.parse(line), fileSessionId);
744
+ } catch {
745
+ }
746
+ if (lineCount >= maxLines || metadata.id && metadata.cwd && metadata.firstPrompt && metadata.model) {
747
+ break;
748
+ }
749
+ }
750
+ } finally {
751
+ reader.close();
752
+ stream.destroy();
753
+ }
754
+ const tail = await readTextTail(filePath, QWEN_HISTORY_TAIL_BYTES);
755
+ for (const line of tail.split("\n").filter(Boolean)) {
756
+ try {
757
+ applyQwenSessionEvent(metadata, JSON.parse(line), fileSessionId);
758
+ } catch {
759
+ }
760
+ }
761
+ if (!metadata.id || !(0, import_provider_session_id.isSafeProviderSessionId)(metadata.id)) return null;
762
+ metadata.title = firstTrimmedString(metadata.title, metadata.firstPrompt, "Qwen Code session");
763
+ metadata.workspace = normalizePathValue(metadata.cwd || "");
764
+ return metadata;
765
+ }
766
+ async function listQwenSessions(options = {}) {
767
+ const qwenHome = options.qwenHome || path.join(os.homedir(), ".qwen");
768
+ const limit = typeof options.limit === "number" && Number.isFinite(options.limit) ? Math.max(0, Math.min(MAX_AGENT_SESSION_HISTORY_LIMIT, Math.floor(options.limit))) : DEFAULT_LIMIT;
769
+ const scanLimit = typeof options.scanLimit === "number" && Number.isFinite(options.scanLimit) ? Math.max(limit, Math.min(MAX_AGENT_SESSION_SCAN_LIMIT, Math.floor(options.scanLimit))) : DEFAULT_SCAN_LIMIT;
770
+ const projectsRoot = path.join(qwenHome, "projects");
771
+ const sessionFiles = await collectRecentFiles(
772
+ projectsRoot,
773
+ ".jsonl",
774
+ scanLimit,
775
+ (filePath) => {
776
+ const relativeParts = path.relative(projectsRoot, filePath).split(path.sep);
777
+ return relativeParts.length === 3 && relativeParts[1] === "chats";
778
+ },
779
+ (directoryPath) => {
780
+ const relativeParts = path.relative(projectsRoot, directoryPath).split(path.sep);
781
+ return relativeParts.length === 1 || relativeParts.length === 2 && relativeParts[1] === "chats";
782
+ }
783
+ );
784
+ const sessions = [];
785
+ for (const { filePath, mtimeMs } of sessionFiles) {
786
+ const metadata = await readQwenSessionMetadata(filePath);
787
+ if (!metadata) continue;
788
+ const mtimeIso = mtimeMs > 0 ? new Date(mtimeMs).toISOString() : "";
789
+ const updatedAt = timestampMs(mtimeIso) > timestampMs(metadata.updatedAt) ? mtimeIso : metadata.updatedAt || mtimeIso;
790
+ const session = {
791
+ provider: "qwen",
792
+ providerName: "Qwen Code",
793
+ id: metadata.id,
794
+ title: metadata.title,
795
+ cwd: metadata.cwd,
796
+ workspace: metadata.workspace,
797
+ updatedAt,
798
+ createdAt: metadata.createdAt,
799
+ archived: false,
800
+ pinned: false,
801
+ unread: false,
802
+ projectless: !metadata.workspace,
803
+ model: metadata.model,
804
+ effort: "",
805
+ source: metadata.source,
806
+ cliVersion: metadata.cliVersion,
807
+ capabilities: ["resume"]
808
+ };
809
+ if (isVisibleAgentSession(session)) sessions.push(session);
810
+ }
811
+ return dedupeAgentSessions(sessions).sort((a, b) => timestampMs(b.updatedAt) - timestampMs(a.updatedAt)).slice(0, limit);
812
+ }
813
+ function runOpenCodeSessionList(options = {}) {
814
+ const executable = options.opencodeBin || process.env.FARMING_OPENCODE_BIN || "opencode";
815
+ const maxCount = typeof options.maxCount === "number" && Number.isFinite(options.maxCount) ? Math.max(1, Math.floor(options.maxCount)) : DEFAULT_SCAN_LIMIT;
816
+ const env = { ...process.env };
817
+ if (options.opencodeHome) env.OPENCODE_CONFIG_DIR = options.opencodeHome;
818
+ return new Promise((resolve, reject) => {
819
+ (0, import_child_process.execFile)(executable, ["session", "list", "--format", "json", "--max-count", String(maxCount)], {
820
+ env,
821
+ maxBuffer: 4 * 1024 * 1024,
822
+ timeout: 15e3
823
+ }, (error, stdout) => {
824
+ if (error) {
825
+ reject(error);
826
+ return;
827
+ }
828
+ resolve(stdout);
829
+ });
830
+ });
831
+ }
832
+ async function listOpenCodeSessions(options = {}) {
833
+ const limit = typeof options.limit === "number" && Number.isFinite(options.limit) ? Math.max(0, Math.min(MAX_AGENT_SESSION_HISTORY_LIMIT, Math.floor(options.limit))) : DEFAULT_LIMIT;
834
+ const scanLimit = typeof options.scanLimit === "number" && Number.isFinite(options.scanLimit) ? Math.max(limit, Math.min(MAX_AGENT_SESSION_SCAN_LIMIT, Math.floor(options.scanLimit))) : DEFAULT_SCAN_LIMIT;
835
+ const listCommand = options.runOpenCodeSessionList || runOpenCodeSessionList;
836
+ let rawSessions = [];
837
+ try {
838
+ const output = await listCommand({
839
+ maxCount: scanLimit,
840
+ opencodeBin: options.opencodeBin,
841
+ opencodeHome: options.opencodeHome
842
+ });
843
+ rawSessions = JSON.parse(String(output || "[]"));
844
+ } catch {
845
+ return [];
846
+ }
847
+ if (!Array.isArray(rawSessions)) return [];
848
+ return dedupeAgentSessions(rawSessions.map((raw) => {
849
+ if (!isHistoryRecord(raw)) return null;
850
+ const id = firstTrimmedString(raw.id);
851
+ const cwd = normalizePathValue(raw.directory || "");
852
+ if (!id || !(0, import_provider_session_id.isSafeProviderSessionId)(id)) return null;
853
+ return {
854
+ provider: "opencode",
855
+ providerName: "OpenCode",
856
+ id,
857
+ title: firstTrimmedString(raw.title, "OpenCode session"),
858
+ cwd,
859
+ workspace: cwd,
860
+ updatedAt: isoTimestamp(raw.updated),
861
+ createdAt: isoTimestamp(raw.created),
862
+ archived: false,
863
+ pinned: false,
864
+ unread: false,
865
+ projectless: !cwd,
866
+ source: "opencode",
867
+ capabilities: ["resume", "fork"]
868
+ };
869
+ }).filter((session) => session !== null && isVisibleAgentSession(session))).sort((a, b) => timestampMs(b.updatedAt) - timestampMs(a.updatedAt)).slice(0, limit);
870
+ }
871
+ function normalizeCodexSession(session) {
872
+ return {
873
+ provider: "codex",
874
+ providerName: "Codex",
875
+ ...session,
876
+ capabilities: ["resume", "fork"]
877
+ };
878
+ }
879
+ function normalizeProvider(provider) {
880
+ const normalized = String(provider || "").trim().toLowerCase();
881
+ return isAgentProvider(normalized) ? normalized : "";
882
+ }
883
+ function isSafeSessionId(sessionId) {
884
+ return (0, import_provider_session_id.isSafeProviderSessionId)(sessionId);
885
+ }
886
+ function buildAgentSessionResumeCommand(provider, sessionId, options = {}) {
887
+ const normalizedProvider = normalizeProvider(provider);
888
+ const normalizedSessionId = String(sessionId || "").trim();
889
+ if (!normalizedProvider || !isSafeSessionId(normalizedSessionId)) return "";
890
+ if (normalizedProvider === "codex") {
891
+ const cwd = normalizePathValue(options.cwd);
892
+ const modelProvider = String(
893
+ options.modelProvider || (Object.prototype.hasOwnProperty.call(options, "providerHomePath") ? resolveCodexResumeModelProvider(options.providerHomePath) : "")
894
+ ).trim();
895
+ const providerArgs = modelProvider ? ` -c ${quoteCommandArg(`model_provider=${JSON.stringify(modelProvider)}`)}` : "";
896
+ const cwdArgs = cwd ? ` -C ${quoteCommandArg(cwd)}` : "";
897
+ return `codex ${options.fork === true ? "fork" : "resume"}${providerArgs}${cwdArgs} ${normalizedSessionId}`;
898
+ }
899
+ if (normalizedProvider === "claude") {
900
+ return options.fork === true ? `claude --resume ${normalizedSessionId} --fork-session` : `claude --resume ${normalizedSessionId}`;
901
+ }
902
+ if (normalizedProvider === "qoder") {
903
+ return options.fork === true ? `qodercli --resume ${normalizedSessionId} --fork-session` : `qodercli --resume ${normalizedSessionId}`;
904
+ }
905
+ if (normalizedProvider === "qwen") {
906
+ return options.fork === true ? "" : `qwen --resume ${normalizedSessionId}`;
907
+ }
908
+ if (normalizedProvider === "opencode") {
909
+ return `opencode --session ${normalizedSessionId}${options.fork === true ? " --fork" : ""}`;
910
+ }
911
+ return "";
912
+ }
913
+ async function listAgentSessions(options = {}) {
914
+ const limit = typeof options.limit === "number" && Number.isFinite(options.limit) ? Math.max(0, Math.min(MAX_AGENT_SESSION_HISTORY_LIMIT, Math.floor(options.limit))) : DEFAULT_LIMIT;
915
+ const requestedProviders = Array.isArray(options.providers) ? options.providers.map(normalizeProvider).filter((provider) => Boolean(provider)) : ["codex", "claude", "opencode", "qoder", "qwen"];
916
+ const providers = Array.from(new Set(requestedProviders));
917
+ const sessions = [];
918
+ const providerHomes = options.providerHomes && typeof options.providerHomes === "object" ? options.providerHomes : {};
919
+ async function listForHomes(homes, fallbackHomeKey, listFn, homeOptionKey, normalize = (session) => session) {
920
+ const configuredHomes = Array.isArray(homes) && homes.length > 0 ? homes : [{ id: "default", path: options[fallbackHomeKey] }];
921
+ const perHomeLimit = typeof options.providerLimit === "number" && Number.isFinite(options.providerLimit) ? Math.max(0, Math.min(MAX_AGENT_SESSION_HISTORY_LIMIT, Math.floor(options.providerLimit))) : limit;
922
+ for (const home of configuredHomes) {
923
+ const providerHomeId = String(home && home.id || "default").trim() || "default";
924
+ const providerHomePath = String(home && home.path || "").trim();
925
+ const listOptions = {
926
+ limit: perHomeLimit,
927
+ scanLimit: options.scanLimit,
928
+ opencodeBin: options.opencodeBin,
929
+ runOpenCodeSessionList: options.runOpenCodeSessionList
930
+ };
931
+ if (providerHomePath) listOptions[homeOptionKey] = providerHomePath;
932
+ const homeSessions = await listFn(listOptions);
933
+ sessions.push(...homeSessions.map((session) => normalize({
934
+ ...session,
935
+ providerHomeId,
936
+ providerHomePath
937
+ })).filter(isVisibleAgentSession));
938
+ }
939
+ }
940
+ if (providers.includes("codex")) {
941
+ await listForHomes(providerHomes.codex, "codexHome", import_codex_session_history.listCodexSessions, "codexHome", normalizeCodexSession);
942
+ }
943
+ if (providers.includes("claude")) {
944
+ await listForHomes(providerHomes.claude, "claudeHome", listClaudeSessions, "claudeHome");
945
+ }
946
+ if (providers.includes("qoder")) {
947
+ await listForHomes(providerHomes.qoder, "qoderHome", listQoderSessions, "qoderHome");
948
+ }
949
+ if (providers.includes("qwen")) {
950
+ await listForHomes(providerHomes.qwen, "qwenHome", listQwenSessions, "qwenHome");
951
+ }
952
+ if (providers.includes("opencode")) {
953
+ const configuredHomes = Array.isArray(providerHomes.opencode) && providerHomes.opencode.length > 0 ? providerHomes.opencode : [{ id: "default", path: options.opencodeHome }];
954
+ const home = configuredHomes.find((candidate) => String(candidate?.id || "") === "default") || configuredHomes[0];
955
+ const providerHomeId = String(home?.id || "default").trim() || "default";
956
+ const providerHomePath = String(home?.path || "").trim();
957
+ const homeSessions = await listOpenCodeSessions({
958
+ limit: typeof options.providerLimit === "number" && Number.isFinite(options.providerLimit) ? options.providerLimit : limit,
959
+ scanLimit: options.scanLimit,
960
+ opencodeBin: options.opencodeBin,
961
+ opencodeHome: providerHomePath,
962
+ runOpenCodeSessionList: options.runOpenCodeSessionList
963
+ });
964
+ const bindingsBySession = /* @__PURE__ */ new Map();
965
+ for (const binding of options.providerSessionBindings || []) {
966
+ if (normalizeProvider(binding?.provider) !== "opencode") continue;
967
+ const sessionId = String(binding?.providerSessionId || "").trim();
968
+ if (!sessionId) continue;
969
+ const bindings = bindingsBySession.get(sessionId) || [];
970
+ bindings.push(binding);
971
+ bindingsBySession.set(sessionId, bindings);
972
+ }
973
+ sessions.push(...homeSessions.map((session) => {
974
+ const bindings = bindingsBySession.get(String(session.id || "")) || [];
975
+ const exactBindings = new Map(bindings.map((binding2) => [
976
+ `${binding2.providerHomeId}\0${binding2.providerHomePath}`,
977
+ binding2
978
+ ]));
979
+ const binding = exactBindings.size === 1 ? [...exactBindings.values()][0] : null;
980
+ return {
981
+ ...session,
982
+ providerHomeId: binding?.providerHomeId || providerHomeId,
983
+ providerHomePath: binding?.providerHomePath || providerHomePath
984
+ };
985
+ }));
986
+ }
987
+ return dedupeAgentSessions(sessions).sort(compareAgentSessions).slice(0, limit);
988
+ }
989
+ async function findAgentSession(provider, sessionId, options = {}) {
990
+ const normalizedProvider = normalizeProvider(provider);
991
+ const normalizedSessionId = String(sessionId || "").trim();
992
+ if (!normalizedProvider || !isSafeSessionId(normalizedSessionId)) return null;
993
+ const sessions = await listAgentSessions({
994
+ ...options,
995
+ providers: [normalizedProvider],
996
+ limit: options.limit || 200,
997
+ providerLimit: options.providerLimit || 200
998
+ });
999
+ const requestedHomeId = typeof options.providerHomeId === "string" ? options.providerHomeId.trim() : "";
1000
+ return sessions.find((session) => session.id === normalizedSessionId && (!requestedHomeId || (session.providerHomeId || "default") === requestedHomeId)) || null;
1001
+ }
1002
+ // Annotate the CommonJS export names for ESM import in node:
1003
+ 0 && (module.exports = {
1004
+ buildAgentSessionResumeCommand,
1005
+ compareAgentSessions,
1006
+ findAgentSession,
1007
+ hasTemporaryWorkspaceReference,
1008
+ isAgentManagedWorktree,
1009
+ isDefaultClaudeSessionTitle,
1010
+ isSafeSessionId,
1011
+ isTemporaryWorkspace,
1012
+ isVisibleAgentSession,
1013
+ listAgentSessions,
1014
+ listClaudeSessions,
1015
+ listOpenCodeSessions,
1016
+ listQoderSessions,
1017
+ listQwenSessions,
1018
+ normalizeProvider,
1019
+ paginateAgentSessions,
1020
+ resolveCodexResumeModelProvider,
1021
+ searchAgentSessions
1022
+ });