farming-code 2.2.23 → 2.2.28

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 (264) hide show
  1. package/README.md +9 -2
  2. package/README.zh_cn.md +9 -2
  3. package/THIRD_PARTY_NOTICES.md +3 -0
  4. package/backend/acp-runtime.js +15 -1
  5. package/backend/agent-manager.js +1054 -94
  6. package/backend/atomic-json-store.js +37 -0
  7. package/backend/cli-agents.js +9 -7
  8. package/backend/config-manager.js +167 -58
  9. package/backend/control-api.js +2 -1
  10. package/backend/farming-agent-bootstrap.js +49 -0
  11. package/backend/farming-agent-bootstrap.zh_cn.md +5 -0
  12. package/backend/farming-app-cli.js +9 -2
  13. package/backend/farming-cli.js +55 -0
  14. package/backend/farming-session-store.js +92 -89
  15. package/backend/main-agent-skills.js +17 -0
  16. package/backend/native-pty-host-client.js +99 -7
  17. package/backend/native-pty-host-path.js +20 -0
  18. package/backend/native-pty-host.js +6 -5
  19. package/backend/preview-session-manager.js +68 -0
  20. package/backend/provider-adapters.js +44 -5
  21. package/backend/review-session-store.js +32 -25
  22. package/backend/review-state-store.js +13 -14
  23. package/backend/run-history-store.js +13 -16
  24. package/backend/server.js +103 -78
  25. package/backend/storage-layout.js +20 -0
  26. package/backend/workspace-file-router.js +171 -6
  27. package/backend/workspace-file-service.js +19 -0
  28. package/backend/workspace-root-registry.js +6 -4
  29. package/dist/assets/App-CM7Cy-l4.css +1 -0
  30. package/dist/assets/App-CPG4WcjO.js +658 -0
  31. package/dist/assets/{FileEditorMarkdownPreview-KbnE8VC8.js → FileEditorMarkdownPreview-DYOMm-b1.js} +5 -5
  32. package/dist/assets/FileEditorPane-DXXq82aM.js +2 -0
  33. package/dist/assets/IconGlyphs-DrdPjYXr.js +1 -0
  34. package/dist/assets/ProjectFilesSection-CP66XVPl.js +12 -0
  35. package/dist/assets/{ReviewPage-L1vh1Ggs.js → ReviewPage-w21MEPD6.js} +1 -1
  36. package/dist/assets/{abnfDiagram-VRR7QNED-nnglrXFi.js → abnfDiagram-VRR7QNED-BY1qwq8A.js} +1 -1
  37. package/dist/assets/api-w2x5QfxB.js +1 -0
  38. package/dist/assets/{arc-CWoVlxJw.js → arc-DgZRAlwj.js} +1 -1
  39. package/dist/assets/{architectureDiagram-ZJ3FMSHR-BEXMaFfY.js → architectureDiagram-ZJ3FMSHR-jFn144od.js} +1 -1
  40. package/dist/assets/{blockDiagram-677ZJIJ3-1mCezSBk.js → blockDiagram-677ZJIJ3-BmRjlV0H.js} +1 -1
  41. package/dist/assets/{c4Diagram-LMCZKHZV-DhTiI6Uv.js → c4Diagram-LMCZKHZV-DUKul6tT.js} +1 -1
  42. package/dist/assets/{workspace-editor-monaco-DLlws5Ig.js → channel-CI9j3QFD.js} +1 -1
  43. package/dist/assets/chunk-2Q5K7J3B-87UnWaoh.js +1 -0
  44. package/dist/assets/{chunk-32BRIVSS-CCdsKd73.js → chunk-32BRIVSS-rGVu23o5.js} +1 -1
  45. package/dist/assets/{chunk-52WLFC77-Gncjk4LF.js → chunk-52WLFC77-CvFDKgbB.js} +1 -1
  46. package/dist/assets/{chunk-5VM5RSS4-Dlw7AXWp.js → chunk-5VM5RSS4-CFgnRW1C.js} +1 -1
  47. package/dist/assets/{chunk-7BUUIJ7U-ZBRhjLOh.js → chunk-7BUUIJ7U-Cp7bqW6s.js} +1 -1
  48. package/dist/assets/{chunk-C7G6YPKG-CiDVUP82.js → chunk-C7G6YPKG-BIS1gjZO.js} +1 -1
  49. package/dist/assets/{chunk-EX3LRPZG-z6gXP2_N.js → chunk-EX3LRPZG-BKG-cR9j.js} +1 -1
  50. package/dist/assets/{chunk-FWX5IMBZ-DMZBccQa.js → chunk-FWX5IMBZ-B8PsTr8a.js} +2 -2
  51. package/dist/assets/{chunk-HOUHSVGY-D8tIeoPk.js → chunk-HOUHSVGY-BHFOAiXT.js} +1 -1
  52. package/dist/assets/{chunk-ICXQ74PX-b6oQ2Q17.js → chunk-ICXQ74PX-CvLE1J9X.js} +1 -1
  53. package/dist/assets/{chunk-JWPE2WC7-DSyBRaRG.js → chunk-JWPE2WC7-D8misks7.js} +1 -1
  54. package/dist/assets/{chunk-MOJQB5TN-DAVH_p2a.js → chunk-MOJQB5TN-D-oNgSNH.js} +1 -1
  55. package/dist/assets/{chunk-OGEWGWER-DxoiMCI-.js → chunk-OGEWGWER-C2N-la9e.js} +1 -1
  56. package/dist/assets/{chunk-PUDLZKDR-NsOWh7HM.js → chunk-PUDLZKDR-BwI3Jz8q.js} +1 -1
  57. package/dist/assets/{chunk-Q4XR5HBZ-Di4H7L21.js → chunk-Q4XR5HBZ-BuqGfsXA.js} +1 -1
  58. package/dist/assets/{chunk-RYQCIY6F-CZA9pvFX.js → chunk-RYQCIY6F-Bq4XZcGt.js} +1 -1
  59. package/dist/assets/{chunk-V7JOEXUC-DttpZg9Y.js → chunk-V7JOEXUC-QZLzdTTJ.js} +1 -1
  60. package/dist/assets/chunk-VAUOI2AC-Cb0-kQ9g.js +1 -0
  61. package/dist/assets/{chunk-VR4S4FIN-D-Fmtd4Z.js → chunk-VR4S4FIN-DcZTpML_.js} +1 -1
  62. package/dist/assets/{chunk-WYO6CB5R-CUxMtfK2.js → chunk-WYO6CB5R-DCU8wuny.js} +2 -2
  63. package/dist/assets/chunk-XXDRQBXY-BZAC1Krv.js +1 -0
  64. package/dist/assets/{chunk-ZGVPDNZ5-CoV2QEl0.js → chunk-ZGVPDNZ5-B7r85QbY.js} +1 -1
  65. package/dist/assets/{chunk-ZIRB5QZD-DncwlQQc.js → chunk-ZIRB5QZD-BgEnDWhQ.js} +1 -1
  66. package/dist/assets/classDiagram-OUVF2IWQ-DcvGOuvi.js +1 -0
  67. package/dist/assets/classDiagram-v2-EOCWNBFH-DDYUSofQ.js +1 -0
  68. package/dist/assets/code-dark-BDjwj7Um.css +1 -0
  69. package/dist/assets/{cose-bilkent-JH36ORCC-BNIAz0nN.js → cose-bilkent-JH36ORCC-CThXS2qG.js} +1 -1
  70. package/dist/assets/{cssMode-DDWxTPm_.js → cssMode-Bdg5RpcJ.js} +1 -1
  71. package/dist/assets/{cynefinDiagram-TSTJHNR4-0xPI92Lg.js → cynefinDiagram-TSTJHNR4-DxBgzw25.js} +1 -1
  72. package/dist/assets/{dagre-DXlcHgr3.js → dagre-BM-GvGUZ.js} +1 -1
  73. package/dist/assets/{dagre-VKFMJZFB-DfuMG4gU.js → dagre-VKFMJZFB-B7UCRmxR.js} +1 -1
  74. package/dist/assets/{diagram-FQU43EPY-CT00bLZ6.js → diagram-FQU43EPY-CeL2DwKx.js} +1 -1
  75. package/dist/assets/{diagram-G47NLZAW-Xbh7zXUx.js → diagram-G47NLZAW-BEirglCC.js} +1 -1
  76. package/dist/assets/{diagram-NH7WQ7WH-SRDVPfn7.js → diagram-NH7WQ7WH-C6wcI-Rl.js} +1 -1
  77. package/dist/assets/{diagram-OA4YK3LP-CQRli4Np.js → diagram-OA4YK3LP-DpM-XXtJ.js} +1 -1
  78. package/dist/assets/{diagram-WEI45ONY-DMf17WQi.js → diagram-WEI45ONY-BQyaut9k.js} +1 -1
  79. package/dist/assets/{ebnfDiagram-CCIWWBDH-DhpFkgJ5.js → ebnfDiagram-CCIWWBDH-UmAXsUhr.js} +1 -1
  80. package/dist/assets/{erDiagram-Q63AITRT-1IwxWmJo.js → erDiagram-Q63AITRT-CdYLEOch.js} +1 -1
  81. package/dist/assets/file-icons-BOlcJ0ZF.js +1 -0
  82. package/dist/assets/flowDiagram-23GEKE2U-CO-z9-tq.js +1 -0
  83. package/dist/assets/{freemarker2-QBsTERH-.js → freemarker2-DfMDJfnE.js} +1 -1
  84. package/dist/assets/{ganttDiagram-NO4QXBWP-BNCdfyr1.js → ganttDiagram-NO4QXBWP-DgSUNdUB.js} +1 -1
  85. package/dist/assets/{gitGraphDiagram-IHSO6WYX-pbyWZuiX.js → gitGraphDiagram-IHSO6WYX-DjwjtRtF.js} +1 -1
  86. package/dist/assets/{handlebars-CuoxPo5A.js → handlebars-BEdPtzMT.js} +1 -1
  87. package/dist/assets/{html-gX5PEu0Q.js → html-B1fPb1QD.js} +1 -1
  88. package/dist/assets/html2canvas-DsczWxBa.js +5 -0
  89. package/dist/assets/{htmlMode-DIWUbUxd.js → htmlMode-CY2ZjHxH.js} +1 -1
  90. package/dist/assets/{index-DhTUO8DA.js → index-BzQO3pUr.js} +2 -2
  91. package/dist/assets/{infoDiagram-FWYZ7A6U-BcTOgDbe.js → infoDiagram-FWYZ7A6U-Bi9076l2.js} +1 -1
  92. package/dist/assets/{ishikawaDiagram-FXEZZL3T-DCdvGKrn.js → ishikawaDiagram-FXEZZL3T-DaMaNZN7.js} +1 -1
  93. package/dist/assets/{javascript-BYKGIUGs.js → javascript-BV2OsWA0.js} +1 -1
  94. package/dist/assets/{journeyDiagram-5HDEW3XC-BZ-1q_IT.js → journeyDiagram-5HDEW3XC-CfDy69EZ.js} +1 -1
  95. package/dist/assets/{jsonMode-AFmQQP6u.js → jsonMode-zd07aeuX.js} +1 -1
  96. package/dist/assets/{kanban-definition-HUTT4EX6-BIgejCjj.js → kanban-definition-HUTT4EX6-XFvZ722B.js} +1 -1
  97. package/dist/assets/{line-CfptFMmX.js → line-BXK9PKLn.js} +1 -1
  98. package/dist/assets/{linear-Dld3_ERu.js → linear-CULvmq2Z.js} +1 -1
  99. package/dist/assets/{liquid-DBIl-f0z.js → liquid-BParI24X.js} +1 -1
  100. package/dist/assets/{lspLanguageFeatures-DK6tqicV.js → lspLanguageFeatures-BzredkoV.js} +1 -1
  101. package/dist/assets/main-BlVUXfxa.css +1 -0
  102. package/dist/assets/{map-LZWWoeWa.js → map-C9Qw9eWh.js} +1 -1
  103. package/dist/assets/{mdx-DS-bVtZN.js → mdx-vGzUJN98.js} +1 -1
  104. package/dist/assets/{mermaid.core-gSpX30pV.js → mermaid.core-CzazaIKr.js} +3 -3
  105. package/dist/assets/{mindmap-definition-LN4V7U3C-BKBaI4LW.js → mindmap-definition-LN4V7U3C-Uoff7hZ3.js} +1 -1
  106. package/dist/assets/{monaco.contribution-BXz-lfFB.js → monaco.contribution-BmaeBQEc.js} +2 -2
  107. package/dist/assets/{ordinal-BLrOss5K.js → ordinal-r6pIwRdZ.js} +1 -1
  108. package/dist/assets/{pegDiagram-2B236MQR-sBvDY3VX.js → pegDiagram-2B236MQR-CCBiHQjk.js} +1 -1
  109. package/dist/assets/{pieDiagram-ENE6RG2P-DWlWcu08.js → pieDiagram-ENE6RG2P-D61s7l75.js} +1 -1
  110. package/dist/assets/{python-C93q3xXz.js → python-CUwdLgsI.js} +1 -1
  111. package/dist/assets/{quadrantDiagram-ABIIQ3AL-DZutUd3J.js → quadrantDiagram-ABIIQ3AL-D_CWk2DQ.js} +1 -1
  112. package/dist/assets/{railroadDiagram-RFXS5EU6-DQb3lXGM.js → railroadDiagram-RFXS5EU6-CdlCHtxN.js} +1 -1
  113. package/dist/assets/{razor-CBifNGXO.js → razor-BScebUxU.js} +1 -1
  114. package/dist/assets/{requirementDiagram-TGXJPOKE-DqFGXu2e.js → requirementDiagram-TGXJPOKE-BLpHtkoC.js} +1 -1
  115. package/dist/assets/{sankeyDiagram-HTMAVEWB-d7ECahnO.js → sankeyDiagram-HTMAVEWB-CkhYZN2j.js} +1 -1
  116. package/dist/assets/{sequenceDiagram-DBY2YBRQ-DdsbKqct.js → sequenceDiagram-DBY2YBRQ-8bploKJl.js} +1 -1
  117. package/dist/assets/{sizeCapture-X5ZJPWSS-daTB6OcF.js → sizeCapture-X5ZJPWSS-DtSdkS0d.js} +1 -1
  118. package/dist/assets/{src-WBW1QxJt.js → src-6yeq6WBA.js} +1 -1
  119. package/dist/assets/{stateDiagram-2N3HPSRC-P6iSrgwR.js → stateDiagram-2N3HPSRC-DfmVGpfA.js} +1 -1
  120. package/dist/assets/stateDiagram-v2-6OUMAXLB-B2c9CQ-J.js +1 -0
  121. package/dist/assets/{swimlanes-5IMT3BWC-BGnZJx1M.js → swimlanes-5IMT3BWC-DRLk2zRF.js} +2 -2
  122. package/dist/assets/swimlanesDiagram-G3AALYLV-B7_APh_h.js +8 -0
  123. package/dist/assets/{timeline-definition-FHXFAJF6-rA-r3aUR.js → timeline-definition-FHXFAJF6-Cngfy588.js} +1 -1
  124. package/dist/assets/{tsMode-B0oUTcXQ.js → tsMode-DzUAibXK.js} +1 -1
  125. package/dist/assets/{typescript-KJKfYO7K.js → typescript-D9EOeM7N.js} +1 -1
  126. package/dist/assets/{vennDiagram-L72KCM5P-DiVKUjA9.js → vennDiagram-L72KCM5P-DeJn63Lq.js} +1 -1
  127. package/dist/assets/{wardleyDiagram-EHGQE667-Cfxh7UOn.js → wardleyDiagram-EHGQE667-BH1nzy77.js} +1 -1
  128. package/dist/assets/{workers-BSQRIkqa.js → workers-DAiomYZM.js} +1 -1
  129. package/dist/assets/workspace-editor-model-CSGCl21x.js +1 -0
  130. package/dist/assets/workspace-editor-monaco-CFEfFNcA.js +1 -0
  131. package/dist/assets/{workspace-editor-monaco-BIpqcWf1.js → workspace-editor-monaco-tXA-udGx.js} +3 -3
  132. package/dist/assets/workspace-view-state-BS_V8JVs.js +7 -0
  133. package/dist/assets/{xml-C8FAcN6j.js → xml-wWl1dhkQ.js} +1 -1
  134. package/dist/assets/{xychartDiagram-FW5EYKEG--hmryQeL.js → xychartDiagram-FW5EYKEG-SkO2prCU.js} +1 -1
  135. package/dist/assets/{yaml-BQ4NrRhG.js → yaml-Dc2WDaOZ.js} +1 -1
  136. package/dist/crt-markdown-renderer.js +46 -46
  137. package/dist/index.html +1 -1
  138. package/extensions/browser/backend/agent-capability.js +55 -0
  139. package/extensions/browser/backend/browser-mcp-server.js +269 -0
  140. package/extensions/browser/backend/browser-resource-manager.js +524 -0
  141. package/extensions/browser/backend/browser-resource-store.js +149 -0
  142. package/extensions/browser/backend/browser-router.js +128 -0
  143. package/extensions/browser/backend/cdp-browser-runtime.js +648 -0
  144. package/extensions/browser/backend/cdp-client.js +167 -0
  145. package/extensions/browser/backend/executable-discovery.js +91 -0
  146. package/extensions/browser/backend/farming-browser-client.js +83 -0
  147. package/extensions/browser/backend/index.js +7 -0
  148. package/extensions/browser/bin/farming-browser +117 -0
  149. package/extensions/browser/frontend/BrowserSidebarPortals.tsx +362 -0
  150. package/extensions/browser/frontend/BrowserViewer.tsx +329 -0
  151. package/extensions/browser/frontend/browser-resource-state.ts +60 -0
  152. package/extensions/browser/frontend/browser.css +516 -0
  153. package/extensions/browser/frontend/types.ts +25 -0
  154. package/extensions/browser/frontend/useBrowserResources.ts +151 -0
  155. package/frontend/session-bridge.js +7 -6
  156. package/frontend/skins/crt/app.js +64 -4
  157. package/package.json +18 -13
  158. package/shared/browser-protocol.js +1 -1
  159. package/dist/assets/App-BbNBDA__.js +0 -210
  160. package/dist/assets/App-BrP-ENHg.css +0 -1
  161. package/dist/assets/FileEditorPane-5_HUejjd.js +0 -2
  162. package/dist/assets/IconGlyphs-C2WFcoJS.js +0 -1
  163. package/dist/assets/ProjectFilesSection-C1RAJWOE.js +0 -12
  164. package/dist/assets/api-D8nyOEbz.js +0 -1
  165. package/dist/assets/channel-BVWNatUB.js +0 -1
  166. package/dist/assets/chunk-2Q5K7J3B-d5WWh8jo.js +0 -1
  167. package/dist/assets/chunk-VAUOI2AC-UHNr_yhX.js +0 -1
  168. package/dist/assets/chunk-XXDRQBXY-BBXwjhUx.js +0 -1
  169. package/dist/assets/classDiagram-OUVF2IWQ-Db0ib5iE.js +0 -1
  170. package/dist/assets/classDiagram-v2-EOCWNBFH-Bkf69XF9.js +0 -1
  171. package/dist/assets/code-dark-BKtvf0Xc.css +0 -1
  172. package/dist/assets/file-icons-CHWt5nSy.js +0 -1
  173. package/dist/assets/flowDiagram-23GEKE2U-DYFo2xmB.js +0 -1
  174. package/dist/assets/main-XMXgyJJt.css +0 -1
  175. package/dist/assets/stateDiagram-v2-6OUMAXLB-DIYSf_qh.js +0 -1
  176. package/dist/assets/swimlanesDiagram-G3AALYLV-BIkrlKrZ.js +0 -8
  177. package/dist/assets/workspace-editor-model-D0Im34S5.js +0 -1
  178. package/dist/assets/workspace-view-state-BqB4HM7r.js +0 -7
  179. /package/dist/assets/{abap-Cc5D5h5i.js → abap-CtX5nWyX.js} +0 -0
  180. /package/dist/assets/{apex-BKopwLmx.js → apex-DQJRAHwc.js} +0 -0
  181. /package/dist/assets/{array-HeX70jSN.js → array-BTwzYU0x.js} +0 -0
  182. /package/dist/assets/{azcli-DI-C34WA.js → azcli-9SMrOQ4q.js} +0 -0
  183. /package/dist/assets/{bat-Cbp6u42z.js → bat-CBGLUsw1.js} +0 -0
  184. /package/dist/assets/{bicep-4QA1jTCM.js → bicep-pDx8da1v.js} +0 -0
  185. /package/dist/assets/{cameligo-Dda_adPs.js → cameligo-hZV3vQ6_.js} +0 -0
  186. /package/dist/assets/{chunk-Y2CYZVJY-Di0sYzi1.js → chunk-Y2CYZVJY-BYi0W5ea.js} +0 -0
  187. /package/dist/assets/{clojure-CvY8A83L.js → clojure-BhCwU3gq.js} +0 -0
  188. /package/dist/assets/{coffee-4LX2Sv8A.js → coffee-BVB1PsgH.js} +0 -0
  189. /package/dist/assets/{core-B9MwRjDE.js → core-vPkV8P_m.js} +0 -0
  190. /package/dist/assets/{cpp-D4AzSV28.js → cpp-eTjuiNPq.js} +0 -0
  191. /package/dist/assets/{csharp-C4nWN4Yd.js → csharp-1kP-kKZT.js} +0 -0
  192. /package/dist/assets/{csp-CiEaaS5Z.js → csp-C_iQqIes.js} +0 -0
  193. /package/dist/assets/{css-DXxBRsbk.js → css-CxOs7IfP.js} +0 -0
  194. /package/dist/assets/{cypher-DOMzqyFA.js → cypher-Cd-a9Y82.js} +0 -0
  195. /package/dist/assets/{cytoscape.esm-Cl8iC3D7.js → cytoscape.esm-OLojuicg.js} +0 -0
  196. /package/dist/assets/{dart-BWS7MXt_.js → dart-whhXpexn.js} +0 -0
  197. /package/dist/assets/{defaultLocale-GJwWH1Jr.js → defaultLocale-CPimVhfE.js} +0 -0
  198. /package/dist/assets/{dist-ClAL-Tv5.js → dist-CLPYXg1u.js} +0 -0
  199. /package/dist/assets/{dockerfile-Baf4U3xT.js → dockerfile-DibBi8b6.js} +0 -0
  200. /package/dist/assets/{ecl-CT7udlkQ.js → ecl-DlF1KdoW.js} +0 -0
  201. /package/dist/assets/{editor.api2-B9h6iFPK.js → editor.api2-D74ufkbr.js} +0 -0
  202. /package/dist/assets/{elixir-CIbAZw5l.js → elixir-CHQ8uFT3.js} +0 -0
  203. /package/dist/assets/{flow9-Dqiw45WV.js → flow9-8nUnVKk1.js} +0 -0
  204. /package/dist/assets/{fsharp-E8E2L9jU.js → fsharp-DNZNZyEE.js} +0 -0
  205. /package/dist/assets/{go-CouVSN4D.js → go-_kPJjNc_.js} +0 -0
  206. /package/dist/assets/{graphlib-CbSvZcZU.js → graphlib-CBGF9gA9.js} +0 -0
  207. /package/dist/assets/{graphql-a6h6h5-t.js → graphql-4HCNVt5g.js} +0 -0
  208. /package/dist/assets/{hcl-vso3e6N-.js → hcl-C87ymY0o.js} +0 -0
  209. /package/dist/assets/{ini-SwZZkotR.js → ini-BYrrGNTc.js} +0 -0
  210. /package/dist/assets/{init-BPLPMQ3Y.js → init-8_PCa3LO.js} +0 -0
  211. /package/dist/assets/{java-CtRLC4_3.js → java-B211rJbk.js} +0 -0
  212. /package/dist/assets/{julia-CuJWFKQH.js → julia-DVPsRtBm.js} +0 -0
  213. /package/dist/assets/{katex-C8DPyI6s.js → katex-C2iYad0m.js} +0 -0
  214. /package/dist/assets/{kotlin-B_kBhsre.js → kotlin-BYyNerjp.js} +0 -0
  215. /package/dist/assets/{less-CtrHIfz3.js → less-EC9UblGE.js} +0 -0
  216. /package/dist/assets/{lexon-yVt1pJLu.js → lexon-B1yuUdqW.js} +0 -0
  217. /package/dist/assets/{lua-prOwgJ4U.js → lua-Bo6GFzxT.js} +0 -0
  218. /package/dist/assets/{m3-DhrdTQ84.js → m3-C-Y9cBVI.js} +0 -0
  219. /package/dist/assets/{markdown-DoI5HwSM.js → markdown-BHu-wLbe.js} +0 -0
  220. /package/dist/assets/{mermaid-parser.core-BQtepoLd.js → mermaid-parser.core-IxcGtNYG.js} +0 -0
  221. /package/dist/assets/{mips-Dye5jsBU.js → mips-Dkds26rX.js} +0 -0
  222. /package/dist/assets/{msdax-TkNOyIL8.js → msdax-PU4g-8_g.js} +0 -0
  223. /package/dist/assets/{mysql-CEc-RKZF.js → mysql-fPpuGpS7.js} +0 -0
  224. /package/dist/assets/{objective-c-CqqCsQz0.js → objective-c-Wy1e5JUf.js} +0 -0
  225. /package/dist/assets/{pascal-DO_pj8yg.js → pascal-BIXwvrqU.js} +0 -0
  226. /package/dist/assets/{pascaligo-1cbdZdF3.js → pascaligo-DwR0AtL_.js} +0 -0
  227. /package/dist/assets/{path-YdFzr2W6.js → path-BxQuywGl.js} +0 -0
  228. /package/dist/assets/{perl-B_N3PYfC.js → perl-CGHAl8my.js} +0 -0
  229. /package/dist/assets/{pgsql-9iYk1FQ7.js → pgsql-B91M73E2.js} +0 -0
  230. /package/dist/assets/{php-rO2sgoUM.js → php-C70ttrCx.js} +0 -0
  231. /package/dist/assets/{pla-Cbgv60kq.js → pla-BNrXaRh0.js} +0 -0
  232. /package/dist/assets/{postiats-y6xrhy_M.js → postiats-Dv2IAZR9.js} +0 -0
  233. /package/dist/assets/{powerquery-BaD8gWNE.js → powerquery-CkY5Wq7J.js} +0 -0
  234. /package/dist/assets/{powershell-BMhG4JVe.js → powershell-uGIYLU3C.js} +0 -0
  235. /package/dist/assets/{protobuf-CdOP5kN3.js → protobuf-CavfmJu-.js} +0 -0
  236. /package/dist/assets/{pug-Ck60hNF9.js → pug-Drqnyitx.js} +0 -0
  237. /package/dist/assets/{qrcode-DV-_rjU8.js → qrcode-7uGsTEmi.js} +0 -0
  238. /package/dist/assets/{qsharp-BcaKFfP-.js → qsharp-C7yF-Dti.js} +0 -0
  239. /package/dist/assets/{r-rFNes0iK.js → r-HXLGP0_-.js} +0 -0
  240. /package/dist/assets/{redis-DkpQ3K6G.js → redis-C4y6mf2p.js} +0 -0
  241. /package/dist/assets/{redshift-Di9N5TI3.js → redshift-DdQrFPrv.js} +0 -0
  242. /package/dist/assets/{restructuredtext-By5ZzLt6.js → restructuredtext-CBrf2PNj.js} +0 -0
  243. /package/dist/assets/{rough.esm-c4PR5shF.js → rough.esm-6CnTHTkH.js} +0 -0
  244. /package/dist/assets/{ruby-fF5zGiLp.js → ruby-CVtMoX2B.js} +0 -0
  245. /package/dist/assets/{rust-C5b3AYY6.js → rust-Ckq4sbMP.js} +0 -0
  246. /package/dist/assets/{sb-CD07UNRs.js → sb-er66OpE3.js} +0 -0
  247. /package/dist/assets/{scala-jtn1ip9G.js → scala-BdWZz-hH.js} +0 -0
  248. /package/dist/assets/{scheme-C4vqMkn_.js → scheme-kTV_s2kP.js} +0 -0
  249. /package/dist/assets/{scss-I4Glxjbz.js → scss-Bymy2VJQ.js} +0 -0
  250. /package/dist/assets/{shell-DubUcuns.js → shell-bwEP1LQ1.js} +0 -0
  251. /package/dist/assets/{solidity-CNy2KSl2.js → solidity-DCddeBgL.js} +0 -0
  252. /package/dist/assets/{sophia-D9_URt84.js → sophia-BMN3AQig.js} +0 -0
  253. /package/dist/assets/{sparql-DviXpm4C.js → sparql-CSXOLjzi.js} +0 -0
  254. /package/dist/assets/{sql-vDRbAZgK.js → sql-COg8ewmK.js} +0 -0
  255. /package/dist/assets/{st-CnpnRqA7.js → st-CIaZtBS_.js} +0 -0
  256. /package/dist/assets/{swift-D_g8Ganz.js → swift-DXiOhUHu.js} +0 -0
  257. /package/dist/assets/{systemverilog-OuZa5h1M.js → systemverilog-BTDE6Dr2.js} +0 -0
  258. /package/dist/assets/{tcl-DBm9ucsV.js → tcl-B0zy9NvV.js} +0 -0
  259. /package/dist/assets/{twig-BRzEqX5Y.js → twig-D594l4Z1.js} +0 -0
  260. /package/dist/assets/{typespec-D4ZgGeX8.js → typespec-XKVjaPqo.js} +0 -0
  261. /package/dist/assets/{useWorkspaceMenuKeyboard-Brws6Ar9.js → useWorkspaceMenuKeyboard-Bpy_s69Z.js} +0 -0
  262. /package/dist/assets/{vb-DcP4s6WS.js → vb-B2wYoKRV.js} +0 -0
  263. /package/dist/assets/{wgsl-CnRJ_QUf.js → wgsl-D0Yf2LbK.js} +0 -0
  264. /package/dist/assets/{workspace-working-copy-D8-s_Sgh.js → workspace-working-copy-C3FSR3N6.js} +0 -0
