evershell CLI
evershell is a single static binary that wraps the Evershell control plane
API for shell-friendly automation. Install it once, run
evershell login, and every verb thereafter reads credentials from
~/.config/evershell/credentials (or EVERSHELL_API_KEY + EVERSHELL_SLUG env
vars).
Install
Section titled “Install”Pre-built binaries for macOS, Linux, and Windows live at
downloads.evershell.ai. The latest/ path always serves the most
recent release — pick the archive that matches your machine,
extract, and put evershell on your $PATH:
# macOS (Apple Silicon)curl -L https://downloads.evershell.ai/evershell/latest/evershell_darwin_arm64.tar.gz | tar -xzsudo mv evershell /usr/local/bin/
# Linux (amd64)curl -L https://downloads.evershell.ai/evershell/latest/evershell_linux_amd64.tar.gz | tar -xzsudo mv evershell /usr/local/bin/
# Windows (amd64) — download the zip from the same URL pattern,# unzip, and put evershell.exe somewhere on %PATH%.Available platforms: macOS (darwin_amd64, darwin_arm64), Linux
(linux_amd64, linux_arm64), Windows (windows_amd64).
Pinning a specific version
Section titled “Pinning a specific version”The latest/ mirror always points at the newest release. To pin,
swap latest for an exact version (e.g. v0.2.0):
curl -L https://downloads.evershell.ai/evershell/v0.2.0/evershell_0.2.0_darwin_arm64.tar.gz | tar -xzEvery released version is listed in the manifest at
https://downloads.evershell.ai/evershell/versions.json:
{ "latest": "0.2.0", "versions": ["0.2.0", "0.1.0"]}A Homebrew tap is on the roadmap — once it ships you’ll be able to
brew install evershell. Until then, curl is the install path.
Verify the download
Section titled “Verify the download”Every release includes a checksums.txt listing SHA-256 hashes:
curl -L https://downloads.evershell.ai/evershell/latest/checksums.txtsha256sum -c checksums.txt --ignore-missingAuthenticate
Section titled “Authenticate”evershell login --slug=acme# Prompts for API key (issued from Settings → API keys in the console)
# Or pass the key directly via flag or stdin:evershell login --slug=acme --api-key sk_live_...echo "sk_live_..." | evershell login --slug=acme --api-key -The CLI verifies the credential against /v1/me/session before
persisting. Failed auth surfaces a friendly error instead of
writing a broken credentials file.
For CI / unattended environments, skip login entirely:
export EVERSHELL_SLUG=acmeexport EVERSHELL_API_KEY=sk_live_...evershell psEnv vars take precedence over the credentials file when both are set — handy for one-off overrides during testing.
Run evershell <verb> --help for the full flag list. Each verb below
declares the permission scope it needs; see the
permissions reference for what
each one gates and which scopes every default role holds.
evershell ps — list workspaces
Section titled “evershell ps — list workspaces”Permissions: workspace:read or workspace:read:own.
evershell ps # active workspacesevershell ps --include-archived # include archivedevershell ps --role analyst # filter to one agent role by nameevershell ps -o json | jq . # machine-readable--role <name> resolves the role server-side and 404s with
role_not_found if the name doesn’t match — silent empties would
hide typos. Each row shows the workspace’s role_id, not the
role’s name (workspace rows don’t carry either the name or the
display name).
evershell run — create a workspace and submit the first task
Section titled “evershell run — create a workspace and submit the first task”Permissions: (workspace:write or workspace:write:own) and
(tasks:write or tasks:write:own).
evershell run analyst "summarize Q3 revenue"# Workspace ws_01HZ created, task task_01HZ submitted.# Follow with: evershell logs ws_01HZOptional overrides:
evershell run analyst "..." \ --environment staging \ --thinking-effort high \ --max-continuations 10Scheduled invocations. evershell run is a regular CLI command —
schedule it from your OS’s scheduler (cron, launchd, systemd timers):
# nightly CVE triage at 03:00 local0 3 * * * /usr/local/bin/evershell run secops "triage today's CVE feed"
# every Monday morning — weekly metrics writeup0 8 * * 1 /usr/local/bin/evershell run analyst "compile last week's metrics"evershell logs — tail a workspace’s activity stream
Section titled “evershell logs — tail a workspace’s activity stream”Permissions: workspace:read or workspace:read:own.
evershell logs ws_01HZ # follow (default — SSE stream)evershell logs ws_01HZ --no-follow # print history once and exitevershell logs ws_01HZ -o json # JSON-per-event for piping to jqHistory mode supports the same paging flags as evershell audit. Passing
any of them auto-implies --no-follow (paging only applies to the
history endpoint, not to the live SSE stream):
# Single page, capped at 100 by defaultevershell logs ws_01HZ --limit 500
# Auto-paginate the full activity historyevershell logs ws_01HZ --all -o json | jq '.events | length'
# Resume from where a previous page left offevershell logs ws_01HZ --cursor "2026-05-23T12:34:56.789Z|01HZABCD..."
# Reverse chronology (default is asc — chronological)evershell logs ws_01HZ --order desc --limit 50evershell stop — stop a workspace
Section titled “evershell stop — stop a workspace”Permissions: workspace:write or workspace:write:own.
evershell stop ws_01HZ# Workspace ws_01HZ: stopped.State is snapshotted before pod tear-down — resume later via the
console or by submitting a new task. Stopping an already-stopped
workspace returns 409 workspace_already_stopped; guard your
callers if you want a no-op on repeat invocations.
evershell audit — query the audit log
Section titled “evershell audit — query the audit log”Permissions: audit:read or audit:read:own. With
--workspace, additionally requires workspace:read or
workspace:read:own (creator-match) on the target workspace.
Filters compose AND across columns. Each --filter value supports
equality (col=val), IN (col=v1,v2), not-equal (col!=val), and
“column populated” (col!=).
# Every deny in the last hourevershell audit --filter event_type=policy_decision --filter decision=deny \ --from "$(date -u -d '1 hour ago' +%FT%TZ)"
# A bounded windowevershell audit --from 2026-05-01T00:00:00Z --to 2026-05-02T00:00:00Z
# Pipe to jq for richer queryingevershell audit -o json --filter category=audit | jq '.events[].event_type' | sort | uniq -c
# Auto-paginate through every result page (no manual cursor passing).# JSON output still wraps in `{events, cursor}` so the same jq selector# works whether you pass --all or not.evershell audit -o json --all --filter category=audit | jq '.events | length'
# Workspace-scoped — every actor's events on this workspace, not just# yours. The user-id narrowing that bare `evershell audit` applies for# audit:read:own callers is skipped on this route, so a Member who# owns the workspace (or holds workspace:read) sees every event that# affected it.evershell audit --workspace ws_01HZ --allResults larger than one page (--limit, default 100) come back with
a cursor field — pass it back as --cursor <value> for the next
page, or --all to auto-paginate from the start.
--workspace <id> routes to /v1/workspaces/{id}/audit instead of
/v1/audit. The two endpoints share filter columns, paging, and
response shape; they differ in scoping. Bare evershell audit is the
org-wide view, narrowed by user_id for audit:read:own callers.
evershell audit --workspace <id> is the workspace view — no user_id
narrowing, so a Member investigating their own workspace sees the
same row set an Owner would.
See Audit events for the full event-type catalog and filter column whitelist.
evershell files — inspect / extract workspace files
Section titled “evershell files — inspect / extract workspace files”Permissions: workspace:read or workspace:read:own.
evershell files ls ws_01HZ # every entry in the sandbox tree
evershell files cat ws_01HZ /logs/run.log# Truncated at 512 KB by default — for big files use get, or# raise the cap inline:evershell files cat ws_01HZ /logs/run.log --max-bytes 2097152# Binary files print a "use evershell files get" hint to stderr# instead of dumping bytes that would clobber the terminal.
evershell files get ws_01HZ /reports/q3.csv ./local.csv# Wrote 14823 bytes to ./local.csv
# Local path is optional — defaults to the remote basename in CWD:evershell files get ws_01HZ /reports/q3.csv# Wrote 14823 bytes to ./q3.csv
# Pass `-` as the local path to stream stdout (binary-safe, uncapped):evershell files get ws_01HZ /artifacts/build.tar.gz - | tar -xz
# Read from a stopped workspace's snapshot instead of live sandbox:evershell files ls ws_01HZ --from snapshotevershell files get ws_01HZ /artifacts/build.tar.gz . --from snapshotevershell files cat truncates at 512 KB by default (override with
--max-bytes <N>) and is text-friendly: binary files print a hint
to stderr rather than dumping raw bytes. evershell files get streams
without a size cap and is safe for binaries. The --from snapshot
flag works on all three sub-commands and reads from the
stopped-workspace snapshot instead of the live sandbox.
evershell caps validate / evershell caps compile
Section titled “evershell caps validate / evershell caps compile”Permissions: none — runs locally, no network or auth.
Local validation of caps.yaml against the same parser the control
plane uses at agent-role create time. Runs in CI / pre-commit hooks.
evershell caps validate ./caps.yaml# caps.yaml: OK (3 capabilities)
evershell caps validate ./caps.yaml --strict# Upgrade warnings to errors. Exit 2 on either errors or warnings.
evershell caps compile ./caps.yaml > policy.rego# Print the OPA Rego the proxy would enforce.Both verbs accept - for stdin so cat caps.yaml | evershell caps validate -
works in piped flows.
evershell version / evershell upgrade — self-update
Section titled “evershell version / evershell upgrade — self-update”Permissions: none — talks to the public release bucket, not the control plane.
evershell version # current version + platform; "vX available" hintevershell version --no-check # skip the manifest fetch (offline / CI)
evershell upgrade # download + verify + atomically replaceevershell upgrade --check # print the upgrade plan; don't touch diskevershell upgrade --to 0.2.0 # pin to a specific version (rollback)evershell upgrade walks the same pipeline curl | tar -xz does
manually: fetches the release manifest, verifies the archive’s
SHA-256 against the published checksums.txt, extracts the
binary, and atomically replaces the running executable.
Self-upgrade is POSIX-only — on Windows the command refuses with
a “download manually” message that includes the right URL.
Permission errors on the install directory (e.g. /usr/local/bin
owned by root) print a sudo hint.
Set EVERSHELL_UPGRADE_URL to point the upgrader at a staging bucket
or air-gapped mirror; default is https://downloads.evershell.ai/evershell.
After any successful command, evershell prints a one-line
(evershell vX available — run evershell upgrade to install.) hint to
stderr when a newer release is out. The check is rate-limited to
one network round-trip per 24h (cached in
~/.config/evershell/update-check.json) and silently skipped when:
EVERSHELL_NO_UPDATE_CHECK=1is set--output jsonis in effect (avoids polluting machine-readable pipelines)- The running binary is a dev build
- The command was
evershell versionorevershell upgrade(already redundant) - The manifest fetch fails (errors swallowed — a flaky network must never fail your command)
Homebrew installs are detected — if the resolved binary lives
inside a Cellar/ path, evershell upgrade refuses with a redirect
to brew upgrade evershell so brew’s package tracking stays
consistent.
evershell orgs — list / switch between organizations
Section titled “evershell orgs — list / switch between organizations”Permissions: any signed-in caller (reads from /v1/me/session).
evershell orgs list# SLUG ORG NAME ROLE BILLING# * acme Acme Corp owner active# contoso Contoso member active
evershell orgs switch contoso# Switched to contoso. Credentials updated at ~/.config/evershell/credentials.Note: API keys are org-scoped — switching slugs only works if the
saved key was minted for the destination org. Most workflows call
evershell login against each org separately instead.
Configuration
Section titled “Configuration”| Env var | Effect |
|---|---|
EVERSHELL_SLUG | Tenant subdomain. Wins over the saved file. |
EVERSHELL_API_KEY | API key. Wins over the saved file. |
EVERSHELL_API_URL | Full base URL override. Skips slug → DNS resolution. Useful for pointing the CLI at a non-default endpoint (custom domain, internal mirror). |
EVERSHELL_UPGRADE_URL | Override the release bucket evershell upgrade pulls from. Default https://downloads.evershell.ai/evershell. |
EVERSHELL_NO_UPDATE_CHECK | When set to 1, suppresses the manifest fetch on evershell version. |
The credentials file is plain JSON at
~/.config/evershell/credentials with mode 0600. (Honors
XDG_CONFIG_HOME if you’ve set the XDG Base Directory env var.)
Exit codes
Section titled “Exit codes”Conventions match common lint tools (eslint, ruff, shellcheck):
| Code | Meaning |
|---|---|
0 | Success |
1 | Command failed — network error, server-side error, missing arg, or caps validate found warnings (no errors) |
2 | caps validate found errors (or warnings with --strict) |
Exit 2 is reserved for caps validate; every other verb maps
failures to exit 1 via Cobra’s default error handling.
Output goes to stdout in table form by default; pipe-friendly
JSON via -o json. Errors and progress hints go to stderr.