@krodak/clickup-cli 0.11.0 → 0.12.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 +28 -7
- package/dist/index.js +76 -37
- package/package.json +1 -1
- package/skills/clickup-cli/SKILL.md +40 -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
|
|
|
@@ -263,6 +265,7 @@ Post a comment on a task.
|
|
|
263
265
|
|
|
264
266
|
```bash
|
|
265
267
|
cu comment abc123 -m "Addressed in PR #42"
|
|
268
|
+
cu comment abc123 -m "Done" --json
|
|
266
269
|
```
|
|
267
270
|
|
|
268
271
|
### `cu comments <id>`
|
|
@@ -309,11 +312,11 @@ cu spaces --my
|
|
|
309
312
|
cu spaces --json
|
|
310
313
|
```
|
|
311
314
|
|
|
312
|
-
| Flag | Description
|
|
313
|
-
| ------------------ |
|
|
314
|
-
| `--name <partial>` | Filter spaces by partial name match
|
|
315
|
-
| `--my` | Show only spaces
|
|
316
|
-
| `--json` | Force JSON output
|
|
315
|
+
| Flag | Description |
|
|
316
|
+
| ------------------ | -------------------------------------------- |
|
|
317
|
+
| `--name <partial>` | Filter spaces by partial name match |
|
|
318
|
+
| `--my` | Show only spaces where I have assigned tasks |
|
|
319
|
+
| `--json` | Force JSON output |
|
|
317
320
|
|
|
318
321
|
### `cu open <query>`
|
|
319
322
|
|
|
@@ -356,10 +359,11 @@ cu summary --json
|
|
|
356
359
|
|
|
357
360
|
### `cu overdue`
|
|
358
361
|
|
|
359
|
-
List tasks that are past their due date (excludes done/closed tasks). Sorted most overdue first.
|
|
362
|
+
List tasks that are past their due date (excludes done/closed tasks by default). Sorted most overdue first.
|
|
360
363
|
|
|
361
364
|
```bash
|
|
362
365
|
cu overdue
|
|
366
|
+
cu overdue --include-closed
|
|
363
367
|
cu overdue --json
|
|
364
368
|
```
|
|
365
369
|
|
|
@@ -400,6 +404,23 @@ cu depend abc123 --on def456 --json
|
|
|
400
404
|
| `--remove` | Remove the dependency instead of adding it |
|
|
401
405
|
| `--json` | Force JSON output |
|
|
402
406
|
|
|
407
|
+
### `cu move <id>`
|
|
408
|
+
|
|
409
|
+
Add or remove a task from a list. Tasks can belong to multiple lists in ClickUp.
|
|
410
|
+
|
|
411
|
+
```bash
|
|
412
|
+
cu move abc123 --to <listId> # add task to a list
|
|
413
|
+
cu move abc123 --remove <listId> # remove task from a list
|
|
414
|
+
cu move abc123 --to <newListId> --remove <oldListId> # move between lists
|
|
415
|
+
cu move abc123 --to <listId> --json
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
| Flag | Description |
|
|
419
|
+
| ------------------- | -------------------------- |
|
|
420
|
+
| `--to <listId>` | Add task to this list |
|
|
421
|
+
| `--remove <listId>` | Remove task from this list |
|
|
422
|
+
| `--json` | Force JSON output |
|
|
423
|
+
|
|
403
424
|
### `cu auth`
|
|
404
425
|
|
|
405
426
|
Check authentication status. Validates your API token and shows your user info.
|
package/dist/index.js
CHANGED
|
@@ -175,10 +175,10 @@ 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
|
-
async
|
|
181
|
-
return this.updateTask(taskId, {
|
|
180
|
+
async updateTaskMarkdown(taskId, markdown) {
|
|
181
|
+
return this.updateTask(taskId, { markdown_content: markdown });
|
|
182
182
|
}
|
|
183
183
|
async createTask(listId, options) {
|
|
184
184
|
return this.request(`/list/${listId}/task`, {
|
|
@@ -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 } : {}
|
|
@@ -712,7 +733,7 @@ function parseTimeEstimate(value) {
|
|
|
712
733
|
function buildUpdatePayload(opts) {
|
|
713
734
|
const payload = {};
|
|
714
735
|
if (opts.name !== void 0) payload.name = opts.name;
|
|
715
|
-
if (opts.description !== void 0) payload.
|
|
736
|
+
if (opts.description !== void 0) payload.markdown_content = opts.description;
|
|
716
737
|
if (opts.status !== void 0) payload.status = opts.status;
|
|
717
738
|
if (opts.priority !== void 0) payload.priority = parsePriority(opts.priority);
|
|
718
739
|
if (opts.dueDate !== void 0) {
|
|
@@ -728,7 +749,7 @@ function buildUpdatePayload(opts) {
|
|
|
728
749
|
return payload;
|
|
729
750
|
}
|
|
730
751
|
function hasUpdateFields(options) {
|
|
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;
|
|
752
|
+
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;
|
|
732
753
|
}
|
|
733
754
|
async function resolveStatus(client, taskId, statusInput) {
|
|
734
755
|
const task = await client.getTask(taskId);
|
|
@@ -771,7 +792,7 @@ async function createTask(config, options) {
|
|
|
771
792
|
}
|
|
772
793
|
const payload = {
|
|
773
794
|
name: options.name,
|
|
774
|
-
...options.description !== void 0 ? {
|
|
795
|
+
...options.description !== void 0 ? { markdown_content: options.description } : {},
|
|
775
796
|
...options.parent !== void 0 ? { parent: options.parent } : {},
|
|
776
797
|
...options.status !== void 0 ? { status: options.status } : {}
|
|
777
798
|
};
|
|
@@ -1181,9 +1202,12 @@ function groupTasks(tasks, now) {
|
|
|
1181
1202
|
}
|
|
1182
1203
|
return groups;
|
|
1183
1204
|
}
|
|
1184
|
-
async function fetchInbox(config, days = 30) {
|
|
1205
|
+
async function fetchInbox(config, days = 30, opts = {}) {
|
|
1185
1206
|
const client = new ClickUpClient(config);
|
|
1186
|
-
const tasks = await client.getMyTasks(config.teamId, {
|
|
1207
|
+
const tasks = await client.getMyTasks(config.teamId, {
|
|
1208
|
+
subtasks: true,
|
|
1209
|
+
includeClosed: opts.includeClosed
|
|
1210
|
+
});
|
|
1187
1211
|
const cutoff = Date.now() - days * 24 * 60 * 60 * 1e3;
|
|
1188
1212
|
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
1213
|
}
|
|
@@ -1258,7 +1282,6 @@ async function listSpaces(config, opts) {
|
|
|
1258
1282
|
}
|
|
1259
1283
|
|
|
1260
1284
|
// src/commands/assigned.ts
|
|
1261
|
-
var CLOSED_STATUSES = /* @__PURE__ */ new Set(["done", "closed", "complete", "completed"]);
|
|
1262
1285
|
var STATUS_ORDER = [
|
|
1263
1286
|
"code review",
|
|
1264
1287
|
"in review",
|
|
@@ -1270,18 +1293,6 @@ var STATUS_ORDER = [
|
|
|
1270
1293
|
"backlog",
|
|
1271
1294
|
"blocked"
|
|
1272
1295
|
];
|
|
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
1296
|
function statusSortKey(status) {
|
|
1286
1297
|
const idx = STATUS_ORDER.indexOf(status.toLowerCase());
|
|
1287
1298
|
return idx === -1 ? STATUS_ORDER.length : idx;
|
|
@@ -1290,16 +1301,15 @@ function groupByStatus(tasks, includeClosed) {
|
|
|
1290
1301
|
const groups = /* @__PURE__ */ new Map();
|
|
1291
1302
|
for (const task of tasks) {
|
|
1292
1303
|
const status = task.status.status;
|
|
1293
|
-
|
|
1294
|
-
if (!includeClosed && CLOSED_STATUSES.has(key)) continue;
|
|
1304
|
+
if (!includeClosed && isDoneStatus(status)) continue;
|
|
1295
1305
|
if (!groups.has(status)) {
|
|
1296
1306
|
groups.set(status, []);
|
|
1297
1307
|
}
|
|
1298
1308
|
groups.get(status).push(task);
|
|
1299
1309
|
}
|
|
1300
1310
|
return Array.from(groups.entries()).sort((a, b) => {
|
|
1301
|
-
const aIsClosed =
|
|
1302
|
-
const bIsClosed =
|
|
1311
|
+
const aIsClosed = isDoneStatus(a[0]);
|
|
1312
|
+
const bIsClosed = isDoneStatus(b[0]);
|
|
1303
1313
|
if (aIsClosed !== bIsClosed) return aIsClosed ? 1 : -1;
|
|
1304
1314
|
return statusSortKey(a[0]) - statusSortKey(b[0]);
|
|
1305
1315
|
}).map(([status, tasks2]) => ({ status, tasks: tasks2 }));
|
|
@@ -1317,7 +1327,7 @@ async function runAssignedCommand(config, opts) {
|
|
|
1317
1327
|
if (shouldOutputJson(opts.json ?? false)) {
|
|
1318
1328
|
const result = {};
|
|
1319
1329
|
for (const group of groups) {
|
|
1320
|
-
result[group.status.toLowerCase()] = group.tasks.map(
|
|
1330
|
+
result[group.status.toLowerCase()] = group.tasks.map(summarize);
|
|
1321
1331
|
}
|
|
1322
1332
|
console.log(JSON.stringify(result, null, 2));
|
|
1323
1333
|
return;
|
|
@@ -1450,7 +1460,7 @@ ${label} (${tasks.length})`);
|
|
|
1450
1460
|
}
|
|
1451
1461
|
async function runSummaryCommand(config, opts) {
|
|
1452
1462
|
const client = new ClickUpClient(config);
|
|
1453
|
-
const allTasks = await client.getMyTasks(config.teamId);
|
|
1463
|
+
const allTasks = await client.getMyTasks(config.teamId, { includeClosed: true });
|
|
1454
1464
|
const result = categorizeTasks(allTasks, opts.hours);
|
|
1455
1465
|
if (shouldOutputJson(opts.json)) {
|
|
1456
1466
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -1475,11 +1485,11 @@ function isOverdue2(task, now) {
|
|
|
1475
1485
|
if (!task.due_date) return false;
|
|
1476
1486
|
return Number(task.due_date) < now;
|
|
1477
1487
|
}
|
|
1478
|
-
async function fetchOverdueTasks(config) {
|
|
1488
|
+
async function fetchOverdueTasks(config, opts = {}) {
|
|
1479
1489
|
const client = new ClickUpClient(config);
|
|
1480
|
-
const allTasks = await client.getMyTasks(config.teamId);
|
|
1490
|
+
const allTasks = await client.getMyTasks(config.teamId, { includeClosed: opts.includeClosed });
|
|
1481
1491
|
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);
|
|
1492
|
+
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
1493
|
}
|
|
1484
1494
|
|
|
1485
1495
|
// src/commands/config.ts
|
|
@@ -2075,6 +2085,24 @@ async function manageDependency(config, taskId, opts) {
|
|
|
2075
2085
|
return `Added dependency: ${taskId} blocks ${opts.blocks}`;
|
|
2076
2086
|
}
|
|
2077
2087
|
|
|
2088
|
+
// src/commands/move.ts
|
|
2089
|
+
async function moveTask(config, taskId, opts) {
|
|
2090
|
+
if (!opts.to && !opts.remove) {
|
|
2091
|
+
throw new Error("Provide --to <listId> or --remove <listId>");
|
|
2092
|
+
}
|
|
2093
|
+
const client = new ClickUpClient(config);
|
|
2094
|
+
const messages = [];
|
|
2095
|
+
if (opts.to) {
|
|
2096
|
+
await client.addTaskToList(taskId, opts.to);
|
|
2097
|
+
messages.push(`Added ${taskId} to list ${opts.to}`);
|
|
2098
|
+
}
|
|
2099
|
+
if (opts.remove) {
|
|
2100
|
+
await client.removeTaskFromList(taskId, opts.remove);
|
|
2101
|
+
messages.push(`Removed ${taskId} from list ${opts.remove}`);
|
|
2102
|
+
}
|
|
2103
|
+
return messages.join("; ");
|
|
2104
|
+
}
|
|
2105
|
+
|
|
2078
2106
|
// src/index.ts
|
|
2079
2107
|
var require2 = createRequire(import.meta.url);
|
|
2080
2108
|
var { version } = require2("../package.json");
|
|
@@ -2159,7 +2187,7 @@ program.command("update <taskId>").description("Update a task").option("-n, --na
|
|
|
2159
2187
|
}
|
|
2160
2188
|
})
|
|
2161
2189
|
);
|
|
2162
|
-
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(
|
|
2190
|
+
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 (markdown supported)").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(
|
|
2163
2191
|
wrapAction(async (opts) => {
|
|
2164
2192
|
const config = loadConfig();
|
|
2165
2193
|
const result = await createTask(config, opts);
|
|
@@ -2239,14 +2267,14 @@ program.command("spaces").description("List spaces in your workspace").option("-
|
|
|
2239
2267
|
await listSpaces(config, opts);
|
|
2240
2268
|
})
|
|
2241
2269
|
);
|
|
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(
|
|
2270
|
+
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
2271
|
wrapAction(async (opts) => {
|
|
2244
2272
|
const config = loadConfig();
|
|
2245
2273
|
const days = Number(opts.days ?? 30);
|
|
2246
2274
|
if (!Number.isFinite(days) || days <= 0) {
|
|
2247
2275
|
throw new Error("--days must be a positive number");
|
|
2248
2276
|
}
|
|
2249
|
-
const tasks = await fetchInbox(config, days);
|
|
2277
|
+
const tasks = await fetchInbox(config, days, { includeClosed: opts.includeClosed });
|
|
2250
2278
|
await printInbox(tasks, opts.json ?? false, config);
|
|
2251
2279
|
})
|
|
2252
2280
|
);
|
|
@@ -2284,10 +2312,10 @@ program.command("summary").description("Daily standup summary: completed, in-pro
|
|
|
2284
2312
|
await runSummaryCommand(config, { hours, json: opts.json ?? false });
|
|
2285
2313
|
})
|
|
2286
2314
|
);
|
|
2287
|
-
program.command("overdue").description("List tasks that are past their due date").option("--json", "Force JSON output even in terminal").action(
|
|
2315
|
+
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
2316
|
wrapAction(async (opts) => {
|
|
2289
2317
|
const config = loadConfig();
|
|
2290
|
-
const tasks = await fetchOverdueTasks(config);
|
|
2318
|
+
const tasks = await fetchOverdueTasks(config, { includeClosed: opts.includeClosed });
|
|
2291
2319
|
await printTasks(tasks, opts.json ?? false, config);
|
|
2292
2320
|
})
|
|
2293
2321
|
);
|
|
@@ -2313,6 +2341,17 @@ program.command("depend <taskId>").description("Add or remove task dependencies"
|
|
|
2313
2341
|
}
|
|
2314
2342
|
})
|
|
2315
2343
|
);
|
|
2344
|
+
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(
|
|
2345
|
+
wrapAction(async (taskId, opts) => {
|
|
2346
|
+
const config = loadConfig();
|
|
2347
|
+
const message = await moveTask(config, taskId, opts);
|
|
2348
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
2349
|
+
console.log(JSON.stringify({ taskId, ...opts, message }, null, 2));
|
|
2350
|
+
} else {
|
|
2351
|
+
console.log(message);
|
|
2352
|
+
}
|
|
2353
|
+
})
|
|
2354
|
+
);
|
|
2316
2355
|
var configCmd = program.command("config").description("Manage CLI configuration");
|
|
2317
2356
|
configCmd.command("get <key>").description("Print a config value").action(
|
|
2318
2357
|
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]` | 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 (
|
|
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] [--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
|
|
|
@@ -133,6 +135,7 @@ cu comment abc123def -m "Completed in PR #42"
|
|
|
133
135
|
cu assign abc123def --to me
|
|
134
136
|
cu depend task3 --on task2 # task3 waits for task2
|
|
135
137
|
cu depend task1 --blocks task2 # task1 blocks task2
|
|
138
|
+
cu move task1 --to list2 --remove list1 # move between lists
|
|
136
139
|
```
|
|
137
140
|
|
|
138
141
|
### Discover workspace structure
|