farming-code 2.2.6

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 (453) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +287 -0
  3. package/README.zh_cn.md +329 -0
  4. package/SECURITY.md +29 -0
  5. package/THIRD_PARTY_NOTICES.md +106 -0
  6. package/backend/acp/client-services.js +312 -0
  7. package/backend/acp/patch-decisions.js +137 -0
  8. package/backend/acp/permission-security.js +108 -0
  9. package/backend/acp-runtime.js +1144 -0
  10. package/backend/acp-session-state.js +448 -0
  11. package/backend/acp-transcript.js +169 -0
  12. package/backend/agent-activity.js +186 -0
  13. package/backend/agent-env.js +250 -0
  14. package/backend/agent-json-stream.js +268 -0
  15. package/backend/agent-manager.js +4259 -0
  16. package/backend/agent-memory-report.js +583 -0
  17. package/backend/agent-order.js +162 -0
  18. package/backend/agent-provider-session.js +287 -0
  19. package/backend/agent-session-history.js +888 -0
  20. package/backend/app-server-api.js +917 -0
  21. package/backend/async-cache.js +94 -0
  22. package/backend/auth.js +178 -0
  23. package/backend/claude-settings.js +121 -0
  24. package/backend/cli-agents.js +484 -0
  25. package/backend/codex-app-server-home.js +39 -0
  26. package/backend/codex-app-server-runtime.js +901 -0
  27. package/backend/codex-context-window.js +189 -0
  28. package/backend/codex-models.js +229 -0
  29. package/backend/codex-rollout-follower.js +243 -0
  30. package/backend/codex-session-history.js +553 -0
  31. package/backend/codex-transcript-sanitizer.js +103 -0
  32. package/backend/codex-transcript.js +2341 -0
  33. package/backend/command-runner-child.js +67 -0
  34. package/backend/config-manager.js +815 -0
  35. package/backend/control-api.js +151 -0
  36. package/backend/data/chinese-poetic-words.json +8223 -0
  37. package/backend/data/poetic-word-sources/china.json +49209 -0
  38. package/backend/data/poetic-word-sources/india.json +9763 -0
  39. package/backend/data/poetic-word-sources/japan.json +8455 -0
  40. package/backend/executable-discovery.js +207 -0
  41. package/backend/farming-app-cli.js +790 -0
  42. package/backend/farming-cli.js +400 -0
  43. package/backend/farming-session-store.js +373 -0
  44. package/backend/haiku-token.js +772 -0
  45. package/backend/index-html.js +49 -0
  46. package/backend/input-parts.js +54 -0
  47. package/backend/input-routing.js +24 -0
  48. package/backend/json-cli-runtime.js +161 -0
  49. package/backend/local-session-engine.js +620 -0
  50. package/backend/main-agent-skills.js +292 -0
  51. package/backend/main-page-session.js +119 -0
  52. package/backend/native-pty-host-client.js +516 -0
  53. package/backend/native-pty-host-path.js +22 -0
  54. package/backend/native-pty-host.js +816 -0
  55. package/backend/native-session-engine.js +196 -0
  56. package/backend/network.js +23 -0
  57. package/backend/npm-update-helper.js +196 -0
  58. package/backend/packaged-node-pty.js +79 -0
  59. package/backend/provider-session-id.js +47 -0
  60. package/backend/qr-share-tickets.js +100 -0
  61. package/backend/review-diff-router.js +180 -0
  62. package/backend/review-diff-service.js +1270 -0
  63. package/backend/review-session-router.js +74 -0
  64. package/backend/review-session-service.js +432 -0
  65. package/backend/review-session-store.js +144 -0
  66. package/backend/review-state-router.js +116 -0
  67. package/backend/review-state-store.js +287 -0
  68. package/backend/run-history-store.js +70 -0
  69. package/backend/server.js +2446 -0
  70. package/backend/session-engine-bridge.js +110 -0
  71. package/backend/session-engine-router.js +66 -0
  72. package/backend/session-engine.js +39 -0
  73. package/backend/shell-busy-integration.js +472 -0
  74. package/backend/slash-command-discovery.js +296 -0
  75. package/backend/storage-layout.js +101 -0
  76. package/backend/system-monitor.js +77 -0
  77. package/backend/terminal-runtime-cleanup.js +80 -0
  78. package/backend/terminal-screen-state.js +240 -0
  79. package/backend/terminal-screen-worker-pool.js +165 -0
  80. package/backend/terminal-screen-worker-thread.js +161 -0
  81. package/backend/terminal-screen-worker.js +255 -0
  82. package/backend/terminal-status.js +356 -0
  83. package/backend/theme-manager.js +145 -0
  84. package/backend/update-service.js +1183 -0
  85. package/backend/usage-forecast.js +86 -0
  86. package/backend/usage-monitor.js +1357 -0
  87. package/backend/workspace-discovery.js +311 -0
  88. package/backend/workspace-file-router.js +431 -0
  89. package/backend/workspace-file-service.js +2765 -0
  90. package/bin/farming +5 -0
  91. package/config/farming.deploy.env.example +13 -0
  92. package/config/farming.install.env.example +17 -0
  93. package/dist/assets/App-BrP-ENHg.css +1 -0
  94. package/dist/assets/App-Dza5yEDe.js +124 -0
  95. package/dist/assets/FileEditorMarkdownPreview-DRDNQ8mX.css +1 -0
  96. package/dist/assets/FileEditorMarkdownPreview-elKWc8Im.js +404 -0
  97. package/dist/assets/FileEditorPane-BQLocXOp.js +5 -0
  98. package/dist/assets/IconGlyphs-RkMAdBXF.js +1 -0
  99. package/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  100. package/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  101. package/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  102. package/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  103. package/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  104. package/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  105. package/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  106. package/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  107. package/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  108. package/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  109. package/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  110. package/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  111. package/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  112. package/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  113. package/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  114. package/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  115. package/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  116. package/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  117. package/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  118. package/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  119. package/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  120. package/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  121. package/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  122. package/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  123. package/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  124. package/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  125. package/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  126. package/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  127. package/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  128. package/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  129. package/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  130. package/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  131. package/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  132. package/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  133. package/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  134. package/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  135. package/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  136. package/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  137. package/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  138. package/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  139. package/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  140. package/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  141. package/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  142. package/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  143. package/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  144. package/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  145. package/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  146. package/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  147. package/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  148. package/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  149. package/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  150. package/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  151. package/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  152. package/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  153. package/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  154. package/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  155. package/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  156. package/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  157. package/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  158. package/dist/assets/ProjectFilesSection-lS1azbgj.js +12 -0
  159. package/dist/assets/ReviewPage-DgnmgU2T.js +3 -0
  160. package/dist/assets/abap-Cc5D5h5i.js +1 -0
  161. package/dist/assets/abnfDiagram-VRR7QNED-BgawzDQT.js +1 -0
  162. package/dist/assets/apex-BKopwLmx.js +1 -0
  163. package/dist/assets/api-D1lyBYIQ.js +1 -0
  164. package/dist/assets/arc-CWoVlxJw.js +1 -0
  165. package/dist/assets/architecture-TIHT7OUA-CbJBFh3w.js +1 -0
  166. package/dist/assets/architectureDiagram-ZJ3FMSHR-DUShwPg0.js +36 -0
  167. package/dist/assets/array-HeX70jSN.js +1 -0
  168. package/dist/assets/azcli-DI-C34WA.js +1 -0
  169. package/dist/assets/bat-Cbp6u42z.js +1 -0
  170. package/dist/assets/bicep-4QA1jTCM.js +2 -0
  171. package/dist/assets/blockDiagram-677ZJIJ3-CeGZviXR.js +132 -0
  172. package/dist/assets/c4Diagram-LMCZKHZV-CLhYht6S.js +10 -0
  173. package/dist/assets/cameligo-Dda_adPs.js +1 -0
  174. package/dist/assets/channel-Uw90AO0b.js +1 -0
  175. package/dist/assets/chunk-2Q5K7J3B-d5WWh8jo.js +1 -0
  176. package/dist/assets/chunk-32BRIVSS-LFYpT-Cu.js +1 -0
  177. package/dist/assets/chunk-52WLFC77-BH6jDw9J.js +10 -0
  178. package/dist/assets/chunk-5FCAYU7R-C7AmIhYv.js +1 -0
  179. package/dist/assets/chunk-5HE753X5-C8cXaouP.js +1 -0
  180. package/dist/assets/chunk-5JV3BV7I-C1PtimcA.js +1 -0
  181. package/dist/assets/chunk-5TONJI2A-_81zUME8.js +2 -0
  182. package/dist/assets/chunk-5VM5RSS4-Dlw7AXWp.js +15 -0
  183. package/dist/assets/chunk-7BUUIJ7U-ZBRhjLOh.js +1 -0
  184. package/dist/assets/chunk-BIQX33UG-CWmzxeAw.js +1 -0
  185. package/dist/assets/chunk-C7G6YPKG-B_mIUlb7.js +1 -0
  186. package/dist/assets/chunk-CQNSW5MT-CMayolwI.js +1 -0
  187. package/dist/assets/chunk-CYSBUYHQ-lSPbrL3Z.js +1 -0
  188. package/dist/assets/chunk-DECur_0Z.js +1 -0
  189. package/dist/assets/chunk-EMLP6XTP-D9-jtCnM.js +1 -0
  190. package/dist/assets/chunk-EX3LRPZG-C63hVuAJ.js +231 -0
  191. package/dist/assets/chunk-FWX5IMBZ-CboX-WF_.js +2 -0
  192. package/dist/assets/chunk-HOUHSVGY-BOgSd6Un.js +1 -0
  193. package/dist/assets/chunk-ICXQ74PX-C0K-pgZt.js +2 -0
  194. package/dist/assets/chunk-JG7HCLWE-Cib606u_.js +2 -0
  195. package/dist/assets/chunk-JWPE2WC7-DSyBRaRG.js +1 -0
  196. package/dist/assets/chunk-KEIR6QF5-CNOHik0T.js +161 -0
  197. package/dist/assets/chunk-MOJQB5TN-CVMfwN_7.js +88 -0
  198. package/dist/assets/chunk-MOZMSUNE-D6JeZqmE.js +1 -0
  199. package/dist/assets/chunk-OGEWGWER-DLT3pxyw.js +1 -0
  200. package/dist/assets/chunk-OSBZ3O6U-C0W8KSeg.js +1 -0
  201. package/dist/assets/chunk-PUDLZKDR-Cd079yIQ.js +156 -0
  202. package/dist/assets/chunk-Q4XR5HBZ-D0jHa6SO.js +70 -0
  203. package/dist/assets/chunk-QBLGF6JB-p4omp7uO.js +1 -0
  204. package/dist/assets/chunk-R7FJI6CG-CZ_p9hSr.js +1 -0
  205. package/dist/assets/chunk-RYQCIY6F-CZA9pvFX.js +1 -0
  206. package/dist/assets/chunk-U6XO7XAA-CcXKsWxp.js +2 -0
  207. package/dist/assets/chunk-V7JOEXUC-CVDtR75H.js +206 -0
  208. package/dist/assets/chunk-VAUOI2AC-B-W2_9Ot.js +1 -0
  209. package/dist/assets/chunk-VR4S4FIN-FD3kWh32.js +1 -0
  210. package/dist/assets/chunk-WYO6CB5R-C2bGaS5r.js +127 -0
  211. package/dist/assets/chunk-XXDRQBXY-BBXwjhUx.js +1 -0
  212. package/dist/assets/chunk-Y2CYZVJY-Di0sYzi1.js +1 -0
  213. package/dist/assets/chunk-YOTPTUD7-BXHmEk89.js +1 -0
  214. package/dist/assets/chunk-ZGVPDNZ5-ymgts0zo.js +62 -0
  215. package/dist/assets/chunk-ZIRB5QZD-DncwlQQc.js +32 -0
  216. package/dist/assets/classDiagram-OUVF2IWQ-DKW_dtku.js +1 -0
  217. package/dist/assets/classDiagram-v2-EOCWNBFH-C8Fi7-yv.js +1 -0
  218. package/dist/assets/clojure-CvY8A83L.js +1 -0
  219. package/dist/assets/code-dark-Cjb1QGhu.css +1 -0
  220. package/dist/assets/code-mobile-3C2Rr-CN.css +1 -0
  221. package/dist/assets/codicon-ngg6Pgfi.ttf +0 -0
  222. package/dist/assets/coffee-4LX2Sv8A.js +1 -0
  223. package/dist/assets/core-ZlAPicox.js +3 -0
  224. package/dist/assets/cose-bilkent-JH36ORCC-BNIAz0nN.js +1 -0
  225. package/dist/assets/cpp-D4AzSV28.js +1 -0
  226. package/dist/assets/csharp-C4nWN4Yd.js +1 -0
  227. package/dist/assets/csp-CiEaaS5Z.js +1 -0
  228. package/dist/assets/css-DXxBRsbk.js +3 -0
  229. package/dist/assets/css.worker-DyDu5ynT.js +89 -0
  230. package/dist/assets/cssMode-DDWxTPm_.js +1 -0
  231. package/dist/assets/cynefin-VYW2F7L2-DgXGHlRt.js +1 -0
  232. package/dist/assets/cynefinDiagram-TSTJHNR4-CwpobXIl.js +62 -0
  233. package/dist/assets/cypher-DOMzqyFA.js +1 -0
  234. package/dist/assets/cytoscape.esm-Cl8iC3D7.js +321 -0
  235. package/dist/assets/dagre-DXlcHgr3.js +1 -0
  236. package/dist/assets/dagre-VKFMJZFB-Dkhlfjna.js +4 -0
  237. package/dist/assets/dart-BWS7MXt_.js +1 -0
  238. package/dist/assets/defaultLocale-GJwWH1Jr.js +1 -0
  239. package/dist/assets/diagram-FQU43EPY-hA8dicp6.js +3 -0
  240. package/dist/assets/diagram-G47NLZAW-BTY6JTzO.js +24 -0
  241. package/dist/assets/diagram-NH7WQ7WH-xkaHHX9M.js +24 -0
  242. package/dist/assets/diagram-OA4YK3LP-gk_fg9UU.js +30 -0
  243. package/dist/assets/diagram-WEI45ONY-BvC8xd6T.js +41 -0
  244. package/dist/assets/dist-ClAL-Tv5.js +1 -0
  245. package/dist/assets/dockerfile-Baf4U3xT.js +1 -0
  246. package/dist/assets/ebnfDiagram-CCIWWBDH-CR7RaNat.js +1 -0
  247. package/dist/assets/ecl-CT7udlkQ.js +1 -0
  248. package/dist/assets/editor-CtbFZlk0.css +1 -0
  249. package/dist/assets/editor.api2-B9h6iFPK.js +872 -0
  250. package/dist/assets/editor.worker-Dpt_xPrs.js +26 -0
  251. package/dist/assets/elixir-CIbAZw5l.js +1 -0
  252. package/dist/assets/erDiagram-Q63AITRT-_M-JFPbj.js +85 -0
  253. package/dist/assets/eventmodeling-45OFAUF4-DXYTQ2nt.js +1 -0
  254. package/dist/assets/file-icons-EFUGSSwf.js +1 -0
  255. package/dist/assets/flow9-Dqiw45WV.js +1 -0
  256. package/dist/assets/flowDiagram-23GEKE2U-DAiS5Y7G.js +1 -0
  257. package/dist/assets/freemarker2-QBsTERH-.js +3 -0
  258. package/dist/assets/fsharp-E8E2L9jU.js +1 -0
  259. package/dist/assets/ganttDiagram-NO4QXBWP-Bl8P1yf_.js +292 -0
  260. package/dist/assets/gitGraph-TEB2WS4Q-CzTBjEvV.js +1 -0
  261. package/dist/assets/gitGraphDiagram-IHSO6WYX-DoHa5ysz.js +106 -0
  262. package/dist/assets/go-CouVSN4D.js +1 -0
  263. package/dist/assets/graphlib-CbSvZcZU.js +1 -0
  264. package/dist/assets/graphql-a6h6h5-t.js +1 -0
  265. package/dist/assets/handlebars-CuoxPo5A.js +1 -0
  266. package/dist/assets/hcl-vso3e6N-.js +1 -0
  267. package/dist/assets/html-gX5PEu0Q.js +1 -0
  268. package/dist/assets/html.worker-IWNXhnIC.js +502 -0
  269. package/dist/assets/htmlMode-DIWUbUxd.js +1 -0
  270. package/dist/assets/index-BpHPeJf0.js +10 -0
  271. package/dist/assets/info-DKCQHKI2-DznP7j3s.js +1 -0
  272. package/dist/assets/infoDiagram-FWYZ7A6U-DSFcSuUs.js +2 -0
  273. package/dist/assets/ini-SwZZkotR.js +1 -0
  274. package/dist/assets/init-BPLPMQ3Y.js +1 -0
  275. package/dist/assets/ishikawaDiagram-FXEZZL3T-DdkqullI.js +70 -0
  276. package/dist/assets/java-CtRLC4_3.js +1 -0
  277. package/dist/assets/javascript-BYKGIUGs.js +1 -0
  278. package/dist/assets/journeyDiagram-5HDEW3XC-B4hRnQJr.js +139 -0
  279. package/dist/assets/json.worker-c4h5s80L.js +58 -0
  280. package/dist/assets/jsonMode-AFmQQP6u.js +7 -0
  281. package/dist/assets/jsx-runtime-BthL93pI.js +1 -0
  282. package/dist/assets/julia-CuJWFKQH.js +1 -0
  283. package/dist/assets/kanban-definition-HUTT4EX6-tm2FZB2E.js +89 -0
  284. package/dist/assets/katex-C8DPyI6s.js +257 -0
  285. package/dist/assets/kotlin-B_kBhsre.js +1 -0
  286. package/dist/assets/less-CtrHIfz3.js +2 -0
  287. package/dist/assets/lexon-yVt1pJLu.js +1 -0
  288. package/dist/assets/line-CmsjK4kn.js +1 -0
  289. package/dist/assets/linear-Dld3_ERu.js +1 -0
  290. package/dist/assets/liquid-DBIl-f0z.js +1 -0
  291. package/dist/assets/lspLanguageFeatures-DK6tqicV.js +4 -0
  292. package/dist/assets/lua-prOwgJ4U.js +1 -0
  293. package/dist/assets/m3-DhrdTQ84.js +1 -0
  294. package/dist/assets/main-DTJwH51M.css +1 -0
  295. package/dist/assets/map-LZWWoeWa.js +1 -0
  296. package/dist/assets/markdown-DoI5HwSM.js +1 -0
  297. package/dist/assets/mdx-DS-bVtZN.js +1 -0
  298. package/dist/assets/mermaid-parser.core-BQtepoLd.js +4 -0
  299. package/dist/assets/mermaid.core-C7UT_EEL.js +11 -0
  300. package/dist/assets/mindmap-definition-LN4V7U3C-DplfjGms.js +96 -0
  301. package/dist/assets/mips-Dye5jsBU.js +1 -0
  302. package/dist/assets/monaco.contribution-CyLosfZI.js +2 -0
  303. package/dist/assets/msdax-TkNOyIL8.js +1 -0
  304. package/dist/assets/mysql-CEc-RKZF.js +1 -0
  305. package/dist/assets/objective-c-CqqCsQz0.js +1 -0
  306. package/dist/assets/ordinal-BLrOss5K.js +1 -0
  307. package/dist/assets/packet-7NZHBO7P-BDEPOPha.js +1 -0
  308. package/dist/assets/pascal-DO_pj8yg.js +1 -0
  309. package/dist/assets/pascaligo-1cbdZdF3.js +1 -0
  310. package/dist/assets/path-YdFzr2W6.js +1 -0
  311. package/dist/assets/pegDiagram-2B236MQR-lu3SdkQs.js +1 -0
  312. package/dist/assets/perl-B_N3PYfC.js +1 -0
  313. package/dist/assets/pgsql-9iYk1FQ7.js +1 -0
  314. package/dist/assets/php-rO2sgoUM.js +1 -0
  315. package/dist/assets/pie-RZYD4A2V-DWIrwPJQ.js +1 -0
  316. package/dist/assets/pieDiagram-ENE6RG2P-3fHbmDf9.js +39 -0
  317. package/dist/assets/pla-Cbgv60kq.js +1 -0
  318. package/dist/assets/postiats-y6xrhy_M.js +1 -0
  319. package/dist/assets/powerquery-BaD8gWNE.js +1 -0
  320. package/dist/assets/powershell-BMhG4JVe.js +1 -0
  321. package/dist/assets/preload-helper-mJowh_hw.js +1 -0
  322. package/dist/assets/protobuf-CdOP5kN3.js +2 -0
  323. package/dist/assets/pug-Ck60hNF9.js +1 -0
  324. package/dist/assets/python-C93q3xXz.js +1 -0
  325. package/dist/assets/qoder-C9LmmOSf.svg +1 -0
  326. package/dist/assets/qoder-Cf9gl0Y5.svg +1 -0
  327. package/dist/assets/qoder-gHCinseV.svg +1 -0
  328. package/dist/assets/qrcode-DV-_rjU8.js +3 -0
  329. package/dist/assets/qsharp-BcaKFfP-.js +1 -0
  330. package/dist/assets/quadrantDiagram-ABIIQ3AL-a5qoWz-X.js +7 -0
  331. package/dist/assets/r-rFNes0iK.js +1 -0
  332. package/dist/assets/radar-I7S5WNFK-B7OaD8vp.js +1 -0
  333. package/dist/assets/railroad-3IZDKUUU-BXW2nuCA.js +1 -0
  334. package/dist/assets/railroad-abnf-AHOZXSZD-Buw9QG2r.js +1 -0
  335. package/dist/assets/railroad-ebnf-EBAXGLYW-BjSi4sWJ.js +1 -0
  336. package/dist/assets/railroad-peg-LSFZ7HO6-DN1wIVhS.js +1 -0
  337. package/dist/assets/railroadDiagram-RFXS5EU6-D2TOuXW9.js +1 -0
  338. package/dist/assets/razor-CBifNGXO.js +1 -0
  339. package/dist/assets/react-dom-gtU6X-Hj.js +1 -0
  340. package/dist/assets/redis-DkpQ3K6G.js +1 -0
  341. package/dist/assets/redshift-Di9N5TI3.js +1 -0
  342. package/dist/assets/requirementDiagram-TGXJPOKE-LQBWpUvd.js +84 -0
  343. package/dist/assets/restructuredtext-By5ZzLt6.js +1 -0
  344. package/dist/assets/review-BcnwQtJv.css +1 -0
  345. package/dist/assets/rough.esm-c4PR5shF.js +1 -0
  346. package/dist/assets/ruby-fF5zGiLp.js +1 -0
  347. package/dist/assets/rust-C5b3AYY6.js +1 -0
  348. package/dist/assets/sankeyDiagram-HTMAVEWB-B1ohYoyK.js +40 -0
  349. package/dist/assets/sb-CD07UNRs.js +1 -0
  350. package/dist/assets/scala-jtn1ip9G.js +1 -0
  351. package/dist/assets/scheme-C4vqMkn_.js +1 -0
  352. package/dist/assets/scss-I4Glxjbz.js +3 -0
  353. package/dist/assets/sequenceDiagram-DBY2YBRQ-C3vM-hMq.js +162 -0
  354. package/dist/assets/shell-DubUcuns.js +1 -0
  355. package/dist/assets/sizeCapture-X5ZJPWSS-daTB6OcF.js +1 -0
  356. package/dist/assets/solidity-CNy2KSl2.js +1 -0
  357. package/dist/assets/sophia-D9_URt84.js +1 -0
  358. package/dist/assets/sparql-DviXpm4C.js +1 -0
  359. package/dist/assets/sql-vDRbAZgK.js +1 -0
  360. package/dist/assets/src-WBW1QxJt.js +1 -0
  361. package/dist/assets/st-CnpnRqA7.js +1 -0
  362. package/dist/assets/stateDiagram-2N3HPSRC-BvFhOryI.js +1 -0
  363. package/dist/assets/stateDiagram-v2-6OUMAXLB-WMrz4PNo.js +1 -0
  364. package/dist/assets/swift-D_g8Ganz.js +1 -0
  365. package/dist/assets/swimlanes-5IMT3BWC-DKF_b-2s.js +2 -0
  366. package/dist/assets/swimlanesDiagram-G3AALYLV-BGswC9oC.js +8 -0
  367. package/dist/assets/systemverilog-OuZa5h1M.js +1 -0
  368. package/dist/assets/tcl-DBm9ucsV.js +1 -0
  369. package/dist/assets/timeline-definition-FHXFAJF6-vAs11ux_.js +120 -0
  370. package/dist/assets/tokens-BwenNn5Q.css +1 -0
  371. package/dist/assets/treeView-QDETBFTQ-BVfICaZQ.js +1 -0
  372. package/dist/assets/treemap-6X3UGDF4-oWHPqo17.js +1 -0
  373. package/dist/assets/ts.worker-BwM5Ha3L.js +67719 -0
  374. package/dist/assets/tsMode-DGZTlTj8.js +11 -0
  375. package/dist/assets/twig-BRzEqX5Y.js +1 -0
  376. package/dist/assets/typescript-KJKfYO7K.js +1 -0
  377. package/dist/assets/typespec-D4ZgGeX8.js +1 -0
  378. package/dist/assets/useWorkspaceMenuKeyboard-CneKAZUJ.js +1 -0
  379. package/dist/assets/vb-DcP4s6WS.js +1 -0
  380. package/dist/assets/vennDiagram-L72KCM5P-BybTX_9B.js +34 -0
  381. package/dist/assets/wardley-OPB4EBWU-Dg8t5y3s.js +1 -0
  382. package/dist/assets/wardleyDiagram-EHGQE667-CicUmMBR.js +78 -0
  383. package/dist/assets/wgsl-CnRJ_QUf.js +298 -0
  384. package/dist/assets/workers-BSQRIkqa.js +1 -0
  385. package/dist/assets/workspace-view-state-CTyDzk2D.js +1 -0
  386. package/dist/assets/xml-C8FAcN6j.js +1 -0
  387. package/dist/assets/xychartDiagram-FW5EYKEG-BhWDyCX-.js +7 -0
  388. package/dist/assets/yaml-BQ4NrRhG.js +1 -0
  389. package/dist/assets/zsh-CLpveKlF.svg +1 -0
  390. package/dist/assets/zsh-FxSpMPbz.svg +1 -0
  391. package/dist/farming-2/app-icon-v2-180.png +0 -0
  392. package/dist/farming-2/app-icon-v2-192.png +0 -0
  393. package/dist/farming-2/app-icon-v2-512.png +0 -0
  394. package/dist/farming-2/app-icon-v2-maskable-512.png +0 -0
  395. package/dist/farming-2/app-icon-v2-master.png +0 -0
  396. package/dist/farming-2/favicon-v2-16.png +0 -0
  397. package/dist/farming-2/favicon-v2-32.png +0 -0
  398. package/dist/farming-2/favicon-v2-48.png +0 -0
  399. package/dist/farming-2/favicon-v2-64.png +0 -0
  400. package/dist/farming-2/favicon-v2.ico +0 -0
  401. package/dist/farming-2/favicon.ico +0 -0
  402. package/dist/farming-2/github-social-preview.png +0 -0
  403. package/dist/farming-2/images/avatar-watercolor-v1-bee-garden.png +0 -0
  404. package/dist/farming-2/images/avatar-watercolor-v2.png +0 -0
  405. package/dist/farming-2/images/avatar-watercolor-v3.png +0 -0
  406. package/dist/farming-2/legacy-icons-v1/favicon.ico +1 -0
  407. package/dist/farming-2/legacy-icons-v1/logo-16.png +0 -0
  408. package/dist/farming-2/legacy-icons-v1/logo-180.png +0 -0
  409. package/dist/farming-2/legacy-icons-v1/logo-192.png +0 -0
  410. package/dist/farming-2/legacy-icons-v1/logo-32.png +0 -0
  411. package/dist/farming-2/legacy-icons-v1/logo-48.png +0 -0
  412. package/dist/farming-2/legacy-icons-v1/logo-512.png +0 -0
  413. package/dist/farming-2/legacy-icons-v1/logo-64.png +0 -0
  414. package/dist/farming-2/logo-16.png +0 -0
  415. package/dist/farming-2/logo-180.png +0 -0
  416. package/dist/farming-2/logo-192.png +0 -0
  417. package/dist/farming-2/logo-32.png +0 -0
  418. package/dist/farming-2/logo-48.png +0 -0
  419. package/dist/farming-2/logo-512.png +0 -0
  420. package/dist/farming-2/logo-64.png +0 -0
  421. package/dist/farming-2/site.webmanifest +27 -0
  422. package/dist/farming-2/style_capsules/watercolor-pastoral.json +94 -0
  423. package/dist/index.html +27 -0
  424. package/frontend/ghostty-loader.js +24 -0
  425. package/frontend/runtime-paths.js +28 -0
  426. package/frontend/session-bridge.js +82 -0
  427. package/frontend/session-modal-bridge.js +331 -0
  428. package/frontend/skin-bridge.js +25 -0
  429. package/frontend/skins/crt/app.js +6940 -0
  430. package/frontend/skins/crt/assets/branding/farming-crt-icon.svg +11 -0
  431. package/frontend/skins/crt/assets/branding/farming-crt-logo-v1.png +0 -0
  432. package/frontend/skins/crt/assets/effects/phosphor-noise.svg +11 -0
  433. package/frontend/skins/crt/assets/fonts/departure-mono/DepartureMonoNerdFontMono-Regular.otf +0 -0
  434. package/frontend/skins/crt/assets/fonts/departure-mono/LICENSE +93 -0
  435. package/frontend/skins/crt/effects.js +8 -0
  436. package/frontend/skins/crt/index.html +1712 -0
  437. package/frontend/skins/crt/styles/billing.css +1003 -0
  438. package/frontend/skins/crt/styles/effects.css +171 -0
  439. package/frontend/skins/crt/styles/history.css +215 -0
  440. package/frontend/skins/crt/styles/monochrome-green.css +509 -0
  441. package/frontend/skins/crt/styles/search.css +271 -0
  442. package/frontend/terminal-bridge.js +192 -0
  443. package/frontend/theme-loader.js +84 -0
  444. package/frontend/themes/terminal/theme.json +24 -0
  445. package/frontend/vendor/ghostty-web/LICENSE +21 -0
  446. package/frontend/vendor/ghostty-web/__vite-browser-external-2447137e.js +4 -0
  447. package/frontend/vendor/ghostty-web/ghostty-vt.wasm +0 -0
  448. package/frontend/vendor/ghostty-web/ghostty-web.js +2963 -0
  449. package/frontend/vendor/ghostty-web/ghostty-web.umd.cjs +13 -0
  450. package/frontend/vendor/ghostty-web/index.d.ts +1842 -0
  451. package/index.html +23 -0
  452. package/package.json +144 -0
  453. package/scripts/sync-ghostty-vendor.js +66 -0
