diff --git a/src/main/worker-service.ts b/src/main/worker-service.ts index 46f37553..e54a2aeb 100644 --- a/src/main/worker-service.ts +++ b/src/main/worker-service.ts @@ -1,4 +1,4 @@ -import { utilityProcess } from "electron"; +import { app, utilityProcess } from "electron"; import { workerMessageSchema, type WorkerServiceDependencies } from "./worker/worker-types"; import { handleWorkerExit } from "./worker/worker-crash-recovery"; import { handleWorkerMessage } from "./worker/worker-message-handler"; @@ -37,9 +37,15 @@ export function createWorkerService({ } function createWorker() { + // S-01: Propagate packaged-build signal so the worker can hard-refuse + // connector bypass flags in production. worker = utilityProcess.fork(workerPath, [], { stdio: "pipe", serviceName: "AgentCompany Orchestrator", + env: { + ...process.env, + AGENTCOMPANY_PACKAGED: app.isPackaged ? "true" : "false", + }, }); worker.stdout?.on("data", (chunk) => { diff --git a/src/main/worker/worker-entry.ts b/src/main/worker/worker-entry.ts index 9beb4378..446c5fdd 100644 --- a/src/main/worker/worker-entry.ts +++ b/src/main/worker/worker-entry.ts @@ -80,10 +80,13 @@ const activeByAgent = new Map(); const activeByWorkspace = new Map(); const queue: RunJob[] = []; const cancelledRuns = new Set(); -// Agent runs are autonomous by design — they must execute commands without interactive approval. -// The env-var gate is retained as an emergency kill switch but defaults to enabled. +// S-01: Bypass is opt-in only. Packaged builds hard-refuse the dangerous CLI +// flags unless the operator sets BOTH `AGENTCOMPANY_ALLOW_UNSAFE_CONNECTOR_BYPASS=true` +// AND is running a dev/E2E build (AGENTCOMPANY_PACKAGED !== "true"). Main forks +// the worker with AGENTCOMPANY_PACKAGED=. +const isPackaged = process.env.AGENTCOMPANY_PACKAGED === "true"; const allowUnsafeConnectorBypass = - process.env.AGENTCOMPANY_ALLOW_UNSAFE_CONNECTOR_BYPASS !== "false"; + !isPackaged && process.env.AGENTCOMPANY_ALLOW_UNSAFE_CONNECTOR_BYPASS === "true"; function post(message: ChildMessage) { parentPort.postMessage(message);