@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.
- package/.claude-plugin/plugin.json +2 -2
- package/README.md +168 -107
- package/dist/index.js +166 -4
- package/package.json +1 -1
- package/skills/clickup-cli/SKILL.md +47 -35
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clickup-cli",
|
|
3
|
-
"description": "
|
|
4
|
-
"version": "0.
|
|
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
|
|
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
|
-
##
|
|
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> <img src="https://
|
|
36
|
-
|
|
37
|
-
**1. Install the CLI**
|
|
35
|
+
<summary> <img src="https://img.shields.io/badge/npm-CB3837?logo=npm&logoColor=white" height="18" align="center"> <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
|
-
|
|
42
|
+
</details>
|
|
43
|
+
|
|
44
|
+
<details>
|
|
45
|
+
<summary> <img src="https://img.shields.io/badge/Homebrew-FBB040?logo=homebrew&logoColor=black" height="18" align="center"> <strong>Homebrew</strong></summary>
|
|
45
46
|
|
|
46
47
|
```bash
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
brew tap krodak/tap
|
|
49
|
+
brew install clickup-cli
|
|
50
|
+
cu init
|
|
49
51
|
```
|
|
50
52
|
|
|
51
53
|
</details>
|
|
52
54
|
|
|
53
|
-
|
|
54
|
-
|
|
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> <img src="https://img.shields.io/badge/Claude_Code-D97757?logo=anthropic&logoColor=white" height="18" align="center"> <strong>Claude Code</strong></summary>
|
|
55
61
|
|
|
56
|
-
**
|
|
62
|
+
**Install as a [plugin](https://docs.anthropic.com/en/docs/claude-code/plugins)** (recommended):
|
|
57
63
|
|
|
58
64
|
```bash
|
|
59
|
-
npm
|
|
60
|
-
cu init
|
|
65
|
+
claude plugin add $(npm root -g)/@krodak/clickup-cli
|
|
61
66
|
```
|
|
62
67
|
|
|
63
|
-
|
|
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 $
|
|
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> <img src="https://
|
|
81
|
+
<summary> <img src="https://img.shields.io/badge/Codex-412991?logo=openai&logoColor=white" height="18" align="center"> <strong>Codex</strong></summary>
|
|
76
82
|
|
|
77
|
-
|
|
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
|
|
85
|
+
**Install as a user skill** (available across all your projects):
|
|
80
86
|
|
|
81
87
|
```bash
|
|
82
|
-
npm
|
|
83
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
<details>
|
|
89
|
-
<summary> <img src="https://cdn.simpleicons.org/homebrew/FBB040" height="16" align="center"> <strong>Homebrew</strong></summary>
|
|
93
|
+
**Or install as a project skill** (checked into your repo):
|
|
90
94
|
|
|
91
95
|
```bash
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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
|
-
|
|
101
|
+
You can also use the built-in installer: `$skill-installer clickup`
|
|
98
102
|
|
|
99
103
|
</details>
|
|
100
104
|
|
|
101
105
|
<details>
|
|
102
|
-
<summary> <img src="https://
|
|
103
|
-
|
|
104
|
-
**1. Install the CLI**
|
|
106
|
+
<summary> <img src="https://img.shields.io/badge/OpenCode-24292e?logoColor=white" height="18" align="center"> <strong>OpenCode</strong></summary>
|
|
105
107
|
|
|
106
108
|
```bash
|
|
107
|
-
npm
|
|
108
|
-
|
|
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
|
-
|
|
114
|
+
</details>
|
|
115
|
+
|
|
116
|
+
<details>
|
|
117
|
+
<summary> <strong>Other agents</strong></summary>
|
|
112
118
|
|
|
113
|
-
Copy `skills/clickup-cli/SKILL.md` into your agent's system prompt or
|
|
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
|
-
##
|
|
123
|
+
## API Coverage
|
|
124
|
+
|
|
125
|
+
[Full command reference with examples and flags](docs/commands.md).
|
|
118
126
|
|
|
119
|
-
|
|
127
|
+
Status: :white_check_mark: implemented | :construction: planned | :no_entry_sign: won't add
|
|
120
128
|
|
|
121
129
|
### Tasks
|
|
122
130
|
|
|
123
|
-
| Command
|
|
124
|
-
|
|
|
125
|
-
|
|
|
126
|
-
| `cu task <id>`
|
|
127
|
-
| `cu
|
|
128
|
-
|
|
|
129
|
-
| `cu
|
|
130
|
-
| `cu
|
|
131
|
-
| `cu
|
|
132
|
-
| `cu
|
|
133
|
-
| `cu
|
|
134
|
-
| `cu
|
|
135
|
-
|
|
|
136
|
-
|
|
|
137
|
-
|
|
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 |
|
|
142
|
-
| ------------- |
|
|
143
|
-
| `cu sprint` |
|
|
144
|
-
| `cu sprints` |
|
|
145
|
-
| `cu assigned` |
|
|
146
|
-
| `cu summary` |
|
|
147
|
-
| `cu overdue` |
|
|
148
|
-
| `cu inbox` |
|
|
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
|
|
153
|
-
|
|
|
154
|
-
| `cu
|
|
155
|
-
| `cu
|
|
156
|
-
| `cu comment-edit <id>`
|
|
157
|
-
| `cu activity <id>`
|
|
158
|
-
|
|
|
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
|
-
###
|
|
183
|
+
### Checklists
|
|
161
184
|
|
|
162
|
-
| Command
|
|
163
|
-
|
|
|
164
|
-
| `cu
|
|
165
|
-
|
|
|
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
|
-
###
|
|
194
|
+
### Custom Fields
|
|
168
195
|
|
|
169
|
-
| Command
|
|
170
|
-
|
|
|
171
|
-
| `cu
|
|
172
|
-
| `cu
|
|
173
|
-
| `cu
|
|
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
|
|
181
|
-
|
|
|
182
|
-
| `cu tag <id>`
|
|
183
|
-
|
|
|
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
|
|
188
|
-
|
|
|
189
|
-
| `cu spaces`
|
|
190
|
-
| `cu lists <spaceId>`
|
|
191
|
-
| `cu auth`
|
|
192
|
-
|
|
|
193
|
-
|
|
|
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
|
-
###
|
|
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
|
-
|
|
|
198
|
-
|
|
|
199
|
-
|
|
|
200
|
-
| `cu
|
|
201
|
-
|
|
|
202
|
-
|
|
|
203
|
-
|
|
|
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 |
|
|
208
|
-
| ----------------------- |
|
|
209
|
-
| `cu init` |
|
|
210
|
-
| `cu config` |
|
|
211
|
-
| `cu completion <shell>` |
|
|
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/
|
|
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 ?
|
|
2832
|
-
lines.push(`${
|
|
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: 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
|
|
87
|
-
|
|
|
88
|
-
| Task IDs
|
|
89
|
-
| `--type`
|
|
90
|
-
| `--list` on create
|
|
91
|
-
| `--status`
|
|
92
|
-
| `--priority`
|
|
93
|
-
| `--due-date`
|
|
94
|
-
| `--assignee`
|
|
95
|
-
| `--tags`
|
|
96
|
-
| `--time-estimate`
|
|
97
|
-
| `--custom-item-id`
|
|
98
|
-
| `--on` / `--blocks`
|
|
99
|
-
| `--to` / `--remove`
|
|
100
|
-
| `cu field --set`
|
|
101
|
-
| `cu field`
|
|
102
|
-
| `cu delete`
|
|
103
|
-
| `cu tag --add/--remove`
|
|
104
|
-
| `--space`
|
|
105
|
-
| `--name`
|
|
106
|
-
| `--include-closed`
|
|
107
|
-
| `cu assign --to me`
|
|
108
|
-
| `cu search`
|
|
109
|
-
| `cu sprint`
|
|
110
|
-
| `cu summary`
|
|
111
|
-
| `cu overdue`
|
|
112
|
-
| `cu open`
|
|
113
|
-
| `cu checklist`
|
|
114
|
-
| `cu time`
|
|
115
|
-
| `cu comment-edit`
|
|
116
|
-
| `cu
|
|
117
|
-
| `cu
|
|
118
|
-
|
|
|
119
|
-
|
|
|
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
|