Aient CLI
Theaient command runs local development work in isolated remote sandboxes. The current release is available as a static binary for macOS and Linux on Intel and Arm.
Current release: 0.11.10
Authentication and projects
Keep separate customer sessions and bind each checkout to the intended Aient profile.
Run and synchronize
Run a local Git worktree remotely or synchronize its exact state into a retained sandbox.
Retained sandboxes
Create, inspect, reuse, enter, and delete sandboxes.
Executions and files
Observe live commands and transfer explicit files.
Install and verify
Download the current release from the Aient CLI release repository. Follow the repository’s installation and verification guide before placing the binary on yourPATH.
Each release includes static archives, SHA-256 checksums, SPDX SBOMs, Sigstore verification bundles, and SLSA provenance. GitHub-generated source archives are documentation only; they are not verified Aient CLI release artifacts.
Customer Agent conversations
From a configured project, select the refresh-backed customer OAuth profile explicitly withaient --profile NAME agent .... Ambient project access is sandbox-scoped and intentionally does not grant Agent conversation authority.
Find a reconnectable Agent Thread or attach to one:
agent list accepts an exact Thread ID or title query plus explicit status, archive, page-size, and cursor filters. Its human continuation command preserves the active filters; --json emits one versioned page. List, status, and events require aient.agent.read; messages, answers, explicit cancellation, and chat mutations require aient.agent.write. status --json emits one deterministic document. events --follow --json emits JSONL and can resume after a durable sequence. Stable Thread, task, message, interaction, operation, sandbox, and execution identifiers preserve the reconnect path after terminal or network loss.
--immediate requires one explicit stable operation UUID; an ordinary message may omit it and let the CLI generate one. Reuse an explicit UUID only for an exact retry. Exact text and delivery mode return duplicate; changed text or mode returns operation_conflict. Immediate delivery never cancels or replaces the active task or changes its tool scope. The receipt reports steered, started, queued, or duplicate; incompatible active-task origin or attachment plans fail with cooperative_steering_scope_mismatch.
Inside agent chat, enter ! COMMAND to run a supervised shell command in the environment and sandbox frozen from the latest rendered Agent status. The CLI shows the target and preallocated execution UUID before output, passes no workstation process environment or local repository inference, and sends no Agent message. Reconnect by passing the exact EXECUTION identifier to the execution commands above. Ctrl-C in ordinary chat detaches without cancelling Agent work; Ctrl-C in the active remote-command view explicitly requests cancellation of that exact execution. This release requires an existing THREAD; it does not start a new Agent Thread.
The standard aient-agent catalog uses the V3 workspace writer. The retained aient-pr-e2e catalog remains the V2 rollback control. The server keeps the closed V2 and V3 readers and negotiates capabilities per template; the CLI does not infer one global workspace layout version.
From a configured Aient Git project on macOS, login establishes bounded project access by default. The refresh credential stays in Keychain while launchd rotates only a short-lived repository-private envelope for up to 90 days. Login returns only after manager-owned renewal is verified. No foreground terminal or PID owns renewal. New installations persist the directory birth time so an APFS device-number change across a remount does not invalidate the same protected project. A legacy installation whose APFS device already changed still fails closed once; if the host profile is healthy, aient --profile NAME auth export --store-in-project replaces it without another login. Linux managed renewal remains preview pending a real systemd-user and D-Bus Secret Service renewal, restart, and logout canary. Use --project-access=none for host-only login, managed-project opt-out, or to avoid the Linux preview.
Quick start
From a local Git checkout:--environment, the CLI synchronizes the current workspace by default. It shows the organisation, resolved environment, inferred or selected repository, and brokered GitHub capabilities before creating the sandbox.
Use --size small|medium|large to request a product-owned compute class, or omit it to use the environment default. The server owns the underlying template and resource envelope.
Every customer-development create advertises developmentSizeBindingVersion: v2. A compatible product response binds exact aientSizeBinding=v2, aientSizeClass, aientSizeSource=requested|environment-default, and aientSizeEnvelope=v1|v2 selectors into the signed request target. Partial, duplicated, unknown, crossed, or mismatched bindings fail before the control-plane request. Legacy explicit V1 and an old server’s unbound environment default remain supported during rollout. This size-binding reader does not choose the workspace writer; the standard aient-agent catalog uses V3 independently.
An organisation administrator must enable customer CLI workspaces for the selected environment. If it is disabled, the command fails before sandbox creation with
HTTP 403: development environment is not enabled for CLI workloads.Choose a workflow
Usesandbox run for a disposable command:
--keep when you want to retain the created sandbox:
sandbox run --json and sandbox exec --json emit execution_started with executionId and outputCursor after publishing the cursor-0 local pointer. This identifies the admission attempt for reconnect; it does not prove that the server admitted or started the command. The validated server admission frame remains authoritative.
sandbox execution attach SANDBOX EXECUTION --after-cursor CURSOR replays supervisor-retained output after the caller’s last accepted cursor, then follows live output. The cursor advances only after a complete frame is presented, so reconnect may repeat one frame but cannot create an output gap.
--timing-json emits one content-free JSON line on stderr without changing command output or exit status. It records process-relative preflight, create-ready, proven workspace activation, first output, truthful terminal status, downloads, and confirmed cleanup or retention. Same-execution recovery never dispatches a replacement command, and a timing-writer failure cannot mask the command result.
Automatic disposable cleanup performs exactly one DELETE with the full configured --timeout, then a fresh equally bounded GET-only absence check. Ambiguous deletion is not retried. A failed lease restore keeps the primary error authoritative and reports retained=true with cleanupConfirmed=false; genuine lease-refresh failures still warn and retry while an active heartbeat continues.
A foreground CLI reconnects the same execution during a bounded grace. If it must leave a potentially live execution, it retains the sandbox and prints the exact attach command. Cross-process reattachment is explicit; an ordinary new run always starts a fresh execution.
Use a named retained sandbox when you want follow-up lifecycle reads and supervised execution:
--environment. Without the matching selectors, the owner-only client deliberately cannot see the bound sandbox.
To select ignored and untracked non-Git paths broadly, omit regular AppleDouble sidecars, and subtract explicit exclusions:
.git metadata. Regular macOS AppleDouble ._* files are omitted from broad non-Git selection before archive, manifest, byte-count, or digest construction; the local source remains unchanged. There are no implicit cache or secret exclusions, so review the selected scope and explicitly exclude .env files, credentials, tokens, private keys, and other secret-bearing non-Git paths.
To replace an exact generated remote directory without changing its local contents:
--reset-remote-dir is repeatable explicit authority. It publishes an ordinary empty candidate-owned directory through atomic activation so build cleanup can remove or recreate it. On legacy servers, other ignored remote state keeps its existing preservation behavior. When explicit repository path ownership is advertised, unselected non-Git paths are absent unless named by --preserve-remote-dir. Reset paths must be exact repository-relative non-Git directories and cannot be combined with --exclude.
In that negotiated mode, unselected generated, dependency, and cache directories are absent from a new candidate instead of becoming inferred preservation mount roots. Package tooling can remove and recreate them normally.
To retain an exact ordinary remote directory across synchronization:
--preserve-remote-dir is repeatable explicit authority. Preservation roots must be exact repository-relative non-Git directories and cannot overlap Git content, selected uploads, reset paths, symlinks, files, or one another. A server without explicit path-ownership support rejects preservation instead of silently changing its meaning.
For a deliberately incomplete parent-only checkout when submodules are initialized locally:
--submodules=gitlinks recursively verifies every initialized child is clean, untracked-free, and checked out at the exact parent-index object before any remote request. It omits child bytes and binds the complete sorted parent-index Gitlink set into manifest-backed activation. This is an incomplete Gitlink-only workspace, not recursive submodule transfer; commands that need child files must initialize them separately.
To transfer only exact nested repositories consumed by the remote command:
--submodule for every selected ancestor; selection never expands recursively. Initialized but unselected children contribute no bytes and remain empty Gitlink boundaries remotely. Selected submodules may be combined with declared parent-repository extras; the server verifies every declared path and atomic exchange before activation. Capability preflight recognizes the exact old helper generation mounted by an already-running sandbox. A reader without exact selected-submodule support rejects the operation rather than weakening the policy.
Default snapshots keep raw uninitialized Gitlink index paths exact without applying explicit-manifest UTF-8, backslash, or entry-count limits. Those snapshots emit no Gitlink manifest. Explicit --submodules=gitlinks remains fail-closed and applies the portability rules plus the 512-entry bound before any remote request.
Retained workspace-operation storage
Interrupted V2/V3 publication retains exact local evidence under~/.aient/workspace-operations. Inspect and recover it with:
workspace list is local and makes no authentication or network request. It reports valid operations, logical usage, the capacity boundary, unsafe residue, and copyable recovery commands. New whole-bundle publication fails before upload when the retained total would exceed 10 GiB, less than 1 GiB of filesystem space would remain after copying, or inventory is unsafe or incomplete. There is no count limit, no configuration override, and the CLI does not evict retained operations automatically. Existing receipts remain listable, resumable, and discardable, including when the store is already over limit.
Automatic cross-process preparation matching lets a repeated ordinary sync or workspace-backed run resume the exact retained operation when its source generations and authenticated authority still match. Unsupported development targets announce the explicit workspace-resume fallback before capture.
This boundary does not change broad non-Git selection or temporary staging. Continue to use precise --include and --exclude rules; selector and temporary-staging bloat remain separate work.
Environment secrets
Organisation owners and administrators can replace an encrypted environment secret after consenting to the dedicated write capability:Runtime service mappings
Inspect discovered runtime services and repository paths, or classify one service explicitly:services apply is dry-run by default. These commands require the services:read and services:manage OAuth scopes; existing sandbox access remains valid, while an older profile may need one interactive login before service management.
Current release boundary
The commands documented in this section are the surface shipped in Aient CLI 0.11.10.-
Environment-bound
status,wait, andlogsresolve the repeated environment selector through the authenticated profile. -
Exclude-only workspace selection starts from the broad eligible non-Git inventory, keeps Git state authoritative, omits regular macOS AppleDouble
._*files by default, and applies only caller-supplied exclusions beyond that documented filter. -
Exact
--reset-remote-dirselection replaces a named remote non-Git directory with an ordinary empty candidate-owned directory without modifying the local source or weakening atomic activation. - Unselected non-Git paths are absent under explicit repository path ownership, so generated and cache directories remain ordinary removable directories instead of inferred bind-mount roots.
-
Repeatable
--preserve-remote-dirretains only exact declared ordinary remote directories; collision and size checks fail locally before upload, and unsupported servers reject explicit preservation. -
Explicit
--submodules=gitlinksomits clean exact child checkouts only after recursive local verification and binds the complete parent-index Gitlink boundary into V2 or V3 activation; it does not transfer submodule content. - Default snapshots preserve raw uninitialized Gitlink index entries without applying constraints that belong only to the explicit Gitlink manifest; explicit mode continues to require UTF-8 portable paths, reject literal backslashes, and enforce the 512-entry bound.
-
sandbox workspace list [--json]reports retained local operation evidence without authentication or network access. New publication is bounded by 10 GiB aggregate logical bytes plus a fixed 1 GiB post-copy filesystem reserve, with no count limit, configuration override, or automatic eviction. - Idle and timeout cleanup acts only on the exact sandbox revision it evaluated. This protects an accepted concurrent refresh without renewing or extending the operation lease or server-owned hard expiry.
-
Customer create and run support the
small,medium, andlargeproduct-owned compute classes. -
Customer-development create advertises
developmentSizeBindingVersion: v2and accepts only a complete exactaientSizeBinding=v2,aientSizeClass,aientSizeSource=requested|environment-default, andaientSizeEnvelope=v1|v2binding. Invalid combinations fail before the control-plane request; legacy explicit V1 and an old server’s unbound default remain rollout-only compatibility paths. -
A conditional one-use
repository-prewarmpath handles an exact-clean same-HEAD workspace at the default repository root. A matching Ready member sends zero committed Git bytes and skips sandbox creation, MinIO reads, and workspace materialization; typed no-ready continues the same immutable capture cold, while an ambiguous claim stops without duplicate work. Dirty overlays, selected repositories, custom roots, explicit names, and other ineligible requests stay on the existing path. Ready-member supply is operator-bounded and not promised for every command. -
Immutable capture overlaps remote preflight while an exact retained operation keeps precedence. Compact JSON cache phases remain one object per physical line, and
--timing-jsonreportsgitCache.outcome=repository_prewarmwith zero client bytes on a hit. - A stale derived commit-graph that references only pruned unreachable objects does not block capture. Refs and reachable objects remain authoritative, the CLI does not rewrite user Git metadata, and a genuinely missing reachable object still fails before upload.
-
Named sandbox creation is replay-safe under bounded ambiguous-transport retries: one public name keeps one idempotency identity, matching fingerprinted settings adopt the accepted sandbox, changed fingerprinted settings conflict, and
sandbox runnever executes in or deletes a sandbox whose returned identity is unproven. - Organisation selection is bound to one canonical lowercase UUID. The CLI resolves the authenticated display name and canonical organisation UUID for human-readable status and trusted legacy-project migration guidance; the display name is render-only, and every present authenticated identity source must agree before the requested operation.
-
Environment-bound sandbox commands carry one authenticated organisation/environment/repository tuple across create, synchronization, files, execution, observation, lease refresh, and deletion. New customer workspace operations retain that tuple in
workspace-operation-bundle-v2and resume with the exact authority instead of weakening to owner-only access; legacy V1 receipts keep their established compatibility behavior. -
The conservative supervised execution timeout ceiling is
23h56m18s. Largersandbox execcommand budgets fail locally before a sandbox request and at server admission before claim creation or provider dispatch withsandbox_execution_timeout_invalid; a valid budget can still conflict with the remaining hard lease of an older retained sandbox. -
aient auth exec --profile NAME -- COMMAND...gives a trusted same-UID host wrapper one renewable access-only credential while injecting or copying no refresh, profile, operator, or imported portable authority. It is credential minimization, not a local process sandbox; untrusted same-UID descendants require external confinement. -
From a configured project,
aient auth logininstalls bounded manager-owned project access by default. Refresh authority remains in the OS credential store; ordinary repository commands discover only the rotating short-lived envelope with no profile/token flags, foreground exporter, or PID tracking. -
Explicit
--submodules=selectedtransfers only the named clean exact Gitlink dependency closure; unselected initialized children contribute no bytes and remain empty boundaries. - Selected submodules may be combined with declared parent-repository extras. The server verifies their exact receipts and capability preflight recognizes the mounted old helper generation for generation-bound resume.
-
sandbox runuses supervised execution and allocates one fresh execution per ordinary CLI process.--jsonemitsexecution_startedwithexecutionIdandoutputCursorbefore command output; same-process recovery and explicit--after-cursorattach replay retained output after the last accepted cursor and never redispatch the command. -
sandbox run --timing-jsonwrites one content-free stderr receipt for proven workspace activation through cleanup or retention without changing command output or exit status. -
Automatic cleanup issues exactly one DELETE with the full configured
--timeout; ambiguous deletion remains an error, and genuine lease-refresh failures still warn and retry. -
aient services list|paths|classify|applymanages explicit runtime-service repository mappings. Batch apply is dry-run by default and uses the dedicatedservices:readandservices:manageOAuth scopes. - Owner/admin environment-secret writes are encrypted, capability-gated, and write-only from the CLI.
-
Synchronization to
/workspace/reponegotiates V3 immutable-candidate activation when an exact attested server advertises the closed V3 capability; it retains typed V2 on V2 servers and compatible V1 on older servers. V3 selection rejects unknown, duplicate, mixed, or invalid capability evidence before upload and never falls back after selection. - Workspace synchronization publishes complete, self-contained parent-repository Git history. Shallow, promisor, alternate-backed, grafted, or replace-influenced local sources fail before upload; incompatible sandbox helpers fail before probe or mutation instead of selecting a shallow fallback.
-
V2 workspace activation returns success only after the exact activated revision is certified under the same exclusive workspace-operation fence. If the result is lost after commit,
sandbox workspace resumeresumes the same immutable operation and revision; it does not rebuild the candidate or replay the requested command. Separately, genuine cross-writer fence contention can still return typedworkspace_layout_certification_busy; workspace-backedsandbox runretries only that exact pre-dispatch response for up to 10 seconds, honorsRetry-After, and never replays a user command. -
aient agent list|status|events|message|respond|cancel|chatfinds or attaches to an existing Agent Thread through the public API. It does not start a new Agent Thread. -
agent events --follow --jsonemits JSONL after durable sequence replay; Ctrl-C detaches ordinary chat without remote cancellation. -
! COMMANDin Agent chat runs only in the frozen reported sandbox through supervised execution. Reconnect withagent execution status|attach|wait|cancel; no local shell, caller environment, repository inference, or Agent message is added. - Supervisor-retained output is cursor-replayable. Cursor acceptance is frame-atomic, so reconnect may repeat the last complete frame but cannot create a gap; retention remains bounded rather than permanent command history.
-
sandbox shellalways opens a new shell. Shell reattachment and shell history are unavailable. - Public port exposure is not yet available.
- CPU and memory override flags and the Docker lifecycle helper are operator controls, not customer sizing features.