farming-code 2.2.29 → 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 (385) hide show
  1. package/README.md +25 -66
  2. package/README.zh_cn.md +15 -66
  3. package/THIRD_PARTY_NOTICES.md +7 -0
  4. package/backend/acp/{client-services.js → client-services.cjs} +132 -134
  5. package/backend/acp/packaged-claude-acp.cjs +37 -0
  6. package/backend/acp/packaged-codex-acp.cjs +37 -0
  7. package/backend/acp/patch-decisions.cjs +182 -0
  8. package/backend/acp/permission-security.cjs +131 -0
  9. package/backend/{acp-checkpoint-store.js → acp-checkpoint-store.cjs} +90 -59
  10. package/backend/{acp-runtime.js → acp-runtime.cjs} +1219 -1125
  11. package/backend/acp-session-state.cjs +622 -0
  12. package/backend/acp-transcript.cjs +525 -0
  13. package/backend/agent-env.cjs +257 -0
  14. package/backend/agent-extension-discovery.cjs +452 -0
  15. package/backend/agent-extension-inventory.cjs +116 -0
  16. package/backend/agent-json-stream.cjs +283 -0
  17. package/backend/agent-lifecycle-journal.cjs +185 -0
  18. package/backend/{agent-manager.js → agent-manager.cjs} +3116 -4275
  19. package/backend/agent-order-transaction.cjs +85 -0
  20. package/backend/agent-order.cjs +159 -0
  21. package/backend/agent-provider-session.cjs +98 -0
  22. package/backend/agent-runtime-binding.cjs +179 -0
  23. package/backend/agent-session-history.cjs +1022 -0
  24. package/backend/agent-session-inventory.cjs +291 -0
  25. package/backend/async-cache.cjs +104 -0
  26. package/backend/atomic-json-store.cjs +67 -0
  27. package/backend/auth.cjs +261 -0
  28. package/backend/authoritative-inventory-cache.cjs +383 -0
  29. package/backend/business-health.cjs +68 -0
  30. package/backend/chat-runtime.cjs +50 -0
  31. package/backend/claude-settings.cjs +132 -0
  32. package/backend/cli-agents.cjs +435 -0
  33. package/backend/codex-context-window.cjs +196 -0
  34. package/backend/codex-models.cjs +228 -0
  35. package/backend/codex-session-archive.cjs +82 -0
  36. package/backend/codex-session-history.cjs +590 -0
  37. package/backend/{codex-terminal-profile.js → codex-terminal-profile.cjs} +149 -155
  38. package/backend/codex-transcript-sanitizer.cjs +130 -0
  39. package/backend/codex-transcript.cjs +2107 -0
  40. package/backend/command-runner-child.cjs +105 -0
  41. package/backend/config-manager.cjs +1263 -0
  42. package/backend/control-api.cjs +439 -0
  43. package/backend/data/LICENSE.cua +21 -0
  44. package/backend/executable-discovery.cjs +204 -0
  45. package/backend/farming-agent-bootstrap.cjs +81 -0
  46. package/backend/farming-agent-bootstrap.zh_cn.md +6 -2
  47. package/backend/{farming-app-cli.js → farming-app-cli.cjs} +441 -493
  48. package/backend/farming-cli.cjs +414 -0
  49. package/backend/farming-net-pass.cjs +319 -0
  50. package/backend/farming-net-registry.cjs +123 -0
  51. package/backend/farming-net-server.cjs +309 -0
  52. package/backend/farming-session-store.cjs +651 -0
  53. package/backend/git-worktree-info.cjs +181 -0
  54. package/backend/haiku-token.cjs +828 -0
  55. package/backend/index-html.cjs +96 -0
  56. package/backend/input-parts.cjs +68 -0
  57. package/backend/input-routing.cjs +40 -0
  58. package/backend/{local-session-engine.js → local-session-engine.cjs} +276 -282
  59. package/backend/main-agent-skills.cjs +309 -0
  60. package/backend/main-page-session.cjs +132 -0
  61. package/backend/native-pty-controller-generation.cjs +139 -0
  62. package/backend/{native-pty-host-client.js → native-pty-host-client.cjs} +338 -346
  63. package/backend/native-pty-host-identity.cjs +125 -0
  64. package/backend/native-pty-host-path.cjs +68 -0
  65. package/backend/{native-pty-host.js → native-pty-host.cjs} +480 -569
  66. package/backend/native-session-engine.cjs +296 -0
  67. package/backend/network.cjs +57 -0
  68. package/backend/npm-update-helper.cjs +399 -0
  69. package/backend/packaged-node-pty.cjs +120 -0
  70. package/backend/preview-session-manager.cjs +89 -0
  71. package/backend/provider-adapters.cjs +492 -0
  72. package/backend/provider-home-configuration.cjs +211 -0
  73. package/backend/provider-session-id.cjs +79 -0
  74. package/backend/provider-session-service.cjs +333 -0
  75. package/backend/qr-share-tickets.cjs +119 -0
  76. package/backend/resource-broadcast-protocol.cjs +50 -0
  77. package/backend/review-diff-router.cjs +202 -0
  78. package/backend/review-diff-service.cjs +1267 -0
  79. package/backend/review-session-router.cjs +93 -0
  80. package/backend/review-session-service.cjs +470 -0
  81. package/backend/review-session-store.cjs +161 -0
  82. package/backend/review-state-router.cjs +132 -0
  83. package/backend/review-state-store.cjs +299 -0
  84. package/backend/run-history-store.cjs +97 -0
  85. package/backend/runtime-dependency-manager.cjs +893 -0
  86. package/backend/runtime-executable-invocation.cjs +37 -0
  87. package/backend/runtime-observation.cjs +96 -0
  88. package/backend/server-process-identity.cjs +70 -0
  89. package/backend/server.cjs +3356 -0
  90. package/backend/session-engine-bridge.cjs +144 -0
  91. package/backend/session-engine-router.cjs +105 -0
  92. package/backend/session-engine.cjs +64 -0
  93. package/backend/session-stream-protocol.cjs +181 -0
  94. package/backend/shell-busy-integration.cjs +442 -0
  95. package/backend/slash-command-discovery.cjs +423 -0
  96. package/backend/storage-layout.cjs +263 -0
  97. package/backend/system-monitor.cjs +96 -0
  98. package/backend/terminal-attach-checkpoint.cjs +73 -0
  99. package/backend/terminal-exit-quiescence.cjs +57 -0
  100. package/backend/{terminal-reducer-flow-control.js → terminal-reducer-flow-control.cjs} +45 -22
  101. package/backend/terminal-runtime-cleanup.cjs +99 -0
  102. package/backend/{terminal-screen-state.js → terminal-screen-state.cjs} +100 -108
  103. package/backend/{terminal-screen-worker-pool.js → terminal-screen-worker-pool.cjs} +89 -79
  104. package/backend/{terminal-screen-worker-thread.js → terminal-screen-worker-thread.cjs} +64 -65
  105. package/backend/terminal-screen-worker.cjs +352 -0
  106. package/backend/terminal-state-serialization.cjs +147 -0
  107. package/backend/{terminal-status.js → terminal-status.cjs} +137 -187
  108. package/backend/theme-manager.cjs +185 -0
  109. package/backend/update-service.cjs +675 -0
  110. package/backend/usage-forecast.cjs +95 -0
  111. package/backend/{usage-history-client.js → usage-history-client.cjs} +144 -94
  112. package/backend/usage-history-smoke.cjs +85 -0
  113. package/backend/usage-history-worker.cjs +60 -0
  114. package/backend/{usage-monitor.js → usage-monitor.cjs} +363 -390
  115. package/backend/workspace-directory.cjs +239 -0
  116. package/backend/workspace-discovery.cjs +271 -0
  117. package/backend/{workspace-file-router.js → workspace-file-router.cjs} +213 -282
  118. package/backend/{workspace-file-service.js → workspace-file-service.cjs} +1139 -1318
  119. package/backend/workspace-root-registry.cjs +192 -0
  120. package/bin/farming +1 -1
  121. package/config/farming.deploy.env.example +1 -1
  122. package/config/farming.install.env.example +1 -1
  123. package/dist/acp/codex-acp-1.1.4.mjs +405 -8
  124. package/dist/assets/App-BCkdpWB6.css +1 -0
  125. package/dist/assets/App-CRjKpaGp.js +697 -0
  126. package/dist/assets/CodeSelect-Ci8sKZPU.js +1 -0
  127. package/dist/assets/CodeSelect-T2eNzrOc.css +1 -0
  128. package/dist/assets/{FileEditorMarkdownPreview-Cs9cLv8a.js → FileEditorMarkdownPreview-V06QHlAg.js} +55 -55
  129. package/dist/assets/FileEditorPane-BX-Wjg9U.js +2 -0
  130. package/dist/assets/IconGlyphs-YhV7tqd4.js +1 -0
  131. package/dist/assets/ProjectFilesSection-BDT2_r0o.js +12 -0
  132. package/dist/assets/ReviewPage-BqAs5sG1.js +3 -0
  133. package/dist/assets/code-dark-B7eM_9G9.css +1 -0
  134. package/dist/assets/{cssMode-Bdg5RpcJ.js → cssMode-ADdAlxTO.js} +1 -1
  135. package/dist/assets/{editor.api2-D74ufkbr.js → editor.api2-BFLAr0YF.js} +162 -162
  136. package/dist/assets/file-icons-BpeqWkIB.js +1 -0
  137. package/dist/assets/{freemarker2-DfMDJfnE.js → freemarker2-C90q5jrp.js} +1 -1
  138. package/dist/assets/{handlebars-BEdPtzMT.js → handlebars-BwUQcEDq.js} +1 -1
  139. package/dist/assets/{html-B1fPb1QD.js → html-1s3uPKfh.js} +1 -1
  140. package/dist/assets/{htmlMode-CY2ZjHxH.js → htmlMode-xtKD99de.js} +1 -1
  141. package/dist/assets/{index-CQNaZc3l.js → index-C8MchCem.js} +3 -3
  142. package/dist/assets/{javascript-BV2OsWA0.js → javascript-Ph7ijyny.js} +1 -1
  143. package/dist/assets/{jsonMode-zd07aeuX.js → jsonMode-D-jGAnFH.js} +1 -1
  144. package/dist/assets/linkComputer-CbGyI_qx.js +1 -0
  145. package/dist/assets/{liquid-BParI24X.js → liquid-0IamE_cI.js} +1 -1
  146. package/dist/assets/{lspLanguageFeatures-BzredkoV.js → lspLanguageFeatures-BxnQunWF.js} +1 -1
  147. package/dist/assets/main-CLKXa6hf.css +1 -0
  148. package/dist/assets/{mdx-vGzUJN98.js → mdx-DdNmfivn.js} +1 -1
  149. package/dist/assets/{monaco.contribution-BmaeBQEc.js → monaco.contribution-B43jsUs1.js} +2 -2
  150. package/dist/assets/{python-CUwdLgsI.js → python-IAt4X5TS.js} +1 -1
  151. package/dist/assets/{razor-BScebUxU.js → razor-DRkFYW0S.js} +1 -1
  152. package/dist/assets/review-C8-oPKXk.css +1 -0
  153. package/dist/assets/{tsMode-DzUAibXK.js → tsMode-_d_4U2gf.js} +1 -1
  154. package/dist/assets/{typescript-D9EOeM7N.js → typescript-C7zcMq9l.js} +1 -1
  155. package/dist/assets/{workers-DAiomYZM.js → workers-D0nOyJzf.js} +1 -1
  156. package/dist/assets/workspace-editor-model-DND_Y-Bj.js +1 -0
  157. package/dist/assets/workspace-editor-monaco-BPWhgcIB.js +4 -0
  158. package/dist/assets/workspace-editor-monaco-N641qPjX.js +1 -0
  159. package/dist/assets/workspace-view-state-k1bTlJ_Z.js +13 -0
  160. package/dist/assets/{xml-wWl1dhkQ.js → xml-BR-HvxT8.js} +1 -1
  161. package/dist/assets/{yaml-Dc2WDaOZ.js → yaml-YtFQwh4q.js} +1 -1
  162. package/dist/index.html +2 -1
  163. package/extensions/browser/backend/agent-browser-runtime.cjs +1040 -0
  164. package/extensions/browser/backend/agent-capability.cjs +85 -0
  165. package/extensions/browser/backend/browser-mcp-server.cjs +655 -0
  166. package/extensions/browser/backend/browser-resource-manager.cjs +1486 -0
  167. package/extensions/browser/backend/browser-resource-store.cjs +228 -0
  168. package/extensions/browser/backend/browser-router.cjs +203 -0
  169. package/extensions/browser/backend/executable-discovery.cjs +248 -0
  170. package/extensions/browser/backend/farming-browser-client.cjs +116 -0
  171. package/extensions/browser/backend/index.cjs +32 -0
  172. package/extensions/browser/backend/managed-chromium-installer.cjs +833 -0
  173. package/extensions/browser/bin/farming-browser +16 -7
  174. package/extensions/computer/backend/agent-capability.cjs +72 -0
  175. package/extensions/computer/backend/computer-constants.cjs +59 -0
  176. package/extensions/computer/backend/computer-mcp-server.cjs +182 -0
  177. package/extensions/computer/backend/computer-resource-manager.cjs +1219 -0
  178. package/extensions/computer/backend/computer-resource-store.cjs +190 -0
  179. package/extensions/computer/backend/computer-router.cjs +257 -0
  180. package/extensions/computer/backend/cua-tools.json +3067 -0
  181. package/extensions/computer/backend/farming-computer-client.cjs +84 -0
  182. package/extensions/computer/backend/index.cjs +35 -0
  183. package/extensions/computer/backend/isolated-browser-provider.cjs +157 -0
  184. package/extensions/computer/bin/farming-computer +131 -0
  185. package/frontend/farming-net/app.js +255 -262
  186. package/frontend/ghostty-loader.js +24 -20
  187. package/frontend/reading-anchor.js +210 -193
  188. package/frontend/runtime-paths.js +24 -26
  189. package/frontend/session-bridge.js +90 -111
  190. package/frontend/session-modal-bridge.js +184 -302
  191. package/frontend/skin-bridge.js +20 -23
  192. package/frontend/skins/crt/app.js +7686 -7901
  193. package/frontend/skins/crt/effects.js +7 -6
  194. package/frontend/skins/crt/index.html +6 -6
  195. package/frontend/skins/crt/styles/markdown.css +4 -4
  196. package/frontend/terminal-bridge.js +174 -181
  197. package/frontend/terminal-replay.js +320 -345
  198. package/frontend/theme-loader.js +55 -71
  199. package/index.html +1 -0
  200. package/package.json +64 -37
  201. package/shared/backend-connection-status.js +38 -69
  202. package/shared/browser-protocol.js +235 -110
  203. package/shared/websocket-liveness.js +40 -0
  204. package/backend/acp/packaged-claude-acp.js +0 -13
  205. package/backend/acp/packaged-codex-acp.js +0 -13
  206. package/backend/acp/patch-decisions.js +0 -153
  207. package/backend/acp/permission-security.js +0 -108
  208. package/backend/acp-session-state.js +0 -644
  209. package/backend/acp-transcript.js +0 -512
  210. package/backend/agent-env.js +0 -250
  211. package/backend/agent-json-stream.js +0 -268
  212. package/backend/agent-lifecycle-journal.js +0 -133
  213. package/backend/agent-memory-report.js +0 -583
  214. package/backend/agent-order.js +0 -166
  215. package/backend/agent-provider-session.js +0 -76
  216. package/backend/agent-runtime-binding.js +0 -174
  217. package/backend/agent-session-history.js +0 -953
  218. package/backend/async-cache.js +0 -94
  219. package/backend/atomic-json-store.js +0 -37
  220. package/backend/auth.js +0 -251
  221. package/backend/bundle-update-helper.js +0 -113
  222. package/backend/chat-runtime.js +0 -28
  223. package/backend/claude-settings.js +0 -121
  224. package/backend/cli-agents.js +0 -486
  225. package/backend/codex-context-window.js +0 -189
  226. package/backend/codex-models.js +0 -226
  227. package/backend/codex-rollout-follower.js +0 -326
  228. package/backend/codex-session-archive.js +0 -65
  229. package/backend/codex-session-history.js +0 -647
  230. package/backend/codex-transcript-sanitizer.js +0 -115
  231. package/backend/codex-transcript.js +0 -2564
  232. package/backend/command-runner-child.js +0 -67
  233. package/backend/config-manager.js +0 -1133
  234. package/backend/control-api.js +0 -455
  235. package/backend/executable-discovery.js +0 -216
  236. package/backend/farming-agent-bootstrap.js +0 -49
  237. package/backend/farming-cli.js +0 -457
  238. package/backend/farming-net-pass.js +0 -285
  239. package/backend/farming-net-registry.js +0 -112
  240. package/backend/farming-net-server.js +0 -298
  241. package/backend/farming-session-store.js +0 -677
  242. package/backend/git-worktree-info.js +0 -181
  243. package/backend/haiku-token.js +0 -772
  244. package/backend/index-html.js +0 -62
  245. package/backend/input-parts.js +0 -54
  246. package/backend/input-routing.js +0 -24
  247. package/backend/json-cli-runtime.js +0 -275
  248. package/backend/main-agent-skills.js +0 -305
  249. package/backend/main-page-session.js +0 -122
  250. package/backend/native-pty-controller-generation.js +0 -106
  251. package/backend/native-pty-host-identity.js +0 -86
  252. package/backend/native-pty-host-path.js +0 -42
  253. package/backend/native-session-engine.js +0 -268
  254. package/backend/network.js +0 -23
  255. package/backend/npm-update-helper.js +0 -374
  256. package/backend/packaged-node-pty.js +0 -99
  257. package/backend/preview-session-manager.js +0 -68
  258. package/backend/provider-adapters.js +0 -399
  259. package/backend/provider-session-id.js +0 -47
  260. package/backend/provider-session-service.js +0 -345
  261. package/backend/qr-share-tickets.js +0 -100
  262. package/backend/review-diff-router.js +0 -180
  263. package/backend/review-diff-service.js +0 -1270
  264. package/backend/review-session-router.js +0 -74
  265. package/backend/review-session-service.js +0 -446
  266. package/backend/review-session-store.js +0 -151
  267. package/backend/review-state-router.js +0 -116
  268. package/backend/review-state-store.js +0 -286
  269. package/backend/run-history-store.js +0 -67
  270. package/backend/runtime-dependency-manager.js +0 -759
  271. package/backend/runtime-executable-invocation.js +0 -20
  272. package/backend/runtime-observation.js +0 -81
  273. package/backend/server-process-identity.js +0 -47
  274. package/backend/server.js +0 -3267
  275. package/backend/session-engine-bridge.js +0 -129
  276. package/backend/session-engine-router.js +0 -66
  277. package/backend/session-engine.js +0 -39
  278. package/backend/session-stream-protocol.js +0 -185
  279. package/backend/shell-busy-integration.js +0 -472
  280. package/backend/slash-command-discovery.js +0 -433
  281. package/backend/storage-layout.js +0 -190
  282. package/backend/system-monitor.js +0 -77
  283. package/backend/terminal-attach-checkpoint.js +0 -74
  284. package/backend/terminal-exit-quiescence.js +0 -39
  285. package/backend/terminal-runtime-cleanup.js +0 -80
  286. package/backend/terminal-screen-worker.js +0 -337
  287. package/backend/terminal-state-serialization.js +0 -127
  288. package/backend/theme-manager.js +0 -163
  289. package/backend/update-service.js +0 -1545
  290. package/backend/usage-forecast.js +0 -86
  291. package/backend/usage-history-scanner.ts +0 -2718
  292. package/backend/usage-history-smoke.js +0 -64
  293. package/backend/usage-history-worker.js +0 -34
  294. package/backend/workspace-directory.js +0 -232
  295. package/backend/workspace-discovery.js +0 -311
  296. package/backend/workspace-root-registry.js +0 -166
  297. package/dist/assets/App-BKNUILuL.css +0 -1
  298. package/dist/assets/App-Ex2oVVXO.js +0 -693
  299. package/dist/assets/FileEditorPane-CNtuGjQ3.js +0 -2
  300. package/dist/assets/IconGlyphs-BClgag6E.js +0 -1
  301. package/dist/assets/ProjectFilesSection-Cf2BEcAN.js +0 -12
  302. package/dist/assets/ReviewPage-BRuxFaH5.js +0 -3
  303. package/dist/assets/code-dark-BEZTQwYZ.css +0 -1
  304. package/dist/assets/file-icons-BOlcJ0ZF.js +0 -1
  305. package/dist/assets/main-DK9Sy7-c.css +0 -1
  306. package/dist/assets/review-BcnwQtJv.css +0 -1
  307. package/dist/assets/workspace-editor-model-CSGCl21x.js +0 -1
  308. package/dist/assets/workspace-editor-monaco-CJNwbpCy.js +0 -4
  309. package/dist/assets/workspace-editor-monaco-CO9w8YV0.js +0 -1
  310. package/dist/assets/workspace-view-state-BjKPYp0E.js +0 -7
  311. package/extensions/browser/backend/agent-browser-runtime.js +0 -1041
  312. package/extensions/browser/backend/agent-capability.js +0 -55
  313. package/extensions/browser/backend/browser-mcp-server.js +0 -621
  314. package/extensions/browser/backend/browser-resource-manager.js +0 -1309
  315. package/extensions/browser/backend/browser-resource-store.js +0 -190
  316. package/extensions/browser/backend/browser-router.js +0 -133
  317. package/extensions/browser/backend/executable-discovery.js +0 -224
  318. package/extensions/browser/backend/farming-browser-client.js +0 -83
  319. package/extensions/browser/backend/index.js +0 -7
  320. package/extensions/browser/frontend/BrowserSidebarPortals.tsx +0 -360
  321. package/extensions/browser/frontend/BrowserViewer.tsx +0 -500
  322. package/extensions/browser/frontend/browser-resource-state.ts +0 -60
  323. package/extensions/browser/frontend/browser.css +0 -567
  324. package/extensions/browser/frontend/types.ts +0 -31
  325. package/extensions/browser/frontend/useBrowserResources.ts +0 -158
  326. package/frontend/vendor/ghostty-web/index.d.ts +0 -1842
  327. package/shared/backend-connection-status.d.ts +0 -37
  328. package/shared/browser-protocol.d.ts +0 -5
  329. /package/dist/assets/{api-w2x5QfxB.js → api-ByCV9MEr.js} +0 -0
  330. /package/dist/assets/{core-vPkV8P_m.js → core-Czwdx12k.js} +0 -0
  331. /package/dist/assets/{fsharp-DNZNZyEE.js → fsharp-BjPpkoJe.js} +0 -0
  332. /package/dist/assets/{go-_kPJjNc_.js → go-BkIDmSUP.js} +0 -0
  333. /package/dist/assets/{graphql-4HCNVt5g.js → graphql-CCJTpqi1.js} +0 -0
  334. /package/dist/assets/{hcl-C87ymY0o.js → hcl-s4z8lUFg.js} +0 -0
  335. /package/dist/assets/{ini-BYrrGNTc.js → ini-CyUW1I7Z.js} +0 -0
  336. /package/dist/assets/{java-B211rJbk.js → java-CFCcGRiM.js} +0 -0
  337. /package/dist/assets/{julia-DVPsRtBm.js → julia-DQyH_EYb.js} +0 -0
  338. /package/dist/assets/{kotlin-BYyNerjp.js → kotlin-B8hA5O51.js} +0 -0
  339. /package/dist/assets/{less-EC9UblGE.js → less-DaVdaas0.js} +0 -0
  340. /package/dist/assets/{lexon-B1yuUdqW.js → lexon-DLBhPd3y.js} +0 -0
  341. /package/dist/assets/{lua-Bo6GFzxT.js → lua-gB1c_cif.js} +0 -0
  342. /package/dist/assets/{m3-C-Y9cBVI.js → m3-C2T3z3gB.js} +0 -0
  343. /package/dist/assets/{markdown-BHu-wLbe.js → markdown-CKq-Euj1.js} +0 -0
  344. /package/dist/assets/{mips-Dkds26rX.js → mips-Bcs5qIDX.js} +0 -0
  345. /package/dist/assets/{msdax-PU4g-8_g.js → msdax-CBP48FHF.js} +0 -0
  346. /package/dist/assets/{mysql-fPpuGpS7.js → mysql-c7tiPcFj.js} +0 -0
  347. /package/dist/assets/{objective-c-Wy1e5JUf.js → objective-c-D4BZkeEV.js} +0 -0
  348. /package/dist/assets/{pascal-BIXwvrqU.js → pascal-CJDZg0MN.js} +0 -0
  349. /package/dist/assets/{pascaligo-DwR0AtL_.js → pascaligo-Bygi8Ynl.js} +0 -0
  350. /package/dist/assets/{perl-CGHAl8my.js → perl-aS8bkf7E.js} +0 -0
  351. /package/dist/assets/{pgsql-B91M73E2.js → pgsql-CzNAYFYl.js} +0 -0
  352. /package/dist/assets/{php-C70ttrCx.js → php-DOtoEFTT.js} +0 -0
  353. /package/dist/assets/{pla-BNrXaRh0.js → pla-DugRnao1.js} +0 -0
  354. /package/dist/assets/{postiats-Dv2IAZR9.js → postiats-DsXwusKh.js} +0 -0
  355. /package/dist/assets/{powerquery-CkY5Wq7J.js → powerquery-DL3o72oD.js} +0 -0
  356. /package/dist/assets/{powershell-uGIYLU3C.js → powershell-C1qHekys.js} +0 -0
  357. /package/dist/assets/{protobuf-CavfmJu-.js → protobuf-DHgsc-cH.js} +0 -0
  358. /package/dist/assets/{pug-Drqnyitx.js → pug-FZXlE_Iu.js} +0 -0
  359. /package/dist/assets/{qrcode-7uGsTEmi.js → qrcode-DJDTdjL7.js} +0 -0
  360. /package/dist/assets/{qsharp-C7yF-Dti.js → qsharp-bLyhI3DT.js} +0 -0
  361. /package/dist/assets/{r-HXLGP0_-.js → r-DjFGXbAa.js} +0 -0
  362. /package/dist/assets/{redis-C4y6mf2p.js → redis-DSoZ_V6u.js} +0 -0
  363. /package/dist/assets/{redshift-DdQrFPrv.js → redshift-CzkdCsrg.js} +0 -0
  364. /package/dist/assets/{restructuredtext-CBrf2PNj.js → restructuredtext-B_XPrGCQ.js} +0 -0
  365. /package/dist/assets/{ruby-CVtMoX2B.js → ruby-Cry2RneJ.js} +0 -0
  366. /package/dist/assets/{rust-Ckq4sbMP.js → rust-CWzdbFq1.js} +0 -0
  367. /package/dist/assets/{sb-er66OpE3.js → sb-DmofU59h.js} +0 -0
  368. /package/dist/assets/{scala-BdWZz-hH.js → scala-BUC2l-vN.js} +0 -0
  369. /package/dist/assets/{scheme-kTV_s2kP.js → scheme-CNIB_72f.js} +0 -0
  370. /package/dist/assets/{scss-Bymy2VJQ.js → scss-DcL4-NbX.js} +0 -0
  371. /package/dist/assets/{shell-bwEP1LQ1.js → shell-CgAGvSSA.js} +0 -0
  372. /package/dist/assets/{solidity-DCddeBgL.js → solidity-DSkt6O_P.js} +0 -0
  373. /package/dist/assets/{sophia-BMN3AQig.js → sophia--5ytcjDN.js} +0 -0
  374. /package/dist/assets/{sparql-CSXOLjzi.js → sparql-C1Srr7cD.js} +0 -0
  375. /package/dist/assets/{sql-COg8ewmK.js → sql-2k_O5fj7.js} +0 -0
  376. /package/dist/assets/{st-CIaZtBS_.js → st-DCCCPqfz.js} +0 -0
  377. /package/dist/assets/{swift-DXiOhUHu.js → swift-Dd8mAfOt.js} +0 -0
  378. /package/dist/assets/{systemverilog-BTDE6Dr2.js → systemverilog-B0-aZYXu.js} +0 -0
  379. /package/dist/assets/{tcl-B0zy9NvV.js → tcl-CZAZwPVX.js} +0 -0
  380. /package/dist/assets/{twig-D594l4Z1.js → twig-D-Ag0tdS.js} +0 -0
  381. /package/dist/assets/{typespec-XKVjaPqo.js → typespec-B7kTFp0Z.js} +0 -0
  382. /package/dist/assets/{useWorkspaceMenuKeyboard-Bpy_s69Z.js → useWorkspaceMenuKeyboard-uYZpDxhU.js} +0 -0
  383. /package/dist/assets/{vb-B2wYoKRV.js → vb-20w1JPum.js} +0 -0
  384. /package/dist/assets/{wgsl-D0Yf2LbK.js → wgsl-CLJfqFt0.js} +0 -0
  385. /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
+ });