farming-code 2.2.28 → 2.2.30
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.
- package/README.md +27 -90
- package/README.zh_cn.md +17 -90
- package/THIRD_PARTY_NOTICES.md +25 -6
- package/backend/acp/packaged-claude-acp.js +13 -0
- package/backend/acp/packaged-codex-acp.js +2 -2
- package/backend/acp-runtime.js +38 -17
- package/backend/acp-session-state.js +78 -88
- package/backend/acp-transcript.js +174 -9
- package/backend/agent-manager.js +27 -2
- package/backend/agent-session-history.js +45 -12
- package/backend/codex-session-history.js +1 -1
- package/backend/codex-transcript.js +0 -202
- package/backend/config-manager.js +44 -16
- package/backend/data/LICENSE.agent-browser +201 -0
- package/backend/data/runtime-dependency-manifest.json +199 -0
- package/backend/data/runtime-dependency-sources.json +5 -0
- package/backend/executable-discovery.js +7 -0
- package/backend/farming-agent-bootstrap.zh_cn.md +4 -2
- package/backend/farming-app-cli.js +161 -65
- package/backend/farming-cli.js +7 -59
- package/backend/index-html.js +31 -0
- package/backend/main-agent-skills.js +7 -28
- package/backend/npm-update-helper.js +43 -6
- package/backend/provider-adapters.js +10 -0
- package/backend/runtime-dependency-manager.js +759 -0
- package/backend/runtime-executable-invocation.js +20 -0
- package/backend/server-process-identity.js +47 -0
- package/backend/server.js +145 -204
- package/backend/slash-command-discovery.js +138 -1
- package/backend/storage-layout.js +30 -0
- package/backend/update-service.js +60 -914
- package/config/farming.deploy.env.example +1 -1
- package/config/farming.install.env.example +5 -1
- package/dist/acp/LICENSE.claude-agent-acp +191 -0
- package/dist/acp/LICENSE.claude-agent-sdk +1 -0
- package/dist/acp/claude-agent-acp-0.59.0.mjs +41606 -0
- package/dist/acp/{codex-acp-1.1.4.js → codex-acp-1.1.4.mjs} +387 -7
- package/dist/assets/{App-CM7Cy-l4.css → App-BKNUILuL.css} +1 -1
- package/dist/assets/App-Z1N7T0eM.js +695 -0
- package/dist/assets/{FileEditorMarkdownPreview-DYOMm-b1.js → FileEditorMarkdownPreview-Cs9cLv8a.js} +1 -1
- package/dist/assets/FileEditorPane-CNtuGjQ3.js +2 -0
- package/dist/assets/IconGlyphs-BClgag6E.js +1 -0
- package/dist/assets/ProjectFilesSection-K3GHuQ4U.js +12 -0
- package/dist/assets/ReviewPage-BRuxFaH5.js +3 -0
- package/dist/assets/code-dark-kLsQLvpf.css +1 -0
- package/dist/assets/{index-BzQO3pUr.js → index-D-zetSol.js} +2 -2
- package/dist/assets/main-DUTz-Rd2.css +1 -0
- package/dist/assets/{workspace-editor-monaco-tXA-udGx.js → workspace-editor-monaco-CJNwbpCy.js} +1 -1
- package/dist/assets/workspace-editor-monaco-CO9w8YV0.js +1 -0
- package/dist/assets/workspace-view-state-BjKPYp0E.js +7 -0
- package/dist/index.html +33 -3
- package/extensions/browser/backend/agent-browser-runtime.js +1041 -0
- package/extensions/browser/backend/browser-mcp-server.js +352 -0
- package/extensions/browser/backend/browser-resource-manager.js +921 -114
- package/extensions/browser/backend/browser-resource-store.js +47 -6
- package/extensions/browser/backend/browser-router.js +15 -2
- package/extensions/browser/backend/executable-discovery.js +164 -17
- package/extensions/browser/backend/managed-chromium-installer.js +593 -0
- package/extensions/browser/bin/farming-browser +384 -30
- package/extensions/browser/frontend/BrowserSidebarPortals.tsx +17 -19
- package/extensions/browser/frontend/BrowserViewer.tsx +217 -46
- package/extensions/browser/frontend/browser.css +68 -17
- package/extensions/browser/frontend/types.ts +13 -0
- package/extensions/browser/frontend/useBrowserResources.ts +18 -3
- package/index.html +32 -2
- package/package.json +10 -6
- package/shared/backend-connection-status.d.ts +12 -0
- package/shared/backend-connection-status.js +35 -4
- package/backend/agent-activity.js +0 -35
- package/backend/agent-memory-report.js +0 -583
- package/backend/bundle-update-helper.js +0 -113
- package/backend/codex-rollout-follower.js +0 -326
- package/dist/assets/App-CPG4WcjO.js +0 -658
- package/dist/assets/FileEditorPane-DXXq82aM.js +0 -2
- package/dist/assets/IconGlyphs-DrdPjYXr.js +0 -1
- package/dist/assets/ProjectFilesSection-CP66XVPl.js +0 -12
- package/dist/assets/ReviewPage-w21MEPD6.js +0 -3
- package/dist/assets/code-dark-BDjwj7Um.css +0 -1
- package/dist/assets/main-BlVUXfxa.css +0 -1
- package/dist/assets/workspace-editor-monaco-CFEfFNcA.js +0 -1
- package/dist/assets/workspace-view-state-BS_V8JVs.js +0 -7
- package/extensions/browser/backend/cdp-browser-runtime.js +0 -648
- package/extensions/browser/backend/cdp-client.js +0 -167
package/README.md
CHANGED
|
@@ -25,19 +25,16 @@ Farming Code runs on the same development machine as your repositories and codin
|
|
|
25
25
|
|
|
26
26
|
## Quick Start
|
|
27
27
|
|
|
28
|
-
With Node.js 22.13 LTS (22.x) or Node.js 24+ and
|
|
28
|
+
With Node.js 22.13 LTS (22.x) or Node.js 24+ and access to a supported coding
|
|
29
|
+
Agent provider:
|
|
29
30
|
|
|
30
31
|
```bash
|
|
31
32
|
npm install --global farming-code@latest && farming daemon
|
|
32
33
|
```
|
|
33
34
|
|
|
34
|
-
Open one of the authenticated URLs printed by the command, choose **New Agent**,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
farming url
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
For a new remote browser, use the authenticated **Network** URL printed when `farming daemon` starts. A VPN, SSH tunnel, or HTTPS reverse proxy can provide a stable reachable address, but the first visit still needs the Farming startup token.
|
|
35
|
+
Open one of the authenticated URLs printed by the command, choose **New Agent**,
|
|
36
|
+
and start a task. See [Getting started](./docs/getting-started.md) for the complete
|
|
37
|
+
first-run flow.
|
|
41
38
|
|
|
42
39
|

