docs: add Sandbox E2B SDK quickstart and Playground - #25
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2baa4e1ece
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| async function list() { | ||
| const rows = []; let next = '', pages = 0 | ||
| do { | ||
| const query = new URLSearchParams({ limit: '100', state: 'running,paused' }); if (next) query.set('nextToken', next) |
There was a problem hiding this comment.
Encode list states as repeated query parameters
When the Playground loads or refreshes instances, this sends a single state value of running,paused. The v2 listing contract models this filter as an array—as the repository's SDK example shows with state: ['running', 'paused'] in _archived/agents/sandbox-list.md:97-100—so the request must contain separate state=running and state=paused parameters. Servers validating the enum reject the combined value, causing every Connect/Refresh call to fail during list() and leaving the instance list unusable.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f0e1c2bf47
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
| async function loadEvents() { | ||
| const rows = await control(`/events/sandboxes/${id.value}?limit=100`) | ||
| for (const event of Array.isArray(rows) ? rows : []) if (!events.value.some(x => x.id === event.id && x.source === 'Gateway lifecycle')) events.value.unshift({ id: event.id, type: event.type, source: 'Gateway lifecycle', time: event.timestamp, data: safe(event) }) |
There was a problem hiding this comment.
Use createdAt for lifecycle event timestamps
When gateway lifecycle events are loaded, the Events API returns their timestamp in createdAt (as documented in _archived/agents/sandbox-events.md:50-62), not timestamp. Consequently every fetched lifecycle event renders an empty time beside its source, making the Playground timeline misleading; populate time from event.createdAt instead.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1971b2dfe0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const result = await control('/v2/sandboxes', 'POST', { templateID: template.value, timeout: Number(ttl.value), metadata: { docsPlayground: connectionID.value, docsCreate: attempt } }) | ||
| const currentID = idOf(result); if (!currentID) throw new Error('create_result_unknown') | ||
| if (result.envdAccessToken) tokens.set(currentID, result.envdAccessToken) | ||
| selected.value = result; pendingCreate.value = ''; await list(); await loadEvents(); record('create.completed', 'Playground', { sandboxId: currentID }) |
There was a problem hiding this comment.
Decouple optional event loading from successful creation
When the Events API is unavailable or denied—an expected possibility according to the new capabilities documentation—the sandbox has already been created and pendingCreate cleared before loadEvents() rejects. That rejection bubbles into act(), which reports the creation as “Not completed” even though a billable resource now exists and creation is immediately enabled again, risking duplicate resources. Treat the event refresh as best-effort so it cannot overwrite the successful mutation result; the same coupling also affects lifecycle actions below.
Useful? React with 👍 / 👎.
Developers can now start with the official E2B SDK or explore Sandbox operations directly in the docs. The existing Sandbox navigation contains Overview & capabilities, Quickstart / E2B SDK, and Playground (Experimental).
The SDK guide covers organization-visible templates, JavaScript and Python examples, commands and files, pause/reconnect, application-port authentication, cleanup, and troubleshooting. The English Playground supports templates with missing-name fallbacks, lifecycle actions, streamed shell output, file readback after resume, and events/logs/metrics/usage. It clearly distinguishes shell commands from AI chat.
The Playground uses the Docs theme with a wider desktop workspace: instances, operation panel, and Events appear side by side. At intermediate widths, Events stays beside the operation panel; phone screens stack the panels. Component typography is isolated from prose styles. The mobile documentation menu now clears the fixed site header.
Each visitor supplies their own API key, held only in page memory. A stateless same-origin Worker proxy uses fixed Sandbox upstreams, an explicit route allowlist, and separate control/data credentials. No shared production key is bundled or configured. Deploy the Worker and built assets together as documented in DEPLOYMENT.md.
Validation:
Credential handling: Clear key works before connection and during in-flight requests, clears displayed state, and rejects late responses. Page exit clears credentials before browser back-forward caching. Public copy limits privacy promises to Playground handling, separates key revocation and resource cleanup, and removes unnecessary provider, routing, and process-protocol details. Latest targeted tests, content/link checks, and browser clear-key verification passed.