@krodak/clickup-cli 1.28.0 → 1.29.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 +1 -1
- package/README.md +2 -2
- package/dist/index.js +352 -66
- package/package.json +1 -1
- package/skills/clickup-cli/SKILL.md +10 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clickup-cli",
|
|
3
3
|
"description": "ClickUp CLI skills for managing tasks, sprints, comments, checklists, custom fields, tags, and time tracking via the cup command",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.29.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Krzysztof Rodak"
|
|
7
7
|
},
|
package/README.md
CHANGED
|
@@ -185,8 +185,8 @@ Full CRUD for the core ClickUp workflow:
|
|
|
185
185
|
| 🏃 **Sprints** | Auto-detect active sprint, `sprint:current` pseudo-ID for move/create, flexible date parsing, config override, favorite sprint folders |
|
|
186
186
|
| ⭐ **Favorites** | Local favorites for quick access to sprint folders, spaces, lists, folders, views, tasks |
|
|
187
187
|
| 👁️ **Views** | List, get, create, update, delete views on lists |
|
|
188
|
-
| 🏢 **Workspace** | Spaces, folders, lists (
|
|
189
|
-
| 📎 **Attachments** | Upload files to tasks, shown in detail views
|
|
188
|
+
| 🏢 **Workspace** | Spaces, folders, lists (full CRUD + rename + from template), members, task types, templates, plan |
|
|
189
|
+
| 📎 **Attachments** | Upload files to tasks, list task attachments, shown in detail views |
|
|
190
190
|
|
|
191
191
|
[Full API coverage details](docs/api-coverage.md) | [Command reference](docs/commands.md)
|
|
192
192
|
|
package/dist/index.js
CHANGED
|
@@ -445,6 +445,28 @@ var ClickUpClient = class {
|
|
|
445
445
|
async deleteTask(taskId) {
|
|
446
446
|
await this.request(this.taskPath(taskId), { method: "DELETE" });
|
|
447
447
|
}
|
|
448
|
+
async deleteList(listId) {
|
|
449
|
+
await this.request(`/list/${listId}`, { method: "DELETE" });
|
|
450
|
+
}
|
|
451
|
+
async deleteFolder(folderId) {
|
|
452
|
+
await this.request(`/folder/${folderId}`, { method: "DELETE" });
|
|
453
|
+
}
|
|
454
|
+
async deleteSpace(spaceId) {
|
|
455
|
+
await this.request(`/space/${spaceId}`, { method: "DELETE" });
|
|
456
|
+
}
|
|
457
|
+
async getTaskMembers(taskId) {
|
|
458
|
+
const data = await this.request(this.taskPath(taskId, "/member"));
|
|
459
|
+
return readCollectionField(data, "members", "task members");
|
|
460
|
+
}
|
|
461
|
+
async getWorkspacePlan() {
|
|
462
|
+
return this.request(`/team/${this.teamId}/plan`);
|
|
463
|
+
}
|
|
464
|
+
async getTaskAttachments(taskId) {
|
|
465
|
+
const data = await this.requestV3(
|
|
466
|
+
`/workspaces/${this.teamId}/tasks/${taskId}/attachments`
|
|
467
|
+
);
|
|
468
|
+
return expectArrayField(data, "data", "task attachments");
|
|
469
|
+
}
|
|
448
470
|
async addTagToTask(taskId, tagName) {
|
|
449
471
|
await this.request(this.taskPath(taskId, `/tag/${encodeURIComponent(tagName)}`), {
|
|
450
472
|
method: "POST"
|
|
@@ -3888,6 +3910,60 @@ var commandMetadata = [
|
|
|
3888
3910
|
flags: ["--confirm", "--json"],
|
|
3889
3911
|
quickReference: [{ section: "write", usage: "delete <taskId>", description: "Delete a task" }]
|
|
3890
3912
|
},
|
|
3913
|
+
{
|
|
3914
|
+
name: "list-delete",
|
|
3915
|
+
description: "Delete a list (requires confirmation)",
|
|
3916
|
+
flags: ["--confirm", "--json"],
|
|
3917
|
+
quickReference: [
|
|
3918
|
+
{ section: "write", usage: "list-delete <listId>", description: "Delete a list" }
|
|
3919
|
+
]
|
|
3920
|
+
},
|
|
3921
|
+
{
|
|
3922
|
+
name: "folder-delete",
|
|
3923
|
+
description: "Delete a folder (requires confirmation)",
|
|
3924
|
+
flags: ["--confirm", "--json"],
|
|
3925
|
+
quickReference: [
|
|
3926
|
+
{ section: "write", usage: "folder-delete <folderId>", description: "Delete a folder" }
|
|
3927
|
+
]
|
|
3928
|
+
},
|
|
3929
|
+
{
|
|
3930
|
+
name: "space-delete",
|
|
3931
|
+
description: "Delete a space (requires confirmation)",
|
|
3932
|
+
flags: ["--confirm", "--json"],
|
|
3933
|
+
quickReference: [
|
|
3934
|
+
{ section: "write", usage: "space-delete <spaceId>", description: "Delete a space" }
|
|
3935
|
+
]
|
|
3936
|
+
},
|
|
3937
|
+
{
|
|
3938
|
+
name: "attachments",
|
|
3939
|
+
description: "List attachments on a task",
|
|
3940
|
+
flags: ["--json"],
|
|
3941
|
+
quickReference: [
|
|
3942
|
+
{
|
|
3943
|
+
section: "read",
|
|
3944
|
+
usage: "attachments <taskId>",
|
|
3945
|
+
description: "List attachments on a task"
|
|
3946
|
+
}
|
|
3947
|
+
]
|
|
3948
|
+
},
|
|
3949
|
+
{
|
|
3950
|
+
name: "task-members",
|
|
3951
|
+
description: "List members with access to a task",
|
|
3952
|
+
flags: ["--json"],
|
|
3953
|
+
quickReference: [
|
|
3954
|
+
{
|
|
3955
|
+
section: "read",
|
|
3956
|
+
usage: "task-members <taskId>",
|
|
3957
|
+
description: "List members with access to a task"
|
|
3958
|
+
}
|
|
3959
|
+
]
|
|
3960
|
+
},
|
|
3961
|
+
{
|
|
3962
|
+
name: "plan",
|
|
3963
|
+
description: "Show workspace plan",
|
|
3964
|
+
flags: ["--json"],
|
|
3965
|
+
quickReference: [{ section: "read", usage: "plan", description: "Show workspace plan" }]
|
|
3966
|
+
},
|
|
3891
3967
|
{
|
|
3892
3968
|
name: "tag",
|
|
3893
3969
|
description: "Add or remove tags from a task",
|
|
@@ -6150,6 +6226,144 @@ async function deleteTaskCommand(config, taskId, opts) {
|
|
|
6150
6226
|
return { taskId, deleted: true };
|
|
6151
6227
|
}
|
|
6152
6228
|
|
|
6229
|
+
// src/commands/list-delete.ts
|
|
6230
|
+
async function deleteListCommand(config, listId, opts) {
|
|
6231
|
+
const client = new ClickUpClient(config);
|
|
6232
|
+
if (!opts.confirm) {
|
|
6233
|
+
if (!isTTY()) {
|
|
6234
|
+
throw new Error("Destructive operation requires --confirm flag in non-interactive mode");
|
|
6235
|
+
}
|
|
6236
|
+
const list = await client.getListWithStatuses(listId);
|
|
6237
|
+
const { confirm: confirm3 } = await import("@inquirer/prompts");
|
|
6238
|
+
const confirmed = await confirm3({
|
|
6239
|
+
message: `Delete list "${list.name}" (${listId})? This cannot be undone.`,
|
|
6240
|
+
default: false
|
|
6241
|
+
});
|
|
6242
|
+
if (!confirmed) {
|
|
6243
|
+
throw new Error("Cancelled");
|
|
6244
|
+
}
|
|
6245
|
+
}
|
|
6246
|
+
await client.deleteList(listId);
|
|
6247
|
+
return { listId, deleted: true };
|
|
6248
|
+
}
|
|
6249
|
+
|
|
6250
|
+
// src/commands/folder-delete.ts
|
|
6251
|
+
async function deleteFolderCommand(config, folderId, opts) {
|
|
6252
|
+
const client = new ClickUpClient(config);
|
|
6253
|
+
if (!opts.confirm) {
|
|
6254
|
+
if (!isTTY()) {
|
|
6255
|
+
throw new Error("Destructive operation requires --confirm flag in non-interactive mode");
|
|
6256
|
+
}
|
|
6257
|
+
const { confirm: confirm3 } = await import("@inquirer/prompts");
|
|
6258
|
+
const confirmed = await confirm3({
|
|
6259
|
+
message: `Delete folder ${folderId}? This cannot be undone.`,
|
|
6260
|
+
default: false
|
|
6261
|
+
});
|
|
6262
|
+
if (!confirmed) {
|
|
6263
|
+
throw new Error("Cancelled");
|
|
6264
|
+
}
|
|
6265
|
+
}
|
|
6266
|
+
await client.deleteFolder(folderId);
|
|
6267
|
+
return { folderId, deleted: true };
|
|
6268
|
+
}
|
|
6269
|
+
|
|
6270
|
+
// src/commands/space-delete.ts
|
|
6271
|
+
async function deleteSpaceCommand(config, spaceId, opts) {
|
|
6272
|
+
const client = new ClickUpClient(config);
|
|
6273
|
+
if (!opts.confirm) {
|
|
6274
|
+
if (!isTTY()) {
|
|
6275
|
+
throw new Error("Destructive operation requires --confirm flag in non-interactive mode");
|
|
6276
|
+
}
|
|
6277
|
+
const space = await client.getSpaceWithStatuses(spaceId);
|
|
6278
|
+
const { confirm: confirm3 } = await import("@inquirer/prompts");
|
|
6279
|
+
const confirmed = await confirm3({
|
|
6280
|
+
message: `Delete space "${space.name}" (${spaceId})? This cannot be undone.`,
|
|
6281
|
+
default: false
|
|
6282
|
+
});
|
|
6283
|
+
if (!confirmed) {
|
|
6284
|
+
throw new Error("Cancelled");
|
|
6285
|
+
}
|
|
6286
|
+
}
|
|
6287
|
+
await client.deleteSpace(spaceId);
|
|
6288
|
+
return { spaceId, deleted: true };
|
|
6289
|
+
}
|
|
6290
|
+
|
|
6291
|
+
// src/commands/attachments.ts
|
|
6292
|
+
function formatSize(size) {
|
|
6293
|
+
if (size < 1024) return `${size} B`;
|
|
6294
|
+
if (size < 1048576) return `${(size / 1024).toFixed(1)} KB`;
|
|
6295
|
+
return `${(size / 1048576).toFixed(1)} MB`;
|
|
6296
|
+
}
|
|
6297
|
+
var ATTACHMENT_COLUMNS = [
|
|
6298
|
+
{ key: "title", label: "Title", maxWidth: 40 },
|
|
6299
|
+
{ key: "extension", label: "Ext", maxWidth: 10 },
|
|
6300
|
+
{ key: "size", label: "Size", maxWidth: 10 },
|
|
6301
|
+
{ key: "date", label: "Date", maxWidth: 12 },
|
|
6302
|
+
{ key: "url", label: "URL", maxWidth: 60 }
|
|
6303
|
+
];
|
|
6304
|
+
function toRow(a) {
|
|
6305
|
+
return {
|
|
6306
|
+
title: a.title,
|
|
6307
|
+
extension: a.extension,
|
|
6308
|
+
size: formatSize(a.size),
|
|
6309
|
+
date: new Date(a.date_created).toLocaleDateString(),
|
|
6310
|
+
url: a.url
|
|
6311
|
+
};
|
|
6312
|
+
}
|
|
6313
|
+
async function listTaskAttachments(config, taskId) {
|
|
6314
|
+
const client = new ClickUpClient(config);
|
|
6315
|
+
return client.getTaskAttachments(taskId);
|
|
6316
|
+
}
|
|
6317
|
+
function formatAttachmentsTable(attachments) {
|
|
6318
|
+
if (attachments.length === 0) return "No attachments found";
|
|
6319
|
+
const rows = attachments.map(toRow);
|
|
6320
|
+
return formatTable(rows, ATTACHMENT_COLUMNS);
|
|
6321
|
+
}
|
|
6322
|
+
function formatAttachmentsMarkdown(attachments) {
|
|
6323
|
+
if (attachments.length === 0) return "No attachments found";
|
|
6324
|
+
return attachments.map((a) => `- **${a.title}** (${a.extension}, ${formatSize(a.size)}) \u2014 ${a.url}`).join("\n");
|
|
6325
|
+
}
|
|
6326
|
+
|
|
6327
|
+
// src/commands/task-members.ts
|
|
6328
|
+
var TASK_MEMBER_COLUMNS = [
|
|
6329
|
+
{ key: "username", label: "Username", maxWidth: 25 },
|
|
6330
|
+
{ key: "id", label: "ID", maxWidth: 15 },
|
|
6331
|
+
{ key: "email", label: "Email", maxWidth: 40 }
|
|
6332
|
+
];
|
|
6333
|
+
async function listTaskMembers(config, taskId) {
|
|
6334
|
+
const client = new ClickUpClient(config);
|
|
6335
|
+
return client.getTaskMembers(taskId);
|
|
6336
|
+
}
|
|
6337
|
+
function formatTaskMembers(members) {
|
|
6338
|
+
if (members.length === 0) return "No task members found";
|
|
6339
|
+
const rows = members.map((m) => ({
|
|
6340
|
+
username: m.username,
|
|
6341
|
+
id: String(m.id),
|
|
6342
|
+
email: m.email
|
|
6343
|
+
}));
|
|
6344
|
+
return formatTable(rows, TASK_MEMBER_COLUMNS);
|
|
6345
|
+
}
|
|
6346
|
+
function formatTaskMembersMarkdown(members) {
|
|
6347
|
+
if (members.length === 0) return "No task members found";
|
|
6348
|
+
return members.map((m) => `- **${m.username}** (${m.id}) - ${m.email}`).join("\n");
|
|
6349
|
+
}
|
|
6350
|
+
|
|
6351
|
+
// src/commands/plan.ts
|
|
6352
|
+
import chalk9 from "chalk";
|
|
6353
|
+
async function getWorkspacePlanCommand(config) {
|
|
6354
|
+
const client = new ClickUpClient(config);
|
|
6355
|
+
return client.getWorkspacePlan();
|
|
6356
|
+
}
|
|
6357
|
+
function formatPlan(plan) {
|
|
6358
|
+
return [
|
|
6359
|
+
`${chalk9.bold("Plan:")} ${plan.name}`,
|
|
6360
|
+
`${chalk9.bold("Plan ID:")} ${plan.plan_id}`
|
|
6361
|
+
].join("\n");
|
|
6362
|
+
}
|
|
6363
|
+
function formatPlanMarkdown(plan) {
|
|
6364
|
+
return [`**Plan:** ${plan.name}`, `**Plan ID:** ${plan.plan_id}`].join("\n");
|
|
6365
|
+
}
|
|
6366
|
+
|
|
6153
6367
|
// src/commands/archive.ts
|
|
6154
6368
|
async function archiveTaskCommand(config, taskId, opts) {
|
|
6155
6369
|
const client = new ClickUpClient(config);
|
|
@@ -6210,7 +6424,7 @@ async function manageTags(config, taskId, opts) {
|
|
|
6210
6424
|
}
|
|
6211
6425
|
|
|
6212
6426
|
// src/commands/checklist.ts
|
|
6213
|
-
import
|
|
6427
|
+
import chalk10 from "chalk";
|
|
6214
6428
|
async function viewChecklists(config, taskId) {
|
|
6215
6429
|
const client = new ClickUpClient(config);
|
|
6216
6430
|
const task = await client.getTask(taskId);
|
|
@@ -6260,19 +6474,19 @@ function formatChecklists(checklists) {
|
|
|
6260
6474
|
const lines = [];
|
|
6261
6475
|
const renderItem = (item, depth) => {
|
|
6262
6476
|
const indent = " ".repeat(depth + 1);
|
|
6263
|
-
const check = item.resolved ?
|
|
6264
|
-
const name = item.resolved ?
|
|
6265
|
-
const assignee = item.assignee ?
|
|
6477
|
+
const check = item.resolved ? chalk10.green("[x]") : chalk10.dim("[ ]");
|
|
6478
|
+
const name = item.resolved ? chalk10.dim(item.name) : item.name;
|
|
6479
|
+
const assignee = item.assignee ? chalk10.dim(` @${item.assignee.username}`) : "";
|
|
6266
6480
|
lines.push(`${indent}${check} ${name}${assignee}`);
|
|
6267
|
-
lines.push(
|
|
6481
|
+
lines.push(chalk10.dim(`${indent} item-id: ${item.id}`));
|
|
6268
6482
|
for (const child of sortByOrder(item.children ?? [])) {
|
|
6269
6483
|
renderItem(child, depth + 1);
|
|
6270
6484
|
}
|
|
6271
6485
|
};
|
|
6272
6486
|
for (const cl of checklists) {
|
|
6273
6487
|
const { total, resolved } = countItems(cl.items);
|
|
6274
|
-
lines.push(
|
|
6275
|
-
lines.push(
|
|
6488
|
+
lines.push(chalk10.bold(`${cl.name} (${resolved}/${total})`));
|
|
6489
|
+
lines.push(chalk10.dim(` ID: ${cl.id}`));
|
|
6276
6490
|
for (const item of sortByOrder(cl.items)) renderItem(item, 0);
|
|
6277
6491
|
}
|
|
6278
6492
|
return lines.join("\n");
|
|
@@ -6338,7 +6552,7 @@ async function deleteCommentByTaskSelection(config, taskId, options) {
|
|
|
6338
6552
|
}
|
|
6339
6553
|
|
|
6340
6554
|
// src/commands/replies.ts
|
|
6341
|
-
import
|
|
6555
|
+
import chalk11 from "chalk";
|
|
6342
6556
|
async function getReplies(config, commentId) {
|
|
6343
6557
|
const client = new ClickUpClient(config);
|
|
6344
6558
|
return client.getThreadedComments(commentId);
|
|
@@ -6354,7 +6568,7 @@ function formatReplies(replies) {
|
|
|
6354
6568
|
return replies.map((r) => {
|
|
6355
6569
|
const user = r.user?.username ?? "Unknown";
|
|
6356
6570
|
const date = formatTimestamp(Number(r.date));
|
|
6357
|
-
return `${
|
|
6571
|
+
return `${chalk11.bold(user)} ${chalk11.dim(date)}
|
|
6358
6572
|
${r.comment_text}`;
|
|
6359
6573
|
}).join("\n\n");
|
|
6360
6574
|
}
|
|
@@ -6417,7 +6631,7 @@ function formatDocsMarkdown(docs) {
|
|
|
6417
6631
|
}
|
|
6418
6632
|
|
|
6419
6633
|
// src/commands/doc.ts
|
|
6420
|
-
import
|
|
6634
|
+
import chalk12 from "chalk";
|
|
6421
6635
|
async function getDocInfo(config, docId) {
|
|
6422
6636
|
const client = new ClickUpClient(config);
|
|
6423
6637
|
const [doc, pages] = await Promise.all([
|
|
@@ -6429,14 +6643,14 @@ async function getDocInfo(config, docId) {
|
|
|
6429
6643
|
function formatDocInfo(doc, pages, indent = 0) {
|
|
6430
6644
|
const lines = [];
|
|
6431
6645
|
if (indent === 0) {
|
|
6432
|
-
lines.push(`${
|
|
6646
|
+
lines.push(`${chalk12.bold(doc.name)} ${chalk12.dim(doc.id)}`);
|
|
6433
6647
|
if (pages.length === 0) {
|
|
6434
6648
|
lines.push(" (no pages)");
|
|
6435
6649
|
}
|
|
6436
6650
|
}
|
|
6437
6651
|
for (const page of pages) {
|
|
6438
6652
|
const prefix = " ".repeat(indent + 1);
|
|
6439
|
-
lines.push(`${prefix}${page.name} ${
|
|
6653
|
+
lines.push(`${prefix}${page.name} ${chalk12.dim(page.id)}`);
|
|
6440
6654
|
if (page.pages && page.pages.length > 0) {
|
|
6441
6655
|
lines.push(formatDocInfo(doc, page.pages, indent + 1));
|
|
6442
6656
|
}
|
|
@@ -6515,7 +6729,7 @@ async function deleteDocPage(config, docId, pageId) {
|
|
|
6515
6729
|
}
|
|
6516
6730
|
|
|
6517
6731
|
// src/commands/folders.ts
|
|
6518
|
-
import
|
|
6732
|
+
import chalk13 from "chalk";
|
|
6519
6733
|
async function listFolders(config, spaceId, nameFilter, archived) {
|
|
6520
6734
|
const client = new ClickUpClient(config);
|
|
6521
6735
|
const folders = await client.getFolders(spaceId, archived);
|
|
@@ -6534,9 +6748,9 @@ async function listFolders(config, spaceId, nameFilter, archived) {
|
|
|
6534
6748
|
function formatFolders(folders) {
|
|
6535
6749
|
if (folders.length === 0) return "No folders found";
|
|
6536
6750
|
return folders.map((f) => {
|
|
6537
|
-
const header = `${
|
|
6751
|
+
const header = `${chalk13.bold(f.name)} ${chalk13.dim(f.id)}`;
|
|
6538
6752
|
if (f.lists.length === 0) return header;
|
|
6539
|
-
const listLines = f.lists.map((l) => ` ${
|
|
6753
|
+
const listLines = f.lists.map((l) => ` ${chalk13.dim(">")} ${l.name} ${chalk13.dim(l.id)}`);
|
|
6540
6754
|
return [header, ...listLines].join("\n");
|
|
6541
6755
|
}).join("\n\n");
|
|
6542
6756
|
}
|
|
@@ -6551,13 +6765,13 @@ function formatFoldersMarkdown(folders) {
|
|
|
6551
6765
|
}
|
|
6552
6766
|
|
|
6553
6767
|
// src/commands/time.ts
|
|
6554
|
-
import
|
|
6768
|
+
import chalk14 from "chalk";
|
|
6555
6769
|
var TIME_COLUMNS = [
|
|
6556
6770
|
{ key: "task", label: "Task", maxWidth: 35 },
|
|
6557
6771
|
{ key: "duration", label: "Duration", maxWidth: 10 },
|
|
6558
6772
|
{ key: "date", label: "Date", maxWidth: 20 },
|
|
6559
6773
|
{ key: "description", label: "Description", maxWidth: 30 },
|
|
6560
|
-
{ key: "status", label: "", maxWidth: 10, format: (v) => v === "RUNNING" ?
|
|
6774
|
+
{ key: "status", label: "", maxWidth: 10, format: (v) => v === "RUNNING" ? chalk14.green(v) : "" }
|
|
6561
6775
|
];
|
|
6562
6776
|
async function startTimer(config, taskId, description) {
|
|
6563
6777
|
const client = new ClickUpClient(config);
|
|
@@ -6653,7 +6867,7 @@ function formatTimeEntriesMarkdown(entries) {
|
|
|
6653
6867
|
}
|
|
6654
6868
|
|
|
6655
6869
|
// src/commands/tags.ts
|
|
6656
|
-
import
|
|
6870
|
+
import chalk15 from "chalk";
|
|
6657
6871
|
var TAG_COLUMNS = [
|
|
6658
6872
|
{ key: "name", label: "Name", maxWidth: 40 },
|
|
6659
6873
|
{ key: "fg", label: "FG", maxWidth: 10 },
|
|
@@ -6686,13 +6900,13 @@ function formatTags(tags) {
|
|
|
6686
6900
|
if (tags.length === 0) return "No tags found";
|
|
6687
6901
|
if (isTTY()) {
|
|
6688
6902
|
const rows = tags.map((t) => ({
|
|
6689
|
-
name: t.tag_bg ?
|
|
6903
|
+
name: t.tag_bg ? chalk15.bgHex(t.tag_bg).hex(t.tag_fg || "#ffffff")(` ${t.name} `) : chalk15.bold(t.name),
|
|
6690
6904
|
fg: t.tag_fg || "",
|
|
6691
6905
|
bg: t.tag_bg || ""
|
|
6692
6906
|
}));
|
|
6693
6907
|
return formatTable(rows, TAG_COLUMNS);
|
|
6694
6908
|
}
|
|
6695
|
-
return tags.map((t) =>
|
|
6909
|
+
return tags.map((t) => chalk15.bold(t.name)).join(", ");
|
|
6696
6910
|
}
|
|
6697
6911
|
function formatTagsMarkdown(tags) {
|
|
6698
6912
|
if (tags.length === 0) return "No tags found";
|
|
@@ -6727,7 +6941,7 @@ function formatMembersMarkdown(members) {
|
|
|
6727
6941
|
}
|
|
6728
6942
|
|
|
6729
6943
|
// src/commands/fields.ts
|
|
6730
|
-
import
|
|
6944
|
+
import chalk16 from "chalk";
|
|
6731
6945
|
var FIELD_COLUMNS = [
|
|
6732
6946
|
{ key: "id", label: "ID", maxWidth: 20 },
|
|
6733
6947
|
{ key: "name", label: "Name", maxWidth: 30 },
|
|
@@ -6736,7 +6950,7 @@ var FIELD_COLUMNS = [
|
|
|
6736
6950
|
key: "required",
|
|
6737
6951
|
label: "Required",
|
|
6738
6952
|
maxWidth: 10,
|
|
6739
|
-
format: (v) => v === "yes" ?
|
|
6953
|
+
format: (v) => v === "yes" ? chalk16.yellow(v) : chalk16.dim(v)
|
|
6740
6954
|
},
|
|
6741
6955
|
{ key: "options", label: "Options", maxWidth: 40 }
|
|
6742
6956
|
];
|
|
@@ -6894,13 +7108,13 @@ async function bulkMove(config, listId, taskIds) {
|
|
|
6894
7108
|
}
|
|
6895
7109
|
|
|
6896
7110
|
// src/commands/goals.ts
|
|
6897
|
-
import
|
|
7111
|
+
import chalk17 from "chalk";
|
|
6898
7112
|
function colorProgress(value) {
|
|
6899
7113
|
const num = parseInt(value, 10);
|
|
6900
7114
|
if (isNaN(num)) return value;
|
|
6901
|
-
if (num >= 75) return
|
|
6902
|
-
if (num >= 25) return
|
|
6903
|
-
return
|
|
7115
|
+
if (num >= 75) return chalk17.green(value);
|
|
7116
|
+
if (num >= 25) return chalk17.yellow(value);
|
|
7117
|
+
return chalk17.red(value);
|
|
6904
7118
|
}
|
|
6905
7119
|
var GOAL_COLUMNS = [
|
|
6906
7120
|
{ key: "id", label: "ID", maxWidth: 15 },
|
|
@@ -6994,14 +7208,14 @@ function formatKeyResultsMarkdown(keyResults) {
|
|
|
6994
7208
|
}
|
|
6995
7209
|
|
|
6996
7210
|
// src/commands/task-types.ts
|
|
6997
|
-
import
|
|
7211
|
+
import chalk18 from "chalk";
|
|
6998
7212
|
async function listTaskTypes(config) {
|
|
6999
7213
|
const client = new ClickUpClient(config);
|
|
7000
7214
|
return client.getCustomTaskTypes(config.teamId);
|
|
7001
7215
|
}
|
|
7002
7216
|
function formatTaskTypes(types) {
|
|
7003
7217
|
if (types.length === 0) return "No custom task types";
|
|
7004
|
-
return types.map((t) => `${
|
|
7218
|
+
return types.map((t) => `${chalk18.bold(t.name)} ${chalk18.dim(`(${t.id})`)}`).join("\n");
|
|
7005
7219
|
}
|
|
7006
7220
|
function formatTaskTypesMarkdown(types) {
|
|
7007
7221
|
if (types.length === 0) return "No custom task types";
|
|
@@ -7009,14 +7223,14 @@ function formatTaskTypesMarkdown(types) {
|
|
|
7009
7223
|
}
|
|
7010
7224
|
|
|
7011
7225
|
// src/commands/templates.ts
|
|
7012
|
-
import
|
|
7226
|
+
import chalk19 from "chalk";
|
|
7013
7227
|
async function listTemplates(config) {
|
|
7014
7228
|
const client = new ClickUpClient(config);
|
|
7015
7229
|
return client.getTaskTemplates(config.teamId);
|
|
7016
7230
|
}
|
|
7017
7231
|
function formatTemplates(templates) {
|
|
7018
7232
|
if (templates.length === 0) return "No task templates";
|
|
7019
|
-
return templates.map((t) => `${
|
|
7233
|
+
return templates.map((t) => `${chalk19.bold(t.name)} ${chalk19.dim(`(${t.id})`)}`).join("\n");
|
|
7020
7234
|
}
|
|
7021
7235
|
function formatTemplatesMarkdown(templates) {
|
|
7022
7236
|
if (templates.length === 0) return "No task templates";
|
|
@@ -7024,14 +7238,14 @@ function formatTemplatesMarkdown(templates) {
|
|
|
7024
7238
|
}
|
|
7025
7239
|
|
|
7026
7240
|
// src/commands/list-templates.ts
|
|
7027
|
-
import
|
|
7241
|
+
import chalk20 from "chalk";
|
|
7028
7242
|
async function listListTemplates(config) {
|
|
7029
7243
|
const client = new ClickUpClient(config);
|
|
7030
7244
|
return client.getListTemplates(config.teamId);
|
|
7031
7245
|
}
|
|
7032
7246
|
function formatListTemplates(templates) {
|
|
7033
7247
|
if (templates.length === 0) return "No list templates";
|
|
7034
|
-
return templates.map((t) => `${
|
|
7248
|
+
return templates.map((t) => `${chalk20.bold(t.name)} ${chalk20.dim(`(${t.id})`)}`).join("\n");
|
|
7035
7249
|
}
|
|
7036
7250
|
function formatListTemplatesMarkdown(templates) {
|
|
7037
7251
|
if (templates.length === 0) return "No list templates";
|
|
@@ -7039,14 +7253,14 @@ function formatListTemplatesMarkdown(templates) {
|
|
|
7039
7253
|
}
|
|
7040
7254
|
|
|
7041
7255
|
// src/commands/folder-templates.ts
|
|
7042
|
-
import
|
|
7256
|
+
import chalk21 from "chalk";
|
|
7043
7257
|
async function listFolderTemplates(config) {
|
|
7044
7258
|
const client = new ClickUpClient(config);
|
|
7045
7259
|
return client.getFolderTemplates(config.teamId);
|
|
7046
7260
|
}
|
|
7047
7261
|
function formatFolderTemplates(templates) {
|
|
7048
7262
|
if (templates.length === 0) return "No folder templates";
|
|
7049
|
-
return templates.map((t) => `${
|
|
7263
|
+
return templates.map((t) => `${chalk21.bold(t.name)} ${chalk21.dim(`(${t.id})`)}`).join("\n");
|
|
7050
7264
|
}
|
|
7051
7265
|
function formatFolderTemplatesMarkdown(templates) {
|
|
7052
7266
|
if (templates.length === 0) return "No folder templates";
|
|
@@ -7069,7 +7283,7 @@ async function createListFromTemplate(config, name, opts) {
|
|
|
7069
7283
|
}
|
|
7070
7284
|
|
|
7071
7285
|
// src/commands/views.ts
|
|
7072
|
-
import
|
|
7286
|
+
import chalk22 from "chalk";
|
|
7073
7287
|
async function listViews(config, id, container = "list") {
|
|
7074
7288
|
const client = new ClickUpClient(config);
|
|
7075
7289
|
if (container === "space") return client.getSpaceViews(id);
|
|
@@ -7080,7 +7294,7 @@ async function listViews(config, id, container = "list") {
|
|
|
7080
7294
|
}
|
|
7081
7295
|
function formatViews(views) {
|
|
7082
7296
|
if (views.length === 0) return "No views";
|
|
7083
|
-
return views.map((v) => `${
|
|
7297
|
+
return views.map((v) => `${chalk22.bold(v.name)} ${chalk22.dim(`(${v.id})`)} ${chalk22.dim(v.type)}`).join("\n");
|
|
7084
7298
|
}
|
|
7085
7299
|
function formatViewsMarkdown(views) {
|
|
7086
7300
|
if (views.length === 0) return "No views";
|
|
@@ -7088,23 +7302,23 @@ function formatViewsMarkdown(views) {
|
|
|
7088
7302
|
}
|
|
7089
7303
|
|
|
7090
7304
|
// src/commands/chat.ts
|
|
7091
|
-
import
|
|
7305
|
+
import chalk23 from "chalk";
|
|
7092
7306
|
function channelName(c) {
|
|
7093
7307
|
return c.name || "DM";
|
|
7094
7308
|
}
|
|
7095
7309
|
function colorChannelType(type) {
|
|
7096
|
-
if (type === "CHANNEL") return
|
|
7097
|
-
if (type === "DM") return
|
|
7098
|
-
if (type === "GROUP_DM") return
|
|
7310
|
+
if (type === "CHANNEL") return chalk23.cyan(type);
|
|
7311
|
+
if (type === "DM") return chalk23.dim(type);
|
|
7312
|
+
if (type === "GROUP_DM") return chalk23.blue(type);
|
|
7099
7313
|
return type;
|
|
7100
7314
|
}
|
|
7101
7315
|
function colorVisibility(v) {
|
|
7102
|
-
if (v === "PUBLIC") return
|
|
7103
|
-
return
|
|
7316
|
+
if (v === "PUBLIC") return chalk23.green(v);
|
|
7317
|
+
return chalk23.dim(v);
|
|
7104
7318
|
}
|
|
7105
7319
|
var CHANNEL_COLUMNS = [
|
|
7106
|
-
{ key: "name", label: "Name", maxWidth: 40, format: (v) =>
|
|
7107
|
-
{ key: "id", label: "ID", maxWidth: 20, format: (v) =>
|
|
7320
|
+
{ key: "name", label: "Name", maxWidth: 40, format: (v) => chalk23.bold(v) },
|
|
7321
|
+
{ key: "id", label: "ID", maxWidth: 20, format: (v) => chalk23.dim(v) },
|
|
7108
7322
|
{ key: "type", label: "Type", maxWidth: 12, format: (v) => colorChannelType(v) },
|
|
7109
7323
|
{ key: "visibility", label: "Visibility", maxWidth: 10, format: (v) => colorVisibility(v) },
|
|
7110
7324
|
{ key: "topic", label: "Topic", maxWidth: 40 }
|
|
@@ -7129,26 +7343,26 @@ function formatChannelsMarkdown(channels) {
|
|
|
7129
7343
|
}
|
|
7130
7344
|
function formatChannelDetail(channel) {
|
|
7131
7345
|
const lines = [];
|
|
7132
|
-
lines.push(
|
|
7346
|
+
lines.push(chalk23.bold.underline(channelName(channel)));
|
|
7133
7347
|
lines.push("");
|
|
7134
7348
|
const fields = [
|
|
7135
|
-
["ID",
|
|
7349
|
+
["ID", chalk23.dim(channel.id)],
|
|
7136
7350
|
["Type", colorChannelType(channel.type)],
|
|
7137
7351
|
["Visibility", colorVisibility(channel.visibility)]
|
|
7138
7352
|
];
|
|
7139
7353
|
if (channel.topic) fields.push(["Topic", channel.topic]);
|
|
7140
7354
|
if (channel.description) fields.push(["Description", channel.description]);
|
|
7141
|
-
fields.push(["Archived", channel.archived ?
|
|
7355
|
+
fields.push(["Archived", channel.archived ? chalk23.yellow("Yes") : "No"]);
|
|
7142
7356
|
fields.push(["Created", formatDate(channel.created_at)]);
|
|
7143
7357
|
const maxLabel = Math.max(...fields.map(([k]) => k.length));
|
|
7144
7358
|
for (const [label, value] of fields) {
|
|
7145
|
-
lines.push(` ${
|
|
7359
|
+
lines.push(` ${chalk23.bold(label.padEnd(maxLabel + 1))} ${value}`);
|
|
7146
7360
|
}
|
|
7147
7361
|
return lines.join("\n");
|
|
7148
7362
|
}
|
|
7149
7363
|
var CHAT_MEMBER_COLUMNS = [
|
|
7150
|
-
{ key: "name", label: "Name", maxWidth: 30, format: (v) =>
|
|
7151
|
-
{ key: "id", label: "ID", maxWidth: 15, format: (v) =>
|
|
7364
|
+
{ key: "name", label: "Name", maxWidth: 30, format: (v) => chalk23.bold(v) },
|
|
7365
|
+
{ key: "id", label: "ID", maxWidth: 15, format: (v) => chalk23.dim(v) },
|
|
7152
7366
|
{ key: "email", label: "Email", maxWidth: 40 },
|
|
7153
7367
|
{ key: "type", label: "Type", maxWidth: 12 }
|
|
7154
7368
|
];
|
|
@@ -7171,22 +7385,22 @@ function formatChatMembersMarkdown(members) {
|
|
|
7171
7385
|
}
|
|
7172
7386
|
|
|
7173
7387
|
// src/commands/chat-message.ts
|
|
7174
|
-
import
|
|
7175
|
-
var separator =
|
|
7388
|
+
import chalk24 from "chalk";
|
|
7389
|
+
var separator = chalk24.dim("-".repeat(60));
|
|
7176
7390
|
function formatMessages(messages) {
|
|
7177
7391
|
if (messages.length === 0) return "No messages";
|
|
7178
7392
|
const lines = [];
|
|
7179
7393
|
for (let i = 0; i < messages.length; i++) {
|
|
7180
7394
|
const msg = messages[i];
|
|
7181
7395
|
if (i > 0) lines.push(separator);
|
|
7182
|
-
const meta = [
|
|
7396
|
+
const meta = [chalk24.bold(`@${msg.user_id}`), chalk24.dim(formatTimestamp(msg.date))];
|
|
7183
7397
|
if (msg.replies_count) {
|
|
7184
|
-
meta.push(
|
|
7398
|
+
meta.push(chalk24.dim(`${msg.replies_count} replies`));
|
|
7185
7399
|
}
|
|
7186
|
-
meta.push(
|
|
7400
|
+
meta.push(chalk24.dim(`(${msg.id})`));
|
|
7187
7401
|
lines.push(meta.join(" "));
|
|
7188
7402
|
if (msg.type === "post" && msg.post_data?.title) {
|
|
7189
|
-
lines.push(
|
|
7403
|
+
lines.push(chalk24.cyan.bold(msg.post_data.title));
|
|
7190
7404
|
}
|
|
7191
7405
|
lines.push(msg.content);
|
|
7192
7406
|
}
|
|
@@ -7205,7 +7419,7 @@ ${msg.content}`;
|
|
|
7205
7419
|
}
|
|
7206
7420
|
|
|
7207
7421
|
// src/commands/chat-reaction.ts
|
|
7208
|
-
import
|
|
7422
|
+
import chalk25 from "chalk";
|
|
7209
7423
|
var EMOJI_MAP = {
|
|
7210
7424
|
thumbsup: "\u{1F44D}",
|
|
7211
7425
|
thumbsdown: "\u{1F44E}",
|
|
@@ -7244,8 +7458,8 @@ function formatReactions(reactions) {
|
|
|
7244
7458
|
const lines = [];
|
|
7245
7459
|
for (const [emoji, users] of groups) {
|
|
7246
7460
|
const icon = emojiChar(emoji);
|
|
7247
|
-
const userList = users.map((u) =>
|
|
7248
|
-
lines.push(`${icon} ${
|
|
7461
|
+
const userList = users.map((u) => chalk25.bold(`@${u}`)).join(", ");
|
|
7462
|
+
lines.push(`${icon} ${chalk25.dim(emoji)} ${chalk25.dim(`(${users.length})`)} \u2014 ${userList}`);
|
|
7249
7463
|
}
|
|
7250
7464
|
return lines.join("\n");
|
|
7251
7465
|
}
|
|
@@ -7260,20 +7474,20 @@ function formatReactionsMarkdown(reactions) {
|
|
|
7260
7474
|
}
|
|
7261
7475
|
|
|
7262
7476
|
// src/commands/view.ts
|
|
7263
|
-
import
|
|
7477
|
+
import chalk26 from "chalk";
|
|
7264
7478
|
async function getView(config, viewId) {
|
|
7265
7479
|
const client = new ClickUpClient(config);
|
|
7266
7480
|
return client.getView(viewId);
|
|
7267
7481
|
}
|
|
7268
7482
|
function formatView(view) {
|
|
7269
7483
|
const lines = [];
|
|
7270
|
-
lines.push(
|
|
7484
|
+
lines.push(chalk26.bold.underline(view.name));
|
|
7271
7485
|
lines.push("");
|
|
7272
|
-
lines.push(` ${
|
|
7273
|
-
lines.push(` ${
|
|
7274
|
-
if (view.visibility) lines.push(` ${
|
|
7275
|
-
if (view.date_created) lines.push(` ${
|
|
7276
|
-
if (view.protected !== void 0) lines.push(` ${
|
|
7486
|
+
lines.push(` ${chalk26.bold("ID")} ${view.id}`);
|
|
7487
|
+
lines.push(` ${chalk26.bold("Type")} ${view.type}`);
|
|
7488
|
+
if (view.visibility) lines.push(` ${chalk26.bold("Visibility")} ${view.visibility}`);
|
|
7489
|
+
if (view.date_created) lines.push(` ${chalk26.bold("Created")} ${formatDate(view.date_created)}`);
|
|
7490
|
+
if (view.protected !== void 0) lines.push(` ${chalk26.bold("Protected")} ${view.protected}`);
|
|
7277
7491
|
return lines.join("\n");
|
|
7278
7492
|
}
|
|
7279
7493
|
function formatViewMarkdown(view) {
|
|
@@ -8187,6 +8401,78 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
8187
8401
|
}
|
|
8188
8402
|
})
|
|
8189
8403
|
);
|
|
8404
|
+
program.command("list-delete <listId>").description("Delete a list (requires confirmation)").option("--confirm", "Skip confirmation prompt (required in non-interactive mode)").option("--json", "Force JSON output even in terminal").action(
|
|
8405
|
+
wrapAction(async (listId, opts) => {
|
|
8406
|
+
const config = loadConfig(getProfileName());
|
|
8407
|
+
const result = await deleteListCommand(config, listId, opts);
|
|
8408
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
8409
|
+
console.log(JSON.stringify(result, null, 2));
|
|
8410
|
+
} else {
|
|
8411
|
+
console.log(`Deleted list ${result.listId}`);
|
|
8412
|
+
}
|
|
8413
|
+
})
|
|
8414
|
+
);
|
|
8415
|
+
program.command("folder-delete <folderId>").description("Delete a folder (requires confirmation)").option("--confirm", "Skip confirmation prompt (required in non-interactive mode)").option("--json", "Force JSON output even in terminal").action(
|
|
8416
|
+
wrapAction(async (folderId, opts) => {
|
|
8417
|
+
const config = loadConfig(getProfileName());
|
|
8418
|
+
const result = await deleteFolderCommand(config, folderId, opts);
|
|
8419
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
8420
|
+
console.log(JSON.stringify(result, null, 2));
|
|
8421
|
+
} else {
|
|
8422
|
+
console.log(`Deleted folder ${result.folderId}`);
|
|
8423
|
+
}
|
|
8424
|
+
})
|
|
8425
|
+
);
|
|
8426
|
+
program.command("space-delete <spaceId>").description("Delete a space (requires confirmation)").option("--confirm", "Skip confirmation prompt (required in non-interactive mode)").option("--json", "Force JSON output even in terminal").action(
|
|
8427
|
+
wrapAction(async (spaceId, opts) => {
|
|
8428
|
+
const config = loadConfig(getProfileName());
|
|
8429
|
+
const result = await deleteSpaceCommand(config, spaceId, opts);
|
|
8430
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
8431
|
+
console.log(JSON.stringify(result, null, 2));
|
|
8432
|
+
} else {
|
|
8433
|
+
console.log(`Deleted space ${result.spaceId}`);
|
|
8434
|
+
}
|
|
8435
|
+
})
|
|
8436
|
+
);
|
|
8437
|
+
program.command("attachments <taskId>").description("List attachments on a task").option("--json", "Force JSON output even in terminal").action(
|
|
8438
|
+
wrapAction(async (taskId, opts) => {
|
|
8439
|
+
const config = loadConfig(getProfileName());
|
|
8440
|
+
const attachments = await listTaskAttachments(config, taskId);
|
|
8441
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
8442
|
+
console.log(JSON.stringify(attachments, null, 2));
|
|
8443
|
+
} else if (isTTY()) {
|
|
8444
|
+
console.log(formatAttachmentsTable(attachments));
|
|
8445
|
+
} else {
|
|
8446
|
+
console.log(formatAttachmentsMarkdown(attachments));
|
|
8447
|
+
}
|
|
8448
|
+
})
|
|
8449
|
+
);
|
|
8450
|
+
program.command("task-members <taskId>").description("List members with access to a task").option("--json", "Force JSON output even in terminal").action(
|
|
8451
|
+
wrapAction(async (taskId, opts) => {
|
|
8452
|
+
const config = loadConfig(getProfileName());
|
|
8453
|
+
const members = await listTaskMembers(config, taskId);
|
|
8454
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
8455
|
+
console.log(JSON.stringify(members, null, 2));
|
|
8456
|
+
} else if (isTTY()) {
|
|
8457
|
+
console.log(formatTaskMembers(members));
|
|
8458
|
+
} else {
|
|
8459
|
+
console.log(formatTaskMembersMarkdown(members));
|
|
8460
|
+
}
|
|
8461
|
+
})
|
|
8462
|
+
);
|
|
8463
|
+
program.command("plan").description("Show workspace plan").option("--json", "Force JSON output even in terminal").action(
|
|
8464
|
+
wrapAction(async (opts) => {
|
|
8465
|
+
const config = loadConfig(getProfileName());
|
|
8466
|
+
const plan = await getWorkspacePlanCommand(config);
|
|
8467
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
8468
|
+
console.log(JSON.stringify(plan, null, 2));
|
|
8469
|
+
} else if (isTTY()) {
|
|
8470
|
+
console.log(formatPlan(plan));
|
|
8471
|
+
} else {
|
|
8472
|
+
console.log(formatPlanMarkdown(plan));
|
|
8473
|
+
}
|
|
8474
|
+
})
|
|
8475
|
+
);
|
|
8190
8476
|
program.command("archive <taskId>").description("Archive a task (or unarchive with --unarchive)").option("--unarchive", "Unarchive instead of archiving").option("--confirm", "Skip confirmation prompt (required in non-interactive mode)").option("--json", "Force JSON output even in terminal").action(
|
|
8191
8477
|
wrapAction(
|
|
8192
8478
|
async (taskId, opts) => {
|
package/package.json
CHANGED
|
@@ -3,11 +3,11 @@ name: clickup
|
|
|
3
3
|
description: 'Use when managing ClickUp tasks, sprints, or comments via the `cup` 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, listing members, listing fields, duplicating tasks, bulk operations, goals, key results, saved filters, favorites.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# ClickUp CLI (`cup`) - skill version 1.
|
|
6
|
+
# ClickUp CLI (`cup`) - skill version 1.29.0
|
|
7
7
|
|
|
8
8
|
Reference for AI agents using the `cup` CLI tool. Covers task management, sprint tracking, comments, time tracking, custom fields, goals, docs, and project workflows.
|
|
9
9
|
|
|
10
|
-
> **Version check:** Run `cup --version`. If your installed version is older than 1.
|
|
10
|
+
> **Version check:** Run `cup --version`. If your installed version is older than 1.29.0, update with `npm install -g @krodak/clickup-cli` and refresh this skill with `cup skill`.
|
|
11
11
|
|
|
12
12
|
## Install & Configure
|
|
13
13
|
|
|
@@ -127,6 +127,9 @@ All commands support `--help` for full flag details. All commands support `--jso
|
|
|
127
127
|
| `cup time-in-status <id>` | Show how long a task has been in each status |
|
|
128
128
|
| `cup members` | Workspace members (username, ID, email) |
|
|
129
129
|
| `cup fields <listId>` | Custom fields on a list (type, required, options) |
|
|
130
|
+
| `cup attachments <taskId>` | List attachments on a task (name, size, URL) |
|
|
131
|
+
| `cup task-members <taskId>` | List members with access to a task |
|
|
132
|
+
| `cup plan` | Show workspace plan and usage |
|
|
130
133
|
| `cup tags <spaceId>` | Tags available in a space |
|
|
131
134
|
| `cup goals` | Workspace goals with progress |
|
|
132
135
|
| `cup key-results <goalId>` | Key results for a goal |
|
|
@@ -169,6 +172,9 @@ All commands support `--help` for full flag details. All commands support `--jso
|
|
|
169
172
|
| `cup link <taskId> <linksTo> [--remove]` | Link/unlink tasks |
|
|
170
173
|
| `cup attach <taskId> <filePath>` | Upload file attachment |
|
|
171
174
|
| `cup delete <id> [--confirm]` | Delete task (DESTRUCTIVE) |
|
|
175
|
+
| `cup list-delete <listId> [--confirm]` | Delete list (DESTRUCTIVE, requires --confirm in non-interactive) |
|
|
176
|
+
| `cup folder-delete <folderId> [--confirm]` | Delete folder (DESTRUCTIVE, requires --confirm in non-interactive) |
|
|
177
|
+
| `cup space-delete <spaceId> [--confirm]` | Delete space (DESTRUCTIVE, requires --confirm in non-interactive) |
|
|
172
178
|
| `cup duplicate <taskId>` | Duplicate a task |
|
|
173
179
|
| `cup bulk status <status> <taskIds...>` | Bulk update status |
|
|
174
180
|
| `cup bulk assign <taskIds...> [--to userId\|me] [--remove userId\|me]` | Bulk assign/unassign user from tasks |
|
|
@@ -282,7 +288,7 @@ When running in a terminal (not piped), task-listing commands (`cup tasks`, `cup
|
|
|
282
288
|
- **Enter** to confirm and view details of selected tasks
|
|
283
289
|
- After viewing details, prompted to open tasks in browser
|
|
284
290
|
|
|
285
|
-
Other interactive prompts: sprint selection (when multiple match), workspace selection (`cup init`), agent selection (`cup skill`), destructive action confirmations (`cup delete`, `cup archive`, `cup view-delete`).
|
|
291
|
+
Other interactive prompts: sprint selection (when multiple match), workspace selection (`cup init`), agent selection (`cup skill`), destructive action confirmations (`cup delete`, `cup list-delete`, `cup folder-delete`, `cup space-delete`, `cup archive`, `cup view-delete`).
|
|
286
292
|
|
|
287
293
|
When piped or called with `--json`, all commands output non-interactive markdown or JSON. Agents should always use `--json` for structured data or pipe for markdown.
|
|
288
294
|
|
|
@@ -420,4 +426,4 @@ cup summary --hours 48 # wider window
|
|
|
420
426
|
|
|
421
427
|
## DELETE SAFETY
|
|
422
428
|
|
|
423
|
-
IMPORTANT: Always confirm with the user before running `cup delete`.
|
|
429
|
+
IMPORTANT: Always confirm with the user before running `cup delete`, `cup list-delete`, `cup folder-delete`, or `cup space-delete`. These are destructive, irreversible operations. Even when using `--confirm` flag, verify the ID is correct with the user first.
|