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,305 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
- const MANAGED_BLOCK_START = '<!-- FARMING_MAIN_AGENT_SKILLS:START -->';
5
- const MANAGED_BLOCK_END = '<!-- FARMING_MAIN_AGENT_SKILLS:END -->';
6
-
7
- const REMOVED_MAIN_AGENT_SKILL_IDS = [];
8
-
9
- const MAIN_AGENT_OPERATING_GUIDE = [
10
- {
11
- title: 'Mission',
12
- lines: [
13
- 'You are the Farming Main Agent: an attention steward for the human, not a background log reader.',
14
- 'Your value is to keep track of what other agents are doing, notice when the human should care, and compress parallel work into clear next actions.',
15
- ],
16
- },
17
- {
18
- title: 'Startup routine',
19
- lines: [
20
- 'On startup or resume, orient yourself with `farming list --json` and inspect `FARMING_PROJECT_WORKSPACE` / `FARMING_MAIN_WORKSPACE` before proposing work.',
21
- 'Do not spawn child agents just because you can. Wait for a concrete user goal, or ask one short clarification if the goal is too vague to route safely.',
22
- 'Use `farming memory report` only when recent local context would change what you do next.',
23
- ],
24
- },
25
- {
26
- title: 'Observing agents',
27
- lines: [
28
- 'Poll at a low frequency and look for state changes, not raw terminal chatter.',
29
- 'Use `farming output <agent-id> --tail <n>` only for agents that are blocked, newly finished, noisy, or directly relevant to the current user question.',
30
- 'Classify agents as running, waiting for input, blocked, failed, complete, stale, or safe to ignore; include the agent id behind each claim.',
31
- ],
32
- },
33
- {
34
- title: 'Delegating work',
35
- lines: [
36
- 'Spawn child agents only when parallelism clearly helps a user goal.',
37
- 'Give each child a narrow workspace, task, success criteria, forbidden scope, and required evidence or tests.',
38
- 'Keep the default fanout small; prefer 2-4 focused children over many overlapping agents.',
39
- ],
40
- },
41
- {
42
- title: 'Intervening',
43
- lines: [
44
- 'Use `farming send` to unblock or redirect a child agent with specific instructions.',
45
- 'Do not issue destructive commands, broad rewrites, permission changes, or high-risk cleanup without summarizing the risk and getting user confirmation.',
46
- 'Kill agents only when they are clearly done, duplicated, stuck beyond recovery, or the user asks.',
47
- ],
48
- },
49
- {
50
- title: 'Reporting to the human',
51
- lines: [
52
- 'Report in short status summaries: What changed, who needs attention, what is done, and what you will do next.',
53
- 'Do not paste long logs. Quote or summarize only the evidence needed for a decision.',
54
- 'When multiple agents disagree, deduplicate findings, rank by severity, and name the evidence gap before deciding.',
55
- ],
56
- },
57
- ];
58
-
59
- const MAIN_AGENT_SKILLS = [
60
- {
61
- id: 'browser-resource',
62
- name: '系统浏览器操作',
63
- trigger: '用户要求打开、查看或操作 Farming Project 下的 Browser Resource,或者需要绕过静态 HTML Viewer 限制验证真实网页时',
64
- summary: '通过 Farming Browser ID 操作用户当前看到的同一个系统浏览器;先走 Browser 的渐进式帮助和标准 Workflow,只在需要时展开具体问题域与原子命令。',
65
- commands: [
66
- 'farming capabilities',
67
- 'farming browser list',
68
- 'farming browser help workflow',
69
- 'farming browser help <lifecycle|navigation|interaction|inspection|debugging|state|files>',
70
- ],
71
- },
72
- {
73
- id: 'memory-report',
74
- name: '记忆读取总结',
75
- trigger: '用户要求总结今日、昨日、本周做过什么,或需要先了解这台机器上各 agent 的近期工作记忆时',
76
- summary: '只读扫描本机 Claude/Qwen/Codex 本地历史线索,按时间段生成 Farming 日报或周报。',
77
- commands: [
78
- 'farming memory report --period today',
79
- 'farming memory report --period yesterday',
80
- 'farming memory report --period week',
81
- 'farming memory report --since <YYYY-MM-DD> --until <YYYY-MM-DD>',
82
- ],
83
- },
84
- {
85
- id: 'pest-control',
86
- name: '牧场除虫计划',
87
- trigger: '用户要求对某个目录、仓库或模块体系做系统性 bug 排查、除虫、深挖潜在缺陷时',
88
- summary: [
89
- 'Main Agent 先只读梳理目标目录结构,划分模块边界,明确模块间协议、数据流、调用关系和共享约束。',
90
- '随后为每个模块启动一个子 Agent 深挖潜在 bug;每个子 Agent 必须聚焦自己的模块,同时检查与相邻模块协议是否破坏。',
91
- 'Main Agent 负责汇总子 Agent 发现,去重、分级、安排可验证修复或给用户确认高风险改动。',
92
- ].join(' '),
93
- commands: [
94
- 'farming spawn --workspace <repo> --task "模块:<name>。请深挖该模块潜在 bug,重点检查边界条件、错误处理、并发/状态一致性、协议违约和测试缺口;不要修改其他模块,先报告可验证发现。" -- <coding-agent-command>',
95
- 'farming list --parent "$FARMING_AGENT_ID"',
96
- 'farming output <agent-id> --tail 2000',
97
- 'farming send <agent-id> "请基于已确认的模块协议继续检查交互边界,并给出最小可验证修复建议"',
98
- 'farming kill <agent-id>',
99
- ],
100
- },
101
- ];
102
-
103
- function getMainAgentSkillsCatalog() {
104
- return MAIN_AGENT_SKILLS.map((skill) => ({
105
- id: skill.id,
106
- name: skill.name,
107
- trigger: skill.trigger,
108
- summary: skill.summary,
109
- commands: skill.commands,
110
- }));
111
- }
112
-
113
- function renderMainAgentOperatingGuide() {
114
- const lines = [
115
- '# Farming Main Agent Operating Contract',
116
- '',
117
- ];
118
-
119
- MAIN_AGENT_OPERATING_GUIDE.forEach((section) => {
120
- lines.push(`## ${section.title}`);
121
- section.lines.forEach((line) => {
122
- lines.push(`- ${line}`);
123
- });
124
- lines.push('');
125
- });
126
-
127
- return lines.join('\n').trim();
128
- }
129
-
130
- function renderMainAgentSkills() {
131
- const lines = [
132
- '# Farming Main Agent Skills',
133
- '',
134
- 'You are the Farming Main Agent.',
135
- 'Run `farming skills` any time you need to review these skills.',
136
- 'Use these skills when the user asks for Farming-specific machine context.',
137
- '',
138
- ];
139
-
140
- MAIN_AGENT_SKILLS.forEach((skill, index) => {
141
- lines.push(`${index + 1}. ${skill.name} (${skill.id})`);
142
- lines.push(`Trigger: ${skill.trigger}`);
143
- lines.push(`Behavior: ${skill.summary}`);
144
- lines.push('Commands:');
145
- skill.commands.forEach((command) => {
146
- lines.push(`- ${command}`);
147
- });
148
- lines.push('');
149
- });
150
-
151
- lines.push('Rules:');
152
- lines.push('- Use `farming browser` only for Browser Resources already in the user-selected Project scope; follow `farming browser help workflow`, and reveal only the help topic or command needed for the current step.');
153
- lines.push('- Use `farming memory report` when you need recent context from local agent memories.');
154
- lines.push('- Use “牧场除虫计划” when the user asks for systematic bug hunting across a directory or module tree.');
155
- lines.push('- Before spawning child agents for pest control, map modules and module protocols first; do not send overlapping or vague tasks.');
156
- lines.push('- Keep child agents scoped to their assigned module and require evidence, reproduction notes, or tests for each bug claim.');
157
- lines.push('- For high-risk writes, destructive operations, or broad refactors, summarize the finding and ask the user before proceeding.');
158
-
159
- return [
160
- renderMainAgentOperatingGuide(),
161
- '',
162
- lines.join('\n'),
163
- ].join('\n');
164
- }
165
-
166
- function renderCanonicalAgentsFile() {
167
- return [
168
- '# Farming Main Agent',
169
- '',
170
- 'This directory is a Farming-managed Main Agent workspace.',
171
- '',
172
- 'Read this file before acting. You are the Farming Main Agent, not a project-local child agent.',
173
- 'Use the local `farming` CLI to inspect your abilities and coordinate work.',
174
- '',
175
- 'Useful commands:',
176
- '- `farming skills`',
177
- '- `farming memory report --period today`',
178
- '- `farming memory report --period yesterday`',
179
- '- `farming memory report --period week`',
180
- '- `farming spawn --workspace <repo> --task "<module bug hunt task>" -- <coding-agent-command>`',
181
- '- `farming list --parent "$FARMING_AGENT_ID"`',
182
- '- `farming output <agent-id> --tail 2000`',
183
- '- `farming send <agent-id> "<follow-up instruction>"`',
184
- '- `farming kill <agent-id>`',
185
- '',
186
- 'Environment:',
187
- '- `FARMING_MAIN_WORKSPACE` points at this Farming identity workspace.',
188
- '- `FARMING_PROJECT_WORKSPACE` points at the user-selected project workspace when available.',
189
- '- `FARMING_SKILLS_FILE` points at the detailed Farming skills file.',
190
- '',
191
- renderMainAgentSkills(),
192
- ].join('\n');
193
- }
194
-
195
- function renderCompatibilityFile(targetName = 'AGENTS.md') {
196
- return [
197
- `# Farming Main Agent (${targetName})`,
198
- '',
199
- `This file is a compatibility entrypoint for ${targetName}.`,
200
- 'It intentionally includes the full Farming Main Agent identity inline, because some coding CLIs read only their own memory filename and may not follow a pointer to AGENTS.md.',
201
- '',
202
- renderCanonicalAgentsFile(),
203
- ].join('\n');
204
- }
205
-
206
- function renderCompatibilityPointerFile(targetName = 'AGENTS.md') {
207
- return [
208
- '# Farming Main Agent',
209
- '',
210
- `This is a compatibility entrypoint for ${targetName}.`,
211
- '',
212
- 'The canonical Farming Main Agent instructions are in `AGENTS.md`.',
213
- 'Read `AGENTS.md`, then run `farming skills` if you need the current skill list.',
214
- '',
215
- ].join('\n');
216
- }
217
-
218
- function renderMainAgentBootstrap() {
219
- return [
220
- renderMainAgentSkills(),
221
- '',
222
- 'Bootstrap note: remember these Farming skills for future user requests.',
223
- ].join('\n');
224
- }
225
-
226
- function upsertManagedBlock(existingContent, block) {
227
- const start = existingContent.indexOf(MANAGED_BLOCK_START);
228
- const end = existingContent.indexOf(MANAGED_BLOCK_END);
229
-
230
- if (start !== -1 && end !== -1 && end > start) {
231
- const before = existingContent.slice(0, start).replace(/\s+$/g, '');
232
- const after = existingContent.slice(end + MANAGED_BLOCK_END.length).replace(/^\s+/g, '');
233
- return [before, block.trim(), after].filter(Boolean).join('\n\n') + '\n';
234
- }
235
-
236
- return [existingContent.trim(), block.trim()].filter(Boolean).join('\n\n') + '\n';
237
- }
238
-
239
- function writeManagedSkillFile(filePath, block) {
240
- let existing = '';
241
- try {
242
- existing = fs.readFileSync(filePath, 'utf8');
243
- } catch {
244
- existing = '';
245
- }
246
-
247
- fs.writeFileSync(filePath, upsertManagedBlock(existing, block));
248
- }
249
-
250
- function ensureMainAgentSkillFiles(farmingDir) {
251
- if (!farmingDir) return;
252
- fs.mkdirSync(farmingDir, { recursive: true });
253
-
254
- const skillsText = renderMainAgentSkills() + '\n';
255
- const skillsDir = path.join(farmingDir, 'skills');
256
- fs.mkdirSync(skillsDir, { recursive: true });
257
-
258
- fs.writeFileSync(path.join(farmingDir, 'FARMING_MAIN_AGENT_SKILLS.md'), skillsText);
259
- fs.writeFileSync(path.join(farmingDir, 'AGENTS.md'), `${renderCanonicalAgentsFile()}\n`);
260
- fs.writeFileSync(path.join(skillsDir, 'index.json'), JSON.stringify(MAIN_AGENT_SKILLS, null, 2) + '\n');
261
- MAIN_AGENT_SKILLS.forEach((skill) => {
262
- const lines = [
263
- `# ${skill.name}`,
264
- '',
265
- `ID: ${skill.id}`,
266
- '',
267
- `Trigger: ${skill.trigger}`,
268
- '',
269
- `Behavior: ${skill.summary}`,
270
- '',
271
- 'Commands:',
272
- ...skill.commands.map(command => `- ${command}`),
273
- '',
274
- ];
275
- fs.writeFileSync(path.join(skillsDir, `${skill.id}.md`), lines.join('\n'));
276
- });
277
- REMOVED_MAIN_AGENT_SKILL_IDS.forEach((skillId) => {
278
- fs.rmSync(path.join(skillsDir, `${skillId}.md`), { force: true });
279
- });
280
-
281
- // These filenames match the common project-memory files used by coding CLIs.
282
- // They live in Farming's internal workspace, not in the user's project.
283
- ['CLAUDE.md', 'QWEN.md'].forEach((filename) => {
284
- writeManagedSkillFile(path.join(farmingDir, filename), [
285
- MANAGED_BLOCK_START,
286
- renderCompatibilityFile(filename).trim(),
287
- MANAGED_BLOCK_END,
288
- '',
289
- ].join('\n'));
290
- });
291
- }
292
-
293
- module.exports = {
294
- MAIN_AGENT_SKILLS,
295
- MAIN_AGENT_OPERATING_GUIDE,
296
- getMainAgentSkillsCatalog,
297
- ensureMainAgentSkillFiles,
298
- renderCanonicalAgentsFile,
299
- renderCompatibilityFile,
300
- renderCompatibilityPointerFile,
301
- renderMainAgentBootstrap,
302
- renderMainAgentOperatingGuide,
303
- renderMainAgentSkills,
304
- upsertManagedBlock,
305
- };
@@ -1,122 +0,0 @@
1
- const path = require('path');
2
- const { parseCommand } = require('./cli-agents');
3
- const { isSafeProviderSessionId } = require('./provider-session-id');
4
-
5
- const AUTO_RESUME_AGENT_SESSION_PROVIDERS = new Set(['codex', 'claude', 'opencode', 'qoder']);
6
-
7
- function normalizeMainPageSessionProvider(provider) {
8
- const normalized = String(provider || '').trim().toLowerCase();
9
- return AUTO_RESUME_AGENT_SESSION_PROVIDERS.has(normalized) ? normalized : '';
10
- }
11
-
12
- function isSafeSessionId(sessionId) {
13
- return isSafeProviderSessionId(sessionId);
14
- }
15
-
16
- function mainPageAgentSessionKey(provider, sessionId, providerHomeId = '') {
17
- const normalizedProvider = normalizeMainPageSessionProvider(provider);
18
- const normalizedSessionId = String(sessionId || '').trim();
19
- if (!normalizedProvider || !normalizedSessionId) return '';
20
- const homeId = String(providerHomeId || '').trim();
21
- if (homeId && homeId !== 'default') return `agent-session:${normalizedProvider}:home:${homeId}:${normalizedSessionId}`;
22
- return `agent-session:${normalizedProvider}:${normalizedSessionId}`;
23
- }
24
-
25
- function mainPageAgentSessionFromKey(key) {
26
- const match = String(key || '').match(/^agent-session:([^:]+):(.+)$/);
27
- if (!match) return null;
28
-
29
- const provider = normalizeMainPageSessionProvider(match[1]);
30
- let providerHomeId = 'default';
31
- let sessionId = String(match[2] || '').trim();
32
- const homeMatch = sessionId.match(/^home:([A-Za-z0-9._-]+):(.+)$/);
33
- if (homeMatch) {
34
- providerHomeId = homeMatch[1];
35
- sessionId = String(homeMatch[2] || '').trim();
36
- }
37
- if (!provider || !isSafeSessionId(sessionId)) {
38
- return null;
39
- }
40
-
41
- return providerHomeId && providerHomeId !== 'default'
42
- ? { provider, providerHomeId, sessionId }
43
- : { provider, sessionId };
44
- }
45
-
46
- function mainPageAgentSessionsToAutoResume(settings) {
47
- const keys = Array.isArray(settings && settings.mainPageSessionKeys)
48
- ? settings.mainPageSessionKeys
49
- : [];
50
- const seen = new Set();
51
- const sessions = [];
52
-
53
- keys.forEach((key) => {
54
- const session = mainPageAgentSessionFromKey(key);
55
- if (!session) return;
56
-
57
- const dedupeKey = `${session.provider}:${session.providerHomeId || 'default'}:${session.sessionId}`;
58
- if (seen.has(dedupeKey)) return;
59
- seen.add(dedupeKey);
60
- sessions.push(session);
61
- });
62
-
63
- return sessions;
64
- }
65
-
66
- function resumedAgentSource(provider, sessionId, providerHomeId = '') {
67
- const homeId = String(providerHomeId || '').trim();
68
- return homeId && homeId !== 'default'
69
- ? `${provider}-history:home:${homeId}:${sessionId}`
70
- : `${provider}-history:${sessionId}`;
71
- }
72
-
73
- function mainPageSessionProviderForCommand(command) {
74
- const executable = parseCommand(command)
75
- .find(token => token !== 'env' && !/^[A-Za-z_][A-Za-z0-9_]*=/.test(token));
76
- const basename = path.basename(executable || '');
77
- if (basename === 'qodercli') return 'qoder';
78
- return normalizeMainPageSessionProvider(basename);
79
- }
80
-
81
- function isActiveAgent(agent) {
82
- return agent
83
- && agent.archived !== true
84
- && agent.status !== 'dead'
85
- && agent.status !== 'stopped';
86
- }
87
-
88
- function findActiveAgentClaimingSession(agents, provider, session) {
89
- const normalizedProvider = normalizeMainPageSessionProvider(provider);
90
- const sessionId = String((session && (session.id || session.sessionId)) || '').trim();
91
- if (!normalizedProvider || !isSafeSessionId(sessionId) || !Array.isArray(agents)) return null;
92
-
93
- const providerHomeId = String((session && session.providerHomeId) || 'default').trim() || 'default';
94
- const sessionKey = mainPageAgentSessionKey(normalizedProvider, sessionId, providerHomeId);
95
- const legacySessionKey = mainPageAgentSessionKey(normalizedProvider, sessionId);
96
- const exactSource = resumedAgentSource(normalizedProvider, sessionId, providerHomeId);
97
- const legacySource = resumedAgentSource(normalizedProvider, sessionId);
98
-
99
- return agents.find(agent => {
100
- if (!isActiveAgent(agent)) return false;
101
- if (agent.providerSessionTemporary === true) return false;
102
- if (agent.providerSessionKey === sessionKey || (providerHomeId === 'default' && agent.providerSessionKey === legacySessionKey)) return true;
103
- if (
104
- agent.providerSessionProvider === normalizedProvider
105
- && agent.providerSessionId === sessionId
106
- && (String(agent.providerHomeId || 'default').trim() || 'default') === providerHomeId
107
- ) {
108
- return true;
109
- }
110
- return agent.source === exactSource || (providerHomeId === 'default' && agent.source === legacySource);
111
- }) || null;
112
- }
113
-
114
- module.exports = {
115
- AUTO_RESUME_AGENT_SESSION_PROVIDERS,
116
- findActiveAgentClaimingSession,
117
- mainPageAgentSessionFromKey,
118
- mainPageAgentSessionKey,
119
- mainPageAgentSessionsToAutoResume,
120
- mainPageSessionProviderForCommand,
121
- resumedAgentSource,
122
- };
@@ -1,106 +0,0 @@
1
- const crypto = require('crypto');
2
- const fs = require('fs');
3
- const path = require('path');
4
- const storageLayout = require('./storage-layout');
5
-
6
- const LOCK_RETRY_MS = 10;
7
- const LOCK_TIMEOUT_MS = 5000;
8
- const STALE_LOCK_MS = 30000;
9
-
10
- function delay(ms) {
11
- return new Promise(resolve => setTimeout(resolve, ms));
12
- }
13
-
14
- function positiveGeneration(value) {
15
- const parsed = Math.floor(Number(value));
16
- return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
17
- }
18
-
19
- async function acquireGenerationLock(lockDir) {
20
- const deadline = Date.now() + LOCK_TIMEOUT_MS;
21
- while (Date.now() < deadline) {
22
- try {
23
- await fs.promises.mkdir(lockDir);
24
- return;
25
- } catch (error) {
26
- if (!error || error.code !== 'EEXIST') throw error;
27
- try {
28
- const stat = await fs.promises.stat(lockDir);
29
- if (Date.now() - stat.mtimeMs > STALE_LOCK_MS) {
30
- await fs.promises.rm(lockDir, { recursive: true, force: true });
31
- continue;
32
- }
33
- } catch (statError) {
34
- if (!statError || statError.code !== 'ENOENT') throw statError;
35
- }
36
- await delay(LOCK_RETRY_MS);
37
- }
38
- }
39
- throw new Error('Timed out allocating native PTY controller generation');
40
- }
41
-
42
- async function allocateGeneration(generationFile, lockDir) {
43
- const root = path.dirname(generationFile);
44
- await fs.promises.mkdir(root, { recursive: true });
45
- await acquireGenerationLock(lockDir);
46
- try {
47
- let current = 0;
48
- try {
49
- current = positiveGeneration(await fs.promises.readFile(generationFile, 'utf8'));
50
- } catch (error) {
51
- if (!error || error.code !== 'ENOENT') throw error;
52
- }
53
- const generation = current + 1;
54
- const temporary = `${generationFile}.${process.pid}.${crypto.randomUUID()}.tmp`;
55
- await fs.promises.writeFile(temporary, `${generation}\n`, { mode: 0o600 });
56
- await fs.promises.rename(temporary, generationFile);
57
- return generation;
58
- } finally {
59
- await fs.promises.rm(lockDir, { recursive: true, force: true });
60
- }
61
- }
62
-
63
- async function allocateNativePtyControllerGeneration(configDir) {
64
- const root = path.resolve(configDir);
65
- const generationFile = storageLayout.nativePtyControllerGenerationFile(root);
66
- const lockDir = storageLayout.nativePtyControllerGenerationLockDir(root);
67
- return allocateGeneration(generationFile, lockDir);
68
- }
69
-
70
- async function allocateNativePtyRuntimeGeneration(configDir) {
71
- const root = path.resolve(configDir);
72
- return allocateGeneration(
73
- storageLayout.nativePtyRuntimeGenerationFile(root),
74
- storageLayout.nativePtyRuntimeGenerationLockDir(root),
75
- );
76
- }
77
-
78
- function formatNativePtyRuntimeEpoch(generation, id = crypto.randomUUID()) {
79
- const normalized = positiveGeneration(generation);
80
- if (!normalized) throw new Error('Native PTY runtime generation must be positive');
81
- return `farming-runtime-v1:${String(normalized).padStart(20, '0')}:${id}`;
82
- }
83
-
84
- function nativePtyRuntimeEpochGeneration(runtimeEpoch) {
85
- const match = /^farming-runtime-v1:(\d{20}):/.exec(String(runtimeEpoch || ''));
86
- if (!match) return null;
87
- const generation = Number(match[1]);
88
- return Number.isSafeInteger(generation) && generation > 0 ? generation : null;
89
- }
90
-
91
- function compareNativePtyRuntimeEpochs(left, right) {
92
- if (left === right) return 0;
93
- const leftGeneration = nativePtyRuntimeEpochGeneration(left);
94
- const rightGeneration = nativePtyRuntimeEpochGeneration(right);
95
- if (leftGeneration === null || rightGeneration === null || leftGeneration === rightGeneration) return null;
96
- return leftGeneration < rightGeneration ? -1 : 1;
97
- }
98
-
99
- module.exports = {
100
- allocateNativePtyControllerGeneration,
101
- allocateNativePtyRuntimeGeneration,
102
- compareNativePtyRuntimeEpochs,
103
- formatNativePtyRuntimeEpoch,
104
- nativePtyRuntimeEpochGeneration,
105
- positiveGeneration,
106
- };
@@ -1,86 +0,0 @@
1
- const crypto = require('crypto');
2
- const fs = require('fs');
3
- const path = require('path');
4
-
5
- const NATIVE_PTY_HOST_PROTOCOL_VERSION = 8;
6
- const NATIVE_PTY_HOST_RUNTIME_FILES = Object.freeze([
7
- 'agent-env.js',
8
- 'input-parts.js',
9
- 'local-session-engine.js',
10
- 'native-pty-host.js',
11
- 'shell-busy-integration.js',
12
- 'terminal-screen-worker-pool.js',
13
- 'terminal-screen-worker-thread.js',
14
- 'terminal-screen-worker.js',
15
- 'terminal-reducer-flow-control.js',
16
- 'terminal-state-serialization.js',
17
- 'native-pty-controller-generation.js',
18
- 'terminal-status.js',
19
- ]);
20
-
21
- function readFileForIdentity(filePath) {
22
- try {
23
- return fs.readFileSync(filePath);
24
- } catch (error) {
25
- return Buffer.from(`missing:${error && error.code ? error.code : 'unknown'}`, 'utf8');
26
- }
27
- }
28
-
29
- function packageVersion(backendDir) {
30
- try {
31
- const packageJson = JSON.parse(fs.readFileSync(path.join(backendDir, '..', 'package.json'), 'utf8'));
32
- return typeof packageJson.version === 'string' ? packageJson.version : '';
33
- } catch {
34
- return '';
35
- }
36
- }
37
-
38
- function nativePtyHostRuntimeIdentity(backendDir = __dirname) {
39
- const hash = crypto.createHash('sha256');
40
- const version = packageVersion(backendDir);
41
- hash.update(`protocol:${NATIVE_PTY_HOST_PROTOCOL_VERSION}\n`);
42
- hash.update(`version:${version}\n`);
43
- for (const filename of NATIVE_PTY_HOST_RUNTIME_FILES) {
44
- hash.update(`file:${filename}\n`);
45
- hash.update(readFileForIdentity(path.join(backendDir, filename)));
46
- hash.update('\n');
47
- }
48
- return Object.freeze({
49
- protocolVersion: NATIVE_PTY_HOST_PROTOCOL_VERSION,
50
- buildId: hash.digest('hex'),
51
- version,
52
- });
53
- }
54
-
55
- function normalizeNativePtyHostRuntimeIdentity(value) {
56
- if (!value || typeof value !== 'object') return null;
57
- const protocolVersion = Number(value.protocolVersion);
58
- const buildId = typeof value.buildId === 'string' ? value.buildId.trim() : '';
59
- if (!Number.isInteger(protocolVersion) || protocolVersion <= 0 || !/^[a-f0-9]{64}$/i.test(buildId)) {
60
- return null;
61
- }
62
- return {
63
- protocolVersion,
64
- buildId: buildId.toLowerCase(),
65
- version: typeof value.version === 'string' ? value.version : '',
66
- };
67
- }
68
-
69
- function nativePtyHostRuntimeIdentityMatches(expected, actual) {
70
- const normalizedExpected = normalizeNativePtyHostRuntimeIdentity(expected);
71
- const normalizedActual = normalizeNativePtyHostRuntimeIdentity(actual);
72
- return Boolean(
73
- normalizedExpected &&
74
- normalizedActual &&
75
- normalizedExpected.protocolVersion === normalizedActual.protocolVersion &&
76
- normalizedExpected.buildId === normalizedActual.buildId
77
- );
78
- }
79
-
80
- module.exports = {
81
- NATIVE_PTY_HOST_PROTOCOL_VERSION,
82
- NATIVE_PTY_HOST_RUNTIME_FILES,
83
- nativePtyHostRuntimeIdentity,
84
- nativePtyHostRuntimeIdentityMatches,
85
- normalizeNativePtyHostRuntimeIdentity,
86
- };
@@ -1,42 +0,0 @@
1
- const crypto = require('crypto');
2
- const os = require('os');
3
- const path = require('path');
4
-
5
- function nativePtyHostSocketPath(configDir) {
6
- const root = configDir || process.env.FARMING_CONFIG_DIR || path.join(os.homedir(), '.farming');
7
- const hash = crypto
8
- .createHash('sha1')
9
- .update(path.resolve(root))
10
- .digest('hex')
11
- .slice(0, 12);
12
-
13
- if (process.platform === 'win32') {
14
- return `\\\\.\\pipe\\farming-native-pty-${hash}`;
15
- }
16
-
17
- return path.join(os.tmpdir(), `farming-native-pty-${process.getuid ? process.getuid() : 'user'}-${hash}.sock`);
18
- }
19
-
20
- function nativePtyHostPrivateSocketHash(socketPath) {
21
- return crypto.createHash('sha256').update(socketPath).digest('hex').slice(0, 8);
22
- }
23
-
24
- function nativePtyHostPrivateSocketPath(socketPath, options = {}) {
25
- const pid = Number(options.pid || process.pid);
26
- const nonce = String(options.nonce || crypto.randomBytes(4).toString('hex'));
27
- return path.join(
28
- path.dirname(socketPath),
29
- `.fpty-${pid}-${nativePtyHostPrivateSocketHash(socketPath)}-${nonce}.sock`,
30
- );
31
- }
32
-
33
- function nativePtyHostPrivateSocketNamePattern(socketPath) {
34
- const hash = nativePtyHostPrivateSocketHash(socketPath);
35
- return new RegExp(`^\\.fpty-\\d+-${hash}-[a-f0-9]+\\.sock$`);
36
- }
37
-
38
- module.exports = {
39
- nativePtyHostPrivateSocketNamePattern,
40
- nativePtyHostPrivateSocketPath,
41
- nativePtyHostSocketPath,
42
- };