@krodak/clickup-cli 0.9.0 → 0.10.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/README.md +48 -22
- package/dist/index.js +97 -11
- package/package.json +1 -1
- package/skills/clickup-cli/SKILL.md +23 -12
package/README.md
CHANGED
|
@@ -98,7 +98,7 @@ When output is piped (no TTY), all commands output **Markdown** by default - opt
|
|
|
98
98
|
|
|
99
99
|
## Commands
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
25 commands total. All support `--help` for full flag details.
|
|
102
102
|
|
|
103
103
|
### `cu init`
|
|
104
104
|
|
|
@@ -190,6 +190,7 @@ List subtasks of a task or initiative.
|
|
|
190
190
|
|
|
191
191
|
```bash
|
|
192
192
|
cu subtasks abc123
|
|
193
|
+
cu subtasks abc123 --include-closed
|
|
193
194
|
cu subtasks abc123 --json
|
|
194
195
|
```
|
|
195
196
|
|
|
@@ -205,18 +206,20 @@ cu update abc123 --priority high
|
|
|
205
206
|
cu update abc123 --due-date 2025-03-15
|
|
206
207
|
cu update abc123 --assignee 12345
|
|
207
208
|
cu update abc123 -n "New name" -s "done" --priority urgent
|
|
209
|
+
cu update abc123 --time-estimate 2h
|
|
208
210
|
cu update abc123 -s "in progress" --json
|
|
209
211
|
```
|
|
210
212
|
|
|
211
|
-
| Flag
|
|
212
|
-
|
|
|
213
|
-
| `-n, --name <text>`
|
|
214
|
-
| `-d, --description <text>`
|
|
215
|
-
| `-s, --status <status>`
|
|
216
|
-
| `--priority <level>`
|
|
217
|
-
| `--due-date <date>`
|
|
218
|
-
| `--
|
|
219
|
-
| `--
|
|
213
|
+
| Flag | Description |
|
|
214
|
+
| ---------------------------- | --------------------------------------------------------------------------- |
|
|
215
|
+
| `-n, --name <text>` | New task name |
|
|
216
|
+
| `-d, --description <text>` | New description (markdown supported) |
|
|
217
|
+
| `-s, --status <status>` | New status, supports fuzzy matching (e.g. `"prog"` matches `"in progress"`) |
|
|
218
|
+
| `--priority <level>` | Priority: `urgent`, `high`, `normal`, `low` (or 1-4) |
|
|
219
|
+
| `--due-date <date>` | Due date (`YYYY-MM-DD`) |
|
|
220
|
+
| `--time-estimate <duration>` | Time estimate (e.g. `"2h"`, `"30m"`, `"1h30m"`) |
|
|
221
|
+
| `--assignee <userId>` | Add assignee by numeric user ID |
|
|
222
|
+
| `--json` | Force JSON output even in terminal |
|
|
220
223
|
|
|
221
224
|
### `cu create`
|
|
222
225
|
|
|
@@ -228,21 +231,25 @@ cu create -n "Subtask name" -p <parentTaskId> # --list auto-detected
|
|
|
228
231
|
cu create -n "Task" -l <listId> -d "desc" -s "open"
|
|
229
232
|
cu create -n "Task" -l <listId> --priority high --due-date 2025-06-01
|
|
230
233
|
cu create -n "Task" -l <listId> --assignee 12345 --tags "bug,frontend"
|
|
234
|
+
cu create -n "Initiative" -l <listId> --custom-item-id 1
|
|
235
|
+
cu create -n "Task" -l <listId> --time-estimate 2h
|
|
231
236
|
cu create -n "Fix bug" -l <listId> --json
|
|
232
237
|
```
|
|
233
238
|
|
|
234
|
-
| Flag
|
|
235
|
-
|
|
|
236
|
-
| `-n, --name <name>`
|
|
237
|
-
| `-l, --list <listId>`
|
|
238
|
-
| `-p, --parent <taskId>`
|
|
239
|
-
| `-d, --description <text>`
|
|
240
|
-
| `-s, --status <status>`
|
|
241
|
-
| `--priority <level>`
|
|
242
|
-
| `--due-date <date>`
|
|
243
|
-
| `--
|
|
244
|
-
| `--
|
|
245
|
-
| `--
|
|
239
|
+
| Flag | Required | Description |
|
|
240
|
+
| ---------------------------- | ---------------- | ---------------------------------------------------- |
|
|
241
|
+
| `-n, --name <name>` | yes | Task name |
|
|
242
|
+
| `-l, --list <listId>` | if no `--parent` | Target list ID |
|
|
243
|
+
| `-p, --parent <taskId>` | no | Parent task (list auto-detected) |
|
|
244
|
+
| `-d, --description <text>` | no | Description (markdown) |
|
|
245
|
+
| `-s, --status <status>` | no | Initial status |
|
|
246
|
+
| `--priority <level>` | no | Priority: `urgent`, `high`, `normal`, `low` (or 1-4) |
|
|
247
|
+
| `--due-date <date>` | no | Due date (`YYYY-MM-DD`) |
|
|
248
|
+
| `--time-estimate <duration>` | no | Time estimate (e.g. `"2h"`, `"30m"`, `"1h30m"`) |
|
|
249
|
+
| `--assignee <userId>` | no | Assignee by numeric user ID |
|
|
250
|
+
| `--tags <tags>` | no | Comma-separated tag names |
|
|
251
|
+
| `--custom-item-id <id>` | no | Custom task type ID (for creating initiatives) |
|
|
252
|
+
| `--json` | no | Force JSON output even in terminal |
|
|
246
253
|
|
|
247
254
|
### `cu comment <id>`
|
|
248
255
|
|
|
@@ -367,6 +374,25 @@ cu assign abc123 --to me --json
|
|
|
367
374
|
| `--remove <userId>` | Remove assignee (user ID or `me`) |
|
|
368
375
|
| `--json` | Force JSON output |
|
|
369
376
|
|
|
377
|
+
### `cu depend <id>`
|
|
378
|
+
|
|
379
|
+
Add or remove task dependencies. Set a task as waiting on or blocking another task.
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
cu depend abc123 --on def456 # abc123 depends on (waits for) def456
|
|
383
|
+
cu depend abc123 --blocks def456 # abc123 blocks def456
|
|
384
|
+
cu depend abc123 --on def456 --remove # remove the dependency
|
|
385
|
+
cu depend abc123 --blocks def456 --remove
|
|
386
|
+
cu depend abc123 --on def456 --json
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
| Flag | Description |
|
|
390
|
+
| ------------------- | ------------------------------------------- |
|
|
391
|
+
| `--on <taskId>` | Task that this task depends on (waiting on) |
|
|
392
|
+
| `--blocks <taskId>` | Task that this task blocks |
|
|
393
|
+
| `--remove` | Remove the dependency instead of adding it |
|
|
394
|
+
| `--json` | Force JSON output |
|
|
395
|
+
|
|
370
396
|
### `cu auth`
|
|
371
397
|
|
|
372
398
|
Check authentication status. Validates your API token and shows your user info.
|
package/dist/index.js
CHANGED
|
@@ -135,6 +135,7 @@ var ClickUpClient = class {
|
|
|
135
135
|
const baseParams = new URLSearchParams({
|
|
136
136
|
subtasks: String(filters.subtasks ?? true)
|
|
137
137
|
});
|
|
138
|
+
if (filters.includeClosed) baseParams.set("include_closed", "true");
|
|
138
139
|
baseParams.append("assignees[]", String(me.id));
|
|
139
140
|
for (const s of filters.statuses ?? []) baseParams.append("statuses[]", s);
|
|
140
141
|
for (const id of filters.listIds ?? []) baseParams.append("list_ids[]", id);
|
|
@@ -161,9 +162,11 @@ var ClickUpClient = class {
|
|
|
161
162
|
const data = await this.request(`/task/${taskId}/comment`);
|
|
162
163
|
return data.comments ?? [];
|
|
163
164
|
}
|
|
164
|
-
async getTasksFromList(listId, params = {}) {
|
|
165
|
+
async getTasksFromList(listId, params = {}, options = {}) {
|
|
165
166
|
return this.paginate((page) => {
|
|
166
|
-
const
|
|
167
|
+
const base = { subtasks: "true", page: String(page), ...params };
|
|
168
|
+
if (options.includeClosed) base["include_closed"] = "true";
|
|
169
|
+
const qs = new URLSearchParams(base).toString();
|
|
167
170
|
return `/list/${listId}/task?${qs}`;
|
|
168
171
|
});
|
|
169
172
|
}
|
|
@@ -220,6 +223,23 @@ var ClickUpClient = class {
|
|
|
220
223
|
async getViewTasks(viewId) {
|
|
221
224
|
return this.paginate((page) => `/view/${viewId}/task?page=${page}`);
|
|
222
225
|
}
|
|
226
|
+
async addDependency(taskId, opts) {
|
|
227
|
+
const body = {};
|
|
228
|
+
if (opts.dependsOn) body.depends_on = opts.dependsOn;
|
|
229
|
+
if (opts.dependencyOf) body.dependency_of = opts.dependencyOf;
|
|
230
|
+
await this.request(`/task/${taskId}/dependency`, {
|
|
231
|
+
method: "POST",
|
|
232
|
+
body: JSON.stringify(body)
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
async deleteDependency(taskId, opts) {
|
|
236
|
+
const params = new URLSearchParams();
|
|
237
|
+
if (opts.dependsOn) params.set("depends_on", opts.dependsOn);
|
|
238
|
+
if (opts.dependencyOf) params.set("dependency_of", opts.dependencyOf);
|
|
239
|
+
await this.request(`/task/${taskId}/dependency?${params.toString()}`, {
|
|
240
|
+
method: "DELETE"
|
|
241
|
+
});
|
|
242
|
+
}
|
|
223
243
|
};
|
|
224
244
|
|
|
225
245
|
// src/output.ts
|
|
@@ -677,6 +697,18 @@ function parseAssigneeId(value) {
|
|
|
677
697
|
if (!Number.isInteger(id)) throw new Error("Assignee must be a numeric user ID");
|
|
678
698
|
return id;
|
|
679
699
|
}
|
|
700
|
+
function parseTimeEstimate(value) {
|
|
701
|
+
const pattern = /^(?:(\d+)h)?(?:(\d+)m)?$/i;
|
|
702
|
+
const match = value.match(pattern);
|
|
703
|
+
if (match && (match[1] || match[2])) {
|
|
704
|
+
const hours = Number(match[1] ?? 0);
|
|
705
|
+
const minutes = Number(match[2] ?? 0);
|
|
706
|
+
return (hours * 60 + minutes) * 60 * 1e3;
|
|
707
|
+
}
|
|
708
|
+
const ms = Number(value);
|
|
709
|
+
if (Number.isFinite(ms) && ms > 0) return ms;
|
|
710
|
+
throw new Error('Time estimate must be a duration (e.g. "2h", "30m", "1h30m") or milliseconds');
|
|
711
|
+
}
|
|
680
712
|
function buildUpdatePayload(opts) {
|
|
681
713
|
const payload = {};
|
|
682
714
|
if (opts.name !== void 0) payload.name = opts.name;
|
|
@@ -690,10 +722,13 @@ function buildUpdatePayload(opts) {
|
|
|
690
722
|
if (opts.assignee !== void 0) {
|
|
691
723
|
payload.assignees = { add: [parseAssigneeId(opts.assignee)] };
|
|
692
724
|
}
|
|
725
|
+
if (opts.timeEstimate !== void 0) {
|
|
726
|
+
payload.time_estimate = parseTimeEstimate(opts.timeEstimate);
|
|
727
|
+
}
|
|
693
728
|
return payload;
|
|
694
729
|
}
|
|
695
730
|
function hasUpdateFields(options) {
|
|
696
|
-
return options.name !== void 0 || options.description !== void 0 || options.status !== void 0 || options.priority !== void 0 || options.due_date !== void 0 || options.assignees !== void 0;
|
|
731
|
+
return options.name !== void 0 || options.description !== void 0 || options.status !== void 0 || options.priority !== void 0 || options.due_date !== void 0 || options.time_estimate !== void 0 || options.assignees !== void 0;
|
|
697
732
|
}
|
|
698
733
|
async function resolveStatus(client, taskId, statusInput) {
|
|
699
734
|
const task = await client.getTask(taskId);
|
|
@@ -713,7 +748,7 @@ async function resolveStatus(client, taskId, statusInput) {
|
|
|
713
748
|
async function updateTask(config, taskId, options) {
|
|
714
749
|
if (!hasUpdateFields(options))
|
|
715
750
|
throw new Error(
|
|
716
|
-
"Provide at least one of: --name, --description, --status, --priority, --due-date, --assignee"
|
|
751
|
+
"Provide at least one of: --name, --description, --status, --priority, --due-date, --time-estimate, --assignee"
|
|
717
752
|
);
|
|
718
753
|
const client = new ClickUpClient(config);
|
|
719
754
|
if (options.status !== void 0) {
|
|
@@ -753,6 +788,15 @@ async function createTask(config, options) {
|
|
|
753
788
|
if (options.tags !== void 0) {
|
|
754
789
|
payload.tags = options.tags.split(",").map((t) => t.trim());
|
|
755
790
|
}
|
|
791
|
+
if (options.customItemId !== void 0) {
|
|
792
|
+
const id = Number(options.customItemId);
|
|
793
|
+
if (!Number.isInteger(id) || id < 0)
|
|
794
|
+
throw new Error("Custom item ID must be a non-negative integer");
|
|
795
|
+
payload.custom_item_id = id;
|
|
796
|
+
}
|
|
797
|
+
if (options.timeEstimate !== void 0) {
|
|
798
|
+
payload.time_estimate = parseTimeEstimate(options.timeEstimate);
|
|
799
|
+
}
|
|
756
800
|
const task = await client.createTask(listId, payload);
|
|
757
801
|
return { id: task.id, name: task.name, url: task.url };
|
|
758
802
|
}
|
|
@@ -974,10 +1018,14 @@ async function listSprints(config, opts = {}) {
|
|
|
974
1018
|
}
|
|
975
1019
|
|
|
976
1020
|
// src/commands/subtasks.ts
|
|
977
|
-
async function fetchSubtasks(config, taskId) {
|
|
1021
|
+
async function fetchSubtasks(config, taskId, options = {}) {
|
|
978
1022
|
const client = new ClickUpClient(config);
|
|
979
1023
|
const parent = await client.getTask(taskId);
|
|
980
|
-
const tasks = await client.getTasksFromList(
|
|
1024
|
+
const tasks = await client.getTasksFromList(
|
|
1025
|
+
parent.list.id,
|
|
1026
|
+
{ parent: taskId, subtasks: "false" },
|
|
1027
|
+
{ includeClosed: options.includeClosed }
|
|
1028
|
+
);
|
|
981
1029
|
return tasks.map(summarize);
|
|
982
1030
|
}
|
|
983
1031
|
|
|
@@ -1244,7 +1292,9 @@ function groupByStatus(tasks, includeClosed) {
|
|
|
1244
1292
|
}
|
|
1245
1293
|
async function runAssignedCommand(config, opts) {
|
|
1246
1294
|
const client = new ClickUpClient(config);
|
|
1247
|
-
const allTasks = await client.getMyTasks(config.teamId
|
|
1295
|
+
const allTasks = await client.getMyTasks(config.teamId, {
|
|
1296
|
+
includeClosed: opts.includeClosed
|
|
1297
|
+
});
|
|
1248
1298
|
const groups = groupByStatus(allTasks, opts.includeClosed ?? false);
|
|
1249
1299
|
if (shouldOutputJson(opts.json ?? false)) {
|
|
1250
1300
|
const result = {};
|
|
@@ -1970,6 +2020,31 @@ async function searchTasks(config, query, opts = {}) {
|
|
|
1970
2020
|
return matched.map(summarize);
|
|
1971
2021
|
}
|
|
1972
2022
|
|
|
2023
|
+
// src/commands/depend.ts
|
|
2024
|
+
async function manageDependency(config, taskId, opts) {
|
|
2025
|
+
if (!opts.on && !opts.blocks) {
|
|
2026
|
+
throw new Error("Provide --on <taskId> or --blocks <taskId>");
|
|
2027
|
+
}
|
|
2028
|
+
if (opts.on && opts.blocks) {
|
|
2029
|
+
throw new Error("Provide only one of --on or --blocks per invocation");
|
|
2030
|
+
}
|
|
2031
|
+
const client = new ClickUpClient(config);
|
|
2032
|
+
if (opts.remove) {
|
|
2033
|
+
await client.deleteDependency(taskId, {
|
|
2034
|
+
dependsOn: opts.on,
|
|
2035
|
+
dependencyOf: opts.blocks
|
|
2036
|
+
});
|
|
2037
|
+
if (opts.on) return `Removed dependency: ${taskId} no longer depends on ${opts.on}`;
|
|
2038
|
+
return `Removed dependency: ${taskId} no longer blocks ${opts.blocks}`;
|
|
2039
|
+
}
|
|
2040
|
+
await client.addDependency(taskId, {
|
|
2041
|
+
dependsOn: opts.on,
|
|
2042
|
+
dependencyOf: opts.blocks
|
|
2043
|
+
});
|
|
2044
|
+
if (opts.on) return `Added dependency: ${taskId} depends on ${opts.on}`;
|
|
2045
|
+
return `Added dependency: ${taskId} blocks ${opts.blocks}`;
|
|
2046
|
+
}
|
|
2047
|
+
|
|
1973
2048
|
// src/index.ts
|
|
1974
2049
|
var require2 = createRequire(import.meta.url);
|
|
1975
2050
|
var { version } = require2("../package.json");
|
|
@@ -2041,7 +2116,7 @@ program.command("task <taskId>").description("Get task details").option("--json"
|
|
|
2041
2116
|
}
|
|
2042
2117
|
})
|
|
2043
2118
|
);
|
|
2044
|
-
program.command("update <taskId>").description("Update a task").option("-n, --name <text>", "New task name").option("-d, --description <text>", "New description (markdown supported)").option("-s, --status <status>", 'New status (e.g. "in progress", "done")').option("--priority <level>", "Priority: urgent, high, normal, low (or 1-4)").option("--due-date <date>", "Due date (YYYY-MM-DD)").option("--assignee <userId>", "Add assignee by user ID").option("--json", "Force JSON output even in terminal").action(
|
|
2119
|
+
program.command("update <taskId>").description("Update a task").option("-n, --name <text>", "New task name").option("-d, --description <text>", "New description (markdown supported)").option("-s, --status <status>", 'New status (e.g. "in progress", "done")').option("--priority <level>", "Priority: urgent, high, normal, low (or 1-4)").option("--due-date <date>", "Due date (YYYY-MM-DD)").option("--time-estimate <duration>", 'Time estimate (e.g. "2h", "30m", "1h30m")').option("--assignee <userId>", "Add assignee by user ID").option("--json", "Force JSON output even in terminal").action(
|
|
2045
2120
|
wrapAction(async (taskId, opts) => {
|
|
2046
2121
|
const config = loadConfig();
|
|
2047
2122
|
const payload = buildUpdatePayload(opts);
|
|
@@ -2053,7 +2128,7 @@ program.command("update <taskId>").description("Update a task").option("-n, --na
|
|
|
2053
2128
|
}
|
|
2054
2129
|
})
|
|
2055
2130
|
);
|
|
2056
|
-
program.command("create").description("Create a new task").option("-l, --list <listId>", "Target list ID (auto-detected from --parent if omitted)").requiredOption("-n, --name <name>", "Task name").option("-d, --description <text>", "Task description").option("-p, --parent <taskId>", "Parent task ID (list auto-detected from parent)").option("-s, --status <status>", "Initial status").option("--priority <level>", "Priority: urgent, high, normal, low (or 1-4)").option("--due-date <date>", "Due date (YYYY-MM-DD)").option("--assignee <userId>", "Assignee user ID").option("--tags <tags>", "Comma-separated tag names").option("--json", "Force JSON output even in terminal").action(
|
|
2131
|
+
program.command("create").description("Create a new task").option("-l, --list <listId>", "Target list ID (auto-detected from --parent if omitted)").requiredOption("-n, --name <name>", "Task name").option("-d, --description <text>", "Task description").option("-p, --parent <taskId>", "Parent task ID (list auto-detected from parent)").option("-s, --status <status>", "Initial status").option("--priority <level>", "Priority: urgent, high, normal, low (or 1-4)").option("--due-date <date>", "Due date (YYYY-MM-DD)").option("--assignee <userId>", "Assignee user ID").option("--tags <tags>", "Comma-separated tag names").option("--custom-item-id <id>", "Custom task type ID (use to create initiatives)").option("--time-estimate <duration>", 'Time estimate (e.g. "2h", "30m", "1h30m")').option("--json", "Force JSON output even in terminal").action(
|
|
2057
2132
|
wrapAction(async (opts) => {
|
|
2058
2133
|
const config = loadConfig();
|
|
2059
2134
|
const result = await createTask(config, opts);
|
|
@@ -2076,10 +2151,10 @@ program.command("sprints").description("List all sprints in sprint folders").opt
|
|
|
2076
2151
|
await listSprints(config, opts);
|
|
2077
2152
|
})
|
|
2078
2153
|
);
|
|
2079
|
-
program.command("subtasks <taskId>").description("List subtasks of a task or initiative").option("--json", "Force JSON output even in terminal").action(
|
|
2154
|
+
program.command("subtasks <taskId>").description("List subtasks of a task or initiative").option("--include-closed", "Include closed/done subtasks").option("--json", "Force JSON output even in terminal").action(
|
|
2080
2155
|
wrapAction(async (taskId, opts) => {
|
|
2081
2156
|
const config = loadConfig();
|
|
2082
|
-
const tasks = await fetchSubtasks(config, taskId);
|
|
2157
|
+
const tasks = await fetchSubtasks(config, taskId, { includeClosed: opts.includeClosed });
|
|
2083
2158
|
await printTasks(tasks, opts.json ?? false, config);
|
|
2084
2159
|
})
|
|
2085
2160
|
);
|
|
@@ -2181,6 +2256,17 @@ program.command("assign <taskId>").description("Assign or unassign users from a
|
|
|
2181
2256
|
}
|
|
2182
2257
|
})
|
|
2183
2258
|
);
|
|
2259
|
+
program.command("depend <taskId>").description("Add or remove task dependencies").option("--on <taskId>", "Task that this task depends on (waiting on)").option("--blocks <taskId>", "Task that this task blocks").option("--remove", "Remove the dependency instead of adding it").option("--json", "Force JSON output even in terminal").action(
|
|
2260
|
+
wrapAction(async (taskId, opts) => {
|
|
2261
|
+
const config = loadConfig();
|
|
2262
|
+
const message = await manageDependency(config, taskId, opts);
|
|
2263
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
2264
|
+
console.log(JSON.stringify({ taskId, ...opts, message }, null, 2));
|
|
2265
|
+
} else {
|
|
2266
|
+
console.log(message);
|
|
2267
|
+
}
|
|
2268
|
+
})
|
|
2269
|
+
);
|
|
2184
2270
|
var configCmd = program.command("config").description("Manage CLI configuration");
|
|
2185
2271
|
configCmd.command("get <key>").description("Print a config value").action(
|
|
2186
2272
|
wrapAction(async (key) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: clickup
|
|
3
|
-
description: 'Use when managing ClickUp tasks, initiatives, 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.'
|
|
3
|
+
description: 'Use when managing ClickUp tasks, initiatives, 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.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# ClickUp CLI (`cu`)
|
|
@@ -43,7 +43,7 @@ All commands support `--help` for full flag details.
|
|
|
43
43
|
| `cu sprints [--space nameOrId] [--json]` | List all sprints (marks active with \*) |
|
|
44
44
|
| `cu search <query> [--status s] [--json]` | Search my tasks by name (multi-word, fuzzy status) |
|
|
45
45
|
| `cu task <id> [--json]` | Single task details |
|
|
46
|
-
| `cu subtasks <id> [--json]`
|
|
46
|
+
| `cu subtasks <id> [--include-closed] [--json]` | Subtasks of a task or initiative |
|
|
47
47
|
| `cu comments <id> [--json]` | Comments on a task |
|
|
48
48
|
| `cu activity <id> [--json]` | Task details + comment history combined |
|
|
49
49
|
| `cu inbox [--days n] [--json]` | Tasks updated in last n days (default 30) |
|
|
@@ -56,14 +56,15 @@ All commands support `--help` for full flag details.
|
|
|
56
56
|
|
|
57
57
|
### Write
|
|
58
58
|
|
|
59
|
-
| Command
|
|
60
|
-
|
|
|
61
|
-
| `cu update <id> [-n name] [-d desc] [-s status] [--priority p] [--due-date d] [--assignee id] [--json]`
|
|
62
|
-
| `cu create -n name [-l listId] [-p parentId] [-d desc] [-s status] [--priority p] [--due-date d] [--assignee id] [--tags t] [--json]` | Create task (list auto-detected from parent) |
|
|
63
|
-
| `cu comment <id> -m text`
|
|
64
|
-
| `cu assign <id> [--to userId\|me] [--remove userId\|me] [--json]`
|
|
65
|
-
| `cu
|
|
66
|
-
| `cu
|
|
59
|
+
| Command | What it does |
|
|
60
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------- |
|
|
61
|
+
| `cu update <id> [-n name] [-d desc] [-s status] [--priority p] [--due-date d] [--time-estimate t] [--assignee id] [--json]` | Update task fields |
|
|
62
|
+
| `cu create -n name [-l listId] [-p parentId] [-d desc] [-s status] [--priority p] [--due-date d] [--time-estimate t] [--assignee id] [--tags t] [--custom-item-id n] [--json]` | Create task (list auto-detected from parent) |
|
|
63
|
+
| `cu comment <id> -m text` | Post comment on task |
|
|
64
|
+
| `cu assign <id> [--to userId\|me] [--remove userId\|me] [--json]` | Assign/unassign users |
|
|
65
|
+
| `cu depend <id> [--on taskId] [--blocks taskId] [--remove] [--json]` | Add/remove task dependencies |
|
|
66
|
+
| `cu config get <key>` / `cu config set <key> <value>` / `cu config path` | Manage CLI config |
|
|
67
|
+
| `cu completion <shell>` | Shell completions (bash/zsh/fish) |
|
|
67
68
|
|
|
68
69
|
## Quick Reference
|
|
69
70
|
|
|
@@ -77,8 +78,12 @@ All commands support `--help` for full flag details.
|
|
|
77
78
|
| `--due-date` | `YYYY-MM-DD` format |
|
|
78
79
|
| `--assignee` | Numeric user ID (find via `cu task <id> --json`) |
|
|
79
80
|
| `--tags` | Comma-separated (e.g. `--tags "bug,frontend"`) |
|
|
81
|
+
| `--time-estimate` | Duration format: `"2h"`, `"30m"`, `"1h30m"`, or raw milliseconds |
|
|
82
|
+
| `--custom-item-id` | Custom task type ID (e.g. `1` for initiative) |
|
|
83
|
+
| `--on` / `--blocks` | Task dependency direction (used with `cu depend`) |
|
|
80
84
|
| `--space` | Partial name match or exact ID |
|
|
81
85
|
| `--name` | Partial match, case-insensitive |
|
|
86
|
+
| `--include-closed` | Include closed/done tasks (on `subtasks` and `assigned`) |
|
|
82
87
|
| `cu assign --to me` | Shorthand for your own user ID |
|
|
83
88
|
| `cu search` | Matches all query words against task name, case-insensitive |
|
|
84
89
|
| `cu sprint` | Auto-detects active sprint via view API and date range parsing |
|
|
@@ -96,7 +101,8 @@ All commands support `--help` for full flag details.
|
|
|
96
101
|
|
|
97
102
|
```bash
|
|
98
103
|
cu task abc123def # markdown summary
|
|
99
|
-
cu subtasks abc123def # child tasks
|
|
104
|
+
cu subtasks abc123def # child tasks (open only)
|
|
105
|
+
cu subtasks abc123def --include-closed # all child tasks
|
|
100
106
|
cu comments abc123def # discussion
|
|
101
107
|
cu activity abc123def # task + comments combined
|
|
102
108
|
```
|
|
@@ -119,17 +125,22 @@ cu inbox --days 7 # recently updated
|
|
|
119
125
|
```bash
|
|
120
126
|
cu update abc123def -s "done"
|
|
121
127
|
cu update abc123def --priority high --due-date 2025-03-15
|
|
128
|
+
cu update abc123def --time-estimate 2h
|
|
122
129
|
cu create -n "Fix the thing" -p abc123def
|
|
123
130
|
cu create -n "Fix bug" -l <listId> --priority urgent --tags "bug,frontend"
|
|
131
|
+
cu create -n "Q3 Roadmap" -l <listId> --custom-item-id 1 # create initiative
|
|
124
132
|
cu comment abc123def -m "Completed in PR #42"
|
|
125
133
|
cu assign abc123def --to me
|
|
134
|
+
cu depend task3 --on task2 # task3 waits for task2
|
|
135
|
+
cu depend task1 --blocks task2 # task1 blocks task2
|
|
126
136
|
```
|
|
127
137
|
|
|
128
138
|
### Discover workspace structure
|
|
129
139
|
|
|
130
140
|
```bash
|
|
131
141
|
cu spaces # all spaces
|
|
132
|
-
cu
|
|
142
|
+
cu spaces --name "Engineering" # find space ID by name
|
|
143
|
+
cu lists <spaceId> # lists in a space (needs ID from cu spaces)
|
|
133
144
|
cu sprints # all sprints across folders
|
|
134
145
|
cu auth # verify token works
|
|
135
146
|
```
|