agy-mcp-bridge 0.1.16 → 0.1.18
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 +87 -55
- package/config/workspaces.example.json +7 -1
- package/dist/scripts/check.js +2 -6
- package/dist/scripts/delegation.js +1 -1
- package/dist/scripts/probe-stream.js +3 -3
- package/dist/src/agents/antigravity.js +63 -0
- package/dist/src/agents/codex.js +120 -0
- package/dist/src/agents/registry.js +55 -0
- package/dist/src/agents/types.js +2 -0
- package/dist/src/antigravity/process.js +57 -8
- package/dist/src/cli.js +67 -13
- package/dist/src/codex-config.js +82 -0
- package/dist/src/config.js +10 -1
- package/dist/src/http.js +2 -12
- package/dist/src/index.js +26 -33
- package/dist/src/isolation/worktree.js +77 -0
- package/dist/src/runtime.js +39 -14
- package/dist/src/security/input.js +26 -2
- package/dist/src/security/redact.js +0 -5
- package/dist/src/setup.js +8 -25
- package/dist/src/tasks/manager.js +197 -62
- package/dist/src/tools/register.js +13 -3
- package/dist/src/ui/routes.js +40 -32
- package/docs/HARDENING.md +8 -8
- package/docs/MULTI-AGENT-PLAN.md +212 -0
- package/docs/SKILL-EVAL.md +1 -1
- package/docs/VERIFICATION.md +6 -4
- package/package.json +2 -2
- package/skills/antigravity-bridge/SKILL.md +39 -16
- package/skills/known-versions.json +4 -0
- package/ui/app.css +1 -13
- package/ui/app.js +74 -70
- package/dist/src/login-notice.js +0 -18
- package/dist/src/security/http-auth.js +0 -57
- package/dist/src/ui/session.js +0 -49
package/README.md
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
# MCP Bridge HTTP:
|
|
1
|
+
# MCP Bridge HTTP: agent điều phối → Antigravity / Codex
|
|
2
2
|
|
|
3
|
-
Server TypeScript chạy độc lập trong terminal, dùng **MCP Streamable HTTP**. Codex
|
|
3
|
+
Server TypeScript chạy độc lập trong terminal, dùng **MCP Streamable HTTP**. Codex, Claude Code hoặc agent điều phối khác kết nối tới cùng endpoint; không khởi chạy process bridge riêng. Bridge gọi CLI agent đã đăng nhập: `agy` (Antigravity) và/hoặc `codex exec` (Codex). Mỗi task chọn agent, chế độ cách ly và quyền tự duyệt; task worktree chạy song song trong git worktree riêng.
|
|
4
4
|
|
|
5
|
-
`npm start` hiện chạy HTTP. STDIO cũ chỉ còn là chế độ tùy chọn `npm run start:stdio`, không dùng trong các cấu hình client bên dưới. Source bridge ở thư mục phát triển riêng `MCP-bridge`, ngoài repository ứng dụng được giao sửa.
|
|
5
|
+
`npm start` hiện chạy HTTP. STDIO cũ chỉ còn là chế độ tùy chọn `npm run start:stdio`, không dùng trong các cấu hình client bên dưới. Source bridge ở thư mục phát triển riêng `MCP-bridge`, ngoài repository ứng dụng được giao sửa. Kế hoạch nhiều agent và trạng thái từng phase ở [docs/MULTI-AGENT-PLAN.md](docs/MULTI-AGENT-PLAN.md).
|
|
6
6
|
|
|
7
7
|
## Cài từ npm (người dùng)
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npm install -g agy-mcp-bridge # cần Node.js >= 20
|
|
10
|
+
npm install -g agy-mcp-bridge # cần Node.js >= 20; Antigravity CLI `agy` 1.4.x và/hoặc Codex CLI là tùy chọn
|
|
11
11
|
agy-mcp-bridge workspaces add /duong/dan/toi/project # cấp quyền cho một thư mục (khởi động lại server sau khi đổi)
|
|
12
12
|
agy-mcp-bridge # mở server http://127.0.0.1:3000 ; giao diện web ở /ui
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
Bridge tự dò `agy` và `codex` khi khởi động; agent nào không có thì bị đánh dấu unavailable và không nhận task. Chọn thứ tự ưu tiên và bật/tắt từng agent trong `agents` của `config/workspaces.json`.
|
|
16
|
+
|
|
15
17
|
**Cách nhanh nhất:** mở terminal tại thư mục dự án rồi chạy `agy-mcp-bridge --workspace .` (cho phép thư mục hiện tại **chỉ trong lần chạy này**, không lưu vào cấu hình; có thể lặp lại cờ cho nhiều thư mục, và log in ra từng thư mục đã được cho phép; thư mục sai hoặc là chính thư mục cài bridge thì dừng ngay, không khởi động server). Muốn lưu lâu dài thì dùng `agy-mcp-bridge workspaces add .`. Trong giao diện web, mục Cài đặt đánh dấu "chỉ lần chạy này" bên cạnh các thư mục này.
|
|
16
18
|
|
|
17
|
-
Các lệnh khác: `agy-mcp-bridge check | setup codex|claude|both | delegation on|off|status | skill install --client codex|claude|both | config | update | help`. Thêm `--open` để tự mở giao diện web trong trình duyệt mặc định khi server đã chạy (`agy-mcp-bridge --open`). Cấu hình
|
|
19
|
+
Các lệnh khác: `agy-mcp-bridge check | setup codex|claude|both | delegation on|off|status | skill install --client codex|claude|both | config | update | help`. Thêm `--open` để tự mở giao diện web trong trình duyệt mặc định khi server đã chạy (`agy-mcp-bridge --open`). Cấu hình và lịch sử task nằm trong thư mục dữ liệu của người dùng (Linux `~/.config/agy-mcp-bridge`, macOS `~/Library/Application Support/agy-mcp-bridge`, Windows `%APPDATA%\agy-mcp-bridge`), không nằm trong thư mục cài đặt nên không mất khi cập nhật; đổi chỗ bằng `BRIDGE_HOME`. `agy-mcp-bridge config` in ra các đường dẫn thật. Phần dưới đây dùng `npm start`/`npm run ...` cho bản clone từ git; với bản cài từ npm hãy dùng lệnh `agy-mcp-bridge` tương ứng.
|
|
18
20
|
|
|
19
21
|
**Skill cho Codex / Claude Code:** gói npm chứa file skill nhưng `npm install` không tự ghi vào thư mục cấu hình của client. Thay vào đó, lần đầu bạn chạy `agy-mcp-bridge` trong terminal tương tác, bridge hiện đường dẫn sẽ ghi rồi hỏi `Install it now? [codex / claude / both / N]`. Chọn mới cài (chỉ cho client chưa có skill; skill bạn đã tự sửa không bao giờ bị đụng tới); chọn `N` hoặc nhấn Enter thì không cài gì và không hỏi lại (câu trả lời lưu ở `onboarding.json` trong thư mục state). Không hỏi khi chạy ngoài terminal tương tác hoặc `CI=true`; tắt hẳn bằng `--no-skill-prompt` hoặc `BRIDGE_NO_SKILL_PROMPT=1`. Cài sau bất kỳ lúc nào bằng `agy-mcp-bridge skill install --client both`. Lỗi khi cài chỉ được báo, server vẫn khởi động. Khi đã cài mà gói có skill mới hơn, bridge hỏi riêng một lần cho việc cập nhật (chỉ với bản cũ do gói phát hành; bản bạn tự sửa không bao giờ được đề nghị hay bị đụng tới).
|
|
20
22
|
|
|
@@ -50,21 +52,22 @@ Nếu publish lỗi sau khi commit version/tag đã được push, dùng **Re-ru
|
|
|
50
52
|
|
|
51
53
|
## Quickstart
|
|
52
54
|
|
|
53
|
-
Requires Git, Node.js ≥20 and a logged-in Antigravity CLI `agy` 1.4.x on PATH (real agent execution was verified on 1.4.3). The longer sections below use PowerShell; the POSIX equivalents are:
|
|
55
|
+
Requires Git, Node.js ≥20 and a logged-in Antigravity CLI `agy` 1.4.x on PATH (real agent execution was verified on 1.4.3 and 1.4.7). The longer sections below use PowerShell; the POSIX equivalents are:
|
|
54
56
|
|
|
55
57
|
```bash
|
|
56
58
|
git clone https://github.com/thanhdo257205/MCP-bridge.git && cd MCP-bridge
|
|
57
59
|
agy --version && npm ci && npm run build
|
|
58
60
|
npm start # terminal 1: server on http://127.0.0.1:3000/mcp
|
|
59
|
-
|
|
60
|
-
npm run check # calls antigravity_environment
|
|
61
|
+
npm run check # terminal 2, same clone: calls antigravity_environment
|
|
61
62
|
```
|
|
62
63
|
|
|
63
|
-
Then allow a workspace in `config/workspaces.json` (created empty on first run, git-ignored), register the client ([Codex](#3-kết-nối-codex), [Claude Code](#4-kết-nối-claude-code)) and install the [skill](#9-skill-giao-tiếp-với-antigravity). Bash equivalents of PowerShell snippets: `$env:X = 'v'` → `export X=v`; `
|
|
64
|
+
Then allow a workspace in `config/workspaces.json` (created empty on first run, git-ignored), register the client ([Codex](#3-kết-nối-codex), [Claude Code](#4-kết-nối-claude-code)) and install the [skill](#9-skill-giao-tiếp-với-antigravity). Bash equivalents of PowerShell snippets: `$env:X = 'v'` → `export X=v`; `Remove-Item Env:X` → `unset X`.
|
|
65
|
+
|
|
66
|
+
> **Không có xác thực.** Bridge chỉ nghe trên `127.0.0.1`, nhưng bất kỳ tiến trình nào chạy trên cùng máy với cùng user đều có thể gọi tool để điều khiển agent. Không mở cổng ra ngoài, không đặt sau reverse proxy công khai, và chỉ dùng trên máy bạn kiểm soát.
|
|
64
67
|
|
|
65
68
|
## 1. Cài đặt và khởi động
|
|
66
69
|
|
|
67
|
-
Yêu cầu Git, Node.js ≥20, npm và Antigravity CLI **1.4.x** đã đăng nhập, có lệnh `agy` trong PATH và đủ cờ bắt buộc trong help. Patch
|
|
70
|
+
Yêu cầu Git, Node.js ≥20, npm và Antigravity CLI **1.4.x** đã đăng nhập, có lệnh `agy` trong PATH và đủ cờ bắt buộc trong help. Patch 1.4.3 và 1.4.7 đã được xác minh thực thi agent thật; patch 1.4.x khác vẫn chạy nhưng có cảnh báo trong log và environment; major/minor khác bị từ chối. SDK chính thức: server 2.3.1, Node HTTP adapter 2.1.1; lockfile khóa dependency. Các lệnh bên dưới dùng PowerShell trên Windows. Xem [thay đổi hardening và giới hạn kiểm chứng](docs/HARDENING.md).
|
|
68
71
|
|
|
69
72
|
Mở PowerShell tại thư mục bạn muốn lưu source, rồi clone và chạy:
|
|
70
73
|
|
|
@@ -91,7 +94,7 @@ Chế độ phát triển:
|
|
|
91
94
|
npm run dev
|
|
92
95
|
```
|
|
93
96
|
|
|
94
|
-
`dev` build rồi chạy HTTP
|
|
97
|
+
`dev` build rồi chạy HTTP; hiện không có hot reload. Sau khi sửa source, Ctrl+C rồi chạy `npm run dev` lại. Không tự restart để tránh gián đoạn task đang sửa code.
|
|
95
98
|
|
|
96
99
|
Server giữ terminal hoạt động tới khi **Ctrl+C**, SIGTERM hoặc lỗi nghiêm trọng. Việc đóng Codex, Claude Code hoặc stdin của bridge không dừng HTTP server. Đóng cưỡng bức cửa sổ terminal không tương đương shutdown an toàn.
|
|
97
100
|
|
|
@@ -100,9 +103,9 @@ Mặc định bind duy nhất `127.0.0.1:3000`. Khi cổng còn trống, termina
|
|
|
100
103
|
```text
|
|
101
104
|
[bridge] HTTP server: http://127.0.0.1:3000
|
|
102
105
|
[bridge] MCP endpoint: http://127.0.0.1:3000/mcp
|
|
103
|
-
[bridge] Health check: http://127.0.0.1:3000/health
|
|
104
|
-
[bridge]
|
|
105
|
-
[bridge] Web UI: http://127.0.0.1:3000/ui
|
|
106
|
+
[bridge] Health check: http://127.0.0.1:3000/health
|
|
107
|
+
[bridge] No authentication: any local process running as this user can control the bridge. Keep it on this machine.
|
|
108
|
+
[bridge] Web UI: http://127.0.0.1:3000/ui (open in a browser on this machine)
|
|
106
109
|
```
|
|
107
110
|
|
|
108
111
|
Dòng `Web UI` là đường dẫn tới giao diện web; nhấn giữ Ctrl (hoặc Cmd) và bấm vào nó trong terminal hỗ trợ liên kết để mở trình duyệt.
|
|
@@ -116,43 +119,40 @@ npm start
|
|
|
116
119
|
|
|
117
120
|
Muốn hệ điều hành chọn một cổng đang trống, đặt `PORT='0'`. Đây là lựa chọn minh bạch do người dùng chỉ định: đọc URL thực tế được in ở terminal rồi cập nhật tất cả client. `PORT` nhận số nguyên 0–65535, không nhận giá trị rỗng. Xóa override để về mặc định: `Remove-Item Env:PORT`.
|
|
118
121
|
|
|
119
|
-
## 2.
|
|
122
|
+
## 2. Không xác thực và health check
|
|
120
123
|
|
|
121
|
-
|
|
124
|
+
Bridge **không có bearer token**. `/mcp` và `/health` nhận request trực tiếp từ loopback. Đây là lựa chọn có chủ đích cho công cụ cục bộ; đổi lại, bất kỳ tiến trình nào trên cùng máy với cùng user đều có thể dùng tool, xem và hủy task, hoặc tắt server. Chỉ chạy bridge trên máy cá nhân hoặc máy bạn kiểm soát hoàn toàn.
|
|
122
125
|
|
|
123
|
-
|
|
126
|
+
Các lớp bảo vệ còn lại: chỉ bind `127.0.0.1`, kiểm tra `Host`/`Origin`, giới hạn body, timeout, allowlist workspace và allowlist biến môi trường cho tiến trình con.
|
|
124
127
|
|
|
125
|
-
Mở **terminal thứ hai tại thư mục gốc của cùng bản clone** (nơi có `package.json`)
|
|
128
|
+
Mở **terminal thứ hai tại thư mục gốc của cùng bản clone** (nơi có `package.json`):
|
|
126
129
|
|
|
127
130
|
```powershell
|
|
128
|
-
|
|
129
|
-
$headers = @{ Authorization = "Bearer $env:BRIDGE_HTTP_TOKEN" }
|
|
130
|
-
Invoke-RestMethod 'http://127.0.0.1:3000/health' -Headers $headers
|
|
131
|
+
Invoke-RestMethod 'http://127.0.0.1:3000/health'
|
|
131
132
|
npm run check
|
|
132
133
|
```
|
|
133
134
|
|
|
134
|
-
`npm run check` không khởi động server hay gọi AI; nó kết nối HTTP và gọi `antigravity_environment`.
|
|
135
|
+
`npm run check` không khởi động server hay gọi AI; nó kết nối HTTP và gọi `antigravity_environment`. Khi server tắt hoặc URL sai, script thoát mã 1 và hướng dẫn chạy `npm start`, kiểm tra PORT/URL, rồi kết nối lại.
|
|
135
136
|
|
|
136
137
|
Với cổng khác, ví dụ 3001:
|
|
137
138
|
|
|
138
139
|
```powershell
|
|
139
140
|
$env:BRIDGE_MCP_URL = 'http://127.0.0.1:3001/mcp'
|
|
140
141
|
npm run check
|
|
141
|
-
Invoke-RestMethod 'http://127.0.0.1:3001/health'
|
|
142
|
+
Invoke-RestMethod 'http://127.0.0.1:3001/health'
|
|
142
143
|
```
|
|
143
144
|
|
|
144
|
-
`BRIDGE_MCP_URL` dành cho script check; URL của Codex và Claude Code phải cập nhật riêng.
|
|
145
|
+
`BRIDGE_MCP_URL` dành cho script check; URL của Codex và Claude Code phải cập nhật riêng. Child `agy` chỉ nhận allowlist môi trường; tên chứa `TOKEN`, `SECRET`, `PASSWORD`, `API_KEY` bị chặn mặc định. Chỉ dùng `extra_env_passthrough` cho biến thực sự cần. Xem danh sách và ví dụ trong [HARDENING.md](docs/HARDENING.md).
|
|
145
146
|
|
|
146
147
|
## 3. Kết nối Codex
|
|
147
148
|
|
|
148
|
-
> Muốn có sẵn đúng lệnh cho máy của bạn (
|
|
149
|
+
> Muốn có sẵn đúng lệnh cho máy của bạn (cổng, PowerShell/cmd/bash) chạy `agy-mcp-bridge setup codex` hoặc `setup claude` (hoặc `setup both`, thêm `--port` và `--shell` nếu cần). Lệnh chỉ in ra, không sửa cấu hình của Codex hay Claude Code; bạn xem rồi tự áp dụng.
|
|
149
150
|
|
|
150
151
|
**Các đoạn dưới là thay đổi đề xuất, chưa áp dụng.** Trình bày để chủ máy duyệt trước khi chạy lệnh ghi cấu hình. Mẫu: [config/codex-mcp.windows.toml](config/codex-mcp.windows.toml).
|
|
151
152
|
|
|
152
153
|
```toml
|
|
153
154
|
[mcp_servers.antigravity]
|
|
154
155
|
url = 'http://127.0.0.1:3000/mcp'
|
|
155
|
-
bearer_token_env_var = 'BRIDGE_HTTP_TOKEN'
|
|
156
156
|
startup_timeout_sec = 30
|
|
157
157
|
tool_timeout_sec = 115
|
|
158
158
|
enabled = true
|
|
@@ -163,17 +163,17 @@ File cấu hình Codex mặc định là `~/.codex/config.toml` (trên Windows:
|
|
|
163
163
|
Sau khi được duyệt có thể dùng CLI thay cho merge TOML (CLI dùng timeout mặc định, thêm timeout bằng TOML nếu cần):
|
|
164
164
|
|
|
165
165
|
```powershell
|
|
166
|
-
codex mcp add antigravity --url 'http://127.0.0.1:3000/mcp'
|
|
166
|
+
codex mcp add antigravity --url 'http://127.0.0.1:3000/mcp'
|
|
167
167
|
codex mcp get antigravity
|
|
168
168
|
codex mcp list
|
|
169
169
|
codex
|
|
170
170
|
```
|
|
171
171
|
|
|
172
|
-
Khởi chạy Codex
|
|
172
|
+
Khởi chạy Codex ở terminal bất kỳ. Trong phiên mới, yêu cầu gọi `antigravity_environment`; kiểm tra phiên bản thuộc 1.4.x, đủ cờ và các cảnh báo patch. `codex mcp list/get` xác nhận cấu hình, không thay thế một tool call thật.
|
|
173
173
|
|
|
174
174
|
Ngắt kết nối: thoát phiên Codex; server và task vẫn chạy. Muốn bỏ cấu hình, sau khi duyệt chạy `codex mcp remove antigravity`, rồi mở phiên mới. Hoặc đặt `enabled=false` trong block và mở lại phiên. Server chỉ dừng khi bạn Ctrl+C tại terminal server.
|
|
175
175
|
|
|
176
|
-
Khi đổi cổng, sửa `url
|
|
176
|
+
Khi đổi cổng, sửa `url` rồi mở phiên mới. Khi server tắt, Codex báo lỗi kết nối/MCP startup. Không có tiến trình HTTP nào có thể tự trả hướng dẫn khi nó đã tắt; chạy `npm run check` để có chẩn đoán và hướng dẫn cụ thể, sau đó `npm start` ở terminal server và mở lại phiên Codex.
|
|
177
177
|
|
|
178
178
|
Tham khảo [tài liệu MCP chính thức của Codex](https://developers.openai.com/codex/mcp/).
|
|
179
179
|
|
|
@@ -186,27 +186,26 @@ Mẫu cấu hình đề xuất ở [config/claude-mcp.http.json](config/claude-m
|
|
|
186
186
|
"mcpServers": {
|
|
187
187
|
"antigravity": {
|
|
188
188
|
"type": "http",
|
|
189
|
-
"url": "http://127.0.0.1:3000/mcp"
|
|
190
|
-
"headers": {"Authorization": "Bearer ${BRIDGE_HTTP_TOKEN}"}
|
|
189
|
+
"url": "http://127.0.0.1:3000/mcp"
|
|
191
190
|
}
|
|
192
191
|
}
|
|
193
192
|
}
|
|
194
193
|
```
|
|
195
194
|
|
|
196
|
-
Sau khi duyệt, từ
|
|
195
|
+
Sau khi duyệt, từ thư mục project của bạn:
|
|
197
196
|
|
|
198
197
|
```powershell
|
|
199
|
-
claude mcp add --transport http --scope local antigravity 'http://127.0.0.1:3000/mcp'
|
|
198
|
+
claude mcp add --transport http --scope local antigravity 'http://127.0.0.1:3000/mcp'
|
|
200
199
|
claude mcp get antigravity
|
|
201
200
|
claude mcp list
|
|
202
201
|
claude
|
|
203
202
|
```
|
|
204
203
|
|
|
205
|
-
|
|
204
|
+
`--scope local` chỉ cấu hình cho project và người dùng hiện tại. Mẫu JSON wrapper dành cho `.mcp.json`; không tự tạo file đó trong repository ứng dụng.
|
|
206
205
|
|
|
207
206
|
Trong Claude Code dùng `/mcp` để xem trạng thái, reconnect hoặc disable server, và gọi `antigravity_environment` để kiểm tra tool. Nếu server tắt, `/mcp` hiển thị lỗi kết nối; chạy `npm run check`, bật server bằng `npm start`, rồi reconnect qua `/mcp` hoặc mở lại phiên. Thoát Claude Code/disable kết nối không hủy task.
|
|
208
207
|
|
|
209
|
-
Gỡ sau khi duyệt: `claude mcp remove antigravity --scope local`. Đổi cổng: cập nhật URL trong cùng entry, hoặc remove rồi add lại URL mới
|
|
208
|
+
Gỡ sau khi duyệt: `claude mcp remove antigravity --scope local`. Đổi cổng: cập nhật URL trong cùng entry, hoặc remove rồi add lại URL mới, sau đó reconnect. Không cần dừng server vì client ngắt kết nối.
|
|
210
209
|
|
|
211
210
|
Tham khảo [tài liệu MCP chính thức của Claude Code](https://code.claude.com/docs/en/mcp). Các phiên bản CLI và kết quả đã kiểm chứng được ghi trong [báo cáo khảo sát](docs/VERIFICATION.md). Sau khi cấu hình trên máy của bạn, hãy gọi tool thật từ từng client để kiểm tra kết nối; kiểm thử protocol bằng SDK không thay thế bước này.
|
|
212
211
|
|
|
@@ -235,20 +234,41 @@ Luồng sử dụng trong Codex hoặc Claude Code:
|
|
|
235
234
|
"task": "Sửa hàm parseCount trong src/count.ts để từ chối số âm. Chỉ sửa hàm này và test liên quan. Không chạy lệnh; Tech Lead tự test. Báo cáo file đã sửa và vấn đề còn lại.",
|
|
236
235
|
"workspace": "C:/absolute/path/to/approved-project",
|
|
237
236
|
"acceptance_criteria": ["Số âm trả lỗi validation hiện hành", "0 và số nguyên dương giữ hành vi cũ"],
|
|
238
|
-
"timeout_seconds": 300
|
|
237
|
+
"timeout_seconds": 300,
|
|
238
|
+
"agent": "codex",
|
|
239
|
+
"autonomy": "auto"
|
|
239
240
|
}
|
|
240
241
|
```
|
|
241
242
|
|
|
243
|
+
Task chạy song song an toàn dùng `isolation: "worktree"` và khai báo đúng các đường dẫn agent được sửa trong `owns`:
|
|
244
|
+
|
|
245
|
+
```json
|
|
246
|
+
{
|
|
247
|
+
"task": "Thêm validate cho parser và test tương ứng.",
|
|
248
|
+
"workspace": "C:/absolute/path/to/approved-project",
|
|
249
|
+
"acceptance_criteria": ["Test mới chạy qua"],
|
|
250
|
+
"agent": "codex",
|
|
251
|
+
"isolation": "worktree",
|
|
252
|
+
"owns": ["src/parser", "test/parser.test.ts"]
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
- `agent`: id lấy từ `agents_list` (`antigravity`, `codex`). Bỏ trống thì dùng agent ưu tiên đang available; agent được chỉ định nhưng không available sẽ báo lỗi, không âm thầm đổi agent.
|
|
257
|
+
- `isolation`: `none` (mặc định, sửa trực tiếp workspace, chạy tuần tự toàn cục) hoặc `worktree` (tạo branch `bridge/<task_id>` trong `.bridge-state/worktrees/<task_id>`, chạy song song tối đa `max_parallel_worktrees`). Task worktree bắt buộc có `owns`.
|
|
258
|
+
- `owns`: đường dẫn tương đối trong workspace. Sau khi agent xong, bridge so diff thực tế với danh sách này; file ngoài phạm vi được báo trong `scope.out_of_scope` và task cần review. Bridge **không tự merge** worktree.
|
|
259
|
+
- `autonomy`: `suggest` | `auto` | `full` (mặc định lấy `default_autonomy`, thường là `auto`). Đây là chỉ dẫn cho agent CLI; các hành động phá hủy, deploy, xóa dữ liệu, đọc credential và thay đổi hệ thống vẫn bị cấm tuyệt đối, không có cờ bypass permission.
|
|
260
|
+
|
|
242
261
|
| Tool | Công dụng |
|
|
243
262
|
|---|---|
|
|
244
|
-
| `antigravity_environment` | CLI/version/allowlist/giới hạn và recent_tasks để tìm lại task ID |
|
|
245
|
-
| `
|
|
263
|
+
| `antigravity_environment` | CLI/version/allowlist/giới hạn, danh sách agent, mức song song và recent_tasks để tìm lại task ID |
|
|
264
|
+
| `agents_list` | Agent đã dò được, capabilities, available/version, agent mặc định và giới hạn worktree; chỉ đọc |
|
|
265
|
+
| `antigravity_delegate` | Nhận task, workspace, acceptance_criteria, context?, timeout_seconds?, agent?, isolation?, owns?, autonomy?; trả `running` (hoặc `queued` nếu hết slot) cùng task_id |
|
|
246
266
|
| `antigravity_task_status` | Trạng thái/process/thời gian/lỗi/denied_actions/số byte theo task_id, không kèm log (rẻ để poll) |
|
|
247
267
|
| `antigravity_task_wait` | Chờ tối đa `wait_seconds` (1 đến `max_wait_seconds`, mặc định là mức tối đa, 55 giây) tới khi task kết thúc, trả cùng nội dung như status; còn chạy thì gọi lại |
|
|
248
268
|
| `antigravity_task_output` | Phản hồi cuối, stdout/stderr, lỗi, denied_actions, truncation theo task_id |
|
|
249
269
|
| `antigravity_cancel_task` | Hủy cây tiến trình thuộc task; không rollback thay đổi file |
|
|
250
270
|
|
|
251
|
-
`completed` chỉ là CLI chạy xong và có
|
|
271
|
+
`completed` chỉ là CLI chạy xong và có kết quả hợp lệ. Luôn `review_required=true`, `acceptance_verified=false`. SUCCESS/exit 0 vẫn có thể bị bridge đánh dấu failed do permission denial hoặc timeout. Prompt mẫu review/sửa tiếp: [docs/PROMPTS.md](docs/PROMPTS.md).
|
|
252
272
|
|
|
253
273
|
### Để Codex/Claude tự chia việc dễ khó và tiết kiệm token (chế độ tùy chọn)
|
|
254
274
|
|
|
@@ -265,17 +285,19 @@ Bạn kết thúc chế độ bất cứ lúc nào bằng cách bảo agent tự
|
|
|
265
285
|
|
|
266
286
|
### Khi chỉ muốn Codex/Claude tự làm
|
|
267
287
|
|
|
268
|
-
- **Công tắc cứng (khuyến nghị):** `npm run delegation -- off` chặn mọi lần giao task mới ngay lập tức, không cần restart
|
|
288
|
+
- **Công tắc cứng (khuyến nghị):** `npm run delegation -- off` chặn mọi lần giao task mới ngay lập tức, không cần restart. `npm run delegation -- on` bật lại, `-- status` xem trạng thái. Có thể đặt `BRIDGE_DELEGATION=off` trước `npm start` (giá trị khác `on`/`off` cũng bị coi là tắt). Khi tắt, `antigravity_delegate` trả lỗi nêu rõ "disabled by the bridge owner" và `antigravity_environment` trả `delegation: {enabled: false, reason}`. Task đang chạy không bị dừng và vẫn xem/hủy được.
|
|
269
289
|
- **Chỉ dẫn cho agent:** skill có mục "When NOT to delegate": agent không giao việc khi bạn bảo tự làm, khi bạn không nhắc Antigravity, hoặc khi công tắc đang tắt. Đây là chỉ dẫn, không phải rào chắn; muốn chắc chắn hãy dùng công tắc. Chạy lại `npm run skill:install` sau khi pull để cập nhật skill.
|
|
270
290
|
- Muốn tắt theo từng client: `enabled=false` trong cấu hình Codex hoặc `/mcp` trong Claude Code (xem mục 3, 4).
|
|
271
291
|
|
|
272
292
|
## 6. Vòng đời, giới hạn và dừng an toàn
|
|
273
293
|
|
|
274
|
-
TaskManager thuộc HTTP server, không thuộc phiên MCP. Server sử dụng handler stateless cho kết nối MCP; mọi request truy cập cùng TaskManager. Disconnect, DELETE session, request cancellation hoặc client thoát không tự hủy task đã tiếp nhận. Nếu mất response giao task, tra `recent_tasks` trước khi thử lại.
|
|
294
|
+
TaskManager thuộc HTTP server, không thuộc phiên MCP. Server sử dụng handler stateless cho kết nối MCP; mọi request truy cập cùng TaskManager. Disconnect, DELETE session, request cancellation hoặc client thoát không tự hủy task đã tiếp nhận. Nếu mất response giao task, tra `recent_tasks` trước khi thử lại. Mọi client kết nối tới cùng bridge đều xem/hủy được task của nhau.
|
|
275
295
|
|
|
276
|
-
**Hàng đợi:**
|
|
296
|
+
**Hàng đợi:** task `isolation: "none"` chạy tuần tự toàn cục. Task `isolation: "worktree"` chạy song song tối đa `max_parallel_worktrees` (mặc định 2, cấu hình 1–8 trong `config/workspaces.json`); hai lane không chạy chồng lên nhau (đang có task normal thì worktree xếp hàng và ngược lại). Khi bridge đang bận, tối đa `max_queued_tasks` task nữa (mặc định 3, cấu hình 0–20) được nhận với trạng thái `queued` và chạy theo thứ tự gửi. `0` trả về hành vi cũ: từ chối ngay với "busy". Task đang chờ chưa có tiến trình, chưa đụng file, có thể hủy; thời hạn (`timeout`) chỉ tính từ lúc bắt đầu chạy. Nếu công tắc giao việc bị tắt trước khi đến lượt thì task bị hủy; server dừng thì hủy hết; crash giữa chừng thì task đang chờ được nạp lại ở trạng thái `failed` ("never started").
|
|
277
297
|
|
|
278
|
-
|
|
298
|
+
Task worktree tạo branch `bridge/<task_id>` và thư mục `.bridge-state/worktrees/<task_id>` tại HEAD của repo; thay đổi chưa commit trong workspace gốc **không** được copy sang. Sau khi task kết thúc, bridge so diff với `owns`, giữ nguyên worktree và branch để Tech Lead review/merge thủ công. Bridge không tự merge, không tự xóa branch, và không chạy hook của repo khi tạo worktree. Chỉ dùng worktree cho repo đã có ít nhất một commit; workspace là thư mục con của repo vẫn được hỗ trợ.
|
|
299
|
+
|
|
300
|
+
Mặc định giữ 50 task (tối đa cấu hình 200); task cũ hoàn tất bị loại bỏ. Bản ghi task được lưu tại `.bridge-state/tasks/<task_id>.json` (mode 0600 trên POSIX; nội dung đã qua lọc secret) và nạp lại khi khởi động, nên tra được kết quả sau restart. Task đang chạy lúc server dừng đột ngột được nạp lại với trạng thái `failed` ("Bridge restarted…"): tiến trình agent không được khôi phục, hãy kiểm tra diff dở dang. Đây là lịch sử kết quả, không phải durable task recovery. Task vẫn timeout nếu không có client theo dõi. Lane normal giữ khóa giữa các process dùng cùng bản cài tại `.bridge-state/execution.lock`; lane worktree dựa vào branch riêng và không dùng khóa này.
|
|
279
301
|
|
|
280
302
|
Nhấn **Ctrl+C một lần** tại terminal server:
|
|
281
303
|
|
|
@@ -286,11 +308,13 @@ Nhấn **Ctrl+C một lần** tại terminal server:
|
|
|
286
308
|
|
|
287
309
|
Nếu cleanup thất bại, báo lỗi và giữ execution lock khi process chưa đóng. Khi khởi động hoặc lấy lock, bridge chỉ tự thu hồi nếu đọc được owner hợp lệ, cả `server_pid` lẫn `child_pid` đều đã chết và record khớp lock. Lệnh `agy-mcp-bridge unlock` dùng cùng kiểm tra; PID còn sống, thiếu thông tin hoặc quyền sở hữu không rõ thì giữ lock và in lý do. Bridge không kill process Antigravity khác. PID có thể được tái sử dụng nên trường hợp không rõ cần kiểm tra thủ công. Force kill/OS crash vẫn không bảo đảm cleanup: chưa có Windows Job Object. POSIX gửi SIGTERM cho nhóm process, chờ tối đa 8 giây rồi SIGKILL; Windows giữ taskkill cây PID. Ctrl+C tiếp trong lúc cleanup chỉ báo `cleanup in progress, please wait`.
|
|
288
310
|
|
|
289
|
-
Giới hạn mặc định: CLI task 300s, tối đa 900s; watchdog của bridge cộng thêm 10s để CLI tự báo timeout trước. Chủ máy nâng mức tối đa (và mặc định) lên tới 3600s bằng `max_timeout_seconds` / `default_timeout_seconds` trong file cấu hình (khởi động lại bridge); mỗi task đặt `timeout_seconds` riêng, không vượt mức tối đa đó. Task hết thời hạn không bị hoàn tác: file đã sửa trước đó vẫn nằm trên đĩa (xem "Thay đổi trong workspace" hoặc `git diff`), trạng thái là `timeout`, và skill dặn Codex/Claude giao task mới hẹp hơn cho phần còn lại thay vì gửi lại y nguyên. Task lớn nên chia nhỏ hơn là chỉ tăng thời hạn. Output mỗi stream 256 KiB (cấu hình 1 KiB–1 MiB), vượt trần sẽ hủy task và trả failed/truncated. Tổng task JSON vẫn tối đa 24000 ký tự; HTTP body tối đa 128 KiB. Prompt mặc định đi qua argv với print/json (`prompt_transport: "argv"`, đường đã chạy thật với `agy` 1.4.3). Đặt `prompt_transport: "stdin"` để gửi qua stdin stream-json, không lộ prompt trong danh sách tiến trình; chế độ này chưa được chạy thử với `agy` thật, và stream gồm cả init/progress nên có thể chạm output cap sớm hơn. Snapshot log được cập nhật tối đa mỗi giây và flush khi kết thúc. Không dùng CLI detach/remote-control API chưa được xác minh.
|
|
311
|
+
Giới hạn mặc định: CLI task 300s, tối đa 900s; watchdog của bridge cộng thêm 10s để CLI tự báo timeout trước. Chủ máy nâng mức tối đa (và mặc định) lên tới 3600s bằng `max_timeout_seconds` / `default_timeout_seconds` trong file cấu hình (khởi động lại bridge); mỗi task đặt `timeout_seconds` riêng, không vượt mức tối đa đó. Task hết thời hạn không bị hoàn tác: file đã sửa trước đó vẫn nằm trên đĩa (xem "Thay đổi trong workspace" hoặc `git diff`), trạng thái là `timeout`, và skill dặn Codex/Claude giao task mới hẹp hơn cho phần còn lại thay vì gửi lại y nguyên. Task lớn nên chia nhỏ hơn là chỉ tăng thời hạn. Output mỗi stream 256 KiB (cấu hình 1 KiB–1 MiB), vượt trần sẽ hủy task và trả failed/truncated. Tổng task JSON vẫn tối đa 24000 ký tự; HTTP body tối đa 128 KiB. Prompt mặc định đi qua argv với print/json (`prompt_transport: "argv"`, đường đã chạy thật với `agy` 1.4.3 và 1.4.7). Đặt `prompt_transport: "stdin"` để gửi qua stdin stream-json, không lộ prompt trong danh sách tiến trình; chế độ này chưa được chạy thử với `agy` thật, và stream gồm cả init/progress nên có thể chạm output cap sớm hơn. Snapshot log được cập nhật tối đa mỗi giây và flush khi kết thúc. Không dùng CLI detach/remote-control API chưa được xác minh.
|
|
290
312
|
|
|
291
313
|
## 7. Bảo mật và vận hành
|
|
292
314
|
|
|
293
|
-
Chỉ listen `127.0.0.1`, không có tùy chọn bind LAN trong bản này. Host phải đúng địa chỉ/cổng thực tế; Origin khác bị từ chối; không bật CORS cho website ngoài.
|
|
315
|
+
Chỉ listen `127.0.0.1`, không có tùy chọn bind LAN trong bản này. Host phải đúng địa chỉ/cổng thực tế; Origin khác bị từ chối; không bật CORS cho website ngoài. **Không có xác thực**: mọi tiến trình cục bộ cùng user đều có thể gọi tool, đọc task, điều khiển agent và tắt server. Đây là mô hình tin cậy cục bộ có chủ đích; không mở cổng, không đặt sau proxy công khai. Không log HTTP headers/body.
|
|
316
|
+
|
|
317
|
+
Cách ly worktree là ranh giới **quy trình**, không phải sandbox OS: agent vẫn chạy dưới quyền user hiện tại. Bridge tạo worktree trong `.bridge-state/worktrees` với `core.hooksPath` rỗng, so diff sau khi chạy và báo `scope.out_of_scope`; file ngoài `owns` không bao giờ được tự merge. Codex chạy với `--sandbox workspace-write`; các hành động cần approval vẫn thất bại thay vì được bypass. Không dùng `--dangerously-*`, `--yolo` hoặc bất kỳ cờ bỏ qua permission nào. Deploy, publish, xóa dữ liệu, push nhánh bảo vệ, đọc credential và thay đổi hệ thống ngoài workspace là hành động bị cấm tuyệt đối, không phụ thuộc `autonomy`.
|
|
294
318
|
|
|
295
319
|
Allowlist kiểm tra realpath, boundary, traversal; link/junction trong thành phần đường dẫn đầu vào vẫn bị từ chối. Trong cây, link phải resolve được vào cùng workspace; không theo alias/cycle. Quét bỏ qua nội dung thư mục `node_modules` và `.git`; trần 200000 chỉ tính các entry còn lại. Task từ queue được kiểm tra lại trước launch. **Đây không phải OS sandbox**: đặc biệt nội dung hai thư mục được bỏ qua không được kiểm tra, và tiến trình khác vẫn có thể đổi link sau preflight. Quyền agent/hooks/MCP và file ngoài workspace vẫn cần kiểm soát OS/CLI phù hợp. Lọc output không nhận ra mọi bí mật; không đưa secret vào task.
|
|
296
320
|
|
|
@@ -299,10 +323,12 @@ Allowlist kiểm tra realpath, boundary, traversal; link/junction trong thành p
|
|
|
299
323
|
Các lỗi thường gặp:
|
|
300
324
|
|
|
301
325
|
- `Port is already in use`: chọn PORT khác, cập nhật URL cả hai client.
|
|
302
|
-
- 401: token thiếu/sai; nạp lại env rồi khởi động lại client. Không thử OAuth login với bridge này.
|
|
303
326
|
- 403: sai Host/Origin; dùng đúng URL 127.0.0.1 được in ra, không đi qua proxy/alias.
|
|
304
327
|
- Connection refused/fetch failed: server tắt hoặc sai cổng; chạy check, bật lại server và reconnect.
|
|
305
328
|
- CLI unsupported: kiểm tra agy path/version/help; environment vẫn có thể hoạt động dù không giao được task.
|
|
329
|
+
- Agent unavailable: gọi `agents_list`; kiểm tra `codex --version` và `codex exec --help`, hoặc tên/`agents.enabled` trong cấu hình.
|
|
330
|
+
- Worktree bị từ chối: workspace phải là git repo có ít nhất một commit; `owns` phải là đường dẫn tương đối, không chứa `..`.
|
|
331
|
+
- `scope.out_of_scope` khác rỗng: agent sửa file ngoài phạm vi; review worktree, không merge tự động.
|
|
306
332
|
- `denied_actions`: Antigravity chưa cho phép thao tác; xin quyền tối thiểu, không bỏ permission check.
|
|
307
333
|
- Workspace bị từ chối: kiểm tra allowlist, link/junction hoặc số entry vượt trần.
|
|
308
334
|
- Timeout/canceled/output limit: có thể có diff dở dang; review trước khi giao task tiếp theo.
|
|
@@ -314,11 +340,11 @@ npm test
|
|
|
314
340
|
npm run test:live
|
|
315
341
|
```
|
|
316
342
|
|
|
317
|
-
`npm test` (cũng chạy trong [CI](.github/workflows/ci.yml) trên Ubuntu và Windows, Node 20/22): unit/integration dùng executable giả, không gọi AI. Bao gồm lifecycle/security cũ và HTTP startup/port conflict/PORT tùy chọn/
|
|
343
|
+
`npm test` (cũng chạy trong [CI](.github/workflows/ci.yml) trên Ubuntu và Windows, Node 20/22): unit/integration dùng executable giả, không gọi AI. Bao gồm lifecycle/security cũ và HTTP startup/port conflict/PORT tùy chọn/Host/Origin/body limit/kết nối hai protocol era/client reconnect/task completion/cancel/server shutdown.
|
|
318
344
|
|
|
319
345
|
`test:live`: **gọi AI thật**, dùng cached login/quota. Test harness khởi động HTTP server riêng với PORT=0 và scratch workspace, dùng official SDK HTTP client, ngắt/kết nối lại khi task chạy, xác minh `BRIDGE_SMOKE_OK` và sentinel không đổi, hủy task thật, rồi kiểm tra shutdown có task đang chạy. Trên Windows, harness phát event SIGINT vào đúng handler của entry point qua IPC riêng của harness; kiểm tra Ctrl+C terminal được ghi riêng trong báo cáo. Đây không phải yêu cầu client production tự khởi động server. Kết quả ở `test-results/live-report.json`; phần sửa file thật vẫn bị chặn đến khi cấp quyền.
|
|
320
346
|
|
|
321
|
-
`src/index.ts`: HTTP entry; `src/http.ts`: listener/
|
|
347
|
+
`src/index.ts`: HTTP entry; `src/http.ts`: listener/routing/shutdown; `src/runtime.ts`: CLI và TaskManager dùng chung; `src/agents`: adapter Antigravity/Codex, registry và contract; `src/isolation`: tạo worktree và kiểm tra phạm vi `owns`; `src/tools`: tool; `src/antigravity`: child process; `src/security`: validation/workspace/redaction; `src/tasks`: lifecycle/lock/output; `scripts/check.ts`: kiểm tra server đang chạy; `scripts/live.ts`: AI smoke test. Không thay cấu hình Codex/Claude Code/Antigravity trong test.
|
|
322
348
|
|
|
323
349
|
## 9. Skill giao tiếp với Antigravity
|
|
324
350
|
|
|
@@ -346,7 +372,7 @@ npm run skill:install -- --client both
|
|
|
346
372
|
npm run skill:install -- --client both --project 'C:\path\to\your-project'
|
|
347
373
|
```
|
|
348
374
|
|
|
349
|
-
Installer chỉ ghi `SKILL.md`, không sửa config MCP, allowlist,
|
|
375
|
+
Installer chỉ ghi `SKILL.md`, không sửa config MCP, allowlist, AGENTS.md/CLAUDE.md hay settings Antigravity. Nội dung giống nhau thì không ghi lại (khác nhau kiểu xuống dòng CRLF/LF không tính là khác). Khi file đã cài khác nội dung, bridge phân biệt hai trường hợp bằng danh sách hash `skills/known-versions.json` (sha256 của mọi bản `SKILL.md` đã phát hành):
|
|
350
376
|
- **Bản cũ do gói này phát hành** (khớp một hash trong danh sách): `skill install` báo cần `--update`; chạy `agy-mcp-bridge skill install --client both --update` (hoặc `npm run skill:install -- --client both --update`) sẽ thay bằng bản mới, ghi nguyên tử qua file tạm. Khi chạy server lần đầu sau khi có skill mới, bridge cũng hỏi `Update them now? [y / N]` đúng một lần cho mỗi bản skill mới (không hỏi lại nếu bạn trả lời không, cho tới khi có bản mới hơn).
|
|
351
377
|
- **Bản bạn tự sửa** (không khớp bản nào): không bao giờ bị ghi đè hay xóa, kể cả khi có `--update`; lệnh báo lỗi để bạn tự review/gộp.
|
|
352
378
|
|
|
@@ -374,16 +400,16 @@ Vị trí và cách gọi đã đối chiếu [Codex skills](https://developers.
|
|
|
374
400
|
|
|
375
401
|
Khi `npm start` đang chạy, mở `http://127.0.0.1:3000/ui` (đúng cổng đã in ở terminal) trên cùng máy. Giao diện chỉ chạy trong server của bridge, **không đi qua Codex/Claude nên không tốn thêm token của chúng**, và không thêm tool MCP nào.
|
|
376
402
|
|
|
377
|
-
|
|
403
|
+
Không cần đăng nhập: giao diện mở trực tiếp vì bridge không có xác thực. Trang chỉ dùng được từ loopback và bị chặn nếu `Host`/`Origin` không khớp. Đóng tab chỉ đóng giao diện, không dừng server; dùng nút **Tắt bridge** trong Cài đặt để dừng server và dọn tiến trình.
|
|
378
404
|
|
|
379
405
|
| Màn hình | Nội dung |
|
|
380
406
|
|---|---|
|
|
381
|
-
| Task | Tổng quan (trạng thái bridge,
|
|
382
|
-
| Cài đặt | Công tắc giao việc
|
|
407
|
+
| Task | Tổng quan (trạng thái bridge, agent sẵn sàng, công tắc giao việc, số task đang chạy, mức song song); danh sách task; với mỗi task là cuộc trao đổi **Tech Lead → agent** (yêu cầu, tiêu chí nghiệm thu, ngữ cảnh, agent/cách ly/quyền tự duyệt) và **agent → Tech Lead** (phản hồi cuối, thao tác bị từ chối quyền, lỗi), log stdout/stderr, prompt đầy đủ, worktree/branch và kết quả kiểm tra `owns`. Tên client đã giao (từ `clientInfo` của MCP, hoặc User-Agent nếu client dùng giao thức cũ; có thể trống hoặc chỉ là `node`), trạng thái hàng đợi, lọc theo trạng thái và tìm kiếm. Cập nhật từng vùng nên bôi đen log/văn bản vẫn giữ nguyên khi task đang chạy; nút Hủy task cho task đang chạy hoặc đang chờ |
|
|
408
|
+
| Cài đặt | Công tắc giao việc (cùng cơ chế với `npm run delegation`, bị khóa nếu đặt `BRIDGE_DELEGATION`), endpoint MCP, thông tin từng agent, workspace được phép, giới hạn song song, lưu ý. Workspace, agent và giới hạn chỉ đọc: sửa trong `config/workspaces.json` rồi khởi động lại. Nút **Tắt bridge** dừng HTTP server, hủy task đang chạy hoặc đang chờ và dọn các tiến trình agent do bridge khởi tạo |
|
|
383
409
|
|
|
384
410
|
**Thay đổi trong workspace:** mỗi task có mục "Thay đổi trong workspace" (mở ra mới đọc, có nút Làm mới) liệt kê file đã sửa, xóa, file mới chưa theo dõi và số dòng thêm/xóa so với commit HEAD, kể cả thay đổi có từ trước khi task chạy. Chỉ hiện tên file và số dòng, không hiện nội dung, và chỉ cho workspace vẫn còn trong danh sách được phép. Để đọc an toàn, bridge **không bao giờ nạp cấu hình của repo**: `git status`/`git diff` thông thường chạy cả những lệnh do chính repo khai báo (`core.fsmonitor`, `filter.*.clean`, `diff.*.textconv`), mà Antigravity có quyền ghi file nên có thể cài sẵn vào `.git/config`; chỉ tắt trình diff ngoài là chưa đủ (đã thử: lệnh `filter clean` vẫn chạy). Thay vào đó bridge so sánh trong một thư mục git tạm với cấu hình rỗng, chỉ mượn kho đối tượng của repo, tắt cấu hình hệ thống/người dùng, và chỉ sao chép vài thiết lập xuống dòng/quyền file đã kiểm tra giá trị (`core.autocrlf`, `eol`, `filemode`, `symlinks`, `ignorecase`). Có test dựng repo "nhiễm độc" để chứng minh không lệnh nào bị chạy. Giới hạn: cần `git` trong PATH, chỉ tính khác biệt nội dung (file chỉ khác kiểu xuống dòng sau chuyển đổi không tính), tối đa 500 mục mỗi nhóm, không hiện submodule, và không thay thế việc tự xem diff đầy đủ.
|
|
385
411
|
|
|
386
|
-
Lưu ý bảo mật: nội dung yêu cầu và phản hồi được hiển thị dạng văn bản thuần, trang dùng CSP không cho script/style nội tuyến hay tải từ nơi khác, nên output của model không thể thực thi. Yêu cầu của Tech Lead được lưu cùng bản ghi task trong `.bridge-state/tasks` (đã qua lọc secret nhận diện được) để xem lại sau khi restart; đừng đưa secret vào task. Giao diện chỉ đọc, ngoại trừ các thao tác
|
|
412
|
+
Lưu ý bảo mật: nội dung yêu cầu và phản hồi được hiển thị dạng văn bản thuần, trang dùng CSP không cho script/style nội tuyến hay tải từ nơi khác, nên output của model không thể thực thi. Yêu cầu của Tech Lead được lưu cùng bản ghi task trong `.bridge-state/tasks` (đã qua lọc secret nhận diện được) để xem lại sau khi restart; đừng đưa secret vào task. Giao diện chỉ đọc, ngoại trừ các thao tác của chủ máy: hủy task, bật/tắt giao việc, tắt bridge và những mục trong Cài đặt. Mã nguồn giao diện nằm ở `ui/` (HTML/CSS/JS thuần, không cần build), phần máy chủ ở `src/ui/`.
|
|
387
413
|
|
|
388
414
|
**Chọn model:** mục Cài đặt → Model liệt kê các model lấy từ `agy models` (chỉ chạy khi mở trang Cài đặt). Chọn một model thì bridge truyền `--model <id>` cho mọi task mới; chọn "Mặc định của Antigravity" thì không truyền cờ nào. Có hiệu lực ngay, không cần khởi động lại; task đang chạy hoặc đang chờ giữ model đã chốt lúc nhận, và mỗi task ghi lại model đã dùng (hiện trong chi tiết task). Chỉ nhận id nằm trong danh sách của `agy models`; nếu không đọc được danh sách thì không cho đổi. Lựa chọn lưu ở `.bridge-state/model.json`. Codex/Claude không chọn được model theo từng task (không thêm tham số vào tool MCP nên không tốn thêm token).
|
|
389
415
|
|
|
@@ -395,7 +421,7 @@ Lưu ý bảo mật: nội dung yêu cầu và phản hồi được hiển th
|
|
|
395
421
|
|
|
396
422
|
1. **Thời gian chờ mỗi lần gọi** chỉnh trong giao diện web (Cài đặt → "Thời gian chờ mỗi lần Codex / Claude gọi"): 55 giây (mặc định), 5, 10, 15, 30 hoặc 60 phút; có hiệu lực ngay, không cần khởi động lại. Cũng đặt được bằng `max_wait_seconds` trong file cấu hình (lựa chọn trong giao diện được ưu tiên). Mức đang dùng được báo cho client qua `max_wait_seconds` của `antigravity_environment`.
|
|
397
423
|
2. **Thời hạn tool của client phải lớn hơn thời gian chờ**, nếu không client cắt lần chờ và báo timeout. Codex: đặt `tool_timeout_sec` trong `config.toml` ở mục `[mcp_servers.antigravity]`, bằng thời gian chờ cộng thêm khoảng 60 giây (ví dụ chờ 600 giây thì `tool_timeout_sec = 660`), rồi mở lại Codex. Lệnh `agy-mcp-bridge setup codex` in sẵn dòng này theo mức đang chọn; giao diện cũng hiện đúng giá trị cần đặt. Claude Code: biến môi trường `MCP_TOOL_TIMEOUT` tính bằng mili giây, theo tài liệu của Claude Code (chưa kiểm chứng ở đây). Nếu chưa chắc về thời hạn tool của client, giữ mặc định 55 giây.
|
|
398
|
-
3. **Skill dặn agent chỉ chờ:** trong lúc task chạy, agent chỉ gọi `antigravity_task_wait`, không đọc file, không chạy git, test hay đọc log, không tự review cùng thay đổi và không viết gì giữa các lần chờ; chỉ khi task kết thúc mới lấy `antigravity_task_output` một lần rồi review. Mỗi lần chờ mà task còn chạy trả kèm ghi chú `next_step` nhắc đúng điều đó ngay lúc agent quyết định bước tiếp theo. Skill cũng cấm agent tự viết script hay client HTTP để gọi bridge: nếu phiên không có các tool `antigravity_*`, agent báo cho bạn (nguyên nhân thường là
|
|
424
|
+
3. **Skill dặn agent chỉ chờ:** trong lúc task chạy, agent chỉ gọi `antigravity_task_wait`, không đọc file, không chạy git, test hay đọc log, không tự review cùng thay đổi và không viết gì giữa các lần chờ; chỉ khi task kết thúc mới lấy `antigravity_task_output` một lần rồi review. Mỗi lần chờ mà task còn chạy trả kèm ghi chú `next_step` nhắc đúng điều đó ngay lúc agent quyết định bước tiếp theo. Skill cũng cấm agent tự viết script hay client HTTP để gọi bridge: nếu phiên không có các tool `antigravity_*`, agent báo cho bạn (nguyên nhân thường là bridge chưa chạy hoặc client chưa trỏ đúng endpoint) rồi dừng.
|
|
399
425
|
|
|
400
426
|
Đây là chỉ dẫn, không phải rào chắn kỹ thuật: bridge không ép được mô hình ngừng đọc file trong lúc chờ. Mức tiết kiệm thực tế chưa được đo.
|
|
401
427
|
|
|
@@ -413,6 +439,10 @@ Lưu ý bảo mật: nội dung yêu cầu và phản hồi được hiển th
|
|
|
413
439
|
|
|
414
440
|
**Nhịp tim khi chờ (thử nghiệm):** nếu client gửi kèm `progressToken` (chuẩn MCP), `antigravity_task_wait` gửi một thông báo tiến độ mỗi 10 giây trong lúc giữ lệnh (nội dung là dòng `activity`). Client nào đặt lại đồng hồ timeout khi nhận tiến độ thì có thể chờ lâu hơn `tool_timeout_sec`; client không làm vậy thì bỏ qua và mọi thứ chạy như cũ. **Chưa biết Codex / Claude Code có đặt lại timeout theo tiến độ hay không**: cách thử là để `tool_timeout_sec` ở mức mặc định (60), đặt thời gian chờ 300 giây trong Cài đặt, giao một task chạy quá 1 phút và xem lệnh chờ có bị báo timeout không. Nếu vẫn timeout thì cần đặt `tool_timeout_sec` như trước. Không có token thì không gửi gì.
|
|
415
441
|
|
|
442
|
+
**Ghi cấu hình Codex bằng một lệnh:** `agy-mcp-bridge setup codex --apply` hiện đúng thay đổi sẽ ghi vào `~/.codex/config.toml` (hoặc `$CODEX_HOME/config.toml`), hỏi xác nhận (`--yes` để bỏ qua câu hỏi), sao lưu file cũ thành `config.toml.bak-<thời gian>` rồi mới ghi. Nếu mục `[mcp_servers.antigravity]` đã có thì chỉ đổi dòng `tool_timeout_sec` (mặc định **3700** giây, lớn hơn mức chờ tối đa 60 phút của giao diện nên đổi mức chờ không cần chạy lại; đổi bằng `--tool-timeout N`); nếu chưa có thì thêm cả mục. Kiểu viết nó không đọc chắc chắn được (inline table, khóa trong ngoặc kép, hai mục trùng) thì lệnh từ chối và bạn sửa tay. File CRLF giữ nguyên CRLF. Claude Code không bị sửa. Sau khi ghi, mở lại Codex.
|
|
443
|
+
|
|
444
|
+
**Kết quả "đang chạy" gọn hơn:** khi task còn chạy, `antigravity_task_wait`/`status` chỉ trả `task_id`, `status`, `duration_ms`, `activity` và `next_step` (ngắn). Đường dẫn, số byte, pid... xem ở giao diện web hoặc trong trạng thái đầy đủ khi task đã kết thúc. Mỗi lần Codex hỏi lại vì thế tốn ít token hơn.
|
|
445
|
+
|
|
416
446
|
- **Đây là mức dùng qua bridge, không phải hạn mức.** `agy` không có lệnh xem hạn mức còn lại và bridge không bịa ra con số đó; xem hạn mức trên tài khoản Antigravity của bạn.
|
|
417
447
|
- Bridge **không biết trước** các trường bên trong `usage` (tên trường do `agy` quyết định): nó cộng mọi giá trị số; một vài tên phổ biến (`input_tokens`, `output_tokens`, `total_tokens`...) được dịch nhãn. Task nào kết quả không có `usage` thì ghi nhận là "không có", không phải 0.
|
|
418
448
|
- Chỉ thống kê task bắt đầu từ bản có tính năng này trở đi. Số liệu usage không được gửi cho Codex/Claude (không tốn token).
|
|
@@ -438,13 +468,15 @@ Lưu ý bảo mật: nội dung yêu cầu và phản hồi được hiển th
|
|
|
438
468
|
| Tự động | `--mode auto` | Chế độ tự động của Antigravity |
|
|
439
469
|
| Toàn quyền | `--dangerously-skip-permissions` | Duyệt mọi yêu cầu, gồm chạy lệnh và truy cập ngoài thư mục dự án |
|
|
440
470
|
|
|
441
|
-
Chỉ chủ máy đổi được, qua giao diện web
|
|
471
|
+
Chỉ chủ máy đổi được, qua giao diện web; Codex/Claude không có tool nào để đổi. Mức `Tự động` và `Toàn quyền` yêu cầu xác nhận; khi đang bật, giao diện hiện dải cảnh báo, `antigravity_environment` báo `agy_permissions` để Codex/Claude biết và nói với bạn, và chi tiết mỗi task ghi mức quyền đã dùng. Có hiệu lực ngay, không cần khởi động lại. Hạ mức xuống thì áp dụng cả cho task đang xếp hàng; nâng lên thì không (task giữ mức lúc được nhận). Biến `BRIDGE_AGY_PERMISSIONS=default|plan|accept-edits|auto|full` đặt cố định và khóa giao diện (giá trị sai thì dùng `default`). Lựa chọn lưu ở `.bridge-state/permissions.json`.
|
|
442
472
|
|
|
443
473
|
**Cảnh báo:** danh sách "Workspace được phép" chỉ kiểm tra đường dẫn của task, không phải sandbox; với `Tự động` hay `Toàn quyền`, Antigravity có thể tác động ra ngoài thư mục đó (xóa file, chạy lệnh, dùng thông tin đăng nhập đã lưu). Chỉ bật khi bạn tin tưởng tác vụ, dự án đã được git theo dõi hoặc sao lưu. Các cờ `--mode` chưa được kiểm chứng với `agy` thật qua chế độ `--print`.
|
|
444
474
|
|
|
445
475
|
## 11. Ghi chú thiết kế và việc chưa làm
|
|
446
476
|
|
|
477
|
+
- **Nhiều agent:** Phase 1 đã có adapter Antigravity + Codex, chọn agent theo `agents.priority`/`agents.enabled`, worktree song song, kiểm tra `owns`, `agents_list` và `autonomy`. Chưa có daemon mission/orchestrator tự chạy dài hạn, adapter OpenCode/Qoder/Zcode, UI auto-approve riêng hay merge tự động. Xem lộ trình và quyết định trong [docs/MULTI-AGENT-PLAN.md](docs/MULTI-AGENT-PLAN.md).
|
|
447
478
|
- **Tiến độ thật của task:** stdin stream-json hiện đã được xác minh ở đường kiểm tra lỗi không gọi AI, và parser lấy terminal `result` theo tài liệu chính thức. Luồng thành công đang được test bằng mock; chưa thực thi AI thật trong đợt hardening. UI hiện hiển thị log snapshot, chưa diễn giải từng `step_update` thành phần trăm tiến độ. Trong lúc task chạy, trang chi tiết có thanh thời gian đã chạy so với giới hạn, thời điểm `agy` ghi output gần nhất, và danh sách thay đổi trong workspace tự làm mới mỗi vài giây khi mở mục "Thay đổi trong workspace" (các tín hiệu này không phụ thuộc định dạng output của `agy`; ở chế độ print/json `agy` chỉ in khi xong nên dòng output có thể trống).
|
|
448
479
|
- **`outputSchema` cho tool MCP:** đã thử và bỏ. Schema đầy đủ làm danh sách tool tăng từ khoảng 3,9 KB lên 12,1 KB; nếu client đưa vào ngữ cảnh của agent thì tốn thêm token ở mỗi lượt, trái với mục tiêu giữ chi phí thấp.
|
|
449
480
|
- **Đánh giá hành vi của skill:** xem [docs/SKILL-EVAL.md](docs/SKILL-EVAL.md): bộ tình huống và tiêu chí chấm để chạy thủ công với Codex/Claude Code; chưa được chạy tự động.
|
|
450
481
|
- **Dọn tiến trình khi crash trên Windows:** xem mục 6; mới có cảnh báo, chưa có bảo đảm.
|
|
482
|
+
|
|
@@ -7,5 +7,11 @@
|
|
|
7
7
|
"default_timeout_seconds": 300,
|
|
8
8
|
"max_output_bytes": 262144,
|
|
9
9
|
"max_retained_tasks": 50,
|
|
10
|
-
"max_queued_tasks": 3
|
|
10
|
+
"max_queued_tasks": 3,
|
|
11
|
+
"max_parallel_worktrees": 2,
|
|
12
|
+
"default_autonomy": "auto",
|
|
13
|
+
"agents": {
|
|
14
|
+
"priority": ["antigravity", "codex"],
|
|
15
|
+
"enabled": ["antigravity", "codex"]
|
|
16
|
+
}
|
|
11
17
|
}
|
package/dist/scripts/check.js
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import { Client } from '@modelcontextprotocol/client';
|
|
2
2
|
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/client';
|
|
3
|
-
import { readFile } from 'node:fs/promises';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import { paths } from '../src/paths.js';
|
|
6
3
|
const endpoint = process.env.BRIDGE_MCP_URL ?? `http://127.0.0.1:${process.env.PORT ?? '3000'}/mcp`;
|
|
7
4
|
const client = new Client({ name: 'bridge-check', version: '0.1.0' });
|
|
8
5
|
try {
|
|
9
|
-
const
|
|
10
|
-
const transport = new StreamableHTTPClientTransport(new URL(endpoint), { requestInit: { headers: { Authorization: `Bearer ${token}` }, signal: AbortSignal.timeout(5000) } });
|
|
6
|
+
const transport = new StreamableHTTPClientTransport(new URL(endpoint), { requestInit: { signal: AbortSignal.timeout(5000) } });
|
|
11
7
|
await client.connect(transport);
|
|
12
8
|
const result = await client.callTool({ name: 'antigravity_environment', arguments: {} });
|
|
13
9
|
if (result.isError)
|
|
@@ -15,7 +11,7 @@ try {
|
|
|
15
11
|
console.log(JSON.stringify(result.structuredContent, null, 2));
|
|
16
12
|
}
|
|
17
13
|
catch {
|
|
18
|
-
console.error(`[bridge-check] Cannot connect to ${endpoint}. Start the server (npm start, or agy-mcp-bridge when installed from npm); check URL/PORT
|
|
14
|
+
console.error(`[bridge-check] Cannot connect to ${endpoint}. Start the server (npm start, or agy-mcp-bridge when installed from npm); check the URL/PORT, then reconnect.`);
|
|
19
15
|
process.exitCode = 1;
|
|
20
16
|
}
|
|
21
17
|
finally {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { paths } from '../src/paths.js';
|
|
2
2
|
import { delegationState, setDelegationSwitch } from '../src/delegation.js';
|
|
3
|
-
// Local, immediate switch for whether the running bridge accepts new delegations. No restart
|
|
3
|
+
// Local, immediate switch for whether the running bridge accepts new delegations. No restart needed.
|
|
4
4
|
const stateDirectory = paths.stateDirectory;
|
|
5
5
|
const command = process.argv[2];
|
|
6
6
|
if (command === 'off')
|
|
@@ -2,14 +2,14 @@ import { mkdir, mkdtemp, writeFile } from 'node:fs/promises';
|
|
|
2
2
|
import { tmpdir } from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { paths } from '../src/paths.js';
|
|
5
|
-
import {
|
|
5
|
+
import { resolveCommand, startProcess, terminateOwned } from '../src/antigravity/process.js';
|
|
6
6
|
import { loadConfig } from '../src/config.js';
|
|
7
7
|
// Captures what `agy --output-format stream-json` really emits so progress reporting can be built on the real format.
|
|
8
8
|
// It makes one tiny real AI call (cached login, no tools, scratch directory) and only writes under test-results/.
|
|
9
9
|
const config = await loadConfig();
|
|
10
|
-
const
|
|
10
|
+
const command = await resolveCommand(config.executable);
|
|
11
11
|
const workspace = await mkdtemp(path.join(tmpdir(), 'agy-stream-probe-'));
|
|
12
|
-
const child = startProcess(executable, ['--print', 'Reply with exactly STREAM_PROBE_OK. Do not use any tools, read files, change files or run commands.',
|
|
12
|
+
const child = startProcess(command.executable, [...command.prefixArgs, '--print', 'Reply with exactly STREAM_PROBE_OK. Do not use any tools, read files, change files or run commands.',
|
|
13
13
|
'--output-format', 'stream-json', '--print-timeout', '90s', '--disable-slash-commands'], workspace);
|
|
14
14
|
let stdout = '';
|
|
15
15
|
let stderr = '';
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { finalEnvelope, invocationFor } from '../antigravity/invocation.js';
|
|
2
|
+
import { extractStats } from '../usage.js';
|
|
3
|
+
const CAPABILITIES = ['code', 'review', 'test', 'research', 'long-run'];
|
|
4
|
+
export function antigravityAdapter(executable, defaultTransport) {
|
|
5
|
+
return {
|
|
6
|
+
id: 'antigravity',
|
|
7
|
+
label: 'Antigravity',
|
|
8
|
+
capabilities: CAPABILITIES,
|
|
9
|
+
buildInvocation(task) {
|
|
10
|
+
const transport = task.promptTransport ?? defaultTransport;
|
|
11
|
+
const invocation = invocationFor(task.prompt, task.timeoutSeconds, transport, task.model ?? null, task.extraArgs ?? []);
|
|
12
|
+
return { executable, args: invocation.args, stdin: invocation.stdin, transport };
|
|
13
|
+
},
|
|
14
|
+
async parseResult(raw) {
|
|
15
|
+
const transport = raw.transport ?? defaultTransport;
|
|
16
|
+
let envelope;
|
|
17
|
+
try {
|
|
18
|
+
envelope = finalEnvelope(raw.stdout, transport);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
throw new Error(transport === 'stdin'
|
|
22
|
+
? 'CLI output is not a valid stream-json final result. If this happens with a real agy, set "prompt_transport": "argv" in the bridge config (the previously verified mode) and restart'
|
|
23
|
+
: transport === 'argv-stream'
|
|
24
|
+
? 'CLI output is not a valid stream-json final result. Turn off step progress in the web UI Settings to return to the verified JSON mode'
|
|
25
|
+
: 'CLI output is not a valid final JSON envelope');
|
|
26
|
+
}
|
|
27
|
+
const response = typeof envelope.response === 'string' ? envelope.response : null;
|
|
28
|
+
const deniedActions = Array.isArray(envelope.denied_actions)
|
|
29
|
+
? envelope.denied_actions.slice(0, 100).map((item) => {
|
|
30
|
+
const value = item;
|
|
31
|
+
return { action: String(value?.action ?? 'unknown').slice(0, 200), display_name: String(value?.display_name ?? '').slice(0, 200) };
|
|
32
|
+
})
|
|
33
|
+
: [];
|
|
34
|
+
const numTurns = typeof envelope.num_turns === 'number' ? envelope.num_turns : null;
|
|
35
|
+
const result = {
|
|
36
|
+
success: false, response, error: null,
|
|
37
|
+
cliStatus: typeof envelope.status === 'string' ? envelope.status : null,
|
|
38
|
+
numTurns, deniedActions, stats: extractStats(envelope, null)
|
|
39
|
+
};
|
|
40
|
+
if (/print timeout|AGY_ERROR.*TIMEOUT/i.test(raw.stderr)) {
|
|
41
|
+
return { ...result, timeout: true, error: 'CLI reported a print timeout (possibly with exit code 0)' };
|
|
42
|
+
}
|
|
43
|
+
if (deniedActions.length || /auto-denied|soft.denied|permission.*cannot prompt/i.test(raw.stderr)) {
|
|
44
|
+
return { ...result, error: 'Required tool permissions were denied; approve a scoped rule interactively before retrying' };
|
|
45
|
+
}
|
|
46
|
+
if (raw.exitCode === 0 && envelope.status === 'SUCCESS' && numTurns !== null && numTurns > 0 && response?.trim()) {
|
|
47
|
+
return { ...result, success: true };
|
|
48
|
+
}
|
|
49
|
+
// A stream result that is not the expected envelope is reported by field name, because that is what tells the owner to turn step progress off.
|
|
50
|
+
const fields = transport === 'argv' ? '' : ` (stream result fields: ${Object.keys(envelope).slice(0, 12).join(', ') || 'none'}; if step progress is on, turn it off in Settings to return to the JSON mode)`;
|
|
51
|
+
return { ...result, error: typeof envelope.error === 'string' ? envelope.error : `CLI did not provide a complete successful response${fields}` };
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export function legacyAntigravityAgent(runtime, transport) {
|
|
56
|
+
const status = {
|
|
57
|
+
id: 'antigravity', label: 'Antigravity', available: runtime.supported,
|
|
58
|
+
version: null, executable: runtime.executable || null, capabilities: CAPABILITIES,
|
|
59
|
+
warnings: runtime.supported ? [] : ['Requires agy 1.4.x and all required print/output/timeout flags']
|
|
60
|
+
};
|
|
61
|
+
return { adapter: antigravityAdapter(runtime.executable, transport), status, enabled: true, launch: runtime.launch };
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=antigravity.js.map
|