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 CHANGED
@@ -1,20 +1,22 @@
1
- # MCP Bridge HTTP: Codex / Claude Code → Antigravity
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 và Claude Code kết nối tới cùng endpoint; không khởi chạy process bridge riêng. Không cần mở Antigravity IDE; bridge gọi executable `agy` đã đăng nhập.
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 và Antigravity CLI `agy` 1.4.x đã đăng nhập
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, token 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, gồm `token file` (đọc token ở đó để dán vào giao diện web hoặc nạp vào `BRIDGE_HTTP_TOKEN` cho Codex/Claude Code). **Lần đầu chạy** (khi token vừa được tạo), bridge in token ngay trong terminal, tô nổi bật, để bạn dán vào trang đăng nhập; các lần sau không in nữa. Muốn xem lại thì chạy `agy-mcp-bridge --show-token`. Token chỉ được in trong terminal tương tác: khi output bị chuyển hướng (file log, CI) hoặc khi token lấy từ `BRIDGE_HTTP_TOKEN` thì không bao giờ in. Đừng chụp màn hình hoặc quay video đoạn này. 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.
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
- export BRIDGE_HTTP_TOKEN="$(cat .bridge-state/http-token)" # terminal 2, same clone
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`; `Get-Content -Raw f` → `cat f`; `Remove-Item Env:X` → `unset X`.
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 khác 1.4.3 vẫn chạy nhưng có cảnh báo trong log và environment vì chưa được xác minh thực thi agent thật; 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).
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 với cùng cơ chế bảo mật; 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.
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 (bearer authentication required)
104
- [bridge] Token source: <đường dẫn file token hoặc BRIDGE_HTTP_TOKEN> (value never logged)
105
- [bridge] Web UI: http://127.0.0.1:3000/ui (open in a browser on this machine; sign in with the token from the source above)
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. Token xác thực và health check
122
+ ## 2. Không xác thực và health check
120
123
 
121
- Mọi request tới `/mcp` và `/health` phải có `Authorization: Bearer <token>`. Đây là token dùng chung cho một người dùng cục bộ, không phải OAuth. Không cần `codex mcp login` hay `claude mcp login` cho bridge này.
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
- Nếu chưa đặt `BRIDGE_HTTP_TOKEN`, lần khởi động đầu tự tạo token ngẫu nhiên 256 bit tại `.bridge-state/http-token`, rồi tái sử dụng qua các lần chạy. Server chỉ in **đường dẫn nguồn token**, không in giá trị. Thư mục này được gitignore. Token file mới dùng mode 0600 trên POSIX; Windows dùng `whoami /user` và `icacls` không qua shell để bỏ kế thừa ACL và cấp đọc/ghi cho SID tài khoản hiện tại. Nếu ACL lỗi, server cảnh báo và vẫn chạy: chủ máy cần bảo vệ file thủ công. File có sẵn không bị tự đổi ACL. Bất cứ ai đọc được token đều có quyền dùng các tool, xem và hủy task của server.
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`), rồi đọc token vào môi trường mà không in nó:
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
- $env:BRIDGE_HTTP_TOKEN = (Get-Content -Raw '.bridge-state/http-token').Trim()
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`. Nếu không có token trong env, script đọc file token mặc định. Khi server tắt, token sai hoặc URL sai, script thoát mã 1 và hướng dẫn chạy `npm start`, kiểm tra PORT/URL/token, rồi kết nối lại.
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' -Headers $headers
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. Nếu chủ động cấp token bằng env trước `npm start`, dùng token đó ở các client; token env phải dài 32–256 ký tự thuộc A–Z, a–z, 0–9, `_`, `-`. Env ưu tiên hơn file. Không commit token hoặc dán vào prompt. Child `agy` chỉ nhận allowlist môi trường; secret, gồm `BRIDGE_HTTP_TOKEN`, bị chặn mặc định. Chỉ dùng `extra_env_passthrough` cho biến thực sự cần và không liệt kê bearer token của bridge. Xem danh sách và ví dụ trong [HARDENING.md](docs/HARDENING.md).
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 (đường dẫn token, 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
+ > 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' --bearer-token-env-var BRIDGE_HTTP_TOKEN
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 từ terminal đã nạp token. Với IDE/app đang mở, phải nạp env vào môi trường của app và khởi động lại app; đặt env ở terminal khác không cập nhật tiến trình đã chạy. 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.
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`, giữ `bearer_token_env_var`, 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.
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ừ terminal đã nạp token và thư mục project của bạn:
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' --header 'Authorization: Bearer ${BRIDGE_HTTP_TOKEN}'
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
- Dấu nháy đơn PowerShell giữ nguyên `${BRIDGE_HTTP_TOKEN}` trong cấu hình; Claude Code đọc env khi khởi động. Không thay bằng token literal trong lệnh, để tránh lưu token vào history/config. `--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.
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 với cùng header env, sau đó reconnect. Không cần dừng server vì client ngắt kết nố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
- | `antigravity_delegate` | Nhận task, workspace, acceptance_criteria, context?, timeout_seconds?; trả `running` (hoặc `queued` nếu bridge đang bận và hàng đợi còn chỗ) cùng task_id |
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ó envelope 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).
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 hay token. `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.
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. Một người dùng có cùng token được xem/hủy task từ cả hai client.
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:** chỉ một task chạy tại một thời điểm, nhưng khi bridge đang bận, tối đa `max_queued_tasks` task nữa (mặc định 3, cấu hình 0–20 trong `config/workspaces.json`) được nhận với trạng thái `queued` và chạy lần lượt 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"). Queue không làm thay đổi quy tắc "một task toàn cục": không có chạy song song.
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
- 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 `agy` 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. Chỉ một task chạy toàn cục, khóa giữa các process dùng cùng bản cài tại `.bridge-state/execution.lock`; không điều phối editor/agent ngoài hoặc bản cài bridge khác.
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. Mọi endpoint yêu cầu bearer token, so sánh constant time khi cùng độ dài. Không log HTTP headers/body hoặc token. Không mở HTTP không xác thực.
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/auth/Host/Origin/body limit/kết nối hai protocol era/client reconnect/task completion/cancel/server shutdown.
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/auth/routing/shutdown; `src/runtime.ts`: CLI và TaskManager dùng chung; `src/tools`: tool; `src/antigravity`: child process; `src/security`: validation/workspace/token/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.
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, token, 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):
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
- Đăng nhập bằng bridge token, dán vào ô nhập (`Get-Content .bridge-state/http-token` hoặc `cat .bridge-state/http-token`). Server đổi token lấy một mã phiên ngẫu nhiên, hết hạn sau 8 giờ hoặc khi restart, gửi qua header chứ không dùng cookie; token không bao giờ được hiển thị lại. Sai quá 10 lần trong một phút thì bị khóa tạm.
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, phiên bản `agy`, công tắc giao việc, số task đang chạy); danh sách task; với mỗi task là cuộc trao đổi **Tech Lead → Antigravity** (yêu cầu, tiêu chí nghiệm thu, ngữ cảnh) và **Antigravity → Tech Lead** (phản hồi cuối, thao tác bị từ chối quyền, lỗi), log stdout/stderr, prompt đầy đủ gửi tới `agy`. 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ờ |
382
- | Cài đặt | Công tắc giao việc cho Antigravity (cùng cơ chế với `npm run delegation`, bị khóa nếu đặt `BRIDGE_DELEGATION`), endpoint MCP, thông tin CLI, workspace được phép, giới hạn, lưu ý. Workspace và giới hạn chỉ đọc: sửa trong `config/workspaces.json` rồi khởi động lại |
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 cần phiên đăng nhập: hủy task, bật/tắt giao việc và chọn model. 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/`.
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à client được mở khi chưa có `BRIDGE_HTTP_TOKEN`) rồi dừng.
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 (cần phiên đăng nhập bằng token); Codex/Claude không có tool nào để đổi và file skill cấm xin token để làm việc đó. 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`.
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
  }
@@ -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 token = process.env.BRIDGE_HTTP_TOKEN ?? (await readFile(path.join(paths.stateDirectory, 'http-token'), 'utf8')).trim();
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 and BRIDGE_HTTP_TOKEN, then reconnect.`);
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, no token needed.
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 { findExecutable, startProcess, terminateOwned } from '../src/antigravity/process.js';
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 executable = await findExecutable(config.executable);
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