## Summary
Resolves all 31 open [Dependabot
alerts](https://github.com/e2b-dev/e2b/security/dependabot) across the
workspace.
- **npm** — added range-based `pnpm.overrides` to bump vulnerable
transitive deps to their patched versions: postcss, vite, lodash,
brace-expansion, picomatch (2.x + 4.x), yaml, @tootallnate/once,
smol-toml, flatted, and minimatch (3.x/5.x/9.x/10.x).
- **python-sdk** — bumped dev deps in `poetry.lock`: pytest 7.4 → 9.0.3
(with constraint update in `pyproject.toml`), pytest-asyncio 0.23 → 1.3
(required for pytest 9), python-dotenv 1.2.2, pygments 2.20.0, requests
2.33.1, black 26.3.1; removed 4 now-unused `# ty: ignore` directives
that pytest 9's stricter type signatures made obsolete.
## Test plan
- [x] \`pnpm run typecheck\` passes
- [x] \`pnpm run lint\` passes
- [x] \`pnpm run format\` clean
- [x] CLI tests (80/80) and js-sdk/python-sdk unit tests pass;
integration tests not run locally (need \`E2B_API_KEY\`)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
## Summary
Consolidates the fix and tests from #1285 and #1293 into a single PR.
- **js-sdk**: `uploadFile` used to pass a Node `Readable` directly to
`fetch`, causing undici to fall back to `Transfer-Encoding: chunked`. S3
presigned PUT URLs reject chunked with 501 NotImplemented. Fix buffers
the archive first so `Content-Length` is set. Includes:
- Regression test that spins up a local HTTP server and asserts
`Content-Length` is set and matches the body, and `Transfer-Encoding` is
not chunked.
- Type-fix for the CLI's typecheck (cast `Pack` →
`AsyncIterable<Buffer>`).
- Dynamic import of `node:stream/consumers` so the browser bundle
doesn't pull it in.
- **python-sdk**: Adds sync + async regression tests for `upload_file`
that guard against the same class of bug (someone swapping
`tar_buffer.getvalue()` for a stream/generator). No Python code change —
the current implementation already passes bytes to `httpx.put(...,
content=...)`.
Authorship of the original JS fix commit preserved (truffle-dev).
Closes#1243.
## Test plan
- [x] `pnpm run test tests/template/uploadFile.test.ts` — passes
- [x] `pnpm run typecheck` / `lint` clean across js-sdk and cli
- [x] `poetry run pytest tests/sync/template_sync/test_upload_file.py
tests/async/template_async/test_upload_file.py -v` — both pass
- [x] `poetry run make format` / `make lint` / `make typecheck` clean
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: truffle <truffleagent@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
## Summary
- Deletes install test files for apt, bun, npm, and pip in both JS and
Python SDKs
- Removes sync and async variants in Python
- Stacktrace tests for these install methods are kept
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- Bumps metrics polling from 15s to 30s in Python async/sync and JS SDK
tests so the backend has enough headroom to populate metrics under load
— this test was the new #1 CI offender (5/9 Python runs and 4/10 JS runs
failed).
- Raises the async Python sandbox timeout from 20s to 60s for parity
with sync, and adds per-test timeout overrides
(`@pytest.mark.timeout(60)` / `{ timeout: 60_000 }`) so polling can
complete under the default 30s pytest/vitest cap.
- Happy path is unchanged: the loop still breaks as soon as metrics
appear.
## Test plan
- [x] `pnpm run format`, `pnpm run lint`, `pnpm run typecheck` pass
- [x] `test_sbx_metrics` (Python async) passed locally in 8.4s
- [x] `test_sbx_metrics` (Python sync) passed locally in 15.6s
- [x] `metrics.test.ts` (JS) passed locally in 20.7s
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
## Summary
Fixes#1154
When creating a sandbox with an `mcp` config, the JSON-serialized config
is interpolated directly into a shell command wrapped in single quotes.
Since `json.dumps()` / `JSON.stringify()` do not escape single quotes,
any MCP config value containing a single quote (e.g., API keys, tokens,
URLs) breaks out of shell quoting and allows arbitrary command execution
inside the sandbox.
## Changes
### Python SDK (`sandbox_async/main.py`, `sandbox_sync/main.py`)
- Use `shlex.quote()` to properly escape the JSON config string (4
locations)
- `shlex.quote()` is a stdlib function designed exactly for this purpose
### JS/TS SDK (`sandbox/index.ts`)
- Add a `shellQuote()` helper that escapes single quotes using the
standard `'\'''` pattern (equivalent to Python's `shlex.quote()`)
- Apply it to both MCP config interpolation sites (2 locations)
## Before / After
**Before** (vulnerable):
```
mcp-gateway --config '{"servers": {"test": {"envs": {"KEY": "it's a value"}}}}'
# ^^ breaks out
```
**After** (safe):
```
mcp-gateway --config '{"servers": {"test": {"envs": {"KEY": "it'\''s a value"}}}}'
# ^^^^ properly escaped
```
## Testing
Verified escaping behavior for both Python (`shlex.quote`) and JS
(`shellQuote`) with the PoC from the issue — single quotes in config
values are properly escaped and no longer allow shell breakout.
---------
Co-authored-by: Mish Ushakov <10400064+mishushakov@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
## 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
## Summary
- Adds `template` as an optional property on `SandboxOpts` in the JS
SDK, enabling `Sandbox.create({ template: 'my-template' })` syntax
- Updates both `create` and `betaCreate` to check `opts.template` before
falling back to the default template
- Python SDK already supports `Sandbox.create(template='template')` via
named parameters, so no changes needed there
## Test plan
- [ ] Verify `Sandbox.create({ template: 'base' })` works
- [ ] Verify `Sandbox.create('base')` still works (backwards compatible)
- [ ] Verify `Sandbox.create()` still defaults to `'base'`
- [ ] Verify MCP template fallback still works when no template is
specified
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- Fixes the Python SDK `write_files` docstring (both sync and async)
which incorrectly stated that writing to a non-existing directory would
produce an error
- The backend actually auto-creates parent directories, consistent with
the `write()` docstring and existing tests
(`test_write_to_non_existing_directory`)
## Test plan
- [x] Verified behavior with a test script — both `write()` and
`write_files()` auto-create nested directories
- [x] Existing tests pass (`test_write_to_non_existing_directory`,
`writeFiles creates parent directories`)
## 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>
## Summary
- Adds optional `gzip` parameter to sandbox file read/write operations
across JS and Python SDKs
- Uploads are gzip-compressed via `CompressionStream` (JS) /
`gzip.compress` (Python) when enabled, downloads request
`Accept-Encoding: gzip`
- Only applies to the octet-stream upload path (envd >= 0.5.7), so older
envd versions are unaffected
- Includes tests for both SDKs covering write+read with gzip, write gzip
+ read plain, multi-file writes, and byte format reads
## Test plan
- [ ] Run JS SDK content encoding tests (`contentEncoding.test.ts`)
- [ ] Run Python async/sync content encoding tests
(`test_content_encoding.py`)
- [ ] Integration test with envd backend supporting `Content-Encoding:
gzip`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- Switches sandbox filesystem file uploads from `multipart/form-data` to
`application/octet-stream` in both the JS and Python SDKs
- Each file is now uploaded as raw binary with the path passed as a
query parameter, matching the `application/octet-stream` content type in
the envd API spec
- Multi-file writes send one request per file sequentially
## Test plan
- [ ] Run JS SDK filesystem write tests (`pnpm run test` in
`packages/js-sdk`)
- [ ] Run Python SDK filesystem write tests (`pytest` in
`packages/python-sdk`)
- [ ] Verify single file write, multi-file write, and various data types
(string, bytes, streams)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Increases the default timeout for volume `writeFile`/`write_file`
operations from 60 seconds to 1 hour in both the JS and Python SDKs.
Other volume operations retain the existing 60s default. Users can still
override via `requestTimeoutMs` (JS) or `request_timeout` (Python).
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- Made `runCode()` and `run_code()` references in READMEs link to the
[code interpreting docs](https://e2b.dev/docs/code-interpreting)
- Updated root README, js-sdk README, and python-sdk README
## Test plan
- [ ] Verify links render correctly on GitHub
- [ ] Confirm docs URL resolves
## Summary
- Updated root README, js-sdk README, and python-sdk README to show base
`e2b` SDK install and usage as the default
- Code-interpreter is now shown as an optional step for when
`runCode()`/`run_code()` is actually needed
- SDK links in descriptions now point to base `e2b` packages on npm/PyPI
## Why
The base `e2b` package covers commands, files, git, networking, and
sandbox lifecycle. Users who don't need code execution shouldn't be
directed to install `@e2b/code-interpreter` / `e2b-code-interpreter` as
their first step.
## Test plan
- [ ] Verify README renders correctly on GitHub
- [ ] Confirm base SDK examples use correct import syntax
- [ ] Confirm code-interpreter section still shows correct usage for
`runCode()`
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 -->
extracts the `allow_internet_access`, `lifecycle`, and `network` configs
to the get info responses from the api when present.
Create a sandbox with lifecycle and network rules, check info while
running, pause it, and check info again. Network rules, lifecycle
config, and `allowInternetAccess` all returned while running and paused
```
$ e2b sandbox info xxx --format json
# running
{
"sandboxId": "xxx",
"templateId": "xxx",
"name": "stdin",
"metadata": {},
"allowInternetAccess": true,
"envdVersion": "0.4.3",
"startedAt": "2026-03-19T01:39:56.238Z",
"endAt": "2026-03-19T01:44:56.238Z",
"state": "running",
"cpuCount": 2,
"memoryMB": 1024,
"network": {
"allowOut": ["api.example.com", "cdn.example.com"],
"denyOut": ["0.0.0.0/0"],
"allowPublicTraffic": true
},
"lifecycle": {
"onTimeout": "pause",
"autoResume": true
}
}
# paused
{
"sandboxId": "xxx",
"templateId": "xxx",
"metadata": {},
"allowInternetAccess": true,
"envdVersion": "0.4.3",
"startedAt": "2026-03-19T01:39:56.238Z",
"endAt": "2026-03-19T01:40:27.964Z",
"state": "paused",
"cpuCount": 2,
"memoryMB": 1024,
"network": {
"allowOut": ["api.example.com", "cdn.example.com"],
"denyOut": ["0.0.0.0/0"],
"allowPublicTraffic": true
},
"lifecycle": {
"onTimeout": "pause",
"autoResume": true
}
}
```
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Updates the public `sandbox info` response shape across OpenAPI, JS,
and Python SDKs, which may impact downstream consumers that assume the
previous schema. Risk is moderate since changes are additive/optional
but touch generated models and response mapping logic.
>
> **Overview**
> **Sandbox info responses now include network and lifecycle
configuration when present.** The OpenAPI spec and generated JS schema
extend `SandboxDetail` with `allowInternetAccess`, `network`, and a new
`lifecycle` object (with `SandboxOnTimeout` and `SandboxLifecycle`).
>
> The JS SDK updates `SandboxApi.getFullInfo()` and exported types to
return these fields, introducing `SandboxInfoLifecycle` for info
responses. The Python SDK updates generated client models accordingly,
adds `SandboxLifecycle`/`SandboxOnTimeout` models, and maps
`SandboxDetail.network`/`SandboxDetail.lifecycle` into `SandboxInfo`
(plus exports `SandboxInfoLifecycle`).
>
> A changeset bumps `@e2b/python-sdk` and `e2b` as minor for the
expanded info payload.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
adb22292c08b1db9c8fe60c702f83fee2695af97. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> **Medium Risk**
> Changes how instance methods merge and forward connection options (api
key/domain/headers/timeouts) to API calls in both JS and Python SDKs,
which can affect request routing and auth headers. Regression tests
reduce risk but behavior changes could impact callers relying on
previous (incorrect) defaults.
>
> **Overview**
> Fixes **missing propagation of instance `connectionConfig`** when
calling sandbox instance methods (notably `pause`/`betaPause`/`connect`,
plus related methods) so default config is always forwarded and per-call
overrides still win.
>
> In the JS SDK this centralizes option merging via a new
`resolveApiOpts()` helper and updates multiple `SandboxApi.*` calls to
use it; in the Python SDK it updates `Sandbox.connect()` and
`Sandbox.pause()` (sync + async) to pass
`self.connection_config.get_api_params(**opts)`.
>
> Adds regression tests in both SDKs to assert defaults are forwarded
and overrides are applied correctly.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
60aa6ca1c386d99613976269106298267d5dbfbe. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> **Medium Risk**
> Changes public error/exception types in both JS and Python SDKs by
introducing new subclasses and remapping 404/NotFound conditions, which
may affect downstream error handling despite deprecation shims.
>
> **Overview**
> **Distinguishes “sandbox not found” from “file/directory not found”
across the SDKs.** Adds `FileNotFound*` and `SandboxNotFound*`
error/exception types (with `NotFound*` marked deprecated) and updates
sandbox lifecycle APIs to throw `SandboxNotFound*` for
missing/non-running sandboxes.
>
> Refactors envd HTTP/RPC error handling in both JS and Python to
support overridable status/code→error maps, and wires filesystem
operations to map 404/`NotFound` into `FileNotFound*`. Tests are updated
accordingly, and patch changesets are added for both packages.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
73da92694c02f71355b1f8625845c82865bf3b1d. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## 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>
## Summary
- Added `fixMissing` option to `aptInstall()` in JS SDK
- Added `fix_missing` parameter to `apt_install()` in Python SDK
- Enables `--fix-missing` flag for `apt-get install` command
🤖 Generated with Claude Code
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk: adds an optional flag passthrough to the generated `apt-get
install` command in both SDKs, with no behavior change unless explicitly
enabled.
>
> **Overview**
> Adds an optional `fixMissing` (JS) / `fix_missing` (Python) parameter
to template `apt` install helpers so callers can emit `apt-get install
--fix-missing` when builds hit transient package download issues.
>
> Updates the JS type definitions/docs accordingly and includes a
changeset bumping `e2b` and `@e2b/python-sdk` as a minor release.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
4c0b897e192c3ec6b880ab4e3f1695f1b1289d7b. 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>
## 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>
## 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>
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> **Medium Risk**
> Changes request timeout semantics for server-stream calls by adding
`write` and conditional `read` timeouts, which could alter behavior for
long-running/slow streams but is limited to client-side networking
configuration.
>
> **Overview**
> **Improves timeout handling for server-stream requests in the Python
SDK.** `Client._prepare_server_stream_request` now builds a richer
`httpcore` timeout extension: `request_timeout` applies to `connect`,
`pool`, and `write`, and the separate `timeout` parameter is mapped to a
`read` timeout (to help prevent hanging streams).
>
> Adds a changeset to publish a patch release documenting the updated
`request_timeout` behavior.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
e66ef8e5056cfdb81892222881519e5e63f9e514. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Matt Brockman <matt.brockman@e2b.dev>
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> **Medium Risk**
> Medium risk because it deletes a large subtree (`apps/web`) and
removes SDK-reference generation/commit steps from the package publish
workflow, which may affect downstream docs/release expectations.
>
> **Overview**
> **Removes the docs web app and generated SDK reference content.** The
PR deletes `apps/web` configs/scripts (Next.js/MDX setup, Sentry config,
prebuild/sitemap generation) and removes the committed `sdk-reference`
MDX pages.
>
> **Simplifies repo automation and ownership.** The package publish
workflow no longer generates/clones/commits SDK reference docs,
`CODEOWNERS` drops web/docs ownership entries, and the root ESLint
config removes `@stylistic/ts` in favor of the built-in `semi` rule.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
4158d777b5f3d3fa30b538e434d34ce0e697d473. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- 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 -->
## Summary
- Fixes `Sandbox.create()` failing in self-hosted environments because
`sandboxHeaders` were not propagated to `EnvdApiClient`
- Spreads `sandboxHeaders` (`E2b-Sandbox-Id`, `E2b-Sandbox-Port`) into
the headers passed to the envd API client
Closes#1158
Based on #1159 by @ajuijas
## Test plan
- [ ] Verify sandbox creation works in self-hosted environments
- [ ] Verify sandbox headers are correctly passed to EnvdApiClient
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> <sup>[Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) is
generating a summary for commit
f78d8b53196ced16dc48916720f02a1cb957884b. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Signed-off-by: ajuijas <ijas.ahmd.ap@gmail.com>
Co-authored-by: ajuijas <ijas.ahmd.ap@gmail.com>
## Summary
- Enable glob patterns to match files starting with dot (e.g., `.env`,
`.gitignore`)
- JS SDK: Add `dot: true` to glob calls in `getAllFilesInPath`
- Python SDK: Add `glob.DOTMATCH` flag to glob calls in
`get_all_files_in_path`
- Add comprehensive tests for dotfile handling in both SDKs
Previously, the glob library defaults prevented dotfiles from being
matched, preventing upload of configuration files like `.env`. This fix
enables proper handling of dotfiles in template file uploads.
## Test plan
- ✅ All 16 JS SDK tests pass (4 new dotfile tests)
- ✅ All 17 Python SDK tests pass (4 new dotfile tests)
- ✅ `pnpm run format` passes
- ✅ `pnpm run lint` passes
- ✅ `pnpm run typecheck` passes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Small, well-scoped change to glob options that only broadens matched
file sets; main risk is unintentionally including hidden files unless
excluded via ignore patterns.
>
> **Overview**
> Template file collection now includes dot-prefixed files and
directories (e.g., `.env`, `.gitignore`, `.hidden/**`) when
building/uploading templates.
>
> This updates globbing in the JS SDK’s `getAllFilesInPath` to set `dot:
true` (including recursive directory expansion) and the Python SDK’s
`get_all_files_in_path` to add `glob.DOTMATCH`, and adds targeted tests
in both SDKs to verify dotfile inclusion and that ignore patterns still
exclude specified dotfiles. A changeset bumps both `e2b` and
`@e2b/python-sdk` as patch releases.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
fc3cbcc232bc28559d38bb267162d3f55138b558. 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>
Implements the `lifecycle` prop on `Sandbox.create`, taking over and
deprecating the `beta_pause` functionality.
Currently supports:
- `on_timeout`: `kill` (default) | `pause`. Controls what should happen
to the sandbox when it hits end of life. Pause allows for resuming
- `auto_resume`: False (default) | True. Whether the sandbox should
autoresume on traffic
Intended for additional functionality as we update the backend to
support additional props. Blocked from deploying until the API and
client-proxy are deployed but for pre-approval.
(Meant to be extended later as add more capabilities to the API)
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Changes the API contract and request payload shape for sandbox
auto-resume and alters lifecycle/timeout behavior mapping, which could
break older integrations if backend/client versions are mismatched.
>
> **Overview**
> Adds a new `lifecycle` configuration on `Sandbox.create` (JS + Python)
to control what happens at timeout (`kill` vs `pause`) and whether
paused sandboxes auto-resume on traffic (`auto_resume`).
>
> Deprecates `betaPause`/`beta_pause` and the JS `autoPause` create
option in favor of the new lifecycle semantics, updates connect/pause
call paths accordingly, and expands tests to cover resume-on-connect and
auto-resume behaviors.
>
> Updates the OpenAPI contract and generated clients so `autoResume` is
now an object with an `enabled: boolean` flag (removing the previous
policy enum), and bumps SDK versions via a changeset.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
515f9b7fc13a5ec13db75450e8f6252e3c7bcf03. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## Summary
- Add `GET /templates/{templateID}/tags` endpoint to the OpenAPI spec
- Add `Template.getTags()` to JS/TS SDK
- Add `Template.get_tags()` (sync) and `AsyncTemplate.get_tags()`
(async) to Python SDK
- Returns a list of `TemplateTag` objects with `tag`, `buildId`, and
`createdAt` fields
## Test plan
- Added unit tests for JS SDK (`Template.getTags` happy path + 404
error)
- Added unit tests for Python SDK (sync + async, happy path + error)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Clarifies connection behavior in JS SDK API clients; no functional
changes.
>
> - Adds inline comments in `api/index.ts` and `envd/api.ts` noting that
undici keeps connections alive by default and leaves `keepalive`
commented out
> - No code path, config, or runtime behavior modified
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
127f6fe57151e86a0a5280af58902f1efb1e46ee. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->