@krodak/clickup-cli 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "clickup-cli",
3
- "description": "Claude Code skills for the cu (ClickUp CLI) tool - manage tasks, sprints, initiatives, and comments",
4
- "version": "0.6.1",
3
+ "description": "ClickUp CLI skills for managing tasks, sprints, comments, checklists, custom fields, tags, and time tracking via the cu command",
4
+ "version": "0.16.0",
5
5
  "author": {
6
6
  "name": "Krzysztof Rodak"
7
7
  },
package/README.md CHANGED
@@ -13,7 +13,7 @@ npm install -g @krodak/clickup-cli && cu init
13
13
 
14
14
  ## Talk to your agent
15
15
 
16
- Install `cu`, install the skill file, and your agent works with ClickUp. No API knowledge needed.
16
+ Install the CLI, add the skill file to your agent, and it works with ClickUp. No API knowledge needed.
17
17
 
18
18
  > **"Read task abc123, do the work, then mark it in review and leave a comment with the commit hash."**
19
19
 
@@ -27,188 +27,249 @@ Install `cu`, install the skill file, and your agent works with ClickUp. No API
27
27
 
28
28
  The agent reads the skill file, picks the right `cu` commands, and handles everything. You don't need to learn the CLI - the agent does.
29
29
 
30
- ## Setup
30
+ ## Install
31
31
 
