@sandbar-sdk/cli 0.4.0 → 0.5.0

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 CHANGED
@@ -93,7 +93,7 @@ The CLI carries an agent skill that matches its own version. `sandbar skill` pri
93
93
 
94
94
  - Profile selection: `--profile`, `SANDBAR_PROFILE`, `--provider`, `SANDBAR_PROVIDER`, then `default`.
95
95
  - `provider` names an official adapter (`@sandbar-sdk/<provider>`); `config` and `credentials` are that adapter's own settings. `module` and `export` load any adapter, either a definition or a bound adapter.
96
- - Credentials can be written in the profile directly, as `env:NAME` references, or as password-manager references (below). Keep the file private (`chmod 600`) if it holds keys. Env-only providers read `DAYTONA_API_KEY` and `DAYTONA_TARGET`; `E2B_API_KEY`; `BOXD_API_KEY`, `BOXD_ORG` and `BOXD_NETWORK=internet` (boxd always allows egress, so its adapter requires choosing it); `VERCEL_TOKEN`, `VERCEL_TEAM_ID` and `VERCEL_PROJECT_ID`; `MODAL_TOKEN_ID`, `MODAL_TOKEN_SECRET`, `MODAL_APP_NAME` and `MODAL_ENVIRONMENT`.
96
+ - Credentials can be written in the profile directly, as `env:NAME` references, or as password-manager references (below). Keep the file private (`chmod 600`) if it holds keys. Env-only providers read `DAYTONA_API_KEY` and `DAYTONA_TARGET`; `E2B_API_KEY`; `BOXD_API_KEY`, `BOXD_ORG` and `BOXD_NETWORK=internet` (boxd always allows egress, so its adapter requires choosing it); `BOAT_API_KEY` and `BOAT_NETWORK=internet` (likewise for Boat); `VERCEL_TOKEN`, `VERCEL_TEAM_ID` and `VERCEL_PROJECT_ID`; `MODAL_TOKEN_ID`, `MODAL_TOKEN_SECRET`, `MODAL_APP_NAME` and `MODAL_ENVIRONMENT`.
97
97
  - `limits.maxSandboxes` (or `SANDBAR_MAX_SANDBOXES`) caps how many sandboxes the store may hold. Unset means uncapped.
98
98
 
99
99
  ## Password managers
package/dist/main.js CHANGED
@@ -5,7 +5,7 @@ import { parseArgs } from "node:util";
5
5
  // package.json
