Skip to content

Commit 1f61420

Browse files
Add per-command env and cwd options documentation
Document new per-command environment variable and working directory options added to exec(), execStream(), and startProcess() methods. Changes: - Add env and cwd parameters to exec() and execStream() API docs - Add practical examples showing per-command env variable scoping - Add working directory override examples - Update environment variables configuration guide - Clarify that per-command options do not persist in session Related PR: cloudflare/sandbox-sdk#204 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent cf08f2d commit 1f61420

File tree

3 files changed

+101
-8
lines changed

3 files changed

+101
-8
lines changed

src/content/docs/sandbox/api/commands.mdx

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ const result = await sandbox.exec(command: string, options?: ExecOptions): Promi
2525
- `stream` - Enable streaming callbacks (default: `false`)
2626
- `onOutput` - Callback for real-time output: `(stream: 'stdout' | 'stderr', data: string) => void`
2727
- `timeout` - Maximum execution time in milliseconds
28+
- `env` - Environment variables for this command only (does not persist in session)
29+
- `cwd` - Working directory for this command only (does not persist in session)
2830

2931
**Returns**: `Promise<ExecuteResponse>` with `success`, `stdout`, `stderr`, `exitCode`
3032

@@ -43,6 +45,12 @@ await sandbox.exec('npm install', {
4345
stream: true,
4446
onOutput: (stream, data) => console.log(`[${stream}] ${data}`)
4547
});
48+
49+
// With per-command environment variables and working directory
50+
await sandbox.exec('npm test', {
51+
env: { NODE_ENV: 'test', CI: 'true' },
52+
cwd: '/workspace/my-app'
53+
});
4654
```
4755
</TypeScriptExample>
4856

@@ -56,7 +64,7 @@ const stream = await sandbox.execStream(command: string, options?: ExecOptions):
5664

5765
**Parameters**:
5866
- `command` - The command to execute
59-
- `options` - Same as `exec()`
67+
- `options` - Same as `exec()` (includes `timeout`, `env`, `cwd`)
6068

6169
**Returns**: `Promise<ReadableStream>` emitting `ExecEvent` objects (`start`, `stdout`, `stderr`, `complete`, `error`)
6270

@@ -79,6 +87,12 @@ for await (const event of parseSSEStream<ExecEvent>(stream)) {
7987
break;
8088
}
8189
}
90+
91+
// With per-command options
92+
const stream = await sandbox.execStream('python analyze.py', {
93+
env: { DATA_PATH: '/workspace/data' },
94+
cwd: '/workspace/analysis'
95+
});
8296
```
8397
</TypeScriptExample>
8498

