Skip to content

About

Official Cobalt command-line interface

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Cobalt CLI

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

Install

Node.js 22 or newer is required.

npx @amaretto-software-labs/cobalt-cli --help
npm install --global @amaretto-software-labs/cobalt-cli
cobalt auth login

OAuth 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.

Quick start

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> --jsonl

Environments 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.

Commands

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.

Loops and worker roles

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> off

Task 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.

Reuse the branded OAuth callback in an MCP client

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.

Development

corepack enable
pnpm install --frozen-lockfile
pnpm verify

openapi/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.

Releasing

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:

  1. Run pnpm verify, then generate the chosen initial version with COBALT_CLI_PACKAGE_VERSION=<version> pnpm pack:check.
  2. Authenticate with npm and run npm publish release/npm/*.tgz --access public, completing the 2FA prompt.
  3. In the npm package settings, add the GitHub Actions trusted publisher for Amaretto-Software-Labs/cobalt-cli and workflow release.yml.
  4. Set the repository variable NPM_TRUSTED_PUBLISHING_ENABLED to true.

Until that variable is enabled, main pushes still run CI and build the release artifact, while the publish job is intentionally skipped.

Security

Please report vulnerabilities privately through GitHub Security Advisories. Do not include access tokens, refresh tokens, task messages, or repository content in public issues.

License

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.

Workspace environments and sidecars

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 container images

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 3

Image 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.

About

Official Cobalt command-line interface

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages