Docs/Sandbox CLI (v2) (Beta)
#

Sandbox CLI (v2) (Beta)

Every cofactor sandbox command for Sandboxes v2: what it does, its flags, and what its JSON output contains.

All Sandboxes v2 commands live under cofactor sandbox. The same command group also holds the older Sandboxes (Beta) commands (create, provision, logs, diagnostics and others); this page covers only the v2 ones.

CommandWhat it does
validateCheck a cofactor.sandbox.yaml offline
connectBuild an application's sandboxes from a GitHub repository
pushPush a built image as the application's next version
envsWhat an application's sandboxes offer
claimClaim a sandbox
showA sandbox's status, URLs, logins and seed outputs
runRun an action or emulator operation on a sandbox
destroyTear a sandbox down
verify-envProve each environment's seed chain runs, end to end
previewA pull request's preview and its logins
guide v2Print the built-in Sandboxes v2 guide

01Common flags

  • --application <name|id> names the application (case-insensitive name, or id). --property is accepted as an alias. Required by connect, push, envs, claim, verify-env and preview.
  • --environment <name> is a sandbox environment from the definition (default, free-plan…).
  • --env <dev|prod> is the CLI's global flag for which Cofactor to talk to. It has nothing to do with a sandbox's environment, which is always --environment.
  • --json prints machine-readable output on stdout (progress, where there is any, goes to stderr). Accepted by every command except destroy.
  • The other global flags (--org, --token, --api-url) work as on every command. See Command reference.

connect, push, envs, claim, show, run, verify-env and destroy refuse any argument they don't take, rather than ignoring it: a quoted "--at pr-12" is an error, not a claim of the newest version. validate, preview and guide v2 don't check for unknown arguments.

validate and guide v2 run offline with no login. Every other command needs a logged-in session or an API key; the sandbox scope table lists what each needs.

02The core loop

bash
cofactor sandbox validate [--upload]                          # check the definition
cofactor sandbox push --application A <image> --wait          # or: connect, once
cofactor sandbox envs --application A                         # what's there
cofactor sandbox claim --application A --environment E --wait # get a sandbox
cofactor sandbox run <id> <action> --input k=v                # as many times as the test needs
cofactor sandbox destroy <id>                                 # always

03validate

bash
cofactor sandbox validate [file] [--upload] [--json]

Offline schema check and cross-check of a definition. No sandbox, no login.

Argument / flagMeaning
fileThe definition. Default: ./cofactor.sandbox.yaml.
--uploadCheck it as a definition for pushed images (no setup, no lifecycle.build, no after_build). Without it, as one built from a GitHub checkout (setup and lifecycle.build required).
--jsonPrint { ok, issues }.

On success it prints the counts of environments, actions and emulator operations. On failure it prints one path: message line per issue and exits 1. See Sandbox definition for every rule.

JSON output:

json
{ "ok": false, "issues": [{ "path": "environments.default.seeds[0].action", "message": "unknown action \"create-workspce\"" }] }

04connect

bash
cofactor sandbox connect --application <name|id> --repo <owner/name> [--dir <path>] [--json]

Builds the application's sandboxes from a GitHub repository: the cofactor.sandbox.yaml under --dir at each commit. Requires GitHub to be connected to your organization.

FlagMeaning
--repoThe repository, owner/name. Required.
--dirThe definition's directory, relative to the repository root, with no leading or trailing / and no ... Default: . (the root).

connect reads the definition at the default branch's head and saves nothing unless it exists and is valid (invalid definitions print their issues). Then the definition's environments become the application's sandbox environments and its personas the application's personas. Each repository directory belongs to at most one application.

Output: the same as envs.

See Sandboxes from GitHub.

05push

bash
cofactor sandbox push --application <name|id> <image> [--definition <file>] [--tag <tag>]... [--wait] [--json]

For an application that gives Cofactor no repository access: pushes a locally built image, with its definition, as the application's next version.

Argument / flagMeaning
imageA local Docker image (name:tag or id). It must be linux/amd64, with a WORKDIR other than /. Required.
--definitionThe definition to push with the image. Default: ./cofactor.sandbox.yaml. Validated as for validate --upload before anything is uploaded.
--tagName this push. Repeatable, up to 10. Letters, digits, ., _ and -, at most 64 characters, starting with a letter or digit. A tag always names the newest ready push carrying it. Also accepted as --tag=<tag>.
--waitWait until Cofactor has imported the image: booted it until every service is healthy. It waits up to 50 minutes; if the import is still going then, push prints the push as importing and exits 0 (follow it with envs). Without --wait, push returns once the upload completes.

