@agentproto/driver-agent-cli 2.8.0 → 2.10.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-E45SX7GU.mjs → chunk-K5PKRW2Q.mjs} +127 -27
- package/dist/chunk-K5PKRW2Q.mjs.map +1 -0
- package/dist/index.d.ts +26 -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-DafVng6S.d.ts → schema-M-CpE8Yf.d.ts} +58 -1
- package/package.json +1 -1
- package/dist/chunk-E45SX7GU.mjs.map +0 -1
|
@@ -2,7 +2,7 @@ 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, realpathSync, mkdtempSync } from 'fs';
|
|
5
|
+
import { existsSync, readFileSync, mkdirSync, writeFileSync, rmSync, rmdirSync, realpathSync, mkdtempSync, lstatSync, unlinkSync, symlinkSync } from 'fs';
|
|
6
6
|
import { createInterface } from 'readline';
|
|
7
7
|
import { join, isAbsolute, resolve, delimiter, dirname, basename } from 'path';
|
|
8
8
|
import { tmpdir, homedir } from 'os';
|
|
@@ -392,6 +392,15 @@ var agentCliFrontmatterSchema = z.object({
|
|
|
392
392
|
routeSelection: z.enum(["free", "derived-from-model"]).optional(),
|
|
393
393
|
authEnforce: z.enum(["always", "when-configured"]).optional(),
|
|
394
394
|
sandbox: z.union([z.string(), z.record(z.string(), z.unknown())]),
|
|
395
|
+
stateHome: z.object({
|
|
396
|
+
env: z.string().regex(/^[A-Z][A-Z0-9_]*$/),
|
|
397
|
+
defaultDir: z.string().min(1).refine((d) => !d.startsWith("/") && !d.split("/").includes(".."), {
|
|
398
|
+
message: "defaultDir must be relative to $HOME and stay inside it"
|
|
399
|
+
}),
|
|
400
|
+
share: z.array(z.string().regex(/^[^/]+$/)).optional(),
|
|
401
|
+
seed: z.record(z.string().regex(/^[^/]+$/).refine((n) => n !== "." && n !== "..", { message: "seed names a file of the home" }), z.string()).optional()
|
|
402
|
+
}).strict().optional(),
|
|
403
|
+
credentialDataHome: z.object({ env: z.string().regex(/^[A-Z][A-Z0-9_]*$/) }).strict().optional(),
|
|
395
404
|
runner: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
|
|
396
405
|
protocol: z.enum(["acp", "mcp", "proprietary", "print"]),
|
|
397
406
|
acp: z.string().optional(),
|
|
@@ -720,15 +729,15 @@ function isAlive(pid) {
|
|
|
720
729
|
}
|
|
721
730
|
}
|
|
722
731
|
function listProcesses() {
|
|
723
|
-
return new Promise((
|
|
732
|
+
return new Promise((resolve3) => {
|
|
724
733
|
execFile("ps", ["-axo", "pid=,ppid="], { maxBuffer: 32 * 1024 * 1024 }, (err, stdout) => {
|
|
725
|
-
if (err) return
|
|
734
|
+
if (err) return resolve3([]);
|
|
726
735
|
const out = [];
|
|
727
736
|
for (const line of stdout.split("\n")) {
|
|
728
737
|
const m = line.match(/^\s*(\d+)\s+(\d+)\s*$/);
|
|
729
738
|
if (m) out.push({ pid: Number(m[1]), ppid: Number(m[2]) });
|
|
730
739
|
}
|
|
731
|
-
|
|
740
|
+
resolve3(out);
|
|
732
741
|
});
|
|
733
742
|
});
|
|
734
743
|
}
|
|
@@ -777,9 +786,17 @@ function defaultToolchainReadPaths() {
|
|
|
777
786
|
// macOS Keychain DB — git/gh credential retrieval (read-only; see doc above)
|
|
778
787
|
];
|
|
779
788
|
}
|
|
789
|
+
function effectiveSpawnSandboxMode(opts, configured) {
|
|
790
|
+
return opts.zones ? opts.mode ?? "workspace" : opts.mode ?? configured;
|
|
791
|
+
}
|
|
792
|
+
async function willConfineAgentCliSpawn(opts) {
|
|
793
|
+
const cfg = await loadAdapterSpawnSandboxConfig(opts.cwd);
|
|
794
|
+
const mode = effectiveSpawnSandboxMode(opts, cfg.mode);
|
|
795
|
+
return mode !== void 0 && mode !== "off";
|
|
796
|
+
}
|
|
780
797
|
async function wrapAgentCliSpawn(bin, args, opts) {
|
|
781
798
|
const cfg = await loadAdapterSpawnSandboxConfig(opts.cwd);
|
|
782
|
-
const mode = opts
|
|
799
|
+
const mode = effectiveSpawnSandboxMode(opts, cfg.mode);
|
|
783
800
|
if (mode === void 0) return [bin, args];
|
|
784
801
|
if (mode === "off" && opts.zones) {
|
|
785
802
|
throw new Error(
|
|
@@ -880,11 +897,11 @@ function createPrintSession(opts) {
|
|
|
880
897
|
});
|
|
881
898
|
activeChild = child;
|
|
882
899
|
let spawnFailure;
|
|
883
|
-
await new Promise((
|
|
884
|
-
child.once("spawn", () =>
|
|
900
|
+
await new Promise((resolve3) => {
|
|
901
|
+
child.once("spawn", () => resolve3());
|
|
885
902
|
child.once("error", (err) => {
|
|
886
903
|
spawnFailure = err;
|
|
887
|
-
|
|
904
|
+
resolve3();
|
|
888
905
|
});
|
|
889
906
|
});
|
|
890
907
|
if (spawnFailure) {
|
|
@@ -1503,16 +1520,16 @@ var EventQueue = class {
|
|
|
1503
1520
|
`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.`
|
|
1504
1521
|
);
|
|
1505
1522
|
}
|
|
1506
|
-
const
|
|
1523
|
+
const resolve3 = this.resolveNext;
|
|
1507
1524
|
this.resolveNext = null;
|
|
1508
|
-
|
|
1525
|
+
resolve3?.();
|
|
1509
1526
|
}
|
|
1510
1527
|
/** Signal that no further events will be pushed. */
|
|
1511
1528
|
end() {
|
|
1512
1529
|
this.ended = true;
|
|
1513
|
-
const
|
|
1530
|
+
const resolve3 = this.resolveNext;
|
|
1514
1531
|
this.resolveNext = null;
|
|
1515
|
-
|
|
1532
|
+
resolve3?.();
|
|
1516
1533
|
}
|
|
1517
1534
|
async *[Symbol.asyncIterator]() {
|
|
1518
1535
|
for (; ; ) {
|
|
@@ -1522,8 +1539,8 @@ var EventQueue = class {
|
|
|
1522
1539
|
continue;
|
|
1523
1540
|
}
|
|
1524
1541
|
if (this.ended) return;
|
|
1525
|
-
await new Promise((
|
|
1526
|
-
this.resolveNext =
|
|
1542
|
+
await new Promise((resolve3) => {
|
|
1543
|
+
this.resolveNext = resolve3;
|
|
1527
1544
|
});
|
|
1528
1545
|
}
|
|
1529
1546
|
}
|
|
@@ -1542,9 +1559,9 @@ function mapMastraFinishReason(raw) {
|
|
|
1542
1559
|
}
|
|
1543
1560
|
}
|
|
1544
1561
|
function waitForExit(child) {
|
|
1545
|
-
return new Promise((
|
|
1546
|
-
child.once("exit", (code) =>
|
|
1547
|
-
child.once("error", () =>
|
|
1562
|
+
return new Promise((resolve3) => {
|
|
1563
|
+
child.once("exit", (code) => resolve3(code));
|
|
1564
|
+
child.once("error", () => resolve3(null));
|
|
1548
1565
|
});
|
|
1549
1566
|
}
|
|
1550
1567
|
async function createProprietaryProtocolArm(options) {
|
|
@@ -1792,6 +1809,49 @@ function interpolateEnv(env, value) {
|
|
|
1792
1809
|
}
|
|
1793
1810
|
return out;
|
|
1794
1811
|
}
|
|
1812
|
+
function realStateHome(stateHome, env) {
|
|
1813
|
+
const fromEnv = env[stateHome.env];
|
|
1814
|
+
if (fromEnv && isAbsolute(fromEnv)) return fromEnv;
|
|
1815
|
+
return resolve(homedir(), stateHome.defaultDir);
|
|
1816
|
+
}
|
|
1817
|
+
function prepareIsolatedStateHome(stateHome, opts) {
|
|
1818
|
+
const real = realStateHome(stateHome, opts.env);
|
|
1819
|
+
let dir;
|
|
1820
|
+
if (opts.configDir) {
|
|
1821
|
+
dir = opts.configDir;
|
|
1822
|
+
mkdirSync(dir, { recursive: true });
|
|
1823
|
+
} else {
|
|
1824
|
+
dir = mkdtempSync(join(tmpdir(), `agentproto-${stateHome.env.toLowerCase()}-`));
|
|
1825
|
+
}
|
|
1826
|
+
const writePaths = [dir];
|
|
1827
|
+
for (const name of stateHome.share ?? []) {
|
|
1828
|
+
const target = join(real, name);
|
|
1829
|
+
const link = join(dir, name);
|
|
1830
|
+
try {
|
|
1831
|
+
lstatSync(link);
|
|
1832
|
+
unlinkSync(link);
|
|
1833
|
+
} catch {
|
|
1834
|
+
}
|
|
1835
|
+
if (!existsSync(target)) continue;
|
|
1836
|
+
symlinkSync(target, link);
|
|
1837
|
+
writePaths.push(realpathSync(target));
|
|
1838
|
+
}
|
|
1839
|
+
for (const [name, content] of Object.entries(stateHome.seed ?? {})) {
|
|
1840
|
+
const file = join(dir, name);
|
|
1841
|
+
try {
|
|
1842
|
+
unlinkSync(file);
|
|
1843
|
+
} catch {
|
|
1844
|
+
}
|
|
1845
|
+
writeFileSync(file, content);
|
|
1846
|
+
}
|
|
1847
|
+
return { dir, writePaths };
|
|
1848
|
+
}
|
|
1849
|
+
var CREDENTIAL_DATA_SUBDIR = "auth-data";
|
|
1850
|
+
function isolatedCredentialDataHome(configDir) {
|
|
1851
|
+
const dir = configDir ? join(configDir, CREDENTIAL_DATA_SUBDIR) : mkdtempSync(join(tmpdir(), "agentproto-data-"));
|
|
1852
|
+
mkdirSync(dir, { recursive: true });
|
|
1853
|
+
return dir;
|
|
1854
|
+
}
|
|
1795
1855
|
function agentCliSupportsHostContextIsolation(adapterId) {
|
|
1796
1856
|
return adapterId === "claude-code";
|
|
1797
1857
|
}
|
|
@@ -1981,8 +2041,8 @@ async function* promptTurn(arm, turnId, message, stderrTurnError) {
|
|
|
1981
2041
|
return;
|
|
1982
2042
|
}
|
|
1983
2043
|
const nextEvent = iterator.next();
|
|
1984
|
-
const stderrArrived = new Promise((
|
|
1985
|
-
wake =
|
|
2044
|
+
const stderrArrived = new Promise((resolve3) => {
|
|
2045
|
+
wake = resolve3;
|
|
1986
2046
|
});
|
|
1987
2047
|
const winner = await Promise.race([
|
|
1988
2048
|
nextEvent.then((result) => ({ source: "event", result })),
|
|
@@ -2111,6 +2171,26 @@ function ensureExecDirOnPath(env, execPath = process.execPath) {
|
|
|
2111
2171
|
if (parts.includes(execDir)) return;
|
|
2112
2172
|
env.PATH = [...parts, execDir].join(delimiter);
|
|
2113
2173
|
}
|
|
2174
|
+
function isPlainObject(v) {
|
|
2175
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
2176
|
+
}
|
|
2177
|
+
function deepMergeJson(base, over) {
|
|
2178
|
+
const out = { ...base };
|
|
2179
|
+
for (const [k, v] of Object.entries(over)) {
|
|
2180
|
+
const prev = out[k];
|
|
2181
|
+
out[k] = isPlainObject(prev) && isPlainObject(v) ? deepMergeJson(prev, v) : v;
|
|
2182
|
+
}
|
|
2183
|
+
return out;
|
|
2184
|
+
}
|
|
2185
|
+
function mergeJsonEnvValue(base, over) {
|
|
2186
|
+
try {
|
|
2187
|
+
const a = JSON.parse(base);
|
|
2188
|
+
const b = JSON.parse(over);
|
|
2189
|
+
if (isPlainObject(a) && isPlainObject(b)) return JSON.stringify(deepMergeJson(a, b));
|
|
2190
|
+
} catch {
|
|
2191
|
+
}
|
|
2192
|
+
return over;
|
|
2193
|
+
}
|
|
2114
2194
|
function createAgentCliRuntime(definition) {
|
|
2115
2195
|
return {
|
|
2116
2196
|
definition,
|
|
@@ -2128,6 +2208,7 @@ function createAgentCliRuntime(definition) {
|
|
|
2128
2208
|
};
|
|
2129
2209
|
for (const k of composed.envUnset) delete env[k];
|
|
2130
2210
|
const authSpec = opts?.auth;
|
|
2211
|
+
let credentialDataDir;
|
|
2131
2212
|
const hasGatewayAuthToken = "ANTHROPIC_AUTH_TOKEN" in composed.env;
|
|
2132
2213
|
const hasGatewayBaseUrl = "ANTHROPIC_BASE_URL" in composed.env;
|
|
2133
2214
|
const resolverCoupledGateway = authSpec?.baseUrl !== void 0;
|
|
@@ -2147,6 +2228,15 @@ function createAgentCliRuntime(definition) {
|
|
|
2147
2228
|
throw new RuntimeConfigError("missing_auth_credential", "opts.auth.credential", message);
|
|
2148
2229
|
}
|
|
2149
2230
|
env[authSpec.setEnv] = authSpec.credential;
|
|
2231
|
+
if (authSpec.extraEnv) {
|
|
2232
|
+
for (const [key, value] of Object.entries(authSpec.extraEnv)) {
|
|
2233
|
+
env[key] = key in composed.env ? mergeJsonEnvValue(composed.env[key], value) : value;
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
if (definition.credentialDataHome && authSpec.isolateDataHome !== false) {
|
|
2237
|
+
credentialDataDir = isolatedCredentialDataHome(opts?.configDir);
|
|
2238
|
+
env[definition.credentialDataHome.env] = credentialDataDir;
|
|
2239
|
+
}
|
|
2150
2240
|
}
|
|
2151
2241
|
}
|
|
2152
2242
|
Object.assign(env, opts?.env ?? {});
|
|
@@ -2212,6 +2302,16 @@ function createAgentCliRuntime(definition) {
|
|
|
2212
2302
|
);
|
|
2213
2303
|
env.CLAUDE_CONFIG_DIR = claudeConfigDir;
|
|
2214
2304
|
}
|
|
2305
|
+
const extraWritePaths = claudeConfigDir ? [claudeConfigDir] : [];
|
|
2306
|
+
if (credentialDataDir) extraWritePaths.push(credentialDataDir);
|
|
2307
|
+
if (definition.stateHome && definition.protocol !== "proprietary" && await willConfineAgentCliSpawn({ mode: opts?.commandSandbox, cwd, zones: opts?.fsZones })) {
|
|
2308
|
+
const isolated = prepareIsolatedStateHome(definition.stateHome, {
|
|
2309
|
+
...opts?.configDir ? { configDir: opts.configDir } : {},
|
|
2310
|
+
env
|
|
2311
|
+
});
|
|
2312
|
+
env[definition.stateHome.env] = isolated.dir;
|
|
2313
|
+
extraWritePaths.push(...isolated.writePaths);
|
|
2314
|
+
}
|
|
2215
2315
|
if (definition.protocol === "print") {
|
|
2216
2316
|
const printModel = config?.options?.model;
|
|
2217
2317
|
return createPrintSession({
|
|
@@ -2224,7 +2324,7 @@ function createAgentCliRuntime(definition) {
|
|
|
2224
2324
|
printConfig: definition.print,
|
|
2225
2325
|
commandSandbox: opts?.commandSandbox,
|
|
2226
2326
|
...opts?.fsZones ? { fsZones: opts.fsZones } : {},
|
|
2227
|
-
...
|
|
2327
|
+
...extraWritePaths.length ? { extraWritePaths } : {},
|
|
2228
2328
|
// Exact-file read grant — see the ACP arm's wrapAgentCliSpawn call.
|
|
2229
2329
|
...opts?.additionalReadPaths?.length ? { extraReadPaths: opts.additionalReadPaths } : {},
|
|
2230
2330
|
...definition.routeSelection === "derived-from-model" && printModel ? { expectedModel: String(printModel) } : {}
|
|
@@ -2241,7 +2341,7 @@ function createAgentCliRuntime(definition) {
|
|
|
2241
2341
|
mode: opts?.commandSandbox,
|
|
2242
2342
|
cwd,
|
|
2243
2343
|
...opts?.fsZones ? { zones: opts.fsZones } : {},
|
|
2244
|
-
...
|
|
2344
|
+
...extraWritePaths.length ? { extraWritePaths } : {},
|
|
2245
2345
|
// Exact-file read grant (see additionalReadPaths above):
|
|
2246
2346
|
// READ-only exceptions to the confinement boundary, never writes.
|
|
2247
2347
|
...opts?.additionalReadPaths?.length ? { extraReadPaths: opts.additionalReadPaths } : {},
|
|
@@ -2261,11 +2361,11 @@ function createAgentCliRuntime(definition) {
|
|
|
2261
2361
|
});
|
|
2262
2362
|
child = spawned;
|
|
2263
2363
|
let spawnFailure;
|
|
2264
|
-
await new Promise((
|
|
2265
|
-
spawned.once("spawn", () =>
|
|
2364
|
+
await new Promise((resolve3) => {
|
|
2365
|
+
spawned.once("spawn", () => resolve3());
|
|
2266
2366
|
spawned.once("error", (err) => {
|
|
2267
2367
|
spawnFailure = err;
|
|
2268
|
-
|
|
2368
|
+
resolve3();
|
|
2269
2369
|
});
|
|
2270
2370
|
});
|
|
2271
2371
|
if (spawnFailure) {
|
|
@@ -2486,6 +2586,6 @@ function derivedModelRefusalError(definition, requested, reason) {
|
|
|
2486
2586
|
);
|
|
2487
2587
|
}
|
|
2488
2588
|
|
|
2489
|
-
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 };
|
|
2490
|
-
//# sourceMappingURL=chunk-
|
|
2491
|
-
//# sourceMappingURL=chunk-
|
|
2589
|
+
export { CREDENTIAL_DATA_SUBDIR, 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 };
|
|
2590
|
+
//# sourceMappingURL=chunk-K5PKRW2Q.mjs.map
|
|
2591
|
+
//# sourceMappingURL=chunk-K5PKRW2Q.mjs.map
|