The official open-source command-line client for Cobalt. It talks only to the versioned Cobalt External API and is distributed as a normal npm package—there are no platform executables.
Website: cobaltcode.ai · Built by Amaretto Software Labs
Node.js 22 or newer is required.
npx @amaretto-software-labs/cobalt-cli --help
npm install --global @amaretto-software-labs/cobalt-cli
cobalt auth loginOAuth sessions are stored in macOS Keychain, Windows Credential Manager, or Linux Secret Service. Credential storage fails closed; the CLI never falls back to a plaintext token file. For automation, provide one scoped token through COBALT_TOKEN.
If browser sign-in fails or you cancel consent, keep the CLI running. The branded recovery page offers Try again and Use another account (which signs out of the web app before returning to sign-in). You can also press Enter in an interactive terminal to start a fresh attempt, or open the recovery URL printed by the CLI if you closed the browser. Each attempt uses new OAuth state and PKCE values. Attempts time out after five minutes; the retry page remains available for another ten minutes. Ctrl+C stops login and closes the local listener. The success page is shown only after credentials are validated and securely saved.
cobalt auth login
cobalt workspace list
cobalt workspace use "My Workspace"
cobalt repo list --eligible-only
cobalt agent list --available
cobalt task create \
--repo my-repository \
--message "Fix the failing tests and open a PR"
cobalt task list --created-by-me
cobalt task follow <task-id> --jsonlEnvironments are selected with --environment prod|dev|demo|local or COBALT_ENVIRONMENT. Select a workspace with --workspace, COBALT_WORKSPACE, or the saved per-environment workspace context.
The local environment targets the standard Cobalt Aspire endpoints (https://localhost:7295/v1, https://localhost:7270, and https://localhost:7250) and reuses the development OAuth client registration. It adds the operating-system trust store to Node's default roots when the runtime supports that API. On older Node 22 builds, use NODE_OPTIONS=--use-system-ca after trusting the ASP.NET Core development certificate. Certificate verification remains enabled.
auth login|logout|status
workspace list|use|current
repo list
agent list
task list|get|search|create|messages|message-search|events
task send|steer|cancel|suspend|resume|auto-wake|delete|wait|follow|open
task queue list|hold|release|cancel|retry|move
task environment list|attach|detach|dns-default
environment list|get|create|update|start|stop|restart|delete|revoke-service|operation
environment sidecar diagnostics|restart|delete|retry-image
environment image-source list|create|update|delete|repositories|tags
pr-gate list|configure|action
loop list|get|create|update|enable|disable|delete|run|rerun
loop runs|decisions|lanes|descriptors|preview
role list|get|create|update|delete
interactive
completion bash|zsh|fish|powershell
version
All mutations accept --idempotency-key <uuid>. Message input uses exactly one of --message, --message-file, or --stdin. Output defaults to human-readable text; use --json for one envelope or --jsonl for streams and pagination.
Interactive mode retains an ambiguous mutation's idempotency key and directs you to /retry, which safely replays the same operation with that key. Read-only inspection remains available, while another mutation or context change waits for the replay.
Exit codes are stable: 0 success, 2 usage, 3 authentication, 4 authorization, 5 not found, 6 conflict, 7 rate limited, 8 unavailable, 9 admission, 10 configuration, and 130 interrupted.
Read the current definition before replacing it. Updates require its observed version/revision and one complete file; creates start no work. Enabling a Loop authorizes its future unattended runs as your current identity.
cobalt loop list --all
cobalt loop get <loop-id> --json
cobalt loop update <loop-id> --document-file review.md --expected-version 7
cobalt loop enable <loop-id> --expected-version 8
cobalt loop runs <loop-id> --all
cobalt loop descriptors --json
cobalt role list --all
cobalt role get pr-reviewer --json
cobalt role update pr-reviewer --name "PR Reviewer" --description "Review PRs" \
--instructions-file reviewer.md --expected-revision 2
cobalt task create --repo <repository-id> --pull-request 184 \
--title "[PR Review 184] Review current revision" --retention persistent \
--default-role pr-reviewer --role pr-reviewer --no-auto-wake \
--message "Review the exact head/base."
cobalt task send <task-id> --role pr-reviewer --message "Review the next revision."
cobalt task auto-wake <task-id> offTask creation supports --on-hold; inspect and release admission through
cobalt task queue. Role selection belongs to task creation or message send.
task resume restores compute and does not accept a role. Auto-wake controls
generic environment restoration on resume; it is separate from automatic
suspension after a turn. Server-side permissions, capacity, and immutable role
snapshots apply to every command.
Desktop MCP clients can use the same renderer and response headers as the CLI:
import {
oauthCallbackResponseHeaders,
renderOAuthCallbackPage,
} from "@amaretto-software-labs/cobalt-cli/oauth-callback";
// Only after the client's OAuth state/PKCE and token validation succeed:
response.writeHead(200, oauthCallbackResponseHeaders);
response.end(renderOAuthCallbackPage("success", undefined, "mcp"));The shared renderer supports success, cancelled, waiting, invalid,
timeout, and failed states. The MCP variant directs the user back to their
desktop app. It performs no OAuth operations and never receives tokens or raw
provider error details. The client owns validation, token storage, and listener
cleanup. Pass a local retry path only when the client implements that route.
corepack enable
pnpm install --frozen-lockfile
pnpm verifyopenapi/v1.json is the canonical Cobalt External API schema copied from the product repository. pnpm openapi:check fails if its 39 CLI operations drift from the client mapping. The five OAuth browser-session operations are accounted for separately because they belong to the browser extension.
The release workflow uses Node 24, pnpm 10.14.0, npm provenance, and npm trusted publishing through GitHub OIDC. Main-branch releases publish a generated 0.1.0-dev.<run>.<attempt> version under the dev tag. Manual runs support dev, demo, and stable prod channels.
Create GitHub environments named dev, demo, and prod before enabling releases, and configure prod with required reviewers. Both package creation and publishing are bound to the selected environment so a production release cannot bypass its approval policy.
The package must exist before npm allows a trusted publisher to be configured. Bootstrap publishing once from an npm account protected by 2FA:
- Run
pnpm verify, then generate the chosen initial version withCOBALT_CLI_PACKAGE_VERSION=<version> pnpm pack:check. - Authenticate with npm and run
npm publish release/npm/*.tgz --access public, completing the 2FA prompt. - In the npm package settings, add the GitHub Actions trusted publisher for
Amaretto-Software-Labs/cobalt-cliand workflowrelease.yml. - Set the repository variable
NPM_TRUSTED_PUBLISHING_ENABLEDtotrue.
Until that variable is enabled, main pushes still run CI and build the release artifact, while the publish job is intentionally skipped.
Please report vulnerabilities privately through GitHub Security Advisories. Do not include access tokens, refresh tokens, task messages, or repository content in public issues.
Apache-2.0.
Computer availability is automatic: Borealis suspends idle VMs and activates them for prompts, commands and previews. There is no task auto-suspend option. Workspace concurrency counts active agent turns or commands.
environment manages persistent workspace resources. The global
--environment option still selects the API deployment. Create and update use a
complete JSON definition with a container image selection, launch commands,
readiness and secretReferences mapping variable names to saved secret UUIDs.
Plaintext launch secrets are not accepted in definitions.
cobalt environment list --json
cobalt environment create --definition-file database.json
cobalt environment get <environment-id> --json
cobalt environment update <environment-id> --definition-file database.json --expected-generation 3
cobalt environment start <environment-id> --expected-generation 4
cobalt environment operation <operation-id> --wait --timeout 300 --json
cobalt environment sidecar restart <environment-id> <sidecar-id> --expected-generation 5
cobalt environment sidecar diagnostics <environment-id> <sidecar-id>
cobalt task create --message "Run the integration tests" \
--attach-environment <database-environment-id> <cache-environment-id> \
--default-dns-environment <database-environment-id>
cobalt task environment list <task-id> --json
cobalt task environment attach <task-id> <environment-id>
cobalt task environment dns-default <task-id> --attachment <attachment-id> --expected-generation 3
cobalt task environment dns-default <task-id> --clear --expected-generation 4
cobalt task environment detach <task-id> <attachment-id> --expected-generation 2
cobalt task send <task-id> --message "Retry with the database repaired"Environment power actions are start, stop, restart, delete and
revoke-service. Sidecar actions are restart and delete. Mutations require
the observed resource generation where applicable; use the same explicit
--idempotency-key when retrying an uncertain result. A durable attachment can
remain recorded while its task is suspended. Inspect connectivity separately
before relying on live access. --bindings-file accepts a JSON map of
application variable names to sidecar DNS labels, for example
{"DATABASE_HOST":"db"}. Cobalt resolves each label to its qualified private host.
Sidecar definitions use image: { "kind": "registry", "reference": "docker.io/library/postgres:17" }, or kind: "archive" with a direct HTTPS OCI/Docker image archive URL. Cobalt resolves and prepares the runtime image; template IDs, digests and architecture are not request fields. Existing sidecar disks remain pinned after allocation.
For private registries, create a workspace source referencing an existing Vault secret, then set its sourceId in the sidecar image:
cobalt environment image-source create --name GHCR --registry ghcr.io --username builder --credential-entry <vault-entry-id>
cobalt environment image-source repositories <source-id>
cobalt environment image-source tags <source-id> team/database
cobalt environment sidecar retry-image <environment-id> <sidecar-id> --expected-generation 3Image preparation status is separate from service readiness. An accepted create does not mean the image, sidecar or task is running. Retry uncertain mutations with the same --idempotency-key.