|
|
43
40
|
|
|
@@ -47,67 +44,46 @@ Farming Code is the default desktop and mobile interface. It groups work by proj
|
|
|
47
44
|
|
|
48
45
|
### Agents, Chat, and Terminal
|
|
49
46
|
|
|
50
|
-
Start or resume Codex, Claude Code, OpenCode, Qoder, and other detected coding
|
|
47
|
+
Start or resume Codex, Claude Code, OpenCode, Qoder, and other detected coding
|
|
48
|
+
Agents. Use structured Chat to read results and inspect the process, or Terminal
|
|
49
|
+
to work directly with the CLI.
|
|
51
50
|
|
|
52
51
|

|
|
53
52
|
|
|
54
53
|
### Files and Review
|
|
55
54
|
|
|
56
|
-
Browse, search, and lightly edit Project Files without leaving the current task.
|
|
57
|
-
|
|
58
|
-

|
|
55
|
+
Browse, search, and lightly edit Project Files without leaving the current task.
|
|
56
|
+
Inspect changes and open Review when you need evidence.
|
|
59
57
|
|
|
60
58
|
### Browser Resources
|
|
61
59
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
This first Browser Viewer targets web pages and simple Agent interaction. It is not a replacement for the browser's full window chrome, DevTools, downloads UI, extensions, or Computer Use.
|
|
60
|
+
Farming lets people and Agents use the same project browser. See [Farming Browser](docs/products/code/browser-agent-cli.md).
|
|
65
61
|
|
|
66
62
|
## Supported Agents
|
|
67
63
|
|
|
68
|
-
Farming discovers installed CLIs on the host. Codex, Claude Code, OpenCode, and Qoder support both structured Chat and a native Terminal; other detected coding agents use the Terminal path.
|
|
69
|
-
|
|
70
64
|
| Agent | Structured Chat | Terminal | History / resume |
|
|
71
65
|
| --- | --- | --- | --- |
|
|
72
66
|
| Codex | Yes | Yes | Yes |
|
|
73
67
|
| Claude Code | Yes | Yes | Yes |
|
|
74
68
|
| OpenCode | Yes | Yes | Yes |
|
|
75
69
|
| Qoder | Yes | Yes | Yes |
|
|
76
|
-
| Qwen Code | — | Yes | CLI-dependent |
|
|
77
|
-
| Aider | — | Yes | CLI-dependent |
|
|
78
|
-
| GitHub Copilot CLI | — | Yes | CLI-dependent |
|
|
79
|
-
| Amazon Q | — | Yes | CLI-dependent |
|
|
80
70
|
| bash / zsh | — | Yes | No |
|
|
81
71
|
|
|
82
|
-
|
|
72
|
+
Provider-backed Agents still require a valid provider login. Other detected CLIs
|
|
73
|
+
must be able to run on the Farming host.
|
|
83
74
|
|
|
84
75
|
## Remote Use
|
|
85
76
|
|
|
86
|
-
Run Farming on the development machine and open its authenticated URL from
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
│ HTTP / WebSocket
|
|
91
|
-
▼
|
|
92
|
-
Development machine
|
|
93
|
-
Farming server
|
|
94
|
-
├── coding Agent processes
|
|
95
|
-
├── real terminals
|
|
96
|
-
├── repositories and project files
|
|
97
|
-
└── optional system-browser processes
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
The browser can disconnect and reconnect without stopping an Agent. A normal Farming server restart can also reconnect supported live terminal sessions. The desktop layout keeps projects, conversations, files, and review together; the mobile layout focuses one conversation, terminal, or file at a time.
|
|
101
|
-
|
|
102
|
-
<p align="center">
|
|
103
|
-
<img src="./docs/products/code/assets/05-mobile-agent-chat.png" alt="Farming Code reconnecting to a running Agent from a phone" width="390">
|
|
104
|
-
</p>
|
|
77
|
+
Run Farming on the development machine and open its authenticated URL from a
|
|
78
|
+
desktop or phone that can reach it. Agents keep running when the browser
|
|
79
|
+
disconnects. See [Operations](./docs/operations/README.md) for remote-access and
|
|
80
|
+
security guidance.
|
|
105
81
|
|
|
106
82
|
## Farming CRT
|
|
107
83
|
|
|
108
84
|
Farming CRT is an optional keyboard-first, retro control-room interface for scanning many Agents, opening their Chat or Terminal sessions, searching history, and viewing usage telemetry.
|
|
109
85
|
|
|
110
|
-

