Skip to content
Changelog

Report a bug

Use the Sandbox

A sandbox is an isolated Linux machine. An automation can use it to run shell commands, Git, the GitHub CLI, and scripts, and to keep files between runs.

AutomationSandbox
Instruction automationThe managed agent has its own sandbox. It runs commands, reads and writes files, and runs skill scripts as part of the run. Ask for this work in the instructions.
Code automationEach automation has one sandbox. Your code calls it with ctx.tools.call and the managed-sandbox service.

The rest of this page is about the sandbox of a code automation.

Code automations run in a QuickJS VM with no shell. For shell work, call these managed-sandbox tools:

ToolUse it to
exec_commandRun a short shell command and get its output.
start_background_commandStart a long command that keeps running after the call returns.
read_file, write_file, edit_fileRead and change text files.
list_directory, list_working_directoriesFind files and folders.
src/main.ts
export default class {
async check(ctx: AutomationContext, event: RecurringEvent) {
const result = await ctx.tools.call(
{
service: "managed-sandbox",
name: "exec_command",
arguments: { command: "printf automation-ready" },
},
{ automationEffectKey: `workspace-check:${event.scheduledAt}` },
);
if (result.isErr()) return err(result.error);
if (result.value.isError) return err(new TypeApiError("Command failed", "invalid_response"));
const text = result.value.content
.filter((block) => block.type === "text")
.map((block) => block.text)
.join("\n");
return ctx.setOutput({ text });
}
}
  • Each sandbox call needs an automationEffectKey, also for reads.
  • exec_command returns text content. It does not return { stdout, exitCode }. Check isError, then read the text.
  • To return structured data, print a marker and JSON, for example printf 'JSON:%s\n' "$out", then parse the line in code.
  • The first sandbox call in a run starts the sandbox. The sandbox folder is /tmp/type-automation.
  • Each automation has its own sandbox. Type keeps it between runs for speed, but it can replace it at any time.
  • Files can stay between runs. Treat them as a cache. Make setup steps safe to run again.
  • Agent checkouts and environment variables from threads are not copied into the sandbox.
  • Commands get no Type credential.

The sandbox has gh and jq. Type gives fresh GitHub credentials for the GitHub connections of the Space. The credentials belong to the automation’s creator.

TYPE_GITHUB_CONNECTIONS is a JSON list. Each item has fullName, organizationIntegrationId, and tokenEnv, the name of the environment variable that holds the token.

const repo = "acme/project"; // a fixed value, never event text
const command = [
`t=$(printf %s "$TYPE_GITHUB_CONNECTIONS" | jq -er 'first(.[] | select(.fullName == "${repo}") | .tokenEnv)') || { echo "No GitHub connection covers ${repo}" >&2; exit 1; }`,
`out=$(GH_TOKEN=$(printenv "$t") gh api 'repos/${repo}/pulls?per_page=1' --jq 'map({number, title})') || exit 1`,
`printf 'JSON:%s\\n' "$out"`,
].join("\n");
  • Sandbox commands run only in live runs. In fixtures, give the result in toolResponses. A test never starts the sandbox.
  • For GitHub, the connection must be in the Space with full automation access. If there is none, the deploy fails.
  • A shell cannot enforce read-only access. A command with a full-access token can change data.

An effect key identifies the call. It does not stop a command from running again if a run fails part of the way. Make commands safe to repeat. For example, check if a branch exists before you create it.

  • One sandbox call can take up to 170 seconds.
  • exec_command returns at most 16 KiB of output. Filter output in the command, for example with jq or head.
  • Each sandbox call counts toward the 128 requests in a run.
  • The run deadline still applies. See Limits.