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,189 @@
1
+ const fsp = require('fs/promises');
2
+ const os = require('os');
3
+ const path = require('path');
4
+ const {
5
+ collectRecentJsonlFiles,
6
+ readSessionMetadata,
7
+ sessionIdFromFilePath,
8
+ } = require('./codex-session-history');
9
+ const { isSafeProviderSessionId, isTemporaryProviderSessionId } = require('./provider-session-id');
10
+
11
+ const CACHE_TTL_MS = 5_000;
12
+ const CONTEXT_TAIL_BYTES = 512 * 1024;
13
+ const DEFAULT_SCAN_LIMIT = 800;
14
+
15
+ function numberOrNull(value) {
16
+ const numeric = Number(value);
17
+ return Number.isFinite(numeric) ? numeric : null;
18
+ }
19
+
20
+ function unavailable(agentId, reason) {
21
+ return {
22
+ agentId,
23
+ available: false,
24
+ reason,
25
+ };
26
+ }
27
+
28
+ function contextWindowFromRecord(agentId, sessionId, record) {
29
+ if (!record || record.type !== 'event_msg' || record.payload?.type !== 'token_count') return null;
30
+
31
+ const usage = record.payload.info?.last_token_usage;
32
+ const usedTokens = numberOrNull(usage?.input_tokens);
33
+ const limitTokens = numberOrNull(record.payload.model_context_window ?? record.payload.info?.model_context_window);
34
+ if (usedTokens === null || limitTokens === null || usedTokens < 0 || limitTokens <= 0) return null;
35
+
36
+ const percentUsed = Math.max(0, Math.min(100, Math.round((usedTokens / limitTokens) * 100)));
37
+ return {
38
+ agentId,
39
+ available: true,
40
+ provider: 'codex',
41
+ sessionId,
42
+ usedTokens,
43
+ limitTokens,
44
+ percentUsed,
45
+ percentLeft: Math.max(0, 100 - percentUsed),
46
+ cachedInputTokens: Math.max(0, numberOrNull(usage?.cached_input_tokens) ?? 0),
47
+ outputTokens: Math.max(0, numberOrNull(usage?.output_tokens) ?? 0),
48
+ reasoningOutputTokens: Math.max(0, numberOrNull(usage?.reasoning_output_tokens) ?? 0),
49
+ updatedAt: typeof record.timestamp === 'string' ? record.timestamp : '',
50
+ source: 'codex token_count events',
51
+ confidence: 'exact',
52
+ };
53
+ }
54
+
55
+ async function readJsonlTail(filePath, maxBytes = CONTEXT_TAIL_BYTES) {
56
+ const stat = await fsp.stat(filePath);
57
+ if (stat.size <= 0) return '';
58
+
59
+ const bytesToRead = Math.min(stat.size, maxBytes);
60
+ const start = stat.size - bytesToRead;
61
+ const buffer = Buffer.alloc(bytesToRead);
62
+ const handle = await fsp.open(filePath, 'r');
63
+ try {
64
+ await handle.read(buffer, 0, bytesToRead, start);
65
+ } finally {
66
+ await handle.close();
67
+ }
68
+
69
+ let text = buffer.toString('utf8');
70
+ if (start > 0) {
71
+ const newlineIndex = text.indexOf('\n');
72
+ text = newlineIndex >= 0 ? text.slice(newlineIndex + 1) : '';
73
+ }
74
+ return text;
75
+ }
76
+
77
+ async function readLatestCodexContextWindow({ agentId, sessionId, filePath }) {
78
+ const lines = (await readJsonlTail(filePath)).split(/\r?\n/).filter(Boolean);
79
+ for (let index = lines.length - 1; index >= 0; index -= 1) {
80
+ let record = null;
81
+ try {
82
+ record = JSON.parse(lines[index]);
83
+ } catch {
84
+ continue;
85
+ }
86
+ const contextWindow = contextWindowFromRecord(agentId, sessionId, record);
87
+ if (contextWindow) return contextWindow;
88
+ }
89
+ return unavailable(agentId, 'No Codex token_count event with context window was found.');
90
+ }
91
+
92
+ class CodexContextWindowReader {
93
+ constructor(options = {}) {
94
+ this.codexHome = options.codexHome || path.join(os.homedir(), '.codex');
95
+ this.cacheTtlMs = options.cacheTtlMs ?? CACHE_TTL_MS;
96
+ this.scanLimit = options.scanLimit ?? DEFAULT_SCAN_LIMIT;
97
+ this.now = options.now || (() => Date.now());
98
+ this.fileCache = new Map();
99
+ }
100
+
101
+ codexRoots() {
102
+ return [
103
+ path.join(this.codexHome, 'sessions'),
104
+ path.join(this.codexHome, 'archived_sessions'),
105
+ ];
106
+ }
107
+
108
+ async cachedFilePath(sessionId) {
109
+ const cached = this.fileCache.get(sessionId);
110
+ if (!cached || this.now() - cached.checkedAt > this.cacheTtlMs) return '';
111
+ if (sessionIdFromFilePath(cached.filePath) !== sessionId) return '';
112
+ try {
113
+ const stat = await fsp.stat(cached.filePath);
114
+ if (stat.isFile()) return cached.filePath;
115
+ } catch {
116
+ // Fall through to a fresh scan.
117
+ }
118
+ return '';
119
+ }
120
+
121
+ collectCandidates() {
122
+ return this.codexRoots()
123
+ .flatMap(root => collectRecentJsonlFiles(root, this.scanLimit))
124
+ .sort((a, b) => b.mtimeMs - a.mtimeMs)
125
+ .slice(0, this.scanLimit);
126
+ }
127
+
128
+ async findSessionFile(sessionId) {
129
+ const cached = await this.cachedFilePath(sessionId);
130
+ if (cached) return cached;
131
+
132
+ const candidates = this.collectCandidates();
133
+ const direct = candidates.find(candidate => sessionIdFromFilePath(candidate.filePath) === sessionId);
134
+ if (direct) {
135
+ this.fileCache.set(sessionId, { filePath: direct.filePath, checkedAt: this.now() });
136
+ return direct.filePath;
137
+ }
138
+
139
+ for (const candidate of candidates) {
140
+ const metadata = await readSessionMetadata(candidate.filePath, 40).catch(() => null);
141
+ if (metadata?.id !== sessionId) continue;
142
+ this.fileCache.set(sessionId, { filePath: candidate.filePath, checkedAt: this.now() });
143
+ return candidate.filePath;
144
+ }
145
+
146
+ this.fileCache.delete(sessionId);
147
+ return '';
148
+ }
149
+
150
+ async readForAgent(agent) {
151
+ const requestedCodexHome = String(agent?.providerHomePath || '').trim();
152
+ if (requestedCodexHome && requestedCodexHome !== this.codexHome) {
153
+ const reader = new CodexContextWindowReader({
154
+ codexHome: requestedCodexHome,
155
+ cacheTtlMs: this.cacheTtlMs,
156
+ scanLimit: this.scanLimit,
157
+ now: this.now,
158
+ });
159
+ return reader.readForAgent({ ...agent, providerHomePath: '' });
160
+ }
161
+ const agentId = String(agent?.id || '');
162
+ if (!agentId) return unavailable('', 'Agent id is empty.');
163
+ if (agent?.providerSessionProvider !== 'codex') return unavailable(agentId, 'Agent is not a Codex session.');
164
+
165
+ const sessionId = String(agent.providerSessionId || '').trim();
166
+ if (!sessionId || isTemporaryProviderSessionId(sessionId)) {
167
+ return unavailable(agentId, 'Codex session has not been resolved yet.');
168
+ }
169
+ if (!isSafeProviderSessionId(sessionId)) return unavailable(agentId, 'Codex session id is not safe.');
170
+
171
+ const filePath = await this.findSessionFile(sessionId);
172
+ if (!filePath) return unavailable(agentId, 'Codex session log was not found.');
173
+
174
+ return readLatestCodexContextWindow({ agentId, sessionId, filePath }).catch(() => (
175
+ unavailable(agentId, 'Failed to read Codex context window.')
176
+ ));
177
+ }
178
+
179
+ async readForAgents(agents) {
180
+ const list = Array.isArray(agents) ? agents : [];
181
+ return Promise.all(list.map(agent => this.readForAgent(agent)));
182
+ }
183
+ }
184
+
185
+ module.exports = {
186
+ CodexContextWindowReader,
187
+ contextWindowFromRecord,
188
+ readLatestCodexContextWindow,
189
+ };
@@ -0,0 +1,229 @@
1
+ const { execFile } = require('child_process');
2
+
3
+ const FALLBACK_MODELS = [
4
+ {
5
+ slug: 'gpt-5.5',
6
+ display_name: 'GPT-5.5',
7
+ description: 'Frontier model for complex coding, research, and real-world work.',
8
+ default_reasoning_level: 'medium',
9
+ supported_reasoning_levels: [
10
+ { effort: 'low', description: 'Fast responses with lighter reasoning' },
11
+ { effort: 'medium', description: 'Balances speed and reasoning depth for everyday tasks' },
12
+ { effort: 'high', description: 'Greater reasoning depth for complex problems' },
13
+ { effort: 'xhigh', description: 'Extra high reasoning depth for complex problems' },
14
+ ],
15
+ service_tiers: [
16
+ { id: 'priority', name: 'Fast', description: '1.5x speed, increased usage' },
17
+ ],
18
+ visibility: 'list',
19
+ },
20
+ {
21
+ slug: 'gpt-5.4',
22
+ display_name: 'GPT-5.4',
23
+ description: 'Strong model for everyday coding.',
24
+ default_reasoning_level: 'medium',
25
+ supported_reasoning_levels: [
26
+ { effort: 'low', description: 'Fast responses with lighter reasoning' },
27
+ { effort: 'medium', description: 'Balances speed and reasoning depth for everyday tasks' },
28
+ { effort: 'high', description: 'Greater reasoning depth for complex problems' },
29
+ { effort: 'xhigh', description: 'Extra high reasoning depth for complex problems' },
30
+ ],
31
+ service_tiers: [
32
+ { id: 'priority', name: 'Fast', description: '1.5x speed, increased usage' },
33
+ ],
34
+ visibility: 'list',
35
+ },
36
+ {
37
+ slug: 'gpt-5.4-mini',
38
+ display_name: 'GPT-5.4 Mini',
39
+ description: 'Small, fast, and cost-efficient model for simpler coding tasks.',
40
+ default_reasoning_level: 'medium',
41
+ supported_reasoning_levels: [
42
+ { effort: 'low', description: 'Fast responses with lighter reasoning' },
43
+ { effort: 'medium', description: 'Balances speed and reasoning depth for everyday tasks' },
44
+ { effort: 'high', description: 'Greater reasoning depth for complex problems' },
45
+ ],
46
+ visibility: 'list',
47
+ },
48
+ {
49
+ slug: 'gpt-5.3-codex-spark',
50
+ display_name: 'GPT-5.3 Codex Spark',
51
+ description: 'Ultra-fast coding model.',
52
+ default_reasoning_level: 'medium',
53
+ supported_reasoning_levels: [
54
+ { effort: 'low', description: 'Fast responses with lighter reasoning' },
55
+ { effort: 'medium', description: 'Balances speed and reasoning depth for everyday tasks' },
56
+ ],
57
+ visibility: 'list',
58
+ },
59
+ ];
60
+
61
+ const EFFORT_LABELS = {
62
+ low: 'Low',
63
+ medium: 'Medium',
64
+ high: 'High',
65
+ xhigh: 'Extra High',
66
+ max: 'Max',
67
+ };
68
+
69
+ const DEFAULT_SERVICE_TIER = {
70
+ value: 'default',
71
+ label: 'Standard',
72
+ description: 'Default speed',
73
+ };
74
+
75
+ function compactModelLabel(model) {
76
+ const displayName = String(model.display_name || model.slug || '').trim();
77
+ if (!displayName) return String(model.slug || '').trim();
78
+ return displayName.replace(/^GPT-/i, '');
79
+ }
80
+
81
+ function normalizeReasoningLevels(model) {
82
+ const levels = Array.isArray(model.supported_reasoning_levels)
83
+ ? model.supported_reasoning_levels
84
+ : [];
85
+
86
+ if (levels.length > 0) {
87
+ return levels
88
+ .map(level => ({
89
+ effort: String(level && level.effort || '').trim(),
90
+ description: String(level && level.description || '').trim(),
91
+ }))
92
+ .filter(level => level.effort);
93
+ }
94
+
95
+ const fallbackEffort = String(model.default_reasoning_level || '').trim();
96
+ return fallbackEffort ? [{ effort: fallbackEffort, description: '' }] : [];
97
+ }
98
+
99
+ function normalizeServiceTiers(model) {
100
+ const tiers = Array.isArray(model.service_tiers) ? model.service_tiers : [];
101
+ const normalized = tiers
102
+ .map(tier => ({
103
+ value: String(tier && (tier.id || tier.value) || '').trim(),
104
+ label: String(tier && (tier.name || tier.label) || '').trim(),
105
+ description: String(tier && tier.description || '').trim(),
106
+ }))
107
+ .filter(tier => tier.value);
108
+
109
+ return [
110
+ DEFAULT_SERVICE_TIER,
111
+ ...normalized.map(tier => ({
112
+ ...tier,
113
+ label: tier.label || tier.value,
114
+ })),
115
+ ];
116
+ }
117
+
118
+ function catalogModelsFromJson(rawJson) {
119
+ const parsed = JSON.parse(rawJson);
120
+ const models = Array.isArray(parsed) ? parsed : parsed.models;
121
+ return Array.isArray(models) ? models : [];
122
+ }
123
+
124
+ function visibleModels(models) {
125
+ return models
126
+ .filter(model => model && typeof model.slug === 'string' && model.slug.trim())
127
+ .filter(model => !model.visibility || model.visibility === 'list')
128
+ .sort((a, b) => {
129
+ const priorityA = Number.isFinite(a.priority) ? a.priority : Number.MAX_SAFE_INTEGER;
130
+ const priorityB = Number.isFinite(b.priority) ? b.priority : Number.MAX_SAFE_INTEGER;
131
+ return priorityA - priorityB;
132
+ });
133
+ }
134
+
135
+ function buildModelCatalog(models, source = 'codex') {
136
+ return visibleModels(models).map(model => {
137
+ const modelId = model.slug.trim();
138
+ const levels = normalizeReasoningLevels(model);
139
+
140
+ return {
141
+ value: modelId,
142
+ model: modelId,
143
+ label: compactModelLabel(model),
144
+ displayName: String(model.display_name || model.slug || '').trim(),
145
+ description: String(model.description || '').trim(),
146
+ defaultEffort: String(model.default_reasoning_level || levels[0]?.effort || '').trim(),
147
+ reasoningLevels: levels.map(level => ({
148
+ value: level.effort,
149
+ effort: level.effort,
150
+ label: EFFORT_LABELS[level.effort] || level.effort,
151
+ description: level.description,
152
+ })),
153
+ serviceTiers: normalizeServiceTiers(model),
154
+ source,
155
+ };
156
+ });
157
+ }
158
+
159
+ function buildModelOptions(models, source = 'codex') {
160
+ return buildModelCatalog(models, source).flatMap(model => {
161
+ if (model.reasoningLevels.length === 0) {
162
+ return [{
163
+ value: model.value,
164
+ model: model.value,
165
+ effort: '',
166
+ label: model.label,
167
+ description: model.description,
168
+ source,
169
+ }];
170
+ }
171
+
172
+ return model.reasoningLevels.map(level => ({
173
+ value: `${model.value}:${level.value}`,
174
+ model: model.value,
175
+ effort: level.value,
176
+ label: `${model.label} ${level.label}`,
177
+ description: level.description || model.description,
178
+ source,
179
+ }));
180
+ });
181
+ }
182
+
183
+ function listCodexModelOptions(options = {}) {
184
+ const codexBin = options.codexBin || process.env.FARMING_CODEX_BIN || 'codex';
185
+ const timeout = options.timeout || 3000;
186
+
187
+ return new Promise((resolve) => {
188
+ const fallback = () => resolve({
189
+ models: buildModelOptions(FALLBACK_MODELS, 'fallback'),
190
+ catalog: buildModelCatalog(FALLBACK_MODELS, 'fallback'),
191
+ source: 'fallback',
192
+ });
193
+
194
+ try {
195
+ execFile(codexBin, ['debug', 'models'], {
196
+ timeout,
197
+ maxBuffer: 20 * 1024 * 1024,
198
+ }, (error, stdout) => {
199
+ if (!error && stdout) {
200
+ try {
201
+ const models = catalogModelsFromJson(stdout);
202
+ const modelOptions = buildModelOptions(models, 'codex');
203
+ if (modelOptions.length > 0) {
204
+ resolve({
205
+ models: modelOptions,
206
+ catalog: buildModelCatalog(models, 'codex'),
207
+ source: 'codex',
208
+ });
209
+ return;
210
+ }
211
+ } catch {
212
+ // fall through to fallback catalog
213
+ }
214
+ }
215
+
216
+ fallback();
217
+ });
218
+ } catch {
219
+ fallback();
220
+ }
221
+ });
222
+ }
223
+
224
+ module.exports = {
225
+ buildModelCatalog,
226
+ buildModelOptions,
227
+ catalogModelsFromJson,
228
+ listCodexModelOptions,
229
+ };
@@ -0,0 +1,243 @@
1
+ const EventEmitter = require('events');
2
+ const fs = require('fs');
3
+ const fsp = require('fs/promises');
4
+ const os = require('os');
5
+ const path = require('path');
6
+
7
+ const DEFAULT_POLL_INTERVAL_MS = 1000;
8
+ const DEFAULT_MAX_READ_BYTES = 512 * 1024;
9
+ const USER_MESSAGE_BEGIN = '## My request for Codex:';
10
+
11
+ function normalizePathValue(value) {
12
+ if (typeof value !== 'string') return '';
13
+ const trimmed = value.trim();
14
+ if (!trimmed || trimmed === path.sep) return trimmed;
15
+ return trimmed.replace(/[\\/]+$/, '');
16
+ }
17
+
18
+ function sessionIdFromFilePath(filePath) {
19
+ 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);
20
+ return match ? match[1] : '';
21
+ }
22
+
23
+ function findCodexRolloutFile(sessionId, options = {}) {
24
+ const normalizedSessionId = String(sessionId || '').trim();
25
+ if (!normalizedSessionId) return '';
26
+
27
+ const codexHome = normalizePathValue(options.codexHome || path.join(os.homedir(), '.codex'));
28
+ const roots = [
29
+ path.join(codexHome, 'sessions'),
30
+ path.join(codexHome, 'archived_sessions'),
31
+ ];
32
+
33
+ for (const root of roots) {
34
+ const stack = [root];
35
+ while (stack.length > 0) {
36
+ const directory = stack.pop();
37
+ let entries = [];
38
+ try {
39
+ entries = fs.readdirSync(directory, { withFileTypes: true });
40
+ } catch {
41
+ continue;
42
+ }
43
+
44
+ for (const entry of entries) {
45
+ const fullPath = path.join(directory, entry.name);
46
+ if (entry.isDirectory()) {
47
+ stack.push(fullPath);
48
+ } else if (
49
+ entry.isFile()
50
+ && entry.name.endsWith('.jsonl')
51
+ && sessionIdFromFilePath(fullPath) === normalizedSessionId
52
+ ) {
53
+ return fullPath;
54
+ }
55
+ }
56
+ }
57
+ }
58
+
59
+ return '';
60
+ }
61
+
62
+ function normalizePreviewText(value, maxLength = 400) {
63
+ return String(value || '')
64
+ .replace(/\r\n/g, '\n')
65
+ .replace(/\r/g, '\n')
66
+ .trim()
67
+ .slice(0, maxLength);
68
+ }
69
+
70
+ function stripUserMessagePrefix(value) {
71
+ const text = String(value || '');
72
+ const index = text.indexOf(USER_MESSAGE_BEGIN);
73
+ return index >= 0 ? text.slice(index + USER_MESSAGE_BEGIN.length).trim() : text.trim();
74
+ }
75
+
76
+ function jsonFieldPreview(value, key, maxLength = 120) {
77
+ try {
78
+ const parsed = typeof value === 'string' ? JSON.parse(value) : value;
79
+ const field = parsed && typeof parsed === 'object' ? parsed[key] : '';
80
+ return normalizePreviewText(field, maxLength).replace(/\s+/g, ' ');
81
+ } catch {
82
+ return '';
83
+ }
84
+ }
85
+
86
+ function formatFunctionCall(payload) {
87
+ const name = String(payload.name || '').trim();
88
+ if (!name) return '';
89
+
90
+ if (name === 'exec_command') {
91
+ const cmd = jsonFieldPreview(payload.arguments, 'cmd');
92
+ return cmd ? `running command: ${cmd}` : 'running command';
93
+ }
94
+
95
+ if (name === 'apply_patch') return 'applying patch';
96
+ return `running ${name}`;
97
+ }
98
+
99
+ function formatCodexRolloutEvent(line) {
100
+ let event = null;
101
+ try {
102
+ event = JSON.parse(line);
103
+ } catch {
104
+ return '';
105
+ }
106
+
107
+ const payload = event && typeof event.payload === 'object' ? event.payload : null;
108
+ if (!payload) return '';
109
+
110
+ if (event.type === 'event_msg') {
111
+ if (payload.type === 'agent_message') {
112
+ const message = normalizePreviewText(payload.message);
113
+ return message ? `[Codex live]\r\n${message.replace(/\n/g, '\r\n')}\r\n` : '';
114
+ }
115
+
116
+ if (payload.type === 'user_message') {
117
+ const message = normalizePreviewText(stripUserMessagePrefix(payload.message), 240);
118
+ return message ? `[Codex live] queued user message: ${message.replace(/\n/g, ' ')}\r\n` : '';
119
+ }
120
+
121
+ if (payload.type === 'task_complete') {
122
+ return '[Codex live] task complete\r\n';
123
+ }
124
+
125
+ return '';
126
+ }
127
+
128
+ if (event.type === 'response_item') {
129
+ if (payload.type === 'function_call') {
130
+ const message = formatFunctionCall(payload);
131
+ return message ? `[Codex live] ${message}\r\n` : '';
132
+ }
133
+
134
+ return '';
135
+ }
136
+
137
+ return '';
138
+ }
139
+
140
+ async function readFileRange(filePath, start, end) {
141
+ const length = Math.max(0, end - start);
142
+ if (length <= 0) return '';
143
+
144
+ const handle = await fsp.open(filePath, 'r');
145
+ try {
146
+ const buffer = Buffer.alloc(length);
147
+ const result = await handle.read(buffer, 0, length, start);
148
+ return buffer.subarray(0, result.bytesRead).toString('utf8');
149
+ } finally {
150
+ await handle.close().catch(() => {});
151
+ }
152
+ }
153
+
154
+ class CodexRolloutFollower extends EventEmitter {
155
+ constructor(sessionId, options = {}) {
156
+ super();
157
+ this.sessionId = String(sessionId || '').trim();
158
+ this.codexHome = options.codexHome;
159
+ this.pollIntervalMs = Number.isFinite(options.pollIntervalMs)
160
+ ? Math.max(250, options.pollIntervalMs)
161
+ : DEFAULT_POLL_INTERVAL_MS;
162
+ this.maxReadBytes = Number.isFinite(options.maxReadBytes)
163
+ ? Math.max(4096, options.maxReadBytes)
164
+ : DEFAULT_MAX_READ_BYTES;
165
+ this.filePath = options.filePath || '';
166
+ this.offset = Number.isFinite(options.offset) ? Math.max(0, options.offset) : 0;
167
+ this.partialLine = '';
168
+ this.timer = null;
169
+ this.stopped = false;
170
+ this.polling = false;
171
+ }
172
+
173
+ async start() {
174
+ if (!this.sessionId || this.timer || this.stopped) return;
175
+ this.filePath = this.filePath || findCodexRolloutFile(this.sessionId, {
176
+ codexHome: this.codexHome,
177
+ });
178
+ if (!this.filePath) return;
179
+
180
+ if (!this.offset) {
181
+ try {
182
+ this.offset = (await fsp.stat(this.filePath)).size;
183
+ } catch {
184
+ this.offset = 0;
185
+ }
186
+ }
187
+
188
+ this.timer = setInterval(() => {
189
+ this.poll().catch(error => this.emit('error', error));
190
+ }, this.pollIntervalMs);
191
+ }
192
+
193
+ async poll() {
194
+ if (this.stopped || this.polling || !this.filePath) return;
195
+ this.polling = true;
196
+ try {
197
+ const stat = await fsp.stat(this.filePath);
198
+ if (stat.size < this.offset) {
199
+ this.offset = stat.size;
200
+ this.partialLine = '';
201
+ return;
202
+ }
203
+ if (stat.size === this.offset) return;
204
+
205
+ const oldOffset = this.offset;
206
+ const start = Math.max(oldOffset, stat.size - this.maxReadBytes);
207
+ const droppedPrefix = start > oldOffset;
208
+ const chunk = await readFileRange(this.filePath, start, stat.size);
209
+ this.offset = stat.size;
210
+
211
+ const text = droppedPrefix ? chunk : this.partialLine + chunk;
212
+ const lines = text.split('\n');
213
+ this.partialLine = lines.pop() || '';
214
+ if (droppedPrefix) {
215
+ lines.shift();
216
+ }
217
+
218
+ const formatted = lines
219
+ .map(formatCodexRolloutEvent)
220
+ .filter(Boolean)
221
+ .join('');
222
+ if (formatted) {
223
+ this.emit('data', formatted);
224
+ }
225
+ } finally {
226
+ this.polling = false;
227
+ }
228
+ }
229
+
230
+ stop() {
231
+ this.stopped = true;
232
+ if (this.timer) {
233
+ clearInterval(this.timer);
234
+ this.timer = null;
235
+ }
236
+ }
237
+ }
238
+
239
+ module.exports = {
240
+ CodexRolloutFollower,
241
+ findCodexRolloutFile,
242
+ formatCodexRolloutEvent,
243
+ };