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.30
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.
Sync selected files into an Agent checkout
--path for 1–128 existing regular files, each at most 64 KiB. This one-shot command targets the Agent’s current primary checkout on a compatible runtime; unsupported runtimes and another repository are rejected. Selection follows Git/extras policy; --include explicitly allows ignored source. Git control files, .aient, active credentials, symlinks and submodules are rejected.
Each write atomically replaces an existing single-link regular destination, preserving its mode; remote parents must already exist. Whole-file updates use last completed write wins, while the model’s line-hash edit checks remain in force. Agent ownership, incarnation and lease remain unchanged; Git metadata is not synchronized.
JSON separates confirmed writes from notification. Exact path, byte count, SHA-256 acknowledgement and terminal exit zero confirm each write. After the batch succeeds, a cooperative path-change notice asks the Agent to reread. Delivery does not prove a model read or application reload. Failed or ambiguous writes send no success notice; earlier confirmed writes remain applied. If notification alone fails, retry only agent message with the returned exact text, operation ID and --immediate.
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 never silently skips output. While a client is connected, the command runs at the client’s pace. If a reconnect resumes after output the server no longer retains, stdout keeps only the bytes received before the gap, the retained tail goes to stderr between an aient: output incomplete: bytes FROM-TO lost; ... header that names the command’s own exit status and an aient: output incomplete: end of retained tail line, and the exit status is 74. --json reports the gap as an execution_output_gap event and also exits 74.
--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.
exec --workspace PATH accepts ordinary sync source flags and runs in the synchronized directory unless --workdir is explicit. A failed sync never starts the command; sandbox workspace resume resumes publication only, never execution. The sandbox keeps its existing owner and retention policy; sync may renew its lease. This command neither creates nor releases it. --detach waits for sync and execution acceptance. For this combined command, --timing-json reports synchronization only, not command execution or output latency.
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.
Experimental selected-file live sync
Select existing local regular source files in an already running sandbox, publish them once, then watch ordinary local saves. Pass the actual remote worktree explicitly:--live-path for 1–128 exact repository-relative files, each at most 32 MiB.
The initial upload overwrites those selected files: choose files whose overwrite
is intended. The ordinary tracked Git and non-Git include/exclude policy applies;
Git control paths, credentials, symlink sources and submodules are rejected.
Parent directory watches support ordinary editor atomic saves; identical captured
content is skipped. The sandbox keeps running when the watcher ends.
--live-stream requires a compatible attested native V3 workspace, existing
remote parent directories and normal customer shell permission. It sends captured
bytes over one authenticated terminal WebSocket. Each file replaces atomically;
the exact sequence, byte count and SHA-256 acknowledgement proves individual file
delivery. Setup and helper READY are measured separately from per-file delivery.
The session holds a shared workspace fence, blocking ordinary full sync and
exclusive files API writes. Ctrl-C requests helper STOP and waits for terminal
command completion. Missing proof prints termination UNVERIFIED: the helper and
fence may remain active and keep blocking those writes. The reported session/PID
is diagnostic metadata, not authority to kill a process. Restarting a watcher
does not recover an unverified session and overwrites the selected files again.
Use the separate experimental --live mode instead of --live-stream to upload
selected files through the files API. It requires an attested existing workspace
and normal files permission, and reads the workspace binding for each save batch.
Its diagnostics distinguish binding reads and upload duration. The files transport
remains the default. A long-running app on a compatible runtime holds a shared workspace fence,
which can block those exclusive binding reads and uploads.
For a compatible customer workspace bound to its original allocation, opt into
finite supervised execution for each selected file:
write UNCONFIRMED, stops the watcher
without retry, and means remote bytes may have changed; reconcile selected files
before restarting. Each command is bounded to 30 seconds, and sandbox hard expiry
still applies. Diagnostics measure save detection through confirmed ACK;
application visibility must be measured separately.
Both live modes require explicit --remote-dir and --live-path; choose only one
mode. --live-transport requires --live.
Both modes perform no snapshot activation, application restart or Git metadata
synchronization. Deletions, renames, new unselected files, mode changes, concurrent
edit protection, submodules, overflow/reconnect recovery and multi-file consistency
are unsupported. Errors stop the watcher. Delivery does not prove application
readiness or browser HMR, and there is no universal subsecond latency guarantee.
Existing finite sandbox leases and hard expiry apply.
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. For eligible native V3 Git-cache transfers in 0.11.22, recovery preserves the original captured files even after later local edits. See workspace recovery for the allocation and compatibility limits. 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.30.-
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. -
Terminal
agent execution status|wait|canceloutput failure preserves the local selector for a fresh authorized status read of the same execution; successful terminal delivery still retires it.waitpreserves a nonzero exit even if local retirement fails. Recovery requires surviving server evidence and current authorization, not permanent execution history. - 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. -
Selected-file
sandbox sync --live|--live-streamis experimental. Native V3--live-streamrequires normal customer shell permission and holds a shared workspace fence. Aftertermination UNVERIFIED, the helper/fence may remain active and block full sync or exclusive files API writes; starting another watcher does not recover it. Neither mode provides conflict protection, deletion/rename propagation, multi-file consistency or reconnect recovery. File ACKs do not establish application readiness, browser HMR or universal subsecond latency. -
aient sandbox port SANDBOX PORTpublishes a public HTTPS capability URL on a configured native deployment;aient sandbox port SANDBOX --revokeremoves the binding. Anyone with the URL can access the application. The binding follows the remaining lease and exact incarnation, without another retention owner. Server-side preview routing, certificates, DNS, and exposure policy must be configured; installing the CLI does not establish availability. Agent-owned previews, raw TCP forwarding, and local-resource forwarding are not promised. -
Customer create and run accept
--cpuand--memoryrequests within the selected size’s server-owned limits. Custom requests select the native agent-sandbox provider and bypass preset warm claims; GPU requests remain unsupported. Resource limits and templates remain operator controls.