@sanlabs/sanbox-cli 0.0.12 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -4
- package/dist/cli.js +10 -5
- package/dist/runs.js +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,7 +15,10 @@ installed_cli_version="$(sanbox --version)"
|
|
|
15
15
|
test "$installed_cli_version" = "$latest_cli_version"
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
Always use the latest published CLI. CLI 0.0.
|
|
18
|
+
Always use the latest published CLI. CLI 0.0.13 allows service templates to start without an
|
|
19
|
+
initial task, including OpenCode Computers that are ready for later SDK steering, and supports
|
|
20
|
+
Custom OpenAI Proxy providers when creating templates, including Browser Use templates.
|
|
21
|
+
CLI 0.0.12 adopted the Stop, Resume, and Delete lifecycle,
|
|
19
22
|
separates run state from execution outcome, retains scrubbed deleted-run tombstones, and adds
|
|
20
23
|
administrator-confirmed template deletion.
|
|
21
24
|
CLI 0.0.11 added OpenCode Computer templates and short-lived native SDK connections for HTTP, SSE
|
|
@@ -128,7 +131,8 @@ and `--force` so scripts cannot remove a template accidentally.
|
|
|
128
131
|
## Create A Browser Use Template
|
|
129
132
|
|
|
130
133
|
Browser Use runs local headless Chromium inside the Firecracker sandbox. It requires OpenAI,
|
|
131
|
-
Anthropic, Google Gemini,
|
|
134
|
+
Anthropic, Google Gemini, Hetzner Inference, or a Custom OpenAI Proxy and at least one
|
|
135
|
+
explicit browser target:
|
|
132
136
|
|
|
133
137
|
```bash
|
|
134
138
|
sanbox templates create \
|
|
@@ -151,6 +155,8 @@ allowed downloads. Browser Use templates are one-shot agent executions.
|
|
|
151
155
|
|
|
152
156
|
## Run Idempotently
|
|
153
157
|
|
|
158
|
+
Task templates require a positional task or `--task`. Service templates may omit it:
|
|
159
|
+
|
|
154
160
|
```bash
|
|
155
161
|
sanbox run "Review this repo and write output/report.md" \
|
|
156
162
|
--input src/ \
|
|
@@ -163,8 +169,18 @@ sanbox run "Review this repo and write output/report.md" \
|
|
|
163
169
|
--input src/ \
|
|
164
170
|
--wait \
|
|
165
171
|
--json
|
|
172
|
+
|
|
173
|
+
sanbox run \
|
|
174
|
+
--template "<service-template-id>" \
|
|
175
|
+
--external-run-id "<stable-service-id>" \
|
|
176
|
+
--json
|
|
166
177
|
```
|
|
167
178
|
|
|
179
|
+
A taskless OpenCode Computer starts `opencode serve` without making an initial model call. A
|
|
180
|
+
taskless Hermes service starts its gateways and waits for WebUI or configured channel messages.
|
|
181
|
+
Supplying instructions starts the initial OpenCode task or seeds Hermes's persistent operating
|
|
182
|
+
context, preserving the existing behavior.
|
|
183
|
+
|
|
168
184
|
Repeat `--input` for files, directories, or globs. The CLI excludes common secrets and applies `.sanboxignore`. `--include` is a deprecated compatibility alias.
|
|
169
185
|
|
|
170
186
|
For a Hermes template that allows `email`, optionally request an address from one of the AgentMail
|
|
@@ -289,8 +305,9 @@ authenticated WebSocket. The temporary key is deleted when the connection closes
|
|
|
289
305
|
user token is not passed to the OpenSSH child process.
|
|
290
306
|
|
|
291
307
|
OpenCode and Browser Use runs are one-shot agent executions. OpenCode Computer keeps its private
|
|
292
|
-
server running
|
|
293
|
-
still be fresh-booted manually for
|
|
308
|
+
server running so it can accept later steering; when an initial task is supplied, Sanbox submits it
|
|
309
|
+
after the server becomes ready. A persisted task workspace can still be fresh-booted manually for
|
|
310
|
+
inspection after the run stops.
|
|
294
311
|
|
|
295
312
|
## Connect The OpenCode SDK
|
|
296
313
|
|
package/dist/cli.js
CHANGED
|
@@ -44,6 +44,7 @@ Commands:
|
|
|
44
44
|
sanbox templates delete <template-id> --force [--json]
|
|
45
45
|
sanbox run "task" --template <template-id> [--email-address <address>] [--telegram-bot-token <token>] [--telegram-allowed-user <id>] [--input <path>] [--wait | --watch] [--json | --jsonl]
|
|
46
46
|
sanbox run --task "..." --template <template-id> [--email-address <address>] [--telegram-bot-token <token>] [--telegram-allowed-user <id>] [--input <path>] [--wait | --watch] [--json | --jsonl]
|
|
47
|
+
sanbox run --template <service-template-id> [--email-address <address>] [--telegram-bot-token <token>] [--telegram-allowed-user <id>] [--json]
|
|
47
48
|
sanbox batch --tasks tasks.json --template <template-id> [--input <path>] [--max-parallel 5] [--wait] [--json]
|
|
48
49
|
sanbox runs list [--limit 50] [--json]
|
|
49
50
|
sanbox runs get <run-id> [--json]
|
|
@@ -93,8 +94,10 @@ const runHelp = `Sanbox run
|
|
|
93
94
|
Usage:
|
|
94
95
|
sanbox run "Review these files" --template <template-id> --input report.pdf --input data/ --wait
|
|
95
96
|
sanbox run --task "Review these files" --template <template-id> --input report.pdf --wait --json
|
|
97
|
+
sanbox run --template <service-template-id> --json
|
|
96
98
|
|
|
97
99
|
Options:
|
|
100
|
+
--task <instruction> Required for task templates; optional for service templates.
|
|
98
101
|
--input <path> File, directory, or glob to upload. Repeatable.
|
|
99
102
|
--template <id> Template id or slug. Required unless SANBOX_TEMPLATE or project config sets it.
|
|
100
103
|
--external-run-id <id> Idempotency key for retries.
|
|
@@ -726,8 +729,6 @@ const commandRun = async (command, flags) => {
|
|
|
726
729
|
throw new CliError("conflicting_arguments", "Use either --task or a positional task, not both.");
|
|
727
730
|
}
|
|
728
731
|
const task = runTask(command, flags);
|
|
729
|
-
if (!task)
|
|
730
|
-
throw new Error("--task or a positional task is required.");
|
|
731
732
|
if (hasFlag(flags, "wait") && wantsWatch(flags)) {
|
|
732
733
|
throw new Error("--wait cannot be combined with --watch or --jsonl.");
|
|
733
734
|
}
|
|
@@ -771,7 +772,7 @@ const commandRun = async (command, flags) => {
|
|
|
771
772
|
try {
|
|
772
773
|
payload = await createRun(client, {
|
|
773
774
|
cwd: cwd(),
|
|
774
|
-
instruction: task,
|
|
775
|
+
instruction: task || undefined,
|
|
775
776
|
inputs: flagList(flags, "input"),
|
|
776
777
|
externalRunId: flagString(flags, "external-run-id") || undefined,
|
|
777
778
|
supabaseUserId: supabaseUserId || undefined,
|
|
@@ -1198,6 +1199,9 @@ const commandTemplates = async (command, flags) => {
|
|
|
1198
1199
|
if (harness === "opencode" && mode === "computer" && llmBudgetUsd !== undefined) {
|
|
1199
1200
|
throw new CliError("opencode_computer_budget_unsupported", "OpenCode Computer templates do not support --llm-budget-usd yet.");
|
|
1200
1201
|
}
|
|
1202
|
+
if (modelProvider === "custom" && llmBudgetUsd !== undefined) {
|
|
1203
|
+
throw new CliError("custom_provider_budget_unsupported", "Custom OpenAI Proxy providers do not support --llm-budget-usd yet.");
|
|
1204
|
+
}
|
|
1201
1205
|
const channels = [...new Set(flagList(flags, "channel").map((value) => value.trim()).filter(Boolean))];
|
|
1202
1206
|
if (channels.some((channel) => channel !== "email" && channel !== "telegram")) {
|
|
1203
1207
|
throw new CliError("invalid_hermes_channels", "--channel must be email or telegram.");
|
|
@@ -1218,8 +1222,9 @@ const commandTemplates = async (command, flags) => {
|
|
|
1218
1222
|
modelProvider !== "openai" &&
|
|
1219
1223
|
modelProvider !== "anthropic" &&
|
|
1220
1224
|
modelProvider !== "google" &&
|
|
1221
|
-
modelProvider !== "hetzner"
|
|
1222
|
-
|
|
1225
|
+
modelProvider !== "hetzner" &&
|
|
1226
|
+
modelProvider !== "custom") {
|
|
1227
|
+
throw new CliError("browser_use_provider_unsupported", "Browser Use templates require --model-provider openai, anthropic, google, hetzner, or custom.");
|
|
1223
1228
|
}
|
|
1224
1229
|
const browserDomains = harness === "browser-use"
|
|
1225
1230
|
? parseBrowserDomains(flagList(flags, "browser-domain"))
|
package/dist/runs.js
CHANGED
|
@@ -52,7 +52,7 @@ export const createRun = async (client, options) => {
|
|
|
52
52
|
return client.createRun({
|
|
53
53
|
external_run_id: options.externalRunId,
|
|
54
54
|
workload_id: options.templateId,
|
|
55
|
-
instruction: options.instruction,
|
|
55
|
+
...(options.instruction ? { instruction: options.instruction } : {}),
|
|
56
56
|
...(options.supabaseUserId ? { supabase_user_id: options.supabaseUserId } : {}),
|
|
57
57
|
...(options.emailAddress ? { email_address: options.emailAddress } : {}),
|
|
58
58
|
...(options.telegramBotToken ? {
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = "0.0.
|
|
1
|
+
export const version = "0.0.13";
|