Skip to content

CLI Overview

The ThinkWork CLI (thinkwork-cli) is the primary way to deploy and manage ThinkWork and to operate a running stack. It wraps Terraform for provisioning, authenticates to the deployed Cognito pool for day-two ops, and exposes every admin-site capability as scriptable + interactive commands.

Terminal window
npm install -g thinkwork-cli

Or run one-off without installing globally:

Terminal window
npx thinkwork-cli --help

Verify the installation:

Terminal window
thinkwork --version
thinkwork --help
  • Node.js 20+
  • Terraform 1.6+ on your $PATH (for deploy/plan/destroy)
  • AWS credentials (via ~/.aws/credentials, environment variables, or EC2/ECS instance role)
  • A browser (for thinkwork login --stage <s> — optional; --api-key skips it)

The CLI has two separate login flows — they do different things and are stored separately in ~/.thinkwork/config.json.

Configures the AWS credentials the CLI uses to shell out to terraform and the aws CLI. Arrow-key picker over your existing ~/.aws/ profiles, with fall-through to access-key entry or aws sso login.

Terminal window
thinkwork login # interactive profile picker
thinkwork login --sso --profile work-sso
thinkwork login --keys --profile thinkwork

The chosen profile is saved as defaultProfile and used by plan, deploy, destroy, bootstrap, doctor, outputs, status, init, etc.

thinkwork login --stage <s> — Cognito session

Section titled “thinkwork login --stage <s> — Cognito session”

Signs in to the deployed stack’s Cognito user pool via OAuth2 authorization-code flow over a local loopback listener (port 42010). Supports Google OAuth through Cognito’s hosted UI. The resulting id/refresh tokens plus the caller’s default tenant are cached on sessions["<stage>"].

Terminal window
# Interactive — opens browser
thinkwork login --stage dev
# Non-interactive — CI / service
thinkwork login --stage prod --api-key "$THINKWORK_API_KEY" --tenant acme

API-backed commands (thinkwork thread list, thinkwork agent create, thinkwork me, …) consume this session. Cognito id-tokens are refreshed transparently from the refresh token.

~/.thinkwork/config.json:

{
"defaultProfile": "thinkwork",
"defaultStage": "dev",
"sessions": {
"dev": { "kind": "cognito", "idToken": "...", "refreshToken": "...", "expiresAt": 1234, "tenantSlug": "acme", ... },
"prod": { "kind": "api-key", "authSecret": "...", "tenantSlug": "acme", "tenantId": "..." }
}
}

~/.thinkwork/environments/<stage>/config.json:

{
"stage": "dev",
"region": "us-east-1",
"accountId": "123456789012",
"terraformDir": "/Users/alice/thinkwork-deploy",
"databaseEngine": "aurora-serverless",
"enableHindsight": false,
"createdAt": "2026-04-16T10:00:00Z",
"updatedAt": "2026-04-16T10:00:00Z"
}

The environment registry is populated by thinkwork init and lets any command resolve the terraform working directory without needing a cd or a --dir flag.

Every API-backed command needs a stage. Resolution order:

  1. -s / --stage <name> flag
  2. THINKWORK_STAGE env var
  3. defaultStage in ~/.thinkwork/config.json (set by a successful thinkwork login --stage <s>)
  4. The sole deployed stage in the configured AWS region, if there’s only one
  5. Interactive picker (TTY only; errors in CI)

API-backed commands also need a tenant (workspace). Resolution order:

  1. -t / --tenant <slug> flag
  2. THINKWORK_TENANT env var
  3. tenantSlug cached on the current stage’s session (set at login time via bootstrapUser)
  4. Interactive picker of the caller’s tenant memberships (TTY only)

Every command works two ways:

  • Flag-driven for agents and CI: pass every field as a flag. Missing required flags in a non-TTY context print a clear error and exit 1.
  • Interactive walkthrough for humans: missing fields are prompted with arrow-key pickers or text input. Ctrl+C cancels cleanly.
Terminal window
# Fully interactive
thinkwork user invite
# Fully scripted
thinkwork user invite alice@example.com --tenant acme -s dev --role admin
# Mix — pass the positional, prompt for everything else
thinkwork user invite alice@example.com

Every API-backed command accepts --json:

Terminal window
thinkwork me --json | jq .tenantSlug
thinkwork thread list --status IN_PROGRESS --json | jq '.[] | .id'
thinkwork cost summary --json | jq .totalUsd

--json routes structured output to stdout; warnings, spinners, and errors always go to stderr so pipelines stay clean.

Terminal window
# 1. AWS side (deploy / destroy / status) — credentials from env or IAM role.
export AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}
export AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}
export AWS_REGION=us-east-1
thinkwork deploy -s prod --auto-approve
# 2. API side (thread / agent / inbox / …) — api-key session, no browser.
thinkwork login --stage prod --api-key "${{ secrets.THINKWORK_API_KEY }}" --tenant acme
thinkwork thread list --status IN_PROGRESS --json | jq '.[].id'

The api-key path stores authSecret + tenant on the session. resolveAuth(stage) sends Authorization: Bearer <secret> + x-tenant-id: <id> for every subsequent call.

See Commands Reference for the full syntax and options for every command — flags, positional args, examples for both interactive and scripted invocations, and the full Phase 1–5 roadmap of scaffolded commands.