@krodak/clickup-cli 0.15.0 → 0.17.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 +248 -4
- package/package.json +1 -1
- package/skills/clickup-cli/SKILL.md +50 -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.17.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>` | :white_check_mark: |
|
|
252
|
+
| List attachments | shown inline in `cu task` | :white_check_mark: |
|
|
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 ?? [];
|
|
@@ -295,6 +314,37 @@ var ClickUpClient = class {
|
|
|
295
314
|
method: "DELETE"
|
|
296
315
|
});
|
|
297
316
|
}
|
|
317
|
+
async createTaskAttachment(taskId, filePath) {
|
|
318
|
+
const { readFile } = await import("fs/promises");
|
|
319
|
+
const { basename } = await import("path");
|
|
320
|
+
const fileBuffer = await readFile(filePath);
|
|
321
|
+
const fileName = basename(filePath);
|
|
322
|
+
const formData = new FormData();
|
|
323
|
+
formData.append("attachment", new Blob([fileBuffer]), fileName);
|
|
324
|
+
const res = await fetch(`${BASE_URL}/task/${taskId}/attachment`, {
|
|
325
|
+
method: "POST",
|
|
326
|
+
headers: { Authorization: this.apiToken },
|
|
327
|
+
body: formData,
|
|
328
|
+
signal: AbortSignal.timeout(6e4)
|
|
329
|
+
});
|
|
330
|
+
if (!res.ok) {
|
|
331
|
+
let msg;
|
|
332
|
+
try {
|
|
333
|
+
const data2 = await res.json();
|
|
334
|
+
msg = data2.err ?? `HTTP ${res.status}`;
|
|
335
|
+
} catch {
|
|
336
|
+
msg = `HTTP ${res.status}`;
|
|
337
|
+
}
|
|
338
|
+
throw new Error(`ClickUp API error ${res.status}: ${msg}`);
|
|
339
|
+
}
|
|
340
|
+
let data;
|
|
341
|
+
try {
|
|
342
|
+
data = await res.json();
|
|
343
|
+
} catch {
|
|
344
|
+
throw new Error(`ClickUp API error ${res.status}: response was not valid JSON`);
|
|
345
|
+
}
|
|
346
|
+
return data;
|
|
347
|
+
}
|
|
298
348
|
};
|
|
299
349
|
|
|
300
350
|
// src/config.ts
|
|
@@ -527,6 +577,12 @@ function formatTaskDetailMarkdown(task) {
|
|
|
527
577
|
lines.push("");
|
|
528
578
|
}
|
|
529
579
|
}
|
|
580
|
+
if (task.attachments?.length) {
|
|
581
|
+
lines.push("", "## Attachments", "");
|
|
582
|
+
for (const att of task.attachments) {
|
|
583
|
+
lines.push(`- [${att.title}](${att.url})`);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
530
586
|
return lines.join("\n");
|
|
531
587
|
}
|
|
532
588
|
function formatUpdateConfirmation(id, name) {
|
|
@@ -673,6 +729,13 @@ function formatTaskDetail(task) {
|
|
|
673
729
|
}
|
|
674
730
|
}
|
|
675
731
|
}
|
|
732
|
+
if (task.attachments?.length) {
|
|
733
|
+
lines.push("");
|
|
734
|
+
lines.push(chalk2.bold("Attachments"));
|
|
735
|
+
for (const att of task.attachments) {
|
|
736
|
+
lines.push(` ${att.title} ${chalk2.dim(att.url)}`);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
676
739
|
if (task.text_content?.trim()) {
|
|
677
740
|
lines.push("");
|
|
678
741
|
lines.push(descriptionPreview(task.text_content));
|
|
@@ -1808,7 +1871,7 @@ function bashCompletion() {
|
|
|
1808
1871
|
cword=$COMP_CWORD
|
|
1809
1872
|
fi
|
|
1810
1873
|
|
|
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"
|
|
1874
|
+
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 attach move field delete tag checklist time config completion"
|
|
1812
1875
|
|
|
1813
1876
|
if [[ $cword -eq 1 ]]; then
|
|
1814
1877
|
COMPREPLY=($(compgen -W "$commands --help --version" -- "$cur"))
|
|
@@ -1917,6 +1980,21 @@ function bashCompletion() {
|
|
|
1917
1980
|
comment-edit)
|
|
1918
1981
|
COMPREPLY=($(compgen -W "-m --message --resolved --unresolved --json" -- "$cur"))
|
|
1919
1982
|
;;
|
|
1983
|
+
comment-delete)
|
|
1984
|
+
COMPREPLY=($(compgen -W "--json" -- "$cur"))
|
|
1985
|
+
;;
|
|
1986
|
+
replies)
|
|
1987
|
+
COMPREPLY=($(compgen -W "--json" -- "$cur"))
|
|
1988
|
+
;;
|
|
1989
|
+
reply)
|
|
1990
|
+
COMPREPLY=($(compgen -W "-m --message --json" -- "$cur"))
|
|
1991
|
+
;;
|
|
1992
|
+
link)
|
|
1993
|
+
COMPREPLY=($(compgen -W "--remove --json" -- "$cur"))
|
|
1994
|
+
;;
|
|
1995
|
+
attach)
|
|
1996
|
+
COMPREPLY=($(compgen -f -- "$cur"))
|
|
1997
|
+
;;
|
|
1920
1998
|
config)
|
|
1921
1999
|
if [[ $cword -eq 2 ]]; then
|
|
1922
2000
|
COMPREPLY=($(compgen -W "get set path" -- "$cur"))
|
|
@@ -1972,6 +2050,11 @@ _cu() {
|
|
|
1972
2050
|
'checklist:Manage checklists on a task'
|
|
1973
2051
|
'time:Track time on tasks'
|
|
1974
2052
|
'comment-edit:Edit an existing comment'
|
|
2053
|
+
'comment-delete:Delete a comment'
|
|
2054
|
+
'replies:List threaded replies on a comment'
|
|
2055
|
+
'reply:Reply to a comment'
|
|
2056
|
+
'link:Add or remove a link between two tasks'
|
|
2057
|
+
'attach:Upload a file attachment to a task'
|
|
1975
2058
|
'config:Manage CLI configuration'
|
|
1976
2059
|
'completion:Output shell completion script'
|
|
1977
2060
|
)
|
|
@@ -2262,6 +2345,35 @@ _cu() {
|
|
|
2262
2345
|
'--unresolved[Mark comment as unresolved]' \\
|
|
2263
2346
|
'--json[Force JSON output]'
|
|
2264
2347
|
;;
|
|
2348
|
+
comment-delete)
|
|
2349
|
+
_arguments \\
|
|
2350
|
+
'1:comment_id:' \\
|
|
2351
|
+
'--json[Force JSON output]'
|
|
2352
|
+
;;
|
|
2353
|
+
replies)
|
|
2354
|
+
_arguments \\
|
|
2355
|
+
'1:comment_id:' \\
|
|
2356
|
+
'--json[Force JSON output]'
|
|
2357
|
+
;;
|
|
2358
|
+
reply)
|
|
2359
|
+
_arguments \\
|
|
2360
|
+
'1:comment_id:' \\
|
|
2361
|
+
'(-m --message)'{-m,--message}'[Reply text]:text:' \\
|
|
2362
|
+
'--json[Force JSON output]'
|
|
2363
|
+
;;
|
|
2364
|
+
link)
|
|
2365
|
+
_arguments \\
|
|
2366
|
+
'1:task_id:' \\
|
|
2367
|
+
'2:links_to:' \\
|
|
2368
|
+
'--remove[Remove the link instead of adding it]' \\
|
|
2369
|
+
'--json[Force JSON output]'
|
|
2370
|
+
;;
|
|
2371
|
+
attach)
|
|
2372
|
+
_arguments \\
|
|
2373
|
+
'1:task_id:' \\
|
|
2374
|
+
'2:file_path:_files' \\
|
|
2375
|
+
'--json[Force JSON output]'
|
|
2376
|
+
;;
|
|
2265
2377
|
config)
|
|
2266
2378
|
local -a config_cmds
|
|
2267
2379
|
config_cmds=(
|
|
@@ -2331,6 +2443,11 @@ complete -c cu -n __fish_use_subcommand -a tag -d 'Add or remove tags from a tas
|
|
|
2331
2443
|
complete -c cu -n __fish_use_subcommand -a checklist -d 'Manage checklists on a task'
|
|
2332
2444
|
complete -c cu -n __fish_use_subcommand -a time -d 'Track time on tasks'
|
|
2333
2445
|
complete -c cu -n __fish_use_subcommand -a comment-edit -d 'Edit an existing comment'
|
|
2446
|
+
complete -c cu -n __fish_use_subcommand -a comment-delete -d 'Delete a comment'
|
|
2447
|
+
complete -c cu -n __fish_use_subcommand -a replies -d 'List threaded replies on a comment'
|
|
2448
|
+
complete -c cu -n __fish_use_subcommand -a reply -d 'Reply to a comment'
|
|
2449
|
+
complete -c cu -n __fish_use_subcommand -a link -d 'Add or remove a link between two tasks'
|
|
2450
|
+
complete -c cu -n __fish_use_subcommand -a attach -d 'Upload a file attachment to a task'
|
|
2334
2451
|
complete -c cu -n __fish_use_subcommand -a config -d 'Manage CLI configuration'
|
|
2335
2452
|
complete -c cu -n __fish_use_subcommand -a completion -d 'Output shell completion script'
|
|
2336
2453
|
|
|
@@ -2463,6 +2580,19 @@ complete -c cu -n '__fish_seen_subcommand_from log; and __fish_seen_subcommand_f
|
|
|
2463
2580
|
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
2581
|
complete -c cu -n '__fish_seen_subcommand_from list; and __fish_seen_subcommand_from time' -l task -d 'Filter by task ID'
|
|
2465
2582
|
|
|
2583
|
+
complete -c cu -n '__fish_seen_subcommand_from comment-delete' -l json -d 'Force JSON output'
|
|
2584
|
+
|
|
2585
|
+
complete -c cu -n '__fish_seen_subcommand_from replies' -l json -d 'Force JSON output'
|
|
2586
|
+
|
|
2587
|
+
complete -c cu -n '__fish_seen_subcommand_from reply' -s m -l message -d 'Reply text'
|
|
2588
|
+
complete -c cu -n '__fish_seen_subcommand_from reply' -l json -d 'Force JSON output'
|
|
2589
|
+
|
|
2590
|
+
complete -c cu -n '__fish_seen_subcommand_from link' -l remove -d 'Remove the link'
|
|
2591
|
+
complete -c cu -n '__fish_seen_subcommand_from link' -l json -d 'Force JSON output'
|
|
2592
|
+
|
|
2593
|
+
complete -c cu -n '__fish_seen_subcommand_from attach' -l json -d 'Force JSON output'
|
|
2594
|
+
complete -c cu -n '__fish_seen_subcommand_from attach' -F
|
|
2595
|
+
|
|
2466
2596
|
complete -c cu -n '__fish_seen_subcommand_from comment-edit' -s m -l message -d 'New comment text'
|
|
2467
2597
|
complete -c cu -n '__fish_seen_subcommand_from comment-edit' -l resolved -d 'Mark comment as resolved'
|
|
2468
2598
|
complete -c cu -n '__fish_seen_subcommand_from comment-edit' -l unresolved -d 'Mark comment as unresolved'
|
|
@@ -2775,8 +2905,58 @@ async function editComment(config, commentId, text, resolved) {
|
|
|
2775
2905
|
await client.updateComment(commentId, text, resolved);
|
|
2776
2906
|
}
|
|
2777
2907
|
|
|
2778
|
-
// src/commands/
|
|
2908
|
+
// src/commands/comment-delete.ts
|
|
2909
|
+
async function deleteComment(config, commentId) {
|
|
2910
|
+
const client = new ClickUpClient(config);
|
|
2911
|
+
await client.deleteComment(commentId);
|
|
2912
|
+
}
|
|
2913
|
+
|
|
2914
|
+
// src/commands/replies.ts
|
|
2779
2915
|
import chalk6 from "chalk";
|
|
2916
|
+
async function getReplies(config, commentId) {
|
|
2917
|
+
const client = new ClickUpClient(config);
|
|
2918
|
+
return client.getThreadedComments(commentId);
|
|
2919
|
+
}
|
|
2920
|
+
async function createReply(config, commentId, text) {
|
|
2921
|
+
if (!text.trim()) throw new Error("Reply text cannot be empty");
|
|
2922
|
+
const client = new ClickUpClient(config);
|
|
2923
|
+
await client.createThreadedComment(commentId, text);
|
|
2924
|
+
}
|
|
2925
|
+
function formatReplies(replies) {
|
|
2926
|
+
if (replies.length === 0) return "No replies";
|
|
2927
|
+
return replies.map((r) => {
|
|
2928
|
+
const user = r.user?.username ?? "Unknown";
|
|
2929
|
+
const date = new Date(Number(r.date)).toLocaleString();
|
|
2930
|
+
return `${chalk6.bold(user)} ${chalk6.dim(date)}
|
|
2931
|
+
${r.comment_text}`;
|
|
2932
|
+
}).join("\n\n");
|
|
2933
|
+
}
|
|
2934
|
+
|
|
2935
|
+
// src/commands/link.ts
|
|
2936
|
+
async function manageTaskLink(config, taskId, linksTo, remove) {
|
|
2937
|
+
const client = new ClickUpClient(config);
|
|
2938
|
+
if (remove) {
|
|
2939
|
+
await client.deleteTaskLink(taskId, linksTo);
|
|
2940
|
+
return `Removed link between ${taskId} and ${linksTo}`;
|
|
2941
|
+
}
|
|
2942
|
+
await client.addTaskLink(taskId, linksTo);
|
|
2943
|
+
return `Linked ${taskId} to ${linksTo}`;
|
|
2944
|
+
}
|
|
2945
|
+
|
|
2946
|
+
// src/commands/attach.ts
|
|
2947
|
+
async function attachFile(config, taskId, filePath) {
|
|
2948
|
+
const { access } = await import("fs/promises");
|
|
2949
|
+
try {
|
|
2950
|
+
await access(filePath);
|
|
2951
|
+
} catch {
|
|
2952
|
+
throw new Error(`File not found: ${filePath}`);
|
|
2953
|
+
}
|
|
2954
|
+
const client = new ClickUpClient(config);
|
|
2955
|
+
return client.createTaskAttachment(taskId, filePath);
|
|
2956
|
+
}
|
|
2957
|
+
|
|
2958
|
+
// src/commands/time.ts
|
|
2959
|
+
import chalk7 from "chalk";
|
|
2780
2960
|
function formatDuration2(ms) {
|
|
2781
2961
|
const totalMinutes = Math.round(Math.abs(ms) / 6e4);
|
|
2782
2962
|
const hours = Math.floor(totalMinutes / 60);
|
|
@@ -2828,8 +3008,8 @@ function formatTimeEntry(entry) {
|
|
|
2828
3008
|
const isRunning = entry.duration < 0;
|
|
2829
3009
|
const elapsed = isRunning ? Date.now() - Number(entry.start) : entry.duration;
|
|
2830
3010
|
const durationStr = formatDuration2(elapsed);
|
|
2831
|
-
const status = isRunning ?
|
|
2832
|
-
lines.push(`${
|
|
3011
|
+
const status = isRunning ? chalk7.green("RUNNING") : "";
|
|
3012
|
+
lines.push(`${chalk7.bold(taskName)} ${chalk7.dim(taskId)} ${status}`);
|
|
2833
3013
|
lines.push(
|
|
2834
3014
|
` ${durationStr} - ${formatTimestamp2(entry.start)}${entry.description ? ` - ${entry.description}` : ""}`
|
|
2835
3015
|
);
|
|
@@ -2997,6 +3177,39 @@ program.command("comment-edit <commentId>").description("Edit an existing commen
|
|
|
2997
3177
|
}
|
|
2998
3178
|
)
|
|
2999
3179
|
);
|
|
3180
|
+
program.command("comment-delete <commentId>").description("Delete a comment").option("--json", "Force JSON output even in terminal").action(
|
|
3181
|
+
wrapAction(async (commentId, opts) => {
|
|
3182
|
+
const config = loadConfig();
|
|
3183
|
+
await deleteComment(config, commentId);
|
|
3184
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
3185
|
+
console.log(JSON.stringify({ success: true, commentId }, null, 2));
|
|
3186
|
+
} else {
|
|
3187
|
+
console.log(`Deleted comment ${commentId}`);
|
|
3188
|
+
}
|
|
3189
|
+
})
|
|
3190
|
+
);
|
|
3191
|
+
program.command("replies <commentId>").description("List threaded replies on a comment").option("--json", "Force JSON output even in terminal").action(
|
|
3192
|
+
wrapAction(async (commentId, opts) => {
|
|
3193
|
+
const config = loadConfig();
|
|
3194
|
+
const replies = await getReplies(config, commentId);
|
|
3195
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
3196
|
+
console.log(JSON.stringify(replies, null, 2));
|
|
3197
|
+
} else {
|
|
3198
|
+
console.log(formatReplies(replies));
|
|
3199
|
+
}
|
|
3200
|
+
})
|
|
3201
|
+
);
|
|
3202
|
+
program.command("reply <commentId>").description("Reply to a comment").requiredOption("-m, --message <text>", "Reply text").option("--json", "Force JSON output even in terminal").action(
|
|
3203
|
+
wrapAction(async (commentId, opts) => {
|
|
3204
|
+
const config = loadConfig();
|
|
3205
|
+
await createReply(config, commentId, opts.message);
|
|
3206
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
3207
|
+
console.log(JSON.stringify({ success: true, commentId }, null, 2));
|
|
3208
|
+
} else {
|
|
3209
|
+
console.log(`Replied to comment ${commentId}`);
|
|
3210
|
+
}
|
|
3211
|
+
})
|
|
3212
|
+
);
|
|
3000
3213
|
program.command("activity <taskId>").description("Show task details and comments combined").option("--json", "Force JSON output even in terminal").action(
|
|
3001
3214
|
wrapAction(async (taskId, opts) => {
|
|
3002
3215
|
const config = loadConfig();
|
|
@@ -3097,6 +3310,37 @@ program.command("depend <taskId>").description("Add or remove task dependencies"
|
|
|
3097
3310
|
}
|
|
3098
3311
|
})
|
|
3099
3312
|
);
|
|
3313
|
+
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(
|
|
3314
|
+
wrapAction(
|
|
3315
|
+
async (taskId, linksTo, opts) => {
|
|
3316
|
+
const config = loadConfig();
|
|
3317
|
+
const result = await manageTaskLink(config, taskId, linksTo, opts.remove ?? false);
|
|
3318
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
3319
|
+
console.log(
|
|
3320
|
+
JSON.stringify(
|
|
3321
|
+
{ success: true, taskId, linksTo, action: opts.remove ? "removed" : "added" },
|
|
3322
|
+
null,
|
|
3323
|
+
2
|
|
3324
|
+
)
|
|
3325
|
+
);
|
|
3326
|
+
} else {
|
|
3327
|
+
console.log(result);
|
|
3328
|
+
}
|
|
3329
|
+
}
|
|
3330
|
+
)
|
|
3331
|
+
);
|
|
3332
|
+
program.command("attach <taskId> <filePath>").description("Upload a file attachment to a task").option("--json", "Force JSON output even in terminal").action(
|
|
3333
|
+
wrapAction(async (taskId, filePath, opts) => {
|
|
3334
|
+
const config = loadConfig();
|
|
3335
|
+
const result = await attachFile(config, taskId, filePath);
|
|
3336
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
3337
|
+
console.log(JSON.stringify(result, null, 2));
|
|
3338
|
+
} else {
|
|
3339
|
+
console.log(`Uploaded "${result.title}" to task ${taskId}`);
|
|
3340
|
+
console.log(` ${result.url}`);
|
|
3341
|
+
}
|
|
3342
|
+
})
|
|
3343
|
+
);
|
|
3100
3344
|
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
3345
|
wrapAction(async (taskId, opts) => {
|
|
3102
3346
|
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, attachments, file uploads.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# ClickUp CLI (`cu`)
|
|
@@ -73,6 +73,11 @@ 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 |
|
|
80
|
+
| `cu attach <taskId> <filePath> [--json]` | Upload file attachment to a task |
|
|
76
81
|
| `cu time start <taskId> [-d desc] [--json]` | Start tracking time on a task |
|
|
77
82
|
| `cu time stop [--json]` | Stop the running timer |
|
|
78
83
|
| `cu time status [--json]` | Show currently running timer |
|
|
@@ -83,40 +88,44 @@ All commands support `--help` for full flag details.
|
|
|
83
88
|
|
|
84
89
|
## Quick Reference
|
|
85
90
|
|
|
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
|
-
|
|
|
91
|
+
| Topic | Detail |
|
|
92
|
+
| ------------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
93
|
+
| Task IDs | Stable alphanumeric strings (e.g. `abc123def`) |
|
|
94
|
+
| `--type` | Filter by task type: `task` (regular), or custom type name/ID (e.g. `initiative`, `Bug`) |
|
|
95
|
+
| `--list` on create | Optional when `--parent` is given (auto-detected) |
|
|
96
|
+
| `--status` | Fuzzy matching: exact > starts-with > contains. Prints match to stderr. |
|
|
97
|
+
| `--priority` | Names (`urgent`, `high`, `normal`, `low`) or numbers (1-4) |
|
|
98
|
+
| `--due-date` | `YYYY-MM-DD` format |
|
|
99
|
+
| `--assignee` | User ID or `me` (on `cu create`, `cu update`, `cu assign`) |
|
|
100
|
+
| `--tags` | Comma-separated (e.g. `--tags "bug,frontend"`) |
|
|
101
|
+
| `--time-estimate` | Duration format: `"2h"`, `"30m"`, `"1h30m"`, or raw milliseconds |
|
|
102
|
+
| `--custom-item-id` | Custom task type ID for `cu create` (e.g. `1` for initiative) |
|
|
103
|
+
| `--on` / `--blocks` | Task dependency direction (used with `cu depend`) |
|
|
104
|
+
| `--to` / `--remove` | List ID to add/remove task (used with `cu move`) |
|
|
105
|
+
| `cu field --set` | Supports: text, number, checkbox (true/false), dropdown (option name), date (YYYY-MM-DD), url, email |
|
|
106
|
+
| `cu field` | Field names resolved case-insensitively; errors list available fields/options |
|
|
107
|
+
| `cu delete` | DESTRUCTIVE. Requires `--confirm` in non-interactive mode. Cannot be undone |
|
|
108
|
+
| `cu tag --add/--remove` | Comma-separated tag names (e.g. `--add "bug,frontend"`) |
|
|
109
|
+
| `--space` | Partial name match or exact ID |
|
|
110
|
+
| `--name` | Partial match, case-insensitive |
|
|
111
|
+
| `--include-closed` | Include closed/done tasks (on `tasks`, `assigned`, `subtasks`, `sprint`, `search`, `inbox`, `overdue`) |
|
|
112
|
+
| `cu assign --to me` | Shorthand for your own user ID |
|
|
113
|
+
| `cu search` | Matches all query words against task name, case-insensitive |
|
|
114
|
+
| `cu sprint` | Auto-detects active sprint via view API and date range parsing |
|
|
115
|
+
| `cu summary` | Categories: completed (done/complete/closed within N hours), in progress, overdue |
|
|
116
|
+
| `cu overdue` | Excludes closed tasks, sorted most overdue first |
|
|
117
|
+
| `cu open` | Tries task ID first, falls back to name search |
|
|
118
|
+
| `cu checklist` | Full CRUD for task checklists: view, create, delete, add-item, edit-item, delete-item |
|
|
119
|
+
| `cu time` | Track time: start/stop timer, log entries, list history. Duration format: "2h", "30m", "1h30m" |
|
|
120
|
+
| `cu comment-edit` | Edit comment text and resolution status |
|
|
121
|
+
| `cu comment-delete` | Delete a comment |
|
|
122
|
+
| `cu replies` / `cu reply` | View and post threaded comment replies |
|
|
123
|
+
| `cu link` | Link/unlink tasks (different from dependencies) |
|
|
124
|
+
| `cu attach` | Upload files to tasks. Attachments shown in `cu task` detail view |
|
|
125
|
+
| `cu task` | Shows custom fields, checklists, and attachments in detail view |
|
|
126
|
+
| `cu lists` | Discovers list IDs needed for `--list` and `cu create -l` |
|
|
127
|
+
| Errors | stderr with exit code 1 |
|
|
128
|
+
| Parsing | Strict - excess/unknown arguments rejected |
|
|
120
129
|
|
|
121
130
|
## Agent Workflow Examples
|
|
122
131
|
|
|
@@ -170,6 +179,12 @@ cu checklist create abc123def "QA Steps" # add checklist
|
|
|
170
179
|
cu checklist add-item <clId> "Run unit tests" # add item
|
|
171
180
|
cu checklist edit-item <clId> <itemId> --resolved # check off item
|
|
172
181
|
cu comment-edit <commentId> -m "Updated findings" # edit a comment
|
|
182
|
+
cu comment-delete <commentId> # delete a comment
|
|
183
|
+
cu replies <commentId> # view threaded replies
|
|
184
|
+
cu reply <commentId> -m "Agreed, fixing" # reply to a comment
|
|
185
|
+
cu link abc123 def456 # link two tasks
|
|
186
|
+
cu link abc123 def456 --remove # unlink two tasks
|
|
187
|
+
cu attach abc123def ./screenshot.png # upload file to task
|
|
173
188
|
cu time start abc123def -d "Working on feature" # start timer
|
|
174
189
|
cu time status # check running timer
|
|
175
190
|
cu time stop # stop timer
|