@yitom/agy-acp-map 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
@@ -75,9 +75,10 @@ bunx @yitom/agy-acp-map@latest # bun users (preferred: no prompt, no shim
75
75
  npx -y @yitom/agy-acp-map@latest # node users
76
76
  ```
77
77
 
78
- Requirements are the same as source runs: a logged-in `agy` on `PATH`. The
79
- optional 95MB single-file `agy-acp-win-x64.exe` is **not** in the npm package —
80
- grab it from GitHub Releases if you want zero-runtime distribution.
78
+ Requirements are the same as source runs: a logged-in `agy` on `PATH`.
79
+ There is no compiled single-file exe anymore — codex-style `bunx`/`npx`
80
+ is the only distribution (the npm tarball is ~5MB: `dist/bin.js` plus the
81
+ tiny `agy-headless.exe` launcher).
81
82
 
82
83
 
83
84
  ## Launch flags / 启动参数 (v0.1.2)
@@ -95,7 +96,7 @@ Configure on **`session/new`** (preferred) and/or env fallbacks. Stored on the S
95
96
  | `--sandbox` | `sandbox: true` | `AGY_ACP_SANDBOX=1` |
96
97
  | `--json-schema` | `jsonSchema` (string or object→stringify) | `AGY_ACP_JSON_SCHEMA` (string or path) |
97
98
  | `--conversation` | `conversationId` (resume / switch-model flow) | _(from prior turn)_ |
98
- | `--dangerously-skip-permissions` | `safety: 'autonomous' \| 'autonomous-unsandboxed'` or `skipPermissions: true` | `AGY_ACP_SAFETY=…` / `AGY_ACP_SKIP_PERMISSIONS=1` if safety unset (**default off / safe**) |
99
+ | `--dangerously-skip-permissions` | `safety: 'autonomous' \| 'autonomous-unsandboxed'` or `skipPermissions: true` | `AGY_ACP_SAFETY=…` / `AGY_ACP_SKIP_PERMISSIONS=1` if safety unset (**default: skip on, unsandboxed**) |
99
100
  | `--disable-slash-commands` | `disableSlashCommands` (default **true**) | `AGY_ACP_DISABLE_SLASH_COMMANDS=0` to omit |
100
101
  | `--print-timeout` | `printTimeout` (e.g. `30m`, `120s`, `0`) | `AGY_ACP_PRINT_TIMEOUT` (default `0`) |
101
102
 
@@ -159,7 +160,7 @@ Display-history path: `~/.agy-acp-map/history/`. Override with `AGY_ACP_HISTORY_
159
160
  | Env | Default | Meaning |
160
161
  |-----|---------|---------|
161
162
  | `AGY_ACP_SAFETY` | `safe` | `safe` \| `autonomous` \| `autonomous-unsandboxed` (aliases: `unsandboxed`, `autonomous_unsandboxed`). See Safety modes table. |
162
- | `AGY_ACP_SKIP_PERMISSIONS` | `0` | If **safety unset**: `1` ≈ treat as `autonomous`; `0` ≈ `safe`. Explicit `AGY_ACP_SAFETY` / `session.safety` wins. |
163
+ | `AGY_ACP_SKIP_PERMISSIONS` | `0` | If **safety unset**: `1` ≈ treat as `autonomous-unsandboxed`; `0` ≈ `safe`. Explicit `AGY_ACP_SAFETY` / `session.safety` wins. |
163
164
  | `AGY_ACP_DISABLE_SLASH_COMMANDS` | `1` | When `1` (default), pass `--disable-slash-commands`. Set `0` to omit. |
164
165
  | `AGY_ACP_PRINT_TIMEOUT` | `0` | Passed as `--print-timeout` (e.g. `30m`, `120s`, `0` = wait until turn completes). |
165
166
  | `AGY_BIN` | `agy` | Override binary |
