@krodak/clickup-cli 0.11.1 → 0.12.1
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 +30 -7
- package/dist/index.js +74 -34
- package/package.json +1 -1
- package/skills/clickup-cli/SKILL.md +41 -37
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
|
+
27 commands total. All support `--help` for full flag details.
|
|
102
102
|
|
|
103
103
|
### `cu init`
|
|
104
104
|
|
|
@@ -153,6 +153,7 @@ List all sprints across sprint folders. Marks the currently active sprint.
|
|
|
153
153
|
|
|
154
154
|
```bash
|
|
155
155
|
cu sprints
|
|
156
|
+
cu sprints --space "Engineering"
|
|
156
157
|
cu sprints --json
|
|
157
158
|
```
|
|
158
159
|
|
|
@@ -174,6 +175,7 @@ Tasks assigned to me that were recently updated, grouped by time period (today,
|
|
|
174
175
|
```bash
|
|
175
176
|
cu inbox
|
|
176
177
|
cu inbox --days 7
|
|
178
|
+
cu inbox --include-closed
|
|
177
179
|
cu inbox --json
|
|
178
180
|
```
|
|
179
181
|
|
|
@@ -213,6 +215,7 @@ cu update abc123 --due-date 2025-03-15
|
|
|
213
215
|
cu update abc123 --assignee 12345
|
|
214
216
|
cu update abc123 -n "New name" -s "done" --priority urgent
|
|
215
217
|
cu update abc123 --time-estimate 2h
|
|
218
|
+
cu update abc123 --parent parentTaskId # make it a subtask
|
|
216
219
|
cu update abc123 -s "in progress" --json
|
|
217
220
|
```
|
|
218
221
|
|
|
@@ -225,6 +228,7 @@ cu update abc123 -s "in progress" --json
|
|
|
225
228
|
| `--due-date <date>` | Due date (`YYYY-MM-DD`) |
|
|
226
229
|
| `--time-estimate <duration>` | Time estimate (e.g. `"2h"`, `"30m"`, `"1h30m"`) |
|
|
227
230
|
| `--assignee <userId>` | Add assignee by numeric user ID |
|
|
231
|
+
| `--parent <taskId>` | Set parent task (makes this a subtask) |
|
|
228
232
|
| `--json` | Force JSON output even in terminal |
|
|
229
233
|
|
|
230
234
|
### `cu create`
|
|
@@ -263,6 +267,7 @@ Post a comment on a task.
|
|
|
263
267
|
|
|
264
268
|
```bash
|
|
265
269
|
cu comment abc123 -m "Addressed in PR #42"
|
|
270
|
+
cu comment abc123 -m "Done" --json
|
|
266
271
|
```
|
|
267
272
|
|
|
268
273
|
### `cu comments <id>`
|
|
@@ -309,11 +314,11 @@ cu spaces --my
|
|
|
309
314
|
cu spaces --json
|
|
310
315
|
```
|
|
311
316
|
|
|
312
|
-
| Flag | Description
|
|
313
|
-
| ------------------ |
|
|
314
|
-
| `--name <partial>` | Filter spaces by partial name match
|
|
315
|
-
| `--my` | Show only spaces
|
|
316
|
-
| `--json` | Force JSON output
|
|
317
|
+
| Flag | Description |
|
|
318
|
+
| ------------------ | -------------------------------------------- |
|
|
319
|
+
| `--name <partial>` | Filter spaces by partial name match |
|
|
320
|
+
| `--my` | Show only spaces where I have assigned tasks |
|
|
321
|
+
| `--json` | Force JSON output |
|
|
317
322
|
|
|
318
323
|
### `cu open <query>`
|
|
319
324
|
|
|
@@ -356,10 +361,11 @@ cu summary --json
|
|
|
356
361
|
|
|
357
362
|
### `cu overdue`
|
|
358
363
|
|
|
359
|
-
List tasks that are past their due date (excludes done/closed tasks). Sorted most overdue first.
|
|
364
|
+
List tasks that are past their due date (excludes done/closed tasks by default). Sorted most overdue first.
|
|
360
365
|
|
|
361
366
|
```bash
|
|
362
367
|
cu overdue
|
|
368
|
+
cu overdue --include-closed
|
|
363
369
|
cu overdue --json
|
|
364
370
|
```
|
|
365
371
|
|
|
@@ -400,6 +406,23 @@ cu depend abc123 --on def456 --json
|
|
|
400
406
|
| `--remove` | Remove the dependency instead of adding it |
|
|
401
407
|
| `--json` | Force JSON output |
|
|
402
408
|
|
|
409
|
+
### `cu move <id>`
|
|
410
|
+
|
|
411
|
+
Add or remove a task from a list. Tasks can belong to multiple lists in ClickUp.
|
|
412
|
+
|
|
413
|
+
```bash
|
|
414
|
+
cu move abc123 --to <listId> # add task to a list
|
|
415
|
+
cu move abc123 --remove <listId> # remove task from a list
|
|
416
|
+
cu move abc123 --to <newListId> --remove <oldListId> # move between lists
|
|
417
|
+
cu move abc123 --to <listId> --json
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
| Flag | Description |
|
|
421
|
+
| ------------------- | -------------------------- |
|
|
422
|
+
| `--to <listId>` | Add task to this list |
|
|
423
|
+
| `--remove <listId>` | Remove task from this list |
|
|
424
|
+
| `--json` | Force JSON output |
|
|
425
|
+
|
|
403
426
|
### `cu auth`
|
|
404
427
|
|
|
405
428
|
Check authentication status. Validates your API token and shows your user info.
|
package/dist/index.js
CHANGED
|
@@ -175,7 +175,7 @@ var ClickUpClient = class {
|
|
|
175
175
|
return this.getTasksFromList(listId, { "assignees[]": String(me.id) });
|
|
176
176
|
}
|
|
177
177
|
async getTask(taskId) {
|
|
178
|
-
return this.request(`/task/${taskId}`);
|
|
178
|
+
return this.request(`/task/${taskId}?include_markdown_description=true`);
|
|
179
179
|
}
|
|
180
180
|
async updateTaskMarkdown(taskId, markdown) {
|
|
181
181
|
return this.updateTask(taskId, { markdown_content: markdown });
|
|
@@ -223,6 +223,12 @@ var ClickUpClient = class {
|
|
|
223
223
|
async getViewTasks(viewId) {
|
|
224
224
|
return this.paginate((page) => `/view/${viewId}/task?page=${page}`);
|
|
225
225
|
}
|
|
226
|
+
async addTaskToList(taskId, listId) {
|
|
227
|
+
await this.request(`/list/${listId}/task/${taskId}`, { method: "POST" });
|
|
228
|
+
}
|
|
229
|
+
async removeTaskFromList(taskId, listId) {
|
|
230
|
+
await this.request(`/list/${listId}/task/${taskId}`, { method: "DELETE" });
|
|
231
|
+
}
|
|
226
232
|
async addDependency(taskId, opts) {
|
|
227
233
|
const body = {};
|
|
228
234
|
if (opts.dependsOn) body.depends_on = opts.dependsOn;
|
|
@@ -281,6 +287,8 @@ var TASK_COLUMNS = [
|
|
|
281
287
|
{ key: "id", label: "ID" },
|
|
282
288
|
{ key: "name", label: "NAME", maxWidth: 60 },
|
|
283
289
|
{ key: "status", label: "STATUS" },
|
|
290
|
+
{ key: "priority", label: "PRIORITY" },
|
|
291
|
+
{ key: "due_date", label: "DUE" },
|
|
284
292
|
{ key: "list", label: "LIST" }
|
|
285
293
|
];
|
|
286
294
|
|
|
@@ -302,6 +310,8 @@ var TASK_MD_COLUMNS = [
|
|
|
302
310
|
{ key: "id", label: "ID" },
|
|
303
311
|
{ key: "name", label: "Name" },
|
|
304
312
|
{ key: "status", label: "Status" },
|
|
313
|
+
{ key: "priority", label: "Priority" },
|
|
314
|
+
{ key: "due_date", label: "Due" },
|
|
305
315
|
{ key: "list", label: "List" }
|
|
306
316
|
];
|
|
307
317
|
function formatTasksMarkdown(tasks) {
|
|
@@ -385,8 +395,9 @@ function formatTaskDetailMarkdown(task) {
|
|
|
385
395
|
lines.push(`**${label}:** ${value}`);
|
|
386
396
|
}
|
|
387
397
|
}
|
|
388
|
-
|
|
389
|
-
|
|
398
|
+
const descriptionContent = task.markdown_content ?? task.description;
|
|
399
|
+
if (descriptionContent) {
|
|
400
|
+
lines.push("", "## Description", "", descriptionContent);
|
|
390
401
|
}
|
|
391
402
|
return lines.join("\n");
|
|
392
403
|
}
|
|
@@ -614,12 +625,22 @@ function isDoneStatus(status) {
|
|
|
614
625
|
function isInitiative(task) {
|
|
615
626
|
return (task.custom_item_id ?? 0) !== 0;
|
|
616
627
|
}
|
|
628
|
+
function formatDueDate(ms) {
|
|
629
|
+
if (!ms) return "";
|
|
630
|
+
const d = new Date(Number(ms));
|
|
631
|
+
const year = d.getUTCFullYear();
|
|
632
|
+
const month = String(d.getUTCMonth() + 1).padStart(2, "0");
|
|
633
|
+
const day = String(d.getUTCDate()).padStart(2, "0");
|
|
634
|
+
return `${year}-${month}-${day}`;
|
|
635
|
+
}
|
|
617
636
|
function summarize(task) {
|
|
618
637
|
return {
|
|
619
638
|
id: task.id,
|
|
620
639
|
name: task.name,
|
|
621
640
|
status: task.status.status,
|
|
622
641
|
task_type: isInitiative(task) ? "initiative" : "task",
|
|
642
|
+
priority: task.priority?.priority ?? "none",
|
|
643
|
+
due_date: formatDueDate(task.due_date),
|
|
623
644
|
list: task.list.name,
|
|
624
645
|
url: task.url,
|
|
625
646
|
...task.parent ? { parent: task.parent } : {}
|
|
@@ -725,10 +746,11 @@ function buildUpdatePayload(opts) {
|
|
|
725
746
|
if (opts.timeEstimate !== void 0) {
|
|
726
747
|
payload.time_estimate = parseTimeEstimate(opts.timeEstimate);
|
|
727
748
|
}
|
|
749
|
+
if (opts.parent !== void 0) payload.parent = opts.parent;
|
|
728
750
|
return payload;
|
|
729
751
|
}
|
|
730
752
|
function hasUpdateFields(options) {
|
|
731
|
-
return options.name !== void 0 || options.description !== void 0 || options.markdown_content !== void 0 || options.status !== void 0 || options.priority !== void 0 || options.due_date !== void 0 || options.time_estimate !== void 0 || options.assignees !== void 0;
|
|
753
|
+
return options.name !== void 0 || options.description !== void 0 || options.markdown_content !== void 0 || options.status !== void 0 || options.priority !== void 0 || options.due_date !== void 0 || options.time_estimate !== void 0 || options.assignees !== void 0 || options.parent !== void 0;
|
|
732
754
|
}
|
|
733
755
|
async function resolveStatus(client, taskId, statusInput) {
|
|
734
756
|
const task = await client.getTask(taskId);
|
|
@@ -748,7 +770,7 @@ async function resolveStatus(client, taskId, statusInput) {
|
|
|
748
770
|
async function updateTask(config, taskId, options) {
|
|
749
771
|
if (!hasUpdateFields(options))
|
|
750
772
|
throw new Error(
|
|
751
|
-
"Provide at least one of: --name, --description, --status, --priority, --due-date, --time-estimate, --assignee"
|
|
773
|
+
"Provide at least one of: --name, --description, --status, --priority, --due-date, --time-estimate, --assignee, --parent"
|
|
752
774
|
);
|
|
753
775
|
const client = new ClickUpClient(config);
|
|
754
776
|
if (options.status !== void 0) {
|
|
@@ -1181,9 +1203,12 @@ function groupTasks(tasks, now) {
|
|
|
1181
1203
|
}
|
|
1182
1204
|
return groups;
|
|
1183
1205
|
}
|
|
1184
|
-
async function fetchInbox(config, days = 30) {
|
|
1206
|
+
async function fetchInbox(config, days = 30, opts = {}) {
|
|
1185
1207
|
const client = new ClickUpClient(config);
|
|
1186
|
-
const tasks = await client.getMyTasks(config.teamId, {
|
|
1208
|
+
const tasks = await client.getMyTasks(config.teamId, {
|
|
1209
|
+
subtasks: true,
|
|
1210
|
+
includeClosed: opts.includeClosed
|
|
1211
|
+
});
|
|
1187
1212
|
const cutoff = Date.now() - days * 24 * 60 * 60 * 1e3;
|
|
1188
1213
|
return tasks.filter((t) => Number(t.date_updated ?? 0) > cutoff).sort((a, b) => Number(b.date_updated ?? 0) - Number(a.date_updated ?? 0)).map(summarizeWithDate);
|
|
1189
1214
|
}
|
|
@@ -1258,7 +1283,6 @@ async function listSpaces(config, opts) {
|
|
|
1258
1283
|
}
|
|
1259
1284
|
|
|
1260
1285
|
// src/commands/assigned.ts
|
|
1261
|
-
var CLOSED_STATUSES = /* @__PURE__ */ new Set(["done", "closed", "complete", "completed"]);
|
|
1262
1286
|
var STATUS_ORDER = [
|
|
1263
1287
|
"code review",
|
|
1264
1288
|
"in review",
|
|
@@ -1270,18 +1294,6 @@ var STATUS_ORDER = [
|
|
|
1270
1294
|
"backlog",
|
|
1271
1295
|
"blocked"
|
|
1272
1296
|
];
|
|
1273
|
-
function toJsonTask(task, summary) {
|
|
1274
|
-
return {
|
|
1275
|
-
id: summary.id,
|
|
1276
|
-
name: summary.name,
|
|
1277
|
-
status: summary.status,
|
|
1278
|
-
task_type: summary.task_type,
|
|
1279
|
-
list: summary.list,
|
|
1280
|
-
url: summary.url,
|
|
1281
|
-
priority: task.priority?.priority ?? null,
|
|
1282
|
-
due_date: task.due_date ?? null
|
|
1283
|
-
};
|
|
1284
|
-
}
|
|
1285
1297
|
function statusSortKey(status) {
|
|
1286
1298
|
const idx = STATUS_ORDER.indexOf(status.toLowerCase());
|
|
1287
1299
|
return idx === -1 ? STATUS_ORDER.length : idx;
|
|
@@ -1290,16 +1302,15 @@ function groupByStatus(tasks, includeClosed) {
|
|
|
1290
1302
|
const groups = /* @__PURE__ */ new Map();
|
|
1291
1303
|
for (const task of tasks) {
|
|
1292
1304
|
const status = task.status.status;
|
|
1293
|
-
|
|
1294
|
-
if (!includeClosed && CLOSED_STATUSES.has(key)) continue;
|
|
1305
|
+
if (!includeClosed && isDoneStatus(status)) continue;
|
|
1295
1306
|
if (!groups.has(status)) {
|
|
1296
1307
|
groups.set(status, []);
|
|
1297
1308
|
}
|
|
1298
1309
|
groups.get(status).push(task);
|
|
1299
1310
|
}
|
|
1300
1311
|
return Array.from(groups.entries()).sort((a, b) => {
|
|
1301
|
-
const aIsClosed =
|
|
1302
|
-
const bIsClosed =
|
|
1312
|
+
const aIsClosed = isDoneStatus(a[0]);
|
|
1313
|
+
const bIsClosed = isDoneStatus(b[0]);
|
|
1303
1314
|
if (aIsClosed !== bIsClosed) return aIsClosed ? 1 : -1;
|
|
1304
1315
|
return statusSortKey(a[0]) - statusSortKey(b[0]);
|
|
1305
1316
|
}).map(([status, tasks2]) => ({ status, tasks: tasks2 }));
|
|
@@ -1317,7 +1328,7 @@ async function runAssignedCommand(config, opts) {
|
|
|
1317
1328
|
if (shouldOutputJson(opts.json ?? false)) {
|
|
1318
1329
|
const result = {};
|
|
1319
1330
|
for (const group of groups) {
|
|
1320
|
-
result[group.status.toLowerCase()] = group.tasks.map(
|
|
1331
|
+
result[group.status.toLowerCase()] = group.tasks.map(summarize);
|
|
1321
1332
|
}
|
|
1322
1333
|
console.log(JSON.stringify(result, null, 2));
|
|
1323
1334
|
return;
|
|
@@ -1450,7 +1461,7 @@ ${label} (${tasks.length})`);
|
|
|
1450
1461
|
}
|
|
1451
1462
|
async function runSummaryCommand(config, opts) {
|
|
1452
1463
|
const client = new ClickUpClient(config);
|
|
1453
|
-
const allTasks = await client.getMyTasks(config.teamId);
|
|
1464
|
+
const allTasks = await client.getMyTasks(config.teamId, { includeClosed: true });
|
|
1454
1465
|
const result = categorizeTasks(allTasks, opts.hours);
|
|
1455
1466
|
if (shouldOutputJson(opts.json)) {
|
|
1456
1467
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -1475,11 +1486,11 @@ function isOverdue2(task, now) {
|
|
|
1475
1486
|
if (!task.due_date) return false;
|
|
1476
1487
|
return Number(task.due_date) < now;
|
|
1477
1488
|
}
|
|
1478
|
-
async function fetchOverdueTasks(config) {
|
|
1489
|
+
async function fetchOverdueTasks(config, opts = {}) {
|
|
1479
1490
|
const client = new ClickUpClient(config);
|
|
1480
|
-
const allTasks = await client.getMyTasks(config.teamId);
|
|
1491
|
+
const allTasks = await client.getMyTasks(config.teamId, { includeClosed: opts.includeClosed });
|
|
1481
1492
|
const now = Date.now();
|
|
1482
|
-
return allTasks.filter((t) => isOverdue2(t, now) && !isDoneStatus(t.status.status)).sort((a, b) => Number(a.due_date) - Number(b.due_date)).map(summarize);
|
|
1493
|
+
return allTasks.filter((t) => isOverdue2(t, now) && (opts.includeClosed || !isDoneStatus(t.status.status))).sort((a, b) => Number(a.due_date) - Number(b.due_date)).map(summarize);
|
|
1483
1494
|
}
|
|
1484
1495
|
|
|
1485
1496
|
// src/commands/config.ts
|
|
@@ -2075,6 +2086,24 @@ async function manageDependency(config, taskId, opts) {
|
|
|
2075
2086
|
return `Added dependency: ${taskId} blocks ${opts.blocks}`;
|
|
2076
2087
|
}
|
|
2077
2088
|
|
|
2089
|
+
// src/commands/move.ts
|
|
2090
|
+
async function moveTask(config, taskId, opts) {
|
|
2091
|
+
if (!opts.to && !opts.remove) {
|
|
2092
|
+
throw new Error("Provide --to <listId> or --remove <listId>");
|
|
2093
|
+
}
|
|
2094
|
+
const client = new ClickUpClient(config);
|
|
2095
|
+
const messages = [];
|
|
2096
|
+
if (opts.to) {
|
|
2097
|
+
await client.addTaskToList(taskId, opts.to);
|
|
2098
|
+
messages.push(`Added ${taskId} to list ${opts.to}`);
|
|
2099
|
+
}
|
|
2100
|
+
if (opts.remove) {
|
|
2101
|
+
await client.removeTaskFromList(taskId, opts.remove);
|
|
2102
|
+
messages.push(`Removed ${taskId} from list ${opts.remove}`);
|
|
2103
|
+
}
|
|
2104
|
+
return messages.join("; ");
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2078
2107
|
// src/index.ts
|
|
2079
2108
|
var require2 = createRequire(import.meta.url);
|
|
2080
2109
|
var { version } = require2("../package.json");
|
|
@@ -2147,7 +2176,7 @@ program.command("task <taskId>").description("Get task details").option("--json"
|
|
|
2147
2176
|
}
|
|
2148
2177
|
})
|
|
2149
2178
|
);
|
|
2150
|
-
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(
|
|
2179
|
+
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("--parent <taskId>", "Set parent task (makes this a subtask)").option("--json", "Force JSON output even in terminal").action(
|
|
2151
2180
|
wrapAction(async (taskId, opts) => {
|
|
2152
2181
|
const config = loadConfig();
|
|
2153
2182
|
const payload = buildUpdatePayload(opts);
|
|
@@ -2239,14 +2268,14 @@ program.command("spaces").description("List spaces in your workspace").option("-
|
|
|
2239
2268
|
await listSpaces(config, opts);
|
|
2240
2269
|
})
|
|
2241
2270
|
);
|
|
2242
|
-
program.command("inbox").description("Recently updated tasks grouped by time period").option("--json", "Force JSON output even in terminal").option("--days <n>", "Lookback period in days", "30").action(
|
|
2271
|
+
program.command("inbox").description("Recently updated tasks grouped by time period").option("--include-closed", "Include done/closed tasks").option("--json", "Force JSON output even in terminal").option("--days <n>", "Lookback period in days", "30").action(
|
|
2243
2272
|
wrapAction(async (opts) => {
|
|
2244
2273
|
const config = loadConfig();
|
|
2245
2274
|
const days = Number(opts.days ?? 30);
|
|
2246
2275
|
if (!Number.isFinite(days) || days <= 0) {
|
|
2247
2276
|
throw new Error("--days must be a positive number");
|
|
2248
2277
|
}
|
|
2249
|
-
const tasks = await fetchInbox(config, days);
|
|
2278
|
+
const tasks = await fetchInbox(config, days, { includeClosed: opts.includeClosed });
|
|
2250
2279
|
await printInbox(tasks, opts.json ?? false, config);
|
|
2251
2280
|
})
|
|
2252
2281
|
);
|
|
@@ -2284,10 +2313,10 @@ program.command("summary").description("Daily standup summary: completed, in-pro
|
|
|
2284
2313
|
await runSummaryCommand(config, { hours, json: opts.json ?? false });
|
|
2285
2314
|
})
|
|
2286
2315
|
);
|
|
2287
|
-
program.command("overdue").description("List tasks that are past their due date").option("--json", "Force JSON output even in terminal").action(
|
|
2316
|
+
program.command("overdue").description("List tasks that are past their due date").option("--include-closed", "Include done/closed overdue tasks").option("--json", "Force JSON output even in terminal").action(
|
|
2288
2317
|
wrapAction(async (opts) => {
|
|
2289
2318
|
const config = loadConfig();
|
|
2290
|
-
const tasks = await fetchOverdueTasks(config);
|
|
2319
|
+
const tasks = await fetchOverdueTasks(config, { includeClosed: opts.includeClosed });
|
|
2291
2320
|
await printTasks(tasks, opts.json ?? false, config);
|
|
2292
2321
|
})
|
|
2293
2322
|
);
|
|
@@ -2313,6 +2342,17 @@ program.command("depend <taskId>").description("Add or remove task dependencies"
|
|
|
2313
2342
|
}
|
|
2314
2343
|
})
|
|
2315
2344
|
);
|
|
2345
|
+
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(
|
|
2346
|
+
wrapAction(async (taskId, opts) => {
|
|
2347
|
+
const config = loadConfig();
|
|
2348
|
+
const message = await moveTask(config, taskId, opts);
|
|
2349
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
2350
|
+
console.log(JSON.stringify({ taskId, ...opts, message }, null, 2));
|
|
2351
|
+
} else {
|
|
2352
|
+
console.log(message);
|
|
2353
|
+
}
|
|
2354
|
+
})
|
|
2355
|
+
);
|
|
2316
2356
|
var configCmd = program.command("config").description("Manage CLI configuration");
|
|
2317
2357
|
configCmd.command("get <key>").description("Print a config value").action(
|
|
2318
2358
|
wrapAction(async (key) => {
|
package/package.json
CHANGED
|
@@ -46,9 +46,9 @@ All commands support `--help` for full flag details.
|
|
|
46
46
|
| `cu subtasks <id> [--status s] [--name q] [--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
|
-
| `cu inbox [--days n] [--json]`
|
|
49
|
+
| `cu inbox [--days n] [--include-closed] [--json]` | Tasks updated in last n days (default 30) |
|
|
50
50
|
| `cu summary [--hours n] [--json]` | Standup helper: completed, in-progress, overdue |
|
|
51
|
-
| `cu overdue [--json]`
|
|
51
|
+
| `cu overdue [--include-closed] [--json]` | Tasks past their due date |
|
|
52
52
|
| `cu spaces [--name partial] [--my] [--json]` | List/filter workspace spaces |
|
|
53
53
|
| `cu lists <spaceId> [--name partial] [--json]` | Lists in a space (including folder lists) |
|
|
54
54
|
| `cu open <query> [--json]` | Open task in browser by ID or name |
|
|
@@ -56,44 +56,46 @@ All commands support `--help` for full flag details.
|
|
|
56
56
|
|
|
57
57
|
### Write
|
|
58
58
|
|
|
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]`
|
|
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 (
|
|
63
|
-
| `cu comment <id> -m text`
|
|
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
|
|
67
|
-
| `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] [--parent id] [--json]` | Update task fields (desc supports markdown) |
|
|
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 (desc supports markdown) |
|
|
63
|
+
| `cu comment <id> -m text [--json]` | 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 move <id> [--to listId] [--remove listId] [--json]` | Add/remove task from lists |
|
|
67
|
+
| `cu config get <key>` / `cu config set <key> <value>` / `cu config path` | Manage CLI config |
|
|
68
|
+
| `cu completion <shell>` | Shell completions (bash/zsh/fish) |
|
|
68
69
|
|
|
69
70
|
## Quick Reference
|
|
70
71
|
|
|
71
|
-
| Topic | Detail
|
|
72
|
-
| ------------------- |
|
|
73
|
-
| Task IDs | Stable alphanumeric strings (e.g. `abc123def`)
|
|
74
|
-
| Initiatives | Detected via `custom_item_id !== 0`
|
|
75
|
-
| `--list` on create | Optional when `--parent` is given (auto-detected)
|
|
76
|
-
| `--status` | Fuzzy matching: exact > starts-with > contains. Prints match to stderr.
|
|
77
|
-
| `--priority` | Names (`urgent`, `high`, `normal`, `low`) or numbers (1-4)
|
|
78
|
-
| `--due-date` | `YYYY-MM-DD` format
|
|
79
|
-
| `--assignee` | Numeric user ID (find via `cu task <id> --json`)
|
|
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`)
|
|
84
|
-
| `--
|
|
85
|
-
| `--
|
|
86
|
-
| `--
|
|
87
|
-
| `
|
|
88
|
-
| `cu
|
|
89
|
-
| `cu
|
|
90
|
-
| `cu
|
|
91
|
-
| `cu
|
|
92
|
-
| `cu
|
|
93
|
-
| `cu
|
|
94
|
-
| `cu
|
|
95
|
-
|
|
|
96
|
-
|
|
|
72
|
+
| Topic | Detail |
|
|
73
|
+
| ------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
74
|
+
| Task IDs | Stable alphanumeric strings (e.g. `abc123def`) |
|
|
75
|
+
| Initiatives | Detected via `custom_item_id !== 0` |
|
|
76
|
+
| `--list` on create | Optional when `--parent` is given (auto-detected) |
|
|
77
|
+
| `--status` | Fuzzy matching: exact > starts-with > contains. Prints match to stderr. |
|
|
78
|
+
| `--priority` | Names (`urgent`, `high`, `normal`, `low`) or numbers (1-4) |
|
|
79
|
+
| `--due-date` | `YYYY-MM-DD` format |
|
|
80
|
+
| `--assignee` | Numeric user ID (find via `cu task <id> --json`) |
|
|
81
|
+
| `--tags` | Comma-separated (e.g. `--tags "bug,frontend"`) |
|
|
82
|
+
| `--time-estimate` | Duration format: `"2h"`, `"30m"`, `"1h30m"`, or raw milliseconds |
|
|
83
|
+
| `--custom-item-id` | Custom task type ID (e.g. `1` for initiative) |
|
|
84
|
+
| `--on` / `--blocks` | Task dependency direction (used with `cu depend`) |
|
|
85
|
+
| `--to` / `--remove` | List ID to add/remove task (used with `cu move`) |
|
|
86
|
+
| `--space` | Partial name match or exact ID |
|
|
87
|
+
| `--name` | Partial match, case-insensitive |
|
|
88
|
+
| `--include-closed` | Include closed/done tasks (on `tasks`, `initiatives`, `assigned`, `subtasks`, `sprint`, `search`, `inbox`, `overdue`) |
|
|
89
|
+
| `cu assign --to me` | Shorthand for your own user ID |
|
|
90
|
+
| `cu search` | Matches all query words against task name, case-insensitive |
|
|
91
|
+
| `cu sprint` | Auto-detects active sprint via view API and date range parsing |
|
|
92
|
+
| `cu summary` | Categories: completed (done/complete/closed within N hours), in progress, overdue |
|
|
93
|
+
| `cu overdue` | Excludes closed tasks, sorted most overdue first |
|
|
94
|
+
| `cu open` | Tries task ID first, falls back to name search |
|
|
95
|
+
| `cu task` | Shows custom fields in detail view |
|
|
96
|
+
| `cu lists` | Discovers list IDs needed for `--list` and `cu create -l` |
|
|
97
|
+
| Errors | stderr with exit code 1 |
|
|
98
|
+
| Parsing | Strict - excess/unknown arguments rejected |
|
|
97
99
|
|
|
98
100
|
## Agent Workflow Examples
|
|
99
101
|
|
|
@@ -126,6 +128,7 @@ cu inbox --days 7 # recently updated
|
|
|
126
128
|
cu update abc123def -s "done"
|
|
127
129
|
cu update abc123def --priority high --due-date 2025-03-15
|
|
128
130
|
cu update abc123def --time-estimate 2h
|
|
131
|
+
cu update abc123def --parent parentId # make it a subtask
|
|
129
132
|
cu create -n "Fix the thing" -p abc123def
|
|
130
133
|
cu create -n "Fix bug" -l <listId> --priority urgent --tags "bug,frontend"
|
|
131
134
|
cu create -n "Q3 Roadmap" -l <listId> --custom-item-id 1 # create initiative
|
|
@@ -133,6 +136,7 @@ cu comment abc123def -m "Completed in PR #42"
|
|
|
133
136
|
cu assign abc123def --to me
|
|
134
137
|
cu depend task3 --on task2 # task3 waits for task2
|
|
135
138
|
cu depend task1 --blocks task2 # task1 blocks task2
|
|
139
|
+
cu move task1 --to list2 --remove list1 # move between lists
|
|
136
140
|
```
|
|
137
141
|
|
|
138
142
|
### Discover workspace structure
|