@agentproto/driver-agent-cli 2.5.1 → 2.6.1
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/dist/{chunk-ES4VLTGZ.mjs → chunk-EZROBN7Q.mjs} +119 -36
- package/dist/chunk-EZROBN7Q.mjs.map +1 -0
- package/dist/index.d.ts +20 -3
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/manifest/index.d.ts +2 -2
- package/dist/manifest/index.mjs +2 -2
- package/dist/{schema-80A5ZPPR.d.ts → schema-lciWmbTG.d.ts} +28 -1
- package/package.json +4 -4
- package/dist/chunk-ES4VLTGZ.mjs.map +0 -1
|
@@ -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,18 +701,34 @@ function isAlive(pid) {
|
|
|
701
701
|
}
|
|
702
702
|
}
|
|
703
703
|
function listProcesses() {
|
|
704
|
-
return new Promise((
|
|
704
|
+
return new Promise((resolve2) => {
|
|
705
705
|
execFile("ps", ["-axo", "pid=,ppid="], { maxBuffer: 32 * 1024 * 1024 }, (err, stdout) => {
|
|
706
|
-
if (err) return
|
|
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
|
-
|
|
712
|
+
resolve2(out);
|
|
713
713
|
});
|
|
714
714
|
});
|
|
715
715
|
}
|
|
716
|
+
function isWindowsBatchFile(exe, deps) {
|
|
717
|
+
if ((process.platform) !== "win32") return false;
|
|
718
|
+
return /\.(?:bat|cmd)$/i.test(exe);
|
|
719
|
+
}
|
|
720
|
+
function windowsBatchShellOption(exe, deps) {
|
|
721
|
+
if (isWindowsBatchFile(exe)) return { shell: true };
|
|
722
|
+
return {};
|
|
723
|
+
}
|
|
724
|
+
function resolveWindowsBatchSpawn(bin, args, deps) {
|
|
725
|
+
if ((process.platform) !== "win32") return void 0;
|
|
726
|
+
if (!isWindowsBatchFile(bin)) return void 0;
|
|
727
|
+
const stem = basename(bin).replace(/\.(?:bat|cmd)$/i, "");
|
|
728
|
+
if (stem !== "npx" && stem !== "npm") return void 0;
|
|
729
|
+
join(dirname(bin), "node_modules", "npm", "bin", `${stem}-cli.js`);
|
|
730
|
+
return void 0;
|
|
731
|
+
}
|
|
716
732
|
function defaultToolchainWritePaths() {
|
|
717
733
|
const home = homedir();
|
|
718
734
|
return [
|
|
@@ -743,8 +759,13 @@ function defaultToolchainReadPaths() {
|
|
|
743
759
|
}
|
|
744
760
|
async function wrapAgentCliSpawn(bin, args, opts) {
|
|
745
761
|
const cfg = await loadAdapterSpawnSandboxConfig(opts.cwd);
|
|
746
|
-
const mode = opts.mode ?? cfg.mode;
|
|
762
|
+
const mode = opts.zones ? opts.mode ?? "workspace" : opts.mode ?? cfg.mode;
|
|
747
763
|
if (mode === void 0) return [bin, args];
|
|
764
|
+
if (mode === "off" && opts.zones) {
|
|
765
|
+
throw new Error(
|
|
766
|
+
`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.`
|
|
767
|
+
);
|
|
768
|
+
}
|
|
748
769
|
if (mode === "off") {
|
|
749
770
|
console.error(
|
|
750
771
|
`[agent-cli] \u26A0 spawning '${opts.label}' UNCONFINED \u2014 no OS-level sandbox is active (commandSandbox mode is "off").`
|
|
@@ -757,18 +778,20 @@ async function wrapAgentCliSpawn(bin, args, opts) {
|
|
|
757
778
|
`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
779
|
);
|
|
759
780
|
}
|
|
781
|
+
const fileCfg = opts.zones ? void 0 : cfg;
|
|
760
782
|
const policy = {
|
|
761
783
|
workspace: opts.cwd,
|
|
762
784
|
extraReadPaths: [
|
|
763
785
|
...defaultToolchainReadPaths(),
|
|
764
|
-
...
|
|
786
|
+
...fileCfg?.extraReadPaths ?? [],
|
|
765
787
|
...opts.extraReadPaths ?? []
|
|
766
788
|
],
|
|
767
789
|
extraWritePaths: [
|
|
768
790
|
...defaultToolchainWritePaths(),
|
|
769
|
-
...
|
|
791
|
+
...fileCfg?.extraWritePaths ?? [],
|
|
770
792
|
...opts.extraWritePaths ?? []
|
|
771
793
|
],
|
|
794
|
+
...opts.zones ? { zones: opts.zones } : {},
|
|
772
795
|
network: mode === "strict" || cfg.network === "deny" ? "deny" : "allow"
|
|
773
796
|
};
|
|
774
797
|
const wrapped = backend.wrap([bin, ...args], policy);
|
|
@@ -777,12 +800,12 @@ async function wrapAgentCliSpawn(bin, args, opts) {
|
|
|
777
800
|
|
|
778
801
|
// src/protocol/print-arm.ts
|
|
779
802
|
function printModelMismatch(requested, reported) {
|
|
780
|
-
const
|
|
803
|
+
const basename3 = (id) => {
|
|
781
804
|
const noSuffix = id.split("@")[0] ?? id;
|
|
782
805
|
const segs = noSuffix.split("/");
|
|
783
806
|
return (segs[segs.length - 1] ?? noSuffix).trim().toLowerCase();
|
|
784
807
|
};
|
|
785
|
-
return
|
|
808
|
+
return basename3(requested) !== basename3(reported);
|
|
786
809
|
}
|
|
787
810
|
var DEFAULT_OUTPUT = ["--output-format", "stream-json"];
|
|
788
811
|
var DEFAULT_PRE_PROMPT = ["--no-interactive"];
|
|
@@ -822,20 +845,26 @@ function createPrintSession(opts) {
|
|
|
822
845
|
cwd: opts.cwd,
|
|
823
846
|
...opts.extraWritePaths ? { extraWritePaths: opts.extraWritePaths } : {},
|
|
824
847
|
...opts.extraReadPaths ? { extraReadPaths: opts.extraReadPaths } : {},
|
|
848
|
+
...opts.fsZones ? { zones: opts.fsZones } : {},
|
|
825
849
|
label: "print-arm"
|
|
826
850
|
});
|
|
827
851
|
const child = spawn(execBin, execArgs, {
|
|
828
852
|
cwd: opts.cwd,
|
|
829
853
|
env: opts.env,
|
|
830
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
854
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
855
|
+
// Win32: only reached for a `.cmd`/`.bat` bin that
|
|
856
|
+
// `resolveWindowsBatchSpawn` couldn't rewrite to its node entry
|
|
857
|
+
// (see `win32-spawn.ts` — Node refuses direct batch spawning,
|
|
858
|
+
// CVE-2024-27980, the recap-10 `spawn EINVAL`). POSIX: `{}`.
|
|
859
|
+
...windowsBatchShellOption(execBin)
|
|
831
860
|
});
|
|
832
861
|
activeChild = child;
|
|
833
862
|
let spawnFailure;
|
|
834
|
-
await new Promise((
|
|
835
|
-
child.once("spawn", () =>
|
|
863
|
+
await new Promise((resolve2) => {
|
|
864
|
+
child.once("spawn", () => resolve2());
|
|
836
865
|
child.once("error", (err) => {
|
|
837
866
|
spawnFailure = err;
|
|
838
|
-
|
|
867
|
+
resolve2();
|
|
839
868
|
});
|
|
840
869
|
});
|
|
841
870
|
if (spawnFailure) {
|
|
@@ -1454,16 +1483,16 @@ var EventQueue = class {
|
|
|
1454
1483
|
`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
1484
|
);
|
|
1456
1485
|
}
|
|
1457
|
-
const
|
|
1486
|
+
const resolve2 = this.resolveNext;
|
|
1458
1487
|
this.resolveNext = null;
|
|
1459
|
-
|
|
1488
|
+
resolve2?.();
|
|
1460
1489
|
}
|
|
1461
1490
|
/** Signal that no further events will be pushed. */
|
|
1462
1491
|
end() {
|
|
1463
1492
|
this.ended = true;
|
|
1464
|
-
const
|
|
1493
|
+
const resolve2 = this.resolveNext;
|
|
1465
1494
|
this.resolveNext = null;
|
|
1466
|
-
|
|
1495
|
+
resolve2?.();
|
|
1467
1496
|
}
|
|
1468
1497
|
async *[Symbol.asyncIterator]() {
|
|
1469
1498
|
for (; ; ) {
|
|
@@ -1473,8 +1502,8 @@ var EventQueue = class {
|
|
|
1473
1502
|
continue;
|
|
1474
1503
|
}
|
|
1475
1504
|
if (this.ended) return;
|
|
1476
|
-
await new Promise((
|
|
1477
|
-
this.resolveNext =
|
|
1505
|
+
await new Promise((resolve2) => {
|
|
1506
|
+
this.resolveNext = resolve2;
|
|
1478
1507
|
});
|
|
1479
1508
|
}
|
|
1480
1509
|
}
|
|
@@ -1493,9 +1522,9 @@ function mapMastraFinishReason(raw) {
|
|
|
1493
1522
|
}
|
|
1494
1523
|
}
|
|
1495
1524
|
function waitForExit(child) {
|
|
1496
|
-
return new Promise((
|
|
1497
|
-
child.once("exit", (code) =>
|
|
1498
|
-
child.once("error", () =>
|
|
1525
|
+
return new Promise((resolve2) => {
|
|
1526
|
+
child.once("exit", (code) => resolve2(code));
|
|
1527
|
+
child.once("error", () => resolve2(null));
|
|
1499
1528
|
});
|
|
1500
1529
|
}
|
|
1501
1530
|
|
|
@@ -1744,6 +1773,42 @@ function interpolateEnv(env, value) {
|
|
|
1744
1773
|
}
|
|
1745
1774
|
return out;
|
|
1746
1775
|
}
|
|
1776
|
+
function agentCliSupportsHostContextIsolation(adapterId) {
|
|
1777
|
+
return adapterId === "claude-code";
|
|
1778
|
+
}
|
|
1779
|
+
function escapeGlob(p) {
|
|
1780
|
+
return p.replace(/[\\*?[\]{}()!+@]/g, "\\$&");
|
|
1781
|
+
}
|
|
1782
|
+
function ancestors(dir) {
|
|
1783
|
+
const out = [];
|
|
1784
|
+
let cur = dirname(dir);
|
|
1785
|
+
for (; ; ) {
|
|
1786
|
+
out.push(cur);
|
|
1787
|
+
const parent = dirname(cur);
|
|
1788
|
+
if (parent === cur) return out;
|
|
1789
|
+
cur = parent;
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
function hostContextExcludes(cwd) {
|
|
1793
|
+
const abs = resolve(cwd);
|
|
1794
|
+
let real = abs;
|
|
1795
|
+
try {
|
|
1796
|
+
real = realpathSync(abs);
|
|
1797
|
+
} catch {
|
|
1798
|
+
}
|
|
1799
|
+
const dirs = /* @__PURE__ */ new Set([...ancestors(abs), ...ancestors(real)]);
|
|
1800
|
+
const out = [];
|
|
1801
|
+
for (const d of dirs) {
|
|
1802
|
+
const base = d === "/" ? "" : escapeGlob(d);
|
|
1803
|
+
out.push(
|
|
1804
|
+
`${base}/CLAUDE.md`,
|
|
1805
|
+
`${base}/CLAUDE.local.md`,
|
|
1806
|
+
`${base}/.claude/CLAUDE.md`,
|
|
1807
|
+
`${base}/.claude/rules/**`
|
|
1808
|
+
);
|
|
1809
|
+
}
|
|
1810
|
+
return out;
|
|
1811
|
+
}
|
|
1747
1812
|
function createArmSessionControls(arm, definition) {
|
|
1748
1813
|
const modelApply = definition.models?.apply ?? "config";
|
|
1749
1814
|
return {
|
|
@@ -1998,6 +2063,9 @@ function createAgentCliRuntime(definition) {
|
|
|
1998
2063
|
}
|
|
1999
2064
|
const spawnBin = npxFast?.bin ?? resolvedBin;
|
|
2000
2065
|
const spawnArgs = npxFast?.args ?? composed.binArgs;
|
|
2066
|
+
const batchRewrite = resolveWindowsBatchSpawn(spawnBin);
|
|
2067
|
+
const finalBin = batchRewrite?.bin ?? spawnBin;
|
|
2068
|
+
const finalArgs = batchRewrite?.args ?? spawnArgs;
|
|
2001
2069
|
if (opts?.additionalReadPaths?.length) {
|
|
2002
2070
|
env.AGENTPROTO_ADDITIONAL_READ_PATHS = JSON.stringify(opts.additionalReadPaths);
|
|
2003
2071
|
}
|
|
@@ -2033,8 +2101,16 @@ function createAgentCliRuntime(definition) {
|
|
|
2033
2101
|
const isolatedSettings = {
|
|
2034
2102
|
attribution: { commit: "", pr: "", sessionUrl: false }
|
|
2035
2103
|
};
|
|
2036
|
-
|
|
2037
|
-
|
|
2104
|
+
const isolatedPermissions = {};
|
|
2105
|
+
if (permissionMode) isolatedPermissions.defaultMode = permissionMode;
|
|
2106
|
+
if (opts?.fsZones?.writable.length) {
|
|
2107
|
+
isolatedPermissions.additionalDirectories = opts.fsZones.writable;
|
|
2108
|
+
}
|
|
2109
|
+
if (Object.keys(isolatedPermissions).length > 0) {
|
|
2110
|
+
isolatedSettings.permissions = isolatedPermissions;
|
|
2111
|
+
}
|
|
2112
|
+
if (opts?.isolateHostContext) {
|
|
2113
|
+
isolatedSettings.claudeMdExcludes = hostContextExcludes(cwd);
|
|
2038
2114
|
}
|
|
2039
2115
|
writeFileSync(
|
|
2040
2116
|
join(claudeConfigDir, "settings.json"),
|
|
@@ -2045,14 +2121,15 @@ function createAgentCliRuntime(definition) {
|
|
|
2045
2121
|
if (definition.protocol === "print") {
|
|
2046
2122
|
const printModel = config?.options?.model;
|
|
2047
2123
|
return createPrintSession({
|
|
2048
|
-
bin:
|
|
2049
|
-
baseArgs:
|
|
2124
|
+
bin: finalBin,
|
|
2125
|
+
baseArgs: finalArgs,
|
|
2050
2126
|
cwd,
|
|
2051
2127
|
env,
|
|
2052
2128
|
...opts?.resumeSessionId ? { resumeSessionId: opts.resumeSessionId } : {},
|
|
2053
2129
|
...opts?.mcpServers ? { mcpServers: opts.mcpServers } : {},
|
|
2054
2130
|
printConfig: definition.print,
|
|
2055
2131
|
commandSandbox: opts?.commandSandbox,
|
|
2132
|
+
...opts?.fsZones ? { fsZones: opts.fsZones } : {},
|
|
2056
2133
|
...claudeConfigDir ? { extraWritePaths: [claudeConfigDir] } : {},
|
|
2057
2134
|
// Exact-file read grant — see the ACP arm's wrapAgentCliSpawn call.
|
|
2058
2135
|
...opts?.additionalReadPaths?.length ? { extraReadPaths: opts.additionalReadPaths } : {},
|
|
@@ -2063,11 +2140,12 @@ function createAgentCliRuntime(definition) {
|
|
|
2063
2140
|
const stderrBuf = [];
|
|
2064
2141
|
if (definition.protocol !== "proprietary") {
|
|
2065
2142
|
const [execBin, execArgs] = await wrapAgentCliSpawn(
|
|
2066
|
-
|
|
2067
|
-
|
|
2143
|
+
finalBin,
|
|
2144
|
+
finalArgs,
|
|
2068
2145
|
{
|
|
2069
2146
|
mode: opts?.commandSandbox,
|
|
2070
2147
|
cwd,
|
|
2148
|
+
...opts?.fsZones ? { zones: opts.fsZones } : {},
|
|
2071
2149
|
...claudeConfigDir ? { extraWritePaths: [claudeConfigDir] } : {},
|
|
2072
2150
|
// Exact-file read grant (see additionalReadPaths above):
|
|
2073
2151
|
// READ-only exceptions to the confinement boundary, never writes.
|
|
@@ -2079,15 +2157,20 @@ function createAgentCliRuntime(definition) {
|
|
|
2079
2157
|
cwd,
|
|
2080
2158
|
env,
|
|
2081
2159
|
stdio: ["pipe", "pipe", "pipe"],
|
|
2082
|
-
signal: opts?.signal
|
|
2160
|
+
signal: opts?.signal,
|
|
2161
|
+
// Win32: a `.cmd`/`.bat` bin that `resolveWindowsBatchSpawn`
|
|
2162
|
+
// couldn't rewrite to its node entry needs the shell — Node
|
|
2163
|
+
// refuses to spawn batch files directly (CVE-2024-27980, the
|
|
2164
|
+
// recap-10 `spawn EINVAL`). POSIX: `{}` — unchanged.
|
|
2165
|
+
...windowsBatchShellOption(execBin)
|
|
2083
2166
|
});
|
|
2084
2167
|
child = spawned;
|
|
2085
2168
|
let spawnFailure;
|
|
2086
|
-
await new Promise((
|
|
2087
|
-
spawned.once("spawn", () =>
|
|
2169
|
+
await new Promise((resolve2) => {
|
|
2170
|
+
spawned.once("spawn", () => resolve2());
|
|
2088
2171
|
spawned.once("error", (err) => {
|
|
2089
2172
|
spawnFailure = err;
|
|
2090
|
-
|
|
2173
|
+
resolve2();
|
|
2091
2174
|
});
|
|
2092
2175
|
});
|
|
2093
2176
|
if (spawnFailure) {
|
|
@@ -2296,6 +2379,6 @@ function derivedModelRefusalError(definition, requested, reason) {
|
|
|
2296
2379
|
);
|
|
2297
2380
|
}
|
|
2298
2381
|
|
|
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-
|
|
2301
|
-
//# sourceMappingURL=chunk-
|
|
2382
|
+
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 };
|
|
2383
|
+
//# sourceMappingURL=chunk-EZROBN7Q.mjs.map
|
|
2384
|
+
//# sourceMappingURL=chunk-EZROBN7Q.mjs.map
|