Skip to main content
Ten subcommands bind this repository to Reticle Cloud so runs and flows land on a dashboard. They dispatch before the local parser, so reticle login is one tool, not a second binary.
These are thin clients over the /v1 API. The logic is server-side; these verbs surface it.

Where credentials live

Auth for any command is RETICLE_API_KEY from the environment (the agent path) if set, otherwise the login token. RETICLE_CLOUD_URL overrides the endpoint; the default is http://localhost:8890. When a command falls back to that default without RETICLE_CLOUD_URL (or a saved session URL), it prints a one-line notice on stderr; stdout stays pure JSON for agents.

The commands

reticle login

With no --email, it runs a browser device flow like gh auth login: fetch a device and user code, open the browser to approve, poll until confirmed. With --email it keeps the two-step code path for CI and servers, because it proves you own the inbox before handing out a session. A local cloud whose dev mailer cannot deliver echoes the code back and completes in one command.

reticle logout

Empties session.json. Per-project keys in credentials.json stay. Prints { "loggedOut": true }.

reticle whoami

The one call to make when you do not know your state. Real capture:
An unattached repo also gets a next-step nudge on stderr, telling you to run reticle link:
whoami exits 0 either way. Throughout this page, the punctuation joining the two halves of a message is shown as ....
Binds this repository to a cloud project. With a login token it mints a project-scoped key, so there is nothing to paste. With RETICLE_API_KEY already set, it resolves that key’s project instead. --project accepts a slug id or a display name; omitted, it uses the default project. Writes cloud.json and the key.

reticle project

rename and rm work but are missing from the top-level reticle help block, which lists only <ls|create <name>>. The command’s own usage error names all four. Missing or malformed arguments exit 2:

reticle config

Edits .reticle/cloud.json in place. Any value other than on or off (or local or server for --verify) exits 2. Requires the repo to be linked; run in an unlinked repo it exits 2 before it looks at the flags at all:

reticle push

Sends local run artifacts from .reticle to the linked project, honoring the sync policy. With sync.runs off it does nothing and says so. Prints { ok, project, sent, pulled }, where sent carries the accepted counts and, when the server refused anything, a rejected array naming each artifact’s index and reason. A rejection is a failed push. If the server refuses any artifact, ok is false and the command exits 1, even when other artifacts in the same bundle landed. A refused artifact never reaches the dashboard and is re-offered on every cycle, so partial loss is still loss. ok: true and exit 0 mean everything offered was accepted, which includes the common case of a repo that was already up to date. The accepted counts still report what did land, so a partial push is visible as one.

reticle runs

The linked project’s recent run artifacts. The key scopes the query server-side.

reticle regression

The CI gate: which flows broke relative to before. Exits 3 when any flow regressed, which is the whole point of it being a separate command.

reticle share

Mints a public proof link for one run. A missing runId exits 2:

When the repo is not attached

push, runs and regression all need a project to talk to. Without one they exit 1 with the same line on stderr, measured:

Exit codes

Output is pretty-printed JSON on stdout. Errors and next-step nudges go to stderr, so an agent parsing stdout is unaffected.

Worked example

Last modified on September 23, 2026