agy-mcp-bridge 0.1.5 → 0.1.6

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
@@ -14,7 +14,7 @@ agy-mcp-bridge # mở server http://127.0.0.1:3000 ; giao
14
14
 
15
15
  **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
16
 
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). 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.
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.
18
18
 
19
19
  **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
20
 
package/dist/src/cli.js CHANGED
@@ -25,6 +25,8 @@ Usage: ${BIN} [command] [options]
25
25
  --workspace <dir> Also allow <dir> (for example .) for this run only; repeatable, not saved
26
26
  --open Open the web UI in your default browser once the server is up
27
27
  --no-update-check Do not ask the npm registry whether a newer version exists
28
+ --show-token Print the web UI login token in this terminal (interactive terminals only; it is also shown once
29
+ automatically the first time the token is created)
28
30
  --no-skill-prompt Do not offer to install the Codex / Claude Code skill on first run
29
31
  check Call antigravity_environment on the running server
30
32
  workspaces list|add <dir>|remove <dir>
@@ -98,6 +100,8 @@ async function start(args) {
98
100
  process.env.BRIDGE_NO_UPDATE_CHECK = '1';
99
101
  else if (args[i] === '--no-skill-prompt')
100
102
  process.env.BRIDGE_NO_SKILL_PROMPT = '1';
103
+ else if (args[i] === '--show-token')
104
+ process.env.BRIDGE_SHOW_TOKEN = '1';
101
105
  else if (args[i] === '--open')
102
106
  process.env.BRIDGE_OPEN_BROWSER = '1';
103
107
  else if (args[i] === '--port' || args[i] === '--workspace')
package/dist/src/index.js CHANGED
@@ -4,9 +4,10 @@ import { checkForUpdate, knownUpdate, readPackageInfo, setKnownUpdate, updateChe
4
4
  import { createRuntime } from './runtime.js';
5
5
  import { configuredPort, startHttpBridge } from './http.js';
6
6
  import { loadHttpToken } from './security/http-auth.js';
7
+ import { shouldShowToken, tokenNotice } from './login-notice.js';
7
8
  async function main() {
8
9
  const port = configuredPort();
9
- const { token, source } = await loadHttpToken(paths.stateDirectory);
10
+ const { token, source, created } = await loadHttpToken(paths.stateDirectory);
10
11
  const { manager, environment } = await createRuntime();
11
12
  const bridge = await startHttpBridge({ manager, environment, token, port });
12
13
  console.error(`[bridge] HTTP server: ${bridge.baseUrl}`);
@@ -14,6 +15,14 @@ async function main() {
14
15
  console.error(`[bridge] Health check: ${bridge.healthUrl} (bearer authentication required)`);
15
16
  console.error(`[bridge] Token source: ${source} (value never logged)`);
16
17
  console.error(`[bridge] Web UI: ${bridge.baseUrl}/ui (open in a browser on this machine; sign in with the token from the source above)`);
18
+ const interactive = Boolean(process.stderr.isTTY);
19
+ if (shouldShowToken({ created, requested: process.env.BRIDGE_SHOW_TOKEN === '1', fromFile: source !== 'BRIDGE_HTTP_TOKEN', interactive })) {
20
+ const color = interactive && process.stderr.hasColors?.() === true && !process.env.NO_COLOR;
21
+ for (const line of tokenNotice(token, { color, firstRun: created }))
22
+ console.error(line);
23
+ }
24
+ else if (process.env.BRIDGE_SHOW_TOKEN === '1')
25
+ console.error('[bridge] --show-token ignored: it only prints in an interactive terminal, and not when the token comes from BRIDGE_HTTP_TOKEN');
17
26
  console.error('[bridge] Client disconnected: tasks continue. Ctrl+C: cancel owned tasks and stop server.');
18
27
  if (process.env.BRIDGE_OPEN_BROWSER === '1') {
19
28
  const url = `${bridge.baseUrl}/ui`;
@@ -0,0 +1,18 @@
1
+ /** Box shown once in an interactive terminal so a new user can copy the login token without hunting for the file. */
2
+ export function tokenNotice(token, options) {
3
+ const mark = (text) => options.color ? `\u001b[1;7m ${text} \u001b[0m` : `>>> ${text} <<<`;
4
+ const rule = '[bridge] ' + '-'.repeat(60);
5
+ return [
6
+ rule,
7
+ options.firstRun ? '[bridge] Login token for the web UI (shown now because it was just created):' : '[bridge] Login token for the web UI (shown because of --show-token):',
8
+ `[bridge] ${mark(token)}`,
9
+ '[bridge] Paste it on the sign-in page. Treat it like a password: do not share screenshots or recordings of this terminal.',
10
+ `[bridge] Show it again with: agy-mcp-bridge --show-token`,
11
+ rule
12
+ ];
13
+ }
14
+ /** Only for a person looking at a terminal: never when output is redirected (logs, CI) and never for a token supplied through the environment. */
15
+ export function shouldShowToken(options) {
16
+ return options.fromFile && options.interactive && (options.created || options.requested);
17
+ }
18
+ //# sourceMappingURL=login-notice.js.map
@@ -27,7 +27,7 @@ export function validateToken(value) {
27
27
  }
28
28
  export async function loadHttpToken(stateDirectory) {
29
29
  if (process.env.BRIDGE_HTTP_TOKEN !== undefined)
30
- return { token: validateToken(process.env.BRIDGE_HTTP_TOKEN), source: 'BRIDGE_HTTP_TOKEN' };
30
+ return { token: validateToken(process.env.BRIDGE_HTTP_TOKEN), source: 'BRIDGE_HTTP_TOKEN', created: false };
31
31
  await mkdir(stateDirectory, { recursive: true });
32
32
  const filename = path.join(stateDirectory, 'http-token');
33
33
  let created = false;
@@ -44,7 +44,7 @@ export async function loadHttpToken(stateDirectory) {
44
44
  const token = validateToken((await readFile(filename, 'utf8')).trim());
45
45
  if (created)
46
46
  await hardenWindowsToken(filename);
47
- return { token, source: filename };
47
+ return { token, source: filename, created };
48
48
  }
49
49
  export function tokensEqual(supplied, token) {
50
50
  const a = Buffer.from(supplied);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agy-mcp-bridge",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Local authenticated HTTP MCP bridge that lets Codex and Claude Code delegate bounded coding tasks to the Antigravity CLI (agy)",
5
5
  "license": "MIT",
6
6
  "keywords": [