What it does: validates the definition, reads the image's config (platform, WORKDIR, ENV), saves the image from local Docker, adds Cofactor's sandbox helper (and the declared object storage server) plus a small layer with your definition, and uploads only the layers Cofactor doesn't already have for your organization. It prints how many blobs and bytes it sent and how much Cofactor already had. Docker must be installed and running.

Pushing to an application connected to GitHub fails: that application takes no pushed images. The first push to an application with no sandbox setting makes it a pushed-image application.

Exit status: non-zero if the push failed (with the reason, such as a service's log when the image could not start).

JSON output (the push, plus what was uploaded):

FieldMeaning
idThe push id, a version you can claim with --at.
statusuploading, importing, ready or failed. With --wait, ready or failed, or still importing if the 50-minute wait ran out.
tagsThe push's tags.
errorWhy it failed, or null.
createdAtWhen the push was created.
uploaded.blobsHow many blobs were uploaded.
uploaded.ofHow many blobs the image has in all.
uploaded.bytesBytes uploaded.
uploaded.reusedBytesBytes Cofactor already had.

See Sandboxes from a pushed image.

06envs

bash
cofactor sandbox envs --application <name|id> [--json]

The application's delivery (GitHub or pushed images), its current version, recent pushes, its sandbox environments, and what its definition offers at that version: every environment (description, seeds), actions, emulator operations (with their schemas), personas and ports. This is what an agent reads to decide which environment to claim and how to call each action.

An application with pushes but none ready yet shows no version and no definition.

JSON output:

FieldMeaning
applicationIdThe application's id.
deliverygithub or upload (pushed images).
repo, definitionDirThe connected repository and directory (GitHub), else null.
sandboxEnvironments[]The application's environments created from the definition: id, name (as shown in Cofactor) and environment (the definition's name).
pushes[]Pushed images only: the newest 10 pushes (id, status, tags, error, createdAt). null for GitHub.
versionThe current version: a commit SHA, or a push id. null before the first push is ready.
definition.environments[]name, description, extends (or null), seeds[] (id, action, input) and envKeys (the names its env: sets).
definition.actions[]slug, description, input, output and timeout, as declared.
definition.operations[]Emulator operations: name (<plugin>.<op>), description, inputSchema, outputSchema (JSON Schema).
definition.personasPersona names.
definition.ports[]name and access, the implicit emulation and object-storage ports included.
definition.emulationDeclared emulation plugin ids.

07claim

bash
cofactor sandbox claim --application <name|id> [--environment <name>] [--at <version>] [--wait] [--json]

Claims a sandbox: a fresh copy of the ready snapshot for the version and environment, given its own URLs and persona logins by prepare. If that snapshot doesn't exist yet, it is built first (build, prepare, seeds), once, however many claims are waiting on it.

FlagMeaning
--environmentThe environment to claim. Default: default.
--atThe version. GitHub: a full 40-character commit SHA. Pushed images: a push id or a tag. Default: for GitHub, the default branch's current ready snapshot of the environment (else its head); for pushes, the newest ready push.
--waitBlock until the sandbox is ready or failed (up to 30 minutes), then print it as show does. Without it, print the claim id and return.

Exit status: non-zero if the claim fails, or with --wait if the sandbox ends failed. A sandbox you stopped waiting for is still yours: show or destroy it.

JSON output: without --wait, { "id": "<sandbox id>" }. With --wait, the same object as show.

Destroy every sandbox you claim when you're done with it.

08show

bash
cofactor sandbox show <id> [--json]

A sandbox's current status, per-port URLs, persona logins (decrypted: this is where they are meant to be read from), seed outputs, how long it took to become ready, when it expires, and the actions and operations you can run on it.

JSON output:

FieldMeaning
id, applicationId, applicationNameThe sandbox and its application.
environmentThe environment it was claimed on.
versionThe commit SHA or push id it runs.
statusclaiming, ready, failed or destroyed.
errorWhy it failed (which step, its action, and the script's stderr), or null.
portUrlsPort name → URL.
personas[]name, email and password of each persona.
seedOutputsSeed step id → its output object. The same for every copy of a snapshot.
leaseExpiresAt, expiredWhen the sandbox's lease ends, and whether it already has.
readyMsMilliseconds from claim to ready.
phasessnapshotMs (waiting for the ready snapshot), restoreMs (restoring the copy), prepareMs (preparing it). Set once ready.
snapshotThe ready snapshot it's a copy of: builtAt, and buildPhases (buildMs, the build steps that ran with their times, prepareMs, and each seed step's id, action and ms). null once the snapshot is gone.
actions[], operations[]As in envs.

The output holds working passwords. Don't paste it anywhere public.

09run

bash
cofactor sandbox run <id> <action|plugin.op> [--input key=value]... [--json-input '{...}'] [--json]

Runs a definition action, or an emulator operation (named <plugin>.<op>, such as email.sent-emails), on a ready sandbox, waits for it, and prints its output.

FlagMeaning
--input key=valueOne input. Repeatable (also --input=key=value). The value is coerced to the declared type: integer and number must parse as numbers, boolean must be true or false, string and persona pass as written. An unknown key is an error that lists the known ones.
--json-input '{...}'The whole input as a JSON object. Overrides --input.

Invalid input (a missing required input, a wrong type, a value outside enum, an undeclared persona) prints the issues and the action's or operation's input schema, and runs nothing. The CLI waits for the action's timeout plus a minute.

Output: on success, the action's output object. On failure, the error and the script's stderr, with exit status 1.

JSON output (the run):

FieldMeaning
id, sandboxIdThe run and its sandbox.
actionThe action or operation name.
seedStepIdThe seed step this run was, or null for a call you made.
inputThe input, with sensitive values masked.
statusrunning, succeeded or failed.
outputThe result object, or null.
exitCodeThe script's exit code, or null.
stdoutTail, stderrTailThe end of the script's stdout and stderr.
errorWhy it failed, or null.
durationMs, createdAt, completedAtTiming.

See Seeds and actions.

10destroy

bash
cofactor sandbox destroy <id>

Tears the sandbox down. Always do this when a claimed sandbox is no longer needed. Prints Sandbox <id> destroying.

11verify-env

bash
cofactor sandbox verify-env --application <name|id> [--environment <name>] [--json]

For each environment of the current version (or only the one named): claim, wait for ready, print every seed step's output and the time it took, then destroy. Environments are verified one at a time. This is the end-to-end proof that an environment's seed chain actually runs, where validate only proves it's well-formed.

It ends with a summary table (Environment, Result, Seconds) and exits 1 if any environment failed. A sandbox that failed or timed out is still destroyed.

JSON output: progress goes to stderr; stdout carries an array of { environment, ok, seconds, error? }.

12preview

bash
cofactor sandbox preview --application <name|id> --pr <number> [--json]

A pull request's preview of a GitHub-delivered application: its status, commit, URLs, expiry, and the persona logins its pull request comment deliberately leaves out.

JSON output:

FieldMeaning
applicationId, prNumberThe application and pull request.
statusqueued, building, ready, failed or destroyed.
headShaThe pull request's head commit.
appliedShaThe commit the preview currently runs, or null. Differs from headSha while a newer push is building.
portUrlsPort name → URL.
personas[]name, email, password.
errorWhy the last update failed, or null.
readyMsHow long the last update took.
leaseExpiresAtWhen the preview's lease ends.

13guide v2

bash
cofactor sandbox guide v2 [topic] [--json]

Prints the built-in Sandboxes v2 guide: every topic, or just one. Topics: overview, definition, environments, seeds-and-actions, personas, env, emulation, object-storage, ports, upload, verify, cli. For pushed images, start with cofactor sandbox guide v2 upload. Plain cofactor sandbox guide prints the older Sandboxes (Beta) guide.

14API key scopes

With an API key, each command needs these sandbox scopes. Every command that takes --application also needs property:read: the CLI lists your applications to resolve it, even when you pass an id.

CommandScopes
validate, guide v2None (offline)
envs, show, previewsandbox:read
connectsandbox:edit
pushsandbox:read, sandbox:publish
claimsandbox:create; with --wait, also sandbox:read
runsandbox:read, sandbox:run
destroysandbox:delete
verify-envsandbox:read, sandbox:create, sandbox:delete

sandbox:read includes the sandboxes' persona logins.