Skip to content
← Public packages

@cameronpak/box

Full Box Public API v1 client: lifecycle, prompts, files, commands, snapshots, environments, webhooks, desktop, hosting, and account.

README.md

156 lines · 5.9 KB · Markdown

@cameronpak/box

Full client for the Box Public API v1 at https://ascii.dev/api/box/v1.

Intent

This package exists so agents can run and build code in a Box cloud sandbox from Kody, without hand-writing fetch calls each time.

Success means:

  • Create a box, wait for it to be ready, and run shell commands in it.
  • Write source files into the box and build or test them.
  • Read results back out.
  • Stop, resume, or fork a box to control cost and reuse state.
  • Cover every documented Box Public API v1 endpoint as a named export.

Prompting Codex or Claude Code inside the box is included, but it is secondary. Command execution is the primary surface.

Auth

Every call sends the user secret boxApiKey as a bearer token. The host ascii.dev must be approved in the Kody account security UI.

PATCH /account/data-retention is the documented exception: it requires an interactive Box session and refuses API keys (403 session_required). The update-data-retention export still exists and will return that error for a normal service key.

Error handling

Every export returns a Result:

type Result<T> = { ok: true; data: T } | { ok: false; error: BoxError }

BoxError carries code, message, status, and requestId when the API supplies one. No export throws on an API error.

Secrets

Treat Box API keys, returned desktop/VNC URLs, hosted _token URLs, webhook signing secrets, and snapshot download signedUrl values as secrets. Do not log or persist them unredacted.

Usage

import { createBox, waitForBox, runCommand, stopBox } from 'kody:@cameronpak/box'

const created = await createBox({ ttlSeconds: 3600 })
if (!created.ok) throw new Error(created.error.message)

const boxId = created.data.box.id
await waitForBox({ boxId })

const result = await runCommand({ boxId, command: 'node --version' })
await stopBox({ boxId })

Exports

Account

  • get-me — GET /me
  • get-limits — GET /limits
  • get-data-retention — GET /account/data-retention
  • update-data-retention — PATCH /account/data-retention (session required)
  • get-deletion-operation — GET /deletion-operations/{operationId}
  • list-repos — GET /repos
  • select-repo — POST /repos
  • list-api-keys — GET /api-keys
  • get-secrets — GET /secrets
  • update-secrets — POST /secrets (full replacement)

Webhooks

  • list-webhooks — GET /webhooks
  • create-webhook — POST /webhooks
  • get-webhook — GET /webhooks/{webhookId}
  • update-webhook — PATCH /webhooks/{webhookId}
  • delete-webhook — DELETE /webhooks/{webhookId}
  • rotate-webhook-secret — POST /webhooks/{webhookId}/rotate

Environments

  • list-environments — GET /environments
  • create-environment — POST /environments
  • update-environment — PUT /environments/{environmentId}
  • delete-environment — DELETE /environments/{environmentId}
  • upgrade-environment — POST /environments/{environmentId}/upgrade
  • set-environment-var — PUT /environments/{environmentId}/vars/{key}
  • delete-environment-var — DELETE /environments/{environmentId}/vars/{key}
  • set-environment-secret-file — PUT /environments/{environmentId}/secret-files
  • delete-environment-secret-file — DELETE /environments/{environmentId}/secret-files
  • add-environment-repo — POST /environments/{environmentId}/repos
  • delete-environment-repo — DELETE /environments/{environmentId}/repos/{repositoryId}

Boxes

  • list-boxes — GET /boxes
  • create-box — POST /boxes
  • get-box — GET /boxes/{boxId}
  • update-box — PATCH /boxes/{boxId}
  • delete-box — DELETE /boxes/{boxId} (X-Ascii-Confirm-Delete, 202)
  • stop-box — POST /boxes/{boxId}/stop
  • resume-box — POST /boxes/{boxId}/resume
  • fork-box — POST /boxes/{boxId}/fork
  • wait-for-box — poll helper around get-box

Agent / I/O

  • prompt-box — POST /boxes/{boxId}/prompt
  • get-prompt-run — GET /boxes/{boxId}/prompts/{promptId}
  • list-events — GET /boxes/{boxId}/events
  • read-file — GET /boxes/{boxId}/files
  • write-file — PUT /boxes/{boxId}/files
  • run-command — POST /boxes/{boxId}/commands
  • get-command-status — GET /boxes/{boxId}/commands/{processId}
  • run-code — write-file then run-command convenience
  • download-artifact — GET /boxes/{boxId}/artifacts
  • interrupt-box — POST /boxes/{boxId}/interrupt
  • get-desktop-url — POST /boxes/{boxId}/desktop
  • configure-ssh-key — POST /boxes/{boxId}/sshkey
  • host-port — POST /boxes/{boxId}/host

Snapshots

  • list-snapshots — GET /snapshots
  • list-box-snapshots — GET /boxes/{boxId}/snapshots
  • get-latest-box-snapshot — GET /boxes/{boxId}/snapshots/latest
  • get-snapshot-tree — GET /snapshots/{snapshotId}/tree
  • get-snapshot-file — GET /snapshots/{snapshotId}/files
  • get-snapshot-download — GET /snapshots/{snapshotId}/download
  • delete-snapshot — DELETE /snapshots/{snapshotId} (X-Ascii-Confirm-Delete, 202)
  • list-named-snapshots — GET /named-snapshots
  • save-named-snapshot — POST /named-snapshots
  • get-named-snapshot — GET /named-snapshots/{name}
  • delete-named-snapshot — DELETE /named-snapshots/{name}

Limits worth knowing

  • runCommand accepts timeoutSeconds from 1 to 600. The API rejects values outside that range. Use detached: true plus getCommandStatus for longer work.
  • Kody's execute has a hard timeout near 90 seconds. Long builds belong in a workflow, or in a prompt run observed through listEvents.
  • promptBox needs Codex or Claude Code credentials configured in the Box dashboard. Without them the API returns provider_not_configured.
  • idle and running reflect prompt work only. A box stays idle while your own command runs.
  • Binary downloads (download-artifact, get-snapshot-file) are returned as base64 BinaryPayload objects.
  • Permanent delete cannot be canceled. Poll get-deletion-operation until completed.