@agentproto/driver-agent-cli 2.5.1 → 2.6.0

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.
@@ -2,9 +2,9 @@ import { z } from 'zod';
2
2
  import { Writable, Readable } from 'stream';
3
3
  import { createAcpClient } from '@agentproto/acp/client';
4
4
  import { spawn, execFile } from 'child_process';
5
- import { existsSync, readFileSync, mkdirSync, writeFileSync, rmSync, rmdirSync, mkdtempSync } from 'fs';
5
+ import { existsSync, readFileSync, mkdirSync, writeFileSync, rmSync, rmdirSync, realpathSync, mkdtempSync } from 'fs';
6
6
  import { createInterface } from 'readline';
7
- import { join, delimiter, dirname, basename } from 'path';
7
+ import { join, resolve, delimiter, dirname, basename } from 'path';
8
8
  import { tmpdir, homedir } from 'os';
9
9
  import { loadAdapterSpawnSandboxConfig, resolveCommandSandbox } from '@agentproto/command-sandbox';
10
10
  import { randomUUID, createHash } from 'crypto';
@@ -701,15 +701,15 @@ function isAlive(pid) {
701
701
  }
702
702
  }
703
703
  function listProcesses() {
704
- return new Promise((resolve) => {
704
+ return new Promise((resolve2) => {
705
705
  execFile("ps", ["-axo", "pid=,ppid="], { maxBuffer: 32 * 1024 * 1024 }, (err, stdout) => {
706
- if (err) return resolve([]);
706
+ if (err) return resolve2([]);
707
707
  const out = [];
708
708
  for (const line of stdout.split("\n")) {
709
709
  const m = line.match(/^\s*(\d+)\s+(\d+)\s*$/);
710
710
  if (m) out.push({ pid: Number(m[1]), ppid: Number(m[2]) });
711
711
  }
712
- resolve(out);
712
+ resolve2(out);
713
713
  });
714
714
  });
715
715
  }
@@ -743,8 +743,13 @@ function defaultToolchainReadPaths() {
743
743
  }
744
744
  async function wrapAgentCliSpawn(bin, args, opts) {
745
745
  const cfg = await loadAdapterSpawnSandboxConfig(opts.cwd);
746
- const mode = opts.mode ?? cfg.mode;
746
+ const mode = opts.zones ? opts.mode ?? "workspace" : opts.mode ?? cfg.mode;
747
747
  if (mode === void 0) return [bin, args];
748
+ if (mode === "off" && opts.zones) {
749
+ throw new Error(
750
+ `agent-cli '${opts.label}': filesystem zones (an app boundary) cannot be combined with commandSandbox "off" \u2014 the zones are only enforceable through the OS sandbox. Refusing to spawn.`
751
+ );
752
+ }
748
753
  if (mode === "off") {
749
754
  console.error(
750
755
  `[agent-cli] \u26A0 spawning '${opts.label}' UNCONFINED \u2014 no OS-level sandbox is active (commandSandbox mode is "off").`
@@ -757,18 +762,20 @@ async function wrapAgentCliSpawn(bin, args, opts) {
757
762
  `agent-cli '${opts.label}': commandSandbox mode="${mode}" is configured but no sandbox backend is available on ${process.platform} (macOS needs sandbox-exec, Linux needs bwrap installed). Refusing to spawn unconfined \u2014 pass commandSandbox: "off" to explicitly accept unconfined execution, or install the missing backend.`
758
763
  );
759
764
  }
765
+ const fileCfg = opts.zones ? void 0 : cfg;
760
766
  const policy = {
761
767
  workspace: opts.cwd,
762
768
  extraReadPaths: [
763
769
  ...defaultToolchainReadPaths(),
764
- ...cfg.extraReadPaths,
770
+ ...fileCfg?.extraReadPaths ?? [],
765
771
  ...opts.extraReadPaths ?? []
766
772
  ],
767
773
  extraWritePaths: [
768
774
  ...defaultToolchainWritePaths(),
769
- ...cfg.extraWritePaths,
775
+ ...fileCfg?.extraWritePaths ?? [],
770
776
  ...opts.extraWritePaths ?? []
771
777
  ],
778
+ ...opts.zones ? { zones: opts.zones } : {},
772
779
  network: mode === "strict" || cfg.network === "deny" ? "deny" : "allow"
773
780
  };
774
781
  const wrapped = backend.wrap([bin, ...args], policy);
@@ -822,6 +829,7 @@ function createPrintSession(opts) {
822
829
  cwd: opts.cwd,
823
830
  ...opts.extraWritePaths ? { extraWritePaths: opts.extraWritePaths } : {},
824
831
  ...opts.extraReadPaths ? { extraReadPaths: opts.extraReadPaths } : {},
832
+ ...opts.fsZones ? { zones: opts.fsZones } : {},
825
833
  label: "print-arm"
826
834
  });
827
835
  const child = spawn(execBin, execArgs, {
@@ -831,11 +839,11 @@ function createPrintSession(opts) {
831
839
  });
832
840
  activeChild = child;
833
841
  let spawnFailure;
834
- await new Promise((resolve) => {
835
- child.once("spawn", () => resolve());
842
+ await new Promise((resolve2) => {
843
+ child.once("spawn", () => resolve2());
836
844
  child.once("error", (err) => {
837
845
  spawnFailure = err;
838
- resolve();
846
+ resolve2();
839
847
  });
840
848
  });
841
849
  if (spawnFailure) {
@@ -1454,16 +1462,16 @@ var EventQueue = class {
1454
1462
  `print-arm: event backlog exceeded ${QUEUE_HIGH_WATER_MARK} buffered events \u2014 downstream consumer is not keeping up. The child's stdout is still being drained (no ENOBUFS), but memory will grow until the consumer catches up.`
1455
1463
  );
1456
1464
  }
1457
- const resolve = this.resolveNext;
1465
+ const resolve2 = this.resolveNext;
1458
1466
  this.resolveNext = null;
1459
- resolve?.();
1467
+ resolve2?.();
1460
1468
  }
1461
1469
  /** Signal that no further events will be pushed. */
1462
1470
  end() {
1463
1471
  this.ended = true;
1464
- const resolve = this.resolveNext;
1472
+ const resolve2 = this.resolveNext;
1465
1473
  this.resolveNext = null;
1466
- resolve?.();
1474
+ resolve2?.();
1467
1475
  }
1468
1476
  async *[Symbol.asyncIterator]() {
1469
1477
  for (; ; ) {
@@ -1473,8 +1481,8 @@ var EventQueue = class {
1473
1481
  continue;
1474
1482
  }
1475
1483
  if (this.ended) return;
1476
- await new Promise((resolve) => {
1477
- this.resolveNext = resolve;
1484
+ await new Promise((resolve2) => {
1485
+ this.resolveNext = resolve2;
1478
1486
  });
1479
1487
  }
1480
1488
  }
@@ -1493,9 +1501,9 @@ function mapMastraFinishReason(raw) {
1493
1501
  }
1494
1502
  }
1495
1503
  function waitForExit(child) {
1496
- return new Promise((resolve) => {
1497
- child.once("exit", (code) => resolve(code));
1498
- child.once("error", () => resolve(null));
1504
+ return new Promise((resolve2) => {
1505
+ child.once("exit", (code) => resolve2(code));
1506
+ child.once("error", () => resolve2(null));
1499
1507
  });
1500
1508
  }
1501
1509
 
@@ -1744,6 +1752,42 @@ function interpolateEnv(env, value) {
1744
1752
  }
1745
1753
  return out;
1746
1754
  }
1755
+ function agentCliSupportsHostContextIsolation(adapterId) {
1756
+ return adapterId === "claude-code";
1757
+ }
1758
+ function escapeGlob(p) {
1759
+ return p.replace(/[\\*?[\]{}()!+@]/g, "\\$&");
1760
+ }
1761
+ function ancestors(dir) {
1762
+ const out = [];
1763
+ let cur = dirname(dir);
1764
+ for (; ; ) {
1765
+ out.push(cur);
1766
+ const parent = dirname(cur);
1767
+ if (parent === cur) return out;
1768
+ cur = parent;
1769
+ }
1770
+ }
1771
+ function hostContextExcludes(cwd) {
1772
+ const abs = resolve(cwd);
1773
+ let real = abs;
1774
+ try {
1775
+ real = realpathSync(abs);
1776
+ } catch {
1777
+ }
1778
+ const dirs = /* @__PURE__ */ new Set([...ancestors(abs), ...ancestors(real)]);
1779
+ const out = [];
1780
+ for (const d of dirs) {
1781
+ const base = d === "/" ? "" : escapeGlob(d);
1782
+ out.push(
1783
+ `${base}/CLAUDE.md`,
1784
+ `${base}/CLAUDE.local.md`,
1785
+ `${base}/.claude/CLAUDE.md`,
1786
+ `${base}/.claude/rules/**`
1787
+ );
1788
+ }
1789
+ return out;
1790
+ }
1747
1791
  function createArmSessionControls(arm, definition) {
1748
1792
  const modelApply = definition.models?.apply ?? "config";
1749
1793
  return {
@@ -2033,8 +2077,16 @@ function createAgentCliRuntime(definition) {
2033
2077
  const isolatedSettings = {
2034
2078
  attribution: { commit: "", pr: "", sessionUrl: false }
2035
2079
  };
2036
- if (permissionMode) {
2037
- isolatedSettings.permissions = { defaultMode: permissionMode };
2080
+ const isolatedPermissions = {};
2081
+ if (permissionMode) isolatedPermissions.defaultMode = permissionMode;
2082
+ if (opts?.fsZones?.writable.length) {
2083
+ isolatedPermissions.additionalDirectories = opts.fsZones.writable;
2084
+ }
2085
+ if (Object.keys(isolatedPermissions).length > 0) {
2086
+ isolatedSettings.permissions = isolatedPermissions;
2087
+ }
2088
+ if (opts?.isolateHostContext) {
2089
+ isolatedSettings.claudeMdExcludes = hostContextExcludes(cwd);
2038
2090
  }
2039
2091
  writeFileSync(
2040
2092
  join(claudeConfigDir, "settings.json"),
@@ -2053,6 +2105,7 @@ function createAgentCliRuntime(definition) {
2053
2105
  ...opts?.mcpServers ? { mcpServers: opts.mcpServers } : {},
2054
2106
  printConfig: definition.print,
2055
2107
  commandSandbox: opts?.commandSandbox,
2108
+ ...opts?.fsZones ? { fsZones: opts.fsZones } : {},
2056
2109
  ...claudeConfigDir ? { extraWritePaths: [claudeConfigDir] } : {},
2057
2110
  // Exact-file read grant — see the ACP arm's wrapAgentCliSpawn call.
2058
2111
  ...opts?.additionalReadPaths?.length ? { extraReadPaths: opts.additionalReadPaths } : {},
@@ -2068,6 +2121,7 @@ function createAgentCliRuntime(definition) {
2068
2121
  {
2069
2122
  mode: opts?.commandSandbox,
2070
2123
  cwd,
2124
+ ...opts?.fsZones ? { zones: opts.fsZones } : {},
2071
2125
  ...claudeConfigDir ? { extraWritePaths: [claudeConfigDir] } : {},
2072
2126
  // Exact-file read grant (see additionalReadPaths above):
2073
2127
  // READ-only exceptions to the confinement boundary, never writes.
@@ -2083,11 +2137,11 @@ function createAgentCliRuntime(definition) {
2083
2137
  });
2084
2138
  child = spawned;
2085
2139
  let spawnFailure;
2086
- await new Promise((resolve) => {
2087
- spawned.once("spawn", () => resolve());
2140
+ await new Promise((resolve2) => {
2141
+ spawned.once("spawn", () => resolve2());
2088
2142
  spawned.once("error", (err) => {
2089
2143
  spawnFailure = err;
2090
- resolve();
2144
+ resolve2();
2091
2145
  });
2092
2146
  });
2093
2147
  if (spawnFailure) {
@@ -2296,6 +2350,6 @@ function derivedModelRefusalError(definition, requested, reason) {
2296
2350
  );
2297
2351
  }
2298
2352
 
2299
- export { LEGACY_GATEWAY_MODE_IDS, LEGACY_POSTURE_MODE_IDS, RuntimeConfigError, agentCliFrontmatterSchema, applyModelCommand, autoAllowPermissionHandler, composeSpawn, createAcpProtocolArm, createAgentCliRuntime, createArmSessionControls, createJcodeMapperState, createMastraMapperState, createPrintSession, createProprietaryProtocolArm, defineAgentCli, inferLegacyModeKind, isLegacyExtractedModeId, isModelSwitchAcknowledgement, mapJcodeEvent, mapMastraEvent, parseModelSwitchCommand, planModePermissionHandler, promptTurn, resolveContinuationStrategy, runtimeConfigSchema, toFileBasedMcpServers };
2300
- //# sourceMappingURL=chunk-ES4VLTGZ.mjs.map
2301
- //# sourceMappingURL=chunk-ES4VLTGZ.mjs.map
2353
+ export { LEGACY_GATEWAY_MODE_IDS, LEGACY_POSTURE_MODE_IDS, RuntimeConfigError, agentCliFrontmatterSchema, agentCliSupportsHostContextIsolation, applyModelCommand, autoAllowPermissionHandler, composeSpawn, createAcpProtocolArm, createAgentCliRuntime, createArmSessionControls, createJcodeMapperState, createMastraMapperState, createPrintSession, createProprietaryProtocolArm, defineAgentCli, hostContextExcludes, inferLegacyModeKind, isLegacyExtractedModeId, isModelSwitchAcknowledgement, mapJcodeEvent, mapMastraEvent, parseModelSwitchCommand, planModePermissionHandler, promptTurn, resolveContinuationStrategy, runtimeConfigSchema, toFileBasedMcpServers };
2354
+ //# sourceMappingURL=chunk-SCR7UF3T.mjs.map
2355
+ //# sourceMappingURL=chunk-SCR7UF3T.mjs.map