Skip to content

Commit 8fc7889

Browse files
AhmedTMMaulorbe
authored andcommitted
feat(local): warn users before executing commands on their machine
Local spawns now show a security warning with three options: Ok (proceed normally), Sandbox (run inside a Docker container), or Cancel (abort). Replaces the previous openclaw-only warning with a universal prompt that applies to all agents. When Sandbox is selected, the function re-invokes with useSandbox=true so the Docker-wrapped runner is used.
1 parent 0822320 commit 8fc7889

1 file changed

Lines changed: 39 additions & 20 deletions

File tree

‎packages/cli/src/local/run.ts‎

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,45 @@ import {
3737
* host (the `local` cloud).
3838
*/
3939
export async function runLocalAgent(agentName: string, useSandbox: boolean): Promise<void> {
40+
// Warn that local spawning executes commands directly on the user's machine.
41+
// Skip in non-interactive mode (headless / CI) and when sandbox is already active.
42+
if (!useSandbox && process.env.SPAWN_NON_INTERACTIVE !== "1") {
43+
process.stderr.write("\n");
44+
logWarn("⚠ Local execution warning");
45+
logWarn(" Spawning locally will execute commands directly on this machine.");
46+
logWarn(" The agent will have full access to your filesystem, shell, and network.\n");
47+
48+
const action = await p.select<"ok" | "sandbox" | "cancel">({
49+
message: "How would you like to proceed?",
50+
options: [
51+
{
52+
value: "ok",
53+
label: "Ok",
54+
hint: "proceed — execute directly on this machine",
55+
},
56+
{
57+
value: "sandbox",
58+
label: "Sandbox",
59+
hint: "run inside a Docker container instead",
60+
},
61+
{
62+
value: "cancel",
63+
label: "Cancel",
64+
hint: "abort the operation",
65+
},
66+
],
67+
});
68+
69+
if (p.isCancel(action) || action === "cancel") {
70+
p.log.info("Operation cancelled.");
71+
process.exit(0);
72+
}
73+
74+
if (action === "sandbox") {
75+
return runLocalAgent(agentName, true);
76+
}
77+
}
78+
4079
const baseRunner = {
4180
runServer: runLocal,
4281
uploadFile: async (l: string, r: string) => uploadFile(l, r),
@@ -55,26 +94,6 @@ export async function runLocalAgent(agentName: string, useSandbox: boolean): Pro
5594
await ensureDocker();
5695
}
5796

58-
// Warn about security implications of installing OpenClaw locally
59-
// (skip warning in sandbox mode — the container provides isolation)
60-
if (agentName === "openclaw" && !useSandbox && process.env.SPAWN_NON_INTERACTIVE !== "1") {
61-
process.stderr.write("\n");
62-
logWarn("⚠ Local installation warning");
63-
logWarn(` This will install ${agent.name} directly on your machine.`);
64-
logWarn(" The agent will have full access to your filesystem, shell, and network.");
65-
logWarn(" For isolation, consider running on a cloud VM instead.\n");
66-
67-
const confirmed = await p.confirm({
68-
message: "Continue with local installation?",
69-
initialValue: true,
70-
});
71-
72-
if (p.isCancel(confirmed) || !confirmed) {
73-
p.log.info("Installation cancelled.");
74-
process.exit(0);
75-
}
76-
}
77-
7897
const cloud: CloudOrchestrator = {
7998
cloudName: "local",
8099
cloudLabel: useSandbox ? "local (sandboxed)" : "local",

0 commit comments

Comments
 (0)