diff --git a/packages/cli/README.md b/packages/cli/README.md index 248d953c..c26f48bf 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -855,7 +855,9 @@ bunny scripts docs Manage on-demand cloud sandbox environments backed by Bunny Magic Containers. Each sandbox is a fully isolated Ubuntu container with Node.js, Bun, Python, and Claude Code pre-installed. A 10 GB persistent volume is mounted at `/workplace`, your default working directory. -Sandbox credentials (app ID, hostname, SSH endpoint, agent token) are stored in `~/.config/bunnynet.json` so you can reconnect without re-creating. +Claude Code is pre-installed but needs your own Anthropic credentials before it can do anything: pass an API key at create time (prefer `--env-file .env` so the key stays out of your shell history), or run `claude` inside the sandbox and complete the login prompt it prints. Both survive restarts and redeploys: baked env vars live on the container, and the login flow writes to `/workplace/.claude` on the persistent volume. + +Sandbox credentials (app ID, SSH endpoint, agent token) are stored in the CLI's local config file (`~/.config/bunnynet.json` by default) so you can reconnect without re-creating. #### `bunny sandbox create` @@ -874,6 +876,9 @@ bunny sandbox create my-sandbox --region NY # Bake in environment variables (persisted for the sandbox's lifetime) bunny sandbox create my-sandbox -e NODE_ENV=production -e PORT=8080 bunny sandbox create my-sandbox --env-file .env + +# Give Claude Code your Anthropic API key at create time (.env holds ANTHROPIC_API_KEY) +bunny sandbox create my-sandbox --env-file .env ``` | Flag | Alias | Description | Default | @@ -884,7 +889,7 @@ bunny sandbox create my-sandbox --env-file .env Variables set at creation are baked into the container and persist across restarts. Values from `--env` override those loaded from `--env-file`. To change them later, use [`bunny sandbox env`](#bunny-sandbox-env). -Once ready, the output shows the app ID, public HTTPS hostname, and SSH address. +Once ready, the output shows the app ID and SSH address. Public URLs come later via [`bunny sandbox url add`](#bunny-sandbox-url-add). #### `bunny sandbox list` @@ -895,7 +900,7 @@ bunny sandbox list bunny sandbox ls # alias ``` -Columns: Name, App ID, Hostname, SSH. +Columns: Name, App ID, SSH. #### `bunny sandbox delete` diff --git a/skills/bunny-cli/SKILL.md b/skills/bunny-cli/SKILL.md index 3d79a4e6..367a755a 100644 --- a/skills/bunny-cli/SKILL.md +++ b/skills/bunny-cli/SKILL.md @@ -1,6 +1,6 @@ --- name: bunny-cli -description: Manage bunny.net resources from the command line (databases, DNS, Edge Scripts, authentication, and raw API requests). Use when working with bunny.net (pullzones, DNS zones/records, databases, storage, Edge Scripts, Magic Containers), invoking the `bunny` CLI, or making authenticated API calls to api.bunny.net. +description: Manage bunny.net resources from the command line (databases, DNS, Edge Scripts, sandboxes, authentication, and raw API requests). Use when working with bunny.net (pullzones, DNS zones/records, databases, storage, Edge Scripts, Magic Containers, cloud sandboxes), invoking the `bunny` CLI, or making authenticated API calls to api.bunny.net. --- # bunny.net CLI Skill @@ -40,6 +40,11 @@ bunny scripts init bunny scripts deploy dist/index.js bunny scripts list +# manage cloud sandboxes (isolated containers with Claude Code inside) +bunny sandbox create my-sandbox -e ANTHROPIC_API_KEY=sk-ant-... +bunny sandbox exec my-sandbox -- bun install +bunny sandbox url add my-sandbox 3000 + # manage DNS bunny dns zones add example.com bunny dns zones nameservers example.com # is the registrar delegated to bunny yet? @@ -56,6 +61,7 @@ Use this to route to the correct reference file: - **Database management (create, list, show, link, delete, shell, studio, regions, tokens)** -> `references/database.md` - **DNS (zones, delegation checks, records, presets, BIND import/export, DNSSEC, logging, Scriptable DNS scripts)** -> `references/dns.md` - **Edge Scripts (init, create, deploy, link, stats, deployments/rollback, env vars, custom domains)** -> `references/scripts.md` +- **Sandboxes (create, exec, ssh, cp, files, public URLs, persistent env vars, Claude Code auth)** -> `references/sandbox.md` - **Make raw API requests** -> `references/api.md` - **CLI doesn't have a command for it** -> use `bunny api` as a fallback (see `references/api.md`) diff --git a/skills/bunny-cli/references/sandbox.md b/skills/bunny-cli/references/sandbox.md new file mode 100644 index 00000000..ed1e0184 --- /dev/null +++ b/skills/bunny-cli/references/sandbox.md @@ -0,0 +1,163 @@ +# Sandbox Commands + +All sandbox commands live under `bunny sandbox`. Each sandbox is a fully isolated Ubuntu container (Bunny Magic Containers) with Node.js, Bun, Python, and Claude Code pre-installed. A 10 GB persistent volume is mounted at `/workplace`, the default working directory; relative remote paths resolve against it. + +Sandbox credentials (app ID, SSH endpoint, agent token) are stored in the CLI's local config (same candidate paths as in SKILL.md), so commands reference sandboxes by name. + +Claude Code is pre-installed but needs the user's own Anthropic credentials: bake an API key in at create time (prefer `--env-file .env` so the key stays out of shell history), set it later with `bunny sandbox env set`, or run `claude` inside the sandbox and complete the login prompt. Both paths survive restarts and redeploys: baked env vars live on the container, and interactive login writes to `/workplace/.claude` (the image pins `CLAUDE_CONFIG_DIR` there) on the persistent volume. + +## Typical workflows + +```bash +# Create, run a command, expose a dev server, tear down +bunny sandbox create my-sandbox --env-file .env # .env holds ANTHROPIC_API_KEY for Claude Code +bunny sandbox exec my-sandbox -- bun install +bunny sandbox url add my-sandbox 3000 # public HTTPS URL for port 3000 +bunny sandbox delete my-sandbox --force + +# Move files in and out +bunny sandbox cp ./app.js my-sandbox:app.js # relative paths resolve against /workplace +bunny sandbox cp my-sandbox:out.log ./out.log + +# Interactive work +bunny sandbox ssh my-sandbox +``` + +--- + +## `bunny sandbox create` + +Create and start a new sandbox. Waits for the container's SSH port to become reachable. Prompts for a name when omitted (in `--output json` mode the positional is required). + +```bash +bunny sandbox create # interactive: prompts for a name +bunny sandbox create my-sandbox +bunny sandbox create my-sandbox --region NY +bunny sandbox create my-sandbox -e NODE_ENV=production --env-file .env +bunny sandbox create my-sandbox --env-file .env # bake in ANTHROPIC_API_KEY for Claude Code +``` + +| Flag | Alias | Description | Default | +| ------------ | ----- | ------------------------------------------------ | ------- | +| `--region` | | Region ID to deploy in (e.g. `AMS`, `NY`, `LA`) | `AMS` | +| `--env` | `-e` | Environment variable as `KEY=VALUE` (repeatable) | | +| `--env-file` | | Load environment variables from a dotenv file | | + +Variables set at creation are baked into the container and persist across restarts; `--env` overrides `--env-file`. Output shows the app ID and SSH address; public URLs come later via `bunny sandbox url add`. + +--- + +## `bunny sandbox list` / `delete` + +```bash +bunny sandbox list # sandboxes in local config (alias: ls) +bunny sandbox delete my-sandbox # destroys the underlying Magic Containers app +bunny sandbox rm my-sandbox -f # alias; --force skips confirmation +``` + +--- + +## `bunny sandbox exec` + +Run a shell command inside a sandbox over SSH. Defaults to `/workplace`. Exit code is propagated; use `--` before the command so its flags are not consumed by the CLI. + +```bash +bunny sandbox exec my-sandbox ls -la +bunny sandbox exec my-sandbox --cwd /tmp env +bunny sandbox exec my-sandbox --env DEBUG=1 -- node app.js +bunny sandbox exec my-sandbox --timeout 30 -- bun run build # exit 124 on timeout +``` + +| Flag | Description | Default | +| ------------ | --------------------------------------------------------------- | ------------ | +| `--cwd` | Working directory inside the sandbox | `/workplace` | +| `--env` | Temporary environment variable as `KEY=VALUE` (repeatable) | | +| `--env-file` | Load temporary environment variables from a dotenv file | | +| `--timeout` | Close the SSH connection and exit `124` after this many seconds | | + +Variables passed here apply to that single command only. For persistent variables, use `bunny sandbox env`. + +--- + +## `bunny sandbox ssh` + +Open a full interactive SSH session (bash at `/workplace`). `exit` or Ctrl-D closes it. + +```bash +bunny sandbox ssh my-sandbox +bunny sandbox ssh my-sandbox -e DEBUG=1 --env-file .env # session-only variables +``` + +--- + +## `bunny sandbox cp` + +Copy a single file between the local machine and a sandbox over SFTP. Exactly one path must be `:`; relative remote paths resolve against `/workplace`. Uploads preserve the local Unix mode. Directory and sandbox-to-sandbox copies are not supported. + +```bash +bunny sandbox cp ./app.js my-sandbox:/workplace/app.js +bunny sandbox cp ./app.js my-sandbox:app.js # relative to /workplace +bunny sandbox cp ./app.js my-sandbox:/workplace/src/ # trailing slash keeps the filename +bunny sandbox cp my-sandbox:/workplace/out.log ./logs/ # ./logs must already exist +``` + +--- + +## `bunny sandbox files` + +Inspect files over SFTP. A bare sandbox name targets `/workplace`; use `:` for a specific directory. + +```bash +bunny sandbox files list my-sandbox # alias: ls +bunny sandbox files ls my-sandbox:src +bunny sandbox files ls my-sandbox --output json # name, type, size, mode +``` + +--- + +## Public URLs + +Expose ports running inside a sandbox as public HTTPS endpoints (for dev servers and APIs). + +### `bunny sandbox url add` + +Waits until the URL is provisioned and prints it. + +```bash +bunny sandbox url add my-sandbox 3000 # endpoint named "port-3000" +bunny sandbox url add my-sandbox 8080 --label my-api +``` + +### `bunny sandbox url list` / `delete` + +```bash +bunny sandbox url list my-sandbox # user-created endpoints (alias: ls) +bunny sandbox url delete my-sandbox port-3000 +bunny sandbox url rm my-sandbox my-api -f # alias; --force skips confirmation +``` + +--- + +## Persistent environment variables + +`bunny sandbox env` manages the variables baked into the container (unlike the temporary `--env` on `exec`/`ssh`). Changing them redeploys the sandbox and restarts running processes. + +### `bunny sandbox env set` + +Merges with the existing set. + +```bash +bunny sandbox env set my-sandbox NODE_ENV=production +bunny sandbox env set my-sandbox A=1 B=2 +bunny sandbox env set my-sandbox --env-file .env +``` + +### `bunny sandbox env list` / `delete` + +```bash +bunny sandbox env list my-sandbox # alias: ls (internal AGENT_TOKEN hidden) +bunny sandbox env delete my-sandbox NODE_ENV +bunny sandbox env rm my-sandbox A B # aliases: rm, unset +``` + +Unset names are reported and skipped; if none match, the command errors and nothing is redeployed.