@@ -167,7 +168,7 @@ Display-history path: `~/.agy-acp-map/history/`. Override with `AGY_ACP_HISTORY_
167
168
  | `AGY_ACP_EFFORT` | — | Default `--effort` |
168
169
  | `AGY_ACP_MODE` | — | Default `--mode` |
169
170
  | `AGY_ACP_AGENT` | — | Default `--agent` |
170
- | `AGY_ACP_SANDBOX` | — | `1`/`0` → force sandbox on/off for `safe`/`autonomous`. Ignored for `autonomous-unsandboxed` (never sandboxed). |
171
+ | `AGY_ACP_SANDBOX` | — | `1`/`0` → force sandbox on/off for `safe`/`autonomous`/defaulted tier. Ignored only when `autonomous-unsandboxed` was explicitly selected. |
171
172
  | `AGY_ACP_JSON_SCHEMA` | — | Schema string or file path for `--json-schema` |
172
173
  | `AGY_ACP_KEEP_STAGING` | — | `1` → keep `.agy-acp-staging` files after turn/close (debug) |
173
174
  | `AGY_ACP_STORE` / `AGY_ACP_SESSION_STORE` | `~/.agy-acp-map/sessions.json` | Disk session index path (`SESSION_STORE` wins if both set) |
@@ -209,15 +210,15 @@ No interactive ACP permission UI — **launch strategies only** (`resolveSafety`
209
210
 
210
211
  | Mode / 模式 | Skip permissions / 跳过权限 | Sandbox / 沙箱 |
211
212
  |-------------|------------------------------|----------------|
212
- | **safe** (default) | no — rely on agy `settings.json` allow/deny + soft-deny messages | only if user sets `sandbox: true` / `AGY_ACP_SANDBOX=1` |
213
+ | **safe** | no — rely on agy `settings.json` allow/deny + soft-deny messages | only if user sets `sandbox: true` / `AGY_ACP_SANDBOX=1` |
213
214
  | **autonomous** | yes (`--dangerously-skip-permissions`) | **default `--sandbox`** unless user sets `sandbox: false` / `AGY_ACP_SANDBOX=0` |
214
- | **autonomous-unsandboxed** (aliases: `autonomous_unsandboxed`, `unsandboxed`) | yes (`--dangerously-skip-permissions`) | **never** pass `--sandbox` (explicit dangerous tier; ignores sandbox overrides) |
215
+ | **autonomous-unsandboxed** (default; aliases: `autonomous_unsandboxed`, `unsandboxed`) | yes (`--dangerously-skip-permissions`) | **never** when explicitly selected (ignores sandbox overrides); the defaulted tier honors explicit `sandbox: true` / `AGY_ACP_SANDBOX=1` |
215
216
 
216
217
  Accept via:
217
218
  - `session/new` field `safety`: `'safe' | 'autonomous' | 'autonomous-unsandboxed'`
218
219
  - env `AGY_ACP_SAFETY` (same values)
219
220
  - idle `session/set_config_option` with `configId: "safety"`
220
- - Backward compat: `AGY_ACP_SKIP_PERMISSIONS=1` ≈ `autonomous` **if safety unset**; `=0` ≈ `safe`
221
+ - Backward compat: `AGY_ACP_SKIP_PERMISSIONS=1` ≈ `autonomous-unsandboxed` **if safety unset**; `=0` ≈ `safe`
221
222
 
222
223
  输入:`session/new.safety` / `AGY_ACP_SAFETY` / `set_config_option`;兼容 `AGY_ACP_SKIP_PERMISSIONS`(仅在未设 safety 时生效)。
223
224
 
@@ -329,9 +330,7 @@ Engineering feasibility ≠ legal permission. 即便只用官方 CLI I/O,仍
329
330
  ## Zed via npm (global install) / Zed 全局安装用法
330
331
 
331
332
  No Bun / TypeScript needed at runtime — the published package ships compiled
332
- `dist/` artifacts (`bin.js` for Node, `agy-headless.exe`). The optional
333
- single-file `agy-acp-win-x64.exe` (no runtime needed) is a GitHub Release
334
- asset, not part of the npm tarball. A **global** install is recommended so Zed
333
+ `dist/` artifacts (`bin.js` for Node, `agy-headless.exe`). A **global** install is recommended so Zed
335
334
  gets a stable absolute path (repo moves would break a local path):
336
335
 
337
336
  ```powershell
