CLI reference

Close to your code.

A single binary for macOS and Linux, on arm64 and x64. Linux builds require glibc.

Install

curl -fsSL https://todos.sh/install | sh

The installer checks the SHA-256 checksum and installs to ~/.local/bin/todos. Run it again to update. You can read the script before you run it or inspect the release manifest.

Sign in and choose a workspace

todos auth login
todos ws list
todos ws use studio
todos team list
todos issue list

Login opens the key creation page. Paste the key into the terminal. If you already have a key, run todos auth login --key to paste it without opening the browser. Settings are stored with mode 0600 in $XDG_CONFIG_HOME/todos/config.json, or ~/.config/todos/config.json.

Use --json for scripts; non-terminal output is also JSON. Terminal tables show times in UTC; JSON keeps Unix timestamps. Exit codes: 0 success, 1 error, 2 unauthenticated, 3 forbidden, 4 rate limited, 5 monthly API allowance used.

Global flags

FlagValueDescription
--workspaceTextWorkspace slug or ID
--jsonSwitchPrint JSON
--quietSwitchSuppress successful output
--help, -hSwitchShow help
--version, -vSwitchPrint the version

todos auth

Log in, log out, or check access

todos auth login [--key [<secret>]]
todos auth logout
todos auth status
FlagValueDescription
--keyOptional textAPI key secret; prompts when empty

todos try

Start a trial workspace without an account

todos try [--name <name>] [--agent <name>]
FlagValueDescription
--nameTextWorkspace name
--agentTextWho works in it, shown on every change

todos ws

List, select, or create workspaces

todos ws list [--limit <n>] [--cursor <cursor>]
todos ws use <workspace>
todos ws create --name <name> [--slug <slug>]
FlagValueDescription
--limitTextPage size (1–100)
--cursorTextNext page cursor
--nameTextWorkspace name
--slugTextWorkspace slug

todos team

List, create, archive, or delete teams, or list workflow states

todos team list [--archived]
todos team create --name <name> --key <key> [--visibility public|private]
todos team states [--team <id>]
todos team archive <id>
todos team unarchive <id>
todos team delete <id> --yes
FlagValueDescription
--nameTextTeam name
--keyTextIssue key prefix, such as ENG
--visibilityTextpublic or private (default: public)
--teamTextOnly this team's states
--archivedSwitchList only archived teams
--yesSwitchConfirm a delete; it cannot be undone

todos project

List, create, update, archive, or delete projects

todos project list [--archived]
todos project create --name <name> [options]
todos project update <id> [options]
todos project archive <id>
todos project unarchive <id>
todos project delete <id> --yes
FlagValueDescription
--nameTextProject name
--teamTextTeam ID
--descriptionTextProject description
--statusTextplanned, active, paused, completed, or canceled
--leadTextLead user ID
--startTextStart date as Unix seconds
--targetTextTarget date as Unix seconds
--archivedSwitchList only archived projects
--yesSwitchConfirm a delete; it cannot be undone

todos issue

Find, create, and manage issues

todos issue list [filters]
todos issue show <key>
todos issue create --team <id> --title <title> [options]
todos issue update <key> [options]
todos issue move <key> --team <id> [--state <id>]
todos issue close <key> [--state <id>]
todos issue comment <key> --body <text>
todos issue search <query> [--limit <n>]
todos issue archive <key>
todos issue unarchive <key>
todos issue delete <key> --yes
FlagValueDescription
--limitTextPage size (1–100)
--cursorTextNext page cursor
--teamTextTeam ID
--titleTextIssue title
--descriptionTextIssue description
--stateTextWorkflow state ID; list accepts a state kind
--priorityTextPriority (0–4)
--assigneeTextAssignee user ID, or none for no assignee
--projectTextProject ID, or none for no project
--parentTextParent issue key or ID, or none for no parent
--ancestorTextIssue key or ID; list its sub-issues at any depth
--labelTextFilter by label ID
--labelsTextComma-separated label IDs; empty clears them
--dueTextDue date as Unix seconds
--estimateTextIssue estimate
--positionTextSort position
--archivedSwitchList only archived issues
--qTextSearch query
--bodyTextComment text
--yesSwitchConfirm a delete; it cannot be undone

todos inbox

List or read your notifications

todos inbox list [--unread] [--limit <n>] [--cursor <cursor>]
todos inbox read [--ids <id,id>] [--issue <key>]
FlagValueDescription
--unreadSwitchOnly unread notifications
--idsTextNotification IDs to mark read (default: all)
--issueTextMark only this issue's notifications read, such as ENG-12
--limitTextPage size (1–100)
--cursorTextNext page cursor

todos label

List or create labels

todos label list
todos label create --name <name> --color <hex> [--team <id>]
FlagValueDescription
--nameTextLabel name
--colorTextLabel color
--teamTextTeam ID (default: workspace-wide)

todos key

List, create, rotate, or revoke API keys

todos key list [--personal] [--limit <n>] [--cursor <cursor>]
todos key create --name <name> --scopes <csv> [--role <role>] [--personal]
todos key rotate <id> [--grace PT0S..PT24H] [--personal]
todos key revoke <id> [--personal]
FlagValueDescription
--limitTextPage size (1–100)
--cursorTextNext page cursor
--personalSwitchManage personal keys
--nameTextKey name
--scopesTextComma-separated scopes or read/write groups
--roleTextWorkspace role (default: member)
--teamsTextComma-separated team IDs
--workspacesTextPersonal key workspace IDs, or *
--expiresTextExpiry timestamp in milliseconds
--graceTextRotation grace: PT0S or PT1H through PT24H

todos webhook

Manage webhooks and inspect deliveries

todos webhook list
todos webhook create --url <https-url> --events <csv>
todos webhook test <id>
todos webhook deliveries <id>
FlagValueDescription
--urlTextWebhook URL
--eventsTextComma-separated event types

todos import

Import a Linear workspace or a GitHub repository

todos import linear [--teams <keys>] [--token <key>] [--dry-run]
todos import github <owner/repo> [--team <key>] [--token <token>] [--dry-run]
FlagValueDescription
--tokenTextSource token; else LINEAR_API_KEY, or GITHUB_TOKEN, GH_TOKEN, or gh auth token
--teamsTextLinear team keys, comma-separated; all teams when omitted
--teamTextTeam key for the repository; made from its name when omitted
--dry-runSwitchRead the source and print counts only

todos config

Read or set local settings

todos config get <api|key|workspace>
todos config set <api|key|workspace> <value>

This command has no extra flags.