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,790 @@
1
+ #!/usr/bin/env node
2
+ const fs = require('fs');
3
+ const http = require('http');
4
+ const net = require('net');
5
+ const os = require('os');
6
+ const path = require('path');
7
+ const { URLSearchParams } = require('url');
8
+ const { execFileSync, spawn } = require('child_process');
9
+ const { run: runControlCli } = require('./farming-cli');
10
+ const storageLayout = require('./storage-layout');
11
+
12
+ const SERVER_MODE_ARG = '--farming-server';
13
+ const SERVER_MODE_ENV = 'FARMING_RUN_SERVER';
14
+ const NATIVE_PTY_HOST_ARG = '--native-pty-host';
15
+ const DEFAULT_PORT = '6694';
16
+ const DEFAULT_BASE_PATH = '/farming';
17
+ const DEFAULT_SERVER_START_TIMEOUT_MS = 30_000;
18
+ const SERVER_COMMANDS = new Set(['start', 'serve', 'daemon', 'stop', 'status', 'logs', 'url', 'help']);
19
+ const CONTROL_COMMANDS = new Set(['skills', 'memory', 'report', 'list', 'spawn', 'output', 'send', 'kill']);
20
+ const SERVER_BACKED_CONTROL_COMMANDS = new Set(['list', 'spawn', 'output', 'send', 'kill']);
21
+
22
+ function defaultConfigDir(env = process.env) {
23
+ return storageLayout.farmingConfigDir(env);
24
+ }
25
+
26
+ function normalizeBasePath(basePath) {
27
+ if (!basePath || basePath === '/') return '';
28
+ return basePath.endsWith('/') ? basePath.slice(0, -1) : basePath;
29
+ }
30
+
31
+ function routePath(basePath, suffix = '') {
32
+ const normalizedBase = normalizeBasePath(basePath);
33
+ const normalizedSuffix = suffix.startsWith('/') ? suffix : `/${suffix}`;
34
+ return normalizedBase ? `${normalizedBase}${normalizedSuffix}` : normalizedSuffix;
35
+ }
36
+
37
+ function quoteShellArg(arg) {
38
+ return `'${String(arg).replace(/'/g, `'\\''`)}'`;
39
+ }
40
+
41
+ function buildCleanEnvExecCommand(env, command, args = []) {
42
+ const parts = ['/usr/bin/env', '-i'];
43
+ Object.entries(env || {}).forEach(([key, value]) => {
44
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) return;
45
+ if (value === undefined || value === null) return;
46
+ parts.push(`${key}=${String(value)}`);
47
+ });
48
+ parts.push(command, ...args);
49
+ return parts.map(quoteShellArg).join(' ');
50
+ }
51
+
52
+ function readMemoryLimitBytes() {
53
+ const candidates = [
54
+ '/sys/fs/cgroup/memory.max',
55
+ '/sys/fs/cgroup/memory/memory.limit_in_bytes',
56
+ ];
57
+ for (const file of candidates) {
58
+ try {
59
+ const raw = fs.readFileSync(file, 'utf8').trim();
60
+ if (raw && raw !== 'max') {
61
+ const value = Number(raw);
62
+ if (Number.isFinite(value) && value > 0 && value < 9_000_000_000_000_000_000) return value;
63
+ }
64
+ } catch {
65
+ // Ignore missing cgroup files on macOS and non-container Linux hosts.
66
+ }
67
+ }
68
+ return os.totalmem();
69
+ }
70
+
71
+ function computeNodeHeapMb() {
72
+ const limitMb = Math.floor(readMemoryLimitBytes() / 1024 / 1024);
73
+ if (!Number.isFinite(limitMb) || limitMb <= 0) return 4096;
74
+ if (limitMb <= 2048) return Math.max(512, Math.floor(limitMb * 0.75));
75
+ if (limitMb <= 8192) return Math.max(512, limitMb - 1024);
76
+ return Math.max(512, Math.floor(limitMb * 0.9));
77
+ }
78
+
79
+ function appendNodeOption(existing, option) {
80
+ const value = String(existing || '').trim();
81
+ return value ? `${value} ${option}` : option;
82
+ }
83
+
84
+ function buildServerEnv(overrides = {}, baseEnv = process.env) {
85
+ const env = { ...baseEnv, ...overrides };
86
+ delete env.PKG_EXECPATH;
87
+ const cliBinDir = process.pkg ? path.dirname(process.execPath) : path.join(__dirname, '..', 'bin');
88
+ env.PORT = String(env.FARMING_PORT || env.PORT || DEFAULT_PORT);
89
+ env.FARMING_BASE_PATH = env.FARMING_BASE_PATH || DEFAULT_BASE_PATH;
90
+ env.FARMING_CONFIG_DIR = env.FARMING_CONFIG_DIR || defaultConfigDir(env);
91
+ if (process.pkg || env.FARMING_PACKAGED_RUNTIME === '1') {
92
+ env.FARMING_PACKAGED_RUNTIME = '1';
93
+ } else {
94
+ delete env.FARMING_PACKAGED_RUNTIME;
95
+ }
96
+ env.FARMING_NODE_BIN = env.FARMING_NODE_BIN || process.execPath;
97
+ env.FARMING_CLI_BIN_DIR = env.FARMING_CLI_BIN_DIR || cliBinDir;
98
+
99
+ const heapSetting = env.FARMING_NODE_MAX_OLD_SPACE_SIZE || 'auto';
100
+ const hasHeapOption = /(?:^|\s)--max-old-space-size(?:=|\s|$)/.test(env.NODE_OPTIONS || '');
101
+ if (!hasHeapOption && !['0', 'off', 'false', 'OFF', 'FALSE'].includes(heapSetting)) {
102
+ const heapMb = heapSetting === 'auto' ? computeNodeHeapMb() : Number(heapSetting);
103
+ if (Number.isFinite(heapMb) && heapMb > 0) {
104
+ env.NODE_OPTIONS = appendNodeOption(env.NODE_OPTIONS, `--max-old-space-size=${Math.floor(heapMb)}`);
105
+ env.FARMING_EFFECTIVE_NODE_HEAP_MB = String(Math.floor(heapMb));
106
+ }
107
+ }
108
+
109
+ return env;
110
+ }
111
+
112
+ function parseServerArgs(argv) {
113
+ const options = {
114
+ command: argv[0] && SERVER_COMMANDS.has(argv[0]) ? argv[0] : 'start',
115
+ env: {},
116
+ portExplicit: false,
117
+ };
118
+ const rest = options.command === argv[0] ? argv.slice(1) : argv;
119
+
120
+ for (let i = 0; i < rest.length; i++) {
121
+ const arg = rest[i];
122
+ const readValue = (name) => {
123
+ const value = rest[i + 1];
124
+ if (!value || value.startsWith('--')) throw new Error(`${name} requires a value`);
125
+ i++;
126
+ return value;
127
+ };
128
+
129
+ if (arg === '--port') {
130
+ options.env.PORT = readValue(arg);
131
+ options.portExplicit = true;
132
+ } else if (arg.startsWith('--port=')) {
133
+ options.env.PORT = arg.slice('--port='.length);
134
+ options.portExplicit = true;
135
+ } else if (arg === '--base-path') {
136
+ options.env.FARMING_BASE_PATH = readValue(arg);
137
+ } else if (arg.startsWith('--base-path=')) {
138
+ options.env.FARMING_BASE_PATH = arg.slice('--base-path='.length);
139
+ } else if (arg === '--config-dir') {
140
+ options.env.FARMING_CONFIG_DIR = readValue(arg);
141
+ } else if (arg.startsWith('--config-dir=')) {
142
+ options.env.FARMING_CONFIG_DIR = arg.slice('--config-dir='.length);
143
+ } else if (arg === '--home') {
144
+ options.env.HOME = readValue(arg);
145
+ } else if (arg.startsWith('--home=')) {
146
+ options.env.HOME = arg.slice('--home='.length);
147
+ } else if (arg === '--no-auth') {
148
+ options.env.FARMING_DISABLE_AUTH = '1';
149
+ } else if (arg === '--help' || arg === '-h') {
150
+ options.command = 'help';
151
+ } else {
152
+ throw new Error(`Unknown option: ${arg}`);
153
+ }
154
+ }
155
+
156
+ return options;
157
+ }
158
+
159
+ function parseSharedAppOption(arg, rest, index, env) {
160
+ const readValue = (name) => {
161
+ const value = rest[index + 1];
162
+ if (!value || value.startsWith('--')) throw new Error(`${name} requires a value`);
163
+ return value;
164
+ };
165
+
166
+ if (arg === '--port') {
167
+ env.PORT = readValue(arg);
168
+ return 2;
169
+ }
170
+ if (arg.startsWith('--port=')) {
171
+ env.PORT = arg.slice('--port='.length);
172
+ return 1;
173
+ }
174
+ if (arg === '--base-path') {
175
+ env.FARMING_BASE_PATH = readValue(arg);
176
+ return 2;
177
+ }
178
+ if (arg.startsWith('--base-path=')) {
179
+ env.FARMING_BASE_PATH = arg.slice('--base-path='.length);
180
+ return 1;
181
+ }
182
+ if (arg === '--config-dir') {
183
+ env.FARMING_CONFIG_DIR = readValue(arg);
184
+ return 2;
185
+ }
186
+ if (arg.startsWith('--config-dir=')) {
187
+ env.FARMING_CONFIG_DIR = arg.slice('--config-dir='.length);
188
+ return 1;
189
+ }
190
+ if (arg === '--home') {
191
+ env.HOME = readValue(arg);
192
+ return 2;
193
+ }
194
+ if (arg.startsWith('--home=')) {
195
+ env.HOME = arg.slice('--home='.length);
196
+ return 1;
197
+ }
198
+ if (arg === '--no-auth') {
199
+ env.FARMING_DISABLE_AUTH = '1';
200
+ return 1;
201
+ }
202
+ return 0;
203
+ }
204
+
205
+ function isPortOverrideExplicit(overrides = {}, baseEnv = process.env) {
206
+ return Boolean(
207
+ overrides.PORT
208
+ || overrides.FARMING_PORT
209
+ || baseEnv.PORT
210
+ || baseEnv.FARMING_PORT
211
+ );
212
+ }
213
+
214
+ function canListenOnHost(port, host) {
215
+ return new Promise((resolve) => {
216
+ const server = net.createServer();
217
+ server.once('error', () => resolve(false));
218
+ server.once('listening', () => {
219
+ server.close(() => resolve(true));
220
+ });
221
+ server.listen({ host, port });
222
+ });
223
+ }
224
+
225
+ async function canListenOnPort(port) {
226
+ return (await canListenOnHost(port, '127.0.0.1'))
227
+ && (await canListenOnHost(port, '0.0.0.0'));
228
+ }
229
+
230
+ async function findAvailablePort(startPort = Number(DEFAULT_PORT), maxAttempts = 50) {
231
+ for (let offset = 0; offset < maxAttempts; offset++) {
232
+ const port = startPort + offset;
233
+ if (await canListenOnPort(port)) return port;
234
+ }
235
+ throw new Error(`No available port found from ${startPort} to ${startPort + maxAttempts - 1}`);
236
+ }
237
+
238
+ async function adaptServerPort(env, parsed) {
239
+ if (parsed.portExplicit || isPortOverrideExplicit(parsed.env, process.env)) return env;
240
+ const port = await findAvailablePort(Number(env.PORT || DEFAULT_PORT));
241
+ if (String(port) !== String(env.PORT)) env.PORT = String(port);
242
+ return env;
243
+ }
244
+
245
+ function splitControlArgs(argv) {
246
+ const command = argv[0];
247
+ const env = {};
248
+ const controlArgs = [command];
249
+
250
+ for (let i = 1; i < argv.length; i++) {
251
+ const arg = argv[i];
252
+ if (arg === '--') {
253
+ controlArgs.push(...argv.slice(i));
254
+ break;
255
+ }
256
+
257
+ const consumed = parseSharedAppOption(arg, argv, i, env);
258
+ if (consumed > 0) {
259
+ i += consumed - 1;
260
+ continue;
261
+ }
262
+ controlArgs.push(arg);
263
+ }
264
+
265
+ return { argv: controlArgs, env };
266
+ }
267
+
268
+ function parseReviewArgs(argv) {
269
+ const options = {
270
+ branch: '',
271
+ env: {},
272
+ noOpen: false,
273
+ portExplicit: false,
274
+ positional: [],
275
+ };
276
+ for (let index = 0; index < argv.length; index++) {
277
+ const arg = argv[index];
278
+ const readValue = (name) => {
279
+ const value = argv[index + 1];
280
+ if (!value || value.startsWith('--')) throw new Error(`${name} requires a value`);
281
+ index++;
282
+ return value;
283
+ };
284
+ if (arg === '--branch') {
285
+ options.branch = readValue(arg);
286
+ continue;
287
+ }
288
+ if (arg.startsWith('--branch=')) {
289
+ options.branch = arg.slice('--branch='.length);
290
+ continue;
291
+ }
292
+ if (arg === '--no-open') {
293
+ options.noOpen = true;
294
+ continue;
295
+ }
296
+ const consumed = parseSharedAppOption(arg, argv, index, options.env);
297
+ if (consumed > 0) {
298
+ if (arg === '--port' || arg.startsWith('--port=')) options.portExplicit = true;
299
+ index += consumed - 1;
300
+ continue;
301
+ }
302
+ if (arg.startsWith('--')) throw new Error(`Unknown review option: ${arg}`);
303
+ options.positional.push(arg);
304
+ }
305
+ if (options.positional.length !== 3) {
306
+ throw new Error('Usage: farming review <git-dir> <old-revision> <new-revision|now> [--branch <branch>]');
307
+ }
308
+ const [gitDir, base, head] = options.positional;
309
+ if (base === 'now') throw new Error('the old revision cannot be now');
310
+ return { ...options, base, gitDir, head };
311
+ }
312
+
313
+ function runGit(root, args) {
314
+ try {
315
+ return execFileSync('git', ['-C', root, ...args], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim();
316
+ } catch (error) {
317
+ const detail = String(error.stderr || error.message || '').trim();
318
+ throw new Error(detail || `git ${args.join(' ')} failed`, { cause: error });
319
+ }
320
+ }
321
+
322
+ function resolveReviewTarget(parsed) {
323
+ const requestedRoot = path.resolve(parsed.gitDir);
324
+ const root = runGit(requestedRoot, ['rev-parse', '--show-toplevel']);
325
+ const branch = parsed.branch || runGit(root, ['symbolic-ref', '--quiet', '--short', 'HEAD']);
326
+ runGit(root, ['rev-parse', '--verify', `${branch}^{commit}`]);
327
+ const resolveRevision = (revision) => {
328
+ if (revision === 'now') return 'now';
329
+ const branchRelative = revision === 'HEAD'
330
+ ? branch
331
+ : revision.startsWith('HEAD~') || revision.startsWith('HEAD^')
332
+ ? `${branch}${revision.slice('HEAD'.length)}`
333
+ : revision;
334
+ return runGit(root, ['rev-parse', '--verify', `${branchRelative}^{commit}`]);
335
+ };
336
+ return {
337
+ base: resolveRevision(parsed.base),
338
+ branch,
339
+ head: resolveRevision(parsed.head),
340
+ root,
341
+ };
342
+ }
343
+
344
+ function reviewUrl(env, target) {
345
+ const params = new URLSearchParams({
346
+ base: target.base,
347
+ head: target.head,
348
+ root: target.root,
349
+ });
350
+ const token = ['1', 'true', 'yes', 'on'].includes(String(env.FARMING_DISABLE_AUTH || '').toLowerCase()) ? '' : readTokenForEnv(env);
351
+ if (token) params.set('token', token);
352
+ return `${entryUrl(env, '127.0.0.1')}/review?${params.toString()}`;
353
+ }
354
+
355
+ function openBrowser(url) {
356
+ const command = process.platform === 'darwin' ? 'open' : 'xdg-open';
357
+ const child = spawn(command, [url], { detached: true, stdio: 'ignore' });
358
+ child.unref();
359
+ }
360
+
361
+ async function runReview(parsed) {
362
+ const target = resolveReviewTarget(parsed);
363
+ const serverParsed = { command: 'daemon', env: parsed.env, portExplicit: parsed.portExplicit };
364
+ const code = await startDaemon(serverParsed);
365
+ if (code) return code;
366
+ const env = buildControlEnv(parsed.env);
367
+ const url = reviewUrl(env, target);
368
+ console.log(url);
369
+ if (!parsed.noOpen) openBrowser(url);
370
+ return 0;
371
+ }
372
+
373
+ function buildControlEnv(overrides = {}, baseEnv = process.env) {
374
+ const env = buildServerEnv(overrides, baseEnv);
375
+ if (!isPortOverrideExplicit(overrides, baseEnv) && !env.FARMING_CONTROL_URL) {
376
+ const state = readServerState(env.FARMING_CONFIG_DIR);
377
+ if (state.port) env.PORT = String(state.port);
378
+ if (state.basePath) env.FARMING_BASE_PATH = state.basePath;
379
+ }
380
+ env.FARMING_CONTROL_URL = env.FARMING_CONTROL_URL || entryUrl(env, '127.0.0.1');
381
+ env.FARMING_TOKEN_FILE = env.FARMING_TOKEN_FILE || storageLayout.sessionTokenFile(env.FARMING_CONFIG_DIR);
382
+ return env;
383
+ }
384
+
385
+ async function runServerBackedControlCli(argv) {
386
+ const parsed = splitControlArgs(argv);
387
+ const env = buildControlEnv(parsed.env);
388
+ const forwardedKeys = [
389
+ 'FARMING_CONFIG_DIR',
390
+ 'FARMING_CONTROL_URL',
391
+ 'FARMING_TOKEN_FILE',
392
+ 'FARMING_DISABLE_AUTH',
393
+ 'FARMING_BASE_PATH',
394
+ 'HOME',
395
+ 'PORT',
396
+ ];
397
+ const previous = new Map(forwardedKeys.map(key => [key, process.env[key]]));
398
+
399
+ forwardedKeys.forEach((key) => {
400
+ if (env[key] === undefined) delete process.env[key];
401
+ else process.env[key] = env[key];
402
+ });
403
+
404
+ try {
405
+ return await runControlCli(parsed.argv);
406
+ } finally {
407
+ forwardedKeys.forEach((key) => {
408
+ const value = previous.get(key);
409
+ if (value === undefined) delete process.env[key];
410
+ else process.env[key] = value;
411
+ });
412
+ }
413
+ }
414
+
415
+ function childInvocation(env = process.env) {
416
+ if (process.pkg) {
417
+ return { command: '/bin/sh', args: ['-c', buildCleanEnvExecCommand(env, process.execPath, ['--'])] };
418
+ }
419
+ return { command: env.FARMING_NODE_BIN || process.execPath, args: [__filename] };
420
+ }
421
+
422
+ function ensureConfigDir(configDir) {
423
+ fs.mkdirSync(configDir, { recursive: true });
424
+ }
425
+
426
+ function pidFile(configDir) {
427
+ return storageLayout.serverPidFile(configDir);
428
+ }
429
+
430
+ function serverStateFile(configDir) {
431
+ return storageLayout.serverStateFile(configDir);
432
+ }
433
+
434
+ function logFile(configDir) {
435
+ return storageLayout.serverLogFile(configDir);
436
+ }
437
+
438
+ function readServerState(configDir) {
439
+ try {
440
+ return JSON.parse(fs.readFileSync(serverStateFile(configDir), 'utf8'));
441
+ } catch {
442
+ return {};
443
+ }
444
+ }
445
+
446
+ function writeServerState(configDir, env, pid) {
447
+ const state = {
448
+ pid,
449
+ port: Number(env.PORT || DEFAULT_PORT),
450
+ basePath: env.FARMING_BASE_PATH || DEFAULT_BASE_PATH,
451
+ configDir,
452
+ updatedAt: new Date().toISOString(),
453
+ };
454
+ fs.writeFileSync(serverStateFile(configDir), `${JSON.stringify(state, null, 2)}\n`);
455
+ }
456
+
457
+ function readPid(configDir) {
458
+ try {
459
+ return Number(fs.readFileSync(pidFile(configDir), 'utf8').trim());
460
+ } catch {
461
+ return 0;
462
+ }
463
+ }
464
+
465
+ function isRunning(pid) {
466
+ if (!pid) return false;
467
+ try {
468
+ process.kill(pid, 0);
469
+ return true;
470
+ } catch {
471
+ return false;
472
+ }
473
+ }
474
+
475
+ function tailFile(file, lineCount = 80) {
476
+ try {
477
+ return fs.readFileSync(file, 'utf8').split(/\r?\n/).slice(-lineCount).join('\n').trim();
478
+ } catch {
479
+ return '';
480
+ }
481
+ }
482
+
483
+ function entryUrl(env, host = 'localhost') {
484
+ const basePath = normalizeBasePath(env.FARMING_BASE_PATH || DEFAULT_BASE_PATH) || '/';
485
+ return `http://${host}:${env.PORT}${basePath}`;
486
+ }
487
+
488
+ function readTokenForEnv(env) {
489
+ const tokenFile = storageLayout.sessionTokenFile(env.FARMING_CONFIG_DIR || defaultConfigDir(env));
490
+ try {
491
+ return fs.readFileSync(tokenFile, 'utf8').trim();
492
+ } catch {
493
+ return '';
494
+ }
495
+ }
496
+
497
+ function serverStartTimeoutMs(env) {
498
+ const parsed = Number(env.FARMING_START_TIMEOUT_MS || env.FARMING_SERVER_START_TIMEOUT_MS);
499
+ if (Number.isFinite(parsed) && parsed > 0) return parsed;
500
+ return DEFAULT_SERVER_START_TIMEOUT_MS;
501
+ }
502
+
503
+ function waitForServer(env, timeoutMs = serverStartTimeoutMs(env), childPid = 0) {
504
+ const startedAt = Date.now();
505
+ const port = Number(env.PORT || DEFAULT_PORT);
506
+ const authDisabled = ['1', 'true', 'yes', 'on'].includes(String(env.FARMING_DISABLE_AUTH || '').toLowerCase());
507
+
508
+ return new Promise((resolve, reject) => {
509
+ const tick = () => {
510
+ if (childPid && !isRunning(childPid)) {
511
+ reject(new Error('server process exited before becoming ready'));
512
+ return;
513
+ }
514
+ const token = authDisabled ? '' : readTokenForEnv(env);
515
+ if (!authDisabled && !token) {
516
+ if (Date.now() - startedAt >= timeoutMs) {
517
+ reject(new Error('server did not create its token file before timeout'));
518
+ return;
519
+ }
520
+ setTimeout(tick, 250);
521
+ return;
522
+ }
523
+ const readyPath = authDisabled
524
+ ? routePath(env.FARMING_BASE_PATH || DEFAULT_BASE_PATH, '/api/auth/status')
525
+ : `${routePath(env.FARMING_BASE_PATH || DEFAULT_BASE_PATH, '/')}?token=${encodeURIComponent(token)}`;
526
+ const req = http.request({
527
+ host: '127.0.0.1',
528
+ port,
529
+ path: readyPath,
530
+ method: 'GET',
531
+ timeout: 500,
532
+ }, (res) => {
533
+ res.resume();
534
+ if (res.statusCode && res.statusCode >= 200 && res.statusCode < 400) {
535
+ resolve();
536
+ return;
537
+ }
538
+ if (Date.now() - startedAt >= timeoutMs) {
539
+ reject(new Error(`server did not accept its startup token before timeout (HTTP ${res.statusCode || 0})`));
540
+ return;
541
+ }
542
+ setTimeout(tick, 250);
543
+ });
544
+ req.on('error', () => {
545
+ if (Date.now() - startedAt >= timeoutMs) {
546
+ reject(new Error('server did not become ready before timeout'));
547
+ return;
548
+ }
549
+ setTimeout(tick, 250);
550
+ });
551
+ req.on('timeout', () => {
552
+ req.destroy();
553
+ });
554
+ req.end();
555
+ };
556
+ tick();
557
+ });
558
+ }
559
+
560
+ function runServerInCurrentProcess() {
561
+ process.env = buildServerEnv();
562
+ const { startServer } = require('./server');
563
+ startServer();
564
+ }
565
+
566
+ function runNativePtyHostInCurrentProcess() {
567
+ const { startNativePtyHostProcess } = require('./native-pty-host');
568
+ startNativePtyHostProcess();
569
+ }
570
+
571
+ async function startForeground(parsed) {
572
+ const env = await adaptServerPort(buildServerEnv(parsed.env), parsed);
573
+ env[SERVER_MODE_ENV] = '1';
574
+ ensureConfigDir(env.FARMING_CONFIG_DIR);
575
+ const invocation = childInvocation(env);
576
+ const child = spawn(invocation.command, invocation.args, {
577
+ env,
578
+ stdio: 'inherit',
579
+ });
580
+ child.on('exit', (code, signal) => {
581
+ if (signal) {
582
+ process.kill(process.pid, signal);
583
+ return;
584
+ }
585
+ process.exit(code || 0);
586
+ });
587
+ child.on('error', (error) => {
588
+ console.error(error.message);
589
+ process.exit(1);
590
+ });
591
+ }
592
+
593
+ async function startDaemon(parsed) {
594
+ const env = await adaptServerPort(buildServerEnv(parsed.env), parsed);
595
+ env[SERVER_MODE_ENV] = '1';
596
+ const configDir = env.FARMING_CONFIG_DIR;
597
+ ensureConfigDir(configDir);
598
+
599
+ const existingPid = readPid(configDir);
600
+ if (isRunning(existingPid)) {
601
+ const state = readServerState(configDir);
602
+ if (state.port) env.PORT = String(state.port);
603
+ if (state.basePath) env.FARMING_BASE_PATH = state.basePath;
604
+ console.log(`Farming is already running (PID ${existingPid})`);
605
+ console.log(entryUrl(env));
606
+ return 0;
607
+ }
608
+
609
+ const out = fs.openSync(logFile(configDir), 'a');
610
+ const invocation = childInvocation(env);
611
+ if (env.FARMING_DEBUG_CLI === '1') {
612
+ fs.appendFileSync(logFile(configDir), [
613
+ `daemon invocation command=${invocation.command}`,
614
+ `daemon invocation args=${JSON.stringify(invocation.args)}`,
615
+ `daemon parent argv=${JSON.stringify(process.argv)}`,
616
+ `daemon parent execPath=${process.execPath}`,
617
+ `daemon child pkg env=${JSON.stringify(Object.fromEntries(Object.entries(env).filter(([key]) => key.startsWith('PKG'))))}`,
618
+ '',
619
+ ].join('\n'));
620
+ }
621
+ const child = spawn(invocation.command, invocation.args, {
622
+ detached: true,
623
+ env,
624
+ stdio: ['ignore', out, out],
625
+ });
626
+ child.unref();
627
+ fs.writeFileSync(pidFile(configDir), String(child.pid));
628
+
629
+ try {
630
+ await waitForServer(env, serverStartTimeoutMs(env), child.pid);
631
+ } catch (error) {
632
+ console.error(error.message);
633
+ const logs = tailFile(logFile(configDir), 80);
634
+ if (logs) console.error(logs);
635
+ return 1;
636
+ }
637
+
638
+ console.log(`Farming started (PID ${child.pid})`);
639
+ writeServerState(configDir, env, child.pid);
640
+ const logs = tailFile(logFile(configDir), 40);
641
+ const urlLines = logs.split(/\r?\n/).filter(line => /Local:|Network:|Token:|Token style:|Token auth:/.test(line));
642
+ if (urlLines.length > 0) {
643
+ console.log(urlLines.join('\n'));
644
+ } else {
645
+ console.log(entryUrl(env));
646
+ }
647
+ return 0;
648
+ }
649
+
650
+ function stopDaemon(parsed) {
651
+ const env = buildServerEnv(parsed.env);
652
+ const configDir = env.FARMING_CONFIG_DIR;
653
+ const pid = readPid(configDir);
654
+ if (!isRunning(pid)) {
655
+ fs.rmSync(pidFile(configDir), { force: true });
656
+ fs.rmSync(serverStateFile(configDir), { force: true });
657
+ console.log('Farming is not running.');
658
+ return 0;
659
+ }
660
+ process.kill(pid, 'SIGTERM');
661
+ fs.rmSync(pidFile(configDir), { force: true });
662
+ fs.rmSync(serverStateFile(configDir), { force: true });
663
+ console.log(`Stopped Farming (PID ${pid})`);
664
+ return 0;
665
+ }
666
+
667
+ function statusDaemon(parsed) {
668
+ const env = buildServerEnv(parsed.env);
669
+ const configDir = env.FARMING_CONFIG_DIR;
670
+ const pid = readPid(configDir);
671
+ if (!isRunning(pid)) {
672
+ console.log('Farming is not running.');
673
+ return 0;
674
+ }
675
+ console.log(`Farming is running (PID ${pid})`);
676
+ const logs = tailFile(logFile(configDir), 30);
677
+ if (logs) console.log(logs);
678
+ return 0;
679
+ }
680
+
681
+ function showLogs(parsed) {
682
+ const env = buildServerEnv(parsed.env);
683
+ const logs = tailFile(logFile(env.FARMING_CONFIG_DIR), 120);
684
+ console.log(logs || 'No Farming log found.');
685
+ return 0;
686
+ }
687
+
688
+ function showUrl(parsed) {
689
+ const env = buildServerEnv(parsed.env);
690
+ if (!parsed.portExplicit && !isPortOverrideExplicit(parsed.env, process.env)) {
691
+ const state = readServerState(env.FARMING_CONFIG_DIR);
692
+ if (state.port) env.PORT = String(state.port);
693
+ if (state.basePath) env.FARMING_BASE_PATH = state.basePath;
694
+ }
695
+ console.log(entryUrl(env));
696
+ return 0;
697
+ }
698
+
699
+ function usage() {
700
+ return `Usage:
701
+ farming [start] [--port 6694] [--base-path /farming] [--config-dir ~/.farming]
702
+ farming daemon [--port 6694] [--base-path /farming] [--config-dir ~/.farming]
703
+ farming status
704
+ farming stop
705
+ farming logs
706
+ farming url
707
+ farming review <git-dir> <old-revision> <new-revision|now> [--branch <branch>] [--no-open]
708
+
709
+ Agent control commands are also available:
710
+ farming skills
711
+ farming list [--json] [--parent <agentId>]
712
+ farming spawn --workspace <repo> -- <command...>
713
+ farming output <agentId> [--tail <chars>]
714
+ farming send <agentId> <text...>
715
+ farming kill <agentId>`;
716
+ }
717
+
718
+ async function run(argv = process.argv.slice(2)) {
719
+ if (process.env.FARMING_DEBUG_CLI === '1' && argv[0] === 'debug-argv') {
720
+ console.log(JSON.stringify({
721
+ argv: process.argv,
722
+ execPath: process.execPath,
723
+ pkg: Boolean(process.pkg),
724
+ }, null, 2));
725
+ return 0;
726
+ }
727
+
728
+ if (argv[0] === NATIVE_PTY_HOST_ARG || process.env.FARMING_RUN_NATIVE_PTY_HOST === '1') {
729
+ runNativePtyHostInCurrentProcess();
730
+ return 0;
731
+ }
732
+
733
+ if (process.env[SERVER_MODE_ENV] === '1' || argv[0] === SERVER_MODE_ARG) {
734
+ runServerInCurrentProcess();
735
+ return 0;
736
+ }
737
+
738
+ if (SERVER_BACKED_CONTROL_COMMANDS.has(argv[0])) {
739
+ return runServerBackedControlCli(argv);
740
+ }
741
+
742
+ if (CONTROL_COMMANDS.has(argv[0])) {
743
+ return runControlCli(argv);
744
+ }
745
+
746
+ if (argv[0] === 'review') return runReview(parseReviewArgs(argv.slice(1)));
747
+
748
+ const parsed = parseServerArgs(argv);
749
+ if (parsed.command === 'help') {
750
+ console.log(usage());
751
+ return 0;
752
+ }
753
+ if (parsed.command === 'daemon') return startDaemon(parsed);
754
+ if (parsed.command === 'stop') return stopDaemon(parsed);
755
+ if (parsed.command === 'status') return statusDaemon(parsed);
756
+ if (parsed.command === 'logs') return showLogs(parsed);
757
+ if (parsed.command === 'url') return showUrl(parsed);
758
+ await startForeground(parsed);
759
+ return 0;
760
+ }
761
+
762
+ if (require.main === module) {
763
+ run().then(code => {
764
+ if (code) process.exit(code);
765
+ }).catch(error => {
766
+ console.error(error.message || error);
767
+ process.exit(1);
768
+ });
769
+ }
770
+
771
+ module.exports = {
772
+ SERVER_MODE_ARG,
773
+ NATIVE_PTY_HOST_ARG,
774
+ buildCleanEnvExecCommand,
775
+ childInvocation,
776
+ buildControlEnv,
777
+ buildServerEnv,
778
+ computeNodeHeapMb,
779
+ defaultConfigDir,
780
+ findAvailablePort,
781
+ parseServerArgs,
782
+ parseReviewArgs,
783
+ resolveReviewTarget,
784
+ reviewUrl,
785
+ readServerState,
786
+ serverStartTimeoutMs,
787
+ splitControlArgs,
788
+ run,
789
+ serverStateFile,
790
+ };