Binary file
package/dist/bin.js CHANGED
@@ -10750,14 +10750,15 @@ function normalizePrintTimeout(v) {
10750
10750
  return s === "" ? undefined : s;
10751
10751
  }
10752
10752
  function resolveSafety(session = {}, env = process.env) {
10753
- let safety = normalizeSafety(session.safety) ?? normalizeSafety(env.AGY_ACP_SAFETY) ?? undefined;
10753
+ const explicitSafety = normalizeSafety(session.safety) ?? normalizeSafety(env.AGY_ACP_SAFETY) ?? undefined;
10754
+ let safety = explicitSafety;
10754
10755
  if (!safety) {
10755
10756
  const envSkip = env.AGY_ACP_SKIP_PERMISSIONS;
10756
10757
  if (envSkip !== undefined && envSkip !== "") {
10757
10758
  const skip = !(envSkip === "0" || envSkip === "false" || envSkip === "no");
10758
- safety = skip ? "autonomous" : "safe";
10759
+ safety = skip ? "autonomous-unsandboxed" : "safe";
10759
10760
  } else {
10760
- safety = "autonomous";
10761
+ safety = "autonomous-unsandboxed";
10761
10762
  }
10762
10763
  }
10763
10764
  let skipPermissions = safety === "autonomous" || safety === "autonomous-unsandboxed";
@@ -10765,7 +10766,7 @@ function resolveSafety(session = {}, env = process.env) {
10765
10766
  skipPermissions = Boolean(session.skipPermissions);
10766
10767
  }
10767
10768
  let sandbox;
10768
- if (safety === "autonomous-unsandboxed") {
10769
+ if (safety === "autonomous-unsandboxed" && explicitSafety === "autonomous-unsandboxed") {
10769
10770
  sandbox = false;
10770
10771
  } else if (session.sandbox !== undefined) {
10771
10772
  sandbox = Boolean(session.sandbox);
@@ -11692,7 +11693,7 @@ function formatSoftDenyMessage(denies) {
11692
11693
  bits.push(`(via ${d.source})`);
11693
11694
  lines.push(bits.join(" "));
11694
11695
  }
11695
- lines.push("Or set AGY_ACP_SAFETY=safe / AGY_ACP_SKIP_PERMISSIONS=0 to re-enable permission checks (autonomous + sandbox is the bridge default).");
11696
+ lines.push("Or set AGY_ACP_SAFETY=safe / AGY_ACP_SKIP_PERMISSIONS=0 to re-enable permission checks (autonomous-unsandboxed — full permissions, no sandbox — is the bridge default; AGY_ACP_SAFETY=autonomous re-enables sandbox containment).");
11696
11697
  if (denies.some((d) => d.source?.includes("sandbox"))) {
11697
11698
  lines.push("Sandbox note: --sandbox = terminal restrictions, not verified offline. Built-in search may still work; if `curl`/`Invoke-WebRequest` failed, retry once with safety=autonomous-unsandboxed (or sandbox:false) to confirm it is a sandbox network block.");
11698
11699
  }
@@ -12632,7 +12633,7 @@ function mcpServerToAgyAddArgs(s) {
12632
12633
  if (s.kind === "stdio") {
12633
12634
  for (const e of s.env)
12634
12635
  argv.push("--env", `${e.name}=${e.value}`);
12635
- argv.push(s.name, s.command, ...s.args);
12636
+ argv.push(s.name, "--", s.command, ...s.args);
12636
12637
  return argv;
12637
12638
  }
12638
12639
  for (const h of s.headers)
@@ -12673,6 +12674,21 @@ ${r.stderr}`)}`);
12673
12674
  }
12674
12675
  added.push(s.name);
12675
12676
  }
12677
+ if (added.length) {
12678
+ let listed = "";
12679
+ try {
12680
+ const lr = await runFn(bin, ["mcp", "list"], { timeoutMs });
12681
+ listed = String(lr.stdout ?? "");
12682
+ } catch (err) {
12683
+ throw new RequestError(-32603, `registered MCP server(s) [${added.join(", ")}] but 'mcp list' verification failed: ${err?.message || err}`);
12684
+ }
12685
+ const lines = listed.split(`
12686
+ `);
12687
+ const missing = added.filter((n) => !lines.some((ln) => ln.includes(n)));
12688
+ if (missing.length) {
12689
+ throw new RequestError(-32603, `MCP server(s) [${missing.join(", ")}] exited 0 on 'mcp add' but are absent from 'mcp list' ` + `(agy swallows its global --version/--help flags even after '--'; check server args). ` + `List tail: ${tail(listed, 300)}`);
12690
+ }
12691
+ }
12676
12692
  return { added };
12677
12693
  }
