Managing Sandboxes
Manage sandbox lifecycle in CodeCourier -- monitor status, send messages, kill sessions, and handle cleanup.
Once a sandbox is running, CodeCourier provides tools to monitor its progress, interact with the AI agent, and manage the sandbox through its full lifecycle. This guide covers status tracking, messaging, termination, cleanup, and the soft-delete/restore system.
Sandbox Lifecycle States
Every sandbox in CodeCourier is in one of five states. These are stored in the status field of the sandbox record and determine what actions are available.
Creating
The sandbox has been requested but the E2B virtual machine is still being provisioned. During this phase, CodeCourier has created a database record and is waiting for E2B to return a sandbox ID. No interaction is possible yet.
Running
The sandbox is active. The AI agent is executing inside the VM and you can send messages, view streaming terminal output, and monitor progress. The active sandbox counter for the project is incremented when a sandbox enters this state.
Paused
The sandbox has been suspended. The VM state is preserved but the agent is not actively executing. Paused sandboxes can be resumed. This state is primarily used by E2B's pause/resume functionality for long-running environments.
Killed
The sandbox has been terminated. The E2B VM has been destroyed and all in-memory state is lost. Files committed to Git before termination are preserved in the remote repository. A sandbox transitions to killed when you manually stop it, when the timeout expires, or when a workflow step completes.
Error
The sandbox encountered a fatal error. The error field on the sandbox record contains the error message. Common causes include missing API keys, E2B provisioning failures, and unrecoverable agent crashes.
State Transitions
Monitoring Sandbox Activity
Streaming Terminal Output
When you open a running sandbox in the dashboard, you see a streaming terminal view that displays the AI agent's output in real time. This includes:
- Text responses from the AI model.
- Tool use indicators (file edits, command execution, searches).
- Error messages and warnings.
- Progress updates as the agent works through its task.
The terminal output is powered by the sandboxMessagestable. Each message has a role (user or assistant),content, and optional streamLog for the raw streaming data. Messages also carry a status field (streaming, completed, or error) to indicate whether the response is still being generated.
Sandbox Detail View
The sandbox detail page shows comprehensive information about the sandbox:
- Status badge -- Visual indicator of the current lifecycle state.
- Configuration -- Template, model, timeout, memory, and CPU settings.
- Metadata -- Creation time, linked run or issue session, trigger run ID.
- Git information -- Repository URL, branch name, and PR status (if a pull request was created).
- Learning extraction status-- Whether learnings have been extracted from the sandbox's message history.
Sending Messages
For standalone sandboxes (not part of a workflow run), you can send follow-up messages to the AI agent while it is running. This is CodeCourier's interactive mode -- it works like a chat conversation where each message triggers the agent to perform additional work.
When you send a message:
- The message is stored in the
sandboxMessagestable with roleuser. - A Trigger.dev task dispatches the message to the running E2B sandbox.
- The AI CLI receives the message and begins generating a response.
- The response streams back and is stored as a message with role
assistant.
If the sandbox has already completed its initial task and the agent is idle, the follow-up message uses the CLI's --continueflag to resume the conversation context.
Workflow Sandboxes
Stopping and Killing Sandboxes
Manual Kill
You can stop a running sandbox at any time from the dashboard. When you kill a sandbox:
- CodeCourier sends a kill command to the AI CLI process inside the sandbox (e.g.,
pkill -9 -f '[c]laude'for Claude Code). - Before destroying the VM, CodeCourier detects any Git repository in the sandbox and attempts a best-effort push of uncommitted changes.
- If a non-default branch with a remote is detected, a pull request is created automatically.
- The E2B sandbox is terminated and the status is updated to
killed.
Automatic Timeout
Every sandbox has a configured timeout. When the timeout expires, E2B automatically destroys the VM. CodeCourier detects this and updates the sandbox status accordingly. The default timeout is 15 minutes for standalone sandboxes and varies for workflow steps based on the workflow configuration.
Pull Request Creation
When a sandbox finishes work (either by completing its task or being killed), CodeCourier can automatically create a GitHub pull request. The PR creation flow:
- Detect Git info from the sandbox: remote URL and current branch.
- Skip if the branch is
mainormaster(no PR needed for default branches). - Push any unpushed commits from the sandbox.
- Create a PR via the GitHub API using the configured GitHub token.
- Store the PR URL, number, and status on the sandbox record.
The PR status field tracks the pull request lifecycle:creating, created, failed,skipped, or merged.
Learning Extraction
After a sandbox completes, CodeCourier can extract learnings from the agent's message history. Learnings are patterns, preferences, gotchas, and architectural insights that the agent discovered during execution. These are stored in the learnings table and can be compiled into learning versions that are injected into future sandboxes.
The extraction status is tracked on the sandbox record:
pending-- Extraction has been queued.running-- The extraction agent is processing messages.completed-- Learnings have been extracted and stored.skipped-- Extraction was not needed (e.g., no messages).error-- Extraction failed. The error is inlearningExtractionError.
Soft Delete and Restore
Sandboxes support soft deletion. When you delete a sandbox from the dashboard, the record is not physically removed from the database. Instead, a deletedAt timestamp is set. Soft-deleted sandboxes:
- Are hidden from the default sandbox list.
- Do not count toward active sandbox counters.
- Can be restored at any time, which clears the
deletedAtfield. - Can be permanently deleted, which physically removes the database record.
This two-phase deletion pattern protects against accidental data loss. The project counters are adjusted during both soft-delete and restore operations.
Resource Management
Active Sandbox Tracking
CodeCourier maintains a denormalized counter of active sandboxes per project. This counter is incremented when a sandbox enters therunning state and decremented when it leaves. The counter is displayed in the project dashboard overview.
Usage Tracking
Every sandbox session generates usage records that track:
- E2B compute -- Sandbox runtime in seconds, billed by E2B.
- AI token usage -- Input and output tokens consumed by the AI model during the session.
- Cost calculation -- Total USD cost based on the usage cost rates configured for each service.
Usage records are linked to the sandbox via the sandboxIdfield and can be viewed in the project's billing and usage section.
// How CodeCourier tracks sandbox state transitions
await ctx.runMutation(internal.sandboxes.updateStatus, {
id: sandboxId,
status: "killed",
});
// Active counter is automatically decremented
// when transitioning from "running" to any other state