@@ -0,0 +1,151 @@
1
+ import { useCallback, useEffect, useMemo, useState } from 'react'
2
+ import { appPath } from '@/lib/base-path'
3
+ import { projectFilesWorkspaceId } from '@/lib/project-workspaces'
4
+ import {
5
+ applyBrowserResource,
6
+ applyBrowserResourceDeletion,
7
+ applyBrowserResourceSnapshot,
8
+ type BrowserResourceCollection,
9
+ type BrowserResourceDeletion,
10
+ } from './browser-resource-state'
11
+ import type { BrowserCapability, BrowserResource } from './types'
12
+
13
+ async function browserRequest<T>(pathname: string, init?: RequestInit): Promise<T> {
14
+ const response = await fetch(appPath(pathname), {
15
+ ...init,
16
+ headers: {
17
+ Accept: 'application/json',
18
+ ...(init?.body ? { 'Content-Type': 'application/json' } : {}),
19
+ ...init?.headers,
20
+ },
21
+ })
22
+ const data = await response.json().catch(() => ({})) as { error?: string }
23
+ if (!response.ok) throw new Error(data.error || `Browser request failed (${response.status})`)
24
+ return data as T
25
+ }
26
+
27
+ export function useBrowserResources() {
28
+ const [collection, setCollection] = useState<BrowserResourceCollection>({
29
+ collectionRevision: 0,
30
+ resources: [],
31
+ })
32
+ const [capability, setCapability] = useState<BrowserCapability | null>(null)
33
+ const [loading, setLoading] = useState(true)
34
+ const [refreshVersion, setRefreshVersion] = useState(0)
35
+
36
+ const mergeResource = useCallback((resource: BrowserResource) => {
37
+ setCollection(current => applyBrowserResource(current, resource))
38
+ }, [])
39
+
40
+ useEffect(() => {
41
+ let active = true
42
+ setLoading(true)
43
+ void browserRequest<BrowserCapability>('/api/browsers/capability').then(async nextCapability => {
44
+ if (!active) return
45
+ setCapability(nextCapability)
46
+ if (!nextCapability.available) {
47
+ setCollection({ collectionRevision: 0, resources: [] })
48
+ setLoading(false)
49
+ return
50
+ }
51
+ const list = await browserRequest<BrowserResourceCollection>('/api/browsers')
52
+ if (!active) return
53
+ setCollection(current => applyBrowserResourceSnapshot(current, list))
54
+ setLoading(false)
55
+ }).catch(() => {
56
+ if (active) setLoading(false)
57
+ })
58
+ return () => {
59
+ active = false
60
+ }
61
+ }, [refreshVersion])
62
+
63
+ useEffect(() => {
64
+ if (capability?.available !== true) return undefined
65
+ let active = true
66
+ const events = new EventSource(appPath('/api/browsers/events'))
67
+ events.addEventListener('resources', event => {
68
+ if (!active) return
69
+ const payload = JSON.parse((event as MessageEvent<string>).data) as BrowserResourceCollection
70
+ setCollection(current => applyBrowserResourceSnapshot(current, payload))
71
+ })
72
+ events.addEventListener('resource', event => {
73
+ if (!active) return
74
+ mergeResource(JSON.parse((event as MessageEvent<string>).data) as BrowserResource)
75
+ })
76
+ events.addEventListener('deleted', event => {
77
+ if (!active) return
78
+ const payload = JSON.parse((event as MessageEvent<string>).data) as BrowserResourceDeletion
79
+ setCollection(current => applyBrowserResourceDeletion(current, payload))
80
+ })
81
+ return () => {
82
+ active = false
83
+ events.close()
84
+ }
85
+ }, [capability?.available, mergeResource])
86
+
87
+ const create = useCallback(async (workspace: string, options: { name?: string; url?: string } = {}) => {
88
+ const resource = await browserRequest<BrowserResource>('/api/browsers', {
89
+ method: 'POST',
90
+ body: JSON.stringify({
91
+ rootId: projectFilesWorkspaceId(workspace),
92
+ name: options.name,
93
+ url: options.url,
94
+ }),
95
+ })
96
+ mergeResource(resource)
97
+ return resource
98
+ }, [mergeResource])
99
+
100
+ const rename = useCallback(async (id: string, name: string) => {
101
+ const resource = await browserRequest<BrowserResource>(`/api/browsers/${encodeURIComponent(id)}`, {
102
+ method: 'PATCH',
103
+ body: JSON.stringify({ name }),
104
+ })
105
+ mergeResource(resource)
106
+ return resource
107
+ }, [mergeResource])
108
+
109
+ const transition = useCallback(async (id: string, operation: 'start' | 'stop') => {
110
+ const resource = await browserRequest<BrowserResource>(
111
+ `/api/browsers/${encodeURIComponent(id)}/${operation}`,
112
+ { method: 'POST' },
113
+ )
114
+ mergeResource(resource)
115
+ return resource
116
+ }, [mergeResource])
117
+
118
+ const remove = useCallback(async (id: string) => {
119
+ const deletion = await browserRequest<BrowserResourceDeletion>(
120
+ `/api/browsers/${encodeURIComponent(id)}`,
121
+ { method: 'DELETE' },
122
+ )
123
+ setCollection(current => applyBrowserResourceDeletion(current, deletion))
124
+ }, [])
125
+
126
+ const byWorkspace = useMemo(() => {
127
+ const result = new Map<string, BrowserResource[]>()
128
+ for (const resource of collection.resources) {
129
+ const current = result.get(resource.workspace) ?? []
130
+ current.push(resource)
131
+ result.set(resource.workspace, current)
132
+ }
133
+ return result
134
+ }, [collection.resources])
135
+
136
+ return {
137
+ resources: collection.resources,
138
+ byWorkspace,
139
+ capability,
140
+ loading,
141
+ create,
142
+ rename,
143
+ start: (id: string) => transition(id, 'start'),
144
+ stop: (id: string) => transition(id, 'stop'),
145
+ remove,
146
+ mergeResource,
147
+ refreshCapability: () => setRefreshVersion(version => version + 1),
148
+ }
149
+ }
150
+
151
+ export type BrowserResourcesController = ReturnType<typeof useBrowserResources>
@@ -34,17 +34,18 @@
34
34
  },
