farming-code 2.2.29 → 2.2.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (385) hide show
  1. package/README.md +25 -66
  2. package/README.zh_cn.md +15 -66
  3. package/THIRD_PARTY_NOTICES.md +7 -0
  4. package/backend/acp/{client-services.js → client-services.cjs} +132 -134
  5. package/backend/acp/packaged-claude-acp.cjs +37 -0
  6. package/backend/acp/packaged-codex-acp.cjs +37 -0
  7. package/backend/acp/patch-decisions.cjs +182 -0
  8. package/backend/acp/permission-security.cjs +131 -0
  9. package/backend/{acp-checkpoint-store.js → acp-checkpoint-store.cjs} +90 -59
  10. package/backend/{acp-runtime.js → acp-runtime.cjs} +1219 -1125
  11. package/backend/acp-session-state.cjs +622 -0
  12. package/backend/acp-transcript.cjs +525 -0
  13. package/backend/agent-env.cjs +257 -0
  14. package/backend/agent-extension-discovery.cjs +452 -0
  15. package/backend/agent-extension-inventory.cjs +116 -0
  16. package/backend/agent-json-stream.cjs +283 -0
  17. package/backend/agent-lifecycle-journal.cjs +185 -0
  18. package/backend/{agent-manager.js → agent-manager.cjs} +3116 -4275
  19. package/backend/agent-order-transaction.cjs +85 -0
  20. package/backend/agent-order.cjs +159 -0
  21. package/backend/agent-provider-session.cjs +98 -0
  22. package/backend/agent-runtime-binding.cjs +179 -0
  23. package/backend/agent-session-history.cjs +1022 -0
  24. package/backend/agent-session-inventory.cjs +291 -0
  25. package/backend/async-cache.cjs +104 -0
  26. package/backend/atomic-json-store.cjs +67 -0
  27. package/backend/auth.cjs +261 -0
  28. package/backend/authoritative-inventory-cache.cjs +383 -0
  29. package/backend/business-health.cjs +68 -0
  30. package/backend/chat-runtime.cjs +50 -0
  31. package/backend/claude-settings.cjs +132 -0
  32. package/backend/cli-agents.cjs +435 -0
  33. package/backend/codex-context-window.cjs +196 -0
  34. package/backend/codex-models.cjs +228 -0
  35. package/backend/codex-session-archive.cjs +82 -0
  36. package/backend/codex-session-history.cjs +590 -0
  37. package/backend/{codex-terminal-profile.js → codex-terminal-profile.cjs} +149 -155
  38. package/backend/codex-transcript-sanitizer.cjs +130 -0
  39. package/backend/codex-transcript.cjs +2107 -0
  40. package/backend/command-runner-child.cjs +105 -0
  41. package/backend/config-manager.cjs +1263 -0
  42. package/backend/control-api.cjs +439 -0
  43. package/backend/data/LICENSE.cua +21 -0
  44. package/backend/executable-discovery.cjs +204 -0
  45. package/backend/farming-agent-bootstrap.cjs +81 -0
  46. package/backend/farming-agent-bootstrap.zh_cn.md +6 -2
  47. package/backend/{farming-app-cli.js → farming-app-cli.cjs} +441 -493
  48. package/backend/farming-cli.cjs +414 -0
  49. package/backend/farming-net-pass.cjs +319 -0
  50. package/backend/farming-net-registry.cjs +123 -0
  51. package/backend/farming-net-server.cjs +309 -0
  52. package/backend/farming-session-store.cjs +651 -0
  53. package/backend/git-worktree-info.cjs +181 -0
  54. package/backend/haiku-token.cjs +828 -0
  55. package/backend/index-html.cjs +96 -0
  56. package/backend/input-parts.cjs +68 -0
  57. package/backend/input-routing.cjs +40 -0
  58. package/backend/{local-session-engine.js → local-session-engine.cjs} +276 -282
  59. package/backend/main-agent-skills.cjs +309 -0
  60. package/backend/main-page-session.cjs +132 -0
  61. package/backend/native-pty-controller-generation.cjs +139 -0
  62. package/backend/{native-pty-host-client.js → native-pty-host-client.cjs} +338 -346
  63. package/backend/native-pty-host-identity.cjs +125 -0
  64. package/backend/native-pty-host-path.cjs +68 -0
  65. package/backend/{native-pty-host.js → native-pty-host.cjs} +480 -569
  66. package/backend/native-session-engine.cjs +296 -0
  67. package/backend/network.cjs +57 -0
  68. package/backend/npm-update-helper.cjs +399 -0
  69. package/backend/packaged-node-pty.cjs +120 -0
  70. package/backend/preview-session-manager.cjs +89 -0
  71. package/backend/provider-adapters.cjs +492 -0
  72. package/backend/provider-home-configuration.cjs +211 -0
  73. package/backend/provider-session-id.cjs +79 -0
  74. package/backend/provider-session-service.cjs +333 -0
  75. package/backend/qr-share-tickets.cjs +119 -0
  76. package/backend/resource-broadcast-protocol.cjs +50 -0
  77. package/backend/review-diff-router.cjs +202 -0
  78. package/backend/review-diff-service.cjs +1267 -0
  79. package/backend/review-session-router.cjs +93 -0
  80. package/backend/review-session-service.cjs +470 -0
  81. package/backend/review-session-store.cjs +161 -0
  82. package/backend/review-state-router.cjs +132 -0
  83. package/backend/review-state-store.cjs +299 -0
  84. package/backend/run-history-store.cjs +97 -0
  85. package/backend/runtime-dependency-manager.cjs +893 -0
  86. package/backend/runtime-executable-invocation.cjs +37 -0
  87. package/backend/runtime-observation.cjs +96 -0
  88. package/backend/server-process-identity.cjs +70 -0
  89. package/backend/server.cjs +3356 -0
  90. package/backend/session-engine-bridge.cjs +144 -0
  91. package/backend/session-engine-router.cjs +105 -0
  92. package/backend/session-engine.cjs +64 -0
  93. package/backend/session-stream-protocol.cjs +181 -0
  94. package/backend/shell-busy-integration.cjs +442 -0
  95. package/backend/slash-command-discovery.cjs +423 -0
  96. package/backend/storage-layout.cjs +263 -0
  97. package/backend/system-monitor.cjs +96 -0
  98. package/backend/terminal-attach-checkpoint.cjs +73 -0
  99. package/backend/terminal-exit-quiescence.cjs +57 -0
  100. package/backend/{terminal-reducer-flow-control.js → terminal-reducer-flow-control.cjs} +45 -22
  101. package/backend/terminal-runtime-cleanup.cjs +99 -0
  102. package/backend/{terminal-screen-state.js → terminal-screen-state.cjs} +100 -108
  103. package/backend/{terminal-screen-worker-pool.js → terminal-screen-worker-pool.cjs} +89 -79
  104. package/backend/{terminal-screen-worker-thread.js → terminal-screen-worker-thread.cjs} +64 -65
  105. package/backend/terminal-screen-worker.cjs +352 -0
  106. package/backend/terminal-state-serialization.cjs +147 -0
  107. package/backend/{terminal-status.js → terminal-status.cjs} +137 -187
  108. package/backend/theme-manager.cjs +185 -0
  109. package/backend/update-service.cjs +675 -0
  110. package/backend/usage-forecast.cjs +95 -0
  111. package/backend/{usage-history-client.js → usage-history-client.cjs} +144 -94
  112. package/backend/usage-history-smoke.cjs +85 -0
  113. package/backend/usage-history-worker.cjs +60 -0
  114. package/backend/{usage-monitor.js → usage-monitor.cjs} +363 -390
  115. package/backend/workspace-directory.cjs +239 -0
  116. package/backend/workspace-discovery.cjs +271 -0
  117. package/backend/{workspace-file-router.js → workspace-file-router.cjs} +213 -282
  118. package/backend/{workspace-file-service.js → workspace-file-service.cjs} +1139 -1318
  119. package/backend/workspace-root-registry.cjs +192 -0
  120. package/bin/farming +1 -1
  121. package/config/farming.deploy.env.example +1 -1
  122. package/config/farming.install.env.example +1 -1
  123. package/dist/acp/codex-acp-1.1.4.mjs +405 -8
  124. package/dist/assets/App-BCkdpWB6.css +1 -0
  125. package/dist/assets/App-CRjKpaGp.js +697 -0
  126. package/dist/assets/CodeSelect-Ci8sKZPU.js +1 -0
  127. package/dist/assets/CodeSelect-T2eNzrOc.css +1 -0
  128. package/dist/assets/{FileEditorMarkdownPreview-Cs9cLv8a.js → FileEditorMarkdownPreview-V06QHlAg.js} +55 -55
  129. package/dist/assets/FileEditorPane-BX-Wjg9U.js +2 -0
  130. package/dist/assets/IconGlyphs-YhV7tqd4.js +1 -0
  131. package/dist/assets/ProjectFilesSection-BDT2_r0o.js +12 -0
  132. package/dist/assets/ReviewPage-BqAs5sG1.js +3 -0
  133. package/dist/assets/code-dark-B7eM_9G9.css +1 -0
  134. package/dist/assets/{cssMode-Bdg5RpcJ.js → cssMode-ADdAlxTO.js} +1 -1
  135. package/dist/assets/{editor.api2-D74ufkbr.js → editor.api2-BFLAr0YF.js} +162 -162
  136. package/dist/assets/file-icons-BpeqWkIB.js +1 -0
  137. package/dist/assets/{freemarker2-DfMDJfnE.js → freemarker2-C90q5jrp.js} +1 -1
  138. package/dist/assets/{handlebars-BEdPtzMT.js → handlebars-BwUQcEDq.js} +1 -1
  139. package/dist/assets/{html-B1fPb1QD.js → html-1s3uPKfh.js} +1 -1
  140. package/dist/assets/{htmlMode-CY2ZjHxH.js → htmlMode-xtKD99de.js} +1 -1
  141. package/dist/assets/{index-CQNaZc3l.js → index-C8MchCem.js} +3 -3
  142. package/dist/assets/{javascript-BV2OsWA0.js → javascript-Ph7ijyny.js} +1 -1
  143. package/dist/assets/{jsonMode-zd07aeuX.js → jsonMode-D-jGAnFH.js} +1 -1
  144. package/dist/assets/linkComputer-CbGyI_qx.js +1 -0
  145. package/dist/assets/{liquid-BParI24X.js → liquid-0IamE_cI.js} +1 -1
  146. package/dist/assets/{lspLanguageFeatures-BzredkoV.js → lspLanguageFeatures-BxnQunWF.js} +1 -1
  147. package/dist/assets/main-CLKXa6hf.css +1 -0
  148. package/dist/assets/{mdx-vGzUJN98.js → mdx-DdNmfivn.js} +1 -1
  149. package/dist/assets/{monaco.contribution-BmaeBQEc.js → monaco.contribution-B43jsUs1.js} +2 -2
  150. package/dist/assets/{python-CUwdLgsI.js → python-IAt4X5TS.js} +1 -1
  151. package/dist/assets/{razor-BScebUxU.js → razor-DRkFYW0S.js} +1 -1
  152. package/dist/assets/review-C8-oPKXk.css +1 -0
  153. package/dist/assets/{tsMode-DzUAibXK.js → tsMode-_d_4U2gf.js} +1 -1
  154. package/dist/assets/{typescript-D9EOeM7N.js → typescript-C7zcMq9l.js} +1 -1
  155. package/dist/assets/{workers-DAiomYZM.js → workers-D0nOyJzf.js} +1 -1
  156. package/dist/assets/workspace-editor-model-DND_Y-Bj.js +1 -0
  157. package/dist/assets/workspace-editor-monaco-BPWhgcIB.js +4 -0
  158. package/dist/assets/workspace-editor-monaco-N641qPjX.js +1 -0
  159. package/dist/assets/workspace-view-state-k1bTlJ_Z.js +13 -0
  160. package/dist/assets/{xml-wWl1dhkQ.js → xml-BR-HvxT8.js} +1 -1
  161. package/dist/assets/{yaml-Dc2WDaOZ.js → yaml-YtFQwh4q.js} +1 -1
  162. package/dist/index.html +2 -1
  163. package/extensions/browser/backend/agent-browser-runtime.cjs +1040 -0
  164. package/extensions/browser/backend/agent-capability.cjs +85 -0
  165. package/extensions/browser/backend/browser-mcp-server.cjs +655 -0
  166. package/extensions/browser/backend/browser-resource-manager.cjs +1486 -0
  167. package/extensions/browser/backend/browser-resource-store.cjs +228 -0
  168. package/extensions/browser/backend/browser-router.cjs +203 -0
  169. package/extensions/browser/backend/executable-discovery.cjs +248 -0
  170. package/extensions/browser/backend/farming-browser-client.cjs +116 -0
  171. package/extensions/browser/backend/index.cjs +32 -0
  172. package/extensions/browser/backend/managed-chromium-installer.cjs +833 -0
  173. package/extensions/browser/bin/farming-browser +16 -7
  174. package/extensions/computer/backend/agent-capability.cjs +72 -0
  175. package/extensions/computer/backend/computer-constants.cjs +59 -0
  176. package/extensions/computer/backend/computer-mcp-server.cjs +182 -0
  177. package/extensions/computer/backend/computer-resource-manager.cjs +1219 -0
  178. package/extensions/computer/backend/computer-resource-store.cjs +190 -0
  179. package/extensions/computer/backend/computer-router.cjs +257 -0
  180. package/extensions/computer/backend/cua-tools.json +3067 -0
  181. package/extensions/computer/backend/farming-computer-client.cjs +84 -0
  182. package/extensions/computer/backend/index.cjs +35 -0
  183. package/extensions/computer/backend/isolated-browser-provider.cjs +157 -0
  184. package/extensions/computer/bin/farming-computer +131 -0
  185. package/frontend/farming-net/app.js +255 -262
  186. package/frontend/ghostty-loader.js +24 -20
  187. package/frontend/reading-anchor.js +210 -193
  188. package/frontend/runtime-paths.js +24 -26
  189. package/frontend/session-bridge.js +90 -111
  190. package/frontend/session-modal-bridge.js +184 -302
  191. package/frontend/skin-bridge.js +20 -23
  192. package/frontend/skins/crt/app.js +7686 -7901
  193. package/frontend/skins/crt/effects.js +7 -6
  194. package/frontend/skins/crt/index.html +6 -6
  195. package/frontend/skins/crt/styles/markdown.css +4 -4
  196. package/frontend/terminal-bridge.js +174 -181
  197. package/frontend/terminal-replay.js +320 -345
  198. package/frontend/theme-loader.js +55 -71
  199. package/index.html +1 -0
  200. package/package.json +64 -37
  201. package/shared/backend-connection-status.js +38 -69
  202. package/shared/browser-protocol.js +235 -110
  203. package/shared/websocket-liveness.js +40 -0
  204. package/backend/acp/packaged-claude-acp.js +0 -13
  205. package/backend/acp/packaged-codex-acp.js +0 -13
  206. package/backend/acp/patch-decisions.js +0 -153
  207. package/backend/acp/permission-security.js +0 -108
  208. package/backend/acp-session-state.js +0 -644
  209. package/backend/acp-transcript.js +0 -512
  210. package/backend/agent-env.js +0 -250
  211. package/backend/agent-json-stream.js +0 -268
  212. package/backend/agent-lifecycle-journal.js +0 -133
  213. package/backend/agent-memory-report.js +0 -583
  214. package/backend/agent-order.js +0 -166
  215. package/backend/agent-provider-session.js +0 -76
  216. package/backend/agent-runtime-binding.js +0 -174
  217. package/backend/agent-session-history.js +0 -953
  218. package/backend/async-cache.js +0 -94
  219. package/backend/atomic-json-store.js +0 -37
  220. package/backend/auth.js +0 -251
  221. package/backend/bundle-update-helper.js +0 -113
  222. package/backend/chat-runtime.js +0 -28
  223. package/backend/claude-settings.js +0 -121
  224. package/backend/cli-agents.js +0 -486
  225. package/backend/codex-context-window.js +0 -189
  226. package/backend/codex-models.js +0 -226
  227. package/backend/codex-rollout-follower.js +0 -326
  228. package/backend/codex-session-archive.js +0 -65
  229. package/backend/codex-session-history.js +0 -647
  230. package/backend/codex-transcript-sanitizer.js +0 -115
  231. package/backend/codex-transcript.js +0 -2564
  232. package/backend/command-runner-child.js +0 -67
  233. package/backend/config-manager.js +0 -1133
  234. package/backend/control-api.js +0 -455
  235. package/backend/executable-discovery.js +0 -216
  236. package/backend/farming-agent-bootstrap.js +0 -49
  237. package/backend/farming-cli.js +0 -457
  238. package/backend/farming-net-pass.js +0 -285
  239. package/backend/farming-net-registry.js +0 -112
  240. package/backend/farming-net-server.js +0 -298
  241. package/backend/farming-session-store.js +0 -677
  242. package/backend/git-worktree-info.js +0 -181
  243. package/backend/haiku-token.js +0 -772
  244. package/backend/index-html.js +0 -62
  245. package/backend/input-parts.js +0 -54
  246. package/backend/input-routing.js +0 -24
  247. package/backend/json-cli-runtime.js +0 -275
  248. package/backend/main-agent-skills.js +0 -305
  249. package/backend/main-page-session.js +0 -122
  250. package/backend/native-pty-controller-generation.js +0 -106
  251. package/backend/native-pty-host-identity.js +0 -86
  252. package/backend/native-pty-host-path.js +0 -42
  253. package/backend/native-session-engine.js +0 -268
  254. package/backend/network.js +0 -23
  255. package/backend/npm-update-helper.js +0 -374
  256. package/backend/packaged-node-pty.js +0 -99
  257. package/backend/preview-session-manager.js +0 -68
  258. package/backend/provider-adapters.js +0 -399
  259. package/backend/provider-session-id.js +0 -47
  260. package/backend/provider-session-service.js +0 -345
  261. package/backend/qr-share-tickets.js +0 -100
  262. package/backend/review-diff-router.js +0 -180
  263. package/backend/review-diff-service.js +0 -1270
  264. package/backend/review-session-router.js +0 -74
  265. package/backend/review-session-service.js +0 -446
  266. package/backend/review-session-store.js +0 -151
  267. package/backend/review-state-router.js +0 -116
  268. package/backend/review-state-store.js +0 -286
  269. package/backend/run-history-store.js +0 -67
  270. package/backend/runtime-dependency-manager.js +0 -759
  271. package/backend/runtime-executable-invocation.js +0 -20
  272. package/backend/runtime-observation.js +0 -81
  273. package/backend/server-process-identity.js +0 -47
  274. package/backend/server.js +0 -3267
  275. package/backend/session-engine-bridge.js +0 -129
  276. package/backend/session-engine-router.js +0 -66
  277. package/backend/session-engine.js +0 -39
  278. package/backend/session-stream-protocol.js +0 -185
  279. package/backend/shell-busy-integration.js +0 -472
  280. package/backend/slash-command-discovery.js +0 -433
  281. package/backend/storage-layout.js +0 -190
  282. package/backend/system-monitor.js +0 -77
  283. package/backend/terminal-attach-checkpoint.js +0 -74
  284. package/backend/terminal-exit-quiescence.js +0 -39
  285. package/backend/terminal-runtime-cleanup.js +0 -80
  286. package/backend/terminal-screen-worker.js +0 -337
  287. package/backend/terminal-state-serialization.js +0 -127
  288. package/backend/theme-manager.js +0 -163
  289. package/backend/update-service.js +0 -1545
  290. package/backend/usage-forecast.js +0 -86
  291. package/backend/usage-history-scanner.ts +0 -2718
  292. package/backend/usage-history-smoke.js +0 -64
  293. package/backend/usage-history-worker.js +0 -34
  294. package/backend/workspace-directory.js +0 -232
  295. package/backend/workspace-discovery.js +0 -311
  296. package/backend/workspace-root-registry.js +0 -166
  297. package/dist/assets/App-BKNUILuL.css +0 -1
  298. package/dist/assets/App-Ex2oVVXO.js +0 -693
  299. package/dist/assets/FileEditorPane-CNtuGjQ3.js +0 -2
  300. package/dist/assets/IconGlyphs-BClgag6E.js +0 -1
  301. package/dist/assets/ProjectFilesSection-Cf2BEcAN.js +0 -12
  302. package/dist/assets/ReviewPage-BRuxFaH5.js +0 -3
  303. package/dist/assets/code-dark-BEZTQwYZ.css +0 -1
  304. package/dist/assets/file-icons-BOlcJ0ZF.js +0 -1
  305. package/dist/assets/main-DK9Sy7-c.css +0 -1
  306. package/dist/assets/review-BcnwQtJv.css +0 -1
  307. package/dist/assets/workspace-editor-model-CSGCl21x.js +0 -1
  308. package/dist/assets/workspace-editor-monaco-CJNwbpCy.js +0 -4
  309. package/dist/assets/workspace-editor-monaco-CO9w8YV0.js +0 -1
  310. package/dist/assets/workspace-view-state-BjKPYp0E.js +0 -7
  311. package/extensions/browser/backend/agent-browser-runtime.js +0 -1041
  312. package/extensions/browser/backend/agent-capability.js +0 -55
  313. package/extensions/browser/backend/browser-mcp-server.js +0 -621
  314. package/extensions/browser/backend/browser-resource-manager.js +0 -1309
  315. package/extensions/browser/backend/browser-resource-store.js +0 -190
  316. package/extensions/browser/backend/browser-router.js +0 -133
  317. package/extensions/browser/backend/executable-discovery.js +0 -224
  318. package/extensions/browser/backend/farming-browser-client.js +0 -83
  319. package/extensions/browser/backend/index.js +0 -7
  320. package/extensions/browser/frontend/BrowserSidebarPortals.tsx +0 -360
  321. package/extensions/browser/frontend/BrowserViewer.tsx +0 -500
  322. package/extensions/browser/frontend/browser-resource-state.ts +0 -60
  323. package/extensions/browser/frontend/browser.css +0 -567
  324. package/extensions/browser/frontend/types.ts +0 -31
  325. package/extensions/browser/frontend/useBrowserResources.ts +0 -158
  326. package/frontend/vendor/ghostty-web/index.d.ts +0 -1842
  327. package/shared/backend-connection-status.d.ts +0 -37
  328. package/shared/browser-protocol.d.ts +0 -5
  329. /package/dist/assets/{api-w2x5QfxB.js → api-ByCV9MEr.js} +0 -0
  330. /package/dist/assets/{core-vPkV8P_m.js → core-Czwdx12k.js} +0 -0
  331. /package/dist/assets/{fsharp-DNZNZyEE.js → fsharp-BjPpkoJe.js} +0 -0
  332. /package/dist/assets/{go-_kPJjNc_.js → go-BkIDmSUP.js} +0 -0
  333. /package/dist/assets/{graphql-4HCNVt5g.js → graphql-CCJTpqi1.js} +0 -0
  334. /package/dist/assets/{hcl-C87ymY0o.js → hcl-s4z8lUFg.js} +0 -0
  335. /package/dist/assets/{ini-BYrrGNTc.js → ini-CyUW1I7Z.js} +0 -0
  336. /package/dist/assets/{java-B211rJbk.js → java-CFCcGRiM.js} +0 -0
  337. /package/dist/assets/{julia-DVPsRtBm.js → julia-DQyH_EYb.js} +0 -0
  338. /package/dist/assets/{kotlin-BYyNerjp.js → kotlin-B8hA5O51.js} +0 -0
  339. /package/dist/assets/{less-EC9UblGE.js → less-DaVdaas0.js} +0 -0
  340. /package/dist/assets/{lexon-B1yuUdqW.js → lexon-DLBhPd3y.js} +0 -0
  341. /package/dist/assets/{lua-Bo6GFzxT.js → lua-gB1c_cif.js} +0 -0
  342. /package/dist/assets/{m3-C-Y9cBVI.js → m3-C2T3z3gB.js} +0 -0
  343. /package/dist/assets/{markdown-BHu-wLbe.js → markdown-CKq-Euj1.js} +0 -0
  344. /package/dist/assets/{mips-Dkds26rX.js → mips-Bcs5qIDX.js} +0 -0
  345. /package/dist/assets/{msdax-PU4g-8_g.js → msdax-CBP48FHF.js} +0 -0
  346. /package/dist/assets/{mysql-fPpuGpS7.js → mysql-c7tiPcFj.js} +0 -0
  347. /package/dist/assets/{objective-c-Wy1e5JUf.js → objective-c-D4BZkeEV.js} +0 -0
  348. /package/dist/assets/{pascal-BIXwvrqU.js → pascal-CJDZg0MN.js} +0 -0
  349. /package/dist/assets/{pascaligo-DwR0AtL_.js → pascaligo-Bygi8Ynl.js} +0 -0
  350. /package/dist/assets/{perl-CGHAl8my.js → perl-aS8bkf7E.js} +0 -0
  351. /package/dist/assets/{pgsql-B91M73E2.js → pgsql-CzNAYFYl.js} +0 -0
  352. /package/dist/assets/{php-C70ttrCx.js → php-DOtoEFTT.js} +0 -0
  353. /package/dist/assets/{pla-BNrXaRh0.js → pla-DugRnao1.js} +0 -0
  354. /package/dist/assets/{postiats-Dv2IAZR9.js → postiats-DsXwusKh.js} +0 -0
  355. /package/dist/assets/{powerquery-CkY5Wq7J.js → powerquery-DL3o72oD.js} +0 -0
  356. /package/dist/assets/{powershell-uGIYLU3C.js → powershell-C1qHekys.js} +0 -0
  357. /package/dist/assets/{protobuf-CavfmJu-.js → protobuf-DHgsc-cH.js} +0 -0
  358. /package/dist/assets/{pug-Drqnyitx.js → pug-FZXlE_Iu.js} +0 -0
  359. /package/dist/assets/{qrcode-7uGsTEmi.js → qrcode-DJDTdjL7.js} +0 -0
  360. /package/dist/assets/{qsharp-C7yF-Dti.js → qsharp-bLyhI3DT.js} +0 -0
  361. /package/dist/assets/{r-HXLGP0_-.js → r-DjFGXbAa.js} +0 -0
  362. /package/dist/assets/{redis-C4y6mf2p.js → redis-DSoZ_V6u.js} +0 -0
  363. /package/dist/assets/{redshift-DdQrFPrv.js → redshift-CzkdCsrg.js} +0 -0
  364. /package/dist/assets/{restructuredtext-CBrf2PNj.js → restructuredtext-B_XPrGCQ.js} +0 -0
  365. /package/dist/assets/{ruby-CVtMoX2B.js → ruby-Cry2RneJ.js} +0 -0
  366. /package/dist/assets/{rust-Ckq4sbMP.js → rust-CWzdbFq1.js} +0 -0
  367. /package/dist/assets/{sb-er66OpE3.js → sb-DmofU59h.js} +0 -0
  368. /package/dist/assets/{scala-BdWZz-hH.js → scala-BUC2l-vN.js} +0 -0
  369. /package/dist/assets/{scheme-kTV_s2kP.js → scheme-CNIB_72f.js} +0 -0
  370. /package/dist/assets/{scss-Bymy2VJQ.js → scss-DcL4-NbX.js} +0 -0
  371. /package/dist/assets/{shell-bwEP1LQ1.js → shell-CgAGvSSA.js} +0 -0
  372. /package/dist/assets/{solidity-DCddeBgL.js → solidity-DSkt6O_P.js} +0 -0
  373. /package/dist/assets/{sophia-BMN3AQig.js → sophia--5ytcjDN.js} +0 -0
  374. /package/dist/assets/{sparql-CSXOLjzi.js → sparql-C1Srr7cD.js} +0 -0
  375. /package/dist/assets/{sql-COg8ewmK.js → sql-2k_O5fj7.js} +0 -0
  376. /package/dist/assets/{st-CIaZtBS_.js → st-DCCCPqfz.js} +0 -0
  377. /package/dist/assets/{swift-DXiOhUHu.js → swift-Dd8mAfOt.js} +0 -0
  378. /package/dist/assets/{systemverilog-BTDE6Dr2.js → systemverilog-B0-aZYXu.js} +0 -0
  379. /package/dist/assets/{tcl-B0zy9NvV.js → tcl-CZAZwPVX.js} +0 -0
  380. /package/dist/assets/{twig-D594l4Z1.js → twig-D-Ag0tdS.js} +0 -0
  381. /package/dist/assets/{typespec-XKVjaPqo.js → typespec-B7kTFp0Z.js} +0 -0
  382. /package/dist/assets/{useWorkspaceMenuKeyboard-Bpy_s69Z.js → useWorkspaceMenuKeyboard-uYZpDxhU.js} +0 -0
  383. /package/dist/assets/{vb-B2wYoKRV.js → vb-20w1JPum.js} +0 -0
  384. /package/dist/assets/{wgsl-D0Yf2LbK.js → wgsl-CLJfqFt0.js} +0 -0
  385. /package/dist/assets/{workspace-working-copy-C3FSR3N6.js → workspace-working-copy-Cfz07cOd.js} +0 -0