@@ -0,0 +1,888 @@
1
+ const fs = require('fs');
2
+ const fsp = require('fs/promises');
3
+ const os = require('os');
4
+ const path = require('path');
5
+ const readline = require('readline');
6
+ const { execFile } = require('child_process');
7
+ const {
8
+ formatAutomationRRuleLabel,
9
+ hasTemporaryWorkspaceReference,
10
+ isTemporaryWorkspace,
11
+ listCodexSessions,
12
+ } = require('./codex-session-history');
13
+ const { isSafeProviderSessionId } = require('./provider-session-id');
14
+
15
+ const DEFAULT_LIMIT = 60;
16
+ const DEFAULT_SCAN_LIMIT = 500;
17
+ const MAX_AGENT_SESSION_HISTORY_LIMIT = 5000;
18
+ const MAX_AGENT_SESSION_SCAN_LIMIT = 5000;
19
+ const CLAUDE_HISTORY_TAIL_BYTES = 2 * 1024 * 1024;
20
+ const QODER_HISTORY_TAIL_BYTES = 2 * 1024 * 1024;
21
+ const MAX_RECENT_FILE_SCAN_DIRECTORIES = 2000;
22
+ const PROVIDERS = new Set(['codex', 'claude', 'opencode', 'qoder']);
23
+
24
+ function quoteCommandArg(value) {
25
+ return `'${String(value).replace(/'/g, `'\\''`)}'`;
26
+ }
27
+
28
+ function normalizePathValue(value) {
29
+ if (typeof value !== 'string') return '';
30
+ const trimmed = value.trim();
31
+ if (!trimmed || trimmed === path.sep) return trimmed;
32
+ return trimmed.replace(/[\\/]+$/, '');
33
+ }
34
+
35
+ function timestampMs(value) {
36
+ const parsed = Date.parse(value || '');
37
+ return Number.isFinite(parsed) ? parsed : 0;
38
+ }
39
+
40
+ function agentSessionIdentity(session) {
41
+ return [
42
+ String(session?.provider || ''),
43
+ String(session?.providerHomeId || 'default'),
44
+ String(session?.id || ''),
45
+ ].join('\u0000');
46
+ }
47
+
48
+ function compareAgentSessions(a, b) {
49
+ const timeDelta = timestampMs(b?.updatedAt || b?.createdAt) - timestampMs(a?.updatedAt || a?.createdAt);
50
+ return timeDelta || agentSessionIdentity(a).localeCompare(agentSessionIdentity(b));
51
+ }
52
+
53
+ function encodeAgentSessionCursor(session) {
54
+ if (!session?.provider || !session?.id) return '';
55
+ return Buffer.from(JSON.stringify({
56
+ version: 1,
57
+ provider: String(session.provider),
58
+ providerHomeId: String(session.providerHomeId || 'default'),
59
+ id: String(session.id),
60
+ updatedAt: String(session.updatedAt || session.createdAt || ''),
61
+ })).toString('base64url');
62
+ }
63
+
64
+ function decodeAgentSessionCursor(value) {
65
+ try {
66
+ const parsed = JSON.parse(Buffer.from(String(value || ''), 'base64url').toString('utf8'));
67
+ if (parsed?.version !== 1 || !parsed.provider || !parsed.id) return null;
68
+ return {
69
+ provider: String(parsed.provider),
70
+ providerHomeId: String(parsed.providerHomeId || 'default'),
71
+ id: String(parsed.id),
72
+ updatedAt: String(parsed.updatedAt || ''),
73
+ };
74
+ } catch {
75
+ return null;
76
+ }
77
+ }
78
+
79
+ function paginateAgentSessions(sessions, options = {}) {
80
+ const limit = Number.isFinite(options.limit)
81
+ ? Math.max(1, Math.min(MAX_AGENT_SESSION_HISTORY_LIMIT, Math.floor(options.limit)))
82
+ : DEFAULT_LIMIT;
83
+ const cursorValue = String(options.cursor || '').trim();
84
+ let start = 0;
85
+ if (cursorValue) {
86
+ const cursor = decodeAgentSessionCursor(cursorValue);
87
+ if (!cursor) return { sessions: [], nextCursor: '', hasMore: false, invalidCursor: true };
88
+ const exactIndex = sessions.findIndex(session => agentSessionIdentity(session) === agentSessionIdentity(cursor));
89
+ if (exactIndex >= 0) {
90
+ start = exactIndex + 1;
91
+ } else {
92
+ const nextIndex = sessions.findIndex(session => compareAgentSessions(session, cursor) > 0);
93
+ start = nextIndex >= 0 ? nextIndex : sessions.length;
94
+ }
95
+ }
96
+ const page = sessions.slice(start, start + limit);
97
+ const hasMore = start + page.length < sessions.length;
98
+ return {
99
+ sessions: page,
100
+ nextCursor: hasMore && page.length > 0 ? encodeAgentSessionCursor(page[page.length - 1]) : '',
101
+ hasMore,
102
+ invalidCursor: false,
103
+ };
104
+ }
105
+
106
+ function searchAgentSessions(sessions, query, options = {}) {
107
+ const normalizedQuery = String(query || '').trim().toLowerCase();
108
+ const limit = Number.isFinite(options.limit)
109
+ ? Math.max(1, Math.min(MAX_AGENT_SESSION_HISTORY_LIMIT, Math.floor(options.limit)))
110
+ : DEFAULT_LIMIT;
111
+ if (!normalizedQuery) {
112
+ return { sessions: [], total: 0, query: '', scope: 'title-project' };
113
+ }
114
+
115
+ const projectNames = options.projectNames && typeof options.projectNames === 'object'
116
+ ? options.projectNames
117
+ : {};
118
+ const matches = sessions.filter(session => {
119
+ const projectPaths = [session?.workspace, session?.cwd];
120
+ return [
121
+ session?.title,
122
+ ...projectPaths,
123
+ ...projectPaths.map(workspace => projectNames[String(workspace || '')]),
124
+ ].some(value => String(value || '').toLowerCase().includes(normalizedQuery));
125
+ });
126
+
127
+ return {
128
+ sessions: matches.slice(0, limit),
129
+ total: matches.length,
130
+ query: normalizedQuery,
131
+ scope: 'title-project',
132
+ };
133
+ }
134
+
135
+ function isAgentManagedWorktree(workspace) {
136
+ const value = normalizePathValue(workspace);
137
+ return value.includes(`${path.sep}.codex${path.sep}worktrees${path.sep}`)
138
+ || value.includes(`${path.sep}.claude${path.sep}worktrees${path.sep}`);
139
+ }
140
+
141
+ function isDefaultClaudeSessionTitle(title) {
142
+ return String(title || '').trim().toLowerCase() === 'claude session';
143
+ }
144
+
145
+ function firstTrimmedString(...values) {
146
+ for (const value of values) {
147
+ if (typeof value !== 'string') continue;
148
+ const trimmed = value.trim();
149
+ if (trimmed) return trimmed;
150
+ }
151
+ return '';
152
+ }
153
+
154
+ function extractClaudeModel(event) {
155
+ return firstTrimmedString(
156
+ event?.model,
157
+ event?.message?.model,
158
+ event?.metadata?.model,
159
+ event?.message?.metadata?.model,
160
+ event?.request?.model,
161
+ event?.options?.model
162
+ );
163
+ }
164
+
165
+ function extractClaudeEffort(event) {
166
+ return firstTrimmedString(
167
+ event?.effort,
168
+ event?.message?.effort,
169
+ event?.metadata?.effort,
170
+ event?.message?.metadata?.effort,
171
+ event?.request?.effort,
172
+ event?.options?.effort
173
+ );
174
+ }
175
+
176
+ function extractQoderModel(event) {
177
+ return firstTrimmedString(
178
+ event?.model,
179
+ event?.message?.model,
180
+ event?.metadata?.model,
181
+ event?.message?.metadata?.model
182
+ );
183
+ }
184
+
185
+ function extractQoderEffort(event) {
186
+ return firstTrimmedString(
187
+ event?.reasoningEffort,
188
+ event?.reasoning_effort,
189
+ event?.effort,
190
+ event?.metadata?.reasoningEffort,
191
+ event?.metadata?.reasoning_effort,
192
+ event?.message?.metadata?.reasoningEffort,
193
+ event?.message?.metadata?.reasoning_effort
194
+ );
195
+ }
196
+
197
+ function isoTimestamp(value) {
198
+ if (typeof value === 'string') {
199
+ const parsed = Date.parse(value);
200
+ return Number.isFinite(parsed) ? new Date(parsed).toISOString() : '';
201
+ }
202
+ if (typeof value === 'number' && Number.isFinite(value) && value > 0) {
203
+ try {
204
+ const date = new Date(value);
205
+ return Number.isFinite(date.getTime()) ? date.toISOString() : '';
206
+ } catch {
207
+ return '';
208
+ }
209
+ }
210
+ return '';
211
+ }
212
+
213
+ function qoderTextFromMessage(message) {
214
+ if (typeof message === 'string') return message.trim();
215
+ if (!message || typeof message !== 'object') return '';
216
+ const content = message.content;
217
+ if (typeof content === 'string') return content.trim();
218
+ if (!Array.isArray(content)) return '';
219
+ return content
220
+ .map(part => {
221
+ if (typeof part === 'string') return part;
222
+ if (!part || typeof part !== 'object') return '';
223
+ if (typeof part.text === 'string') return part.text;
224
+ if (typeof part.content === 'string') return part.content;
225
+ return '';
226
+ })
227
+ .join('\n')
228
+ .trim();
229
+ }
230
+
231
+ function isVisibleAgentSession(session) {
232
+ const provider = String(session?.provider || '').trim().toLowerCase();
233
+ if (provider === 'claude') {
234
+ if (isDefaultClaudeSessionTitle(session?.title)) return false;
235
+ if (isAgentManagedWorktree(session?.cwd) || isAgentManagedWorktree(session?.workspace)) return false;
236
+ }
237
+
238
+ return !isTemporaryWorkspace(session?.cwd)
239
+ && !isTemporaryWorkspace(session?.workspace)
240
+ && !hasTemporaryWorkspaceReference(session?.title);
241
+ }
242
+
243
+ function activeScheduleFromMetadata(value, sessionId = '') {
244
+ if (!value || typeof value !== 'object') return null;
245
+ const rrule = typeof value.rrule === 'string' ? value.rrule.trim() : '';
246
+ if (!rrule) return null;
247
+
248
+ const targetThreadId = typeof value.target_thread_id === 'string'
249
+ ? value.target_thread_id.trim()
250
+ : typeof value.targetThreadId === 'string'
251
+ ? value.targetThreadId.trim()
252
+ : '';
253
+ if (targetThreadId && sessionId && targetThreadId !== sessionId) return null;
254
+
255
+ const rawStatus = typeof value.status === 'string' ? value.status.trim().toUpperCase() : '';
256
+ const enabled = value.enabled !== false && value.active !== false;
257
+ if (rawStatus && !['ACTIVE', 'ENABLED'].includes(rawStatus)) return null;
258
+ if (!enabled) return null;
259
+
260
+ return {
261
+ id: typeof value.id === 'string' ? value.id.trim() : '',
262
+ kind: typeof value.kind === 'string' ? value.kind.trim() : '',
263
+ name: typeof value.name === 'string' ? value.name.trim() : '',
264
+ status: rawStatus || 'ACTIVE',
265
+ rrule,
266
+ label: formatAutomationRRuleLabel(rrule),
267
+ };
268
+ }
269
+
270
+ function scheduleFromClaudeEvent(event, sessionId) {
271
+ const candidates = [
272
+ event?.automation,
273
+ event?.schedule,
274
+ event?.metadata?.automation,
275
+ event?.metadata?.schedule,
276
+ event?.message?.metadata?.automation,
277
+ event?.message?.metadata?.schedule,
278
+ ];
279
+
280
+ for (const candidate of candidates) {
281
+ const schedule = activeScheduleFromMetadata(candidate, sessionId);
282
+ if (schedule) return schedule;
283
+ }
284
+
285
+ return null;
286
+ }
287
+
288
+ async function collectRecentFiles(root, extension, limit, acceptFile = () => true) {
289
+ const directories = [root];
290
+ let files = [];
291
+ let visitedDirectories = 0;
292
+
293
+ while (directories.length > 0 && visitedDirectories < MAX_RECENT_FILE_SCAN_DIRECTORIES) {
294
+ const directory = directories.pop();
295
+ let entries = [];
296
+ try {
297
+ entries = await fsp.readdir(directory, { withFileTypes: true });
298
+ } catch {
299
+ continue;
300
+ }
301
+ visitedDirectories += 1;
302
+ entries.sort((a, b) => {
303
+ if (a.isDirectory() !== b.isDirectory()) return a.isDirectory() ? -1 : 1;
304
+ return a.name.localeCompare(b.name);
305
+ });
306
+
307
+ for (const entry of entries) {
308
+ const fullPath = path.join(directory, entry.name);
309
+ if (entry.isDirectory()) {
310
+ directories.push(fullPath);
311
+ } else if (entry.isFile() && entry.name.endsWith(extension) && acceptFile(fullPath)) {
312
+ let mtimeMs = 0;
313
+ try {
314
+ mtimeMs = (await fsp.stat(fullPath)).mtimeMs;
315
+ } catch {
316
+ mtimeMs = 0;
317
+ }
318
+ files.push({ filePath: fullPath, mtimeMs });
319
+ if (files.length > limit * 2) {
320
+ files = files.sort((a, b) => b.mtimeMs - a.mtimeMs).slice(0, limit);
321
+ }
322
+ }
323
+ }
324
+ }
325
+
326
+ return files.sort((a, b) => b.mtimeMs - a.mtimeMs).slice(0, limit);
327
+ }
328
+
329
+ async function readTextTail(filePath, maxBytes) {
330
+ let handle = null;
331
+ try {
332
+ const stat = await fsp.stat(filePath);
333
+ const start = Math.max(0, stat.size - maxBytes);
334
+ const length = stat.size - start;
335
+ const buffer = Buffer.alloc(length);
336
+ handle = await fsp.open(filePath, 'r');
337
+ await handle.read(buffer, 0, length, start);
338
+ const text = buffer.toString('utf8');
339
+ return start > 0 ? text.replace(/^[^\n]*(\n|$)/, '') : text;
340
+ } catch {
341
+ return '';
342
+ } finally {
343
+ if (handle) {
344
+ await handle.close().catch(() => {});
345
+ }
346
+ }
347
+ }
348
+
349
+ async function readClaudePromptHistory(claudeHome) {
350
+ const historyPath = path.join(claudeHome, 'history.jsonl');
351
+ const entries = new Map();
352
+
353
+ const lines = (await readTextTail(historyPath, CLAUDE_HISTORY_TAIL_BYTES)).split('\n').filter(Boolean);
354
+ for (const line of lines) {
355
+ try {
356
+ const entry = JSON.parse(line);
357
+ if (!entry || typeof entry.sessionId !== 'string') continue;
358
+ entries.set(entry.sessionId, {
359
+ title: typeof entry.display === 'string' ? entry.display.trim() : '',
360
+ workspace: typeof entry.project === 'string' ? normalizePathValue(entry.project) : '',
361
+ updatedAt: typeof entry.timestamp === 'string' ? entry.timestamp : '',
362
+ });
363
+ } catch {
364
+ // Ignore individual corrupt prompt history lines.
365
+ }
366
+ }
367
+
368
+ return entries;
369
+ }
370
+
371
+ function claudeSessionIdFromFilePath(filePath) {
372
+ 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);
373
+ return match ? match[1] : '';
374
+ }
375
+
376
+ async function readClaudeSessionMetadata(filePath, promptHistory, maxLines = 160) {
377
+ const stream = fs.createReadStream(filePath, { encoding: 'utf8' });
378
+ const reader = readline.createInterface({ input: stream, crlfDelay: Infinity });
379
+ const fileSessionId = claudeSessionIdFromFilePath(filePath);
380
+ const metadata = {
381
+ filePath,
382
+ id: fileSessionId,
383
+ title: '',
384
+ cwd: '',
385
+ workspace: '',
386
+ createdAt: '',
387
+ updatedAt: '',
388
+ model: '',
389
+ effort: '',
390
+ source: '',
391
+ schedule: null,
392
+ };
393
+ let lineCount = 0;
394
+
395
+ try {
396
+ for await (const line of reader) {
397
+ if (!line) continue;
398
+ lineCount += 1;
399
+
400
+ try {
401
+ const event = JSON.parse(line);
402
+ if (typeof event.sessionId === 'string') {
403
+ metadata.id = event.sessionId;
404
+ }
405
+ if (typeof event.timestamp === 'string') {
406
+ metadata.updatedAt = event.timestamp;
407
+ metadata.createdAt = metadata.createdAt || event.timestamp;
408
+ }
409
+ if (typeof event.cwd === 'string' && event.cwd.trim()) {
410
+ metadata.cwd = normalizePathValue(event.cwd);
411
+ }
412
+ if (typeof event.entrypoint === 'string' && event.entrypoint.trim()) {
413
+ metadata.source = event.entrypoint.trim();
414
+ }
415
+ if (event.type === 'ai-title' && typeof event.aiTitle === 'string' && event.aiTitle.trim()) {
416
+ metadata.title = event.aiTitle.trim();
417
+ }
418
+ metadata.model = extractClaudeModel(event) || metadata.model;
419
+ metadata.effort = extractClaudeEffort(event) || metadata.effort;
420
+ if (!metadata.schedule) {
421
+ metadata.schedule = scheduleFromClaudeEvent(event, metadata.id || fileSessionId);
422
+ }
423
+ } catch {
424
+ // Ignore individual corrupt session lines.
425
+ }
426
+
427
+ if (lineCount >= maxLines || (metadata.id && metadata.title && metadata.cwd && metadata.model)) {
428
+ break;
429
+ }
430
+ }
431
+ } finally {
432
+ reader.close();
433
+ stream.destroy();
434
+ }
435
+
436
+ if (!metadata.id) return null;
437
+
438
+ const indexed = promptHistory.get(metadata.id);
439
+ metadata.title = metadata.title || indexed?.title || 'Claude session';
440
+ metadata.workspace = normalizePathValue(indexed?.workspace || metadata.cwd || '');
441
+ metadata.updatedAt = metadata.updatedAt || indexed?.updatedAt || '';
442
+ metadata.source = metadata.source || 'claude';
443
+
444
+ return metadata;
445
+ }
446
+
447
+ async function listClaudeSessions(options = {}) {
448
+ const claudeHome = options.claudeHome || path.join(os.homedir(), '.claude');
449
+ const limit = Number.isFinite(options.limit)
450
+ ? Math.max(0, Math.min(MAX_AGENT_SESSION_HISTORY_LIMIT, Math.floor(options.limit)))
451
+ : DEFAULT_LIMIT;
452
+ const scanLimit = Number.isFinite(options.scanLimit)
453
+ ? Math.max(limit, Math.min(MAX_AGENT_SESSION_SCAN_LIMIT, Math.floor(options.scanLimit)))
454
+ : DEFAULT_SCAN_LIMIT;
455
+ const promptHistory = await readClaudePromptHistory(claudeHome);
456
+ const sessionFiles = await collectRecentFiles(path.join(claudeHome, 'projects'), '.jsonl', scanLimit);
457
+
458
+ const sessions = [];
459
+ for (const { filePath, mtimeMs } of sessionFiles) {
460
+ const metadata = await readClaudeSessionMetadata(filePath, promptHistory);
461
+ if (!metadata) continue;
462
+ const mtimeIso = mtimeMs > 0 ? new Date(mtimeMs).toISOString() : '';
463
+ const updatedAt = timestampMs(mtimeIso) > timestampMs(metadata.updatedAt)
464
+ ? mtimeIso
465
+ : (metadata.updatedAt || mtimeIso);
466
+ const session = {
467
+ provider: 'claude',
468
+ providerName: 'Claude',
469
+ id: metadata.id,
470
+ title: metadata.title,
471
+ cwd: metadata.cwd,
472
+ workspace: metadata.workspace,
473
+ updatedAt,
474
+ createdAt: metadata.createdAt,
475
+ archived: false,
476
+ pinned: false,
477
+ unread: false,
478
+ projectless: !metadata.workspace,
479
+ model: metadata.model,
480
+ effort: metadata.effort,
481
+ source: metadata.source,
482
+ schedule: metadata.schedule || undefined,
483
+ capabilities: ['resume', 'fork'],
484
+ };
485
+ if (isVisibleAgentSession(session)) {
486
+ sessions.push(session);
487
+ }
488
+ }
489
+
490
+ return sessions
491
+ .sort((a, b) => timestampMs(b.updatedAt) - timestampMs(a.updatedAt))
492
+ .slice(0, limit);
493
+ }
494
+
495
+ function qoderSessionIdFromFilePath(filePath) {
496
+ 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);
497
+ return match ? match[1] : '';
498
+ }
499
+
500
+ function applyQoderSessionEvent(metadata, event, fileSessionId) {
501
+ if (!event || typeof event !== 'object') return;
502
+ const eventSessionId = typeof event.sessionId === 'string'
503
+ ? event.sessionId
504
+ : typeof event.session_id === 'string'
505
+ ? event.session_id
506
+ : '';
507
+ if (eventSessionId && isSafeProviderSessionId(eventSessionId)) {
508
+ metadata.id = eventSessionId;
509
+ }
510
+
511
+ const timestamp = isoTimestamp(event.timestamp);
512
+ if (timestamp) {
513
+ metadata.updatedAt = timestamp;
514
+ metadata.createdAt = metadata.createdAt || timestamp;
515
+ }
516
+
517
+ if (typeof event.cwd === 'string' && event.cwd.trim()) {
518
+ metadata.cwd = normalizePathValue(event.cwd);
519
+ }
520
+ if (typeof event.entrypoint === 'string' && event.entrypoint.trim()) {
521
+ metadata.source = event.entrypoint.trim();
522
+ }
523
+ if (event.type === 'system' && typeof event.qodercli_version === 'string') {
524
+ metadata.cliVersion = event.qodercli_version.trim();
525
+ }
526
+ if (typeof event.version === 'string' && event.version.trim()) {
527
+ metadata.cliVersion = event.version.trim();
528
+ }
529
+ if (event.type === 'runtime-config' && typeof event.version === 'string') {
530
+ metadata.cliVersion = event.version.trim();
531
+ }
532
+ if (event.type === 'ai-title' && typeof event.aiTitle === 'string' && event.aiTitle.trim()) {
533
+ metadata.title = event.aiTitle.trim();
534
+ }
535
+ if (event.type === 'last-prompt' && typeof event.lastPrompt === 'string' && event.lastPrompt.trim()) {
536
+ metadata.lastPrompt = event.lastPrompt.trim();
537
+ }
538
+ if (!metadata.firstPrompt && event.type === 'user') {
539
+ metadata.firstPrompt = qoderTextFromMessage(event.message);
540
+ }
541
+
542
+ metadata.model = extractQoderModel(event) || metadata.model;
543
+ metadata.effort = extractQoderEffort(event) || metadata.effort;
544
+
545
+ if (!metadata.id && fileSessionId) {
546
+ metadata.id = fileSessionId;
547
+ }
548
+ }
549
+
550
+ async function readQoderSessionMetadata(filePath, maxLines = 160) {
551
+ const fileSessionId = qoderSessionIdFromFilePath(filePath);
552
+ const metadata = {
553
+ filePath,
554
+ id: fileSessionId,
555
+ title: '',
556
+ lastPrompt: '',
557
+ firstPrompt: '',
558
+ cwd: '',
559
+ workspace: '',
560
+ createdAt: '',
561
+ updatedAt: '',
562
+ model: '',
563
+ effort: '',
564
+ source: '',
565
+ cliVersion: '',
566
+ };
567
+
568
+ const stream = fs.createReadStream(filePath, { encoding: 'utf8' });
569
+ const reader = readline.createInterface({ input: stream, crlfDelay: Infinity });
570
+ let lineCount = 0;
571
+
572
+ try {
573
+ for await (const line of reader) {
574
+ if (!line) continue;
575
+ lineCount += 1;
576
+ try {
577
+ applyQoderSessionEvent(metadata, JSON.parse(line), fileSessionId);
578
+ } catch {
579
+ // Ignore individual corrupt session lines.
580
+ }
581
+ if (lineCount >= maxLines || (metadata.id && metadata.cwd && metadata.model && metadata.title)) {
582
+ break;
583
+ }
584
+ }
585
+ } finally {
586
+ reader.close();
587
+ stream.destroy();
588
+ }
589
+
590
+ const tail = await readTextTail(filePath, QODER_HISTORY_TAIL_BYTES);
591
+ for (const line of tail.split('\n').filter(Boolean)) {
592
+ try {
593
+ applyQoderSessionEvent(metadata, JSON.parse(line), fileSessionId);
594
+ } catch {
595
+ // Ignore individual corrupt session lines.
596
+ }
597
+ }
598
+
599
+ if (!metadata.id || !isSafeProviderSessionId(metadata.id)) return null;
600
+ metadata.title = firstTrimmedString(metadata.title, metadata.lastPrompt, metadata.firstPrompt, 'Qoder session');
601
+ metadata.workspace = normalizePathValue(metadata.cwd || '');
602
+ metadata.source = metadata.source || 'qodercli';
603
+
604
+ return metadata;
605
+ }
606
+
607
+ async function listQoderSessions(options = {}) {
608
+ const qoderHome = options.qoderHome || path.join(os.homedir(), '.qoder');
609
+ const limit = Number.isFinite(options.limit)
610
+ ? Math.max(0, Math.min(MAX_AGENT_SESSION_HISTORY_LIMIT, Math.floor(options.limit)))
611
+ : DEFAULT_LIMIT;
612
+ const scanLimit = Number.isFinite(options.scanLimit)
613
+ ? Math.max(limit, Math.min(MAX_AGENT_SESSION_SCAN_LIMIT, Math.floor(options.scanLimit)))
614
+ : DEFAULT_SCAN_LIMIT;
615
+ const projectsRoot = path.join(qoderHome, 'projects');
616
+ // Child-agent transcripts live deeper under <project>/<session-id>/subagents
617
+ // and may repeat the parent id, so only count direct project session files.
618
+ const sessionFiles = await collectRecentFiles(
619
+ projectsRoot,
620
+ '.jsonl',
621
+ scanLimit,
622
+ filePath => path.relative(projectsRoot, filePath).split(path.sep).length === 2
623
+ );
624
+
625
+ const sessions = [];
626
+ for (const { filePath, mtimeMs } of sessionFiles) {
627
+ const metadata = await readQoderSessionMetadata(filePath);
628
+ if (!metadata) continue;
629
+ const mtimeIso = mtimeMs > 0 ? new Date(mtimeMs).toISOString() : '';
630
+ const updatedAt = timestampMs(mtimeIso) > timestampMs(metadata.updatedAt)
631
+ ? mtimeIso
632
+ : (metadata.updatedAt || mtimeIso);
633
+ const session = {
634
+ provider: 'qoder',
635
+ providerName: 'Qoder',
636
+ id: metadata.id,
637
+ title: metadata.title,
638
+ cwd: metadata.cwd,
639
+ workspace: metadata.workspace,
640
+ updatedAt,
641
+ createdAt: metadata.createdAt,
642
+ archived: false,
643
+ pinned: false,
644
+ unread: false,
645
+ projectless: !metadata.workspace,
646
+ model: metadata.model,
647
+ effort: metadata.effort,
648
+ source: metadata.source,
649
+ cliVersion: metadata.cliVersion,
650
+ capabilities: ['resume', 'fork'],
651
+ };
652
+ if (isVisibleAgentSession(session)) {
653
+ sessions.push(session);
654
+ }
655
+ }
656
+
657
+ return sessions
658
+ .sort((a, b) => timestampMs(b.updatedAt) - timestampMs(a.updatedAt))
659
+ .slice(0, limit);
660
+ }
661
+
662
+ function runOpenCodeSessionList(options = {}) {
663
+ const executable = options.opencodeBin || process.env.FARMING_OPENCODE_BIN || 'opencode';
664
+ const maxCount = Number.isFinite(options.maxCount) ? Math.max(1, Math.floor(options.maxCount)) : DEFAULT_SCAN_LIMIT;
665
+ const env = { ...process.env };
666
+ if (options.opencodeHome) env.OPENCODE_CONFIG_DIR = options.opencodeHome;
667
+ return new Promise((resolve, reject) => {
668
+ execFile(executable, ['session', 'list', '--format', 'json', '--max-count', String(maxCount)], {
669
+ env,
670
+ maxBuffer: 4 * 1024 * 1024,
671
+ timeout: 15_000,
672
+ }, (error, stdout) => {
673
+ if (error) {
674
+ reject(error);
675
+ return;
676
+ }
677
+ resolve(stdout);
678
+ });
679
+ });
680
+ }
681
+
682
+ async function listOpenCodeSessions(options = {}) {
683
+ const limit = Number.isFinite(options.limit)
684
+ ? Math.max(0, Math.min(MAX_AGENT_SESSION_HISTORY_LIMIT, Math.floor(options.limit)))
685
+ : DEFAULT_LIMIT;
686
+ const scanLimit = Number.isFinite(options.scanLimit)
687
+ ? Math.max(limit, Math.min(MAX_AGENT_SESSION_SCAN_LIMIT, Math.floor(options.scanLimit)))
688
+ : DEFAULT_SCAN_LIMIT;
689
+ const listCommand = options.runOpenCodeSessionList || runOpenCodeSessionList;
690
+ let rawSessions = [];
691
+ try {
692
+ const output = await listCommand({
693
+ maxCount: scanLimit,
694
+ opencodeBin: options.opencodeBin,
695
+ opencodeHome: options.opencodeHome,
696
+ });
697
+ rawSessions = JSON.parse(String(output || '[]'));
698
+ } catch {
699
+ return [];
700
+ }
701
+ if (!Array.isArray(rawSessions)) return [];
702
+
703
+ return rawSessions
704
+ .map(raw => {
705
+ const id = firstTrimmedString(raw?.id);
706
+ const cwd = normalizePathValue(raw?.directory || '');
707
+ if (!id || !isSafeProviderSessionId(id)) return null;
708
+ return {
709
+ provider: 'opencode',
710
+ providerName: 'OpenCode',
711
+ id,
712
+ title: firstTrimmedString(raw?.title, 'OpenCode session'),
713
+ cwd,
714
+ workspace: cwd,
715
+ updatedAt: isoTimestamp(raw?.updated),
716
+ createdAt: isoTimestamp(raw?.created),
717
+ archived: false,
718
+ pinned: false,
719
+ unread: false,
720
+ projectless: !cwd,
721
+ source: 'opencode',
722
+ capabilities: ['resume', 'fork'],
723
+ };
724
+ })
725
+ .filter(session => session && isVisibleAgentSession(session))
726
+ .sort((a, b) => timestampMs(b.updatedAt) - timestampMs(a.updatedAt))
727
+ .slice(0, limit);
728
+ }
729
+
730
+ function normalizeCodexSession(session) {
731
+ return {
732
+ provider: 'codex',
733
+ providerName: 'Codex',
734
+ ...session,
735
+ capabilities: ['resume', 'fork'],
736
+ };
737
+ }
738
+
739
+ function normalizeProvider(provider) {
740
+ const normalized = String(provider || '').trim().toLowerCase();
741
+ return PROVIDERS.has(normalized) ? normalized : '';
742
+ }
743
+
744
+ function isSafeSessionId(sessionId) {
745
+ return isSafeProviderSessionId(sessionId);
746
+ }
747
+
748
+ function buildAgentSessionResumeCommand(provider, sessionId, options = {}) {
749
+ const normalizedProvider = normalizeProvider(provider);
750
+ const normalizedSessionId = String(sessionId || '').trim();
751
+ if (!normalizedProvider || !isSafeSessionId(normalizedSessionId)) return '';
752
+
753
+ if (normalizedProvider === 'codex') {
754
+ const cwd = normalizePathValue(options.cwd);
755
+ const cwdArgs = cwd ? ` -C ${quoteCommandArg(cwd)}` : '';
756
+ return `codex ${options.fork === true ? 'fork' : 'resume'}${cwdArgs} ${normalizedSessionId}`;
757
+ }
758
+
759
+ if (normalizedProvider === 'claude') {
760
+ return options.fork === true
761
+ ? `claude --resume ${normalizedSessionId} --fork-session`
762
+ : `claude --resume ${normalizedSessionId}`;
763
+ }
764
+
765
+ if (normalizedProvider === 'qoder') {
766
+ return options.fork === true
767
+ ? `qodercli --resume ${normalizedSessionId} --fork-session`
768
+ : `qodercli --resume ${normalizedSessionId}`;
769
+ }
770
+
771
+ if (normalizedProvider === 'opencode') {
772
+ return `opencode --session ${normalizedSessionId}${options.fork === true ? ' --fork' : ''}`;
773
+ }
774
+
775
+ return '';
776
+ }
777
+
778
+ async function listAgentSessions(options = {}) {
779
+ const limit = Number.isFinite(options.limit)
780
+ ? Math.max(0, Math.min(MAX_AGENT_SESSION_HISTORY_LIMIT, Math.floor(options.limit)))
781
+ : DEFAULT_LIMIT;
782
+ const requestedProviders = Array.isArray(options.providers)
783
+ ? options.providers.map(normalizeProvider).filter(Boolean)
784
+ : ['codex', 'claude', 'opencode', 'qoder'];
785
+ const providers = Array.from(new Set(requestedProviders));
786
+ const sessions = [];
787
+
788
+ const providerHomes = options.providerHomes && typeof options.providerHomes === 'object'
789
+ ? options.providerHomes
790
+ : {};
791
+
792
+ async function listForHomes(provider, homes, fallbackHomeKey, listFn, homeOptionKey, normalize = session => session) {
793
+ const configuredHomes = Array.isArray(homes) && homes.length > 0
794
+ ? homes
795
+ : [{ id: 'default', path: options[fallbackHomeKey] }];
796
+ const perHomeLimit = Number.isFinite(options.providerLimit)
797
+ ? Math.max(0, Math.min(MAX_AGENT_SESSION_HISTORY_LIMIT, Math.floor(options.providerLimit)))
798
+ : limit;
799
+ for (const home of configuredHomes) {
800
+ const providerHomeId = String(home && home.id || 'default').trim() || 'default';
801
+ const providerHomePath = String(home && home.path || '').trim();
802
+ const listOptions = {
803
+ limit: perHomeLimit,
804
+ scanLimit: options.scanLimit,
805
+ opencodeBin: options.opencodeBin,
806
+ runOpenCodeSessionList: options.runOpenCodeSessionList,
807
+ };
808
+ if (providerHomePath) listOptions[homeOptionKey] = providerHomePath;
809
+ const homeSessions = await listFn(listOptions);
810
+ sessions.push(...homeSessions.map(session => normalize({
811
+ ...session,
812
+ providerHomeId,
813
+ providerHomePath,
814
+ })).filter(isVisibleAgentSession));
815
+ }
816
+ }
817
+
818
+ if (providers.includes('codex')) {
819
+ await listForHomes('codex', providerHomes.codex, 'codexHome', listCodexSessions, 'codexHome', normalizeCodexSession);
820
+ }
821
+
822
+ if (providers.includes('claude')) {
823
+ await listForHomes('claude', providerHomes.claude, 'claudeHome', listClaudeSessions, 'claudeHome');
824
+ }
825
+
826
+ if (providers.includes('qoder')) {
827
+ await listForHomes('qoder', providerHomes.qoder, 'qoderHome', listQoderSessions, 'qoderHome');
828
+ }
829
+
830
+ if (providers.includes('opencode')) {
831
+ const configuredHomes = Array.isArray(providerHomes.opencode) && providerHomes.opencode.length > 0
832
+ ? providerHomes.opencode
833
+ : [{ id: 'default', path: options.opencodeHome }];
834
+ const home = configuredHomes.find(candidate => String(candidate?.id || '') === 'default') || configuredHomes[0];
835
+ const providerHomeId = String(home?.id || 'default').trim() || 'default';
836
+ const providerHomePath = String(home?.path || '').trim();
837
+ const homeSessions = await listOpenCodeSessions({
838
+ limit: Number.isFinite(options.providerLimit) ? options.providerLimit : limit,
839
+ scanLimit: options.scanLimit,
840
+ opencodeBin: options.opencodeBin,
841
+ opencodeHome: providerHomePath,
842
+ runOpenCodeSessionList: options.runOpenCodeSessionList,
843
+ });
844
+ sessions.push(...homeSessions.map(session => ({
845
+ ...session,
846
+ providerHomeId,
847
+ providerHomePath,
848
+ })));
849
+ }
850
+
851
+ return sessions
852
+ .sort(compareAgentSessions)
853
+ .slice(0, limit);
854
+ }
855
+
856
+ async function findAgentSession(provider, sessionId, options = {}) {
857
+ const normalizedProvider = normalizeProvider(provider);
858
+ const normalizedSessionId = String(sessionId || '').trim();
859
+ if (!normalizedProvider || !isSafeSessionId(normalizedSessionId)) return null;
860
+
861
+ const sessions = await listAgentSessions({
862
+ ...options,
863
+ providers: [normalizedProvider],
864
+ limit: options.limit || 200,
865
+ providerLimit: options.providerLimit || 200,
866
+ });
867
+ const requestedHomeId = typeof options.providerHomeId === 'string' ? options.providerHomeId.trim() : '';
868
+ return sessions.find(session => session.id === normalizedSessionId && (!requestedHomeId || (session.providerHomeId || 'default') === requestedHomeId)) || null;
869
+ }
870
+
871
+ module.exports = {
872
+ buildAgentSessionResumeCommand,
873
+ compareAgentSessions,
874
+ findAgentSession,
875
+ hasTemporaryWorkspaceReference,
876
+ isAgentManagedWorktree,
877
+ isDefaultClaudeSessionTitle,
878
+ isSafeSessionId,
879
+ isTemporaryWorkspace,
880
+ isVisibleAgentSession,
881
+ listAgentSessions,
882
+ listClaudeSessions,
883
+ listOpenCodeSessions,
884
+ listQoderSessions,
885
+ normalizeProvider,
886
+ paginateAgentSessions,
887
+ searchAgentSessions,
888
+ };