Releases: krodak/clickup-cli
v1.23.1
Bug fixes
Custom field display for dropdowns and labels
cup task <id> now correctly renders dropdown and labels custom field values instead of showing raw orderindex numbers or UUIDs.
The CustomField.type_config.options[].id field was typed as number but ClickUp's API returns string UUIDs. interactive.ts was doing a broken o.id === Number(field.value) comparison that never matched, so users saw the raw stored value (e.g. 2) instead of the option name (e.g. "High"). Dropdowns now match on orderindex (which is what the API actually stores as the value), and labels match on the string option IDs.
bulk status I/O correctness
cup bulk status <status> <taskIds...> was writing failure messages to stdout. Piping the command (cup bulk status done t1 t2 > ids.txt) would route error lines into the output file. Fixed by routing through the shared outputBulkResult helper that every other bulk subcommand already uses - failures now go to stderr.
Safety improvements
Config file validators
~/.config/cup/config.json is user-editable. Previously the parser used unchecked as FiltersMap / as FavoritesMap casts, so a malformed entry (e.g. filter.command as a string instead of an array) could crash cup filter run with an opaque error. The parser now validates entry shapes and silently drops malformed ones, preserving the rest of the config.
Code quality refactors
runInBatches discriminated union
The bulk operation helper at src/util/batch.ts now returns {item, ok: true, result} | {item, ok: false, error} instead of a struct with two optional fields. This eliminates nonsense states and gives proper TypeScript narrowing. Moved out of src/commands/bulk.ts into a general-purpose util. Added a validation that concurrency is a positive integer.
Shared type guards
isRecord was duplicated identically in src/api.ts and src/config.ts. Deduplicated into src/util/guards.ts.
Minor type cleanups
VALID_TYPESinsrc/commands/favorite.tsis now inferred asSet<FavoriteType>instead of widened toReadonlySet<string>VALID_GROUP_BY_FIELDSinsrc/commands/view-update.tsis aSetnow, eliminating the awkwardas (typeof VALID_GROUP_BY_FIELDS)[number]cast onincludes()
What's not in this release
Large refactors flagged in code review but deferred to future releases:
- Shell completion rewrite (zsh/fish completions drift every release; proper fix is metadata-driven generation)
bulksubcommand pattern normalization (mixed positional/flag style is a breaking change)request<T>generic architecture (mix of runtime validation and generic trust creates redundant casts)
1013 tests (990 -> 1013).
v1.23.0
Rename commands
Three new top-level commands for renaming workspace containers:
cup list-rename <listId> <newName>
cup folder-rename <folderId> <newName>
cup space-rename <spaceId> <newName>The underlying updateList API method was extended to accept name and content fields alongside the existing statuses support, remaining backward compatible with the status-copy feature. New updateFolder and updateSpace methods call PUT /folder/{id} and PUT /space/{id} respectively.
Bulk move
Batch move multiple tasks to a single destination list:
cup bulk move task1 task2 task3 --to listIdUses the v3 home_list endpoint (from @plainlystated's contribution in #41) which handles status mapping automatically when the destination list has different statuses than the source. Runs up to 5 concurrent requests.
Inline custom fields on task creation
cup create --field now sets custom field values directly during task creation, avoiding the two-step create-then-set-field flow:
cup create --name "Bug: login timeout" --list abc123 \\
--field "Story Points" 3 \\
--field "Priority Labels" "High, Frontend"Field names are resolved from the target list's custom fields in a single API call, then included in the task creation payload. Works with all supported field types (text, number, dropdown, labels, checkbox, date, url, email, emoji/rating, manual_progress, tasks, users).
Housekeeping
- Pre-existing Prettier format drift in 7 files was cleaned up (`src/commands/bulk.ts`, `src/index.ts`, test files). `npm run format:check` now passes on main.
989 unit tests (6 new for rename, 4 for bulk move, 2 for create --field inline).
v1.22.2
Automated version synchronization
scripts/sync-command-docs.ts now updates every version-tracked file from package.json, not just docs/commands.md:
skills/clickup-cli/SKILL.mdheader (previously went stale)skills/clickup-cli/SKILL.md"Version check" hint.claude-plugin/plugin.jsonversion fielddocs/commands.mdquick reference (existing behavior)
The release flow is now two commands instead of three manual file edits:
npm version <version> --no-git-tag-version
node --import tsx scripts/sync-command-docs.tsDrift detection in CI
A new test in tests/unit/scripts/sync-command-docs.test.ts verifies that package.json, plugin.json, and both SKILL.md version lines stay in sync. CI fails loudly if a release forgets a file.
Updated development docs
AGENTS.md and .agents/skills/releasing-clickup-cli now describe the automated sync flow. The "update SKILL.md version header" manual checklist item has been removed.
977 unit tests (3 new version-sync drift tests).
v1.22.1
Easier onboarding
cup init now explains where to get a ClickUp API token instead of just prompting for one:
Welcome to ClickUp CLI!
How to get a ClickUp API token:
1. Open https://app.clickup.com/settings/apps
2. Find the "API Token" section, click "Generate" (or copy the existing one)
3. The token starts with "pk_"
Paste your ClickUp API token (starts with pk_):
After successful setup, next-step hints are printed:
Next steps:
cup auth # verify setup
cup tasks # list your assigned tasks
cup sprint # show current sprint
cup --help # see all commands
Better error messages for agents
cup init now detects non-interactive (piped) stdin and prints a helpful error pointing to the --token and --team flags instead of hanging or crashing:
cup init requires an interactive terminal.
For scripts, CI, or AI agents, use flags:
cup init --token pk_YOUR_TOKEN --team YOUR_TEAM_ID
Or set environment variables:
export CU_API_TOKEN=pk_YOUR_TOKEN
export CU_TEAM_ID=YOUR_TEAM_ID
Invalid token errors now include the ClickUp settings URL. Missing config errors point to cup init with both interactive and non-interactive examples.
Clearer README for AI agents
The "For AI Agents" section now tells the agent exactly what to do: fetch the SKILL.md (which contains the full bootstrap guide), install the CLI, walk the user through getting a token, run cup init, and install the skill persistently with cup skill.
974 unit tests.
v1.22.0
Expanded custom field type support
Four more field types now supported by cup field --set and cup update --field:
cup field abc123 --set "Rating" 3 # emoji/rating (0-5)
cup field abc123 --set "Progress" 75 # manual_progress (0-100)
cup field abc123 --set "Related Tasks" "task1, task2" # tasks relationship
cup field abc123 --set "Reviewers" "123, 456" # users/peopleFull supported types: text, short_text, number, currency, phone, drop_down, labels, checkbox, date, url, email, emoji/rating, manual_progress, tasks, users.
Change task type after creation
cup update --type accepts either a numeric custom_item_id or a type name (resolved via workspace task types):
cup update abc123 --type Initiative
cup update abc123 --type 1001Parallel bulk operations
All cup bulk subcommands (status, assign, due-date, tag) now run up to 5 requests in parallel instead of sequentially. 5x faster for large batches. Partial failures are collected and reported.
New bulk subcommands
cup bulk priority task1 task2 task3 --to urgent
cup bulk field task1 task2 task3 --set "Story Points" 5Multiple assignees at once
cup assign now accepts comma-separated user IDs:
cup assign abc123 --to user1,user2,user3
cup assign abc123 --remove user1,user2
cup assign abc123 --to "me,12345"--archived flag for listing commands
Browse archived items in cup spaces, cup lists, and cup folders:
cup spaces --archived
cup lists space123 --archived
cup folders space123 --archived970 unit tests, 120 e2e tests.
v1.21.1
Dependency updates
- @inquirer/prompts 8.3.2 -> 8.4.0
- dotenv 17.3.1 -> 17.4.1
- vitest 4.1.2 -> 4.1.3
- eslint 10.1.0 -> 10.2.0
- @types/node 25.5.0 -> 25.5.2
937 unit tests, 116 e2e tests.
v1.21.0
Labels custom field support
cup field now supports the labels (multi-select) custom field type. Pass comma-separated label names:
cup field abc123 --set "Priority" "High, Medium"
cup field abc123 --set "Tags" "Backend"
cup field abc123 --remove "Priority"Label names are resolved case-insensitively against the field's configured options. Invalid names show available options in the error message.
Supported field types: text, short_text, number, currency, phone, drop_down, labels, checkbox, date, url, email.
Fixes #47.
937 unit tests, 116 e2e tests.
v1.20.1
v3 API for moving task home list
When using cup move --to <list> --remove <list>, the CLI now uses the v3 PUT /workspaces/{id}/tasks/{id}/home_list/{id} endpoint instead of the v2 add/remove approach. This fixes the "Task home list cannot be altered" error that occurred when trying to change a task's primary list.
Status mappings are automatically built when the task's current status doesn't exist in the destination list.
Thanks to @plainlystated for the contribution (#41).
Dependency updates
- vitest 4.1.1 -> 4.1.2 (CVE fix for flatted, sequential mock/unmock resolution)
- typescript-eslint 8.57.2 -> 8.58.0 (TypeScript 6 support)
933 tests.
v1.20.0
Non-interactive setup for AI agents
cup init now supports --token and --team flags for non-interactive configuration:
cup init --token pk_YOUR_TOKEN --team YOUR_TEAM_ID
cup auth # verifyThis enables AI agents, CI pipelines, and scripts to configure the CLI without interactive prompts. The existing interactive flow (cup init without flags) is unchanged.
Updated skill documentation
SKILL.md now includes complete bootstrap instructions: prerequisites, installation, API token setup, configuration (interactive, non-interactive, and env var paths), and verification. An AI agent reading only the skill file can now set up a user from zero.
934 tests.
v1.19.5
Code quality refactors
Three design debt items resolved from code review:
Sprint folder resolution deduplication - Extracted resolveSprintFolderId helper in sprint.ts to eliminate identical logic duplicated between resolveActiveSprintListId and runSprintCommand.
Config/ProfileData type separation - Config interface no longer declares favorites and filters fields that loadConfig() never populated. A new ProfileData type handles per-profile storage including favorites and filters. Fixes a misleading type contract.
comment-delete --task flag - Task-scoped comment deletion now uses --task <taskId> instead of overloading the <commentId> positional:
# Before (confusing - same arg means different things)
cup comment-delete <taskId> --mine
# After (clear)
cup comment-delete --task <taskId> --mine
cup comment-delete --task <taskId> --mine --match "text"
# Direct comment deletion unchanged
cup comment-delete <commentId>E2E test coverage: 67% -> 98%
38 new e2e tests across 5 files covering dependencies, links, threaded comments, custom fields, space tags, folder/list CRUD, checklist items, time entries, space creation, view scopes, statuses, templates, and more. Free-plan limitations handled gracefully.
929 unit tests, 112 e2e tests.