|
|
111
87
|
|
|
112
88
|
Code and CRT use the same backend Agents and sessions. Switching interfaces does not create a second Agent. Farming Code remains the default interface and the supported phone interface. See the [Farming CRT guide](./docs/products/crt/README.md) for controls and workflows.
|
|
113
89
|
|
|
@@ -117,65 +93,26 @@ Farming Net is a separate, token-protected directory for Farming deployments. It
|
|
|
117
93
|
|
|
118
94
|
## Installation And Updates
|
|
119
95
|
|
|
120
|
-
|
|
96
|
+
Install with the Quick Start command above. npm installations can update from
|
|
97
|
+
**Settings → Updates**.
|
|
121
98
|
|
|
122
|
-
|
|
123
|
-
farming status
|
|
124
|
-
farming url
|
|
125
|
-
farming logs
|
|
126
|
-
farming stop
|
|
127
|
-
```
|
|
99
|
+

|
|
128
100
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
To run from source with the same port and base path:
|
|
132
|
-
|
|
133
|
-
```bash
|
|
134
|
-
npm install
|
|
135
|
-
PORT=6694 FARMING_BASE_PATH=/farming npm start
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
For trusted local development only, `npm run start:no-auth` disables token authentication.
|
|
101
|
+
Standalone CLI and directory bundles remain available from [GitHub Releases](https://github.com/zhuwenzhuang/farming/releases) for manual installation. The in-app updater never reads GitHub Releases; it is available only to npm installations.
|
|
139
102
|
|
|
140
103
|
## Security
|
|
141
104
|
|
|
142
105
|
Farming controls real terminals and files on the development machine. Run it on a trusted host and network. Do not expose it directly to the public internet without a VPN, SSH tunnel, HTTPS reverse proxy, or equivalent access control.
|
|
143
106
|
|
|
144
|
-
|
|
107
|
+
See [SECURITY.md](./SECURITY.md) for deployment and reporting guidance.
|
|
145
108
|
|
|
146
109
|
## Documentation
|
|
147
110
|
|
|
148
|
-
- [
|
|
149
|
-
- [
|
|
150
|
-
- [
|
|
151
|
-
- [Farming Net deployment portal](./docs/products/net/README.md)
|
|
152
|
-
- [Mobile guide](./docs/products/code/mobile-guide.md)
|
|
153
|
-
- [ACP runtime](./docs/products/code/acp-runtime.md)
|
|
154
|
-
- [Review foundation](./docs/products/code/review-foundation.md)
|
|
111
|
+
- [Documentation home](./docs/README.md)
|
|
112
|
+
- [Getting started](./docs/getting-started.md)
|
|
113
|
+
- [Operations](./docs/operations/README.md)
|
|
155
114
|
- [Release history](https://github.com/zhuwenzhuang/farming/releases)
|
|
156
|
-
- [
|
|
157
|
-
|
|
158
|
-
## Development Checks
|
|
159
|
-
|
|
160
|
-
```bash
|
|
161
|
-
npm test
|
|
162
|
-
npm run typecheck
|
|
163
|
-
npm run lint
|
|
164
|
-
FARMING_BASE_PATH=/farming npm run build
|
|
165
|
-
npm run test:e2e:playwright
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
Product screenshots are generated from an anonymous demo workspace with real browser flows:
|
|
169
|
-
|
|
170
|
-
```bash
|
|
171
|
-
npm run docs:product:screenshots
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
To refresh only selected files, pass a comma-separated list:
|
|
175
|
-
|
|
176
|
-
```bash
|
|
177
|
-
FARMING_SCREENSHOT_FILES=01-code-workspace.png npm run docs:product:screenshots
|
|
178
|
-
```
|
|
115
|
+
- [Contributing](./CONTRIBUTING.md)
|
|
179
116
|
|
|
180
117
|
## License
|
|
181
118
|
|
package/README.zh_cn.md
CHANGED
|
@@ -25,19 +25,14 @@ Farming Code 与代码仓库和 Coding CLI 运行在同一台开发机上。Agen
|
|
|
25
25
|
|
|
26
26
|
## 快速开始
|
|
27
27
|
|
|
28
|
-
准备好 Node.js 22.13 LTS(22.x)或 Node.js 24
|
|
28
|
+
准备好 Node.js 22.13 LTS(22.x)或 Node.js 24+,并确保至少有一个可用的
|
|
29
|
+
Coding Agent Provider:
|
|
29
30
|
|
|
30
31
|
```bash
|
|
31
32
|
npm install --global farming-code@latest && farming daemon
|
|
32
33
|
```
|
|
33
34
|
|
|
34
|
-
打开命令输出的任意一个带鉴权 URL,选择 **New Agent
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
farming url
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
新的远程浏览器应使用 `farming daemon` 启动时输出的带鉴权 **Network** URL。VPN、SSH Tunnel 或 HTTPS Reverse Proxy 可以提供稳定且可达的地址,但第一次访问仍需要 Farming 启动 Token。
|
|
35
|
+
打开命令输出的任意一个带鉴权 URL,选择 **New Agent**,然后启动任务。完整首次使用流程见[快速开始](./docs/getting-started.zh_cn.md)。
|
|
41
36
|
|
|
42
37
|

|
|
43
38
|
|
|
@@ -47,67 +42,39 @@ Farming Code 是默认的桌面与手机界面。它按项目组织工作,把
|
|
|
47
42
|
|
|
48
43
|
### Agent、Chat 与 Terminal
|
|
49
44
|
|
|
50
|
-
启动或恢复 Codex、Claude Code、OpenCode、Qoder 以及其他检测到的 Coding
|
|
45
|
+
启动或恢复 Codex、Claude Code、OpenCode、Qoder 以及其他检测到的 Coding Agent。使用结构化 Chat 阅读结果和检查过程,或使用 Terminal 直接操作 CLI。
|
|
51
46
|
|
|
52
47
|

|
|
53
48
|
|
|
54
49
|
### Files 与 Review
|
|
55
50
|
|
|
56
|
-
浏览、搜索并轻量编辑 Project Files
|
|
57
|
-
|
|
58
|
-

|
|
51
|
+
浏览、搜索并轻量编辑 Project Files,不需要离开当前任务。需要证据时可以检查修改并打开 Review。
|
|
59
52
|
|
|
60
53
|
### Browser Resource
|
|
61
54
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
第一版 Browser Viewer 面向网页展示与简单 Agent 操作,不替代浏览器完整窗口、DevTools、下载界面、浏览器扩展或 Computer Use。
|
|
55
|
+
Farming 让人和 Agent 使用同一个 Project Browser。详见 [Farming Browser](docs/products/code/browser-agent-cli.zh_cn.md)。
|
|
65
56
|
|
|
66
57
|
## 支持的 Agent
|
|
67
58
|
|
|
68
|
-
Farming 会发现开发机上已经安装的 CLI。Codex、Claude Code、OpenCode 和 Qoder 同时支持结构化 Chat 与原生 Terminal;其他检测到的 Coding Agent 使用 Terminal 路径。
|
|
69
|
-
|
|
70
59
|
| Agent | 结构化 Chat | Terminal | History / Resume |
|
|
71
60
|
| --- | --- | --- | --- |
|
|
72
61
|
| Codex | 是 | 是 | 是 |
|
|
73
62
|
| Claude Code | 是 | 是 | 是 |
|
|
74
63
|
| OpenCode | 是 | 是 | 是 |
|
|
75
64
|
| Qoder | 是 | 是 | 是 |
|
|
76
|
-
| Qwen Code | — | 是 | 取决于 CLI |
|
|
77
|
-
| Aider | — | 是 | 取决于 CLI |
|
|
78
|
-
| GitHub Copilot CLI | — | 是 | 取决于 CLI |
|
|
79
|
-
| Amazon Q | — | 是 | 取决于 CLI |
|
|
80
65
|
| bash / zsh | — | 是 | 否 |
|
|
81
66
|
|
|
82
|
-
|
|
67
|
+
使用 Provider 的 Agent 仍需要有效登录;其他被发现的 CLI 必须能在 Farming Host 上正常运行。
|
|
83
68
|
|
|
84
69
|
## 远程使用
|
|
85
70
|
|
|
86
|
-
在开发机上运行 Farming,再从能够访问这台机器的电脑或手机打开带鉴权 URL
|
|
87
|
-
|
|
88
|
-
```text
|
|
89
|
-
电脑或手机浏览器
|
|
90
|
-
│ HTTP / WebSocket
|
|
91
|
-
▼
|
|
92
|
-
开发机
|
|
93
|
-
Farming Server
|
|
94
|
-
├── Coding Agent 进程
|
|
95
|
-
├── 真实 Terminal
|
|
96
|
-
├── 代码仓库与项目文件
|
|
97
|
-
└── 可选的系统浏览器进程
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
浏览器断开或重新连接不会停止 Agent。Farming Server 正常重启后也可以重新连接受支持的实时 Terminal Session。桌面布局把项目、对话、文件和 Review 放在一起;手机布局一次聚焦一段对话、一个 Terminal 或一个文件。
|
|
101
|
-
|
|
102
|
-
<p align="center">
|
|
103
|
-
<img src="./docs/products/code/assets/05-mobile-agent-chat.png" alt="使用手机重新连接仍在运行的 Farming Code Agent" width="390">
|
|
104
|
-
</p>
|
|
71
|
+
在开发机上运行 Farming,再从能够访问这台机器的电脑或手机打开带鉴权 URL。浏览器断开后 Agent 仍会继续运行。远程访问和安全说明见[运行与维护](./docs/operations/README.zh_cn.md)。
|
|
105
72
|
|
|
106
73
|
## Farming CRT
|
|
107
74
|
|
|
108
75
|
Farming CRT 是可选的键盘优先复古控制室,用来扫视多个 Agent、打开它们的 Chat 或 Terminal、搜索 History,以及查看用量遥测。
|
|
109
76
|
|
|
110
|
-

|
|
111
78
|
|
|
112
79
|
Code 与 CRT 使用相同的后端 Agent 和 Session,切换界面不会创建第二个 Agent。Farming Code 仍是默认界面,也是受支持的手机界面。控制方式和完整流程见 [Farming CRT 指南](./docs/products/crt/README.zh_cn.md)。
|
|
113
80
|
|
|
@@ -117,65 +84,25 @@ Farming Net 是独立、带 Token 鉴权的 Farming 部署目录。它提供一
|
|
|
117
84
|
|
|
118
85
|
## 安装与更新
|
|
119
86
|
|
|
120
|
-
|
|
87
|
+
按上面的快速开始命令安装即可。npm 安装可以从 **Settings → Updates** 更新。
|
|
121
88
|
|
|
122
|
-
|
|
123
|
-
farming status
|
|
124
|
-
farming url
|
|
125
|
-
farming logs
|
|
126
|
-
farming stop
|
|
127
|
-
```
|
|
89
|
+

|
|
128
90
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
从源码运行,并使用相同的端口与 Base Path:
|
|
132
|
-
|
|
133
|
-
```bash
|
|
134
|
-
npm install
|
|
135
|
-
PORT=6694 FARMING_BASE_PATH=/farming npm start
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
只有在可信本地开发环境中,才可以用 `npm run start:no-auth` 关闭 Token 鉴权。
|
|
91
|
+
独立 CLI 和目录 Bundle 仍可从 [GitHub Releases](https://github.com/zhuwenzhuang/farming/releases) 手动下载安装。应用内更新不会读取 GitHub Releases,只对 npm 安装开放。
|
|
139
92
|
|
|
140
93
|
## 安全
|
|
141
94
|
|
|
142
95
|
Farming 会控制开发机上的真实终端和文件。请只运行在可信主机和可信网络中,不要在没有 VPN、SSH Tunnel、HTTPS Reverse Proxy 或等价访问控制时直接暴露到公网。
|
|
143
96
|
|
|
144
|
-
|
|
97
|
+
部署与报告说明见 [SECURITY.zh_cn.md](./SECURITY.zh_cn.md)。
|
|
145
98
|
|
|
146
99
|
## 文档
|
|
147
100
|
|
|
148
|
-
- [
|
|
149
|
-
- [
|
|
150
|
-
- [
|
|
151
|
-
- [Farming Net 部署门户](./docs/products/net/README.zh_cn.md)
|
|
152
|
-
- [移动端指南](./docs/products/code/mobile-guide.zh_cn.md)
|
|
153
|
-
- [ACP 运行时](./docs/products/code/acp-runtime.zh_cn.md)
|
|
154
|
-
- [Review 基础](./docs/products/code/review-foundation.zh_cn.md)
|
|
101
|
+
- [文档首页](./docs/README.zh_cn.md)
|
|
102
|
+
- [快速开始](./docs/getting-started.zh_cn.md)
|
|
103
|
+
- [运行与维护](./docs/operations/README.zh_cn.md)
|
|
155
104
|
- [版本历史](https://github.com/zhuwenzhuang/farming/releases)
|
|
156
|
-
- [
|
|
157
|
-
|
|
158
|
-
## 开发检查
|
|
159
|
-
|
|
160
|
-
```bash
|
|
161
|
-
npm test
|
|
162
|
-
npm run typecheck
|
|
163
|
-
npm run lint
|
|
164
|
-
FARMING_BASE_PATH=/farming npm run build
|
|
165
|
-
npm run test:e2e:playwright
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
产品截图由匿名 Demo Workspace 和真实浏览器流程生成:
|
|
169
|
-
|
|
170
|
-
```bash
|
|
171
|
-
npm run docs:product:screenshots
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
只更新指定截图时,可以传入逗号分隔的文件名:
|
|
175
|
-
|
|
176
|
-
```bash
|
|
177
|
-
FARMING_SCREENSHOT_FILES=01-code-workspace.png npm run docs:product:screenshots
|
|
178
|
-
```
|
|
105
|
+
- [参与贡献](./CONTRIBUTING.zh_cn.md)
|
|
179
106
|
|
|
180
107
|
## License
|
|
181
108
|
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -15,8 +15,6 @@ preserved in bundled `node_modules` when bundled dependencies are enabled.
|
|
|
15
15
|
| Package | Version | License | Purpose |
|
|
16
16
|
| --- | --- | --- | --- |
|
|
17
17
|
| `@agentclientprotocol/sdk` | 1.2.1 | Apache-2.0 | ACP JSON-RPC client and protocol types |
|
|
18
|
-
| `@agentclientprotocol/codex-acp` | 1.1.4 | Apache-2.0 | Codex ACP adapter |
|
|
19
|
-
| `@agentclientprotocol/claude-agent-acp` | 0.59.0 | Apache-2.0 | Claude Code ACP adapter |
|
|
20
18
|
| `@modelcontextprotocol/sdk` | 1.29.0 | MIT | Browser Extension MCP server and stdio transport |
|
|
21
19
|
| `@xterm/addon-clipboard` | 0.2.0 | MIT | Browser terminal clipboard integration |
|
|
22
20
|
| `@xterm/addon-fit` | 0.11.0 | MIT | Browser terminal sizing |
|
|
@@ -47,12 +45,32 @@ preserved in bundled `node_modules` when bundled dependencies are enabled.
|
|
|
47
45
|
| `remark-gfm` | 4.0.1 | MIT | GitHub Flavored Markdown support |
|
|
48
46
|
| `remark-math` | 6.0.0 | MIT | Markdown math syntax support |
|
|
49
47
|
| `ripgrep` | 0.3.1 | MIT | Node wrapper for file search support |
|
|
48
|
+
| `tar` | 7.5.19 | BlueOak-1.0.0 | Safe extraction of version-locked startup dependency archives |
|
|
50
49
|
| `ws` | 8.21.0 | MIT | WebSocket server/client support |
|
|
51
50
|
| `yaml` | 2.9.0 | ISC | YAML parsing |
|
|
52
51
|
| `zod` | 3.25.76 | MIT | MCP tool input schema validation |
|
|
53
52
|
|
|
54
53
|
## Vendored Assets
|
|
55
54
|
|
|
55
|
+
Farming builds version- and SHA-256-locked ACP runtime files from these exact
|
|
56
|
+
development dependencies and ships their license texts beside the runtime
|
|
57
|
+
files under `dist/acp/`:
|
|
58
|
+
|
|
59
|
+
| Package | Version | License | Purpose |
|
|
60
|
+
| --- | --- | --- | --- |
|
|
61
|
+
| `@agentclientprotocol/codex-acp` | 1.1.4 | Apache-2.0 | Reviewed and patched Codex ACP adapter |
|
|
62
|
+
| `@openai/codex` | 0.144.6 | Apache-2.0 | Codex executable discovery and launch bridge; platform CLI binaries are excluded |
|
|
63
|
+
| `@agentclientprotocol/claude-agent-acp` | 0.59.0 | Apache-2.0 | Claude Code ACP adapter |
|
|
64
|
+
| `@anthropic-ai/claude-agent-sdk` | 0.3.207 | Anthropic commercial terms | Claude Agent SDK bridge; platform CLI binaries are excluded |
|
|
65
|
+
|
|
66
|
+
Before starting a fresh Server, Farming may prepare the exact Codex CLI
|
|
67
|
+
0.144.6, Claude Agent SDK CLI package 0.3.207, and `agent-browser` 0.32.3
|
|
68
|
+
platform artifacts in its private runtime cache. They are not part of the npm
|
|
69
|
+
or application package and remain independent works under their own terms.
|
|
70
|
+
Farming accepts only the version-locked sources and integrity values declared
|
|
71
|
+
by its release manifest. The `agent-browser` license text is included at
|
|
72
|
+
`backend/data/LICENSE.agent-browser`.
|
|
73
|
+
|
|
56
74
|
Farming vendors `ghostty-web` distribution files under
|
|
57
75
|
`frontend/vendor/ghostty-web` for the optional Ghostty debug renderer. The
|
|
58
76
|
source package is `ghostty-web` 0.4.0, licensed under MIT. Its license is kept
|
|
@@ -114,10 +132,11 @@ their code.
|
|
|
114
132
|
|
|
115
133
|
Farming can launch or observe coding-agent CLIs installed by the user, including
|
|
116
134
|
OpenCode and the terminal forms of OpenAI Codex CLI and Anthropic Claude Code.
|
|
117
|
-
The
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
135
|
+
The structured ACP runtime includes reviewed Codex and Claude adapter code, but
|
|
136
|
+
Farming does not bundle a platform Codex or Claude Code CLI inside its package.
|
|
137
|
+
The adapters use the exact system or verified startup-cache executable prepared
|
|
138
|
+
by the Farming launcher. Those tools remain separate projects governed by their
|
|
139
|
+
own terms and licenses.
|
|
121
140
|
|
|
122
141
|
Farming is not affiliated with, sponsored by, or endorsed by OpenAI, Anthropic,
|
|
123
142
|
Microsoft, or the maintainers of the third-party projects listed above.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const PACKAGED_CLAUDE_ACP_ARG = '--farming-claude-acp';
|
|
2
|
+
|
|
3
|
+
async function runPackagedClaudeAcp() {
|
|
4
|
+
if (!process.pkg) {
|
|
5
|
+
throw new Error('The packaged Claude ACP entry is available only in a standalone Farming CLI');
|
|
6
|
+
}
|
|
7
|
+
throw new Error('The standalone Farming CLI omitted its embedded Claude ACP runtime');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
module.exports = {
|
|
11
|
+
PACKAGED_CLAUDE_ACP_ARG,
|
|
12
|
+
runPackagedClaudeAcp,
|
|
13
|
+
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const PACKAGED_CODEX_ACP_ARG = '--farming-codex-acp';
|
|
2
2
|
|
|
3
|
-
function runPackagedCodexAcp() {
|
|
3
|
+
async function runPackagedCodexAcp() {
|
|
4
4
|
if (!process.pkg) {
|
|
5
5
|
throw new Error('The packaged Codex ACP entry is available only in a standalone Farming CLI');
|
|
6
6
|
}
|
|
7
|
-
|
|
7
|
+
throw new Error('The standalone Farming CLI omitted its embedded Codex ACP runtime');
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
module.exports = {
|
package/backend/acp-runtime.js
CHANGED
|
@@ -9,9 +9,9 @@ const { promisify } = require('util');
|
|
|
9
9
|
const packageJson = require('../package.json');
|
|
10
10
|
const { AcpCheckpointStore } = require('./acp-checkpoint-store');
|
|
11
11
|
const { AcpSessionState } = require('./acp-session-state');
|
|
12
|
-
const { readCodexHistoryImageData } = require('./codex-transcript');
|
|
13
12
|
const { AcpClientFileSystem, AcpClientTerminalManager } = require('./acp/client-services');
|
|
14
13
|
const { PACKAGED_CODEX_ACP_ARG } = require('./acp/packaged-codex-acp');
|
|
14
|
+
const { PACKAGED_CLAUDE_ACP_ARG } = require('./acp/packaged-claude-acp');
|
|
15
15
|
const { permissionSecurityWarnings } = require('./acp/permission-security');
|
|
16
16
|
const { patchBlock, rejectPatch } = require('./acp/patch-decisions');
|
|
17
17
|
const { getProviderAdapter, listProviderAdapters } = require('./provider-adapters');
|
|
@@ -35,13 +35,23 @@ const CODEX_SET_SESSION_MODEL_METHOD = 'session/set_model';
|
|
|
35
35
|
const CODEX_STEER_METHOD = '_codex/session/steer';
|
|
36
36
|
const CODEX_ACP_PACKAGE = '@agentclientprotocol/codex-acp';
|
|
37
37
|
const CODEX_ACP_VERSION = '1.1.4';
|
|
38
|
-
const CODEX_ACP_SHA256 = '
|
|
38
|
+
const CODEX_ACP_SHA256 = '75e70159692a7889d496651074cd3476687bafb9dc7d4eb3e9590509ad687611';
|
|
39
|
+
const CLAUDE_ACP_PACKAGE = '@agentclientprotocol/claude-agent-acp';
|
|
40
|
+
const CLAUDE_ACP_VERSION = '0.59.0';
|
|
41
|
+
const CLAUDE_ACP_SHA256 = 'a6aa515dd02382617bf46d9eac47b8a1022c6835bcf7a8d61e2c63939be2e49c';
|
|
39
42
|
const CODEX_ACP_VENDOR_ENTRY = path.join(
|
|
40
43
|
__dirname,
|
|
41
44
|
'..',
|
|
42
45
|
'dist',
|
|
43
46
|
'acp',
|
|
44
|
-
`codex-acp-${CODEX_ACP_VERSION}.
|
|
47
|
+
`codex-acp-${CODEX_ACP_VERSION}.mjs`,
|
|
48
|
+
);
|
|
49
|
+
const CLAUDE_ACP_VENDOR_ENTRY = path.join(
|
|
50
|
+
__dirname,
|
|
51
|
+
'..',
|
|
52
|
+
'dist',
|
|
53
|
+
'acp',
|
|
54
|
+
`claude-agent-acp-${CLAUDE_ACP_VERSION}.mjs`,
|
|
45
55
|
);
|
|
46
56
|
const execFileAsync = promisify(execFile);
|
|
47
57
|
|
|
@@ -70,6 +80,15 @@ function adapterEntry(packageName) {
|
|
|
70
80
|
if (packageName === CODEX_ACP_PACKAGE && fs.existsSync(CODEX_ACP_VENDOR_ENTRY)) {
|
|
71
81
|
return verifiedCodexAcpEntry(CODEX_ACP_VENDOR_ENTRY);
|
|
72
82
|
}
|
|
83
|
+
if (packageName === CLAUDE_ACP_PACKAGE && fs.existsSync(CLAUDE_ACP_VENDOR_ENTRY)) {
|
|
84
|
+
const actualSha256 = fileSha256(CLAUDE_ACP_VENDOR_ENTRY);
|
|
85
|
+
if (actualSha256 !== CLAUDE_ACP_SHA256) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`Claude ACP runtime failed integrity verification: expected ${CLAUDE_ACP_SHA256}, found ${actualSha256}`,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
return CLAUDE_ACP_VENDOR_ENTRY;
|
|
91
|
+
}
|
|
73
92
|
let sdkDirectory;
|
|
74
93
|
try {
|
|
75
94
|
sdkDirectory = path.dirname(runtimeRequire.resolve('@agentclientprotocol/sdk'));
|
|
@@ -109,7 +128,11 @@ function resolveAcpLaunch(provider, options = {}) {
|
|
|
109
128
|
const launch = nodeAdapterLaunch(
|
|
110
129
|
adapterEntry(adapter.acp.packageName),
|
|
111
130
|
options.runtimeEnv || process.env,
|
|
112
|
-
adapter.acp.packageName === CODEX_ACP_PACKAGE
|
|
131
|
+
adapter.acp.packageName === CODEX_ACP_PACKAGE
|
|
132
|
+
? PACKAGED_CODEX_ACP_ARG
|
|
133
|
+
: adapter.acp.packageName === CLAUDE_ACP_PACKAGE
|
|
134
|
+
? PACKAGED_CLAUDE_ACP_ARG
|
|
135
|
+
: '',
|
|
113
136
|
);
|
|
114
137
|
return { ...launch, version: adapter.acp.version };
|
|
115
138
|
}
|
|
@@ -833,19 +856,6 @@ class AcpRuntime extends EventEmitter {
|
|
|
833
856
|
binding.historyReplayActive = false;
|
|
834
857
|
}
|
|
835
858
|
binding.sessionState.finishHistoryReplay();
|
|
836
|
-
if (provider === 'codex' && binding.sessionState.hasCodexHistoryImageReferences()) {
|
|
837
|
-
let imageDataByPath = new Map();
|
|
838
|
-
try {
|
|
839
|
-
imageDataByPath = await readCodexHistoryImageData(requestedSessionId, {
|
|
840
|
-
codexHome: binding.env.CODEX_HOME,
|
|
841
|
-
});
|
|
842
|
-
} catch {
|
|
843
|
-
// Local history images can still be restored from their adapter paths.
|
|
844
|
-
}
|
|
845
|
-
this.requireOpenBinding(binding);
|
|
846
|
-
await binding.sessionState.hydrateCodexHistoryAttachments({ imageDataByPath });
|
|
847
|
-
this.requireOpenBinding(binding);
|
|
848
|
-
}
|
|
849
859
|
this.restorePatchDecisions(binding, restoredCheckpoint?.patchDecisions);
|
|
850
860
|
historyMode = 'load';
|
|
851
861
|
opened = true;
|
|
@@ -2508,6 +2518,17 @@ class AcpRuntime extends EventEmitter {
|
|
|
2508
2518
|
return visible;
|
|
2509
2519
|
}
|
|
2510
2520
|
|
|
2521
|
+
getTranscriptEntry(agentId, entryId) {
|
|
2522
|
+
const binding = this.requireBinding(agentId);
|
|
2523
|
+
const entries = (binding.sessionState?.entries || []).filter(candidate => (
|
|
2524
|
+
String(candidate?.id || '') === String(entryId || '')
|
|
2525
|
+
));
|
|
2526
|
+
if (entries.length !== 1) return null;
|
|
2527
|
+
const [entry] = entries;
|
|
2528
|
+
if (!entry || binding.sessionState.isInternalEntry(entry)) return null;
|
|
2529
|
+
return entry;
|
|
2530
|
+
}
|
|
2531
|
+
|
|
2511
2532
|
getPatchDecision(agentId, toolCallId, requestedPath) {
|
|
2512
2533
|
const binding = this.requireBinding(agentId);
|
|
2513
2534
|
return binding.patchDecisions.get(`${String(toolCallId || '')}\n${String(requestedPath || '')}`) || '';
|