refactor: remove bridge protocol

This commit is contained in:
Peter Steinberger
2026-01-19 04:50:07 +00:00
parent b347d5d9cc
commit 2f8206862a
118 changed files with 1560 additions and 8087 deletions

View File

@@ -425,7 +425,11 @@ export function createExecTool(
applyPathPrepend(env, defaultPathPrepend);
if (host === "node") {
if (security === "deny") {
const approvals = resolveExecApprovals(defaults?.agentId);
const hostSecurity = minSecurity(security, approvals.agent.security);
const hostAsk = maxAsk(ask, approvals.agent.ask);
const askFallback = approvals.agent.askFallback;
if (hostSecurity === "deny") {
throw new Error("exec denied: host=node security=deny");
}
const boundNode = defaults?.node?.trim();
@@ -465,6 +469,79 @@ export function createExecTool(
if (nodeEnv) {
applyPathPrepend(nodeEnv, defaultPathPrepend, { requireExisting: true });
}
const resolution = resolveCommandResolution(params.command, workdir, env);
const allowlistMatch =
hostSecurity === "allowlist" ? matchAllowlist(approvals.allowlist, resolution) : null;
const requiresAsk =
hostAsk === "always" ||
(hostAsk === "on-miss" && hostSecurity === "allowlist" && !allowlistMatch);
let approvedByAsk = false;
if (requiresAsk) {
const decisionResult = (await callGatewayTool("exec.approval.request", {}, {
command: params.command,
cwd: workdir,
host: "node",
security: hostSecurity,
ask: hostAsk,
agentId: defaults?.agentId,
resolvedPath: resolution?.resolvedPath ?? null,
sessionKey: defaults?.sessionKey ?? null,
timeoutMs: 120_000,
})) as { decision?: string } | null;
const decision =
decisionResult && typeof decisionResult === "object"
? decisionResult.decision ?? null
: null;
if (decision === "deny") {
throw new Error("exec denied: user denied");
}
if (!decision) {
if (askFallback === "full") {
approvedByAsk = true;
} else if (askFallback === "allowlist") {
if (!allowlistMatch) {
throw new Error(
"exec denied: approval required (approval UI not available)",
);
}
approvedByAsk = true;
} else {
throw new Error("exec denied: approval required (approval UI not available)");
}
}
if (decision === "allow-once") {
approvedByAsk = true;
}
if (decision === "allow-always") {
approvedByAsk = true;
if (hostSecurity === "allowlist") {
const pattern =
resolution?.resolvedPath ??
resolution?.rawExecutable ??
params.command.split(/\s+/).shift() ??
"";
if (pattern) {
addAllowlistEntry(approvals.file, defaults?.agentId, pattern);
}
}
}
}
if (hostSecurity === "allowlist" && !allowlistMatch && !approvedByAsk) {
throw new Error("exec denied: allowlist miss");
}
if (allowlistMatch) {
recordAllowlistUse(
approvals.file,
defaults?.agentId,
allowlistMatch,
params.command,
resolution?.resolvedPath,
);
}
const invokeParams: Record<string, unknown> = {
nodeId,
command: "system.run",
@@ -476,6 +553,7 @@ export function createExecTool(
timeoutMs: typeof params.timeout === "number" ? params.timeout * 1000 : undefined,
agentId: defaults?.agentId,
sessionKey: defaults?.sessionKey,
approved: approvedByAsk,
},
idempotencyKey: crypto.randomUUID(),
};