12678
12694
  async function removeMcpServers(bin, names, runFn = defaultMcpRunFn, timeoutMs = 30000) {
@@ -12701,7 +12717,7 @@ ${r.stderr}`, 200)}`);
12701
12717
  var AGENT_INFO = {
12702
12718
  name: "agy-acp",
12703
12719
  title: "agy ACP (stream-json)",
12704
- version: "0.1.16"
12720
+ version: "0.1.18"
12705
12721
  };
12706
12722
  var BRIDGE_CAPABILITIES = {
12707
12723
  prompt: true,
package/dist/index.js CHANGED
@@ -10421,14 +10421,15 @@ function normalizePrintTimeout(v) {
10421
10421
  return s === "" ? undefined : s;
10422
10422
  }
10423
10423
  function resolveSafety(session = {}, env = process.env) {
10424
- let safety = normalizeSafety(session.safety) ?? normalizeSafety(env.AGY_ACP_SAFETY) ?? undefined;
10424
+ const explicitSafety = normalizeSafety(session.safety) ?? normalizeSafety(env.AGY_ACP_SAFETY) ?? undefined;
10425
+ let safety = explicitSafety;
10425
10426
  if (!safety) {
10426
10427
  const envSkip = env.AGY_ACP_SKIP_PERMISSIONS;
10427
10428
  if (envSkip !== undefined && envSkip !== "") {
10428
10429
  const skip = !(envSkip === "0" || envSkip === "false" || envSkip === "no");
10429
- safety = skip ? "autonomous" : "safe";
10430
+ safety = skip ? "autonomous-unsandboxed" : "safe";
10430
10431
  } else {
10431
- safety = "autonomous";
10432
+ safety = "autonomous-unsandboxed";
10432
10433
  }
10433
10434
  }
10434
10435
  let skipPermissions = safety === "autonomous" || safety === "autonomous-unsandboxed";
@@ -10436,7 +10437,7 @@ function resolveSafety(session = {}, env = process.env) {
10436
10437
  skipPermissions = Boolean(session.skipPermissions);
10437
10438
  }
10438
10439
  let sandbox;
10439
- if (safety === "autonomous-unsandboxed") {
10440
+ if (safety === "autonomous-unsandboxed" && explicitSafety === "autonomous-unsandboxed") {
10440
10441
  sandbox = false;
10441
10442
  } else if (session.sandbox !== undefined) {
10442
10443
  sandbox = Boolean(session.sandbox);
@@ -11402,7 +11403,7 @@ function formatSoftDenyMessage(denies) {
11402
11403
  bits.push(`(via ${d.source})`);
11403
11404
  lines.push(bits.join(" "));
11404
11405
  }
11405
- lines.push("Or set AGY_ACP_SAFETY=safe / AGY_ACP_SKIP_PERMISSIONS=0 to re-enable permission checks (autonomous + sandbox is the bridge default).");
11406
+ lines.push("Or set AGY_ACP_SAFETY=safe / AGY_ACP_SKIP_PERMISSIONS=0 to re-enable permission checks (autonomous-unsandboxed — full permissions, no sandbox — is the bridge default; AGY_ACP_SAFETY=autonomous re-enables sandbox containment).");
11406
11407
  if (denies.some((d) => d.source?.includes("sandbox"))) {
11407
11408
  lines.push("Sandbox note: --sandbox = terminal restrictions, not verified offline. Built-in search may still work; if `curl`/`Invoke-WebRequest` failed, retry once with safety=autonomous-unsandboxed (or sandbox:false) to confirm it is a sandbox network block.");
11408
11409
  }
@@ -12419,7 +12420,7 @@ function mcpServerToAgyAddArgs(s) {
12419
12420
  if (s.kind === "stdio") {
12420
12421
  for (const e of s.env)
12421
12422
  argv.push("--env", `${e.name}=${e.value}`);
12422
- argv.push(s.name, s.command, ...s.args);
12423
+ argv.push(s.name, "--", s.command, ...s.args);
12423
12424
  return argv;
12424
12425
  }
12425
12426
  for (const h of s.headers)
@@ -12460,6 +12461,21 @@ ${r.stderr}`)}`);
12460
12461
  }
12461
12462
  added.push(s.name);
12462
12463
  }
12464
+ if (added.length) {
12465
+ let listed = "";
12466
+ try {
12467
+ const lr = await runFn(bin, ["mcp", "list"], { timeoutMs });
12468
+ listed = String(lr.stdout ?? "");
12469
+ } catch (err) {
12470
+ throw new RequestError(-32603, `registered MCP server(s) [${added.join(", ")}] but 'mcp list' verification failed: ${err?.message || err}`);
12471
+ }
12472
+ const lines = listed.split(`
12473
+ `);
12474
+ const missing = added.filter((n) => !lines.some((ln) => ln.includes(n)));
12475
+ if (missing.length) {
12476
+ throw new RequestError(-32603, `MCP server(s) [${missing.join(", ")}] exited 0 on 'mcp add' but are absent from 'mcp list' ` + `(agy swallows its global --version/--help flags even after '--'; check server args). ` + `List tail: ${tail(listed, 300)}`);
12477
+ }
12478
+ }
12463
12479
  return { added };
12464
12480
  }
12465
12481
  async function removeMcpServers(bin, names, runFn = defaultMcpRunFn, timeoutMs = 30000) {
@@ -12488,7 +12504,7 @@ ${r.stderr}`, 200)}`);
12488
12504
  var AGENT_INFO = {
12489
12505
  name: "agy-acp",
12490
12506
  title: "agy ACP (stream-json)",
12491
- version: "0.1.16"
12507
+ version: "0.1.18"
12492
12508
  };
12493
12509
  var BRIDGE_CAPABILITIES = {
12494
12510
  prompt: true,
@@ -114,14 +114,17 @@ export type SafetyResolveInput = {
114
114
  *
115
115
  * Tiers:
116
116
  * safe — no skip-permissions; sandbox only if explicitly true
117
- * autonomous (default) — skip-permissions; default --sandbox unless sandbox:false
118
- * autonomous-unsandboxed — skip-permissions; NEVER --sandbox
117
+ * autonomous — skip-permissions; default --sandbox unless sandbox:false
118
+ * (opt-in containment; explicit safety/autonomous only)
119
+ * autonomous-unsandboxed — skip-permissions; NEVER --sandbox (the default:
120
+ * full permissions, no terminal restrictions)
119
121
  *
120
122
  * Inputs:
121
123
  * session.safety / AGY_ACP_SAFETY
122
- * AGY_ACP_SKIP_PERMISSIONS=0 ≈ safe if safety unset; otherwise autonomous
124
+ * AGY_ACP_SKIP_PERMISSIONS=0 ≈ safe if safety unset; otherwise autonomous-unsandboxed
123
125
  * explicit session.skipPermissions overrides the skip flag only
124
- * explicit session.sandbox / AGY_ACP_SANDBOX override sandbox except unsandboxed tier
126
+ * explicit session.sandbox / AGY_ACP_SANDBOX override sandbox except when the
127
+ * unsandboxed tier was explicitly selected (defaulted tier honors opt-in)
125
128
  */
126
129
  export declare function resolveSafety(session?: SafetyResolveInput, env?: NodeJS.ProcessEnv): ResolvedSafety;
127
130
  /**
@@ -53,6 +53,10 @@ export declare function validateMcpServers(input: unknown): NormalizedMcpServer[
53
53
  * Build `agy mcp add` argv. agy rejects flags placed after <name>, so all
54
54
  * flags come first: mcp add [--env K=V] [--header K:V] [--type t] <name>
55
55
  * <commandOrUrl> [args...].
56
+ * stdio ALWAYS inserts `--` after <name>: agy consumes a global `--version`
57
+ * (and may misparse other dash-args) even in post-positional slots, which
58
+ * exits 0 while registering nothing (verified against agy 1.2.8). `--` ends
59
+ * flag parsing so command/args pass through verbatim.
56
60
  */
57
61
  export declare function mcpServerToAgyAddArgs(s: NormalizedMcpServer): string[];
58
62
  export interface McpRunResult {
@@ -70,6 +74,9 @@ export declare const defaultMcpRunFn: McpRunFn;
70
74
  * Register every server via `agy mcp add` (idempotent: add == upsert).
71
75
  * Any failure throws RequestError — a client that asked for MCP must never
72
76
  * get a silent tools-less session.
77
+ * Verify-after-add: agy exits 0 while registering NOTHING when argv contains
78
+ * its global flags (`--version`/`--help` are swallowed even after `--`),
79
+ * so every add is confirmed via `mcp list`. Absent-after-add throws loud.
73
80
  */
74
81
  export declare function syncMcpServers(bin: string, servers: NormalizedMcpServer[], runFn?: McpRunFn, timeoutMs?: number): Promise<{
75
82
  added: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yitom/agy-acp-map",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -28,7 +28,6 @@
28
28
  "build": "bun run build:js && bun run build:types && bun run build:headless",
29
29
  "build:headless": "bun scripts/build-headless.ts",
30
30
  "build:js": "bun build src/sdk-server.ts --target node --outfile dist/bin.js && bun build src/index.ts --target node --outfile dist/index.js",
31
- "build:exe": "bun build src/sdk-server.ts --compile --target=bun-windows-x64 --outfile release/agy-acp-win-x64.exe",
32
31
  "build:types": "bunx tsc -p tsconfig.build.json",
33
32
  "release:patch": "bun scripts/release.ts",
34
33
  "release:publish": "bun scripts/release.ts --publish",
@@ -48,8 +47,11 @@
48
47
  "smoke:permissions": "bun tests/smoke/smoke-permissions.ts",
49
48
  "smoke:image-in": "bun tests/smoke/smoke-image-in.ts",
50
49
  "smoke:image-out": "bun tests/smoke/smoke-image-out.ts",
50
+ "smoke:mcp": "bun tests/smoke/smoke-mcp.ts",
51
+ "smoke:mcp-resume": "bun tests/smoke/smoke-mcp-resume.ts",
52
+ "smoke:mcp-e2e": "bun tests/smoke/smoke-mcp-e2e.ts",
51
53
  "smoke:robustness": "bun tests/smoke/smoke-robustness.ts",
52
- "smoke:all": "bun test src/lib && bun tests/test-agy-args.ts && bun tests/smoke/smoke-basic.ts && bun tests/smoke/smoke-flags.ts && bun tests/smoke/smoke-permissions.ts && bun tests/smoke/smoke-image-in.ts && bun tests/smoke/smoke-image-out.ts && bun tests/smoke/smoke-robustness.ts"
54
+ "smoke:all": "bun test src/lib && bun tests/test-agy-args.ts && bun tests/smoke/smoke-mcp.ts && bun tests/smoke/smoke-mcp-resume.ts && bun tests/smoke/smoke-basic.ts && bun tests/smoke/smoke-flags.ts && bun tests/smoke/smoke-permissions.ts && bun tests/smoke/smoke-image-in.ts && bun tests/smoke/smoke-image-out.ts && bun tests/smoke/smoke-robustness.ts"
53
55
  },
54
56
  "keywords": [
55
57
  "antigravity",