35
35
 
36
36
  sendComposerMessage(agentId, message, attachments = [], options = {}) {
37
- const requestId = options.onResult
38
- ? `composer-${Date.now().toString(36)}-${++composerRequestSequence}`
39
- : '';
37
+ const requestedId = typeof options.requestId === 'string' ? options.requestId.trim() : '';
38
+ const requestId = requestedId
39
+ || globalThis.crypto?.randomUUID?.()
40
+ || `composer-${Date.now().toString(36)}-${++composerRequestSequence}`;
40
41
  const sent = send({
41
42
  type: 'composer-input',
42
43
  agentId,
43
44
  message,
44
- ...(requestId ? { requestId } : {}),
45
+ requestId,
45
46
  ...(attachments.length > 0 ? { attachments } : {}),
46
47
  });
47
- if (sent && requestId) composerResults.set(requestId, options.onResult);
48
+ if (sent && options.onResult) composerResults.set(requestId, options.onResult);
48
49
  return sent;
49
50
  },
50
51
 
@@ -58,7 +59,7 @@
58
59
  },
59
60
 
60
61
  rejectPendingComposerMessages(message = 'Connection unavailable') {
61
- composerResults.forEach(callback => callback({ accepted: false, message }));
62
+ composerResults.forEach(callback => callback({ accepted: false, message, uncertain: true }));
62
63
  composerResults.clear();
63
64
  },