6
6
  var package_default = {
7
7
  name: "@sandbar-sdk/cli",
8
- version: "0.4.0",
8
+ version: "0.5.0",
9
9
  private: false,
10
10
  type: "module",
11
11
  description: "Agent-first command line for creating and managing Sandbar sandboxes.",
@@ -30,6 +30,7 @@ var package_default = {
30
30
  zod: "4.6.5"
31
31
  },
32
32
  devDependencies: {
33
+ "@sandbar-sdk/boat": "workspace:*",
33
34
  "@sandbar-sdk/boxd": "workspace:*",
34
35
  "@sandbar-sdk/daytona": "workspace:*",
35
36
  "@sandbar-sdk/e2b": "workspace:*",
@@ -790,6 +791,16 @@ var providers = [
790
791
  network: { env: "BOXD_NETWORK", required: true }
791
792
  }
792
793
  },
794
+ {
795
+ id: "boat",
796
+ module: "@sandbar-sdk/boat",
797
+ export: "boatAdapter",
798
+ experimental: true,
799
+ credentials: { apiKey: "BOAT_API_KEY" },
800
+ config: {
801
+ network: { env: "BOAT_NETWORK", required: true }
802
+ }
803
+ },
793
804
  {
794
805
  id: "vercel",
795
806
  module: "@sandbar-sdk/vercel",
@@ -1875,7 +1886,7 @@ import { homedir as homedir2 } from "node:os";
1875
1886
  import { dirname as dirname3, join as join5 } from "node:path";
1876
1887
 
1877
1888
  // ../../skills/sandbar-cli/SKILL.md
1878
- var SKILL_default = "---\nname: sandbar-cli\ndescription: Create, use and clean up cloud sandboxes from the shell with the `sandbar` CLI (Daytona, E2B, boxd, Vercel, Modal). Use when you need an isolated machine to run untrusted or generated code, try a build or test in a clean environment, or manage sandboxes someone created with sandbar; prefer it over provider-specific CLIs.\n---\n\n# Use sandboxes with the sandbar CLI\n\n`sandbar` creates and manages sandboxes on any Sandbar provider. It is built for agents: it never prompts, every command has a stable `--json` form, and exit codes tell you what to do next.\n\n## Check the setup first\n\n```sh\nsandbar doctor --json # config, credentials, provider connection; creates nothing\nsandbar providers --json # which adapters are installed and which credentials are missing\n```\n\n- If `sandbar` is not on PATH, stop and tell the user; do not install anything yourself.\n- The provider comes from `--profile`, `SANDBAR_PROFILE`, `--provider`, `SANDBAR_PROVIDER`, then `default` in `~/.config/sandbar/sandbar.json`. Do not edit that file or credentials unless the user asks.\n- A missing adapter (exit 4, `ADAPTER_NOT_INSTALLED`), an installed adapter that fails to load (exit 4, `ADAPTER_LOAD_FAILED`) or a missing credential (exit 2) is the user's to fix. Report the `hint` from the error.\n\n**Sandboxes cost money.** Create only what the task needs and destroy it when done.\n\n## Always use JSON\n\nPass `--json` (or set `SANDBAR_JSON=1`). stdout then holds exactly one document:\n\n```json\n{\"ok\": true, \"data\": {...}}\n{\"ok\": false, \"error\": {\"code\": \"...\", \"message\": \"...\", \"retryable\": false, \"outcome\": \"rejected\", \"hint\": \"...\", \"known\": {...}}}\n```\n\nDiagnostics go to stderr. Read `error.hint` before deciding what to do.\n\n## One-shot work: `run`\n\n`run` creates a sandbox, runs one command and always destroys it. Prefer it whenever you do not need the sandbox afterwards.\n\n```sh\nsandbar run --json -- python3 -c 'print(2 + 2)'\nsandbar run --json --prepared base --timeout 5m -- sh -c 'pip install -q requests && python3 app.py'\n```\n\nPass the command after `--` as separate arguments. Its data is `{exitCode, stdout, stderr, truncated, sandbox}`, where `sandbox` names the sandbox it created and destroyed.\n\n## Longer work: create, use, remove\n\n```sh\nsandbar create --json --name job-1 --prepared base # prints the name; reuse it everywhere\nsandbar cp ./app.py job-1:/home/user/app.py\nsandbar exec --json job-1 --cwd /home/user -- python3 app.py\nsandbar sh --json job-1 'cd /home/user && ls -la | head'\nsandbar cat job-1:/home/user/out.txt\nsandbar rm --json job-1\n```\n\n- Give sandboxes a `--name` so you can find them again; names are lowercase letters, digits and dashes. `--if-not-exists` reuses a live sandbox with that name instead of failing.\n- `exec` takes an argv after `--`; no shell runs. Use `sh` only when you need pipes, redirects or `&&`. For a script that starts with `-`, put it after `--`: `sandbar sh job-1 -- '-n ...'`.\n- `--env K=V` (repeatable), `--cwd`, `--stdin` or `--stdin-file <path>`, `--timeout 30s|5m|1h`, `--max-output 1m`.\n- `cp` copies one file; one side is `<sandbox>:/absolute/path`. `--no-clobber` refuses to overwrite.\n- `--image <oci-ref>` boots an OCI image where the provider supports it; `--prepared <id>` uses a provider template or snapshot. On providers that need a build first (E2B, Daytona), `--image` fails with exit 4 and `UNSUPPORTED` before creating anything until `sandbar image build <oci-ref>` has run once for that profile; later creates reuse the build. Build once rather than passing `--build` in a loop: a build is slow, may cost money and leaves a provider-side resource. `sandbar image ls` shows the builds; `sandbar image forget <name>` drops a record and lists what the provider still holds.\n- `sandbar ls --json` lists known sandboxes with their live state (`running`, `gone`, `unreachable`, ...). `sandbar inspect --json <name>` shows state, expiry and the saved reference.\n\nAlways `rm` what you created before finishing, even after failures. `rm` only destroys sandboxes this CLI created; never pass `--force` or `rm --all` unless the user asked.\n\n## Exit codes\n\n`exec`, `sh` and `run` exit with the **remote command's** exit code. Their own failures always exit **125**, with the error in the JSON document. A command that ran but reported no exit status is 125 with `OUTCOME_UNKNOWN`; its output is in `error.known.exec`. It is never success.\n\nOther commands:\n\n| Code | Meaning | What to do |\n| ---- | ----------------------------------------------------------------- | ---------------------------------------------------- |\n| 0 | success | |\n| 1 | other failure, including a name already taken | read the message |\n| 2 | usage or local error | fix the command; `sandbar <command> --help` |\n| 3 | not found | `sandbar ls` |\n| 4 | unsupported, adapter or tool not installed, limit reached | tell the user; do not work around it |\n| 5 | authentication, permission, or unreadable password-manager secret | tell the user |\n| 6 | **outcome unknown**: the effect may have happened | **do not retry**; run `sandbar ls` / `inspect` first |\n| 7 | retryable (rate limit, capacity, unavailable) before any effect | wait, then retry once or twice |\n| 8 | partial: some steps happened | read `error.known` and `error.details` |\n\n## When things go wrong\n\n- **Never repeat a create after exit 6 or `outcome: \"unknown\"`.** The store keeps the name in status `unknown`; check `sandbar ls --json`. `sandbar rm <name>` first asks the provider how that create ended (never resending it) and destroys the sandbox if one exists. If it still exits 4 because the outcome is unknown, and the user agrees it is gone, `sandbar rm --force <name>` drops the record.\n- **`run` exits 125 with `CLEANUP_FAILED`**: the command result is in `error.known.exec`, but the sandbox is still running. Tell the user and run the `rm` from the hint.\n- **`rm` exits 8**: `error.details` lists what was `removed`, `skipped` and `failed`. Retry only the failed names once the cause is fixed.\n- **`STORE_WRITE_FAILED`**: the sandbox exists but was not recorded. The reference is in `error.known.reference`; save it to a file and destroy with `sandbar rm @file.json`.\n- Interrupting `run` (Ctrl-C, SIGTERM) still destroys its sandbox and exits 130 (143 for SIGTERM) with `INTERRUPTED`. A second signal exits immediately and may leave it running.\n\n## Discover more\n\n`sandbar schema` prints every command, flag and exit code as JSON. `sandbar <command> --help` shows usage and examples.\n";
1889
+ var SKILL_default = "---\nname: sandbar-cli\ndescription: Create, use and clean up cloud sandboxes from the shell with the `sandbar` CLI (Daytona, E2B, boxd, Boat, Vercel, Modal). Use when you need an isolated machine to run untrusted or generated code, try a build or test in a clean environment, or manage sandboxes someone created with sandbar; prefer it over provider-specific CLIs.\n---\n\n# Use sandboxes with the sandbar CLI\n\n`sandbar` creates and manages sandboxes on any Sandbar provider. It is built for agents: it never prompts, every command has a stable `--json` form, and exit codes tell you what to do next.\n\n## Check the setup first\n\n```sh\nsandbar doctor --json # config, credentials, provider connection; creates nothing\nsandbar providers --json # which adapters are installed and which credentials are missing\n```\n\n- If `sandbar` is not on PATH, stop and tell the user; do not install anything yourself.\n- The provider comes from `--profile`, `SANDBAR_PROFILE`, `--provider`, `SANDBAR_PROVIDER`, then `default` in `~/.config/sandbar/sandbar.json`. Do not edit that file or credentials unless the user asks.\n- A missing adapter (exit 4, `ADAPTER_NOT_INSTALLED`), an installed adapter that fails to load (exit 4, `ADAPTER_LOAD_FAILED`) or a missing credential (exit 2) is the user's to fix. Report the `hint` from the error.\n\n**Sandboxes cost money.** Create only what the task needs and destroy it when done.\n\n## Always use JSON\n\nPass `--json` (or set `SANDBAR_JSON=1`). stdout then holds exactly one document:\n\n```json\n{\"ok\": true, \"data\": {...}}\n{\"ok\": false, \"error\": {\"code\": \"...\", \"message\": \"...\", \"retryable\": false, \"outcome\": \"rejected\", \"hint\": \"...\", \"known\": {...}}}\n```\n\nDiagnostics go to stderr. Read `error.hint` before deciding what to do.\n\n## One-shot work: `run`\n\n`run` creates a sandbox, runs one command and always destroys it. Prefer it whenever you do not need the sandbox afterwards.\n\n```sh\nsandbar run --json -- python3 -c 'print(2 + 2)'\nsandbar run --json --prepared base --timeout 5m -- sh -c 'pip install -q requests && python3 app.py'\n```\n\nPass the command after `--` as separate arguments. Its data is `{exitCode, stdout, stderr, truncated, sandbox}`, where `sandbox` names the sandbox it created and destroyed.\n\n## Longer work: create, use, remove\n\n```sh\nsandbar create --json --name job-1 --prepared base # prints the name; reuse it everywhere\nsandbar cp ./app.py job-1:/home/user/app.py\nsandbar exec --json job-1 --cwd /home/user -- python3 app.py\nsandbar sh --json job-1 'cd /home/user && ls -la | head'\nsandbar cat job-1:/home/user/out.txt\nsandbar rm --json job-1\n```\n\n- Give sandboxes a `--name` so you can find them again; names are lowercase letters, digits and dashes. `--if-not-exists` reuses a live sandbox with that name instead of failing.\n- `exec` takes an argv after `--`; no shell runs. Use `sh` only when you need pipes, redirects or `&&`. For a script that starts with `-`, put it after `--`: `sandbar sh job-1 -- '-n ...'`.\n- `--env K=V` (repeatable), `--cwd`, `--stdin` or `--stdin-file <path>`, `--timeout 30s|5m|1h`, `--max-output 1m`.\n- `cp` copies one file; one side is `<sandbox>:/absolute/path`. `--no-clobber` refuses to overwrite.\n- `--image <oci-ref>` boots an OCI image where the provider supports it; `--prepared <id>` uses a provider template or snapshot. On providers that need a build first (E2B, Daytona), `--image` fails with exit 4 and `UNSUPPORTED` before creating anything until `sandbar image build <oci-ref>` has run once for that profile; later creates reuse the build. Build once rather than passing `--build` in a loop: a build is slow, may cost money and leaves a provider-side resource. `sandbar image ls` shows the builds; `sandbar image forget <name>` drops a record and lists what the provider still holds.\n- `sandbar ls --json` lists known sandboxes with their live state (`running`, `gone`, `unreachable`, ...). `sandbar inspect --json <name>` shows state, expiry and the saved reference.\n\nAlways `rm` what you created before finishing, even after failures. `rm` only destroys sandboxes this CLI created; never pass `--force` or `rm --all` unless the user asked.\n\n## Exit codes\n\n`exec`, `sh` and `run` exit with the **remote command's** exit code. Their own failures always exit **125**, with the error in the JSON document. A command that ran but reported no exit status is 125 with `OUTCOME_UNKNOWN`; its output is in `error.known.exec`. It is never success.\n\nOther commands:\n\n| Code | Meaning | What to do |\n| ---- | ----------------------------------------------------------------- | ---------------------------------------------------- |\n| 0 | success | |\n| 1 | other failure, including a name already taken | read the message |\n| 2 | usage or local error | fix the command; `sandbar <command> --help` |\n| 3 | not found | `sandbar ls` |\n| 4 | unsupported, adapter or tool not installed, limit reached | tell the user; do not work around it |\n| 5 | authentication, permission, or unreadable password-manager secret | tell the user |\n| 6 | **outcome unknown**: the effect may have happened | **do not retry**; run `sandbar ls` / `inspect` first |\n| 7 | retryable (rate limit, capacity, unavailable) before any effect | wait, then retry once or twice |\n| 8 | partial: some steps happened | read `error.known` and `error.details` |\n\n## When things go wrong\n\n- **Never repeat a create after exit 6 or `outcome: \"unknown\"`.** The store keeps the name in status `unknown`; check `sandbar ls --json`. `sandbar rm <name>` first asks the provider how that create ended (never resending it) and destroys the sandbox if one exists. If it still exits 4 because the outcome is unknown, and the user agrees it is gone, `sandbar rm --force <name>` drops the record.\n- **`run` exits 125 with `CLEANUP_FAILED`**: the command result is in `error.known.exec`, but the sandbox is still running. Tell the user and run the `rm` from the hint.\n- **`rm` exits 8**: `error.details` lists what was `removed`, `skipped` and `failed`. Retry only the failed names once the cause is fixed.\n- **`STORE_WRITE_FAILED`**: the sandbox exists but was not recorded. The reference is in `error.known.reference`; save it to a file and destroy with `sandbar rm @file.json`.\n- Interrupting `run` (Ctrl-C, SIGTERM) still destroys its sandbox and exits 130 (143 for SIGTERM) with `INTERRUPTED`. A second signal exits immediately and may leave it running.\n\n## Discover more\n\n`sandbar schema` prints every command, flag and exit code as JSON. `sandbar <command> --help` shows usage and examples.\n";
1879
1890
 
1880
1891
  // src/skill.ts
1881
1892
  var skillName = "sandbar-cli";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sandbar-sdk/cli",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Agent-first command line for creating and managing Sandbar sandboxes.",
@@ -20,16 +20,17 @@
20
20
  "build": "rm -rf dist && bun build src/main.ts --target node --format esm --outdir dist --external sandbar-sdk --external @sandbar-sdk/adapter --external zod"
21
21
  },
22
22
  "dependencies": {
23
- "@sandbar-sdk/adapter": "0.4.0",
24
- "sandbar-sdk": "0.4.0",
23
+ "@sandbar-sdk/adapter": "0.5.0",
24
+ "sandbar-sdk": "0.5.0",
25
25
  "zod": "4.6.5"
26
26
  },
27
27
  "devDependencies": {
28
- "@sandbar-sdk/boxd": "0.4.0",
29
- "@sandbar-sdk/daytona": "0.4.0",
30
- "@sandbar-sdk/e2b": "0.4.0",
28
+ "@sandbar-sdk/boat": "0.5.0",
29
+ "@sandbar-sdk/boxd": "0.5.0",
30
+ "@sandbar-sdk/daytona": "0.5.0",
31
+ "@sandbar-sdk/e2b": "0.5.0",
31
32
  "@sandbar-sdk/modal": "0.0.0",
32
- "@sandbar-sdk/vercel": "0.4.0",
33
+ "@sandbar-sdk/vercel": "0.5.0",
33
34
  "@sandbar/provider-fake": "0.0.0"
34
35
  },
35
36
  "license": "Apache-2.0",