@@ -93,8 +107,12 @@ const process = await sandbox.startProcess(command: string, options?: ProcessOpt
93107
**Parameters**:
94108
- `command` - The command to start as a background process
95109
- `options` (optional):
96-
- `cwd` - Working directory
97-
- `env` - Environment variables
110+
- `cwd` - Working directory for the process
111+
- `env` - Environment variables for the process
112+
- `timeout` - Maximum execution time in milliseconds
113+
- `processId` - Custom process ID (auto-generated if not provided)
114+
- `encoding` - Output encoding (default: `'utf-8'`)
115+
- `autoCleanup` - Automatically clean up process on exit (default: `true`)
98116

99117
**Returns**: `Promise<ProcessInfo>` with `id`, `pid`, `command`, `status`
100118

@@ -103,7 +121,7 @@ const process = await sandbox.startProcess(command: string, options?: ProcessOpt
103121
const server = await sandbox.startProcess('python -m http.server 8000');
104122
console.log('Started with PID:', server.pid);
105123
106-
// With custom environment
124+
// With custom environment and working directory
107125
const app = await sandbox.startProcess('node app.js', {
108126
cwd: '/workspace/my-app',
109127
env: { NODE_ENV: 'production', PORT: '3000' }

src/content/docs/sandbox/configuration/environment-variables.mdx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ await sandbox.exec("python seed.py"); // Has DATABASE_URL and API_KEY
3232

3333
### 2. Per-command with exec() options
3434

35-
Pass environment variables for a specific command:
35+
Pass environment variables for a specific command without affecting the session:
3636

3737
```typescript
3838
await sandbox.exec("node app.js", {
@@ -42,6 +42,14 @@ await sandbox.exec("node app.js", {
4242
},
4343
});
4444

45+
// Works with execStream() too
46+
const stream = await sandbox.execStream("npm run build", {
47+
env: {
48+
CI: "true",
49+
NODE_ENV: "production",
50+
},
51+
});
52+
4553
// Also works with startProcess()
4654
await sandbox.startProcess("python server.py", {
4755
env: {
@@ -50,6 +58,8 @@ await sandbox.startProcess("python server.py", {
5058
});
5159
```
5260

61+
Per-command environment variables are scoped to that command only and do not persist in the session. They are automatically cleaned up when the command completes.
62+
5363
**Use when:** You need different environment variables for different commands, or want to override sandbox-level variables.
5464

5565
### 3. Session-level with createSession()

src/content/docs/sandbox/guides/execute-commands.mdx

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,66 @@ await sandbox.exec('python /workspace/analyze.py data.csv');
133133
```
134134
</TypeScriptExample>
135135

136+
## Use per-command environment variables
137+
138+
Set environment variables for a single command without affecting the session:
139+
140+
<TypeScriptExample>
141+
```
142+
// Environment variables scoped to this command only
143+
const result = await sandbox.exec('echo $API_KEY', {
144+
env: { API_KEY: 'secret-key-123' }
145+
});
146+
147+
console.log(result.stdout); // "secret-key-123"
148+
149+
// Next command does not have API_KEY
150+
const verify = await sandbox.exec('echo $API_KEY');
151+
console.log(verify.stdout); // "" (empty)
152+
```
153+
</TypeScriptExample>
154+
155+
Per-command environment variables:
156+
- Do not persist in the session
157+
- Override session-level variables if both are set
158+
- Are isolated from other concurrent commands
159+
- Are cleaned up automatically after the command completes
160+
161+
## Override working directory
162+
163+
Override the working directory for a single command:
164+
165+
<TypeScriptExample>
166+
```
167+
// Execute in a specific directory
168+
const result = await sandbox.exec('pwd', {
169+
cwd: '/workspace/my-project'
170+
});
171+
172+
console.log(result.stdout); // "/workspace/my-project"
173+
174+
// Session working directory unchanged
175+
const verify = await sandbox.exec('pwd');
176+
console.log(verify.stdout); // "/workspace" (default)
177+
```
178+
</TypeScriptExample>
179+
180+
Combining `cwd` and `env` for complex workflows:
181+
182+
<TypeScriptExample>
183+
```
184+
// Run tests in a specific directory with custom environment
185+
await sandbox.exec('npm test', {
186+
cwd: '/workspace/api',
187+
env: {
188+
NODE_ENV: 'test',
189+
DATABASE_URL: 'sqlite::memory:',
190+
LOG_LEVEL: 'debug'
191+
}
192+
});
193+
```
194+
</TypeScriptExample>
195+
136196
## Best practices
137197

138198
- **Check exit codes** - Always verify `result.success` and `result.exitCode`
@@ -158,14 +218,19 @@ if (!check.success) {
158218

159219
### Working directory issues
160220

161-
Use absolute paths or change directory:
221+
Use the `cwd` option for cleaner code, or use absolute paths:
162222

163223
<TypeScriptExample>
164224
```
165-
// Use absolute path
225+
// Best: Use cwd option
226+
await sandbox.exec('python script.py', {
227+
cwd: '/workspace/my-app'
228+
});
229+
230+
// Alternative: Use absolute path
166231
await sandbox.exec('python /workspace/my-app/script.py');
167232
168-
// Or change directory
233+
// Alternative: Change directory inline
169234
await sandbox.exec('cd /workspace/my-app && python script.py');
170235
```
171236
</TypeScriptExample>

0 commit comments

Comments
 (0)