fix: restore doctor sandbox warnings

This commit is contained in:
Peter Steinberger
2026-01-08 01:32:04 +01:00
parent 05b8679c8b
commit 3f1807b6cb
4 changed files with 53 additions and 5 deletions

View File

@@ -1,8 +1,8 @@
import chalk from "chalk";
import type { Command } from "commander";
import type { CronJob, CronSchedule } from "../cron/types.js";
import { danger } from "../globals.js";
import { defaultRuntime } from "../runtime.js";
import type { CronJob, CronSchedule } from "../cron/types.js";
import type { GatewayRpcOpts } from "./gateway-rpc.js";
import { addGatewayClientOptions, callGatewayFromCli } from "./gateway-rpc.js";
@@ -122,8 +122,11 @@ const formatStatus = (job: CronJob) => {
return job.state.lastStatus ?? "idle";
};
const colorize = (rich: boolean, color: (msg: string) => string, msg: string) =>
rich ? color(msg) : msg;
const colorize = (
rich: boolean,
color: (msg: string) => string,
msg: string,
) => (rich ? color(msg) : msg);
function printCronList(jobs: CronJob[], runtime = defaultRuntime) {
if (jobs.length === 0) {

View File

@@ -7,6 +7,7 @@ import {
DEFAULT_SANDBOX_BROWSER_IMAGE,
DEFAULT_SANDBOX_COMMON_IMAGE,
DEFAULT_SANDBOX_IMAGE,
resolveSandboxScope,
} from "../agents/sandbox.js";
import type { ClawdbotConfig } from "../config/config.js";
import { runCommandWithTimeout, runExec } from "../process/exec.js";
@@ -248,3 +249,44 @@ export async function maybeRepairSandboxImages(
return next;
}
export function noteSandboxScopeWarnings(cfg: ClawdbotConfig) {
const globalSandbox = cfg.agent?.sandbox;
const agents = cfg.routing?.agents ?? {};
const warnings: string[] = [];
for (const [agentId, agent] of Object.entries(agents)) {
const agentSandbox = agent.sandbox;
if (!agentSandbox) continue;
const scope = resolveSandboxScope({
scope: agentSandbox.scope ?? globalSandbox?.scope,
perSession: agentSandbox.perSession ?? globalSandbox?.perSession,
});
if (scope !== "shared") continue;
const overrides: string[] = [];
if (agentSandbox.docker && Object.keys(agentSandbox.docker).length > 0) {
overrides.push("docker");
}
if (agentSandbox.browser && Object.keys(agentSandbox.browser).length > 0) {
overrides.push("browser");
}
if (agentSandbox.prune && Object.keys(agentSandbox.prune).length > 0) {
overrides.push("prune");
}
if (overrides.length === 0) continue;
warnings.push(
`- routing.agents.${agentId}.sandbox: ${overrides.join(
"/",
)} overrides ignored (scope resolves to "shared").`,
);
}
if (warnings.length > 0) {
note(warnings.join("\n"), "Sandbox");
}
}

View File

@@ -47,7 +47,6 @@ afterEach(() => {
const readConfigFileSnapshot = vi.fn();
const confirm = vi.fn().mockResolvedValue(true);
const note = vi.fn();
const select = vi.fn().mockResolvedValue("node");
const note = vi.fn();
const writeConfigFile = vi.fn().mockResolvedValue(undefined);

View File

@@ -22,7 +22,10 @@ import {
normalizeLegacyConfigValues,
} from "./doctor-legacy-config.js";
import { createDoctorPrompter, type DoctorOptions } from "./doctor-prompter.js";
import { maybeRepairSandboxImages } from "./doctor-sandbox.js";
import {
maybeRepairSandboxImages,
noteSandboxScopeWarnings,
} from "./doctor-sandbox.js";
import { noteSecurityWarnings } from "./doctor-security.js";
import {
noteStateIntegrity,
@@ -124,6 +127,7 @@ export async function doctorCommand(
await noteStateIntegrity(cfg, prompter);
cfg = await maybeRepairSandboxImages(cfg, runtime, prompter);
noteSandboxScopeWarnings(cfg);
await maybeMigrateLegacyGatewayService(
cfg,