Commit Graph

250 Commits

Author SHA1 Message Date
Mish Ushakov 31ad497635 feat(cli): accept E2B_API_KEY in template list & create (#1361)
## Summary

`E2B_ACCESS_TOKEN` is deprecated, so CLI commands whose endpoints accept
either credential now authenticate with `E2B_API_KEY` instead of
requiring an access token.

- `e2b template list` now uses `ensureAPIKey()`. The underlying `GET
/templates` endpoint accepts both `ApiKeyAuth` and `AccessTokenAuth`,
and since the access token is deprecated we standardize on the API key.
- `e2b template create` no longer calls `ensureAccessToken()`. Its only
API calls — `POST /v3/templates` and `POST
/v2/templates/{id}/builds/{bid}` (via the SDK's `Template.build`) —
accept only `ApiKeyAuth`, so requiring an access token locked out
API-key-only environments for no reason.
- `e2b template build` is intentionally left as-is: its v1 endpoints and
docker-registry login are access-token-only at the API level.
- Removed the now-unused `ensureAccessTokenOrAPIKey()` helper and the
`'BOTH'` variant of the auth-error box that an earlier iteration of this
PR introduced.
- Adds a real backend-integration test in
`tests/commands/template/create.test.ts` that mirrors the existing
`backend_integration.test.ts` pattern: use the real `E2B_DOMAIN` and
assert end-to-end that `template create` succeeds with only
`E2B_API_KEY` set (no `E2B_ACCESS_TOKEN`). Uses a unique template name
per run and cleans up the created template in `afterAll`.

## Test plan

- [x] `pnpm --filter @e2b/cli run typecheck`
- [x] `pnpm --filter @e2b/cli run lint`
- [x] `pnpm --filter @e2b/cli run format`
- [x] `pnpm --filter @e2b/cli run test` (local, with real `E2B_API_KEY`
— new test passes; create succeeds without `E2B_ACCESS_TOKEN`)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-16 11:25:41 +02:00
Mish Ushakov 7dc861f899 fix: align behavior and API surface between the JS and Python SDKs (#1411)
Aligns several behavioral and API-surface discrepancies between the JS
and Python SDKs found during a cross-SDK audit. **Python:**
`commands.send_stdin`/`CommandHandle.send_stdin` now accept `bytes`
(plus `request_timeout` on the handle), `git.reset` gets a typed
`GitResetMode` with JS-matching validation, `sandbox_url` is threaded
through `get_api_params` (and the dead `SandboxOpts` key removed), and
`from_image` requires both `username` and `password` when credentials
are given. **JS:** `getFullInfo` was removed in favor of a single
`getInfo` that now includes `sandboxDomain` (matching Python's
`get_info`), `fromImage` requires both credentials, `getBuildStatus`
defaults `logsOffset` to `0`, `getMetrics`/`kill` short-circuit
consistently in debug mode (instance + static), and `requestTimeoutMs:
0` explicitly disables the request timeout. Tests were added on both
sides (git-arg validation, stdin bytes, credential validation,
timeout-0, connection config) and the CLI's `sandbox info` now uses
`getInfo`. See the changeset for the full per-SDK list.

## Usage examples

```ts
// JS: registry credentials now require both fields
Template().fromImage('registry.example.com/img:latest', { username: 'u', password: 'p' })

// JS: getInfo now exposes sandboxDomain (getFullInfo removed)
const info = await Sandbox.getInfo(sandboxId)
console.log(info.sandboxDomain)

// JS: disable the request timeout
await Sandbox.create({ requestTimeoutMs: 0 })
```

```python
# Python: send raw bytes to stdin
sandbox.commands.send_stdin(cmd.pid, b"hello")

# Python: typed git reset mode (validated)
sandbox.git.reset(repo, mode="hard")

# Python: registry credentials require both fields
Template().from_image("registry.example.com/img:latest", username="u", password="p")
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 13:40:22 +00:00
Matt Brockman f90f35dbc4 Add sandbox lifecycle create option (#1404)
adds the lifecycle for autoresume/autopause and timeout to the cli

---------

Co-authored-by: Mish Ushakov <10400064+mishushakov@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 10:23:28 +00:00
Mish Ushakov f1516d5c6e refactor(cli): remove ensureAccessToken from template create (#1400)
## Summary

Removes the `ensureAccessToken()` call (and its now-unused import) from
`e2b template create`. The command authenticates solely via the API key
(`ensureAPIKey()`), so the access-token check was redundant.

## Changes

- Drop `ensureAccessToken` import and call in
`packages/cli/src/commands/template/create.ts`.
- Add a patch changeset for `@e2b/cli`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 20:21:38 +02:00
Mish Ushakov f188891e1c feat(cli): fully deprecate template build command (v1) (#1390)
## Summary

- Strips all v1 build logic from \`e2b template build\` (\`bd\`): Docker
build/push, API calls, config-loading, and retry/proxy handling are
removed
- The command now only displays the existing yellow deprecation warning
(pointing to the v2 migration guide) and exits with code 1
- Deletes \`buildWithProxy.ts\` which is no longer referenced anywhere
- Moves \`getDockerfile\` helper (used by \`template create\` and
\`template migrate\`) to a new shared \`dockerfile.ts\` module, leaving
\`build.ts\` as a clean stub

## Test plan

- [ ] Run \`e2b template build\` — confirm deprecation warning is shown
and the command exits immediately
- [ ] Run \`e2b template create\` and \`e2b template migrate\` — confirm
they still work (both use the moved \`getDockerfile\` helper)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 10:50:40 +02:00
Mish Ushakov e7a82ea9eb chore: remove unused dead code across SDK packages (#1388)
Removes internal symbols with zero references, found via knip
(js-sdk/cli) and vulture (python-sdk) and verified with repo-wide greps:
`wait` (js-sdk),
`asSandboxTemplate`/`asHeadline`/`selectOption`/`basicDockerfile` (cli),
and `format_execution_timeout_error` (python-sdk). No public API changes
— only dead, unexported-from-index or unreferenced code is dropped.
`format`, `lint`, and `typecheck` pass for all touched packages, and a
patch changeset is included for the three published packages.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 19:50:13 +02:00
Sebastion 8374033875 fix(cli): restrict ~/.e2b/config.json permissions to owner-only (#1320)
## Summary

The CLI stores credentials (E2B access token and team API key) in
plaintext at `~/.e2b/config.json`. Today the file is created with the
process default umask, which on most Linux distributions and macOS
results in mode `0644` — readable by every other local user and by any
process running as a different UID on the same machine.

This PR routes all three write sites through a single
`writeUserConfig()` helper that creates `~/.e2b` as `0700` and
`config.json` as `0600`, matching the convention used by the AWS CLI
(`~/.aws/credentials`), `kubectl` (`~/.kube/config`), and `gh`
(`~/.config/gh/hosts.yml`).

- **CWE:** CWE-312 (Cleartext Storage of Sensitive Information) —
partial mitigation. The file remains plaintext on disk (the existing `//
TODO` in `user.ts` already acknowledges that keychain storage is the
proper long-term fix); this change reduces exposure to other local users
/ less-privileged processes, which is the standard industry mitigation
while plaintext storage remains.
- **Affected file:** `packages/cli/src/user.ts` and the three writers in
`packages/cli/src/commands/`.
- **Severity:** Moderate on shared / multi-user machines (CI runners,
dev VMs, jump boxes); low on single-user workstations.

## What's in `~/.e2b/config.json`

```ts
{
  email, accessToken,           // user access token
  teamName, teamId, teamApiKey  // team API key
}
```

`accessToken` authenticates the user against the E2B control plane;
`teamApiKey` authorizes sandbox creation against the team. Either is
sufficient to impersonate the user / spend on the team's account.

## Fix

A new helper in `packages/cli/src/user.ts`:

```ts
export function writeUserConfig(configPath: string, config: UserConfig): void {
  const dir = path.dirname(configPath)
  fs.mkdirSync(dir, { recursive: true, mode: 0o700 })
  fs.chmodSync(dir, 0o700)
  fs.writeFileSync(configPath, JSON.stringify(config, null, 2), { mode: 0o600 })
  fs.chmodSync(configPath, 0o600)
}
```

The explicit `chmodSync` calls are intentional: `mkdirSync({ mode })`
and `writeFileSync({ mode })` only set permissions when the path is
created. If the directory or file already exists with looser permissions
(the common case for users upgrading), `chmodSync` corrects them on the
next write.

Call sites updated:
- `packages/cli/src/commands/auth/login.ts`
- `packages/cli/src/commands/auth/configure.ts`
- `packages/cli/src/commands/template/buildWithProxy.ts`

`logout` uses `unlinkSync` and is unaffected. I grep'd the package for
any other writers to `USER_CONFIG_PATH` — these three are the complete
set.

Behavior on Windows: `chmodSync` only manipulates the read-only bit on
Windows, which is consistent with how the AWS/kubectl/gh CLIs behave.
ACL hardening on Windows is out of scope for this change.

## Tests

Added `packages/cli/tests/user_config_permissions.test.ts`, which writes
a config to a temporary path and asserts the resulting directory is
`0700` and file is `0600`, plus that the JSON round-trips correctly.

Manually verified before/after on Linux:

```
# before this PR
$ ls -l ~/.e2b/config.json
-rw-r--r-- 1 user user 234 ... config.json
# after
$ ls -l ~/.e2b/config.json
-rw------- 1 user user 234 ... config.json
```

## Why this is worth fixing

The exploitable scenario is a multi-tenant or shared-account host:
another local user (or a process running as `nobody`, a CI worker UID, a
sandboxed app, etc.) can `cat ~/<victim>/.e2b/config.json` and lift live
credentials. No privilege escalation, no race, no special tooling — the
file is simply world-readable today.

Before submitting, I tried to disprove the finding: I checked whether
E2B sets a restrictive umask anywhere in the CLI bootstrap (it doesn't),
whether the tokens are short-lived enough to make disclosure low-impact
(the access token isn't visibly rotated and the team API key is
long-lived), and whether the directory itself was being created
restrictively elsewhere (it wasn't — `mkdirSync` was called with default
mode). None of those mitigations are in place, so the permission
tightening is doing real work.

This doesn't close out CWE-312 — that requires moving the secrets out of
plaintext entirely, which the existing TODO acknowledges. It does close
the "any local user can read it" gap, which is the cheap, high-value
half of the mitigation.

_Submitted by Sebastion — autonomous open-source security research from
[Foundation Machines](https://foundationmachines.ai). Free for public
repos via the [Sebastion AI GitHub
App](https://github.com/marketplace/sebastion-ai)._

---------

Co-authored-by: Mish Ushakov <10400064+mishushakov@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 23:07:58 -07:00
Mish Ushakov 6d66d159d1 fix(cli): handle missing xdg-open on headless machines during login (#1345)
## Summary
- `e2b auth login` previously crashed on headless machines (no
`xdg-open`) with an unhandled `error` event from the spawned browser
process.
- Attach an `error` listener (and `.catch`) to the `open` call; on
failure, print the login URL so the user can open it manually.
- Added a changeset for `@e2b/cli` (patch).

## Test plan
- [ ] On a headless Linux box without `xdg-open`, run `e2b auth login`
and confirm the CLI prints the manual URL instead of crashing.
- [ ] On macOS/Linux with a desktop, confirm the browser still opens
automatically and login completes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 20:37:24 +02:00
Matt Brockman a6a1156a76 fix: cli info handles not found without showing error message (#1247)
Handles sandbox not found on cli info
2026-04-21 08:33:07 -07:00
luo jiyin 7695889b7a Fix typos in docs, tests, and helper names (#1282)
## Summary

- fix typos in hand-written docs and comments
- rename typoed helper variables in the CLI
- fix typoed test identifiers and descriptions in the JS SDK tests
- fix typoed credential warning text in the Python SDK

## Testing

- not run

Closes #1281
2026-04-21 06:00:02 -07:00
devin-ai-integration[bot] fcb95c34e2 cli: replace sandbox.kill() with setTimeout(1s) in create command to prevent snapshot deletions (#1256)
## Summary

In the CLI's `sandbox create` command, the `connectSandbox` function's
`finally` block previously called `sandbox.kill()` when the terminal
session ended. This replaces it with `sandbox.setTimeout(1_000)` so the
sandbox expires implicitly after 1 second rather than being explicitly
killed.

The motivation is that an explicit `kill()` can trigger deletion of
historic sandbox snapshots, whereas letting the sandbox time out avoids
that side effect.

### Updates since last revision

Addressed review feedback about a race condition: `clearInterval` stops
future keep-alive ticks but cannot cancel one already in-flight. The
keep-alive callback now stores its promise in a `pendingKeepAlive`
variable, and the `finally` block awaits it (with `.catch(() => {})`)
before setting the 1s shutdown timeout. This ensures an in-flight
`setTimeout(30_000)` cannot silently override the shutdown timeout.

## Review & Testing Checklist for Human

- [ ] **Verify that `sandbox.setTimeout(1_000)` does not trigger
snapshot deletion** — this is the core assumption behind the change.
Confirm that the implicit expiry path in the backend behaves differently
from the explicit `kill()` path with respect to snapshot preservation.
- [ ] **Test `e2b sandbox create` end-to-end**: connect a terminal,
exit, and confirm the sandbox is cleaned up within a few seconds and no
snapshots are lost.
- [ ] **Review the race condition fix**: confirm that `await
pendingKeepAlive.catch(() => {})` correctly serializes against the last
in-flight keep-alive before the 1s timeout is applied. Note that the
interval callback is no longer `async` — it just assigns the promise.
- [ ] **Edge case: what happens if `setTimeout` fails?** The sandbox
would remain alive with its previous 30s keep-alive timeout. Decide if
that's acceptable or if a fallback is needed.

### Notes
- The 1-second timeout value was chosen per the request. Adjust if a
different grace period is preferred.
- The keep-alive interval (`clearInterval`) is still stopped before
awaiting the pending promise, so no new ticks will fire.

Link to Devin session:
https://app.devin.ai/sessions/68081ba06fa54be9b8127ba1d68481ae

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: ben@e2b.dev <ben@e2b.dev>
2026-04-04 01:27:28 +02:00
Matt Brockman dcaca733e4 feat (cli): adds info command to get sandbox info (#1214)
CLI now supports the `info` command that mirrors the python/js getInfo()

usage:
```
$ e2b sandbox info xxx --format json
{
  "sandboxId": "xxx",
  "templateId": "xxx",
  "name": "stdin",
  "metadata": {},
  "envdVersion": "0.4.3",
  "startedAt": "2026-03-19T01:32:28.055Z",
  "endAt": "2026-03-19T01:37:28.055Z",
  "state": "running",
  "cpuCount": 2,
  "memoryMB": 1024
}
```

```
$ e2b sandbox info xxx
Sandbox info for xxx:
Sandbox ID: xxx
Template ID: xxx
Alias: stdin
State: running
Started at: 3/18/2026, 6:32:28 PM
End at: 3/18/2026, 6:37:28 PM
vCPUs: 2
RAM MiB: 1024
Envd version: xxx
metadata: {}
```




<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: adds a new CLI subcommand and an integration test, with no
changes to existing command behavior or auth flows beyond reusing
`ensureAPIKey`.
> 
> **Overview**
> Adds a new `e2b sandbox info <sandboxID>` subcommand (alias `in`) that
calls `Sandbox.getFullInfo`, supports `--format pretty|json`, and strips
`envdAccessToken` from output.
> 
> Registers the command under `sandbox` and adds a backend integration
test asserting the JSON output includes the correct `sandboxId` and
`state`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7dbe8b7655e5a7ce023644a5cd7b422f1d1fc974. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2026-03-23 14:48:12 -07:00
Mish Ushakov 8abfa627cb fix(cli): use latest Template.build API with name parameter (#1209)
## Summary
- Updates `e2b template init` to generate code using the current
Template.build() API with the `name` parameter
- Replaces deprecated `alias` parameter usage throughout build templates
and generator code
- Maintains support for all languages (TypeScript, Python sync/async)

## Changes
- Renamed `alias` to `name` in generator functions and templates (8
files)
- Updated CLI option description and prompts to reference "template
name" consistently
- Added changeset for patch release

## Testing
All 79 template init tests pass, including validation of generated build
files.

🤖 Generated with Claude Code

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: changes are limited to CLI template-code generation and
user-facing prompts, primarily a rename from deprecated `alias` to
`name` in generated build/README templates.
> 
> **Overview**
> Updates `e2b template init`/`migrate` code generation to pass a `name`
parameter (and `name-dev` for dev builds) instead of the deprecated
`alias`, across the Handlebars generator APIs and the TypeScript/Python
build and README templates.
> 
> Cleans up CLI UX copy to consistently refer to *template name* (option
help text and interactive prompt), and adds a changeset for a patch
release.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d6e291df259a62efa4e59244b44ef8b4044d26dd. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-20 23:43:21 -07:00
Mish Ushakov db000a20e8 fix(cli): log update check errors in debug mode (#1212)
## Summary
- Add `.catch()` to the update check promise to prevent unhandled
rejections from crashing the CLI process (Node.js >= 15)
- Log caught errors only when `DEBUG` env var is set, keeping normal
output clean

## Test plan
- [ ] Run CLI normally — no error output on update check failure
- [ ] Run with `DEBUG=1` — update check errors are logged to stderr

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: only changes error handling around the update-notifier
promise, affecting logging/observability but not CLI command behavior.
> 
> **Overview**
> Makes the CLI’s update-notification check **fail-safe** by catching
promise rejections instead of silently ignoring them.
> 
> When `DEBUG` is set, the caught error is now logged to stderr (`Update
check failed:`), keeping normal CLI output unchanged.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
88dcf26c56012520bf7b1bd8f5065c102769442e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 14:05:38 +00:00
Mish Ushakov ba7caa5959 fix(cli): replace update-notifier with simple-update-notifier (#1210)
## Summary
Replaced `update-notifier` v6 with `simple-update-notifier` v2 to fix
the bundled CLI.

`update-notifier` v6 is ESM-only and spawns a child process (`check.js`)
using `import.meta.url`. When tsup bundles the CLI into a single CJS
file, these file paths become invalid and the update check silently
fails. `simple-update-notifier` is CJS-compatible, checks inline without
spawning, and has an identical API surface.

## Test plan
- ✓ All 79 existing CLI tests pass
- ✓ TypeScript, linting, and formatting checks pass
- ✓ Update check banner still displays with same interval

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: swaps the CLI update-check library and tweaks startup flow
to run the check asynchronously; behavior should be equivalent but could
affect when/if the banner prints.
> 
> **Overview**
> Fixes the CLI update banner by replacing `update-notifier` with
`simple-update-notifier`, dropping the old dependency (and its types)
and adding the new one.
> 
> Updates the CLI entrypoint to use `parseAsync()` and run the update
check via an async `main()` function after argument parsing, and adds a
changeset bumping `@e2b/cli` as a patch release.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
a2ddaeec0b4d0324f388d088916a9fcc7ba17432. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-18 06:50:24 -07:00
Jakub Novák b0ab7f7ec8 fix(cli): add implicit limit to sandbox list (#1164)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> **Low Risk**
> Low risk: CLI-only behavior change that adds a default cap and minor
output messaging; main risk is surprising users who previously relied on
unlimited listing unless they pass `--limit 0`.
> 
> **Overview**
> Adds an **implicit default limit** to `sandbox list` (now defaults to
`1000`, with `--limit 0` meaning no limit) to avoid unbounded sandbox
listing.
> 
> Updates `listSandboxes` to return `{ sandboxes, hasMore }` and prints
a note in pretty output when results are truncated, while keeping API
pagination capped at `100` per page.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3a291032c379822cb4065321f2d3db4a81a19086. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2026-03-09 13:16:08 -07:00
joe-lombrozo-s-bot[bot] bcc6ea867a feat(cli): add pause and resume commands for sandboxes (#1170)
Co-authored-by: djeebot <djeebot@users.noreply.github.com>
Co-authored-by: Joseph Lombrozo <joe.lombrozo@e2b.dev>
2026-03-02 14:51:51 -08:00
Jakub Dobry b989b29847 fix: handle invalid status codes gracefully in error handler (#1167) 2026-02-26 11:49:29 -08:00
Matt Brockman 6c1db7dc28 fix: avoid full pagination on listSandboxes in JS SDK (#1166) 2026-02-25 13:09:11 -08:00
Jakub Dobry 6798071059 fix: resolve CLI sandbox logs timeout and waitForSandboxEnd bug (#1148)
## Summary
- Skip the unnecessary `isRunning()` API call and `wait(400)` when
`--follow` is not set in `sandbox logs`, preventing flaky timeouts in
the backend integration test
- Fix `waitForSandboxEnd` to return the `running` variable instead of
the `isRunning` function reference, so the follow-mode loop actually
terminates when the sandbox stops

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Small control-flow fixes in the CLI logs loop and sandbox status
monitor; low blast radius with minimal behavioral change beyond making
termination conditions correct.
> 
> **Overview**
> `sandbox logs` now breaks out immediately after printing the first
batch when `--follow` isn’t set, avoiding extra status polling/sleeps
that could cause flaky timeouts.
> 
> Fixes `waitForSandboxEnd` to return the mutable `running` boolean
(instead of the `isRunning` function reference), so follow-mode loops
can actually stop when the sandbox exits.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
87cd7af5b1bdf9a7a4fe16e7a2100256b3d55d7b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2026-02-20 17:46:32 -08:00
Mish Ushakov a2cd86cfd4 start sandbox in detached mode using -d (#1147)
Example:

```
e2b sbx create base -d
```

Output:

```
Use the following link to inspect this Sandbox live inside the E2B Dashboard️:
↪ https://e2b.dev/dashboard/inspect/sandbox/i4dct03zur3guplje3eia

Sandbox created with ID i4dct03zur3guplje3eia using template base
```

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Small CLI behavior change isolated to sandbox creation/connection
flow; primary risk is unintended behavior differences in terminal-attach
path due to the refactor.
> 
> **Overview**
> Adds `-d, --detach` to `e2b sandbox create` so users can create a
sandbox and get its dashboard/ID output without connecting a terminal.
> 
> Refactors sandbox creation to happen in the command handler and passes
the created `sandbox` into `connectSandbox`, which now only manages the
keep-alive loop and terminal attachment when not detached.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
cb8be14bb71073b8299010cd45509ca2a58ca32e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2026-02-20 21:36:39 +00:00
Ben Fornefeld a26e2136f6 Feat: Print sandbox inspect url on sandbox spawn (#841)
This PR updates the sandbox spawn process to print the inspect URL to
the console when a new sandbox is created using `e2b sbx spawn` or `e2b
sbx create`. This makes it easier for users to access and debug new
sandboxes directly after creation.

<img width="556" height="87" alt="Screenshot 2025-09-15 at 2 54 22 PM"
src="https://github.com/user-attachments/assets/783129e3-443d-4a7c-a86e-a4265d90831f"
/>

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: primarily adds extra CLI output and URL construction with
env-configurable base; no changes to sandbox lifecycle or auth logic.
> 
> **Overview**
> **Prints a Dashboard inspection link when connecting to or creating a
sandbox.** Both `sandbox connect` and `sandbox create` now output a
terminal-clickable E2B Dashboard *Inspect Sandbox* URL immediately after
obtaining the `sandboxId`.
> 
> Adds `DASHBOARD_BASE`/`SANDBOX_INSPECT_URL` (env-overridable via
`E2B_DASHBOARD_BASE`/`E2B_DOMAIN`) and a new
`printDashboardSandboxInspectUrl` helper to format and print the link,
plus a changeset bump for `@e2b/cli`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f132029f7540408e47e4c37ee58716c95c63a000. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2026-02-20 18:32:54 +01:00
Mish Ushakov 8f53fdc746 Set default template to "base" on spawn command (#938)
- When template is unspecified, the spawn/create command will use base
as a default
2026-02-18 13:11:08 +00:00
Jakub Dobry 85f5b8d2b3 chore: various bug fixes (#1145)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> **Low Risk**
> Mostly CI/test changes plus a small logging tweak; low production
impact, with main risk being altered test timing/flake behavior due to
new timeout defaults.
> 
> **Overview**
> Improves release-candidate GitHub workflows by passing sanitized
`tag`/`preid` via step `env` vars and quoting them when running `npm
version`/`npm publish`, reducing the chance of input/expansion issues.
> 
> Stabilizes sandbox internet-access tests in JS and Python by switching
the curl target to Google’s `generate_204` endpoint and updating
expected status codes. Python tests also tighten global `pytest` timeout
to 30s, remove per-sandbox default timeouts from fixtures, and add 180s
timeouts specifically for template test suites via new `conftest.py`
files.
> 
> CLI sandbox status polling now logs the caught error when
`Sandbox.getInfo` fails (instead of silently returning `false`).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
187849338dd46f9d0dd1adb0a070719ebad87309. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2026-02-18 11:37:32 +01:00
Matt Brockman 87ceec29d9 feat: enable piping on the e2b cli (#1127)
Adds stdin piping support to `e2b sandbox exec`, so users can do:

  ```bash
  echo "data" | e2b sandbox exec <id> -- cat
cat file.bin | e2b sandbox exec <id> -- python3 -c 'import sys;
print(len(sys.stdin.buffer.read()))'
```

  Included:
  - JS SDK updates:
      - closeStdin()
      - supportsStdinClose
  - CLI updates:
      - detects piped stdin
      - streams stdin in 64 KiB chunks
      - closes remote stdin on EOF
  - graceful fallback for older sandbox versions (requires `envd` >= 0.5.2, warn + ignore piped input)


  ### Example Usage

  #### non-piped exec still works
```
  e2b sandbox exec <sandbox_id> -- 'echo backend-non-pipe'
```
  #### piped stdin path (supported envd) should deliver bytes
```
  echo "hello" | e2b sandbox exec <sandbox_id> -- 'wc -c'   # expect 6
printf '\x00\x01\x02\xff' | $e2b sandbox exec <sandbox_id> -- 'wc -c' #
expect 4
```
  #### optional: legacy template behavior should warn + ignore piped stdin
```
echo "hello" | e2b sandbox exec <legacy_sandbox_id> -- 'wc -c' # expect
0 + "Ignoring piped stdin."
```
2026-02-11 16:18:28 -08:00
Tomas Srnka 575d5bc288 fix(cli): resolve team ID from env var, avoid config mismatch (#1121)
Summary

- When E2B_API_KEY is set via environment variable, the CLI no longer
falls back to the teamId from
~/.e2b/config.json, avoiding "Team ID param mismatch with the API key"
errors
  - Adds E2B_TEAM_ID environment variable support
- Introduces resolveTeamId() helper with clear precedence: --team CLI
flag > E2B_TEAM_ID env var > config
   file (only when E2B_API_KEY env var is not set)

  Problem

When using E2B_API_KEY env var (e.g. for local development or CI with a
different team), the CLI still
reads teamId from ~/.e2b/config.json and sends it as a query parameter.
If the config file belongs to a
different team than the API key, the API rejects the request with 400:
Team ID param mismatch with the
  API key.

  Changes

  - api.ts: Export E2B_TEAM_ID env var, add resolveTeamId() helper
- list.ts, build.ts, delete.ts, publish.ts: Use resolveTeamId() instead
of inline userConfig?.teamId
  fallback

  Test plan

- Set E2B_API_KEY to a key from team A, have ~/.e2b/config.json with
team B's ID → e2b template list
  should work (no mismatch error)
  - Set both E2B_API_KEY and E2B_TEAM_ID → CLI uses the env var team ID
- Without any env vars, normal e2b auth login flow still works as before
  - --team flag still takes highest priority

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Small, localized change to CLI argument/env/config precedence for team
selection; main risk is behavior changes for users relying on implicit
`~/.e2b/config.json` teamId when also setting `E2B_API_KEY`.
> 
> **Overview**
> Fixes sandbox template commands failing with "Team ID param mismatch"
when `E2B_API_KEY` is set via environment by changing team resolution
precedence and avoiding `~/.e2b/config.json` team fallback in that case.
> 
> Introduces `E2B_TEAM_ID` and a centralized `resolveTeamId()` helper
(CLI flag > env var > local `e2b.toml` > user config *only when no env
API key*), and updates template `build`, `list`, `delete`, and `publish`
flows to use it consistently. Adds a changeset bump for `@e2b/cli`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
905172fc8e59f8325a8d36af913326f7eb47a15f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 09:46:44 -08:00
Jakub Dobry 631522d74a feat: use v2 template update endpoint with namespaced templates (#1105) 2026-01-29 07:01:41 -08:00
Jakub Dobry 10abab8e96 feat: add template versioning with tags support for JS and Python SDKs (#1080) 2026-01-27 13:41:24 +00:00
Tomas Valenta 4ebabfeaa1 Add exec command to CLI (#1090)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Adds the ability to execute commands inside a running sandbox from the
CLI.
> 
> - New `sandbox exec` command (`exec.ts`): runs a command in a
specified sandbox, supports `--background`, `--cwd`, `--user`, and
repeatable `--env` options; streams stdout/stderr; returns remote exit
code; explicitly disallows stdin piping due to protocol limitations
> - Signal handling utility (`utils/signal.ts`): installs/removes
handlers to kill the remote process on termination signals
> - Registers `exec` in `sandbox/index.ts`
> - Updates `configOption` help in `options.ts` to recommend the new
build system
> - Adds changeset for `@e2b/cli` minor release
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
dcbc64211934c1f92ff033ff77ff6ad50497e8a7. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2026-01-22 22:22:14 +01:00
Mish Ushakov 47fb2ef11d SandboxId-clientId pattern references (#1081)
Remove references to the `sandboxId-clientId` pattern as it is no longer
in use.

We're also converting the long sandbox id's in the API already:
https://github.com/e2b-dev/infra/blob/main/packages/api/internal/handlers/sandbox_get.go#L27

---
<a
href="https://cursor.com/background-agent?bcId=bc-e3bed60d-6524-431f-bce8-4934ddcc81d7"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-cursor-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-cursor-light.svg"><img alt="Open in
Cursor"
src="https://cursor.com/open-in-cursor.svg"></picture></a>&nbsp;<a
href="https://cursor.com/agents?id=bc-e3bed60d-6524-431f-bce8-4934ddcc81d7"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-web-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-web-light.svg"><img alt="Open in Web"
src="https://cursor.com/open-in-web.svg"></picture></a>

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Eliminates reliance on the deprecated `sandboxId-clientId` (short ID)
pattern and standardizes on full `sandboxId`.
> 
> - Removes `getShortID` and uses full `sandboxId` in `isRunning` (CLI
`utils.ts`), calling `Sandbox.getInfo` with the complete ID
> - Updates JS SDK tests to compare `sandboxId` via exact equality (no
`split`/`startsWith`) across list and pagination cases for
running/paused sandboxes
> - Updates Python SDK (async/sync) tests similarly to assert exact
`sandbox_id` equality in list and pagination scenarios
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7ec60a51e5b22ed9b3e90aa46110c016ce0fd73a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-01-13 17:42:44 +01:00
Mish Ushakov b65f190d5c Add dependency notice to migrate command (#995)
Current instructions would fail unless e2b was already installed

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Add `e2b` install instructions to template init/migrate outputs and
README, with minor wording tweaks and a patch changeset.
> 
> - **CLI (templates)**:
> - Update `template init` and `template migrate` post-run output to
include installing `e2b` (`npm install e2b` or `pip install e2b`).
> - Reword headings to “To get started with your template” and clarify
build command labels (run dev/prod build).
> - **Docs/Templates**:
> - Add “Installing Dependencies” section to
`packages/cli/src/templates/readme.hbs` with language-specific `e2b`
install instructions.
> - **Release**:
>   - Add patch changeset for `@e2b/cli`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
68d3093b910ef711923ecfc300ab9fc2ece69456. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-10-31 21:59:13 +01:00
Mish Ushakov ad194b4f4a CLI migrate: Rename old template files no longer needed (#991)
Here's what it will look like. This highlights that the files are no
longer used.

```
🔄 Migrating template configuration to SDK format...

Using language: TypeScript

 Generated TypeScript template files:
   ./template.ts
   ./build.dev.ts
   ./build.prod.ts

📁 Old template files no longer needed:
   ./e2b.Dockerfile → ./e2b.Dockerfile.old
   ./e2b.toml → ./e2b.toml.old

🎉 Migration completed successfully!

🔨 You can now build your template using:
   npx tsx build.dev.ts (for development)
   npx tsx build.prod.ts (for production)

Learn more about Template SDK: https://e2b.dev/docs
```



<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Post-migration, the CLI renames `e2b.Dockerfile` and `e2b.toml` to
`.old` and refactors migration to use Dockerfile content directly.
> 
> - **CLI Template Migration
(`packages/cli/src/commands/template/migrate.ts`)**
> - **Refactor**: `migrateToLanguage` now accepts `dockerfileContent`
(string) instead of a path; Dockerfile retrieval moved to the command
action via `getDockerfile`.
> - **Post-migration cleanup**: Renames `e2b.Dockerfile` and `e2b.toml`
to `*.old` if present and logs old→new paths.
>   - Minor output tweaks (status messages/icons).
> - **Tests (`packages/cli/tests/commands/template/migrate.test.ts`)**
> - Add checks ensuring `e2b.Dockerfile.old` and `e2b.toml.old` exist
and originals are removed across fixtures/languages.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5fc1add2ac8e688b7509c299211b53ac6b09188e. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-10-27 09:31:07 -07:00
Jonas Scholz 057f9027f0 Fix e2b tpl publish/delete --config flag (#968) 2025-10-17 10:04:21 -07:00
Jakub Dobry c05c8c6f24 Build System v2 Introduction (#957) 2025-10-16 04:41:21 -07:00
Jakub Dobry 3046491ea9 feat: set default user and workdir when using Dockerfile (#954)
Set default user for Dockerfiles. Includes also small migrate fixes.



<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Defaults Dockerfile-based templates to user 'user' and workdir
'/home/user', updates CLI templates (sudo start/ready, relative Python
import), and allows template migration without a config file.
> 
> - **SDKs (Dockerfile parsing)**:
> - JS (`packages/js-sdk/src/template/dockerfileParser.ts`) and Python
(`packages/python-sdk/e2b/template/dockerfile_parser.py`): after
parsing, set defaults `setUser('user')` and `setWorkdir('/home/user')`.
> - **CLI Templates**:
> - Python build scripts: switch to relative import `from .template
import template`.
> - Generated template hbs: start/ready commands now prefixed with
`sudo`; removed explicit root/workdir before start/ready.
> - **CLI Migrate**:
> - Supports migration without `e2b.toml`; uses default config values
and prints a warning instead of exiting.
> - Initializes default config when missing; success messaging adjusted.
> - **Tests**:
> - Update fixtures to reflect new defaults (`set_user('user')`,
`set_workdir('/home/user')`, `sudo` start/ready, relative imports).
>   - Relax error case to succeed with warning when config is missing.
> - Comment out stacktrace tests for `fromDockerfile` in JS/Python until
fixed.
> - **Changesets**: Patch bumps for `@e2b/cli`, `@e2b/python-sdk`, and
`e2b`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
934dc3b23b5607f70d4a4f5b7a9413a9d04df28a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-10-15 05:51:40 -07:00
Jakub Dobry a01c2374a9 feat: pretty default logs for build helper (#925) 2025-10-09 05:44:03 -07:00
Tomas Valenta 1203ccbad3 Add MCP experimental feature to beta (#936)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Adds beta MCP support to JS/Python SDKs with template auto-selection,
config POST, MCP URL helpers, and codegen for MCP types/schemas.
> 
> - **SDKs (Beta MCP support)**:
>   - **JS SDK**:
> - Add `McpServer` types and export; extend `Sandbox.betaCreate` with
`mcp` option that auto-selects `mcp-gateway-v0`, configures MCP via POST
`/config` on port `50005` with retries, and expose `betaGetMcpUrl()`.
> - Add `wait(ms)` util; generate MCP types from `spec/mcp-server.json`;
new `generate:mcp` script and dev dep `json-schema-to-typescript`.
>   - **Python SDK**:
> - Generate and export `McpServer` (TypedDict); extend sync/async
`beta_create` with `mcp` option, auto-select default MCP template, POST
MCP config with retries, and add `beta_get_mcp_url()`; define `mcp_port`
and `default_mcp_template`.
> - Makefile: add `generate-mcp` target; include
`datamodel-code-generator` in tooling; update lockfile/pyproject deps.
> - **Tooling**:
> - Add `spec/mcp-server.json` schema; update codegen Dockerfile to
install `datamodel-code-generator`.
> -
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
cf3f175d310d4c242cd2e867efd801f5c04f2099. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Jonas Scholz <Jonas.Scholz@bbscholz.de>
2025-10-09 08:37:32 +00:00
Jakub Dobry a0b6104320 feat: add build v2 command that uses template SDK (#926)
Add template `build-v2` command that uses template SDK

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Introduce `template build-v2` command that builds templates directly
from a Dockerfile via the Template SDK and wire it into the CLI.
> 
> - **CLI - Template**:
> - **New Command**: `template build-v2`
(`packages/cli/src/commands/template/build-v2.ts`)
> - Builds from Dockerfile using SDK:
`Template(...).fromDockerfile(...)` and `Template.build(...)`.
> - Options: `--dockerfile`, `--cmd`, `--ready-cmd`, `--cpu-count`,
`--memory-mb`, `--no-cache`, path via `--path`; alias `bd-v2`.
>     - Validations: template name format, even `memory-mb`.
> - Auth/config: uses access token, API key, domain; streams build logs;
prints success examples.
> - **Wiring**: Add `buildV2Command` to
`packages/cli/src/commands/template/index.ts`.
> - **Release**: Changeset adds patch for `@e2b/cli`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
33578b56dfbcd76c3bb2ecf7fdf6f2cb80c3d0dd. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-10-08 12:44:21 +02:00
Tomas Valenta f5cfa6d897 Update node version in SDK and CLI (#935) 2025-10-08 00:46:01 +00:00
Jonas Scholz ad4b882bff Fix e2b sbx logs -f <id> not following (#930)
This PR fixes 2 bugs that made the follow option in `e2b sbx logs` not
work:

1. `e2b sbx logs -f <id>` failed to follow because the `isRunning`
function was always returning false due to the API call being
unauthenticated if you dont have the `E2B_API_KEY` environment variable
set.

This follows the existing pattern from other API calls:

https://github.com/e2b-dev/E2B/blob/c4ce97e9b9a1809e3419d64499c1e56f9138e3d0/packages/cli/src/commands/sandbox/list.ts#L138-L152

Eventually it would make sense to handle the error here, for now just a
hotfix to fix the --follow usage

2. Once it actually followed, it never stopped following because
`isRunning` was not inside the loop and always true. Now when you kill
the sandbox follow actually stops following

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Fixes `e2b sbx logs -f` by authenticating `isRunning` and re-checking
sandbox state each loop so following works and stops when closed.
> 
> - **CLI — `packages/cli/src/commands/sandbox`**:
>   - **Logs follow behavior (`logs.ts`)**:
> - Re-check `isRunning(sandboxID)` inside the loop (`isSandboxRunning`)
instead of using a cached promise, ensuring follow stops when sandbox is
closed or not found.
>   - **Sandbox state check auth (`utils.ts`)**:
> - Use `ensureAPIKey()` and pass `apiKey` to
`Sandbox.getInfo(getShortID(sandboxID), { apiKey })` so `isRunning` is
authenticated.
> - **Release**:
> - Changeset adds patch for `@e2b/cli` with note: fix sbx logs follow
option.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5fbd87166b70aca7229ccc1ff8fa2c27f12b1641. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
2025-10-03 15:06:17 -07:00
Jakub Dobry 4da865c1f3 fix: add queue for terminal input (#924) 2025-09-30 08:49:39 -07:00
Jakub Dobry ad7ad6f101 Scope template build for typescript and python (#922) 2025-09-29 04:47:24 -07:00
Jakub Dobry 2ec9ea8a44 feat: add template init for new template SDK (#881) 2025-09-26 06:40:58 -07:00
Jakub Novák d90c201cf3 Update docstring in toml after CLI template build (#868)
Forgotten text with old way how to create sandbox in sync Python
2025-09-26 12:06:27 +00:00
Jakub Dobry b43793ceb9 Fix CLI template migrate copy target (#915) 2025-09-25 02:09:04 -07:00
Jakub Dobry b9c4b16baa feat: add template migration to CLI (#880)
## 🔄 Add Template Migration to CLI

### Summary

This PR introduces a new `migrate` command to the E2B CLI that helps
users transition from the legacy Dockerfile + TOML configuration format
to the new Template SDK format. The migration tool automatically
converts existing `e2b.Dockerfile` and `e2b.toml` configurations into
SDK-compatible template files using Handlebars templates.

### What's Changed

####  New Features

- **Template Migration Command**: Added `e2b template migrate` command
for converting legacy configurations to SDK format
- **Multi-Language Support**: Supports migration to TypeScript, Python
(sync), and Python (async) formats
- **Interactive Language Selection**: CLI prompts for target language
when not specified
- **Multi-stage Dockerfile Support**: Added fallback handling for
complex multi-stage Dockerfiles

#### 🔧 Technical Improvements

- **Enhanced ENV Handling**: Improved parsing of multiple environment
variables from single ENV instructions
- **File Name Conflict Resolution**: Automatic unique filename
generation to prevent overwriting existing files
- **Comprehensive Template Generation**: Creates both development and
production build files

#### 📁 New Template Files

- `typescript-template.hbs` - TypeScript template generation
- `typescript-build.hbs` - TypeScript build script template
- `python-template.hbs` - Python template generation (supports both
sync/async)
- `python-build-async.hbs` - Python async build script template
- `python-build-sync.hbs` - Python sync build script template

### Usage

```bash
# Migrate with interactive language selection
e2b template migrate

# Migrate to specific language
e2b template migrate --language typescript
e2b template migrate --language python-sync
e2b template migrate --language python-async

# Custom paths
e2b template migrate --dockerfile custom.dockerfile --config custom.toml
```

### Generated Output

The migration command generates three files per target:
- `template.{ts|py}` - Template definition using SDK
- `build{.|_}dev.{ts|py}` - Development build script
- `build{.|_}prod.{ts|py}` - Production build script

### Migration Process

1. **Parse Configuration**: Reads `e2b.toml` for template settings
2. **Dockerfile Analysis**: Uses E2B SDK to parse Dockerfile
instructions
3. **Transformation**: Converts Docker instructions to SDK method calls
4. **Code Generation**: Uses Handlebars templates to generate target
language files
5. **File Creation**: Writes template and build files with conflict
resolution

### Error Handling

- **Graceful Dockerfile Parsing**: Falls back to custom image reference
for unparseable Dockerfiles
- **Clear User Guidance**: Provides manual build instructions when
automatic conversion fails
- **Validation**: Ensures required configuration files exist before
migration
2025-09-19 17:41:28 +02:00
Mish Ushakov c6efe1f26c CLI: format table > pretty to match rest of DX, added docs (#905)
Follow up my last PR, improves DX consistency and added docs.

Changelog

- format "table" > "pretty" to match other commands (metrics, logs)
- added doc section
2025-09-14 22:27:29 -07:00
Mish Ushakov 2a346bfcd2 Added format option to CLI sandbox + templates list (#903)
This PR is based on https://github.com/e2b-dev/E2B/pull/902, please
proceed with that first

**Changelog**

- Added `--format` option to "e2b sandbox list" and "e2b template list".
Can either be "table" or "json"

Sandboxes list in JSON format

<img width="471" height="341" alt="Screenshot 2025-09-12 at 11 17 45"
src="https://github.com/user-attachments/assets/13455b62-5efb-4b11-8fe3-a39b3fb6dffc"
/>

Templates list in JSON format

<img width="449" height="377" alt="Screenshot 2025-09-12 at 11 18 55"
src="https://github.com/user-attachments/assets/47fa3c2b-2e4c-4854-a87f-65c325261521"
/>
2025-09-12 21:47:07 +02:00
Mish Ushakov a116679b87 CLI: Refactored sandbox kill command (#904)
**Changelog**

- Added ability to pass multiple sandbox ids to "sbx kill id1 id2 id3"
- Added ability to filter sandboxes to be killed by metadata and by
state using --state, --metadata (requires --all)
- Fixed metadata parser and moved to utils
2025-09-12 21:45:25 +02:00
Mish Ushakov 67070bb9ea Synced spec + generated API client (#889)
Changelog

- Synced latest spec from e2b-dev/infra
- Regenerated API clients
2025-09-03 05:43:47 -07:00