64
65
 
@@ -101,6 +101,7 @@ let structuredComposerConfigId = '';
101
101
  let structuredComposerAttachments = [];
102
102
  const structuredComposerHistory = new Map();
103
103
  const structuredComposerPendingFollowUps = new Map();
104
+ const structuredComposerRequestIds = new Map();
104
105
  let structuredComposerHistoryIndex = -1;
105
106
  let structuredComposerCompositionEndAt = 0;
106
107
  let structuredComposerRestoreFocusAfterInterrupt = false;
@@ -6962,6 +6963,27 @@ function structuredComposerPromptAttachments() {
6962
6963
  ));
6963
6964
  }
6964
6965
 
6966
+ function structuredComposerRequestKey(agentId, message, attachments = []) {
6967
+ return JSON.stringify({
6968
+ agentId,
6969
+ message,
6970
+ attachments: attachments.map((attachment) => ({
6971
+ kind: attachment.kind,
6972
+ path: attachment.path,
6973
+ type: attachment.type,
6974
+ })),
6975
+ });
6976
+ }
6977
+
6978
+ function structuredComposerRequestId(requestKey) {
6979
+ const existing = structuredComposerRequestIds.get(requestKey);
6980
+ if (existing) return existing;
6981
+ const requestId = globalThis.crypto?.randomUUID?.()
6982
+ || `composer-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
6983
+ structuredComposerRequestIds.set(requestKey, requestId);
6984
+ return requestId;
6985
+ }
6986
+
6965
6987
  function structuredComposerHistoryFor(agentId) {
6966
6988
  if (!agentId) return [];
6967
6989
  return structuredComposerHistory.get(agentId) || [];
@@ -7580,10 +7602,17 @@ function setupStructuredSessionComposer() {
7580
7602
  const draft = input.value;
7581
7603
  const message = structuredComposerMessage(draft);
7582
7604
  const promptAttachments = structuredComposerPromptAttachments();
7605
+ const submittedAttachmentIds = structuredComposerAttachments.map((attachment) => attachment.id);
7583
7606
  if (!message && promptAttachments.length === 0) return;
7584
7607
  const statusNode = document.getElementById('crt-structured-composer-status');
7585
7608
  const completeSubmission = () => {
7586
7609
  addStructuredComposerHistory(agentId, draft);
7610
+ const ownsComposer = focusedAgentId === agentId
7611
+ && structuredSessionGeneration === generation
7612
+ && input.value === draft
7613
+ && structuredComposerAttachments.length === submittedAttachmentIds.length
7614
+ && structuredComposerAttachments.every((attachment, index) => attachment.id === submittedAttachmentIds[index]);
7615
+ if (!ownsComposer) return;
7587
7616
  input.value = '';
7588
7617
  structuredComposerAttachments = [];
7589
7618
  renderStructuredComposerAttachments();
@@ -7595,17 +7624,48 @@ function setupStructuredSessionComposer() {
7595
7624
  updateStructuredComposerState(agent);
7596
7625
  setTimeout(() => void refreshStructuredSession(agentId, true, generation), 160);
7597
7626
  };
7598
- const sent = action === 'send' && structuredRuntimeStatus(agent) !== 'idle'
7599
- ? (queueStructuredComposerFollowUp(agentId, message, promptAttachments), true)
7600
- : getSessionClient()?.sendComposerMessage(agentId, message, promptAttachments);
7627
+ if (action === 'send' && structuredRuntimeStatus(agent) !== 'idle') {
7628
+ queueStructuredComposerFollowUp(agentId, message, promptAttachments);
7629
+ completeSubmission();
7630
+ return;
7631
+ }
7632
+ const requestKey = structuredComposerRequestKey(agentId, message, promptAttachments);
7633
+ const requestId = structuredComposerRequestId(requestKey);
7634
+ const sent = getSessionClient()?.sendComposerMessage(agentId, message, promptAttachments, {
7635
+ requestId,
7636
+ onResult(result) {
7637
+ if (result?.accepted === true) {
7638
+ if (structuredComposerRequestIds.get(requestKey) === requestId) {
7639
+ structuredComposerRequestIds.delete(requestKey);
7640
+ }
7641
+ completeSubmission();
7642
+ return;
7643
+ }
7644
+ if (result?.uncertain !== true && structuredComposerRequestIds.get(requestKey) === requestId) {
7645
+ structuredComposerRequestIds.delete(requestKey);
7646
+ }
7647
+ if (focusedAgentId !== agentId || structuredSessionGeneration !== generation) return;
7648
+ if (statusNode) {
7649
+ statusNode.textContent = result?.message || 'Submission was not accepted';
7650
+ statusNode.classList.add('error');
7651
+ }
7652
+ input.focus();
7653
+ },
7654
+ });
7601
7655
  if (!sent) {
7656
+ if (structuredComposerRequestIds.get(requestKey) === requestId) {
7657
+ structuredComposerRequestIds.delete(requestKey);
7658
+ }
7602
7659
  if (statusNode) {
7603
7660
  statusNode.textContent = 'Connection unavailable';
7604
7661
  statusNode.classList.add('error');
7605
7662
  }
7606
7663
  return;
7607
7664
  }
7608
- completeSubmission();
7665
+ if (statusNode) {
7666
+ statusNode.textContent = 'SENDING...';
7667
+ statusNode.classList.remove('error');
7668
+ }
7609
7669
  });
7610
7670
  }
7611
7671
 
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "farming-code",
3
- "version": "2.2.23",
3
+ "version": "2.2.28",
4
4
  "description": "Farming Code is a self-hosted browser workspace for running and supervising AI coding agents",
5
5
  "main": "backend/server.js",
6
6
  "bin": {
7
- "farming": "bin/farming"
7
+ "farming": "bin/farming",
8
+ "farming-browser": "extensions/browser/bin/farming-browser"
8
9
  },
9
10
  "files": [
10
11
  "backend/*.js",
12
+ "backend/farming-agent-bootstrap.zh_cn.md",
11
13
  "backend/usage-history-scanner.ts",
12
14
  "backend/acp/",
13
15
  "backend/data/",
@@ -20,6 +22,7 @@
20
22
  "frontend/skins/",
21
23
  "frontend/themes/",
22
24
  "frontend/vendor/ghostty-web/",
25
+ "extensions/browser/",
23
26
  "shared/",
24
27
  "LICENSE",
25
28
  "README.md",
@@ -79,18 +82,17 @@
79
82
  "check": "npm run typecheck && npm run lint && npm test"
80
83
  },
81
84
  "keywords": [
82
- "ai-agent",
83
- "ai-agent-workspace",
85
+ "coding-agent-workspace",
86
+ "agent-supervision",
87
+ "agent-orchestration",
88
+ "multi-agent",
84
89
  "browser-terminal",
85
- "claude-code",
86
- "coding-agent",
87
- "codex",
88
- "codex-cli",
89
- "developer-tools",
90
- "farming-code",
91
- "remote-workspace",
90
+ "browser-workspace",
91
+ "remote-development",
92
92
  "self-hosted",
93
- "terminal"
93
+ "codex",
94
+ "claude-code",
95
+ "opencode"
94
96
  ],
95
97
  "author": "",
96
98
  "license": "MIT",
@@ -112,6 +114,7 @@
112
114
  "@agentclientprotocol/claude-agent-acp": "0.59.0",
113
115
  "@agentclientprotocol/codex-acp": "1.1.4",
114
116
  "@agentclientprotocol/sdk": "1.2.1",
117
+ "@modelcontextprotocol/sdk": "^1.29.0",
115
118
  "@xterm/addon-clipboard": "^0.2.0",
116
119
  "@xterm/addon-fit": "^0.11.0",
117
120
  "@xterm/addon-search": "^0.16.0",
@@ -125,6 +128,7 @@
125
128
  "express": "^4.22.2",
126
129
  "ghostty-web": "^0.4.0",
127
130
  "highlight.js": "^11.11.1",
131
+ "html2canvas": "^1.4.1",
128
132
  "katex": "^0.17.0",
129
133
  "material-icon-theme": "^5.36.1",
130
134
  "mermaid": "^11.16.0",
@@ -141,7 +145,8 @@
141
145
  "remark-math": "^6.0.0",
142
146
  "ripgrep": "^0.3.1",
143
147
  "ws": "^8.21.0",
144
- "yaml": "^2.9.0"
148
+ "yaml": "^2.9.0",
149
+ "zod": "^3.25.76"
145
150
  },
146
151
  "devDependencies": {
147
152
  "@eslint/js": "^10.0.1",
@@ -101,7 +101,7 @@ function validateServerMessage(value) {
101
101
  case 'error': valid = stringField(value, 'message'); break;
102
102
  case 'command-ack': valid = stringField(value, 'requestId') && stringField(value, 'command'); break;
103
103
  case 'state': valid = objectMessage(value.state) && Array.isArray(value.state.agents); break;
104
- case 'composer-input-result': valid = stringField(value, 'requestId') && stringField(value, 'agentId') && typeof value.accepted === 'boolean' && stringField(value, 'message', true); break;
104
+ case 'composer-input-result': valid = stringField(value, 'requestId') && stringField(value, 'agentId') && typeof value.accepted === 'boolean' && stringField(value, 'message', true) && (!Object.prototype.hasOwnProperty.call(value, 'uncertain') || typeof value.uncertain === 'boolean'); break;
105
105
  case 'agent-started': valid = stringField(value, 'agentId'); break;
106
106
  case 'session-output': valid = objectMessage(value.stream) && stringField(value.stream, 'agentId'); break;
107
107
  case 'session-preview': valid = objectMessage(value.preview) && stringField(value.preview, 'agentId'); break;