@@ -1,89 +1,141 @@
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 { PACKAGED_CODEX_ACP_ARG, runPackagedCodexAcp } = require('./acp/packaged-codex-acp');
11
- const { PACKAGED_CLAUDE_ACP_ARG, runPackagedClaudeAcp } = require('./acp/packaged-claude-acp');
12
- const {
13
- SERVER_PROCESS_IDENTITY_FORMAT,
14
- matchingProcessIdentity,
15
- readServerProcessIdentity,
16
- } = require('./server-process-identity');
17
- const storageLayout = require('./storage-layout');
18
-
19
- const SERVER_MODE_ARG = '--farming-server';
20
- const SERVER_MODE_ENV = 'FARMING_RUN_SERVER';
21
- const NATIVE_PTY_HOST_ARG = '--native-pty-host';
22
- const USAGE_HISTORY_SMOKE_ARG = '--farming-usage-history-smoke';
23
- const DEFAULT_PORT = '6694';
24
- const DEFAULT_BASE_PATH = '/farming';
25
- const DEFAULT_SERVER_START_TIMEOUT_MS = 30_000;
26
- const DEFAULT_SERVER_START_STABILITY_MS = 1_500;
27
- const DEFAULT_SERVER_STOP_TIMEOUT_MS = 30_000;
1
+ // Generated by scripts/build-backend-runtime.ts. Do not edit.
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+ var farming_app_cli_exports = {};
31
+ __export(farming_app_cli_exports, {
32
+ NATIVE_PTY_HOST_ARG: () => NATIVE_PTY_HOST_ARG,
33
+ SERVER_MODE_ARG: () => SERVER_MODE_ARG,
34
+ buildCleanEnvExecArgs: () => buildCleanEnvExecArgs,
35
+ buildCleanEnvExecCommand: () => buildCleanEnvExecCommand,
36
+ buildControlEnv: () => buildControlEnv,
37
+ buildServerEnv: () => buildServerEnv,
38
+ childInvocation: () => childInvocation,
39
+ cleanupFailedDaemonStart: () => cleanupFailedDaemonStart,
40
+ computeNodeHeapMb: () => computeNodeHeapMb,
41
+ defaultConfigDir: () => defaultConfigDir,
42
+ findAvailablePort: () => findAvailablePort,
43
+ parseReviewArgs: () => parseReviewArgs,
44
+ parseServerArgs: () => parseServerArgs,
45
+ readServerProcessIdentity: () => import_server_process_identity.readServerProcessIdentity,
46
+ readServerState: () => readServerState,
47
+ resolveReviewTarget: () => resolveReviewTarget,
48
+ reviewUrl: () => reviewUrl,
49
+ run: () => run,
50
+ serverStartStabilityMs: () => serverStartStabilityMs,
51
+ serverStartTimeoutMs: () => serverStartTimeoutMs,
52
+ serverStateFile: () => serverStateFile,
53
+ serverStopTimeoutMs: () => serverStopTimeoutMs,
54
+ splitControlArgs: () => splitControlArgs,
55
+ stopDaemon: () => stopDaemon,
56
+ waitForDaemonStop: () => waitForDaemonStop
57
+ });
58
+ module.exports = __toCommonJS(farming_app_cli_exports);
59
+ var fs = __toESM(require("fs"));
60
+ var http = __toESM(require("http"));
61
+ var net = __toESM(require("net"));
62
+ var os = __toESM(require("os"));
63
+ var path = __toESM(require("path"));
64
+ var import_url = require("url");
65
+ var import_child_process = require("child_process");
66
+ var import_farming_cli = require("./farming-cli.cjs");
67
+ var import_packaged_codex_acp = require("./acp/packaged-codex-acp.cjs");
68
+ var import_packaged_claude_acp = require("./acp/packaged-claude-acp.cjs");
69
+ var import_server_process_identity = require("./server-process-identity.cjs");
70
+ var storageLayout = __toESM(require("./storage-layout.cjs"));
71
+ const packagedProcess = process;
72
+ function errorField(error, field) {
73
+ return error && typeof error === "object" && field in error ? error[field] : void 0;
74
+ }
75
+ function errorString(error, field = "message") {
76
+ const value = errorField(error, field);
77
+ return value ? String(value) : "";
78
+ }
79
+ const SERVER_MODE_ARG = "--farming-server";
80
+ const SERVER_MODE_ENV = "FARMING_RUN_SERVER";
81
+ const NATIVE_PTY_HOST_ARG = "--native-pty-host";
82
+ const USAGE_HISTORY_SMOKE_ARG = "--farming-usage-history-smoke";
83
+ const DEFAULT_PORT = "6694";
84
+ const DEFAULT_BASE_PATH = "/farming";
85
+ const DEFAULT_SERVER_START_TIMEOUT_MS = 3e4;
86
+ const DEFAULT_SERVER_START_STABILITY_MS = 1500;
87
+ const DEFAULT_SERVER_STOP_TIMEOUT_MS = 3e4;
28
88
  const SERVER_STOP_POLL_MS = 100;
