Skip to main content

twist-cli

Twist messaging CLI. View and respond to inbox threads, channel threads, direct messages, mentions, and group conversations; search, react, archive, mute, and manage workspaces. Use when the user mentions Twist, asks about their inbox, mentions, threads, DMs, channels, or wants to read or send Twist messages.

Source facts

Repository
Doist/twist-cli
Last source activity
October 19, 2026 at 12:25
Detected SKILL.md language
English
Stars
3
Forks
1

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
twist-cli
description
Twist messaging CLI. View and respond to inbox threads, channel threads, direct messages, mentions, and group conversations; search, react, archive, mute, and manage workspaces. Use when the user mentions Twist, asks about their inbox, mentions, threads, DMs, channels, or wants to read or send Twist messages.
license
MIT
metadata
{"author":"Doist","version":"3.0.15"}
# Twist CLI (tw) Access Twist messaging via the `tw` CLI. Use when the user asks about their Twist workspaces, threads, messages, or wants to interact with Twist in any way. ## Setup ```bash tw auth login # OAuth login (opens browser, read-write) tw auth login --read-only # OAuth login with read-only scope tw auth login --callback-port <n># Override the local OAuth callback port (default 8766) tw auth login --json # Emit a JSON envelope for scripted / agent use tw auth login --ndjson # Emit an NDJSON envelope for scripted / agent use tw auth token # Save API token manually (prompts securely; scope unknown, assumed write-capable) tw auth status # Verify authentication + show mode tw auth status --json # Full status payload as JSON (--ndjson also supported) tw auth status --user <ref> # Target a specific stored account (id, id:<n>, or display name) tw --user <ref> auth <status|logout|token view> # Equivalent to passing --user after the subcommand; other commands accept the flag but ignore it tw auth logout # Remove saved token and auth metadata tw auth logout --json # Emits `{"ok": true}` (--ndjson is silent) tw auth logout --user <ref> # Target a specific stored account; mismatched ref errors with ACCOUNT_NOT_FOUND tw auth token view # Print the saved token to stdout (pipe-safe; refuses if TWIST_API_TOKEN is set) tw auth token view --user <ref> # Print the saved token for a specific stored account tw account [list|current|use <ref>|remove <ref>] # Manage stored accounts; all support --json/--ndjson # current's payload is {id, label, authMode, authScope, source:"config"} | {source:"env"} | {source:"legacy"} tw auth login # Re-running auth login with a different OAuth grant adds a NEW account; default stays pinned unless none was set tw workspaces # List available workspaces tw workspace use <ref> # Set current workspace tw completion install # Install shell completions tw config view # Show the current CLI configuration file (token masked) tw config set <key> <value> # Set a user preference (e.g. unarchive-new-threads true) tw doctor # Diagnose CLI setup and environment issues tw update # Update CLI to latest version tw changelog # Show recent changelog entries ``` Stored auth uses the system credential manager when available. If secure storage is unavailable, `tw` warns and falls back to `~/.config/twist-cli/config.json`. `TWIST_API_TOKEN` always takes priority over the stored token, and legacy plaintext config tokens are migrated automatically when secure storage is available. In read-only mode (`tw auth login --read-only`), commands that modify Twist data (reply, archive, react, delete, etc.) are blocked by the CLI. Externally provided tokens (`TWIST_API_TOKEN` or `tw auth token`) are treated as unknown scope and assumed write-capable. ## View by URL ```bash tw view <url> # View any Twist entity by URL ``` Routes automatically based on URL structure: - Message URL → `tw msg view` - Conversation URL → `tw conversation view` - Thread+comment URL → `tw thread view` (comment ID extracted from URL) - Thread URL → `tw thread view` All target command flags pass through (e.g. `--json`, `--raw`, `--full`). ## Inbox ```bash tw inbox # Show inbox threads tw inbox --unread # Only unread threads tw inbox --archive-filter all # Show active + done threads tw inbox --archive-filter archived # Show only done threads tw inbox --channel <filter> # Filter by channel name (fuzzy) tw inbox --since <date> # Filter by date (ISO format) tw inbox --limit <n> # Max items (default: 50) ``` ## Threads ```bash tw thread <thread-ref> # View thread (shorthand for view) tw thread view <thread-ref> # View thread with comments tw thread view <ref> --comment <id> # View a specific comment tw thread view <url-with-/c/id> # Comment ID extracted from URL tw thread view <ref> --unread # Show only unread comments tw thread view <ref> --context 3 # Include 3 read comments before unread tw thread view <ref> --limit 20 # Limit number of comments tw thread view <ref> --since <date> # Comments newer than date tw thread view <ref> --raw # Show raw markdown tw thread create <channel-ref> "Title" "content" # Create a new thread tw thread create <channel-ref> "Title" "content" --json # Create and return as JSON tw thread create <channel-ref> "Title" "content" --json --full # Include all thread fields tw thread create <channel-ref> "Title" "content" --notify 123,456 # Notify specific users tw thread create <channel-ref> "Title" "content" --unarchive # Land thread in author's Inbox (overrides default Twist auto-archive) tw thread create <channel-ref> "Title" "content" --no-unarchive # Force archive even when userSettings.unarchiveNewThreads=true tw thread create <channel-ref> "Title" "content" --dry-run # Preview without posting tw thread create <channel-ref> "Title" --file ./a.png # Attach a file (repeatable; content optional) tw thread reply <ref> "content" # Post a comment (notifies EVERYONE_IN_THREAD by default) tw thread reply <ref> "content" --notify EVERYONE # Notify all workspace members tw thread reply <ref> "content" --notify 123,id:456 # Notify specific user IDs tw thread reply <ref> "content" --json # Post and return comment as JSON tw thread reply <ref> "content" --json --full # Include all comment fields tw thread reply <ref> "content" --close # Reply and close the thread tw thread reply <ref> "content" --reopen # Reply and reopen a closed thread tw thread reply <ref> "content" --file ./a.png # Attach a file (repeatable; content optional) tw thread done <ref> # Archive thread (mark done) tw thread done <ref> --json # Archive and return status as JSON tw thread mute <ref> # Mute thread for 60 minutes (default) tw thread mute <ref> --minutes 480 # Mute for custom duration tw thread mute <ref> --json # Mute and return { id, mutedUntil } as JSON tw thread mute <ref> --json --full # Mute and return full thread as JSON tw thread unmute <ref> # Unmute a muted thread tw thread unmute <ref> --json # Unmute and return { id, mutedUntil } as JSON tw thread delete <ref> # Preview thread deletion (requires --yes to execute) tw thread delete <ref> --yes # Permanently delete a thread tw thread delete <ref> --yes --json # Delete and return status as JSON tw thread rename <ref> "New title" # Rename a thread (change its title) tw thread rename <ref> "New title" --json # Rename and return { id, title } as JSON tw thread rename <ref> "New title" --json --full # Rename and return full thread as JSON tw thread update <ref> "New body" # Update a thread's body (the first post) echo "New body" | tw thread update <ref> # Update body from stdin tw thread update <ref> "New body" --dry-run # Preview without updating tw thread update <ref> "New body" --json # Update and return { id, content } as JSON tw thread update <ref> "New body" --json --full # Update and return full thread as JSON ``` Default `--notify` for reply is EVERYONE_IN_THREAD, which may notify more people than intended. Before posting, confirm with the user whether specific people should be notified instead (via `--notify <user-ids>`). Options: EVERYONE, EVERYONE_IN_THREAD, or comma-separated ID refs. `--notify` automatically resolves IDs: group IDs are routed to the `groups` API field, user IDs to `recipients`. No special syntax needed. ## Thread Comments ```bash tw comment <comment-ref> # View a comment (shorthand for view) tw comment view <comment-ref> # View a single thread comment tw comment view <comment-ref> --raw # Show raw markdown tw comment view <comment-ref> --json # Output as JSON tw comment view <comment-ref> --ndjson # Output as newline-delimited JSON tw comment view <comment-ref> --json --full # Include all fields in JSON output tw comment update <comment-ref> "new content" # Update a thread comment tw comment update <comment-ref> "content" --json # Update and return updated comment as JSON tw comment update <comment-ref> "content" --json --full # Include all comment fields tw comment delete <comment-ref> # Delete a thread comment tw comment delete <comment-ref> --json # Delete and return status as JSON ``` ## Conversations (DMs/Groups) ```bash tw conversation unread # List unread conversations tw conversation <conversation-ref> # View conversation (shorthand for view) tw conversation view <conversation-ref> # View conversation messages tw conversation with <user-ref> # Find your 1:1 DM with a user tw conversation with <user-ref> --snippet # Include the latest message preview tw conversation with <user-ref> --include-groups # List any conversations with that user tw conversation reply <ref> "content" # Send a message tw conversation reply <ref> "content" --json # Send and return message as JSON tw conversation reply <ref> "content" --json --full # Include all message fields tw conversation reply <ref> "content" --file ./a.png # Attach a file (repeatable; content optional) tw conversation done <ref> # Archive conversation tw conversation done <ref> --json # Archive and return status as JSON tw conversation mute <ref> # Mute conversation for 60 minutes (default) tw conversation mute <ref> --minutes 480 # Mute for custom duration tw conversation mute <ref> --json # Mute and return { id, mutedUntil } as JSON tw conversation mute <ref> --json --full # Mute and return full conversation as JSON tw conversation unmute <ref> # Unmute a muted conversation tw conversation unmute <ref> --json # Unmute and return { id, mutedUntil } as JSON ``` Alias: `tw convo` works the same as `tw conversation`. ## Conversation Messages ```bash tw msg <message-ref> # View a message (shorthand for view) tw msg view <message-ref> # View a single conversation message tw msg update <ref> "content" # Edit a conversation message tw msg update <ref> "content" --json # Edit and return updated message as JSON tw msg update <ref> "content" --json --full # Include all message fields tw msg delete <ref> # Delete a conversation message tw msg delete <ref> --json # Delete and return status as JSON ``` Alias: `tw message` works the same as `tw msg`. ## Search ```bash tw mentions # Show content mentioning current user tw mentions --since 2026-04-01 --all # Fetch every mention since a date tw mentions --type threads --json # Limit mentions to threads tw search "query" # Search content tw search "query" --type threads # Filter: threads, messages, or all tw search "query" --author <ref> # Filter by author tw search "query" --to <ref> # Messages sent to user tw search "query" --title-only # Search thread titles only tw search "query" --mention-me # Results mentioning current user tw search "query" --conversation <refs> # Limit to conversations (comma-separated refs) tw search "query" --since <date> # Content from date tw search "query" --until <date> # Content until date tw search "query" --channel <refs> # Filter by channel refs (comma-separated) tw search "query" --limit <n> # Max results (default: 50) tw search "query" --cursor <cur> # Pagination cursor tw search "query" --all # Fetch all result pages ``` ## Users, Channels & Groups ```bash tw user # Show current user info tw user --json # JSON output tw user --json --full # Include all fields in JSON output tw users # List active workspace users tw users --search <text> # Filter by name/email tw users --include-removed # Include users removed from the workspace tw channels # List active joined workspace channels (alias of: tw channel list) tw channels --state all # Include archived joined channels too tw channels --scope discoverable # Active public channels you can see but have not joined tw channels --scope public --state all --json # All visible public channels, with joined status tw channel threads <channel-ref> # List threads in a channel (fuzzy name, id:, numeric ID, or URL) tw channel threads "general" --unread # Only unread threads tw channel threads <ref> --archive-filter all # Include archived threads (active|archived|all) tw channel threads <ref> --since 2026-01-01 # Filter by last-updated date (ISO) tw channel threads <ref> --limit 20 # Max threads per page (default: 50) tw channel threads <ref> --limit 20 --cursor <cursor-from-prev> # Paginate tw channel threads <ref> --json # { results, nextCursor } with isUnread + url tw channel create "Name" # Create a new (public) channel in the default/current workspace tw channel create "Name" --workspace <ref> # Target a different workspace tw channel create "Name" --private # Create a private channel tw channel create "Name" --description "..." # Set channel description tw channel create "Name" --json --full # Output created channel as JSON (all fields) tw channel delete <channel-ref> --yes # Delete a channel (requires --yes; usually admin-only on Twist) tw channel delete <ref> --workspace <ref> --yes # Target a different workspace tw channel delete <ref> --dry-run # Preview deletion tw channel archive <channel-ref> # Archive a channel (no-op if already archived) tw channel unarchive id:<id> # Unarchive a channel (pass id:/numeric ref for archived channels) tw channel members <channel-ref> # List members + groups whose membership ⊆ channel tw channel members <channel-ref> --json # JSON with id, name, members, groupsFullyInChannel tw channel members add <channel-ref> <ref...> # Add users and/or group:<ref> (group expansion is one-shot) tw channel members add <channel-ref> alice group:Frontend # Mix of user refs and group: prefix tw channel members add <channel-ref> id:123 --dry-run # Preview the diff tw channel members remove <channel-ref> <ref...> # Remove users and/or group:<ref> tw channel members set <channel-ref> <ref...> # Replace membership; dry-run by default tw channel members set <channel-ref> group:Squad --apply # Mutate. Refuses to remove self unless --include-self tw groups # List workspace groups tw groups --search "frontend" # Filter groups by name (case-insensitive) tw groups --json # JSON output tw groups --json --full # Include all fields in JSON output tw groups view <group-ref> # Show group with member details tw groups view <ref> --json # JSON output with id, name, workspaceId, members tw groups view <ref> --json --full # Include all fields in JSON output tw groups create "Name" # Create a new group tw groups create "Name" --users alice@doist.com,bob@doist.com # Create with members tw groups create "Name" --json # Output created group as JSON tw groups rename <group-ref> "New name" # Rename a group tw groups rename <ref> "Name" --json # Output renamed group as JSON tw groups delete <group-ref> --yes # Delete a group (requires --yes) tw groups delete <ref> --dry-run # Preview deletion tw groups add-user <group-ref> user1 user2 # Add users to a group tw groups add-user <ref> a@d.com,b@d.com # Comma-separated refs tw groups add-user <ref> id:123 --json # Output result as JSON tw groups remove-user <group-ref> user1 user2 # Remove users from a group tw groups remove-user <ref> id:123,id:456 # Comma-separated ID refs ``` If a channel is not found in `tw channels`, widen with broader listings such as `tw channels --scope public`, then `tw channels --scope public --state all`. Check `tw channels --help` for other available filters. `tw channel threads` returns every thread in the channel; pagination filters (`--limit`, `--cursor`, `--since`, `--until`, `--unread`) are applied client-side after fetch. `--archive-filter` is applied server-side. Results are sorted newest-first by last activity. In `--json` / `--ndjson`, the response includes a `nextCursor` string (opaque) you can pass via `--cursor` to fetch the next page; NDJSON emits the cursor as a final `{ "_meta": true, "nextCursor": "..." }` line. `tw channel members add`, `remove`, and `set` accept user refs (id:N, email, name) and `group:<ref>` mixed in any order. Groups are expanded to their current users at call time — the group is **not** persistently linked to the channel, so users added later to the group will not auto-join. `set` replaces the channel's membership with the resolved ref set; it is dry-run by default, pass `--apply` to mutate and `--include-self` to allow the diff to remove the acting user. `tw channel members` (with no subcommand) shows the user list plus a "groups fully in channel" hint — groups whose entire membership is currently present in the channel. ## Away Status ```bash tw away # Show current away status tw away set <type> [until] # Set away (type: vacation, parental, sickleave, other) tw away set vacation 2026-03-20 # Away until March 20 tw away set vacation 2026-03-20 --from 2026-03-15 # Custom start date tw away clear # Clear away status ``` ## Reactions ```bash tw react thread <ref> 👍 # Add reaction to thread tw react comment <ref> +1 # Add reaction (shortcode) tw react message <ref> heart # Add reaction to DM message tw react thread <ref> 👍 --json # Output result as JSON tw unreact thread <ref> 👍 # Remove reaction tw unreact thread <ref> 👍 --json # Output result as JSON ``` Supported shortcodes: +1, -1, heart, tada, smile, laughing, thinking, fire, check, x, eyes, pray, clap, rocket, wave ## Shell Completions ```bash tw completion install # Install tab completions (prompts for shell) tw completion install bash # Install for specific shell tw completion install zsh tw completion install fish tw completion uninstall # Remove completions ```
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub