@agentproto/driver-agent-cli 2.5.0 → 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.
- package/dist/{chunk-JPL6CMLQ.mjs → chunk-SCR7UF3T.mjs} +100 -34
- package/dist/chunk-SCR7UF3T.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-JPL6CMLQ.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,15 +701,15 @@ 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
|
}
|
|
@@ -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
|
-
...
|
|
770
|
+
...fileCfg?.extraReadPaths ?? [],
|
|
765
771
|
...opts.extraReadPaths ?? []
|
|
766
772
|
],
|
|
767
773
|
extraWritePaths: [
|
|
768
774
|
...defaultToolchainWritePaths(),
|
|
769
|
-
...
|
|
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((
|
|
835
|
-
child.once("spawn", () =>
|
|
842
|
+
await new Promise((resolve2) => {
|
|
843
|
+
child.once("spawn", () => resolve2());
|
|
836
844
|
child.once("error", (err) => {
|
|
837
845
|
spawnFailure = err;
|
|
838
|
-
|
|
846
|
+
resolve2();
|
|
839
847
|
});
|
|
840
848
|
});
|
|
841
849
|
if (spawnFailure) {
|
|
@@ -1033,14 +1041,26 @@ function setupMcpConfigFile(opts, eventSchema) {
|
|
|
1033
1041
|
}
|
|
1034
1042
|
function extractPromptText(message) {
|
|
1035
1043
|
if (typeof message === "string") return message;
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
if (
|
|
1040
|
-
|
|
1044
|
+
const blocks = Array.isArray(message) ? message : [message];
|
|
1045
|
+
const texts = [];
|
|
1046
|
+
for (const block of blocks) {
|
|
1047
|
+
if (block !== null && typeof block === "object") {
|
|
1048
|
+
const b = block;
|
|
1049
|
+
if (b.type === "text" && typeof b.text === "string") {
|
|
1050
|
+
texts.push(b.text);
|
|
1051
|
+
continue;
|
|
1052
|
+
}
|
|
1053
|
+
if (b.type === void 0 && typeof b.text === "string") {
|
|
1054
|
+
texts.push(b.text);
|
|
1055
|
+
continue;
|
|
1056
|
+
}
|
|
1041
1057
|
}
|
|
1058
|
+
const kind = block !== null && typeof block === "object" && typeof block.type === "string" ? block.type : typeof block;
|
|
1059
|
+
throw new Error(
|
|
1060
|
+
`this adapter has no multimodal input (capabilities.multimodal: false) \u2014 got a "${kind}" content block it can't send. Upload the file via POST /files/upload and reference its path in the prompt text instead.`
|
|
1061
|
+
);
|
|
1042
1062
|
}
|
|
1043
|
-
return
|
|
1063
|
+
return texts.join("\n");
|
|
1044
1064
|
}
|
|
1045
1065
|
function captureSessionId(evt, schema) {
|
|
1046
1066
|
switch (schema) {
|
|
@@ -1442,16 +1462,16 @@ var EventQueue = class {
|
|
|
1442
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.`
|
|
1443
1463
|
);
|
|
1444
1464
|
}
|
|
1445
|
-
const
|
|
1465
|
+
const resolve2 = this.resolveNext;
|
|
1446
1466
|
this.resolveNext = null;
|
|
1447
|
-
|
|
1467
|
+
resolve2?.();
|
|
1448
1468
|
}
|
|
1449
1469
|
/** Signal that no further events will be pushed. */
|
|
1450
1470
|
end() {
|
|
1451
1471
|
this.ended = true;
|
|
1452
|
-
const
|
|
1472
|
+
const resolve2 = this.resolveNext;
|
|
1453
1473
|
this.resolveNext = null;
|
|
1454
|
-
|
|
1474
|
+
resolve2?.();
|
|
1455
1475
|
}
|
|
1456
1476
|
async *[Symbol.asyncIterator]() {
|
|
1457
1477
|
for (; ; ) {
|
|
@@ -1461,8 +1481,8 @@ var EventQueue = class {
|
|
|
1461
1481
|
continue;
|
|
1462
1482
|
}
|
|
1463
1483
|
if (this.ended) return;
|
|
1464
|
-
await new Promise((
|
|
1465
|
-
this.resolveNext =
|
|
1484
|
+
await new Promise((resolve2) => {
|
|
1485
|
+
this.resolveNext = resolve2;
|
|
1466
1486
|
});
|
|
1467
1487
|
}
|
|
1468
1488
|
}
|
|
@@ -1481,9 +1501,9 @@ function mapMastraFinishReason(raw) {
|
|
|
1481
1501
|
}
|
|
1482
1502
|
}
|
|
1483
1503
|
function waitForExit(child) {
|
|
1484
|
-
return new Promise((
|
|
1485
|
-
child.once("exit", (code) =>
|
|
1486
|
-
child.once("error", () =>
|
|
1504
|
+
return new Promise((resolve2) => {
|
|
1505
|
+
child.once("exit", (code) => resolve2(code));
|
|
1506
|
+
child.once("error", () => resolve2(null));
|
|
1487
1507
|
});
|
|
1488
1508
|
}
|
|
1489
1509
|
|
|
@@ -1732,6 +1752,42 @@ function interpolateEnv(env, value) {
|
|
|
1732
1752
|
}
|
|
1733
1753
|
return out;
|
|
1734
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
|
+
}
|
|
1735
1791
|
function createArmSessionControls(arm, definition) {
|
|
1736
1792
|
const modelApply = definition.models?.apply ?? "config";
|
|
1737
1793
|
return {
|
|
@@ -2021,8 +2077,16 @@ function createAgentCliRuntime(definition) {
|
|
|
2021
2077
|
const isolatedSettings = {
|
|
2022
2078
|
attribution: { commit: "", pr: "", sessionUrl: false }
|
|
2023
2079
|
};
|
|
2024
|
-
|
|
2025
|
-
|
|
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);
|
|
2026
2090
|
}
|
|
2027
2091
|
writeFileSync(
|
|
2028
2092
|
join(claudeConfigDir, "settings.json"),
|
|
@@ -2041,6 +2105,7 @@ function createAgentCliRuntime(definition) {
|
|
|
2041
2105
|
...opts?.mcpServers ? { mcpServers: opts.mcpServers } : {},
|
|
2042
2106
|
printConfig: definition.print,
|
|
2043
2107
|
commandSandbox: opts?.commandSandbox,
|
|
2108
|
+
...opts?.fsZones ? { fsZones: opts.fsZones } : {},
|
|
2044
2109
|
...claudeConfigDir ? { extraWritePaths: [claudeConfigDir] } : {},
|
|
2045
2110
|
// Exact-file read grant — see the ACP arm's wrapAgentCliSpawn call.
|
|
2046
2111
|
...opts?.additionalReadPaths?.length ? { extraReadPaths: opts.additionalReadPaths } : {},
|
|
@@ -2056,6 +2121,7 @@ function createAgentCliRuntime(definition) {
|
|
|
2056
2121
|
{
|
|
2057
2122
|
mode: opts?.commandSandbox,
|
|
2058
2123
|
cwd,
|
|
2124
|
+
...opts?.fsZones ? { zones: opts.fsZones } : {},
|
|
2059
2125
|
...claudeConfigDir ? { extraWritePaths: [claudeConfigDir] } : {},
|
|
2060
2126
|
// Exact-file read grant (see additionalReadPaths above):
|
|
2061
2127
|
// READ-only exceptions to the confinement boundary, never writes.
|
|
@@ -2071,11 +2137,11 @@ function createAgentCliRuntime(definition) {
|
|
|
2071
2137
|
});
|
|
2072
2138
|
child = spawned;
|
|
2073
2139
|
let spawnFailure;
|
|
2074
|
-
await new Promise((
|
|
2075
|
-
spawned.once("spawn", () =>
|
|
2140
|
+
await new Promise((resolve2) => {
|
|
2141
|
+
spawned.once("spawn", () => resolve2());
|
|
2076
2142
|
spawned.once("error", (err) => {
|
|
2077
2143
|
spawnFailure = err;
|
|
2078
|
-
|
|
2144
|
+
resolve2();
|
|
2079
2145
|
});
|
|
2080
2146
|
});
|
|
2081
2147
|
if (spawnFailure) {
|
|
@@ -2284,6 +2350,6 @@ function derivedModelRefusalError(definition, requested, reason) {
|
|
|
2284
2350
|
);
|
|
2285
2351
|
}
|
|
2286
2352
|
|
|
2287
|
-
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 };
|
|
2288
|
-
//# sourceMappingURL=chunk-
|
|
2289
|
-
//# sourceMappingURL=chunk-
|
|
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
|