29
- const SERVER_COMMANDS = new Set(['start', 'serve', 'daemon', 'stop', 'status', 'logs', 'url', 'help']);
30
- const CONTROL_COMMANDS = new Set(['skills', 'capabilities', 'memory', 'report', 'list', 'spawn', 'output', 'send', 'kill']);
31
- const SERVER_BACKED_CONTROL_COMMANDS = new Set(['capabilities', 'list', 'spawn', 'output', 'send', 'kill']);
32
-
89
+ const SERVER_COMMANDS = /* @__PURE__ */ new Set(["start", "serve", "daemon", "stop", "status", "logs", "url", "help"]);
90
+ const CONTROL_COMMANDS = /* @__PURE__ */ new Set(["skills", "capabilities", "list", "spawn", "output", "send", "kill"]);
91
+ const SERVER_BACKED_CONTROL_COMMANDS = /* @__PURE__ */ new Set(["capabilities", "list", "spawn", "output", "send", "kill"]);
33
92
  function defaultConfigDir(env = process.env) {
34
93
  return storageLayout.farmingConfigDir(env);
35
94
  }
36
-
37
95
  function normalizeBasePath(basePath) {
38
- if (!basePath || basePath === '/') return '';
39
- return basePath.endsWith('/') ? basePath.slice(0, -1) : basePath;
96
+ const value = String(basePath || "");
97
+ if (!value || value === "/") return "";
98
+ return value.endsWith("/") ? value.slice(0, -1) : value;
40
99
  }