32
32
  You need Node 22+ and a ClickUp personal API token (`pk_...` from [ClickUp Settings > Apps](https://app.clickup.com/settings/apps)).
33
33
 
34
34
  <details open>
35
- <summary>&nbsp;<img src="https://cdn.simpleicons.org/openai/999999" height="16" align="center">&nbsp;<strong>OpenCode</strong></summary>
36
-
37
- **1. Install the CLI**
35
+ <summary>&nbsp;<img src="https://img.shields.io/badge/npm-CB3837?logo=npm&logoColor=white" height="18" align="center">&nbsp;<strong>npm</strong></summary>
38
36
 
39
37
  ```bash
40
38
  npm install -g @krodak/clickup-cli
41
39
  cu init
42
40
  ```
43
41
 
44
- **2. Install the skill**
42
+ </details>
43
+
44
+ <details>
45
+ <summary>&nbsp;<img src="https://img.shields.io/badge/Homebrew-FBB040?logo=homebrew&logoColor=black" height="18" align="center">&nbsp;<strong>Homebrew</strong></summary>
45
46
 
46
47
  ```bash
47
- mkdir -p ~/.config/opencode/skills/clickup
48
- cp $(npm root -g)/@krodak/clickup-cli/skills/clickup-cli/SKILL.md ~/.config/opencode/skills/clickup/SKILL.md
48
+ brew tap krodak/tap
49
+ brew install clickup-cli
50
+ cu init
49
51
  ```
50
52
 
51
53
  </details>
52
54
 
53
- <details>
54
- <summary>&nbsp;<img src="https://cdn.simpleicons.org/anthropic/D97757" height="16" align="center">&nbsp;<strong>Claude Code</strong></summary>
55
+ ## Set up your agent
56
+
57
+ The package includes a [skill file](https://agentskills.io) that teaches agents all available commands and when to use them. All three major coding agents support skills natively:
58
+
59
+ <details open>
60
+ <summary>&nbsp;<img src="https://img.shields.io/badge/Claude_Code-D97757?logo=anthropic&logoColor=white" height="18" align="center">&nbsp;<strong>Claude Code</strong></summary>
55
61
 
56
- **1. Install the CLI**
62
+ **Install as a [plugin](https://docs.anthropic.com/en/docs/claude-code/plugins)** (recommended):
57
63
 
58
64
  ```bash
59
- npm install -g @krodak/clickup-cli
60
- cu init
65
+ claude plugin add $(npm root -g)/@krodak/clickup-cli
61
66
  ```
62
67
 
63
- **2. Install the skill**
68
+ This registers the skill under the `clickup-cli:` namespace. Claude loads it automatically when you work with ClickUp tasks.
69
+
70
+ **Or install as a personal skill** (no namespace prefix):
64
71
 
65
72
  ```bash
73
+ SKILL=$(npm root -g)/@krodak/clickup-cli/skills/clickup-cli
66
74
  mkdir -p ~/.claude/skills/clickup
67
- cp $(npm root -g)/@krodak/clickup-cli/skills/clickup-cli/SKILL.md ~/.claude/skills/clickup/SKILL.md
75
+ cp "$SKILL/SKILL.md" ~/.claude/skills/clickup/SKILL.md
68
76
  ```
69
77
 
70
- Then reference it in your `CLAUDE.md` or project instructions.
71
-
72
78
  </details>
73
79
 
74
80
  <details>
75
- <summary>&nbsp;<img src="https://cdn.simpleicons.org/anthropic/D97757" height="16" align="center">&nbsp;<strong>Claude Desktop</strong></summary>
81
+ <summary>&nbsp;<img src="https://img.shields.io/badge/Codex-412991?logo=openai&logoColor=white" height="18" align="center">&nbsp;<strong>Codex</strong></summary>
76
82
 
77
- Claude Desktop doesn't run CLI tools directly. Use it alongside a coding agent (Claude Code, OpenCode) that has `cu` installed, or run `cu` commands manually in your terminal.
83
+ Codex supports [agent skills](https://developers.openai.com/codex/skills) across CLI, IDE extension, and web. Skills use the same `SKILL.md` format with YAML frontmatter.
78
84
 
79
- **Install the CLI:**
85
+ **Install as a user skill** (available across all your projects):
80
86
 
81
87
  ```bash
82
- npm install -g @krodak/clickup-cli
83
- cu init
88
+ SKILL=$(npm root -g)/@krodak/clickup-cli/skills/clickup-cli
89
+ mkdir -p ~/.agents/skills/clickup
90
+ cp "$SKILL/SKILL.md" ~/.agents/skills/clickup/SKILL.md
84
91
  ```
85
92
 
86
- </details>
87
-
88
- <details>
89
- <summary>&nbsp;<img src="https://cdn.simpleicons.org/homebrew/FBB040" height="16" align="center">&nbsp;<strong>Homebrew</strong></summary>
93
+ **Or install as a project skill** (checked into your repo):
90
94
 
91
95
  ```bash
92
- brew tap krodak/tap
93
- brew install clickup-cli
94
- cu init
96
+ SKILL=$(npm root -g)/@krodak/clickup-cli/skills/clickup-cli
97
+ mkdir -p .agents/skills/clickup
98
+ cp "$SKILL/SKILL.md" .agents/skills/clickup/SKILL.md
95
99
  ```
96
100
 
97
- Then install the skill for your agent (see OpenCode or Claude Code sections above).
101
+ You can also use the built-in installer: `$skill-installer clickup`
98
102
 
99
103
  </details>
100
104
 
101
105
  <details>
102
- <summary>&nbsp;<img src="https://cdn.simpleicons.org/openai/999999" height="16" align="center">&nbsp;<strong>Codex / Other agents</strong></summary>
103
-
104
- **1. Install the CLI**
106
+ <summary>&nbsp;<img src="https://img.shields.io/badge/OpenCode-24292e?logoColor=white" height="18" align="center">&nbsp;<strong>OpenCode</strong></summary>
105
107
 
106
108
  ```bash
107
- npm install -g @krodak/clickup-cli
108
- cu init
109
+ SKILL=$(npm root -g)/@krodak/clickup-cli/skills/clickup-cli
110
+ mkdir -p ~/.config/opencode/skills/clickup
111
+ cp "$SKILL/SKILL.md" ~/.config/opencode/skills/clickup/SKILL.md
109
112
  ```
110
113
 
111
- **2. Add the skill to your agent**
114
+ </details>
115
+
116
+ <details>
117
+ <summary>&nbsp;<strong>Other agents</strong></summary>
112
118
 
113
- Copy `skills/clickup-cli/SKILL.md` into your agent's system prompt or project instructions. It's a standalone markdown document that teaches the agent all available commands.
119
+ The skill file follows the [Agent Skills](https://agentskills.io) open standard. Copy `skills/clickup-cli/SKILL.md` into your agent's skill directory, system prompt, or `AGENTS.md`.
114
120
 
115
121
  </details>
116
122
 
117
- ## Commands
123
+ ## API Coverage
124
+
125
+ [Full command reference with examples and flags](docs/commands.md).
118
126
 
119
- 36 commands total. [Full reference with examples and flags](docs/commands.md).
127
+ Status: :white_check_mark: implemented | :construction: planned | :no_entry_sign: won't add
120
128
 
121
129
  ### Tasks
122
130
 
123
- | Command | Description |
124
- | --------------------- | ----------------------------------------------------------- |
125
- | `cu tasks` | List my tasks (filter by status, name, type, list, space) |
126
- | `cu task <id>` | Task details with custom fields and checklists |
127
- | `cu subtasks <id>` | List subtasks of a task |
128
- | `cu create` | Create a task or subtask |
129
- | `cu update <id>` | Update task fields (status, name, priority, assignee, etc.) |
130
- | `cu delete <id>` | Delete a task (requires confirmation) |
131
- | `cu assign <id>` | Assign/unassign users |
132
- | `cu depend <id>` | Add/remove task dependencies |
133
- | `cu move <id>` | Add/remove task from lists |
134
- | `cu open <query>` | Open task in browser by ID or name |
135
- | `cu search <query>` | Search my tasks by name |
136
- | _`cu duplicate <id>`_ | _Copy a task - coming soon_ |
137
- | _`cu bulk`_ | _Bulk task operations - coming soon_ |
131
+ | Feature | Command | Status |
132
+ | -------------------- | ---------------------- | ------------------ |
133
+ | List my tasks | `cu tasks` | :white_check_mark: |
134
+ | Get task details | `cu task <id>` | :white_check_mark: |
135
+ | Create task | `cu create` | :white_check_mark: |
136
+ | Update task | `cu update <id>` | :white_check_mark: |
137
+ | Delete task | `cu delete <id>` | :white_check_mark: |
138
+ | Search tasks | `cu search <query>` | :white_check_mark: |
139
+ | Open in browser | `cu open <query>` | :white_check_mark: |
140
+ | List subtasks | `cu subtasks <id>` | :white_check_mark: |
141
+ | Assign / unassign | `cu assign <id>` | :white_check_mark: |
142
+ | Duplicate task | `cu duplicate <id>` | :construction: |
143
+ | Create from template | `cu create --template` | :construction: |
144
+ | Bulk operations | `cu bulk` | :construction: |
145
+
146
+ ### Dependencies & Relations
147
+
148
+ | Feature | Command | Status |
149
+ | -------------------- | ------------------------- | ------------------ |
150
+ | Add dependency | `cu depend <id>` | :white_check_mark: |
151
+ | Remove dependency | `cu depend <id> --remove` | :white_check_mark: |
152
+ | Add/remove task link | `cu link <id> <linksTo>` | :white_check_mark: |
153
+
154
+ ### Multi-list
155
+
156
+ | Feature | Command | Status |
157
+ | ---------------- | ----------------------- | ------------------ |
158
+ | Add task to list | `cu move <id> --add` | :white_check_mark: |
159
+ | Remove from list | `cu move <id> --remove` | :white_check_mark: |
138
160
 
139
161
  ### Sprints & Planning
140
162
 
141
- | Command | Description |
142
- | ------------- | ----------------------------------------------- |
143
- | `cu sprint` | My tasks in the active sprint (auto-detected) |
144
- | `cu sprints` | List all sprints |
145
- | `cu assigned` | All my tasks grouped by status |
146
- | `cu summary` | Standup helper: completed, in progress, overdue |
147
- | `cu overdue` | Tasks past their due date |
148
- | `cu inbox` | Recently updated tasks |
163
+ | Feature | Command | Status |
164
+ | ------------------------ | ------------- | ------------------ |
165
+ | Active sprint tasks | `cu sprint` | :white_check_mark: |
166
+ | List all sprints | `cu sprints` | :white_check_mark: |
167
+ | Assigned tasks by status | `cu assigned` | :white_check_mark: |
168
+ | Standup summary | `cu summary` | :white_check_mark: |
169
+ | Overdue tasks | `cu overdue` | :white_check_mark: |
170
+ | Recently updated | `cu inbox` | :white_check_mark: |
149
171
 
150
172
  ### Comments
151
173
 
152
- | Command | Description |
153
- | -------------------------- | -------------------------------- |
154
- | `cu comment <id>` | Post a comment on a task |
155
- | `cu comments <id>` | List comments on a task |
156
- | `cu comment-edit <id>` | Edit an existing comment |
157
- | `cu activity <id>` | Task details + comments combined |
158
- | _`cu comment-delete <id>`_ | _Delete a comment - coming soon_ |
174
+ | Feature | Command | Status |
175
+ | ------------------------ | ----------------------------------- | ------------------ |
176
+ | List comments | `cu comments <id>` | :white_check_mark: |
177
+ | Post comment | `cu comment <id>` | :white_check_mark: |
178
+ | Edit comment | `cu comment-edit <id>` | :white_check_mark: |
179
+ | Task + comments combined | `cu activity <id>` | :white_check_mark: |
180
+ | Delete comment | `cu comment-delete <id>` | :white_check_mark: |
181
+ | Threaded replies | `cu replies <id>` / `cu reply <id>` | :white_check_mark: |
159
182
 
160
- ### Custom Fields
183
+ ### Checklists
161
184
 
162
- | Command | Description |
163
- | ---------------------- | ----------------------------------------------------------------------------------- |
164
- | `cu field <id>` | Set/remove custom field values (text, number, dropdown, date, checkbox, url, email) |
165
- | _`cu fields <listId>`_ | _List available custom fields for a list - coming soon_ |
185
+ | Feature | Command | Status |
186
+ | ---------------- | ---------------------------------------- | ------------------ |
187
+ | View checklists | `cu checklist view <id>` | :white_check_mark: |
188
+ | Create checklist | `cu checklist create <id> <name>` | :white_check_mark: |
189
+ | Delete checklist | `cu checklist delete <id>` | :white_check_mark: |
190
+ | Add item | `cu checklist add-item <id> <name>` | :white_check_mark: |
191
+ | Edit item | `cu checklist edit-item <id> <itemId>` | :white_check_mark: |
192
+ | Delete item | `cu checklist delete-item <id> <itemId>` | :white_check_mark: |
166
193
 
167
- ### Checklists
194
+ ### Custom Fields
168
195
 
169
- | Command | Description |
170
- | ---------------------------------------- | ------------------------------------------------ |
171
- | `cu checklist view <id>` | View all checklists on a task |
172
- | `cu checklist create <id> <name>` | Create a checklist |
173
- | `cu checklist delete <id>` | Delete a checklist |
174
- | `cu checklist add-item <id> <name>` | Add item to a checklist |
175
- | `cu checklist edit-item <id> <itemId>` | Edit a checklist item (name, resolved, assignee) |
176
- | `cu checklist delete-item <id> <itemId>` | Delete a checklist item |
196
+ | Feature | Command | Status |
197
+ | --------------------- | ------------------------ | ------------------ |
198
+ | Set field value | `cu field <id> --set` | :white_check_mark: |
199
+ | Remove field value | `cu field <id> --remove` | :white_check_mark: |
200
+ | List available fields | `cu fields <listId>` | :construction: |
177
201
 
178
202
  ### Tags
179
203
 
180
- | Command | Description |
181
- | --------------------- | --------------------------------------------------- |
182
- | `cu tag <id>` | Add/remove tags on a task |
183
- | _`cu tags <spaceId>`_ | _List/create/delete space-level tags - coming soon_ |
204
+ | Feature | Command | Status |
205
+ | ----------------------- | ------------------- | ------------------ |
206
+ | Add/remove tag on task | `cu tag <id>` | :white_check_mark: |
207
+ | List space tags | `cu tags <spaceId>` | :construction: |
208
+ | Create/delete space tag | | :construction: |
209
+
210
+ ### Time Tracking
211
+
212
+ | Feature | Command | Status |
213
+ | -------------- | ----------------------------- | ------------------ |
214
+ | Start timer | `cu time start <id>` | :white_check_mark: |
215
+ | Stop timer | `cu time stop` | :white_check_mark: |
216
+ | Timer status | `cu time status` | :white_check_mark: |
217
+ | Log time entry | `cu time log <id> <duration>` | :white_check_mark: |
218
+ | List entries | `cu time list` | :white_check_mark: |
219
+ | Update entry | `cu time update <id>` | :construction: |
220
+ | Delete entry | `cu time delete <id>` | :construction: |
184
221
 
185
222
  ### Workspace
186
223
 
187
- | Command | Description |
188
- | ------------------------ | ----------------------------------------- |
189
- | `cu spaces` | List workspace spaces |
190
- | `cu lists <spaceId>` | Lists in a space (including folder lists) |
191
- | `cu auth` | Check authentication status |
192
- | _`cu folders <spaceId>`_ | _List folders in a space - coming soon_ |
193
- | _`cu members`_ | _List workspace members - coming soon_ |
224
+ | Feature | Command | Status |
225
+ | ------------ | ---------------------- | ------------------ |
226
+ | List spaces | `cu spaces` | :white_check_mark: |
227
+ | List lists | `cu lists <spaceId>` | :white_check_mark: |
228
+ | Check auth | `cu auth` | :white_check_mark: |
229
+ | List folders | `cu folders <spaceId>` | :construction: |
230
+ | List members | `cu members` | :construction: |
194
231
 
195
- ### Time Tracking
232
+ ### Goals & Key Results
233
+
234
+ | Feature | Command | Status |
235
+ | ------------------ | ---------- | -------------- |
236
+ | List goals | `cu goals` | :construction: |
237
+ | Create/update goal | | :construction: |
238
+ | Key results CRUD | | :construction: |
239
+
240
+ ### Docs
241
+
242
+ | Feature | Command | Status |
243
+ | ----------------- | ----------------- | -------------- |
244
+ | Search docs | `cu docs <query>` | :construction: |
245
+ | View page content | `cu doc <id>` | :construction: |
246
+
247
+ ### Attachments
248
+
249
+ | Feature | Command | Status |
250
+ | ---------------- | ----------------------- | -------------- |
251
+ | Upload file | `cu attach <id> <file>` | :construction: |
252
+ | List attachments | | :construction: |
253
+
254
+ ### :no_entry_sign: Won't add
196
255
 
197
- | Command | Description |
198
- | ----------------------------- | ----------------------------------------------- |
199
- | `cu time start <id>` | Start tracking time on a task |
200
- | `cu time stop` | Stop the running timer |
201
- | `cu time status` | Show the currently running timer |
202
- | `cu time log <id> <duration>` | Log a manual time entry (e.g. "2h", "30m") |
203
- | `cu time list` | List recent time entries (default: last 7 days) |
256
+ | Feature | Why |
257
+ | --------------------- | --------------------------------------------------------------------------- |
258
+ | Webhooks | Server-side. A CLI can't listen for events. |
259
+ | OAuth flow | `cu init` already handles auth with API tokens. |
260
+ | Guest/ACL | Enterprise admin. Not what you reach for in a terminal. |
261
+ | Chat/DM | Use the ClickUp app. Chat doesn't belong in a CLI. |
262
+ | Audit logs | Enterprise admin. |
263
+ | User/group management | Too destructive for a CLI - removing someone from a workspace is permanent. |
264
+ | View CRUD | Views are visual layouts. Configure them in the UI. |
204
265
 
205
266
  ### Setup
206
267
 
207
- | Command | Description |
208
- | ----------------------- | --------------------------------- |
209
- | `cu init` | First-time setup wizard |
210
- | `cu config` | Get/set config values |
211
- | `cu completion <shell>` | Shell completions (bash/zsh/fish) |
268
+ | Feature | Command | Status |
269
+ | ----------------- | ----------------------- | ------------------ |
270
+ | First-time setup | `cu init` | :white_check_mark: |
271
+ | Get/set config | `cu config` | :white_check_mark: |
272
+ | Shell completions | `cu completion <shell>` | :white_check_mark: |
212
273
 
213
274
  ## Output Modes
214
275
 
package/dist/index.js CHANGED
@@ -204,6 +204,25 @@ var ClickUpClient = class {
204
204
  body: JSON.stringify(body)
205
205
  });
206
206
  }
207
+ async deleteComment(commentId) {
208
+ await this.request(`/comment/${commentId}`, { method: "DELETE" });
209
+ }
210
+ async getThreadedComments(commentId) {
211
+ const data = await this.request(`/comment/${commentId}/reply`);
212
+ return data.comments ?? [];
213
+ }
214
+ async createThreadedComment(commentId, text) {
215
+ await this.request(`/comment/${commentId}/reply`, {
216
+ method: "POST",
217
+ body: JSON.stringify({ comment_text: text })
218
+ });
219
+ }
220
+ async addTaskLink(taskId, linksTo) {
221
+ await this.request(`/task/${taskId}/link/${linksTo}`, { method: "POST" });
222
+ }
223
+ async deleteTaskLink(taskId, linksTo) {
224
+ await this.request(`/task/${taskId}/link/${linksTo}`, { method: "DELETE" });
225
+ }
207
226
  async getListCustomFields(listId) {
208
227
  const data = await this.request(`/list/${listId}/field`);
209
228
  return data.fields ?? [];
@@ -1808,7 +1827,7 @@ function bashCompletion() {
1808
1827
  cword=$COMP_CWORD
1809
1828
  fi
1810
1829
 
1811
- local commands="init auth tasks task update create sprint sprints subtasks comment comment-edit comments activity lists spaces inbox assigned open search summary overdue assign depend move field delete tag checklist time config completion"
1830
+ local commands="init auth tasks task update create sprint sprints subtasks comment comment-edit comment-delete comments replies reply activity lists spaces inbox assigned open search summary overdue assign depend link move field delete tag checklist time config completion"
1812
1831
 
1813
1832
  if [[ $cword -eq 1 ]]; then
1814
1833
  COMPREPLY=($(compgen -W "$commands --help --version" -- "$cur"))
@@ -1917,6 +1936,18 @@ function bashCompletion() {
1917
1936
  comment-edit)
1918
1937
  COMPREPLY=($(compgen -W "-m --message --resolved --unresolved --json" -- "$cur"))
1919
1938
  ;;
1939
+ comment-delete)
1940
+ COMPREPLY=($(compgen -W "--json" -- "$cur"))
1941
+ ;;
1942
+ replies)
1943
+ COMPREPLY=($(compgen -W "--json" -- "$cur"))
1944
+ ;;
1945
+ reply)
1946
+ COMPREPLY=($(compgen -W "-m --message --json" -- "$cur"))
1947
+ ;;
1948
+ link)
1949
+ COMPREPLY=($(compgen -W "--remove --json" -- "$cur"))
1950
+ ;;
1920
1951
  config)
1921
1952
  if [[ $cword -eq 2 ]]; then
1922
1953
  COMPREPLY=($(compgen -W "get set path" -- "$cur"))
@@ -1972,6 +2003,10 @@ _cu() {
1972
2003
  'checklist:Manage checklists on a task'
1973
2004
  'time:Track time on tasks'
1974
2005
  'comment-edit:Edit an existing comment'
2006
+ 'comment-delete:Delete a comment'
2007
+ 'replies:List threaded replies on a comment'
2008
+ 'reply:Reply to a comment'
2009
+ 'link:Add or remove a link between two tasks'
1975
2010
  'config:Manage CLI configuration'
1976
2011
  'completion:Output shell completion script'
1977
2012
  )
@@ -2262,6 +2297,29 @@ _cu() {
2262
2297
  '--unresolved[Mark comment as unresolved]' \\
2263
2298
  '--json[Force JSON output]'
2264
2299
  ;;
2300
+ comment-delete)
2301
+ _arguments \\
2302
+ '1:comment_id:' \\
2303
+ '--json[Force JSON output]'
2304
+ ;;
2305
+ replies)
2306
+ _arguments \\
2307
+ '1:comment_id:' \\
2308
+ '--json[Force JSON output]'
2309
+ ;;
2310
+ reply)
2311
+ _arguments \\
2312
+ '1:comment_id:' \\
2313
+ '(-m --message)'{-m,--message}'[Reply text]:text:' \\
2314
+ '--json[Force JSON output]'
2315
+ ;;
2316
+ link)
2317
+ _arguments \\
2318
+ '1:task_id:' \\
2319
+ '2:links_to:' \\
2320
+ '--remove[Remove the link instead of adding it]' \\
2321
+ '--json[Force JSON output]'
2322
+ ;;
2265
2323
  config)
