the universal sandbox runtime for agents and humans. pocketenv.io
sandbox openclaw agent claude-code vercel-sandbox deno-sandbox cloudflare-sandbox atproto sprites daytona
7
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix condition check in prepareSandbox

Treat non-zero exit code from conditional checks as "already set up" so
steps are skipped. Update tests and mocks to reflect the `[ ! -f ... ]
||
! command -v ...` style conditions and their expected behavior.

+19 -17
+18 -16
apps/sandbox/src/lib/prepare-sandbox.test.ts
··· 42 42 }); 43 43 44 44 Deno.test("prepareSandbox - skips step when condition is already met", async () => { 45 - // exitCode 0 → condition IS met → conditional run blocks are skipped 46 - const sandbox = new MockSandbox(); 45 + // The if-condition uses `[ ! -f ... ] || ! command -v ...` style. 46 + // When setup IS already done: the condition returns exitCode 1 (not needed) → skip. 47 + class AlreadySetupMock extends MockSandbox { 48 + override sh(strings: TemplateStringsArray, ...values: any[]) { 49 + const cmd = String.raw({ raw: strings }, ...values); 50 + this.calls.push(cmd); 51 + // Condition checks return exitCode 1 = setup already done → skip step 52 + const exitCode = cmd.trimStart().startsWith("[") ? 1 : 0; 53 + return Promise.resolve({ exitCode, stdout: "", stderr: "" }); 54 + } 55 + } 56 + 57 + const sandbox = new AlreadySetupMock(); 47 58 await prepareSandbox(sandbox, "nix"); 48 59 // The nix install command is inside a conditional step and must NOT have run 49 60 const ranNixInstall = sandbox.calls.some((cmd) => ··· 53 64 }); 54 65 55 66 Deno.test("prepareSandbox - executes run commands when condition not met", async () => { 56 - class ConditionFailMock extends MockSandbox { 57 - override sh(strings: TemplateStringsArray, ...values: any[]) { 58 - const cmd = String.raw({ raw: strings }, ...values); 59 - this.calls.push(cmd); 60 - // Only if-condition checks (starting with "[") return non-zero exit code, 61 - // meaning the condition is NOT met → run block executes. 62 - // All subsequent run commands return 0 (success). 63 - const exitCode = cmd.trimStart().startsWith("[") ? 1 : 0; 64 - return Promise.resolve({ exitCode, stdout: "", stderr: "" }); 65 - } 66 - } 67 - 68 - const sandbox = new ConditionFailMock(); 67 + // The if-condition uses `[ ! -f ... ] || ! command -v ...` style. 68 + // When setup is NOT yet done: the condition returns exitCode 0 (needed) → run. 69 + // MockSandbox always returns exitCode 0, simulating a fresh environment. 70 + const sandbox = new MockSandbox(); 69 71 await prepareSandbox(sandbox, "nix"); 70 - // With conditions never met, conditional run commands should have executed 72 + // With conditions saying "setup needed", conditional run commands should have executed 71 73 const ranNixInstall = sandbox.calls.some((cmd) => 72 74 cmd.includes("install.determinate.systems/nix") 73 75 );
+1 -1
apps/sandbox/src/lib/prepare-sandbox.ts
··· 64 64 if (item.if) { 65 65 try { 66 66 const { exitCode } = await sandbox.sh`${item.if}`; 67 - if (exitCode === 0) { 67 + if (exitCode !== 0) { 68 68 console.info( 69 69 chalk.yellow( 70 70 `Condition "${chalk.rgb(100, 232, 130)(item.if)}" met. Skipping commands for "${chalk.rgb(100, 232, 130)(item.name)}".`,