41
-
42
- function routePath(basePath, suffix = '') {
100
+ function routePath(basePath, suffix = "") {
43
101
  const normalizedBase = normalizeBasePath(basePath);
44
- const normalizedSuffix = suffix.startsWith('/') ? suffix : `/${suffix}`;
102
+ const normalizedSuffix = suffix.startsWith("/") ? suffix : `/${suffix}`;
45
103
  return normalizedBase ? `${normalizedBase}${normalizedSuffix}` : normalizedSuffix;
46
104
  }
47
-
48
105
  function quoteShellArg(arg) {
49
106
  return `'${String(arg).replace(/'/g, `'\\''`)}'`;
50
107
  }
51
-
52
108
  function buildCleanEnvExecCommand(env, command, args = []) {
53
- const parts = ['/usr/bin/env', ...buildCleanEnvExecArgs(env, command, args)];
54
- return parts.map(quoteShellArg).join(' ');
109
+ const parts = ["/usr/bin/env", ...buildCleanEnvExecArgs(env, command, args)];
110
+ return parts.map(quoteShellArg).join(" ");
55
111
  }
56
-
57
112
  function buildCleanEnvExecArgs(env, command, args = []) {
58
- const parts = ['-i'];
113
+ const parts = ["-i"];
59
114
  Object.entries(env || {}).forEach(([key, value]) => {
60
115
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) return;
61
- if (value === undefined || value === null) return;
116
+ if (value === void 0 || value === null) return;
62
117
  parts.push(`${key}=${String(value)}`);
63
118
  });
64
119
  parts.push(command, ...args);
65
120
  return parts;
66
121
  }
67
-
68
122
  function readMemoryLimitBytes() {
69
123
  const candidates = [
70
- '/sys/fs/cgroup/memory.max',
71
- '/sys/fs/cgroup/memory/memory.limit_in_bytes',
124
+ "/sys/fs/cgroup/memory.max",
125
+ "/sys/fs/cgroup/memory/memory.limit_in_bytes"
72
126
  ];
73
127
  for (const file of candidates) {
74
128
  try {
75
- const raw = fs.readFileSync(file, 'utf8').trim();
76
- if (raw && raw !== 'max') {
129
+ const raw = fs.readFileSync(file, "utf8").trim();
130
+ if (raw && raw !== "max") {
77
131
  const value = Number(raw);
78
- if (Number.isFinite(value) && value > 0 && value < 9_000_000_000_000_000_000) return value;
132
+ if (Number.isFinite(value) && value > 0 && value < 9e18) return value;
79
133
  }
80
134
  } catch {
81
- // Ignore missing cgroup files on macOS and non-container Linux hosts.
82
135
  }
83
136
  }
84
137
  return os.totalmem();
85
138
  }
86
-
87
139
  function computeNodeHeapMb() {
88
140
  const limitMb = Math.floor(readMemoryLimitBytes() / 1024 / 1024);
89
141
  if (!Number.isFinite(limitMb) || limitMb <= 0) return 4096;
@@ -91,165 +143,146 @@ function computeNodeHeapMb() {
91
143
  if (limitMb <= 8192) return Math.max(512, limitMb - 1024);
92
144
  return Math.max(512, Math.floor(limitMb * 0.9));
93
145
  }
94
-
95
146
  function appendNodeOption(existing, option) {
96
- const value = String(existing || '').trim();
147
+ const value = String(existing || "").trim();
97
148
  return value ? `${value} ${option}` : option;
98
149
  }
99
-
100
150
  function buildServerEnv(overrides = {}, baseEnv = process.env) {
101
151
  const env = { ...baseEnv, ...overrides };
102
152
  delete env.PKG_EXECPATH;
103
- if (!process.pkg && !env.FARMING_MANAGED_PACKAGE_ROOT) {
153
+ if (!packagedProcess.pkg && !env.FARMING_MANAGED_PACKAGE_ROOT) {
104
154
  try {
105
- env.FARMING_MANAGED_PACKAGE_ROOT = fs.realpathSync(path.join(__dirname, '..'));
155
+ env.FARMING_MANAGED_PACKAGE_ROOT = fs.realpathSync(path.join(__dirname, ".."));
106
156
  } catch {
107
- // npm update verification will remain unavailable when the package root cannot be proven.
108
157
  }
109
158
  }
110
- const cliBinDir = process.pkg ? path.dirname(process.execPath) : path.join(__dirname, '..', 'bin');
159
+ const cliBinDir = packagedProcess.pkg ? path.dirname(process.execPath) : path.join(__dirname, "..", "bin");
111
160
  env.PORT = String(env.FARMING_PORT || env.PORT || DEFAULT_PORT);
112
161
  env.FARMING_BASE_PATH = env.FARMING_BASE_PATH || DEFAULT_BASE_PATH;
113
162
  env.FARMING_CONFIG_DIR = env.FARMING_CONFIG_DIR || defaultConfigDir(env);
114
- if (process.pkg || env.FARMING_PACKAGED_RUNTIME === '1') {
115
- env.FARMING_PACKAGED_RUNTIME = '1';
163
+ if (packagedProcess.pkg || env.FARMING_PACKAGED_RUNTIME === "1") {
164
+ env.FARMING_PACKAGED_RUNTIME = "1";
116
165
  } else {
117
166
  delete env.FARMING_PACKAGED_RUNTIME;
118
167
  }
119
168
  env.FARMING_NODE_BIN = env.FARMING_NODE_BIN || process.execPath;
120
169
  env.FARMING_CLI_BIN_DIR = env.FARMING_CLI_BIN_DIR || cliBinDir;
121
-
122
- const heapSetting = env.FARMING_NODE_MAX_OLD_SPACE_SIZE || 'auto';
123
- const hasHeapOption = /(?:^|\s)--max-old-space-size(?:=|\s|$)/.test(env.NODE_OPTIONS || '');
124
- if (!hasHeapOption && !['0', 'off', 'false', 'OFF', 'FALSE'].includes(heapSetting)) {
125
- const heapMb = heapSetting === 'auto' ? computeNodeHeapMb() : Number(heapSetting);
170
+ const heapSetting = env.FARMING_NODE_MAX_OLD_SPACE_SIZE || "auto";
171
+ const hasHeapOption = /(?:^|\s)--max-old-space-size(?:=|\s|$)/.test(env.NODE_OPTIONS || "");
172
+ if (!hasHeapOption && !["0", "off", "false", "OFF", "FALSE"].includes(heapSetting)) {
173
+ const heapMb = heapSetting === "auto" ? computeNodeHeapMb() : Number(heapSetting);
126
174
  if (Number.isFinite(heapMb) && heapMb > 0) {
127
175
  env.NODE_OPTIONS = appendNodeOption(env.NODE_OPTIONS, `--max-old-space-size=${Math.floor(heapMb)}`);
128
176
  env.FARMING_EFFECTIVE_NODE_HEAP_MB = String(Math.floor(heapMb));
129
177
  }
130
178
  }
131
-
132
179
  return env;
133
180
  }
134
-
135
181
  function parseServerArgs(argv) {
136
182
  const options = {
137
- command: argv[0] && SERVER_COMMANDS.has(argv[0]) ? argv[0] : 'start',
183
+ command: argv[0] && SERVER_COMMANDS.has(argv[0]) ? argv[0] : "start",
138
184
  env: {},
139
- portExplicit: false,
185
+ portExplicit: false
140
186
  };
141
187
  const rest = options.command === argv[0] ? argv.slice(1) : argv;
142
-
143
188
  for (let i = 0; i < rest.length; i++) {
144
189
  const arg = rest[i];
145
190
  const readValue = (name) => {
146
191
  const value = rest[i + 1];
147
- if (!value || value.startsWith('--')) throw new Error(`${name} requires a value`);
192
+ if (!value || value.startsWith("--")) throw new Error(`${name} requires a value`);
148
193
  i++;
149
194
  return value;
150
195
  };
151
-
152
- if (arg === '--port') {
196
+ if (arg === "--port") {
153
197
  options.env.PORT = readValue(arg);
154
198
  options.portExplicit = true;
155
- } else if (arg.startsWith('--port=')) {
156
- options.env.PORT = arg.slice('--port='.length);
199
+ } else if (arg.startsWith("--port=")) {
200
+ options.env.PORT = arg.slice("--port=".length);
157
201
  options.portExplicit = true;
158
- } else if (arg === '--base-path') {
202
+ } else if (arg === "--base-path") {
159
203
  options.env.FARMING_BASE_PATH = readValue(arg);
160
- } else if (arg.startsWith('--base-path=')) {
161
- options.env.FARMING_BASE_PATH = arg.slice('--base-path='.length);
162
- } else if (arg === '--config-dir') {
204
+ } else if (arg.startsWith("--base-path=")) {
205
+ options.env.FARMING_BASE_PATH = arg.slice("--base-path=".length);
206
+ } else if (arg === "--config-dir") {
163
207
  options.env.FARMING_CONFIG_DIR = readValue(arg);
164
- } else if (arg.startsWith('--config-dir=')) {
165
- options.env.FARMING_CONFIG_DIR = arg.slice('--config-dir='.length);
166
- } else if (arg === '--home') {
208
+ } else if (arg.startsWith("--config-dir=")) {
209
+ options.env.FARMING_CONFIG_DIR = arg.slice("--config-dir=".length);
210
+ } else if (arg === "--home") {
167
211
  options.env.HOME = readValue(arg);
168
- } else if (arg.startsWith('--home=')) {
169
- options.env.HOME = arg.slice('--home='.length);
170
- } else if (arg === '--no-auth') {
171
- options.env.FARMING_DISABLE_AUTH = '1';
172
- } else if (arg === '--help' || arg === '-h') {
173
- options.command = 'help';
212
+ } else if (arg.startsWith("--home=")) {
213
+ options.env.HOME = arg.slice("--home=".length);
214
+ } else if (arg === "--no-auth") {
215
+ options.env.FARMING_DISABLE_AUTH = "1";
216
+ } else if (arg === "--help" || arg === "-h") {
217
+ options.command = "help";
174
218
  } else {
175
219
  throw new Error(`Unknown option: ${arg}`);
176
220
  }
177
221
  }
178
-
179
222
  return options;
180
223
  }
181
-
182
224
  function parseSharedAppOption(arg, rest, index, env) {
183
225
  const readValue = (name) => {
184
226
  const value = rest[index + 1];
185
- if (!value || value.startsWith('--')) throw new Error(`${name} requires a value`);
227
+ if (!value || value.startsWith("--")) throw new Error(`${name} requires a value`);
186
228
  return value;
187
229
  };
188
-
189
- if (arg === '--port') {
230
+ if (arg === "--port") {
190
231
  env.PORT = readValue(arg);
191
232
  return 2;
192
233
  }
193
- if (arg.startsWith('--port=')) {
194
- env.PORT = arg.slice('--port='.length);
234
+ if (arg.startsWith("--port=")) {
235
+ env.PORT = arg.slice("--port=".length);
195
236
  return 1;
196
237
  }
197
- if (arg === '--base-path') {
238
+ if (arg === "--base-path") {
198
239
  env.FARMING_BASE_PATH = readValue(arg);
199
240
  return 2;
200
241
  }
201
- if (arg.startsWith('--base-path=')) {
202
- env.FARMING_BASE_PATH = arg.slice('--base-path='.length);
242
+ if (arg.startsWith("--base-path=")) {
243
+ env.FARMING_BASE_PATH = arg.slice("--base-path=".length);
203
244
  return 1;
204
245
  }
205
- if (arg === '--config-dir') {
246
+ if (arg === "--config-dir") {
206
247
  env.FARMING_CONFIG_DIR = readValue(arg);
207
248
  return 2;
208
249
  }
209
- if (arg.startsWith('--config-dir=')) {
210
- env.FARMING_CONFIG_DIR = arg.slice('--config-dir='.length);
250
+ if (arg.startsWith("--config-dir=")) {
251
+ env.FARMING_CONFIG_DIR = arg.slice("--config-dir=".length);
211
252
  return 1;
212
253
  }
213
- if (arg === '--home') {
254
+ if (arg === "--home") {
214
255
  env.HOME = readValue(arg);
215
256
  return 2;
216
257
  }
217
- if (arg.startsWith('--home=')) {
218
- env.HOME = arg.slice('--home='.length);
258
+ if (arg.startsWith("--home=")) {
259
+ env.HOME = arg.slice("--home=".length);
219
260
  return 1;
220
261
  }
221
- if (arg === '--no-auth') {
222
- env.FARMING_DISABLE_AUTH = '1';
262
+ if (arg === "--no-auth") {
263
+ env.FARMING_DISABLE_AUTH = "1";
223
264
  return 1;
224
265
  }
225
266
  return 0;
226
267
  }
227
-
228
268
  function isPortOverrideExplicit(overrides = {}, baseEnv = process.env) {
229
269
  return Boolean(
230
- overrides.PORT
231
- || overrides.FARMING_PORT
232
- || baseEnv.PORT
233
- || baseEnv.FARMING_PORT
270
+ overrides.PORT || overrides.FARMING_PORT || baseEnv.PORT || baseEnv.FARMING_PORT
234
271
  );
235
272
  }
236
-
237
273
  function canListenOnHost(port, host) {
238
274
  return new Promise((resolve) => {
239
275
  const server = net.createServer();
240
- server.once('error', () => resolve(false));
241
- server.once('listening', () => {
276
+ server.once("error", () => resolve(false));
277
+ server.once("listening", () => {
242
278
  server.close(() => resolve(true));
243
279
  });
244
280
  server.listen({ host, port });
245
281
  });
246
282
  }
247
-
248
283
  async function canListenOnPort(port) {
249
- return (await canListenOnHost(port, '127.0.0.1'))
250
- && (await canListenOnHost(port, '0.0.0.0'));
284
+ return await canListenOnHost(port, "127.0.0.1") && await canListenOnHost(port, "0.0.0.0");
251
285
  }
252
-
253
286
  async function findAvailablePort(startPort = Number(DEFAULT_PORT), maxAttempts = 50) {
254
287
  for (let offset = 0; offset < maxAttempts; offset++) {
255
288
  const port = startPort + offset;
@@ -257,26 +290,22 @@ async function findAvailablePort(startPort = Number(DEFAULT_PORT), maxAttempts =
257
290
  }
258
291
  throw new Error(`No available port found from ${startPort} to ${startPort + maxAttempts - 1}`);
259
292
  }
260
-
261
293
  async function adaptServerPort(env, parsed) {
262
294
  if (parsed.portExplicit || isPortOverrideExplicit(parsed.env, process.env)) return env;
263
295
  const port = await findAvailablePort(Number(env.PORT || DEFAULT_PORT));
264
296
  if (String(port) !== String(env.PORT)) env.PORT = String(port);
265
297
  return env;
266
298
  }
267
-
268
299
  function splitControlArgs(argv) {
269
300
  const command = argv[0];
270
301
  const env = {};
271
302
  const controlArgs = [command];
272
-
273
303
  for (let i = 1; i < argv.length; i++) {
274
304
  const arg = argv[i];
275
- if (arg === '--') {
305
+ if (arg === "--") {
276
306
  controlArgs.push(...argv.slice(i));
277
307
  break;
278
308
  }
279
-
280
309
  const consumed = parseSharedAppOption(arg, argv, i, env);
281
310
  if (consumed > 0) {
282
311
  i += consumed - 1;
@@ -284,106 +313,95 @@ function splitControlArgs(argv) {
284
313
  }
285
314
  controlArgs.push(arg);
286
315
  }
287
-
288
316
  return { argv: controlArgs, env };
289
317
  }
290
-
291
318
  function parseReviewArgs(argv) {
292
319
  const options = {
293
- branch: '',
320
+ branch: "",
294
321
  env: {},
295
322
  noOpen: false,
296
323
  portExplicit: false,
297
- positional: [],
324
+ positional: []
298
325
  };
299
326
  for (let index = 0; index < argv.length; index++) {
300
327
  const arg = argv[index];
301
328
  const readValue = (name) => {
302
329
  const value = argv[index + 1];
303
- if (!value || value.startsWith('--')) throw new Error(`${name} requires a value`);
330
+ if (!value || value.startsWith("--")) throw new Error(`${name} requires a value`);
304
331
  index++;
305
332
  return value;
306
333
  };
307
- if (arg === '--branch') {
334
+ if (arg === "--branch") {
308
335
  options.branch = readValue(arg);
309
336
  continue;
310
337
  }
311
- if (arg.startsWith('--branch=')) {
312
- options.branch = arg.slice('--branch='.length);
338
+ if (arg.startsWith("--branch=")) {
339
+ options.branch = arg.slice("--branch=".length);
313
340
  continue;
314
341
  }
315
- if (arg === '--no-open') {
342
+ if (arg === "--no-open") {
316
343
  options.noOpen = true;
317
344
  continue;
318
345
  }
319
346
  const consumed = parseSharedAppOption(arg, argv, index, options.env);
320
347
  if (consumed > 0) {
321
- if (arg === '--port' || arg.startsWith('--port=')) options.portExplicit = true;
348
+ if (arg === "--port" || arg.startsWith("--port=")) options.portExplicit = true;
322
349
  index += consumed - 1;
323
350
  continue;
324
351
  }
325
- if (arg.startsWith('--')) throw new Error(`Unknown review option: ${arg}`);
352
+ if (arg.startsWith("--")) throw new Error(`Unknown review option: ${arg}`);
326
353
  options.positional.push(arg);
327
354
  }
328
355
  if (options.positional.length !== 3) {
329
- throw new Error('Usage: farming review <git-dir> <old-revision> <new-revision|now> [--branch <branch>]');
356
+ throw new Error("Usage: farming review <git-dir> <old-revision> <new-revision|now> [--branch <branch>]");
330
357
  }
331
358
  const [gitDir, base, head] = options.positional;
332
- if (base === 'now') throw new Error('the old revision cannot be now');
359
+ if (base === "now") throw new Error("the old revision cannot be now");
333
360
  return { ...options, base, gitDir, head };
334
361
  }
335
-
336
362
  function runGit(root, args) {
337
363
  try {
338
- return execFileSync('git', ['-C', root, ...args], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim();
364
+ return (0, import_child_process.execFileSync)("git", ["-C", root, ...args], { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
339
365
  } catch (error) {
340
- const detail = String(error.stderr || error.message || '').trim();
341
- throw new Error(detail || `git ${args.join(' ')} failed`, { cause: error });
366
+ const detail = String(errorField(error, "stderr") || errorString(error) || "").trim();
367
+ throw new Error(detail || `git ${args.join(" ")} failed`, { cause: error });
342
368
  }
343
369
  }
344
-
345
370
  function resolveReviewTarget(parsed) {
346
371
  const requestedRoot = path.resolve(parsed.gitDir);
347
- const root = runGit(requestedRoot, ['rev-parse', '--show-toplevel']);
348
- const branch = parsed.branch || runGit(root, ['symbolic-ref', '--quiet', '--short', 'HEAD']);
349
- runGit(root, ['rev-parse', '--verify', `${branch}^{commit}`]);
372
+ const root = runGit(requestedRoot, ["rev-parse", "--show-toplevel"]);
373
+ const branch = parsed.branch || runGit(root, ["symbolic-ref", "--quiet", "--short", "HEAD"]);
374
+ runGit(root, ["rev-parse", "--verify", `${branch}^{commit}`]);
350
375
  const resolveRevision = (revision) => {
351
- if (revision === 'now') return 'now';
352
- const branchRelative = revision === 'HEAD'
353
- ? branch
354
- : revision.startsWith('HEAD~') || revision.startsWith('HEAD^')
355
- ? `${branch}${revision.slice('HEAD'.length)}`
356
- : revision;
357
- return runGit(root, ['rev-parse', '--verify', `${branchRelative}^{commit}`]);
376
+ if (revision === "now") return "now";
377
+ const branchRelative = revision === "HEAD" ? branch : revision.startsWith("HEAD~") || revision.startsWith("HEAD^") ? `${branch}${revision.slice("HEAD".length)}` : revision;
378
+ return runGit(root, ["rev-parse", "--verify", `${branchRelative}^{commit}`]);
358
379
  };
359
380
  return {
360
381
  base: resolveRevision(parsed.base),
361
382
  branch,
362
383
  head: resolveRevision(parsed.head),
363
- root,
384
+ root
364
385
  };
365
386
  }
366
-
367
387
  function reviewUrl(env, target) {
368
- const params = new URLSearchParams({
388
+ const params = new import_url.URLSearchParams({
369
389
  base: target.base,
370
390
  head: target.head,
371
- root: target.root,
391
+ root: target.root
372
392
  });
373
- const token = ['1', 'true', 'yes', 'on'].includes(String(env.FARMING_DISABLE_AUTH || '').toLowerCase()) ? '' : readTokenForEnv(env);
374
- if (token) params.set('token', token);
375
- return `${entryUrl(env, '127.0.0.1')}/review?${params.toString()}`;
393
+ const token = ["1", "true", "yes", "on"].includes(String(env.FARMING_DISABLE_AUTH || "").toLowerCase()) ? "" : readTokenForEnv(env);
394
+ if (token) params.set("token", token);
395
+ return `${entryUrl(env, "127.0.0.1")}/review?${params.toString()}`;
376
396
  }
377
-
378
397
  function openBrowser(url) {
379
- const command = process.platform === 'darwin' ? 'open' : 'xdg-open';
380
- const child = spawn(command, [url], { detached: true, stdio: 'ignore' });
398
+ const command = process.platform === "darwin" ? "open" : "xdg-open";
399
+ const child = (0, import_child_process.spawn)(command, [url], { detached: true, stdio: "ignore" });
381
400
  child.unref();
382
401
  }
383
-
384
402
  async function runReview(parsed) {
385
403
  const target = resolveReviewTarget(parsed);
386
- const serverParsed = { command: 'daemon', env: parsed.env, portExplicit: parsed.portExplicit };
404
+ const serverParsed = { command: "daemon", env: parsed.env, portExplicit: parsed.portExplicit };
387
405
  const code = await startDaemon(serverParsed);
388
406
  if (code) return code;
389
407
  const env = buildControlEnv(parsed.env);
@@ -392,7 +410,6 @@ async function runReview(parsed) {
392
410
  if (!parsed.noOpen) openBrowser(url);
393
411
  return 0;
394
412
  }
395
-
396
413
  function buildControlEnv(overrides = {}, baseEnv = process.env) {
397
414
  const env = buildServerEnv(overrides, baseEnv);
398
415
  if (!isPortOverrideExplicit(overrides, baseEnv) && !env.FARMING_CONTROL_URL) {
@@ -400,87 +417,75 @@ function buildControlEnv(overrides = {}, baseEnv = process.env) {
400
417
  if (state.port) env.PORT = String(state.port);
401
418
  if (state.basePath) env.FARMING_BASE_PATH = state.basePath;
402
419
  }
403
- env.FARMING_CONTROL_URL = env.FARMING_CONTROL_URL || entryUrl(env, '127.0.0.1');
420
+ env.FARMING_CONTROL_URL = env.FARMING_CONTROL_URL || entryUrl(env, "127.0.0.1");
404
421
  env.FARMING_TOKEN_FILE = env.FARMING_TOKEN_FILE || storageLayout.sessionTokenFile(env.FARMING_CONFIG_DIR);
405
422
  return env;
406
423
  }
407
-
408
424
  async function runServerBackedControlCli(argv) {
409
425
  const parsed = splitControlArgs(argv);
410
426
  const env = buildControlEnv(parsed.env);
411
427
  const forwardedKeys = [
412
- 'FARMING_CONFIG_DIR',
413
- 'FARMING_CONTROL_URL',
414
- 'FARMING_TOKEN_FILE',
415
- 'FARMING_DISABLE_AUTH',
416
- 'FARMING_BASE_PATH',
417
- 'HOME',
418
- 'PORT',
428
+ "FARMING_CONFIG_DIR",
429
+ "FARMING_CONTROL_URL",
430
+ "FARMING_TOKEN_FILE",
431
+ "FARMING_DISABLE_AUTH",
432
+ "FARMING_BASE_PATH",
433
+ "HOME",
434
+ "PORT"
419
435
  ];
420
- const previous = new Map(forwardedKeys.map(key => [key, process.env[key]]));
421
-
436
+ const previous = new Map(forwardedKeys.map((key) => [key, process.env[key]]));
422
437
  forwardedKeys.forEach((key) => {
423
- if (env[key] === undefined) delete process.env[key];
438
+ if (env[key] === void 0) delete process.env[key];
424
439
  else process.env[key] = env[key];
425
440
  });
426
-
427
441
  try {
428
- return await runControlCli(parsed.argv);
442
+ return await (0, import_farming_cli.run)(parsed.argv);
429
443
  } finally {
430
444
  forwardedKeys.forEach((key) => {
431
445
  const value = previous.get(key);
432
- if (value === undefined) delete process.env[key];
446
+ if (value === void 0) delete process.env[key];
433
447
  else process.env[key] = value;
434
448
  });
435
449
  }
436
450
  }
437
-
438
451
  function childInvocation(env = process.env) {
439
- if (process.pkg) {
440
- // Spawn env directly so it execs the packaged binary in-place. A shell
441
- // wrapper may keep its own PID while the listener belongs to a child,
442
- // making daemon ownership impossible to prove on Linux.
452
+ if (packagedProcess.pkg) {
443
453
  return {
444
- command: '/usr/bin/env',
454
+ command: "/usr/bin/env",
445
455
  // FARMING_RUN_SERVER selects the embedded server entry. Do not append a
446
456
  // sentinel argument: pkg may interpret it as an external script path.
447
- args: buildCleanEnvExecArgs(env, process.execPath),
457
+ args: buildCleanEnvExecArgs(env, process.execPath)
448
458
  };
449
459
  }
450
460
  const nodePath = env.FARMING_NODE_BIN || process.execPath;
451
461
  if (env.FARMING_NODE_LD && env.FARMING_NODE_LIBRARY_PATH) {
452
462
  return {
453
463
  command: env.FARMING_NODE_LD,
454
- args: ['--library-path', env.FARMING_NODE_LIBRARY_PATH, nodePath, __filename],
464
+ args: ["--library-path", env.FARMING_NODE_LIBRARY_PATH, nodePath, __filename]
455
465
  };
456
466
  }
457
467
  return { command: nodePath, args: [__filename] };
458
468
  }
459
-
460
469
  function ensureConfigDir(configDir) {
461
470
  fs.mkdirSync(configDir, { recursive: true });
462
471
  }
463
-
464
472
  function pidFile(configDir) {
465
473
  return storageLayout.serverPidFile(configDir);
466
474
  }
467
-
468
475
  function serverStateFile(configDir) {
469
476
  return storageLayout.serverStateFile(configDir);
470
477
  }
471
-
472
478
  function logFile(configDir) {
473
479
  return storageLayout.serverLogFile(configDir);
474
480
  }
475
-
476
481
  function readServerState(configDir) {
477
482
  try {
478
- return JSON.parse(fs.readFileSync(serverStateFile(configDir), 'utf8'));
483
+ const value = JSON.parse(fs.readFileSync(serverStateFile(configDir), "utf8"));
484
+ return value && typeof value === "object" ? value : {};
479
485
  } catch {
480
486
  return {};
481
487
  }
482
488
  }
483
-
484
489
  function canonicalConfigDir(configDir) {
485
490
  try {
486
491
  return fs.realpathSync.native(configDir);
@@ -488,8 +493,7 @@ function canonicalConfigDir(configDir) {
488
493
  return path.resolve(configDir);
489
494
  }
490
495
  }
491
-
492
- function writeServerState(configDir, env, pid, processIdentity, phase = 'running') {
496
+ function writeServerState(configDir, env, pid, processIdentity, phase = "running") {
493
497
  const state = {
494
498
  pid,
495
499
  port: Number(env.PORT || DEFAULT_PORT),
@@ -497,54 +501,50 @@ function writeServerState(configDir, env, pid, processIdentity, phase = 'running
497
501
  configDir: canonicalConfigDir(configDir),
498
502
  processIdentity,
499
503
  phase,
500
- updatedAt: new Date().toISOString(),
504
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
501
505
  };
502
506
  const target = serverStateFile(configDir);
503
507
  const temporary = `${target}.${process.pid}.tmp`;
504
- fs.writeFileSync(temporary, `${JSON.stringify(state, null, 2)}\n`, { mode: 0o600 });
508
+ fs.writeFileSync(temporary, `${JSON.stringify(state, null, 2)}
509
+ `, { mode: 384 });
505
510
  fs.renameSync(temporary, target);
506
511
  }
507
-
508
512
  function processLooksLikeFarmingServer(pid) {
509
- let environment = '';
513
+ let environment = "";
510
514
  try {
511
- environment = fs.readFileSync(`/proc/${pid}/environ`, 'utf8').replace(/\0/g, ' ');
515
+ environment = fs.readFileSync(`/proc/${pid}/environ`, "utf8").replace(/\0/g, " ");
512
516
  } catch {
513
517
  try {
514
- environment = execFileSync(
515
- '/bin/ps',
516
- ['eww', '-p', String(pid), '-o', 'command='],
517
- { encoding: 'utf8', timeout: 1_000, maxBuffer: 1024 * 1024 },
518
+ environment = (0, import_child_process.execFileSync)(
519
+ "/bin/ps",
520
+ ["eww", "-p", String(pid), "-o", "command="],
521
+ { encoding: "utf8", timeout: 1e3, maxBuffer: 1024 * 1024 }
518
522
  );
519
523
  } catch {
520
- environment = '';
524
+ environment = "";
521
525
  }
522
526
  }
523
527
  if (/(?:^|\s)FARMING_RUN_SERVER=1(?:\s|$)/.test(environment)) return true;
524
528
  return /(?:^|\s)(?:\S+[/\\])?backend[/\\]server\.js(?:\s|$)/.test(environment);
525
529
  }
526
-
527
530
  function processHasExactEnvironment(pid, expected) {
528
531
  try {
529
- const entries = fs.readFileSync(`/proc/${pid}/environ`, 'utf8')
530
- .split('\0')
531
- .filter(Boolean)
532
- .map(entry => {
533
- const separator = entry.indexOf('=');
534
- return separator < 0 ? [entry, ''] : [entry.slice(0, separator), entry.slice(separator + 1)];
535
- });
532
+ const entries = fs.readFileSync(`/proc/${pid}/environ`, "utf8").split("\0").filter(Boolean).map((entry) => {
533
+ const separator = entry.indexOf("=");
534
+ return separator < 0 ? [entry, ""] : [entry.slice(0, separator), entry.slice(separator + 1)];
535
+ });
536
536
  const environment = new Map(entries);
537
537
  return Object.entries(expected).every(([key, value]) => environment.get(key) === String(value));
538
538
  } catch {
539
- if (Object.values(expected).some(value => /\s/.test(String(value)))) return false;
539
+ if (Object.values(expected).some((value) => /\s/.test(String(value)))) return false;
540
540
  try {
541
- const environment = execFileSync(
542
- '/bin/ps',
543
- ['eww', '-p', String(pid), '-o', 'command='],
544
- { encoding: 'utf8', timeout: 1_000, maxBuffer: 1024 * 1024 },
541
+ const environment = (0, import_child_process.execFileSync)(
542
+ "/bin/ps",
543
+ ["eww", "-p", String(pid), "-o", "command="],
544
+ { encoding: "utf8", timeout: 1e3, maxBuffer: 1024 * 1024 }
545
545
  );
546
546
  return Object.entries(expected).every(([key, value]) => {
547
- const escaped = `${key}=${value}`.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
547
+ const escaped = `${key}=${value}`.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
548
548
  return new RegExp(`(?:^|\\s)${escaped}(?:\\s|$)`).test(environment);
549
549
  });
550
550
  } catch {
@@ -552,80 +552,83 @@ function processHasExactEnvironment(pid, expected) {
552
552
  }
553
553
  }
554
554
  }
555
-
556
555
  function readLegacyServerSettings(configDir, state, pid) {
557
- const authDisabled = processHasExactEnvironment(pid, { FARMING_DISABLE_AUTH: '1' });
558
- const token = authDisabled ? '' : readTokenForEnv({ FARMING_CONFIG_DIR: configDir });
556
+ const authDisabled = processHasExactEnvironment(pid, { FARMING_DISABLE_AUTH: "1" });
557
+ const token = authDisabled ? "" : readTokenForEnv({ FARMING_CONFIG_DIR: configDir });
559
558
  if (!authDisabled && !token) {
560
- return Promise.reject(new Error('legacy Farming server identity probe requires this config directory token'));
559
+ return Promise.reject(new Error("legacy Farming server identity probe requires this config directory token"));
561
560
  }
562
- const requestPath = routePath(state.basePath || DEFAULT_BASE_PATH, '/api/settings');
561
+ const requestPath = routePath(state.basePath || DEFAULT_BASE_PATH, "/api/settings");
563
562
  return new Promise((resolve, reject) => {
564
563
  const req = http.request({
565
- host: '127.0.0.1',
564
+ host: "127.0.0.1",
566
565
  port: Number(state.port),
567
566
  path: requestPath,
568
- method: 'GET',
569
- timeout: 1_000,
570
- headers: token ? { Cookie: `farming_token=${encodeURIComponent(token)}` } : {},
571
- }, res => {
572
- let body = '';
573
- res.setEncoding('utf8');
574
- res.on('data', chunk => {
567
+ method: "GET",
568
+ timeout: 1e3,
569
+ headers: token ? { Cookie: `farming_token=${encodeURIComponent(token)}` } : {}
570
+ }, (res) => {
571
+ let body = "";
572
+ res.setEncoding("utf8");
573
+ res.on("data", (chunk) => {
575
574
  if (body.length <= 64 * 1024) body += chunk;
576
575
  });
577
- res.on('end', () => {
576
+ res.on("end", () => {
578
577
  if (res.statusCode !== 200) {
579
578
  reject(new Error(`legacy Farming server identity probe returned HTTP ${res.statusCode || 0}`));
580
579
  return;
581
580
  }
582
581
  try {
583
582
  const payload = JSON.parse(body);
584
- if (!payload?.settings || typeof payload.settings !== 'object') {
585
- reject(new Error('legacy Farming server identity probe did not return Farming settings'));
583
+ const settings = payload && typeof payload === "object" && "settings" in payload ? payload.settings : null;
584
+ if (!settings || typeof settings !== "object") {
585
+ reject(new Error("legacy Farming server identity probe did not return Farming settings"));
586
586
  return;
587
587
  }
588
- resolve(payload.settings);
588
+ resolve(settings);
589
589
  } catch (error) {
590
- reject(new Error(`legacy Farming server identity probe was invalid: ${error.message || error}`));
590
+ reject(new Error(
591
+ `legacy Farming server identity probe was invalid: ${errorString(error) || error}`
592
+ ));
591
593
  }
592
594
  });
593
595
  });
594
- req.on('error', reject);
595
- req.on('timeout', () => req.destroy(new Error('legacy Farming server identity probe timed out')));
596
+ req.on("error", reject);
597
+ req.on("timeout", () => req.destroy(new Error("legacy Farming server identity probe timed out")));
596
598
  req.end();
597
599
  });
598
600
  }
599
-
600
601
  function processOwnsListeningPort(pid, port) {
601
602
  const processId = Number(pid);
602
603
  const portNumber = Number(port);
603
604
  if (!Number.isSafeInteger(processId) || processId <= 0 || !Number.isInteger(portNumber) || portNumber <= 0) {
604
605
  return false;
605
606
  }
606
- if (process.platform === 'linux') {
607
+ if (process.platform === "linux") {
607
608
  try {
608
- const socketInodes = new Set(fs.readdirSync(`/proc/${processId}/fd`).flatMap(entry => {
609
- try {
610
- const target = fs.readlinkSync(`/proc/${processId}/fd/${entry}`);
611
- const match = target.match(/^socket:\[(\d+)\]$/);
612
- return match ? [match[1]] : [];
613
- } catch {
614
- return [];
615
- }
616
- }));
617
- const portHex = portNumber.toString(16).toUpperCase().padStart(4, '0');
618
- for (const table of ['/proc/net/tcp', '/proc/net/tcp6']) {
609
+ const socketInodes = new Set(
610
+ fs.readdirSync(`/proc/${processId}/fd`).flatMap((entry) => {
611
+ try {
612
+ const target = fs.readlinkSync(`/proc/${processId}/fd/${entry}`);
613
+ const match = target.match(/^socket:\[(\d+)\]$/);
614
+ return match ? [match[1]] : [];
615
+ } catch {
616
+ return [];
617
+ }
618
+ })
619
+ );
620
+ const portHex = portNumber.toString(16).toUpperCase().padStart(4, "0");
621
+ for (const table of ["/proc/net/tcp", "/proc/net/tcp6"]) {
619
622
  let rows = [];
620
623
  try {
621
- rows = fs.readFileSync(table, 'utf8').trim().split(/\r?\n/).slice(1);
624
+ rows = fs.readFileSync(table, "utf8").trim().split(/\r?\n/).slice(1);
622
625
  } catch {
623
626
  continue;
624
627
  }
625
- if (rows.some(row => {
628
+ if (rows.some((row) => {
626
629
  const fields = row.trim().split(/\s+/);
627
- const localPort = String(fields[1] || '').split(':').at(-1);
628
- return localPort === portHex && fields[3] === '0A' && socketInodes.has(fields[9]);
630
+ const localPort = String(fields[1] || "").split(":").at(-1);
631
+ return localPort === portHex && fields[3] === "0A" && socketInodes.has(fields[9]);
629
632
  })) return true;
630
633
  }
631
634
  return false;
@@ -634,63 +637,45 @@ function processOwnsListeningPort(pid, port) {
634
637
  }
635
638
  }
636
639
  try {
637
- const lsof = fs.existsSync('/usr/sbin/lsof') ? '/usr/sbin/lsof' : 'lsof';
638
- const stdout = execFileSync(
640
+ const lsof = fs.existsSync("/usr/sbin/lsof") ? "/usr/sbin/lsof" : "lsof";
641
+ const stdout = (0, import_child_process.execFileSync)(
639
642
  lsof,
640
- ['-nP', '-a', '-p', String(processId), `-iTCP:${portNumber}`, '-sTCP:LISTEN', '-Fpfn'],
641
- { encoding: 'utf8', timeout: 1_000, maxBuffer: 64 * 1024 },
643
+ ["-nP", "-a", "-p", String(processId), `-iTCP:${portNumber}`, "-sTCP:LISTEN", "-Fpfn"],
644
+ { encoding: "utf8", timeout: 1e3, maxBuffer: 64 * 1024 }
642
645
  );
643
- return String(stdout || '').split(/\r?\n/).some(line => line.startsWith('n') && line.endsWith(`:${portNumber}`));
646
+ return String(stdout || "").split(/\r?\n/).some((line) => line.startsWith("n") && line.endsWith(`:${portNumber}`));
644
647
  } catch {
645
648
  return false;
646
649
  }
647
650
  }
648
-
649
651
  async function assertServerProcessIdentity(configDir, pid, state) {
650
652
  const expected = state?.processIdentity;
651
- if (
652
- Number(state?.pid) !== pid
653
- || canonicalConfigDir(state?.configDir || '') !== canonicalConfigDir(configDir)
654
- || !expected
655
- || Number(expected.pid) !== pid
656
- || !Number.isSafeInteger(Number(expected.processGroupId))
657
- || Number(expected.processGroupId) <= 0
658
- || !String(expected.startedAt || '').trim()
659
- ) {
653
+ if (Number(state?.pid) !== pid || canonicalConfigDir(typeof state?.configDir === "string" ? state.configDir : "") !== canonicalConfigDir(configDir) || !expected || Number(expected.pid) !== pid || !Number.isSafeInteger(Number(expected.processGroupId)) || Number(expected.processGroupId) <= 0 || !String(expected.startedAt || "").trim()) {
660
654
  throw new Error(
661
- `Refusing to stop Farming PID ${pid}: server control metadata does not contain a matching process identity`,
655
+ `Refusing to stop Farming PID ${pid}: server control metadata does not contain a matching process identity`
662
656
  );
663
657
  }
664
- const current = await readServerProcessIdentity(pid);
665
- if (!matchingProcessIdentity(expected, current)) {
658
+ const current = await (0, import_server_process_identity.readServerProcessIdentity)(pid);
659
+ if (!current || !(0, import_server_process_identity.matchingProcessIdentity)(expected, current)) {
666
660
  throw new Error(
667
- `Refusing to stop Farming PID ${pid}: the live process identity does not match the server control metadata`,
661
+ `Refusing to stop Farming PID ${pid}: the live process identity does not match the server control metadata`
668
662
  );
669
663
  }
670
- if (state.phase !== 'starting' && !processOwnsListeningPort(pid, Number(state.port))) {
664
+ if (state.phase !== "starting" && !processOwnsListeningPort(pid, Number(state.port))) {
671
665
  throw new Error(`Refusing to stop Farming PID ${pid}: the process does not own listening port ${state.port}`);
672
666
  }
673
667
  return current;
674
668
  }
675
-
676
669
  async function migrateLegacyServerIdentity(configDir, pid, state) {
677
- if (
678
- Number(state?.pid) !== pid
679
- || canonicalConfigDir(state?.configDir || '') !== canonicalConfigDir(configDir)
680
- || !Number.isInteger(Number(state?.port))
681
- || Number(state.port) <= 0
682
- || Number(state.port) > 65535
683
- || !processLooksLikeFarmingServer(pid)
684
- || !processHasExactEnvironment(pid, {
685
- FARMING_CONFIG_DIR: configDir,
686
- PORT: String(state.port),
687
- })
688
- ) {
670
+ if (Number(state?.pid) !== pid || canonicalConfigDir(typeof state?.configDir === "string" ? state.configDir : "") !== canonicalConfigDir(configDir) || !Number.isInteger(Number(state?.port)) || Number(state.port) <= 0 || Number(state.port) > 65535 || !processLooksLikeFarmingServer(pid) || !processHasExactEnvironment(pid, {
671
+ FARMING_CONFIG_DIR: configDir,
672
+ PORT: String(state.port)
673
+ })) {
689
674
  throw new Error(
690
- `Refusing to stop Farming PID ${pid}: legacy server control metadata could not prove this process belongs to the config directory`,
675
+ `Refusing to stop Farming PID ${pid}: legacy server control metadata could not prove this process belongs to the config directory`
691
676
  );
692
677
  }
693
- const firstIdentity = await readServerProcessIdentity(pid);
678
+ const firstIdentity = await (0, import_server_process_identity.readServerProcessIdentity)(pid);
694
679
  if (!firstIdentity) {
695
680
  throw new Error(`Refusing to stop Farming PID ${pid}: the legacy server process identity could not be read`);
696
681
  }
@@ -698,8 +683,8 @@ async function migrateLegacyServerIdentity(configDir, pid, state) {
698
683
  throw new Error(`Refusing to stop Farming PID ${pid}: the legacy process does not own listening port ${state.port}`);
699
684
  }
700
685
  await readLegacyServerSettings(configDir, state, pid);
701
- const stableIdentity = await readServerProcessIdentity(pid);
702
- if (!matchingProcessIdentity(firstIdentity, stableIdentity) || readPid(configDir) !== pid) {
686
+ const stableIdentity = await (0, import_server_process_identity.readServerProcessIdentity)(pid);
687
+ if (!stableIdentity || !(0, import_server_process_identity.matchingProcessIdentity)(firstIdentity, stableIdentity) || readPid(configDir) !== pid) {
703
688
  throw new Error(`Refusing to stop Farming PID ${pid}: the legacy server process identity changed during verification`);
704
689
  }
705
690
  fs.writeFileSync(serverStateFile(configDir), `${JSON.stringify({
@@ -707,100 +692,91 @@ async function migrateLegacyServerIdentity(configDir, pid, state) {
707
692
  pid,
708
693
  configDir: canonicalConfigDir(configDir),
709
694
  processIdentity: stableIdentity,
710
- identityMigratedAt: new Date().toISOString(),
711
- }, null, 2)}\n`);
695
+ identityMigratedAt: (/* @__PURE__ */ new Date()).toISOString()
696
+ }, null, 2)}
697
+ `);
712
698
  return stableIdentity;
713
699
  }
714
-
715
700
  function readPid(configDir) {
716
701
  try {
717
- return Number(fs.readFileSync(pidFile(configDir), 'utf8').trim());
702
+ return Number(fs.readFileSync(pidFile(configDir), "utf8").trim());
718
703
  } catch {
719
704
  return 0;
720
705
  }
721
706
  }
722
-
723
707
  function isRunning(pid) {
724
708
  if (!pid) return false;
725
709
  try {
726
710
  process.kill(pid, 0);
727
711
  return true;
728
712
  } catch (error) {
729
- if (error?.code === 'EPERM' || error?.code === 'EACCES') return true;
713
+ if (errorString(error, "code") === "EPERM" || errorString(error, "code") === "EACCES") {
714
+ return true;
715
+ }
730
716
  return false;
731
717
  }
732
718
  }
733
-
734
719
  function tailFile(file, lineCount = 80) {
735
720
  try {
736
- return fs.readFileSync(file, 'utf8').split(/\r?\n/).slice(-lineCount).join('\n').trim();
721
+ return fs.readFileSync(file, "utf8").split(/\r?\n/).slice(-lineCount).join("\n").trim();
737
722
  } catch {
738
- return '';
723
+ return "";
739
724
  }
740
725
  }
741
-
742
- function entryUrl(env, host = 'localhost') {
743
- const basePath = normalizeBasePath(env.FARMING_BASE_PATH || DEFAULT_BASE_PATH) || '/';
726
+ function entryUrl(env, host = "localhost") {
727
+ const basePath = normalizeBasePath(env.FARMING_BASE_PATH || DEFAULT_BASE_PATH) || "/";
744
728
  return `http://${host}:${env.PORT}${basePath}`;
745
729
  }
746
-
747
730
  function readTokenForEnv(env) {
748
731
  const tokenFile = storageLayout.sessionTokenFile(env.FARMING_CONFIG_DIR || defaultConfigDir(env));
749
732
  try {
750
- return fs.readFileSync(tokenFile, 'utf8').trim();
733
+ return fs.readFileSync(tokenFile, "utf8").trim();
751
734
  } catch {
752
- return '';
735
+ return "";
753
736
  }
754
737
  }
755
-
756
738
  function serverStartTimeoutMs(env) {
757
739
  const parsed = Number(env.FARMING_START_TIMEOUT_MS || env.FARMING_SERVER_START_TIMEOUT_MS);
758
740
  if (Number.isFinite(parsed) && parsed > 0) return parsed;
759
741
  return DEFAULT_SERVER_START_TIMEOUT_MS;
760
742
  }
761
-
762
743
  function serverStartStabilityMs(env) {
763
744
  const parsed = Number(env.FARMING_START_STABILITY_MS || env.FARMING_SERVER_START_STABILITY_MS);
764
- if (Number.isFinite(parsed) && parsed >= 0) return Math.min(parsed, 60_000);
745
+ if (Number.isFinite(parsed) && parsed >= 0) return Math.min(parsed, 6e4);
765
746
  return DEFAULT_SERVER_START_STABILITY_MS;
766
747
  }
767
-
768
748
  function serverStopTimeoutMs(env) {
769
749
  const parsed = Number(env.FARMING_STOP_TIMEOUT_MS || env.FARMING_SERVER_STOP_TIMEOUT_MS);
770
- if (Number.isFinite(parsed) && parsed > 0) return Math.min(parsed, 120_000);
750
+ if (Number.isFinite(parsed) && parsed > 0) return Math.min(parsed, 12e4);
771
751
  return DEFAULT_SERVER_STOP_TIMEOUT_MS;
772
752
  }
773
-
774
753
  async function waitForDaemonStop(pid, port, options = {}) {
775
754
  const timeoutMs = options.timeoutMs || DEFAULT_SERVER_STOP_TIMEOUT_MS;
776
755
  const processRunning = options.isRunning || isRunning;
777
756
  const portAvailable = options.canListenOnPort || canListenOnPort;
778
757
  const now = options.now || Date.now;
779
- const wait = options.wait || (durationMs => new Promise(resolve => setTimeout(resolve, durationMs)));
758
+ const wait = options.wait || ((durationMs) => new Promise((resolve) => setTimeout(resolve, durationMs)));
780
759
  const startedAt = now();
781
760
  let running = true;
782
761
  let released = false;
783
-
784
762
  while (true) {
785
763
  running = processRunning(pid);
786
764
  released = await portAvailable(port);
787
765
  if (!running && released) return;
788
766
  if (now() - startedAt >= timeoutMs) {
789
767
  throw new Error(
790
- `Farming server PID ${pid} did not stop and release port ${port} within ${timeoutMs}ms`
791
- + ` (process ${running ? 'still running' : 'exited'}, port ${released ? 'released' : 'still in use'})`,
768
+ `Farming server PID ${pid} did not stop and release port ${port} within ${timeoutMs}ms (process ${running ? "still running" : "exited"}, port ${released ? "released" : "still in use"})`
792
769
  );
793
770
  }
794
771
  await wait(SERVER_STOP_POLL_MS);
795
772
  }
796
773
  }
797
-
798
774
  function waitForProcessStability(pid, durationMs = DEFAULT_SERVER_START_STABILITY_MS) {
799
775
  const startedAt = Date.now();
800
776
  return new Promise((resolve, reject) => {
801
777
  const tick = () => {
802
778
  if (!isRunning(pid)) {
803
- reject(new Error('server process exited during startup stability check'));
779
+ reject(new Error("server process exited during startup stability check"));
804
780
  return;
805
781
  }
806
782
  const remainingMs = durationMs - (Date.now() - startedAt);
@@ -813,68 +789,62 @@ function waitForProcessStability(pid, durationMs = DEFAULT_SERVER_START_STABILIT
813
789
  tick();
814
790
  });
815
791
  }
816
-
817
792
  async function cleanupFailedDaemonStart(configDir, childPid, expectedIdentity = null) {
818
793
  if (isRunning(childPid)) {
819
794
  const expected = expectedIdentity || readServerState(configDir).processIdentity;
820
- const current = readServerProcessIdentity(childPid);
821
- if (!matchingProcessIdentity(expected, current)) {
795
+ const current = (0, import_server_process_identity.readServerProcessIdentity)(childPid);
796
+ if (!(0, import_server_process_identity.matchingProcessIdentity)(expected, current)) {
822
797
  throw new Error(`Failed Farming startup left live PID ${childPid} with an unproved identity; refusing to signal it`);
823
798
  }
824
799
  try {
825
- process.kill(childPid, 'SIGKILL');
800
+ process.kill(childPid, "SIGKILL");
826
801
  } catch (error) {
827
- if (error?.code === 'EPERM' || error?.code === 'EACCES') {
802
+ if (errorString(error, "code") === "EPERM" || errorString(error, "code") === "EACCES") {
828
803
  throw new Error(
829
- `Failed Farming startup left Server PID ${childPid} running because cleanup lacks permission. `
830
- + 'Stop it as the operating-system user that owns the process, then retry.',
831
- { cause: error },
804
+ `Failed Farming startup left Server PID ${childPid} running because cleanup lacks permission. Stop it as the operating-system user that owns the process, then retry.`,
805
+ { cause: error }
832
806
  );
833
807
  }
834
- if (error?.code !== 'ESRCH') throw error;
808
+ if (errorString(error, "code") !== "ESRCH") throw error;
835
809
  }
836
810
  const startedAt = Date.now();
837
- while (matchingProcessIdentity(expected, readServerProcessIdentity(childPid))) {
838
- if (Date.now() - startedAt >= 5_000) {
811
+ while ((0, import_server_process_identity.matchingProcessIdentity)(expected, (0, import_server_process_identity.readServerProcessIdentity)(childPid))) {
812
+ if (Date.now() - startedAt >= 5e3) {
839
813
  throw new Error(`Failed Farming startup left Server PID ${childPid} running after SIGKILL`);
840
814
  }
841
- await new Promise(resolve => setTimeout(resolve, SERVER_STOP_POLL_MS));
815
+ await new Promise((resolve) => setTimeout(resolve, SERVER_STOP_POLL_MS));
842
816
  }
843
817
  }
844
818
  if (readPid(configDir) !== childPid) return;
845
819
  fs.rmSync(pidFile(configDir), { force: true });
846
820
  fs.rmSync(serverStateFile(configDir), { force: true });
847
821
  }
848
-
849
822
  function waitForServer(env, timeoutMs = serverStartTimeoutMs(env), childPid = 0) {
850
823
  const startedAt = Date.now();
851
824
  const port = Number(env.PORT || DEFAULT_PORT);
852
- const authDisabled = ['1', 'true', 'yes', 'on'].includes(String(env.FARMING_DISABLE_AUTH || '').toLowerCase());
853
-
825
+ const authDisabled = ["1", "true", "yes", "on"].includes(String(env.FARMING_DISABLE_AUTH || "").toLowerCase());
854
826
  return new Promise((resolve, reject) => {
855
827
  const tick = () => {
856
828
  if (childPid && !isRunning(childPid)) {
857
- reject(new Error('server process exited before becoming ready'));
829
+ reject(new Error("server process exited before becoming ready"));
858
830
  return;
859
831
  }
860
- const token = authDisabled ? '' : readTokenForEnv(env);
832
+ const token = authDisabled ? "" : readTokenForEnv(env);
861
833
  if (!authDisabled && !token) {
862
834
  if (Date.now() - startedAt >= timeoutMs) {
863
- reject(new Error('server did not create its token file before timeout'));
835
+ reject(new Error("server did not create its token file before timeout"));
864
836
  return;
865
837
  }
866
838
  setTimeout(tick, 250);
867
839
  return;
868
840
  }
869
- const readyPath = authDisabled
870
- ? routePath(env.FARMING_BASE_PATH || DEFAULT_BASE_PATH, '/api/auth/status')
871
- : `${routePath(env.FARMING_BASE_PATH || DEFAULT_BASE_PATH, '/')}?token=${encodeURIComponent(token)}`;
841
+ const readyPath = authDisabled ? routePath(env.FARMING_BASE_PATH || DEFAULT_BASE_PATH, "/api/auth/status") : `${routePath(env.FARMING_BASE_PATH || DEFAULT_BASE_PATH, "/")}?token=${encodeURIComponent(token)}`;
872
842
  const req = http.request({
873
- host: '127.0.0.1',
843
+ host: "127.0.0.1",
874
844
  port,
875
845
  path: readyPath,
876
- method: 'GET',
877
- timeout: 500,
846
+ method: "GET",
847
+ timeout: 500
878
848
  }, (res) => {
879
849
  res.resume();
880
850
  if (res.statusCode && res.statusCode >= 200 && res.statusCode < 400) {
@@ -887,14 +857,14 @@ function waitForServer(env, timeoutMs = serverStartTimeoutMs(env), childPid = 0)
887
857
  }
888
858
  setTimeout(tick, 250);
889
859
  });
890
- req.on('error', () => {
860
+ req.on("error", () => {
891
861
  if (Date.now() - startedAt >= timeoutMs) {
892
- reject(new Error('server did not become ready before timeout'));
862
+ reject(new Error("server did not become ready before timeout"));
893
863
  return;
894
864
  }
895
865
  setTimeout(tick, 250);
896
866
  });
897
- req.on('timeout', () => {
867
+ req.on("timeout", () => {
898
868
  req.destroy();
899
869
  });
900
870
  req.end();
@@ -902,100 +872,92 @@ function waitForServer(env, timeoutMs = serverStartTimeoutMs(env), childPid = 0)
902
872
  tick();
903
873
  });
904
874
  }
905
-
906
875
  async function runServerInCurrentProcess() {
907
- process.env = buildServerEnv();
908
- ensureConfigDir(process.env.FARMING_CONFIG_DIR);
909
- fs.writeFileSync(pidFile(process.env.FARMING_CONFIG_DIR), String(process.pid), { mode: 0o600 });
910
- const processIdentity = await readServerProcessIdentity(process.pid);
911
- if (!processIdentity) throw new Error('server process identity could not be committed before startup');
912
- writeServerState(process.env.FARMING_CONFIG_DIR, process.env, process.pid, processIdentity, 'starting');
913
- const { startServer } = require('./server');
876
+ const env = buildServerEnv();
877
+ process.env = env;
878
+ ensureConfigDir(env.FARMING_CONFIG_DIR);
879
+ fs.writeFileSync(pidFile(env.FARMING_CONFIG_DIR), String(process.pid), { mode: 384 });
880
+ const processIdentity = await (0, import_server_process_identity.readServerProcessIdentity)(process.pid);
881
+ if (!processIdentity) throw new Error("server process identity could not be committed before startup");
882
+ writeServerState(env.FARMING_CONFIG_DIR, env, process.pid, processIdentity, "starting");
883
+ const { startServer } = require("./server.cjs");
914
884
  const server = startServer();
915
- server.once('listening', () => {
885
+ server.once("listening", () => {
916
886
  writeServerState(
917
- process.env.FARMING_CONFIG_DIR,
918
- process.env,
887
+ env.FARMING_CONFIG_DIR,
888
+ env,
919
889
  process.pid,
920
890
  processIdentity,
921
- 'running',
891
+ "running"
922
892
  );
923
- const { pruneRuntimeDependencies } = require('./runtime-dependency-manager');
893
+ const { pruneRuntimeDependencies } = require("./runtime-dependency-manager.cjs");
924
894
  void pruneRuntimeDependencies({
925
- configDir: process.env.FARMING_CONFIG_DIR,
926
- env: process.env,
927
- }).catch(error => {
928
- console.warn(`Startup dependency cache cleanup failed: ${error?.message || error}`);
895
+ configDir: env.FARMING_CONFIG_DIR,
896
+ env
897
+ }).catch((error) => {
898
+ console.warn(`Startup dependency cache cleanup failed: ${errorString(error) || error}`);
929
899
  });
930
900
  });
931
901
  }
932
-
933
902
  function runNativePtyHostInCurrentProcess() {
934
- const { startNativePtyHostProcess } = require('./native-pty-host');
903
+ const { startNativePtyHostProcess } = require("./native-pty-host.cjs");
935
904
  startNativePtyHostProcess();
936
905
  }
937
-
938
906
  async function prepareStartupDependencies(env, options = {}) {
939
- if (
940
- options.force !== true
941
- && (env.FARMING_SKIP_RUNTIME_PREPARE === '1' || env.NODE_ENV === 'test')
942
- ) {
907
+ if (options.force !== true && (env.FARMING_SKIP_RUNTIME_PREPARE === "1" || env.NODE_ENV === "test")) {
943
908
  return { skipped: true };
944
909
  }
945
- const { prepareRuntimeDependencies } = require('./runtime-dependency-manager');
910
+ const { prepareRuntimeDependencies } = require("./runtime-dependency-manager.cjs");
946
911
  return prepareRuntimeDependencies({
912
+ activate: options.activate,
947
913
  configDir: env.FARMING_CONFIG_DIR,
948
- env,
914
+ env
949
915
  });
950
916
  }
951
-
952
917
  async function startForeground(parsed) {
953
918
  const env = buildServerEnv(parsed.env);
954
919
  await prepareStartupDependencies(env);
955
920
  await adaptServerPort(env, parsed);
956
- env[SERVER_MODE_ENV] = '1';
921
+ env[SERVER_MODE_ENV] = "1";
957
922
  ensureConfigDir(env.FARMING_CONFIG_DIR);
958
923
  const invocation = childInvocation(env);
959
- const child = spawn(invocation.command, invocation.args, {
924
+ const child = (0, import_child_process.spawn)(invocation.command, invocation.args, {
960
925
  env,
961
- stdio: 'inherit',
926
+ stdio: "inherit"
962
927
  });
963
- child.on('exit', (code, signal) => {
928
+ child.on("exit", (code, signal) => {
964
929
  if (signal) {
965
930
  process.kill(process.pid, signal);
966
931
  return;
967
932
  }
968
933
  process.exit(code || 0);
969
934
  });
970
- child.on('error', (error) => {
935
+ child.on("error", (error) => {
971
936
  console.error(error.message);
972
937
  process.exit(1);
973
938
  });
974
939
  }
975
-
976
940
  async function startDaemon(parsed) {
977
941
  const env = await adaptServerPort(buildServerEnv(parsed.env), parsed);
978
- env[SERVER_MODE_ENV] = '1';
942
+ env[SERVER_MODE_ENV] = "1";
979
943
  const configDir = env.FARMING_CONFIG_DIR;
980
944
  ensureConfigDir(configDir);
981
-
982
945
  const existingPid = readPid(configDir);
983
946
  if (isRunning(existingPid)) {
984
947
  const state = readServerState(configDir);
985
948
  try {
986
- if (state.processIdentity?.format === SERVER_PROCESS_IDENTITY_FORMAT) {
949
+ if (state.processIdentity?.format === import_server_process_identity.SERVER_PROCESS_IDENTITY_FORMAT) {
987
950
  await assertServerProcessIdentity(configDir, existingPid, state);
988
951
  } else {
989
952
  await migrateLegacyServerIdentity(configDir, existingPid, state);
990
953
  }
991
954
  } catch (error) {
992
955
  console.error(
993
- `Farming PID ${existingPid} is live, but this config directory does not prove that it owns the Server: `
994
- + `${error.message || error}`,
956
+ `Farming PID ${existingPid} is live, but this config directory does not prove that it owns the Server: ${errorString(error) || error}`
995
957
  );
996
958
  return 1;
997
959
  }
998
- if (state.phase === 'starting') {
960
+ if (state.phase === "starting") {
999
961
  console.warn(`Previous Farming startup (PID ${existingPid}) did not complete; replacing it.`);
1000
962
  const stopCode = await stopDaemon({ env });
1001
963
  if (stopCode !== 0) return stopCode;
@@ -1007,69 +969,65 @@ async function startDaemon(parsed) {
1007
969
  return 0;
1008
970
  }
1009
971
  }
1010
-
1011
972
  await prepareStartupDependencies(env);
1012
- const out = fs.openSync(logFile(configDir), 'a');
973
+ const out = fs.openSync(logFile(configDir), "a");
1013
974
  const invocation = childInvocation(env);
1014
- if (env.FARMING_DEBUG_CLI === '1') {
975
+ if (env.FARMING_DEBUG_CLI === "1") {
1015
976
  fs.appendFileSync(logFile(configDir), [
1016
977
  `daemon invocation command=${invocation.command}`,
1017
978
  `daemon invocation args=${JSON.stringify(invocation.args)}`,
1018
979
  `daemon parent argv=${JSON.stringify(process.argv)}`,
1019
980
  `daemon parent execPath=${process.execPath}`,
1020
- `daemon child pkg env=${JSON.stringify(Object.fromEntries(Object.entries(env).filter(([key]) => key.startsWith('PKG'))))}`,
1021
- '',
1022
- ].join('\n'));
981
+ `daemon child pkg env=${JSON.stringify(Object.fromEntries(Object.entries(env).filter(([key]) => key.startsWith("PKG"))))}`,
982
+ ""
983
+ ].join("\n"));
1023
984
  }
1024
- const child = spawn(invocation.command, invocation.args, {
985
+ const child = (0, import_child_process.spawn)(invocation.command, invocation.args, {
1025
986
  detached: true,
1026
987
  env,
1027
- stdio: ['ignore', out, out],
988
+ stdio: ["ignore", out, out]
1028
989
  });
990
+ const childPid = child.pid;
991
+ if (!childPid) throw new Error("server process did not report its PID after launch");
1029
992
  child.unref();
1030
- fs.writeFileSync(pidFile(configDir), String(child.pid));
1031
-
993
+ fs.writeFileSync(pidFile(configDir), String(childPid));
1032
994
  let processIdentity = null;
1033
995
  try {
1034
- processIdentity = await readServerProcessIdentity(child.pid);
1035
- if (!processIdentity) throw new Error('server process identity could not be verified after launch');
1036
- writeServerState(configDir, env, child.pid, processIdentity, 'starting');
1037
- await waitForServer(env, serverStartTimeoutMs(env), child.pid);
1038
- await waitForProcessStability(child.pid, serverStartStabilityMs(env));
1039
- await waitForServer(env, Math.min(serverStartTimeoutMs(env), 5_000), child.pid);
1040
- const stableIdentity = await readServerProcessIdentity(child.pid);
1041
- if (
1042
- !stableIdentity
1043
- || stableIdentity.processGroupId !== processIdentity.processGroupId
1044
- || stableIdentity.startedAt !== processIdentity.startedAt
1045
- ) {
1046
- throw new Error('server process identity changed during startup');
996
+ processIdentity = await (0, import_server_process_identity.readServerProcessIdentity)(childPid);
997
+ if (!processIdentity) throw new Error("server process identity could not be verified after launch");
998
+ writeServerState(configDir, env, childPid, processIdentity, "starting");
999
+ await waitForServer(env, serverStartTimeoutMs(env), childPid);
1000
+ await waitForProcessStability(childPid, serverStartStabilityMs(env));
1001
+ await waitForServer(env, Math.min(serverStartTimeoutMs(env), 5e3), childPid);
1002
+ const stableIdentity = await (0, import_server_process_identity.readServerProcessIdentity)(childPid);
1003
+ if (!stableIdentity || stableIdentity.processGroupId !== processIdentity.processGroupId || stableIdentity.startedAt !== processIdentity.startedAt) {
1004
+ throw new Error("server process identity changed during startup");
1047
1005
  }
1048
- writeServerState(configDir, env, child.pid, stableIdentity, 'running');
1006
+ writeServerState(configDir, env, childPid, stableIdentity, "running");
1049
1007
  } catch (error) {
1050
1008
  try {
1051
- await cleanupFailedDaemonStart(configDir, child.pid, processIdentity);
1009
+ await cleanupFailedDaemonStart(configDir, childPid, processIdentity);
1052
1010
  } catch (cleanupError) {
1053
- console.error(`${error.message}; cleanup failed: ${cleanupError.message || cleanupError}`);
1011
+ console.error(
1012
+ `${errorString(error)}; cleanup failed: ${errorString(cleanupError) || cleanupError}`
1013
+ );
1054
1014
  return 1;
1055
1015
  }
1056
- console.error(error.message);
1057
- const logs = tailFile(logFile(configDir), 80);
1058
- if (logs) console.error(logs);
1016
+ console.error(errorString(error));
1017
+ const logs2 = tailFile(logFile(configDir), 80);
1018
+ if (logs2) console.error(logs2);
1059
1019
  return 1;
1060
1020
  }
1061
-
1062
- console.log(`Farming started (PID ${child.pid})`);
1021
+ console.log(`Farming started (PID ${childPid})`);
1063
1022
  const logs = tailFile(logFile(configDir), 40);
1064
- const urlLines = logs.split(/\r?\n/).filter(line => /Local:|Network:|Token:|Token style:|Token auth:/.test(line));
1023
+ const urlLines = logs.split(/\r?\n/).filter((line) => /Local:|Network:|Token:|Token style:|Token auth:/.test(line));
1065
1024
  if (urlLines.length > 0) {
1066
- console.log(urlLines.join('\n'));
1025
+ console.log(urlLines.join("\n"));
1067
1026
  } else {
1068
1027
  console.log(entryUrl(env));
1069
1028
  }
1070
1029
  return 0;
1071
1030
  }
1072
-
1073
1031
  async function stopDaemon(parsed) {
1074
1032
  const env = buildServerEnv(parsed.env);
1075
1033
  const configDir = env.FARMING_CONFIG_DIR;
@@ -1077,27 +1035,26 @@ async function stopDaemon(parsed) {
1077
1035
  if (!isRunning(pid)) {
1078
1036
  fs.rmSync(pidFile(configDir), { force: true });
1079
1037
  fs.rmSync(serverStateFile(configDir), { force: true });
1080
- console.log('Farming is not running.');
1038
+ console.log("Farming is not running.");
1081
1039
  return 0;
1082
1040
  }
1083
1041
  const state = readServerState(configDir);
1084
1042
  const port = Number(state.port || env.PORT || DEFAULT_PORT);
1085
- if (state.processIdentity?.format === SERVER_PROCESS_IDENTITY_FORMAT) {
1043
+ if (state.processIdentity?.format === import_server_process_identity.SERVER_PROCESS_IDENTITY_FORMAT) {
1086
1044
  await assertServerProcessIdentity(configDir, pid, state);
1087
1045
  } else {
1088
1046
  await migrateLegacyServerIdentity(configDir, pid, state);
1089
1047
  }
1090
1048
  try {
1091
- process.kill(pid, 'SIGKILL');
1049
+ process.kill(pid, "SIGKILL");
1092
1050
  } catch (error) {
1093
- if (error?.code === 'EPERM' || error?.code === 'EACCES') {
1051
+ if (errorString(error, "code") === "EPERM" || errorString(error, "code") === "EACCES") {
1094
1052
  throw new Error(
1095
- `Farming cannot stop server ${pid} because this command lacks permission. `
1096
- + 'Run it as the operating-system user that owns the process (or as an administrator), then start Farming again.',
1097
- { cause: error },
1053
+ `Farming cannot stop server ${pid} because this command lacks permission. Run it as the operating-system user that owns the process (or as an administrator), then start Farming again.`,
1054
+ { cause: error }
1098
1055
  );
1099
1056
  }
1100
- if (error?.code !== 'ESRCH') throw error;
1057
+ if (errorString(error, "code") !== "ESRCH") throw error;
1101
1058
  }
1102
1059
  await waitForDaemonStop(pid, port, { timeoutMs: serverStopTimeoutMs(env) });
1103
1060
  if (readPid(configDir) === pid) fs.rmSync(pidFile(configDir), { force: true });
@@ -1105,30 +1062,28 @@ async function stopDaemon(parsed) {
1105
1062
  console.log(`Stopped Farming (PID ${pid})`);
1106
1063
  return 0;
1107
1064
  }
1108
-
1109
1065
  async function statusDaemon(parsed) {
1110
1066
  const env = buildServerEnv(parsed.env);
1111
1067
  const configDir = env.FARMING_CONFIG_DIR;
1112
1068
  const pid = readPid(configDir);
1113
1069
  if (!isRunning(pid)) {
1114
- console.log('Farming is not running.');
1070
+ console.log("Farming is not running.");
1115
1071
  return 0;
1116
1072
  }
1117
1073
  const state = readServerState(configDir);
1118
1074
  try {
1119
- if (state.processIdentity?.format === SERVER_PROCESS_IDENTITY_FORMAT) {
1075
+ if (state.processIdentity?.format === import_server_process_identity.SERVER_PROCESS_IDENTITY_FORMAT) {
1120
1076
  await assertServerProcessIdentity(configDir, pid, state);
1121
1077
  } else {
1122
1078
  await migrateLegacyServerIdentity(configDir, pid, state);
1123
1079
  }
1124
1080
  } catch (error) {
1125
1081
  console.error(
1126
- `Farming PID ${pid} is live, but this config directory does not prove that it owns the Server: `
1127
- + `${error.message || error}`,
1082
+ `Farming PID ${pid} is live, but this config directory does not prove that it owns the Server: ${errorString(error) || error}`
1128
1083
  );
1129
1084
  return 1;
1130
1085
  }
1131
- if (state.phase === 'starting') {
1086
+ if (state.phase === "starting") {
1132
1087
  console.log(`Farming is starting (PID ${pid}). Run 'farming start' to replace an interrupted startup.`);
1133
1088
  return 1;
1134
1089
  }
@@ -1137,14 +1092,12 @@ async function statusDaemon(parsed) {
1137
1092
  if (logs) console.log(logs);
1138
1093
  return 0;
1139
1094
  }
1140
-
1141
1095
  function showLogs(parsed) {
1142
1096
  const env = buildServerEnv(parsed.env);
1143
1097
  const logs = tailFile(logFile(env.FARMING_CONFIG_DIR), 120);
1144
- console.log(logs || 'No Farming log found.');
1098
+ console.log(logs || "No Farming log found.");
1145
1099
  return 0;
1146
1100
  }
1147
-
1148
1101
  function showUrl(parsed) {
1149
1102
  const env = buildServerEnv(parsed.env);
1150
1103
  if (!parsed.portExplicit && !isPortOverrideExplicit(parsed.env, process.env)) {
@@ -1155,7 +1108,6 @@ function showUrl(parsed) {
1155
1108
  console.log(entryUrl(env));
1156
1109
  return 0;
1157
1110
  }
1158
-
1159
1111
  function usage() {
1160
1112
  return `Usage:
1161
1113
  farming [start] [--port 6694] [--base-path /farming] [--config-dir ~/.farming]
@@ -1164,127 +1116,123 @@ function usage() {
1164
1116
  farming stop
1165
1117
  farming logs
1166
1118
  farming url
1167
- farming runtime prepare [--config-dir ~/.farming]
1119
+ farming runtime prepare [--config-dir ~/.farming] [--no-activate]
1168
1120
  farming review <git-dir> <old-revision> <new-revision|now> [--branch <branch>] [--no-open]
1169
1121
 
1170
1122
  Agent control commands are also available:
1171
1123
  farming skills
1172
1124
  farming capabilities [--json]
1173
1125
  farming browser ...
1126
+ farming computer ...
1174
1127
  farming list [--json] [--parent <agentId>]
1175
1128
  farming spawn --workspace <repo> -- <command...>
1176
1129
  farming output <agentId> [--tail <chars>]
1177
1130
  farming send <agentId> <text...>
1178
1131
  farming kill <agentId>`;
1179
1132
  }
1180
-
1181
1133
  async function run(argv = process.argv.slice(2)) {
1182
- if (process.env.FARMING_DEBUG_CLI === '1' && argv[0] === 'debug-argv') {
1134
+ if (process.env.FARMING_DEBUG_CLI === "1" && argv[0] === "debug-argv") {
1183
1135
  console.log(JSON.stringify({
1184
1136
  argv: process.argv,
1185
1137
  execPath: process.execPath,
1186
- pkg: Boolean(process.pkg),
1138
+ pkg: Boolean(packagedProcess.pkg)
1187
1139
  }, null, 2));
1188
1140
  return 0;
1189
1141
  }
1190
-
1191
- if (argv[0] === PACKAGED_CODEX_ACP_ARG) {
1192
- await runPackagedCodexAcp();
1142
+ if (argv[0] === import_packaged_codex_acp.PACKAGED_CODEX_ACP_ARG) {
1143
+ await (0, import_packaged_codex_acp.runPackagedCodexAcp)();
1193
1144
  return 0;
1194
1145
  }
1195
-
1196
- if (argv[0] === PACKAGED_CLAUDE_ACP_ARG) {
1197
- await runPackagedClaudeAcp();
1146
+ if (argv[0] === import_packaged_claude_acp.PACKAGED_CLAUDE_ACP_ARG) {
1147
+ await (0, import_packaged_claude_acp.runPackagedClaudeAcp)();
1198
1148
  return 0;
1199
1149
  }
1200
-
1201
1150
  if (argv[0] === USAGE_HISTORY_SMOKE_ARG) {
1202
- const { runUsageHistorySmoke } = require('./usage-history-smoke');
1151
+ const { runUsageHistorySmoke } = require("./usage-history-smoke.cjs");
1203
1152
  const result = await runUsageHistorySmoke();
1204
1153
  console.log(JSON.stringify(result));
1205
1154
  return 0;
1206
1155
  }
1207
-
1208
- if (argv[0] === NATIVE_PTY_HOST_ARG || process.env.FARMING_RUN_NATIVE_PTY_HOST === '1') {
1156
+ if (argv[0] === NATIVE_PTY_HOST_ARG || argv.length === 0 && process.env.FARMING_RUN_NATIVE_PTY_HOST === "1") {
1209
1157
  runNativePtyHostInCurrentProcess();
1210
1158
  return 0;
1211
1159
  }
1212
-
1213
- if (process.env[SERVER_MODE_ENV] === '1' || argv[0] === SERVER_MODE_ARG) {
1160
+ if (argv[0] === SERVER_MODE_ARG || argv.length === 0 && process.env[SERVER_MODE_ENV] === "1") {
1214
1161
  await runServerInCurrentProcess();
1215
1162
  return 0;
1216
1163
  }
1217
-
1218
- if (argv[0] === 'browser') {
1219
- const { run: runBrowserCli } = require('../extensions/browser/bin/farming-browser');
1164
+ if (argv[0] === "browser") {
1165
+ const { run: runBrowserCli } = require("../extensions/browser/bin/farming-browser");
1220
1166
  return runBrowserCli(argv.slice(1));
1221
1167
  }
1222
-
1223
- if (argv[0] === 'runtime' && argv[1] === 'prepare') {
1224
- const parsed = parseServerArgs(['start', ...argv.slice(2)]);
1225
- const env = buildServerEnv(parsed.env);
1226
- const result = await prepareStartupDependencies(env, { force: true });
1168
+ if (argv[0] === "computer") {
1169
+ const { run: runComputerCli } = require("../extensions/computer/bin/farming-computer");
1170
+ return runComputerCli(argv.slice(1));
1171
+ }
1172
+ if (argv[0] === "runtime" && argv[1] === "prepare") {
1173
+ const activate = !argv.slice(2).includes("--no-activate");
1174
+ const parsed2 = parseServerArgs([
1175
+ "start",
1176
+ ...argv.slice(2).filter((arg) => arg !== "--no-activate")
1177
+ ]);
1178
+ const env = buildServerEnv(parsed2.env);
1179
+ const result = await prepareStartupDependencies(env, { activate, force: true });
1227
1180
  console.log(JSON.stringify(result, null, 2));
1228
1181
  return 0;
1229
1182
  }
1230
-
1231
1183
  if (SERVER_BACKED_CONTROL_COMMANDS.has(argv[0])) {
1232
1184
  return runServerBackedControlCli(argv);
1233
1185
  }
1234
-
1235
1186
  if (CONTROL_COMMANDS.has(argv[0])) {
1236
- return runControlCli(argv);
1187
+ return (0, import_farming_cli.run)(argv);
1237
1188
  }
1238
-
1239
- if (argv[0] === 'review') return runReview(parseReviewArgs(argv.slice(1)));
1240
-
1189
+ if (argv[0] === "review") return runReview(parseReviewArgs(argv.slice(1)));
1241
1190
  const parsed = parseServerArgs(argv);
1242
- if (parsed.command === 'help') {
1191
+ if (parsed.command === "help") {
1243
1192
  console.log(usage());
1244
1193
  return 0;
1245
1194
  }
1246
- if (parsed.command === 'daemon') return startDaemon(parsed);
1247
- if (parsed.command === 'stop') return stopDaemon(parsed);
1248
- if (parsed.command === 'status') return statusDaemon(parsed);
1249
- if (parsed.command === 'logs') return showLogs(parsed);
1250
- if (parsed.command === 'url') return showUrl(parsed);
1195
+ if (parsed.command === "daemon") return startDaemon(parsed);
1196
+ if (parsed.command === "stop") return stopDaemon(parsed);
1197
+ if (parsed.command === "status") return statusDaemon(parsed);
1198
+ if (parsed.command === "logs") return showLogs(parsed);
1199
+ if (parsed.command === "url") return showUrl(parsed);
1251
1200
  await startForeground(parsed);
1252
1201
  return 0;
1253
1202
  }
1254
-
1255
1203
  if (require.main === module) {
1256
- run().then(code => {
1204
+ run().then((code) => {
1257
1205
  if (code) process.exit(code);
1258
- }).catch(error => {
1259
- console.error(error.message || error);
1206
+ }).catch((error) => {
1207
+ console.error(errorString(error) || error);
1260
1208
  process.exit(1);
1261
1209
  });
1262
1210
  }
1263
-
1264
- module.exports = {
1265
- SERVER_MODE_ARG,
1211
+ // Annotate the CommonJS export names for ESM import in node:
1212
+ 0 && (module.exports = {
1266
1213
  NATIVE_PTY_HOST_ARG,
1214
+ SERVER_MODE_ARG,
1267
1215
  buildCleanEnvExecArgs,
1268
1216
  buildCleanEnvExecCommand,
1269
- childInvocation,
1270
- cleanupFailedDaemonStart,
1271
1217
  buildControlEnv,
1272
1218
  buildServerEnv,
1219
+ childInvocation,
1220
+ cleanupFailedDaemonStart,
1273
1221
  computeNodeHeapMb,
1274
1222
  defaultConfigDir,
1275
1223
  findAvailablePort,
1276
- parseServerArgs,
1277
1224
  parseReviewArgs,
1225
+ parseServerArgs,
1226
+ readServerProcessIdentity,
1227
+ readServerState,
1278
1228
  resolveReviewTarget,
1279
1229
  reviewUrl,
1280
- readServerState,
1281
- readServerProcessIdentity,
1282
- serverStartTimeoutMs,
1230
+ run,
1283
1231
  serverStartStabilityMs,
1232
+ serverStartTimeoutMs,
1233
+ serverStateFile,
1284
1234
  serverStopTimeoutMs,
1285
1235
  splitControlArgs,
1286
1236
  stopDaemon,
1287
- run,
1288
- serverStateFile,
1289
- waitForDaemonStop,
1290
- };
1237
+ waitForDaemonStop
1238
+ });