2266
2324
  local -a config_cmds
2267
2325
  config_cmds=(
@@ -2331,6 +2389,10 @@ complete -c cu -n __fish_use_subcommand -a tag -d 'Add or remove tags from a tas
2331
2389
  complete -c cu -n __fish_use_subcommand -a checklist -d 'Manage checklists on a task'
2332
2390
  complete -c cu -n __fish_use_subcommand -a time -d 'Track time on tasks'
2333
2391
  complete -c cu -n __fish_use_subcommand -a comment-edit -d 'Edit an existing comment'
2392
+ complete -c cu -n __fish_use_subcommand -a comment-delete -d 'Delete a comment'
2393
+ complete -c cu -n __fish_use_subcommand -a replies -d 'List threaded replies on a comment'
2394
+ complete -c cu -n __fish_use_subcommand -a reply -d 'Reply to a comment'
2395
+ complete -c cu -n __fish_use_subcommand -a link -d 'Add or remove a link between two tasks'
2334
2396
  complete -c cu -n __fish_use_subcommand -a config -d 'Manage CLI configuration'
2335
2397
  complete -c cu -n __fish_use_subcommand -a completion -d 'Output shell completion script'
2336
2398
 
@@ -2463,6 +2525,16 @@ complete -c cu -n '__fish_seen_subcommand_from log; and __fish_seen_subcommand_f
2463
2525
  complete -c cu -n '__fish_seen_subcommand_from list; and __fish_seen_subcommand_from time' -l days -d 'Number of days to look back'
2464
2526
  complete -c cu -n '__fish_seen_subcommand_from list; and __fish_seen_subcommand_from time' -l task -d 'Filter by task ID'
2465
2527
 
2528
+ complete -c cu -n '__fish_seen_subcommand_from comment-delete' -l json -d 'Force JSON output'
2529
+
2530
+ complete -c cu -n '__fish_seen_subcommand_from replies' -l json -d 'Force JSON output'
2531
+
2532
+ complete -c cu -n '__fish_seen_subcommand_from reply' -s m -l message -d 'Reply text'
2533
+ complete -c cu -n '__fish_seen_subcommand_from reply' -l json -d 'Force JSON output'
2534
+
2535
+ complete -c cu -n '__fish_seen_subcommand_from link' -l remove -d 'Remove the link'
2536
+ complete -c cu -n '__fish_seen_subcommand_from link' -l json -d 'Force JSON output'
2537
+
2466
2538
  complete -c cu -n '__fish_seen_subcommand_from comment-edit' -s m -l message -d 'New comment text'
2467
2539
  complete -c cu -n '__fish_seen_subcommand_from comment-edit' -l resolved -d 'Mark comment as resolved'
2468
2540
  complete -c cu -n '__fish_seen_subcommand_from comment-edit' -l unresolved -d 'Mark comment as unresolved'
@@ -2775,8 +2847,46 @@ async function editComment(config, commentId, text, resolved) {
2775
2847
  await client.updateComment(commentId, text, resolved);
2776
2848
  }
2777
2849
 
2778
- // src/commands/time.ts
2850
+ // src/commands/comment-delete.ts
2851
+ async function deleteComment(config, commentId) {
2852
+ const client = new ClickUpClient(config);
2853
+ await client.deleteComment(commentId);
2854
+ }
2855
+
2856
+ // src/commands/replies.ts
2779
2857
  import chalk6 from "chalk";
2858
+ async function getReplies(config, commentId) {
2859
+ const client = new ClickUpClient(config);
2860
+ return client.getThreadedComments(commentId);
2861
+ }
2862
+ async function createReply(config, commentId, text) {
2863
+ if (!text.trim()) throw new Error("Reply text cannot be empty");
2864
+ const client = new ClickUpClient(config);
2865
+ await client.createThreadedComment(commentId, text);
2866
+ }
2867
+ function formatReplies(replies) {
2868
+ if (replies.length === 0) return "No replies";
2869
+ return replies.map((r) => {
2870
+ const user = r.user?.username ?? "Unknown";
2871
+ const date = new Date(Number(r.date)).toLocaleString();
2872
+ return `${chalk6.bold(user)} ${chalk6.dim(date)}
2873
+ ${r.comment_text}`;
2874
+ }).join("\n\n");
2875
+ }
2876
+
2877
+ // src/commands/link.ts
2878
+ async function manageTaskLink(config, taskId, linksTo, remove) {
2879
+ const client = new ClickUpClient(config);
2880
+ if (remove) {
2881
+ await client.deleteTaskLink(taskId, linksTo);
2882
+ return `Removed link between ${taskId} and ${linksTo}`;
2883
+ }
2884
+ await client.addTaskLink(taskId, linksTo);
2885
+ return `Linked ${taskId} to ${linksTo}`;
2886
+ }
2887
+
2888
+ // src/commands/time.ts
2889
+ import chalk7 from "chalk";
2780
2890
  function formatDuration2(ms) {
2781
2891
  const totalMinutes = Math.round(Math.abs(ms) / 6e4);
2782
2892
  const hours = Math.floor(totalMinutes / 60);
@@ -2828,8 +2938,8 @@ function formatTimeEntry(entry) {
2828
2938
  const isRunning = entry.duration < 0;
2829
2939
  const elapsed = isRunning ? Date.now() - Number(entry.start) : entry.duration;
2830
2940
  const durationStr = formatDuration2(elapsed);
2831
- const status = isRunning ? chalk6.green("RUNNING") : "";
2832
- lines.push(`${chalk6.bold(taskName)} ${chalk6.dim(taskId)} ${status}`);
2941
+ const status = isRunning ? chalk7.green("RUNNING") : "";
2942
+ lines.push(`${chalk7.bold(taskName)} ${chalk7.dim(taskId)} ${status}`);
2833
2943
  lines.push(
2834
2944
  ` ${durationStr} - ${formatTimestamp2(entry.start)}${entry.description ? ` - ${entry.description}` : ""}`
2835
2945
  );
@@ -2997,6 +3107,39 @@ program.command("comment-edit <commentId>").description("Edit an existing commen
2997
3107
  }
2998
3108
  )
2999
3109
  );
3110
+ program.command("comment-delete <commentId>").description("Delete a comment").option("--json", "Force JSON output even in terminal").action(
3111
+ wrapAction(async (commentId, opts) => {
3112
+ const config = loadConfig();
3113
+ await deleteComment(config, commentId);
3114
+ if (shouldOutputJson(opts.json ?? false)) {
3115
+ console.log(JSON.stringify({ success: true, commentId }, null, 2));
3116
+ } else {
3117
+ console.log(`Deleted comment ${commentId}`);
3118
+ }
3119
+ })
3120
+ );
3121
+ program.command("replies <commentId>").description("List threaded replies on a comment").option("--json", "Force JSON output even in terminal").action(
3122
+ wrapAction(async (commentId, opts) => {
3123
+ const config = loadConfig();
3124
+ const replies = await getReplies(config, commentId);
3125
+ if (shouldOutputJson(opts.json ?? false)) {
3126
+ console.log(JSON.stringify(replies, null, 2));
3127
+ } else {
3128
+ console.log(formatReplies(replies));
3129
+ }
3130
+ })
3131
+ );
3132
+ program.command("reply <commentId>").description("Reply to a comment").requiredOption("-m, --message <text>", "Reply text").option("--json", "Force JSON output even in terminal").action(
3133
+ wrapAction(async (commentId, opts) => {
3134
+ const config = loadConfig();
3135
+ await createReply(config, commentId, opts.message);
3136
+ if (shouldOutputJson(opts.json ?? false)) {
3137
+ console.log(JSON.stringify({ success: true, commentId }, null, 2));
3138
+ } else {
3139
+ console.log(`Replied to comment ${commentId}`);
3140
+ }
3141
+ })
3142
+ );
3000
3143
  program.command("activity <taskId>").description("Show task details and comments combined").option("--json", "Force JSON output even in terminal").action(
3001
3144
  wrapAction(async (taskId, opts) => {
3002
3145
  const config = loadConfig();
@@ -3097,6 +3240,25 @@ program.command("depend <taskId>").description("Add or remove task dependencies"
3097
3240
  }
3098
3241
  })
3099
3242
  );
3243
+ program.command("link <taskId> <linksTo>").description("Add or remove a link between two tasks").option("--remove", "Remove the link instead of adding it").option("--json", "Force JSON output even in terminal").action(
3244
+ wrapAction(
3245
+ async (taskId, linksTo, opts) => {
3246
+ const config = loadConfig();
3247
+ const result = await manageTaskLink(config, taskId, linksTo, opts.remove ?? false);
3248
+ if (shouldOutputJson(opts.json ?? false)) {
3249
+ console.log(
3250
+ JSON.stringify(
3251
+ { success: true, taskId, linksTo, action: opts.remove ? "removed" : "added" },
3252
+ null,
3253
+ 2
3254
+ )
3255
+ );
3256
+ } else {
3257
+ console.log(result);
3258
+ }
3259
+ }
3260
+ )
3261
+ );
3100
3262
  program.command("move <taskId>").description("Add or remove a task from a list").option("--to <listId>", "Add task to this list").option("--remove <listId>", "Remove task from this list").option("--json", "Force JSON output even in terminal").action(
3101
3263
  wrapAction(async (taskId, opts) => {
3102
3264
  const config = loadConfig();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@krodak/clickup-cli",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "ClickUp CLI for AI agents and humans",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: clickup
3
- description: 'Use when managing ClickUp tasks, sprints, or comments via the `cu` CLI tool. Triggers: task queries, status updates, sprint tracking, creating subtasks, posting comments, standup summaries, searching tasks, checking overdue items, assigning tasks, listing spaces and lists, opening tasks in browser, checking auth or config, setting custom fields, deleting tasks, managing tags, managing checklists, editing comments, time tracking.'
3
+ description: 'Use when managing ClickUp tasks, sprints, or comments via the `cu` CLI tool. Triggers: task queries, status updates, sprint tracking, creating subtasks, posting comments, threaded replies, standup summaries, searching tasks, checking overdue items, assigning tasks, listing spaces and lists, opening tasks in browser, checking auth or config, setting custom fields, deleting tasks, managing tags, managing checklists, editing comments, task links, time tracking.'
4
4
  ---
5
5
 
6
6
  # ClickUp CLI (`cu`)
@@ -73,6 +73,10 @@ All commands support `--help` for full flag details.
73
73
  | `cu checklist add-item <checklistId> <name> [--json]` | Add item to a checklist |
74
74
  | `cu checklist edit-item <checklistId> <itemId> [--name n] [--resolved] [--unresolved] [--assignee id] [--json]` | Edit a checklist item |
75
75
  | `cu checklist delete-item <checklistId> <itemId> [--json]` | Delete a checklist item |
76
+ | `cu comment-delete <commentId> [--json]` | Delete a comment |
77
+ | `cu replies <commentId> [--json]` | List threaded replies on a comment |
78
+ | `cu reply <commentId> -m text [--json]` | Reply to a comment |
79
+ | `cu link <taskId> <linksTo> [--remove] [--json]` | Add or remove link between tasks |
76
80
  | `cu time start <taskId> [-d desc] [--json]` | Start tracking time on a task |
77
81
  | `cu time stop [--json]` | Stop the running timer |
78
82
  | `cu time status [--json]` | Show currently running timer |
@@ -83,40 +87,43 @@ All commands support `--help` for full flag details.
83
87
 
84
88
  ## Quick Reference
85
89
 
86
- | Topic | Detail |
87
- | ----------------------- | ------------------------------------------------------------------------------------------------------ |
88
- | Task IDs | Stable alphanumeric strings (e.g. `abc123def`) |
89
- | `--type` | Filter by task type: `task` (regular), or custom type name/ID (e.g. `initiative`, `Bug`) |
90
- | `--list` on create | Optional when `--parent` is given (auto-detected) |
91
- | `--status` | Fuzzy matching: exact > starts-with > contains. Prints match to stderr. |
92
- | `--priority` | Names (`urgent`, `high`, `normal`, `low`) or numbers (1-4) |
93
- | `--due-date` | `YYYY-MM-DD` format |
94
- | `--assignee` | User ID or `me` (on `cu create`, `cu update`, `cu assign`) |
95
- | `--tags` | Comma-separated (e.g. `--tags "bug,frontend"`) |
96
- | `--time-estimate` | Duration format: `"2h"`, `"30m"`, `"1h30m"`, or raw milliseconds |
97
- | `--custom-item-id` | Custom task type ID for `cu create` (e.g. `1` for initiative) |
98
- | `--on` / `--blocks` | Task dependency direction (used with `cu depend`) |
99
- | `--to` / `--remove` | List ID to add/remove task (used with `cu move`) |
100
- | `cu field --set` | Supports: text, number, checkbox (true/false), dropdown (option name), date (YYYY-MM-DD), url, email |
101
- | `cu field` | Field names resolved case-insensitively; errors list available fields/options |
102
- | `cu delete` | DESTRUCTIVE. Requires `--confirm` in non-interactive mode. Cannot be undone |
103
- | `cu tag --add/--remove` | Comma-separated tag names (e.g. `--add "bug,frontend"`) |
104
- | `--space` | Partial name match or exact ID |
105
- | `--name` | Partial match, case-insensitive |
106
- | `--include-closed` | Include closed/done tasks (on `tasks`, `assigned`, `subtasks`, `sprint`, `search`, `inbox`, `overdue`) |
107
- | `cu assign --to me` | Shorthand for your own user ID |
108
- | `cu search` | Matches all query words against task name, case-insensitive |
109
- | `cu sprint` | Auto-detects active sprint via view API and date range parsing |
110
- | `cu summary` | Categories: completed (done/complete/closed within N hours), in progress, overdue |
111
- | `cu overdue` | Excludes closed tasks, sorted most overdue first |
112
- | `cu open` | Tries task ID first, falls back to name search |
113
- | `cu checklist` | Full CRUD for task checklists: view, create, delete, add-item, edit-item, delete-item |
114
- | `cu time` | Track time: start/stop timer, log entries, list history. Duration format: "2h", "30m", "1h30m" |
115
- | `cu comment-edit` | Edit comment text and resolution status |
116
- | `cu task` | Shows custom fields and checklists in detail view |
117
- | `cu lists` | Discovers list IDs needed for `--list` and `cu create -l` |
118
- | Errors | stderr with exit code 1 |
119
- | Parsing | Strict - excess/unknown arguments rejected |
90
+ | Topic | Detail |
91
+ | ------------------------- | ------------------------------------------------------------------------------------------------------ |
92
+ | Task IDs | Stable alphanumeric strings (e.g. `abc123def`) |
93
+ | `--type` | Filter by task type: `task` (regular), or custom type name/ID (e.g. `initiative`, `Bug`) |
94
+ | `--list` on create | Optional when `--parent` is given (auto-detected) |
95
+ | `--status` | Fuzzy matching: exact > starts-with > contains. Prints match to stderr. |
96
+ | `--priority` | Names (`urgent`, `high`, `normal`, `low`) or numbers (1-4) |
97
+ | `--due-date` | `YYYY-MM-DD` format |
98
+ | `--assignee` | User ID or `me` (on `cu create`, `cu update`, `cu assign`) |
99
+ | `--tags` | Comma-separated (e.g. `--tags "bug,frontend"`) |
100
+ | `--time-estimate` | Duration format: `"2h"`, `"30m"`, `"1h30m"`, or raw milliseconds |
101
+ | `--custom-item-id` | Custom task type ID for `cu create` (e.g. `1` for initiative) |
102
+ | `--on` / `--blocks` | Task dependency direction (used with `cu depend`) |
103
+ | `--to` / `--remove` | List ID to add/remove task (used with `cu move`) |
104
+ | `cu field --set` | Supports: text, number, checkbox (true/false), dropdown (option name), date (YYYY-MM-DD), url, email |
105
+ | `cu field` | Field names resolved case-insensitively; errors list available fields/options |
106
+ | `cu delete` | DESTRUCTIVE. Requires `--confirm` in non-interactive mode. Cannot be undone |
107
+ | `cu tag --add/--remove` | Comma-separated tag names (e.g. `--add "bug,frontend"`) |
108
+ | `--space` | Partial name match or exact ID |
109
+ | `--name` | Partial match, case-insensitive |
110
+ | `--include-closed` | Include closed/done tasks (on `tasks`, `assigned`, `subtasks`, `sprint`, `search`, `inbox`, `overdue`) |
111
+ | `cu assign --to me` | Shorthand for your own user ID |
112
+ | `cu search` | Matches all query words against task name, case-insensitive |
113
+ | `cu sprint` | Auto-detects active sprint via view API and date range parsing |
114
+ | `cu summary` | Categories: completed (done/complete/closed within N hours), in progress, overdue |
115
+ | `cu overdue` | Excludes closed tasks, sorted most overdue first |
116
+ | `cu open` | Tries task ID first, falls back to name search |
117
+ | `cu checklist` | Full CRUD for task checklists: view, create, delete, add-item, edit-item, delete-item |
118
+ | `cu time` | Track time: start/stop timer, log entries, list history. Duration format: "2h", "30m", "1h30m" |
119
+ | `cu comment-edit` | Edit comment text and resolution status |
120
+ | `cu comment-delete` | Delete a comment |
121
+ | `cu replies` / `cu reply` | View and post threaded comment replies |
122
+ | `cu link` | Link/unlink tasks (different from dependencies) |
123
+ | `cu task` | Shows custom fields and checklists in detail view |
124
+ | `cu lists` | Discovers list IDs needed for `--list` and `cu create -l` |
125
+ | Errors | stderr with exit code 1 |
126
+ | Parsing | Strict - excess/unknown arguments rejected |
120
127
 
121
128
  ## Agent Workflow Examples
122
129
 
@@ -170,6 +177,11 @@ cu checklist create abc123def "QA Steps" # add checklist
170
177
  cu checklist add-item <clId> "Run unit tests" # add item
171
178
  cu checklist edit-item <clId> <itemId> --resolved # check off item
172
179
  cu comment-edit <commentId> -m "Updated findings" # edit a comment
180
+ cu comment-delete <commentId> # delete a comment
181
+ cu replies <commentId> # view threaded replies
182
+ cu reply <commentId> -m "Agreed, fixing" # reply to a comment
183
+ cu link abc123 def456 # link two tasks
184
+ cu link abc123 def456 --remove # unlink two tasks
173
185
  cu time start abc123def -d "Working on feature" # start timer
174
186
  cu time status # check running timer
175
187
  cu time stop # stop timer