Drive the Ellipsis cloud from your terminal: start agent sessions, stream their output live, manage configurations, and open a session in the browser IDE.
This is a thin client. The agent runs in the Ellipsis cloud; the CLI authenticates, opens a WebSocket, and streams results. It is open source (MIT), and the proprietary engine stays server-side.
brew install ellipsis-dev/cli/agentskills/ellipsis is an
Agent Skill that teaches any coding agent (Claude
Code, Cursor, Codex, and others) what the Ellipsis platform is and how to
drive it with this CLI:
npx skills add ellipsis-dev/cliOr copy skills/ellipsis/ into your agent's skills directory
(~/.claude/skills/ for Claude Code). Ellipsis agents can load it straight
from their config, no clone required:
skills:
- path: skills/ellipsis
repository:
owner: ellipsis-dev
name: cliagent install # open the dashboard sign-in page, where you install Ellipsis
agent login # device-code auth against the active host
agent logout # remove stored credentials (--all for every host)
agent me # show the current credential's identity
agent host list # list configured hosts (the active one is marked *)
agent host add beta https://beta-api.ellipsis.dev # add a host and switch to it
agent host use prod # switch the active host
agent host current # show the active host and how it resolves
agent host set beta --rename staging # rename / re-point a host (--api-base / --app-base)
agent host delete beta # remove a host and its stored token
agent session start --config <id> # start a session from a saved config
agent session start --config-file f.json # ...or from an inline config
agent session start --template ellipsis-helper # ...or from a maintained template
agent session start --config <id> --config-override "budget:\n session: 5" # override config fields for this session
agent session start --config <id> --watch # start and immediately stream it
agent session list --limit 20 # list recent sessions (filter by --source, --author, --since, …)
agent session search "webhook retries" # search session history: transcripts, recaps, created PRs, similarity
agent session search "acme/api#512" --author tony --since "3 days ago" # PR-shaped queries and facets
agent session get <session-id> # inspect one session (prints a dashboard link)
agent session get <session-id> --watch # follow a session until it finishes
agent session record <session-id> # read a session's stored transcript, one line per record
agent session connect <session-id> # connect to a session: transcript + live output + send messages
agent session connect # inside an Ellipsis sandbox: connects to the running session
agent session stop <session-id> # stop an in-flight session
agent review 123 # review a pull request now, instead of waiting for a push
agent review get <review-id> # a review's findings, scope, and whether it posted
agent review list --repo api # list a repository's reviews, newest first
agent review init # scaffold a starter review pipeline (code_review.yaml)
agent config list # list saved agent configs
agent config get <config-id> # show one config as YAML (--json for JSON)
agent config init [path] # scaffold a starter config (default: agents/my_agent.yaml)
agent config create --repo api --file agents/foo.yaml # create an agent via a pull request (or --template <slug>)
agent config default # the effective default agent for the repo you are standing in
agent config default set <config-id> # set the account default agent (--repo [owner/name] for one repo)
agent config default clear # clear the account default (--repo [owner/name] for one repo)
agent model list # list selectable agent models (the account default is marked)
agent integration # every connected integration in one table
agent github repos # repositories connected to the GitHub installation
agent github members # org roster (the logins/ids --author accepts), with linked Slack identities
agent slack channels # channels in the connected Slack workspace
agent slack members # workspace members, with linked GitHub identities
agent linear teams # teams in the connected Linear organization
agent sentry orgs # connected Sentry organizations
agent file upload shot.png # store a PNG; prints an org-gated link to paste into a PR comment
agent file list # list stored files (--session <id> scopes to one run's uploads)
agent file get <file-id> -o shot.png # show one file, or download its bytes with -o
agent file delete <file-id> # delete a file (it disappears from list/get and its link stops resolving)
agent variable list # list sandbox env variable names (values are write-only)
agent variable set A=1 B=2 # create/update variables (or --from-file .env/.json)
agent variable delete K # delete a variable
agent budget # current budget summary
agent usage # usage dashboard for the period
agent analytics reviewer --account-type bot # which apps review the most PRs
agent analytics pr --days 30 # PR volume/trend with human vs bot splits
agent analytics review --repo my-service # review totals + top reviewers
agent ping # check authenticated API connectivityEvery command shown is singular. The plural spelling of each (agent files,
agent sessions, agent analytics prs) is a hidden alias that works but is
left out of --help. See
skills/cli-conventions for the full
argument, flag, and help-text conventions.
Most commands accept --json to print the raw API response. The CLI talks to
the public REST API. Point it at a different instance durably with
agent host (below), or per-invocation with ELLIPSIS_API_BASE_URL (or the
legacy ELLIPSIS_API_BASE).
--watch (on both session start and session get) streams the session's
output live over WebSocket until it reaches a terminal status, falling back to
periodic status polling if the live stream is unavailable. Either way it first
prints a clickable dashboard link. The stream protocol is specified in
docs/RUN_STREAMING_SPEC.md.
agent login uses the device-code flow: it requests a code pair, prints a
verification URL (and opens it unless --no-browser), and polls until you
approve the request in the dashboard. The issued user token is stored under
~/.ellipsis/config.json (mode 0600) and attributes sessions to you.
Credentials resolve in this order (highest wins): explicit argument →
environment (ELLIPSIS_API_TOKEN / ELLIPSIS_API_BASE_URL, with the legacy
ELLIPSIS_API_BASE accepted as a fallback) → the active host in the config
file → default (prod). This lets the CLI run headlessly — e.g. inside an
Ellipsis cloud sandbox where a per-sandbox token and base URL are injected into
the environment — with no agent login and no config file on disk. agent logout only clears the on-disk token (--all for every host); a token supplied
via ELLIPSIS_API_TOKEN lives in the environment and keeps working until you
unset it.
agent host selects which Ellipsis instance the CLI targets — Ellipsis Cloud,
a preview environment, or a self-hosted deployment — so you can switch without
re-exporting env vars. agent host add <name> <api-url> registers an instance
and makes it active; agent host use <name> switches; agent host list shows
them all (the active one marked *). Each host keeps its own token (so
switching doesn't re-authenticate) and its own dashboard/app URL. The app URL
is derived from the API URL by default (api. → app.); a self-hosted instance
whose dashboard host isn't a mechanical swap sets it explicitly with agent host add … --app-base <url> (or agent host set <name> --app-base <url>). agent login then authenticates the active host, and every link the CLI prints points
at that host's dashboard.
Hosts and tokens live in ~/.ellipsis/config.json (mode 0600); set
ELLIPSIS_CONFIG_DIR to relocate it. A config file from before hosts existed
is migrated on first use — your existing login becomes a host named for its API
base.
The config file also carries UI preferences. "sessionBar" scopes the session
list at the bottom of the interactive UI:
{
"sessionBar": {
"hidden": false,
"rows": 5,
"days": 7,
"repo": "cwd",
"statuses": "all",
"sources": ["cli", "manual"]
}
}hidden drops the bar entirely and gives its rows to the chat window. rows is
how many sessions it lists (a short terminal shows fewer). days hides sessions
that have not moved in that long; 0 means no age cutoff. repo is "cwd" to
list only sessions on the repository your shell is in, or "any" for all of
them. statuses is "unfinished" to leave out the sessions that finished,
errored, or were stopped, or "all" to keep them. sources lists only sessions
started those ways (react, manual, api, cli, mention, cron); leave it
out for all of them.
Every field is optional and the defaults above are what you get with no
sessionBar at all. Two caveats on repo: a shell outside a repository lists
every repository rather than nothing, and sessions that name their repository
only inside their agent config — dashboard starts, cron runs, handoffs — do not
match a repo filter, so "repo": "any" is the way to see those alongside the
rest.
npm install
npm run dev -- --help # run from source (tsx)
npm run typecheck # tsc --noEmit
npm test # unit tests (vitest)
npm run build # bundle to dist/ (tsup)
npm run compile # single-binary build (bun)-
npm testruns the vitest unit suite (test/): query building and error parsing in the API client, the option coercions, money formatting, and thedeviceLoginpoll loop (driven with fake timers, no network). -
scripts/smoke-local.shis a fully-automated end-to-end check against a localdocker composebackend. It drives the device-code login itself — scraping the verification code and approving it headlessly through the runningpublic_apicontainer — then exercises the authenticated API calls with a throwaway config dir. One command, no manual approval:./scripts/smoke-local.sh # overrides: ELLIPSIS_API_BASE, ELLIPSIS_PUBLIC_API_CONTAINER, ELLIPSIS_SMOKE_CUSTOMER_ID -
scripts/smoke.shis the manual variant for any backend (incl. staging/prod): it drives login and the API calls but waits for you to approve in the dashboard. See its header for the approval options.ELLIPSIS_API_BASE=http://localhost:5000 ./scripts/smoke.sh
Note: the
verification_urithe backend returns points atapp.ellipsis.devunless the container setsELLIPSIS_APP_BASE_URL=http://localhost:3000, so for local runs prefersmoke-local.sh's headless container approval over the browser link.
| Path | Purpose |
|---|---|
src/cli.tsx |
entry point; wires up the command tree |
src/commands/ |
one module per top-level command group |
src/ui/ |
Ink components for interactive / streaming views |
src/lib/ |
API client, WebSocket client, config, constants |
Pushing a v* tag triggers .github/workflows/release.yml, which Bun-compiles
binaries for macOS and Linux (arm64 + x64), publishes a GitHub release with the
tarballs, and regenerates the formula in
ellipsis-dev/homebrew-cli.
git tag v0.1.0 && git push origin v0.1.0The cross-repo push to the tap uses a write-scoped deploy key: the public
half is registered on ellipsis-dev/homebrew-cli (Settings → Deploy keys, write
access), and the private half is stored as the HOMEBREW_TAP_DEPLOY_KEY secret
on this repo. The workflow checks out the tap over SSH with it. A deploy key is
scoped to that one repo only — no account-wide PAT involved.
The full public REST surface (auth, sessions, session search/steps, configs,
integration discovery, budget/usage) is wired against the live API, including
live WebSocket streaming and session stop.
Still pending: replacing the hand-rolled request/response types with the
generated @ellipsis/sdk package.