@krodak/clickup-cli 1.28.0 → 1.30.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 +17 -16
- package/dist/index.js +865 -67
- package/package.json +1 -1
- package/skills/clickup-cli/SKILL.md +21 -4
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"
|
|
@@ -978,6 +1000,77 @@ var ClickUpClient = class {
|
|
|
978
1000
|
{ method: "DELETE" }
|
|
979
1001
|
);
|
|
980
1002
|
}
|
|
1003
|
+
async mergeTasks(taskId, mergeWithTaskIds) {
|
|
1004
|
+
await this.request(this.taskPath(taskId, "/merge"), {
|
|
1005
|
+
method: "POST",
|
|
1006
|
+
body: JSON.stringify({ merge_with: mergeWithTaskIds })
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
async updateTimeEstimatesByUser(taskId, estimates) {
|
|
1010
|
+
return this.requestV3(`/workspaces/${this.teamId}/tasks/${taskId}/time_estimates_by_user`, {
|
|
1011
|
+
method: "PATCH",
|
|
1012
|
+
body: JSON.stringify({ time_estimates_by_user: estimates })
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
1015
|
+
async replaceTimeEstimatesByUser(taskId, estimates) {
|
|
1016
|
+
return this.requestV3(`/workspaces/${this.teamId}/tasks/${taskId}/time_estimates_by_user`, {
|
|
1017
|
+
method: "PUT",
|
|
1018
|
+
body: JSON.stringify({ time_estimates_by_user: estimates })
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
async getSharedHierarchy() {
|
|
1022
|
+
return this.request(`/team/${this.teamId}/shared`);
|
|
1023
|
+
}
|
|
1024
|
+
async getWebhooks() {
|
|
1025
|
+
const data = await this.request(`/team/${this.teamId}/webhook`);
|
|
1026
|
+
return readCollectionField(data, "webhooks", "webhooks");
|
|
1027
|
+
}
|
|
1028
|
+
async createWebhook(endpoint, events, opts) {
|
|
1029
|
+
const body = { endpoint, events };
|
|
1030
|
+
if (opts?.taskId) body.task_id = opts.taskId;
|
|
1031
|
+
if (opts?.listId) body.list_id = opts.listId;
|
|
1032
|
+
if (opts?.folderId) body.folder_id = opts.folderId;
|
|
1033
|
+
if (opts?.spaceId) body.space_id = opts.spaceId;
|
|
1034
|
+
const data = await this.request(`/team/${this.teamId}/webhook`, {
|
|
1035
|
+
method: "POST",
|
|
1036
|
+
body: JSON.stringify(body)
|
|
1037
|
+
});
|
|
1038
|
+
return expectRecordField(data, "webhook", "webhook");
|
|
1039
|
+
}
|
|
1040
|
+
async updateWebhook(webhookId, opts) {
|
|
1041
|
+
const data = await this.request(`/webhook/${webhookId}`, {
|
|
1042
|
+
method: "PUT",
|
|
1043
|
+
body: JSON.stringify(opts)
|
|
1044
|
+
});
|
|
1045
|
+
return expectRecordField(data, "webhook", "webhook");
|
|
1046
|
+
}
|
|
1047
|
+
async deleteWebhook(webhookId) {
|
|
1048
|
+
await this.request(`/webhook/${webhookId}`, { method: "DELETE" });
|
|
1049
|
+
}
|
|
1050
|
+
async getListComments(listId) {
|
|
1051
|
+
const data = await this.request(`/list/${listId}/comment`);
|
|
1052
|
+
return readCollectionField(data, "comments", "list comments");
|
|
1053
|
+
}
|
|
1054
|
+
async postListComment(listId, commentText, notifyAll) {
|
|
1055
|
+
const body = { comment_text: commentText };
|
|
1056
|
+
if (notifyAll) body.notify_all = true;
|
|
1057
|
+
return this.request(`/list/${listId}/comment`, {
|
|
1058
|
+
method: "POST",
|
|
1059
|
+
body: JSON.stringify(body)
|
|
1060
|
+
});
|
|
1061
|
+
}
|
|
1062
|
+
async getViewComments(viewId) {
|
|
1063
|
+
const data = await this.request(`/view/${viewId}/comment`);
|
|
1064
|
+
return readCollectionField(data, "comments", "view comments");
|
|
1065
|
+
}
|
|
1066
|
+
async postViewComment(viewId, commentText, notifyAll) {
|
|
1067
|
+
const body = { comment_text: commentText };
|
|
1068
|
+
if (notifyAll) body.notify_all = true;
|
|
1069
|
+
return this.request(`/view/${viewId}/comment`, {
|
|
1070
|
+
method: "POST",
|
|
1071
|
+
body: JSON.stringify(body)
|
|
1072
|
+
});
|
|
1073
|
+
}
|
|
981
1074
|
};
|
|
982
1075
|
|
|
983
1076
|
// src/config.ts
|
|
@@ -3888,6 +3981,60 @@ var commandMetadata = [
|
|
|
3888
3981
|
flags: ["--confirm", "--json"],
|
|
3889
3982
|
quickReference: [{ section: "write", usage: "delete <taskId>", description: "Delete a task" }]
|
|
3890
3983
|
},
|
|
3984
|
+
{
|
|
3985
|
+
name: "list-delete",
|
|
3986
|
+
description: "Delete a list (requires confirmation)",
|
|
3987
|
+
flags: ["--confirm", "--json"],
|
|
3988
|
+
quickReference: [
|
|
3989
|
+
{ section: "write", usage: "list-delete <listId>", description: "Delete a list" }
|
|
3990
|
+
]
|
|
3991
|
+
},
|
|
3992
|
+
{
|
|
3993
|
+
name: "folder-delete",
|
|
3994
|
+
description: "Delete a folder (requires confirmation)",
|
|
3995
|
+
flags: ["--confirm", "--json"],
|
|
3996
|
+
quickReference: [
|
|
3997
|
+
{ section: "write", usage: "folder-delete <folderId>", description: "Delete a folder" }
|
|
3998
|
+
]
|
|
3999
|
+
},
|
|
4000
|
+
{
|
|
4001
|
+
name: "space-delete",
|
|
4002
|
+
description: "Delete a space (requires confirmation)",
|
|
4003
|
+
flags: ["--confirm", "--json"],
|
|
4004
|
+
quickReference: [
|
|
4005
|
+
{ section: "write", usage: "space-delete <spaceId>", description: "Delete a space" }
|
|
4006
|
+
]
|
|
4007
|
+
},
|
|
4008
|
+
{
|
|
4009
|
+
name: "attachments",
|
|
4010
|
+
description: "List attachments on a task",
|
|
4011
|
+
flags: ["--json"],
|
|
4012
|
+
quickReference: [
|
|
4013
|
+
{
|
|
4014
|
+
section: "read",
|
|
4015
|
+
usage: "attachments <taskId>",
|
|
4016
|
+
description: "List attachments on a task"
|
|
4017
|
+
}
|
|
4018
|
+
]
|
|
4019
|
+
},
|
|
4020
|
+
{
|
|
4021
|
+
name: "task-members",
|
|
4022
|
+
description: "List members with access to a task",
|
|
4023
|
+
flags: ["--json"],
|
|
4024
|
+
quickReference: [
|
|
4025
|
+
{
|
|
4026
|
+
section: "read",
|
|
4027
|
+
usage: "task-members <taskId>",
|
|
4028
|
+
description: "List members with access to a task"
|
|
4029
|
+
}
|
|
4030
|
+
]
|
|
4031
|
+
},
|
|
4032
|
+
{
|
|
4033
|
+
name: "plan",
|
|
4034
|
+
description: "Show workspace plan",
|
|
4035
|
+
flags: ["--json"],
|
|
4036
|
+
quickReference: [{ section: "read", usage: "plan", description: "Show workspace plan" }]
|
|
4037
|
+
},
|
|
3891
4038
|
{
|
|
3892
4039
|
name: "tag",
|
|
3893
4040
|
description: "Add or remove tags from a task",
|
|
@@ -3969,7 +4116,12 @@ var commandMetadata = [
|
|
|
3969
4116
|
description: "List my recent time entries (--all for team)"
|
|
3970
4117
|
},
|
|
3971
4118
|
{ section: "write", usage: "time update <timeEntryId>", description: "Update a time entry" },
|
|
3972
|
-
{ section: "write", usage: "time delete <timeEntryId>", description: "Delete a time entry" }
|
|
4119
|
+
{ section: "write", usage: "time delete <timeEntryId>", description: "Delete a time entry" },
|
|
4120
|
+
{
|
|
4121
|
+
section: "write",
|
|
4122
|
+
usage: "time estimate-by-user <taskId> <userId> <duration>",
|
|
4123
|
+
description: "Set per-user time estimate"
|
|
4124
|
+
}
|
|
3973
4125
|
]
|
|
3974
4126
|
},
|
|
3975
4127
|
{
|
|
@@ -4425,6 +4577,92 @@ var commandMetadata = [
|
|
|
4425
4577
|
{ section: "read", usage: "favorite list", description: "List saved favorites" }
|
|
4426
4578
|
]
|
|
4427
4579
|
},
|
|
4580
|
+
{
|
|
4581
|
+
name: "list-comments",
|
|
4582
|
+
description: "List comments on a list",
|
|
4583
|
+
flags: ["--json"],
|
|
4584
|
+
quickReference: [
|
|
4585
|
+
{
|
|
4586
|
+
section: "read",
|
|
4587
|
+
usage: "list-comments <listId>",
|
|
4588
|
+
description: "List comments on a list"
|
|
4589
|
+
}
|
|
4590
|
+
]
|
|
4591
|
+
},
|
|
4592
|
+
{
|
|
4593
|
+
name: "list-comment",
|
|
4594
|
+
description: "Post a comment on a list",
|
|
4595
|
+
flags: ["-m", "--message", "--notify-all", "--json"],
|
|
4596
|
+
quickReference: [
|
|
4597
|
+
{
|
|
4598
|
+
section: "write",
|
|
4599
|
+
usage: "list-comment <listId>",
|
|
4600
|
+
description: "Post a comment on a list"
|
|
4601
|
+
}
|
|
4602
|
+
]
|
|
4603
|
+
},
|
|
4604
|
+
{
|
|
4605
|
+
name: "view-comments",
|
|
4606
|
+
description: "List comments on a view",
|
|
4607
|
+
flags: ["--json"],
|
|
4608
|
+
quickReference: [
|
|
4609
|
+
{
|
|
4610
|
+
section: "read",
|
|
4611
|
+
usage: "view-comments <viewId>",
|
|
4612
|
+
description: "List comments on a view"
|
|
4613
|
+
}
|
|
4614
|
+
]
|
|
4615
|
+
},
|
|
4616
|
+
{
|
|
4617
|
+
name: "view-comment",
|
|
4618
|
+
description: "Post a comment on a view",
|
|
4619
|
+
flags: ["-m", "--message", "--notify-all", "--json"],
|
|
4620
|
+
quickReference: [
|
|
4621
|
+
{
|
|
4622
|
+
section: "write",
|
|
4623
|
+
usage: "view-comment <viewId>",
|
|
4624
|
+
description: "Post a comment on a view"
|
|
4625
|
+
}
|
|
4626
|
+
]
|
|
4627
|
+
},
|
|
4628
|
+
{
|
|
4629
|
+
name: "webhook",
|
|
4630
|
+
description: "Manage webhooks",
|
|
4631
|
+
quickReference: [
|
|
4632
|
+
{ section: "read", usage: "webhook list", description: "List webhooks" },
|
|
4633
|
+
{
|
|
4634
|
+
section: "write",
|
|
4635
|
+
usage: "webhook create",
|
|
4636
|
+
description: "Create a webhook"
|
|
4637
|
+
},
|
|
4638
|
+
{ section: "write", usage: "webhook update <webhookId>", description: "Update a webhook" },
|
|
4639
|
+
{ section: "write", usage: "webhook delete <webhookId>", description: "Delete a webhook" }
|
|
4640
|
+
]
|
|
4641
|
+
},
|
|
4642
|
+
{
|
|
4643
|
+
name: "merge",
|
|
4644
|
+
description: "Merge a task into another (source becomes subtask of target)",
|
|
4645
|
+
flags: ["--confirm", "--json"],
|
|
4646
|
+
quickReference: [
|
|
4647
|
+
{
|
|
4648
|
+
section: "write",
|
|
4649
|
+
usage: "merge <sourceTaskId> <intoTaskId>",
|
|
4650
|
+
description: "Merge a task into another"
|
|
4651
|
+
}
|
|
4652
|
+
]
|
|
4653
|
+
},
|
|
4654
|
+
{
|
|
4655
|
+
name: "shared",
|
|
4656
|
+
description: "Show shared spaces, folders, and lists",
|
|
4657
|
+
flags: ["--json"],
|
|
4658
|
+
quickReference: [
|
|
4659
|
+
{
|
|
4660
|
+
section: "read",
|
|
4661
|
+
usage: "shared",
|
|
4662
|
+
description: "Show shared spaces, folders, and lists"
|
|
4663
|
+
}
|
|
4664
|
+
]
|
|
4665
|
+
},
|
|
4428
4666
|
{
|
|
4429
4667
|
name: "chat",
|
|
4430
4668
|
description: "Chat channels and messaging",
|
|
@@ -6150,6 +6388,144 @@ async function deleteTaskCommand(config, taskId, opts) {
|
|
|
6150
6388
|
return { taskId, deleted: true };
|
|
6151
6389
|
}
|
|
6152
6390
|
|
|
6391
|
+
// src/commands/list-delete.ts
|
|
6392
|
+
async function deleteListCommand(config, listId, opts) {
|
|
6393
|
+
const client = new ClickUpClient(config);
|
|
6394
|
+
if (!opts.confirm) {
|
|
6395
|
+
if (!isTTY()) {
|
|
6396
|
+
throw new Error("Destructive operation requires --confirm flag in non-interactive mode");
|
|
6397
|
+
}
|
|
6398
|
+
const list = await client.getListWithStatuses(listId);
|
|
6399
|
+
const { confirm: confirm3 } = await import("@inquirer/prompts");
|
|
6400
|
+
const confirmed = await confirm3({
|
|
6401
|
+
message: `Delete list "${list.name}" (${listId})? This cannot be undone.`,
|
|
6402
|
+
default: false
|
|
6403
|
+
});
|
|
6404
|
+
if (!confirmed) {
|
|
6405
|
+
throw new Error("Cancelled");
|
|
6406
|
+
}
|
|
6407
|
+
}
|
|
6408
|
+
await client.deleteList(listId);
|
|
6409
|
+
return { listId, deleted: true };
|
|
6410
|
+
}
|
|
6411
|
+
|
|
6412
|
+
// src/commands/folder-delete.ts
|
|
6413
|
+
async function deleteFolderCommand(config, folderId, opts) {
|
|
6414
|
+
const client = new ClickUpClient(config);
|
|
6415
|
+
if (!opts.confirm) {
|
|
6416
|
+
if (!isTTY()) {
|
|
6417
|
+
throw new Error("Destructive operation requires --confirm flag in non-interactive mode");
|
|
6418
|
+
}
|
|
6419
|
+
const { confirm: confirm3 } = await import("@inquirer/prompts");
|
|
6420
|
+
const confirmed = await confirm3({
|
|
6421
|
+
message: `Delete folder ${folderId}? This cannot be undone.`,
|
|
6422
|
+
default: false
|
|
6423
|
+
});
|
|
6424
|
+
if (!confirmed) {
|
|
6425
|
+
throw new Error("Cancelled");
|
|
6426
|
+
}
|
|
6427
|
+
}
|
|
6428
|
+
await client.deleteFolder(folderId);
|
|
6429
|
+
return { folderId, deleted: true };
|
|
6430
|
+
}
|
|
6431
|
+
|
|
6432
|
+
// src/commands/space-delete.ts
|
|
6433
|
+
async function deleteSpaceCommand(config, spaceId, opts) {
|
|
6434
|
+
const client = new ClickUpClient(config);
|
|
6435
|
+
if (!opts.confirm) {
|
|
6436
|
+
if (!isTTY()) {
|
|
6437
|
+
throw new Error("Destructive operation requires --confirm flag in non-interactive mode");
|
|
6438
|
+
}
|
|
6439
|
+
const space = await client.getSpaceWithStatuses(spaceId);
|
|
6440
|
+
const { confirm: confirm3 } = await import("@inquirer/prompts");
|
|
6441
|
+
const confirmed = await confirm3({
|
|
6442
|
+
message: `Delete space "${space.name}" (${spaceId})? This cannot be undone.`,
|
|
6443
|
+
default: false
|
|
6444
|
+
});
|
|
6445
|
+
if (!confirmed) {
|
|
6446
|
+
throw new Error("Cancelled");
|
|
6447
|
+
}
|
|
6448
|
+
}
|
|
6449
|
+
await client.deleteSpace(spaceId);
|
|
6450
|
+
return { spaceId, deleted: true };
|
|
6451
|
+
}
|
|
6452
|
+
|
|
6453
|
+
// src/commands/attachments.ts
|
|
6454
|
+
function formatSize(size) {
|
|
6455
|
+
if (size < 1024) return `${size} B`;
|
|
6456
|
+
if (size < 1048576) return `${(size / 1024).toFixed(1)} KB`;
|
|
6457
|
+
return `${(size / 1048576).toFixed(1)} MB`;
|
|
6458
|
+
}
|
|
6459
|
+
var ATTACHMENT_COLUMNS = [
|
|
6460
|
+
{ key: "title", label: "Title", maxWidth: 40 },
|
|
6461
|
+
{ key: "extension", label: "Ext", maxWidth: 10 },
|
|
6462
|
+
{ key: "size", label: "Size", maxWidth: 10 },
|
|
6463
|
+
{ key: "date", label: "Date", maxWidth: 12 },
|
|
6464
|
+
{ key: "url", label: "URL", maxWidth: 60 }
|
|
6465
|
+
];
|
|
6466
|
+
function toRow(a) {
|
|
6467
|
+
return {
|
|
6468
|
+
title: a.title,
|
|
6469
|
+
extension: a.extension,
|
|
6470
|
+
size: formatSize(a.size),
|
|
6471
|
+
date: new Date(a.date_created).toLocaleDateString(),
|
|
6472
|
+
url: a.url
|
|
6473
|
+
};
|
|
6474
|
+
}
|
|
6475
|
+
async function listTaskAttachments(config, taskId) {
|
|
6476
|
+
const client = new ClickUpClient(config);
|
|
6477
|
+
return client.getTaskAttachments(taskId);
|
|
6478
|
+
}
|
|
6479
|
+
function formatAttachmentsTable(attachments) {
|
|
6480
|
+
if (attachments.length === 0) return "No attachments found";
|
|
6481
|
+
const rows = attachments.map(toRow);
|
|
6482
|
+
return formatTable(rows, ATTACHMENT_COLUMNS);
|
|
6483
|
+
}
|
|
6484
|
+
function formatAttachmentsMarkdown(attachments) {
|
|
6485
|
+
if (attachments.length === 0) return "No attachments found";
|
|
6486
|
+
return attachments.map((a) => `- **${a.title}** (${a.extension}, ${formatSize(a.size)}) \u2014 ${a.url}`).join("\n");
|
|
6487
|
+
}
|
|
6488
|
+
|
|
6489
|
+
// src/commands/task-members.ts
|
|
6490
|
+
var TASK_MEMBER_COLUMNS = [
|
|
6491
|
+
{ key: "username", label: "Username", maxWidth: 25 },
|
|
6492
|
+
{ key: "id", label: "ID", maxWidth: 15 },
|
|
6493
|
+
{ key: "email", label: "Email", maxWidth: 40 }
|
|
6494
|
+
];
|
|
6495
|
+
async function listTaskMembers(config, taskId) {
|
|
6496
|
+
const client = new ClickUpClient(config);
|
|
6497
|
+
return client.getTaskMembers(taskId);
|
|
6498
|
+
}
|
|
6499
|
+
function formatTaskMembers(members) {
|
|
6500
|
+
if (members.length === 0) return "No task members found";
|
|
6501
|
+
const rows = members.map((m) => ({
|
|
6502
|
+
username: m.username,
|
|
6503
|
+
id: String(m.id),
|
|
6504
|
+
email: m.email
|
|
6505
|
+
}));
|
|
6506
|
+
return formatTable(rows, TASK_MEMBER_COLUMNS);
|
|
6507
|
+
}
|
|
6508
|
+
function formatTaskMembersMarkdown(members) {
|
|
6509
|
+
if (members.length === 0) return "No task members found";
|
|
6510
|
+
return members.map((m) => `- **${m.username}** (${m.id}) - ${m.email}`).join("\n");
|
|
6511
|
+
}
|
|
6512
|
+
|
|
6513
|
+
// src/commands/plan.ts
|
|
6514
|
+
import chalk9 from "chalk";
|
|
6515
|
+
async function getWorkspacePlanCommand(config) {
|
|
6516
|
+
const client = new ClickUpClient(config);
|
|
6517
|
+
return client.getWorkspacePlan();
|
|
6518
|
+
}
|
|
6519
|
+
function formatPlan(plan) {
|
|
6520
|
+
return [
|
|
6521
|
+
`${chalk9.bold("Plan:")} ${plan.name}`,
|
|
6522
|
+
`${chalk9.bold("Plan ID:")} ${plan.plan_id}`
|
|
6523
|
+
].join("\n");
|
|
6524
|
+
}
|
|
6525
|
+
function formatPlanMarkdown(plan) {
|
|
6526
|
+
return [`**Plan:** ${plan.name}`, `**Plan ID:** ${plan.plan_id}`].join("\n");
|
|
6527
|
+
}
|
|
6528
|
+
|
|
6153
6529
|
// src/commands/archive.ts
|
|
6154
6530
|
async function archiveTaskCommand(config, taskId, opts) {
|
|
6155
6531
|
const client = new ClickUpClient(config);
|
|
@@ -6210,7 +6586,7 @@ async function manageTags(config, taskId, opts) {
|
|
|
6210
6586
|
}
|
|
6211
6587
|
|
|
6212
6588
|
// src/commands/checklist.ts
|
|
6213
|
-
import
|
|
6589
|
+
import chalk10 from "chalk";
|
|
6214
6590
|
async function viewChecklists(config, taskId) {
|
|
6215
6591
|
const client = new ClickUpClient(config);
|
|
6216
6592
|
const task = await client.getTask(taskId);
|
|
@@ -6260,19 +6636,19 @@ function formatChecklists(checklists) {
|
|
|
6260
6636
|
const lines = [];
|
|
6261
6637
|
const renderItem = (item, depth) => {
|
|
6262
6638
|
const indent = " ".repeat(depth + 1);
|
|
6263
|
-
const check = item.resolved ?
|
|
6264
|
-
const name = item.resolved ?
|
|
6265
|
-
const assignee = item.assignee ?
|
|
6639
|
+
const check = item.resolved ? chalk10.green("[x]") : chalk10.dim("[ ]");
|
|
6640
|
+
const name = item.resolved ? chalk10.dim(item.name) : item.name;
|
|
6641
|
+
const assignee = item.assignee ? chalk10.dim(` @${item.assignee.username}`) : "";
|
|
6266
6642
|
lines.push(`${indent}${check} ${name}${assignee}`);
|
|
6267
|
-
lines.push(
|
|
6643
|
+
lines.push(chalk10.dim(`${indent} item-id: ${item.id}`));
|
|
6268
6644
|
for (const child of sortByOrder(item.children ?? [])) {
|
|
6269
6645
|
renderItem(child, depth + 1);
|
|
6270
6646
|
}
|
|
6271
6647
|
};
|
|
6272
6648
|
for (const cl of checklists) {
|
|
6273
6649
|
const { total, resolved } = countItems(cl.items);
|
|
6274
|
-
lines.push(
|
|
6275
|
-
lines.push(
|
|
6650
|
+
lines.push(chalk10.bold(`${cl.name} (${resolved}/${total})`));
|
|
6651
|
+
lines.push(chalk10.dim(` ID: ${cl.id}`));
|
|
6276
6652
|
for (const item of sortByOrder(cl.items)) renderItem(item, 0);
|
|
6277
6653
|
}
|
|
6278
6654
|
return lines.join("\n");
|
|
@@ -6338,7 +6714,7 @@ async function deleteCommentByTaskSelection(config, taskId, options) {
|
|
|
6338
6714
|
}
|
|
6339
6715
|
|
|
6340
6716
|
// src/commands/replies.ts
|
|
6341
|
-
import
|
|
6717
|
+
import chalk11 from "chalk";
|
|
6342
6718
|
async function getReplies(config, commentId) {
|
|
6343
6719
|
const client = new ClickUpClient(config);
|
|
6344
6720
|
return client.getThreadedComments(commentId);
|
|
@@ -6354,7 +6730,7 @@ function formatReplies(replies) {
|
|
|
6354
6730
|
return replies.map((r) => {
|
|
6355
6731
|
const user = r.user?.username ?? "Unknown";
|
|
6356
6732
|
const date = formatTimestamp(Number(r.date));
|
|
6357
|
-
return `${
|
|
6733
|
+
return `${chalk11.bold(user)} ${chalk11.dim(date)}
|
|
6358
6734
|
${r.comment_text}`;
|
|
6359
6735
|
}).join("\n\n");
|
|
6360
6736
|
}
|
|
@@ -6417,7 +6793,7 @@ function formatDocsMarkdown(docs) {
|
|
|
6417
6793
|
}
|
|
6418
6794
|
|
|
6419
6795
|
// src/commands/doc.ts
|
|
6420
|
-
import
|
|
6796
|
+
import chalk12 from "chalk";
|
|
6421
6797
|
async function getDocInfo(config, docId) {
|
|
6422
6798
|
const client = new ClickUpClient(config);
|
|
6423
6799
|
const [doc, pages] = await Promise.all([
|
|
@@ -6429,14 +6805,14 @@ async function getDocInfo(config, docId) {
|
|
|
6429
6805
|
function formatDocInfo(doc, pages, indent = 0) {
|
|
6430
6806
|
const lines = [];
|
|
6431
6807
|
if (indent === 0) {
|
|
6432
|
-
lines.push(`${
|
|
6808
|
+
lines.push(`${chalk12.bold(doc.name)} ${chalk12.dim(doc.id)}`);
|
|
6433
6809
|
if (pages.length === 0) {
|
|
6434
6810
|
lines.push(" (no pages)");
|
|
6435
6811
|
}
|
|
6436
6812
|
}
|
|
6437
6813
|
for (const page of pages) {
|
|
6438
6814
|
const prefix = " ".repeat(indent + 1);
|
|
6439
|
-
lines.push(`${prefix}${page.name} ${
|
|
6815
|
+
lines.push(`${prefix}${page.name} ${chalk12.dim(page.id)}`);
|
|
6440
6816
|
if (page.pages && page.pages.length > 0) {
|
|
6441
6817
|
lines.push(formatDocInfo(doc, page.pages, indent + 1));
|
|
6442
6818
|
}
|
|
@@ -6515,7 +6891,7 @@ async function deleteDocPage(config, docId, pageId) {
|
|
|
6515
6891
|
}
|
|
6516
6892
|
|
|
6517
6893
|
// src/commands/folders.ts
|
|
6518
|
-
import
|
|
6894
|
+
import chalk13 from "chalk";
|
|
6519
6895
|
async function listFolders(config, spaceId, nameFilter, archived) {
|
|
6520
6896
|
const client = new ClickUpClient(config);
|
|
6521
6897
|
const folders = await client.getFolders(spaceId, archived);
|
|
@@ -6534,9 +6910,9 @@ async function listFolders(config, spaceId, nameFilter, archived) {
|
|
|
6534
6910
|
function formatFolders(folders) {
|
|
6535
6911
|
if (folders.length === 0) return "No folders found";
|
|
6536
6912
|
return folders.map((f) => {
|
|
6537
|
-
const header = `${
|
|
6913
|
+
const header = `${chalk13.bold(f.name)} ${chalk13.dim(f.id)}`;
|
|
6538
6914
|
if (f.lists.length === 0) return header;
|
|
6539
|
-
const listLines = f.lists.map((l) => ` ${
|
|
6915
|
+
const listLines = f.lists.map((l) => ` ${chalk13.dim(">")} ${l.name} ${chalk13.dim(l.id)}`);
|
|
6540
6916
|
return [header, ...listLines].join("\n");
|
|
6541
6917
|
}).join("\n\n");
|
|
6542
6918
|
}
|
|
@@ -6551,13 +6927,13 @@ function formatFoldersMarkdown(folders) {
|
|
|
6551
6927
|
}
|
|
6552
6928
|
|
|
6553
6929
|
// src/commands/time.ts
|
|
6554
|
-
import
|
|
6930
|
+
import chalk14 from "chalk";
|
|
6555
6931
|
var TIME_COLUMNS = [
|
|
6556
6932
|
{ key: "task", label: "Task", maxWidth: 35 },
|
|
6557
6933
|
{ key: "duration", label: "Duration", maxWidth: 10 },
|
|
6558
6934
|
{ key: "date", label: "Date", maxWidth: 20 },
|
|
6559
6935
|
{ key: "description", label: "Description", maxWidth: 30 },
|
|
6560
|
-
{ key: "status", label: "", maxWidth: 10, format: (v) => v === "RUNNING" ?
|
|
6936
|
+
{ key: "status", label: "", maxWidth: 10, format: (v) => v === "RUNNING" ? chalk14.green(v) : "" }
|
|
6561
6937
|
];
|
|
6562
6938
|
async function startTimer(config, taskId, description) {
|
|
6563
6939
|
const client = new ClickUpClient(config);
|
|
@@ -6653,7 +7029,7 @@ function formatTimeEntriesMarkdown(entries) {
|
|
|
6653
7029
|
}
|
|
6654
7030
|
|
|
6655
7031
|
// src/commands/tags.ts
|
|
6656
|
-
import
|
|
7032
|
+
import chalk15 from "chalk";
|
|
6657
7033
|
var TAG_COLUMNS = [
|
|
6658
7034
|
{ key: "name", label: "Name", maxWidth: 40 },
|
|
6659
7035
|
{ key: "fg", label: "FG", maxWidth: 10 },
|
|
@@ -6686,13 +7062,13 @@ function formatTags(tags) {
|
|
|
6686
7062
|
if (tags.length === 0) return "No tags found";
|
|
6687
7063
|
if (isTTY()) {
|
|
6688
7064
|
const rows = tags.map((t) => ({
|
|
6689
|
-
name: t.tag_bg ?
|
|
7065
|
+
name: t.tag_bg ? chalk15.bgHex(t.tag_bg).hex(t.tag_fg || "#ffffff")(` ${t.name} `) : chalk15.bold(t.name),
|
|
6690
7066
|
fg: t.tag_fg || "",
|
|
6691
7067
|
bg: t.tag_bg || ""
|
|
6692
7068
|
}));
|
|
6693
7069
|
return formatTable(rows, TAG_COLUMNS);
|
|
6694
7070
|
}
|
|
6695
|
-
return tags.map((t) =>
|
|
7071
|
+
return tags.map((t) => chalk15.bold(t.name)).join(", ");
|
|
6696
7072
|
}
|
|
6697
7073
|
function formatTagsMarkdown(tags) {
|
|
6698
7074
|
if (tags.length === 0) return "No tags found";
|
|
@@ -6727,7 +7103,7 @@ function formatMembersMarkdown(members) {
|
|
|
6727
7103
|
}
|
|
6728
7104
|
|
|
6729
7105
|
// src/commands/fields.ts
|
|
6730
|
-
import
|
|
7106
|
+
import chalk16 from "chalk";
|
|
6731
7107
|
var FIELD_COLUMNS = [
|
|
6732
7108
|
{ key: "id", label: "ID", maxWidth: 20 },
|
|
6733
7109
|
{ key: "name", label: "Name", maxWidth: 30 },
|
|
@@ -6736,7 +7112,7 @@ var FIELD_COLUMNS = [
|
|
|
6736
7112
|
key: "required",
|
|
6737
7113
|
label: "Required",
|
|
6738
7114
|
maxWidth: 10,
|
|
6739
|
-
format: (v) => v === "yes" ?
|
|
7115
|
+
format: (v) => v === "yes" ? chalk16.yellow(v) : chalk16.dim(v)
|
|
6740
7116
|
},
|
|
6741
7117
|
{ key: "options", label: "Options", maxWidth: 40 }
|
|
6742
7118
|
];
|
|
@@ -6894,13 +7270,13 @@ async function bulkMove(config, listId, taskIds) {
|
|
|
6894
7270
|
}
|
|
6895
7271
|
|
|
6896
7272
|
// src/commands/goals.ts
|
|
6897
|
-
import
|
|
7273
|
+
import chalk17 from "chalk";
|
|
6898
7274
|
function colorProgress(value) {
|
|
6899
7275
|
const num = parseInt(value, 10);
|
|
6900
7276
|
if (isNaN(num)) return value;
|
|
6901
|
-
if (num >= 75) return
|
|
6902
|
-
if (num >= 25) return
|
|
6903
|
-
return
|
|
7277
|
+
if (num >= 75) return chalk17.green(value);
|
|
7278
|
+
if (num >= 25) return chalk17.yellow(value);
|
|
7279
|
+
return chalk17.red(value);
|
|
6904
7280
|
}
|
|
6905
7281
|
var GOAL_COLUMNS = [
|
|
6906
7282
|
{ key: "id", label: "ID", maxWidth: 15 },
|
|
@@ -6994,14 +7370,14 @@ function formatKeyResultsMarkdown(keyResults) {
|
|
|
6994
7370
|
}
|
|
6995
7371
|
|
|
6996
7372
|
// src/commands/task-types.ts
|
|
6997
|
-
import
|
|
7373
|
+
import chalk18 from "chalk";
|
|
6998
7374
|
async function listTaskTypes(config) {
|
|
6999
7375
|
const client = new ClickUpClient(config);
|
|
7000
7376
|
return client.getCustomTaskTypes(config.teamId);
|
|
7001
7377
|
}
|
|
7002
7378
|
function formatTaskTypes(types) {
|
|
7003
7379
|
if (types.length === 0) return "No custom task types";
|
|
7004
|
-
return types.map((t) => `${
|
|
7380
|
+
return types.map((t) => `${chalk18.bold(t.name)} ${chalk18.dim(`(${t.id})`)}`).join("\n");
|
|
7005
7381
|
}
|
|
7006
7382
|
function formatTaskTypesMarkdown(types) {
|
|
7007
7383
|
if (types.length === 0) return "No custom task types";
|
|
@@ -7009,14 +7385,14 @@ function formatTaskTypesMarkdown(types) {
|
|
|
7009
7385
|
}
|
|
7010
7386
|
|
|
7011
7387
|
// src/commands/templates.ts
|
|
7012
|
-
import
|
|
7388
|
+
import chalk19 from "chalk";
|
|
7013
7389
|
async function listTemplates(config) {
|
|
7014
7390
|
const client = new ClickUpClient(config);
|
|
7015
7391
|
return client.getTaskTemplates(config.teamId);
|
|
7016
7392
|
}
|
|
7017
7393
|
function formatTemplates(templates) {
|
|
7018
7394
|
if (templates.length === 0) return "No task templates";
|
|
7019
|
-
return templates.map((t) => `${
|
|
7395
|
+
return templates.map((t) => `${chalk19.bold(t.name)} ${chalk19.dim(`(${t.id})`)}`).join("\n");
|
|
7020
7396
|
}
|
|
7021
7397
|
function formatTemplatesMarkdown(templates) {
|
|
7022
7398
|
if (templates.length === 0) return "No task templates";
|
|
@@ -7024,14 +7400,14 @@ function formatTemplatesMarkdown(templates) {
|
|
|
7024
7400
|
}
|
|
7025
7401
|
|
|
7026
7402
|
// src/commands/list-templates.ts
|
|
7027
|
-
import
|
|
7403
|
+
import chalk20 from "chalk";
|
|
7028
7404
|
async function listListTemplates(config) {
|
|
7029
7405
|
const client = new ClickUpClient(config);
|
|
7030
7406
|
return client.getListTemplates(config.teamId);
|
|
7031
7407
|
}
|
|
7032
7408
|
function formatListTemplates(templates) {
|
|
7033
7409
|
if (templates.length === 0) return "No list templates";
|
|
7034
|
-
return templates.map((t) => `${
|
|
7410
|
+
return templates.map((t) => `${chalk20.bold(t.name)} ${chalk20.dim(`(${t.id})`)}`).join("\n");
|
|
7035
7411
|
}
|
|
7036
7412
|
function formatListTemplatesMarkdown(templates) {
|
|
7037
7413
|
if (templates.length === 0) return "No list templates";
|
|
@@ -7039,14 +7415,14 @@ function formatListTemplatesMarkdown(templates) {
|
|
|
7039
7415
|
}
|
|
7040
7416
|
|
|
7041
7417
|
// src/commands/folder-templates.ts
|
|
7042
|
-
import
|
|
7418
|
+
import chalk21 from "chalk";
|
|
7043
7419
|
async function listFolderTemplates(config) {
|
|
7044
7420
|
const client = new ClickUpClient(config);
|
|
7045
7421
|
return client.getFolderTemplates(config.teamId);
|
|
7046
7422
|
}
|
|
7047
7423
|
function formatFolderTemplates(templates) {
|
|
7048
7424
|
if (templates.length === 0) return "No folder templates";
|
|
7049
|
-
return templates.map((t) => `${
|
|
7425
|
+
return templates.map((t) => `${chalk21.bold(t.name)} ${chalk21.dim(`(${t.id})`)}`).join("\n");
|
|
7050
7426
|
}
|
|
7051
7427
|
function formatFolderTemplatesMarkdown(templates) {
|
|
7052
7428
|
if (templates.length === 0) return "No folder templates";
|
|
@@ -7069,7 +7445,7 @@ async function createListFromTemplate(config, name, opts) {
|
|
|
7069
7445
|
}
|
|
7070
7446
|
|
|
7071
7447
|
// src/commands/views.ts
|
|
7072
|
-
import
|
|
7448
|
+
import chalk22 from "chalk";
|
|
7073
7449
|
async function listViews(config, id, container = "list") {
|
|
7074
7450
|
const client = new ClickUpClient(config);
|
|
7075
7451
|
if (container === "space") return client.getSpaceViews(id);
|
|
@@ -7080,7 +7456,7 @@ async function listViews(config, id, container = "list") {
|
|
|
7080
7456
|
}
|
|
7081
7457
|
function formatViews(views) {
|
|
7082
7458
|
if (views.length === 0) return "No views";
|
|
7083
|
-
return views.map((v) => `${
|
|
7459
|
+
return views.map((v) => `${chalk22.bold(v.name)} ${chalk22.dim(`(${v.id})`)} ${chalk22.dim(v.type)}`).join("\n");
|
|
7084
7460
|
}
|
|
7085
7461
|
function formatViewsMarkdown(views) {
|
|
7086
7462
|
if (views.length === 0) return "No views";
|
|
@@ -7088,23 +7464,23 @@ function formatViewsMarkdown(views) {
|
|
|
7088
7464
|
}
|
|
7089
7465
|
|
|
7090
7466
|
// src/commands/chat.ts
|
|
7091
|
-
import
|
|
7467
|
+
import chalk23 from "chalk";
|
|
7092
7468
|
function channelName(c) {
|
|
7093
7469
|
return c.name || "DM";
|
|
7094
7470
|
}
|
|
7095
7471
|
function colorChannelType(type) {
|
|
7096
|
-
if (type === "CHANNEL") return
|
|
7097
|
-
if (type === "DM") return
|
|
7098
|
-
if (type === "GROUP_DM") return
|
|
7472
|
+
if (type === "CHANNEL") return chalk23.cyan(type);
|
|
7473
|
+
if (type === "DM") return chalk23.dim(type);
|
|
7474
|
+
if (type === "GROUP_DM") return chalk23.blue(type);
|
|
7099
7475
|
return type;
|
|
7100
7476
|
}
|
|
7101
7477
|
function colorVisibility(v) {
|
|
7102
|
-
if (v === "PUBLIC") return
|
|
7103
|
-
return
|
|
7478
|
+
if (v === "PUBLIC") return chalk23.green(v);
|
|
7479
|
+
return chalk23.dim(v);
|
|
7104
7480
|
}
|
|
7105
7481
|
var CHANNEL_COLUMNS = [
|
|
7106
|
-
{ key: "name", label: "Name", maxWidth: 40, format: (v) =>
|
|
7107
|
-
{ key: "id", label: "ID", maxWidth: 20, format: (v) =>
|
|
7482
|
+
{ key: "name", label: "Name", maxWidth: 40, format: (v) => chalk23.bold(v) },
|
|
7483
|
+
{ key: "id", label: "ID", maxWidth: 20, format: (v) => chalk23.dim(v) },
|
|
7108
7484
|
{ key: "type", label: "Type", maxWidth: 12, format: (v) => colorChannelType(v) },
|
|
7109
7485
|
{ key: "visibility", label: "Visibility", maxWidth: 10, format: (v) => colorVisibility(v) },
|
|
7110
7486
|
{ key: "topic", label: "Topic", maxWidth: 40 }
|
|
@@ -7129,26 +7505,26 @@ function formatChannelsMarkdown(channels) {
|
|
|
7129
7505
|
}
|
|
7130
7506
|
function formatChannelDetail(channel) {
|
|
7131
7507
|
const lines = [];
|
|
7132
|
-
lines.push(
|
|
7508
|
+
lines.push(chalk23.bold.underline(channelName(channel)));
|
|
7133
7509
|
lines.push("");
|
|
7134
7510
|
const fields = [
|
|
7135
|
-
["ID",
|
|
7511
|
+
["ID", chalk23.dim(channel.id)],
|
|
7136
7512
|
["Type", colorChannelType(channel.type)],
|
|
7137
7513
|
["Visibility", colorVisibility(channel.visibility)]
|
|
7138
7514
|
];
|
|
7139
7515
|
if (channel.topic) fields.push(["Topic", channel.topic]);
|
|
7140
7516
|
if (channel.description) fields.push(["Description", channel.description]);
|
|
7141
|
-
fields.push(["Archived", channel.archived ?
|
|
7517
|
+
fields.push(["Archived", channel.archived ? chalk23.yellow("Yes") : "No"]);
|
|
7142
7518
|
fields.push(["Created", formatDate(channel.created_at)]);
|
|
7143
7519
|
const maxLabel = Math.max(...fields.map(([k]) => k.length));
|
|
7144
7520
|
for (const [label, value] of fields) {
|
|
7145
|
-
lines.push(` ${
|
|
7521
|
+
lines.push(` ${chalk23.bold(label.padEnd(maxLabel + 1))} ${value}`);
|
|
7146
7522
|
}
|
|
7147
7523
|
return lines.join("\n");
|
|
7148
7524
|
}
|
|
7149
7525
|
var CHAT_MEMBER_COLUMNS = [
|
|
7150
|
-
{ key: "name", label: "Name", maxWidth: 30, format: (v) =>
|
|
7151
|
-
{ key: "id", label: "ID", maxWidth: 15, format: (v) =>
|
|
7526
|
+
{ key: "name", label: "Name", maxWidth: 30, format: (v) => chalk23.bold(v) },
|
|
7527
|
+
{ key: "id", label: "ID", maxWidth: 15, format: (v) => chalk23.dim(v) },
|
|
7152
7528
|
{ key: "email", label: "Email", maxWidth: 40 },
|
|
7153
7529
|
{ key: "type", label: "Type", maxWidth: 12 }
|
|
7154
7530
|
];
|
|
@@ -7171,22 +7547,22 @@ function formatChatMembersMarkdown(members) {
|
|
|
7171
7547
|
}
|
|
7172
7548
|
|
|
7173
7549
|
// src/commands/chat-message.ts
|
|
7174
|
-
import
|
|
7175
|
-
var separator =
|
|
7550
|
+
import chalk24 from "chalk";
|
|
7551
|
+
var separator = chalk24.dim("-".repeat(60));
|
|
7176
7552
|
function formatMessages(messages) {
|
|
7177
7553
|
if (messages.length === 0) return "No messages";
|
|
7178
7554
|
const lines = [];
|
|
7179
7555
|
for (let i = 0; i < messages.length; i++) {
|
|
7180
7556
|
const msg = messages[i];
|
|
7181
7557
|
if (i > 0) lines.push(separator);
|
|
7182
|
-
const meta = [
|
|
7558
|
+
const meta = [chalk24.bold(`@${msg.user_id}`), chalk24.dim(formatTimestamp(msg.date))];
|
|
7183
7559
|
if (msg.replies_count) {
|
|
7184
|
-
meta.push(
|
|
7560
|
+
meta.push(chalk24.dim(`${msg.replies_count} replies`));
|
|
7185
7561
|
}
|
|
7186
|
-
meta.push(
|
|
7562
|
+
meta.push(chalk24.dim(`(${msg.id})`));
|
|
7187
7563
|
lines.push(meta.join(" "));
|
|
7188
7564
|
if (msg.type === "post" && msg.post_data?.title) {
|
|
7189
|
-
lines.push(
|
|
7565
|
+
lines.push(chalk24.cyan.bold(msg.post_data.title));
|
|
7190
7566
|
}
|
|
7191
7567
|
lines.push(msg.content);
|
|
7192
7568
|
}
|
|
@@ -7205,7 +7581,7 @@ ${msg.content}`;
|
|
|
7205
7581
|
}
|
|
7206
7582
|
|
|
7207
7583
|
// src/commands/chat-reaction.ts
|
|
7208
|
-
import
|
|
7584
|
+
import chalk25 from "chalk";
|
|
7209
7585
|
var EMOJI_MAP = {
|
|
7210
7586
|
thumbsup: "\u{1F44D}",
|
|
7211
7587
|
thumbsdown: "\u{1F44E}",
|
|
@@ -7244,8 +7620,8 @@ function formatReactions(reactions) {
|
|
|
7244
7620
|
const lines = [];
|
|
7245
7621
|
for (const [emoji, users] of groups) {
|
|
7246
7622
|
const icon = emojiChar(emoji);
|
|
7247
|
-
const userList = users.map((u) =>
|
|
7248
|
-
lines.push(`${icon} ${
|
|
7623
|
+
const userList = users.map((u) => chalk25.bold(`@${u}`)).join(", ");
|
|
7624
|
+
lines.push(`${icon} ${chalk25.dim(emoji)} ${chalk25.dim(`(${users.length})`)} \u2014 ${userList}`);
|
|
7249
7625
|
}
|
|
7250
7626
|
return lines.join("\n");
|
|
7251
7627
|
}
|
|
@@ -7260,20 +7636,20 @@ function formatReactionsMarkdown(reactions) {
|
|
|
7260
7636
|
}
|
|
7261
7637
|
|
|
7262
7638
|
// src/commands/view.ts
|
|
7263
|
-
import
|
|
7639
|
+
import chalk26 from "chalk";
|
|
7264
7640
|
async function getView(config, viewId) {
|
|
7265
7641
|
const client = new ClickUpClient(config);
|
|
7266
7642
|
return client.getView(viewId);
|
|
7267
7643
|
}
|
|
7268
7644
|
function formatView(view) {
|
|
7269
7645
|
const lines = [];
|
|
7270
|
-
lines.push(
|
|
7646
|
+
lines.push(chalk26.bold.underline(view.name));
|
|
7271
7647
|
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(` ${
|
|
7648
|
+
lines.push(` ${chalk26.bold("ID")} ${view.id}`);
|
|
7649
|
+
lines.push(` ${chalk26.bold("Type")} ${view.type}`);
|
|
7650
|
+
if (view.visibility) lines.push(` ${chalk26.bold("Visibility")} ${view.visibility}`);
|
|
7651
|
+
if (view.date_created) lines.push(` ${chalk26.bold("Created")} ${formatDate(view.date_created)}`);
|
|
7652
|
+
if (view.protected !== void 0) lines.push(` ${chalk26.bold("Protected")} ${view.protected}`);
|
|
7277
7653
|
return lines.join("\n");
|
|
7278
7654
|
}
|
|
7279
7655
|
function formatViewMarkdown(view) {
|
|
@@ -7562,6 +7938,222 @@ function formatFavoritesMarkdown(favorites) {
|
|
|
7562
7938
|
return lines.join("\n");
|
|
7563
7939
|
}
|
|
7564
7940
|
|
|
7941
|
+
// src/commands/merge.ts
|
|
7942
|
+
async function mergeCommand(config, sourceTaskId, intoTaskId, opts) {
|
|
7943
|
+
const client = new ClickUpClient(config);
|
|
7944
|
+
if (!opts.confirm) {
|
|
7945
|
+
if (!isTTY()) {
|
|
7946
|
+
throw new Error("Destructive operation requires --confirm flag in non-interactive mode");
|
|
7947
|
+
}
|
|
7948
|
+
const { confirm: confirm3 } = await import("@inquirer/prompts");
|
|
7949
|
+
const confirmed = await confirm3({
|
|
7950
|
+
message: `Merge task ${sourceTaskId} into ${intoTaskId}? The source task becomes a subtask of the target.`,
|
|
7951
|
+
default: false
|
|
7952
|
+
});
|
|
7953
|
+
if (!confirmed) {
|
|
7954
|
+
throw new Error("Cancelled");
|
|
7955
|
+
}
|
|
7956
|
+
}
|
|
7957
|
+
await client.mergeTasks(intoTaskId, [sourceTaskId]);
|
|
7958
|
+
return { sourceTaskId, intoTaskId, merged: true };
|
|
7959
|
+
}
|
|
7960
|
+
|
|
7961
|
+
// src/commands/webhook.ts
|
|
7962
|
+
import chalk27 from "chalk";
|
|
7963
|
+
var WEBHOOK_COLUMNS = [
|
|
7964
|
+
{ key: "id", label: "ID" },
|
|
7965
|
+
{ key: "endpoint", label: "Endpoint", maxWidth: 45 },
|
|
7966
|
+
{ key: "events", label: "Events", maxWidth: 30 },
|
|
7967
|
+
{
|
|
7968
|
+
key: "status",
|
|
7969
|
+
label: "Status",
|
|
7970
|
+
maxWidth: 10,
|
|
7971
|
+
format: (v) => v === "active" ? chalk27.green(v) : chalk27.dim(v)
|
|
7972
|
+
},
|
|
7973
|
+
{ key: "scope", label: "Scope", maxWidth: 15 }
|
|
7974
|
+
];
|
|
7975
|
+
function webhookScope(w) {
|
|
7976
|
+
if (w.task_id) return `task:${w.task_id}`;
|
|
7977
|
+
if (w.list_id) return `list:${w.list_id}`;
|
|
7978
|
+
if (w.folder_id) return `folder:${w.folder_id}`;
|
|
7979
|
+
if (w.space_id) return `space:${w.space_id}`;
|
|
7980
|
+
return "workspace";
|
|
7981
|
+
}
|
|
7982
|
+
async function fetchWebhooks(config) {
|
|
7983
|
+
const client = new ClickUpClient(config);
|
|
7984
|
+
return client.getWebhooks();
|
|
7985
|
+
}
|
|
7986
|
+
async function createWebhookCommand(config, opts) {
|
|
7987
|
+
const client = new ClickUpClient(config);
|
|
7988
|
+
const events = opts.events.split(",").map((e) => e.trim());
|
|
7989
|
+
const scopeOpts = {};
|
|
7990
|
+
if (opts.space) scopeOpts.spaceId = opts.space;
|
|
7991
|
+
if (opts.folder) scopeOpts.folderId = opts.folder;
|
|
7992
|
+
if (opts.list) scopeOpts.listId = opts.list;
|
|
7993
|
+
if (opts.task) scopeOpts.taskId = opts.task;
|
|
7994
|
+
return client.createWebhook(opts.url, events, scopeOpts);
|
|
7995
|
+
}
|
|
7996
|
+
async function updateWebhookCommand(config, webhookId, opts) {
|
|
7997
|
+
const client = new ClickUpClient(config);
|
|
7998
|
+
const payload = {};
|
|
7999
|
+
if (opts.url) payload.endpoint = opts.url;
|
|
8000
|
+
if (opts.events) payload.events = opts.events.split(",").map((e) => e.trim());
|
|
8001
|
+
if (opts.status) payload.status = opts.status;
|
|
8002
|
+
return client.updateWebhook(webhookId, payload);
|
|
8003
|
+
}
|
|
8004
|
+
async function deleteWebhookCommand(config, webhookId, opts) {
|
|
8005
|
+
const client = new ClickUpClient(config);
|
|
8006
|
+
if (!opts.confirm) {
|
|
8007
|
+
if (!isTTY()) {
|
|
8008
|
+
throw new Error("Destructive operation requires --confirm flag in non-interactive mode");
|
|
8009
|
+
}
|
|
8010
|
+
const { confirm: confirm3 } = await import("@inquirer/prompts");
|
|
8011
|
+
const confirmed = await confirm3({
|
|
8012
|
+
message: `Delete webhook ${webhookId}? This cannot be undone.`,
|
|
8013
|
+
default: false
|
|
8014
|
+
});
|
|
8015
|
+
if (!confirmed) {
|
|
8016
|
+
throw new Error("Cancelled");
|
|
8017
|
+
}
|
|
8018
|
+
}
|
|
8019
|
+
await client.deleteWebhook(webhookId);
|
|
8020
|
+
return { webhookId, deleted: true };
|
|
8021
|
+
}
|
|
8022
|
+
function formatWebhooks(webhooks) {
|
|
8023
|
+
if (webhooks.length === 0) return "No webhooks found.";
|
|
8024
|
+
const rows = webhooks.map((w) => ({
|
|
8025
|
+
id: w.id,
|
|
8026
|
+
endpoint: w.endpoint,
|
|
8027
|
+
events: w.events.join(", "),
|
|
8028
|
+
status: w.status,
|
|
8029
|
+
scope: webhookScope(w)
|
|
8030
|
+
}));
|
|
8031
|
+
return formatTable(rows, WEBHOOK_COLUMNS);
|
|
8032
|
+
}
|
|
8033
|
+
function formatWebhooksMarkdown(webhooks) {
|
|
8034
|
+
if (webhooks.length === 0) return "No webhooks found.";
|
|
8035
|
+
const lines = [];
|
|
8036
|
+
for (const w of webhooks) {
|
|
8037
|
+
lines.push(`## ${w.id}`);
|
|
8038
|
+
lines.push("");
|
|
8039
|
+
lines.push(`- **Endpoint:** ${w.endpoint}`);
|
|
8040
|
+
lines.push(`- **Events:** ${w.events.join(", ")}`);
|
|
8041
|
+
lines.push(`- **Status:** ${w.status}`);
|
|
8042
|
+
lines.push(`- **Scope:** ${webhookScope(w)}`);
|
|
8043
|
+
lines.push("");
|
|
8044
|
+
}
|
|
8045
|
+
return lines.join("\n");
|
|
8046
|
+
}
|
|
8047
|
+
|
|
8048
|
+
// src/commands/time-estimate-by-user.ts
|
|
8049
|
+
async function timeEstimateByUserCommand(config, taskId, userId, duration, opts) {
|
|
8050
|
+
const client = new ClickUpClient(config);
|
|
8051
|
+
const timeMs = parseTimeEstimate(duration);
|
|
8052
|
+
const estimates = [{ assignee: userId, time: timeMs }];
|
|
8053
|
+
if (opts.replace) {
|
|
8054
|
+
return client.replaceTimeEstimatesByUser(taskId, estimates);
|
|
8055
|
+
}
|
|
8056
|
+
return client.updateTimeEstimatesByUser(taskId, estimates);
|
|
8057
|
+
}
|
|
8058
|
+
|
|
8059
|
+
// src/commands/shared.ts
|
|
8060
|
+
import chalk28 from "chalk";
|
|
8061
|
+
async function fetchSharedHierarchy(config) {
|
|
8062
|
+
const client = new ClickUpClient(config);
|
|
8063
|
+
return client.getSharedHierarchy();
|
|
8064
|
+
}
|
|
8065
|
+
function formatSharedHierarchy(hierarchy) {
|
|
8066
|
+
const { spaces, folders, lists } = hierarchy.shared;
|
|
8067
|
+
if (spaces.length === 0 && folders.length === 0 && lists.length === 0) {
|
|
8068
|
+
return "No shared items found.";
|
|
8069
|
+
}
|
|
8070
|
+
const lines = [];
|
|
8071
|
+
if (spaces.length > 0) {
|
|
8072
|
+
lines.push(chalk28.bold("Spaces"));
|
|
8073
|
+
for (const s of spaces) {
|
|
8074
|
+
lines.push(` ${s.name} ${chalk28.dim(s.id)}`);
|
|
8075
|
+
}
|
|
8076
|
+
}
|
|
8077
|
+
if (folders.length > 0) {
|
|
8078
|
+
if (lines.length > 0) lines.push("");
|
|
8079
|
+
lines.push(chalk28.bold("Folders"));
|
|
8080
|
+
for (const f of folders) {
|
|
8081
|
+
lines.push(` ${f.name} ${chalk28.dim(f.id)}`);
|
|
8082
|
+
}
|
|
8083
|
+
}
|
|
8084
|
+
if (lists.length > 0) {
|
|
8085
|
+
if (lines.length > 0) lines.push("");
|
|
8086
|
+
lines.push(chalk28.bold("Lists"));
|
|
8087
|
+
for (const l of lists) {
|
|
8088
|
+
lines.push(` ${l.name} ${chalk28.dim(l.id)}`);
|
|
8089
|
+
}
|
|
8090
|
+
}
|
|
8091
|
+
return lines.join("\n");
|
|
8092
|
+
}
|
|
8093
|
+
function formatSharedHierarchyMarkdown(hierarchy) {
|
|
8094
|
+
const { spaces, folders, lists } = hierarchy.shared;
|
|
8095
|
+
if (spaces.length === 0 && folders.length === 0 && lists.length === 0) {
|
|
8096
|
+
return "No shared items found.";
|
|
8097
|
+
}
|
|
8098
|
+
const lines = ["# Shared Hierarchy", ""];
|
|
8099
|
+
if (spaces.length > 0) {
|
|
8100
|
+
lines.push("## Spaces", "");
|
|
8101
|
+
for (const s of spaces) {
|
|
8102
|
+
lines.push(`- **${s.name}** (${s.id})`);
|
|
8103
|
+
}
|
|
8104
|
+
lines.push("");
|
|
8105
|
+
}
|
|
8106
|
+
if (folders.length > 0) {
|
|
8107
|
+
lines.push("## Folders", "");
|
|
8108
|
+
for (const f of folders) {
|
|
8109
|
+
lines.push(`- **${f.name}** (${f.id})`);
|
|
8110
|
+
}
|
|
8111
|
+
lines.push("");
|
|
8112
|
+
}
|
|
8113
|
+
if (lists.length > 0) {
|
|
8114
|
+
lines.push("## Lists", "");
|
|
8115
|
+
for (const l of lists) {
|
|
8116
|
+
lines.push(`- **${l.name}** (${l.id})`);
|
|
8117
|
+
}
|
|
8118
|
+
lines.push("");
|
|
8119
|
+
}
|
|
8120
|
+
return lines.join("\n");
|
|
8121
|
+
}
|
|
8122
|
+
|
|
8123
|
+
// src/commands/list-comments.ts
|
|
8124
|
+
async function fetchListComments(config, listId) {
|
|
8125
|
+
const client = new ClickUpClient(config);
|
|
8126
|
+
const comments = await client.getListComments(listId);
|
|
8127
|
+
return comments.map((c) => ({
|
|
8128
|
+
id: c.id,
|
|
8129
|
+
user: c.user.username,
|
|
8130
|
+
date: c.date,
|
|
8131
|
+
text: c.comment_text
|
|
8132
|
+
}));
|
|
8133
|
+
}
|
|
8134
|
+
async function postListCommentCommand(config, listId, text, notifyAll) {
|
|
8135
|
+
if (!text.trim()) throw new Error("Comment text cannot be empty");
|
|
8136
|
+
const client = new ClickUpClient(config);
|
|
8137
|
+
return client.postListComment(listId, text, notifyAll);
|
|
8138
|
+
}
|
|
8139
|
+
|
|
8140
|
+
// src/commands/view-comments.ts
|
|
8141
|
+
async function fetchViewComments(config, viewId) {
|
|
8142
|
+
const client = new ClickUpClient(config);
|
|
8143
|
+
const comments = await client.getViewComments(viewId);
|
|
8144
|
+
return comments.map((c) => ({
|
|
8145
|
+
id: c.id,
|
|
8146
|
+
user: c.user.username,
|
|
8147
|
+
date: c.date,
|
|
8148
|
+
text: c.comment_text
|
|
8149
|
+
}));
|
|
8150
|
+
}
|
|
8151
|
+
async function postViewCommentCommand(config, viewId, text, notifyAll) {
|
|
8152
|
+
if (!text.trim()) throw new Error("Comment text cannot be empty");
|
|
8153
|
+
const client = new ClickUpClient(config);
|
|
8154
|
+
return client.postViewComment(viewId, text, notifyAll);
|
|
8155
|
+
}
|
|
8156
|
+
|
|
7565
8157
|
// src/index.ts
|
|
7566
8158
|
var require2 = createRequire(import.meta.url);
|
|
7567
8159
|
var { version } = require2("../package.json");
|
|
@@ -8187,6 +8779,78 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
8187
8779
|
}
|
|
8188
8780
|
})
|
|
8189
8781
|
);
|
|
8782
|
+
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(
|
|
8783
|
+
wrapAction(async (listId, opts) => {
|
|
8784
|
+
const config = loadConfig(getProfileName());
|
|
8785
|
+
const result = await deleteListCommand(config, listId, opts);
|
|
8786
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
8787
|
+
console.log(JSON.stringify(result, null, 2));
|
|
8788
|
+
} else {
|
|
8789
|
+
console.log(`Deleted list ${result.listId}`);
|
|
8790
|
+
}
|
|
8791
|
+
})
|
|
8792
|
+
);
|
|
8793
|
+
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(
|
|
8794
|
+
wrapAction(async (folderId, opts) => {
|
|
8795
|
+
const config = loadConfig(getProfileName());
|
|
8796
|
+
const result = await deleteFolderCommand(config, folderId, opts);
|
|
8797
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
8798
|
+
console.log(JSON.stringify(result, null, 2));
|
|
8799
|
+
} else {
|
|
8800
|
+
console.log(`Deleted folder ${result.folderId}`);
|
|
8801
|
+
}
|
|
8802
|
+
})
|
|
8803
|
+
);
|
|
8804
|
+
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(
|
|
8805
|
+
wrapAction(async (spaceId, opts) => {
|
|
8806
|
+
const config = loadConfig(getProfileName());
|
|
8807
|
+
const result = await deleteSpaceCommand(config, spaceId, opts);
|
|
8808
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
8809
|
+
console.log(JSON.stringify(result, null, 2));
|
|
8810
|
+
} else {
|
|
8811
|
+
console.log(`Deleted space ${result.spaceId}`);
|
|
8812
|
+
}
|
|
8813
|
+
})
|
|
8814
|
+
);
|
|
8815
|
+
program.command("attachments <taskId>").description("List attachments on a task").option("--json", "Force JSON output even in terminal").action(
|
|
8816
|
+
wrapAction(async (taskId, opts) => {
|
|
8817
|
+
const config = loadConfig(getProfileName());
|
|
8818
|
+
const attachments = await listTaskAttachments(config, taskId);
|
|
8819
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
8820
|
+
console.log(JSON.stringify(attachments, null, 2));
|
|
8821
|
+
} else if (isTTY()) {
|
|
8822
|
+
console.log(formatAttachmentsTable(attachments));
|
|
8823
|
+
} else {
|
|
8824
|
+
console.log(formatAttachmentsMarkdown(attachments));
|
|
8825
|
+
}
|
|
8826
|
+
})
|
|
8827
|
+
);
|
|
8828
|
+
program.command("task-members <taskId>").description("List members with access to a task").option("--json", "Force JSON output even in terminal").action(
|
|
8829
|
+
wrapAction(async (taskId, opts) => {
|
|
8830
|
+
const config = loadConfig(getProfileName());
|
|
8831
|
+
const members = await listTaskMembers(config, taskId);
|
|
8832
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
8833
|
+
console.log(JSON.stringify(members, null, 2));
|
|
8834
|
+
} else if (isTTY()) {
|
|
8835
|
+
console.log(formatTaskMembers(members));
|
|
8836
|
+
} else {
|
|
8837
|
+
console.log(formatTaskMembersMarkdown(members));
|
|
8838
|
+
}
|
|
8839
|
+
})
|
|
8840
|
+
);
|
|
8841
|
+
program.command("plan").description("Show workspace plan").option("--json", "Force JSON output even in terminal").action(
|
|
8842
|
+
wrapAction(async (opts) => {
|
|
8843
|
+
const config = loadConfig(getProfileName());
|
|
8844
|
+
const plan = await getWorkspacePlanCommand(config);
|
|
8845
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
8846
|
+
console.log(JSON.stringify(plan, null, 2));
|
|
8847
|
+
} else if (isTTY()) {
|
|
8848
|
+
console.log(formatPlan(plan));
|
|
8849
|
+
} else {
|
|
8850
|
+
console.log(formatPlanMarkdown(plan));
|
|
8851
|
+
}
|
|
8852
|
+
})
|
|
8853
|
+
);
|
|
8190
8854
|
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
8855
|
wrapAction(
|
|
8192
8856
|
async (taskId, opts) => {
|
|
@@ -9575,6 +10239,140 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
9575
10239
|
}
|
|
9576
10240
|
})
|
|
9577
10241
|
);
|
|
10242
|
+
program.command("merge <sourceTaskId> <intoTaskId>").description("Merge a task into another (source becomes subtask of target)").option("--confirm", "Skip confirmation prompt (required in non-interactive mode)").option("--json", "Force JSON output even in terminal").action(
|
|
10243
|
+
wrapAction(
|
|
10244
|
+
async (sourceTaskId, intoTaskId, opts) => {
|
|
10245
|
+
const config = loadConfig(getProfileName());
|
|
10246
|
+
const result = await mergeCommand(config, sourceTaskId, intoTaskId, opts);
|
|
10247
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
10248
|
+
console.log(JSON.stringify(result, null, 2));
|
|
10249
|
+
} else {
|
|
10250
|
+
console.log(`Merged task ${result.sourceTaskId} into ${result.intoTaskId}`);
|
|
10251
|
+
}
|
|
10252
|
+
}
|
|
10253
|
+
)
|
|
10254
|
+
);
|
|
10255
|
+
timeCmd.command("estimate-by-user <taskId> <userId> <duration>").description(
|
|
10256
|
+
'Set per-user time estimate (e.g. "2h", "30m"). Use --replace to overwrite all estimates.'
|
|
10257
|
+
).option("--replace", "Replace all estimates (PUT) instead of updating (PATCH)").option("--json", "Force JSON output even in terminal").action(
|
|
10258
|
+
wrapAction(
|
|
10259
|
+
async (taskId, userId, duration, opts) => {
|
|
10260
|
+
const config = loadConfig(getProfileName());
|
|
10261
|
+
const result = await timeEstimateByUserCommand(config, taskId, userId, duration, opts);
|
|
10262
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
10263
|
+
console.log(JSON.stringify(result, null, 2));
|
|
10264
|
+
} else {
|
|
10265
|
+
console.log(
|
|
10266
|
+
`${opts.replace ? "Replaced" : "Updated"} time estimate for user ${userId} on task ${taskId}`
|
|
10267
|
+
);
|
|
10268
|
+
}
|
|
10269
|
+
}
|
|
10270
|
+
)
|
|
10271
|
+
);
|
|
10272
|
+
program.command("shared").description("Show shared spaces, folders, and lists").option("--json", "Force JSON output even in terminal").action(
|
|
10273
|
+
wrapAction(async (opts) => {
|
|
10274
|
+
const config = loadConfig(getProfileName());
|
|
10275
|
+
const hierarchy = await fetchSharedHierarchy(config);
|
|
10276
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
10277
|
+
console.log(JSON.stringify(hierarchy, null, 2));
|
|
10278
|
+
} else if (isTTY()) {
|
|
10279
|
+
console.log(formatSharedHierarchy(hierarchy));
|
|
10280
|
+
} else {
|
|
10281
|
+
console.log(formatSharedHierarchyMarkdown(hierarchy));
|
|
10282
|
+
}
|
|
10283
|
+
})
|
|
10284
|
+
);
|
|
10285
|
+
program.command("list-comments <listId>").description("List comments on a list").option("--json", "Force JSON output even in terminal").action(
|
|
10286
|
+
wrapAction(async (listId, opts) => {
|
|
10287
|
+
const config = loadConfig(getProfileName());
|
|
10288
|
+
const comments = await fetchListComments(config, listId);
|
|
10289
|
+
printComments(comments, opts.json ?? false);
|
|
10290
|
+
})
|
|
10291
|
+
);
|
|
10292
|
+
program.command("list-comment <listId>").description("Post a comment on a list").requiredOption("-m, --message <text>", "Comment text").option("--notify-all", "Notify all assignees").option("--json", "Force JSON output even in terminal").action(
|
|
10293
|
+
wrapAction(
|
|
10294
|
+
async (listId, opts) => {
|
|
10295
|
+
const config = loadConfig(getProfileName());
|
|
10296
|
+
const result = await postListCommentCommand(config, listId, opts.message, opts.notifyAll);
|
|
10297
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
10298
|
+
console.log(JSON.stringify(result, null, 2));
|
|
10299
|
+
} else {
|
|
10300
|
+
console.log(formatCommentConfirmation(result.id));
|
|
10301
|
+
}
|
|
10302
|
+
}
|
|
10303
|
+
)
|
|
10304
|
+
);
|
|
10305
|
+
program.command("view-comments <viewId>").description("List comments on a view").option("--json", "Force JSON output even in terminal").action(
|
|
10306
|
+
wrapAction(async (viewId, opts) => {
|
|
10307
|
+
const config = loadConfig(getProfileName());
|
|
10308
|
+
const comments = await fetchViewComments(config, viewId);
|
|
10309
|
+
printComments(comments, opts.json ?? false);
|
|
10310
|
+
})
|
|
10311
|
+
);
|
|
10312
|
+
program.command("view-comment <viewId>").description("Post a comment on a view").requiredOption("-m, --message <text>", "Comment text").option("--notify-all", "Notify all assignees").option("--json", "Force JSON output even in terminal").action(
|
|
10313
|
+
wrapAction(
|
|
10314
|
+
async (viewId, opts) => {
|
|
10315
|
+
const config = loadConfig(getProfileName());
|
|
10316
|
+
const result = await postViewCommentCommand(config, viewId, opts.message, opts.notifyAll);
|
|
10317
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
10318
|
+
console.log(JSON.stringify(result, null, 2));
|
|
10319
|
+
} else {
|
|
10320
|
+
console.log(formatCommentConfirmation(result.id));
|
|
10321
|
+
}
|
|
10322
|
+
}
|
|
10323
|
+
)
|
|
10324
|
+
);
|
|
10325
|
+
const webhookCmd = program.command("webhook").description("Manage webhooks");
|
|
10326
|
+
webhookCmd.command("list").description("List webhooks in your workspace").option("--json", "Force JSON output even in terminal").action(
|
|
10327
|
+
wrapAction(async (opts) => {
|
|
10328
|
+
const config = loadConfig(getProfileName());
|
|
10329
|
+
const webhooks = await fetchWebhooks(config);
|
|
10330
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
10331
|
+
console.log(JSON.stringify(webhooks, null, 2));
|
|
10332
|
+
} else if (isTTY()) {
|
|
10333
|
+
console.log(formatWebhooks(webhooks));
|
|
10334
|
+
} else {
|
|
10335
|
+
console.log(formatWebhooksMarkdown(webhooks));
|
|
10336
|
+
}
|
|
10337
|
+
})
|
|
10338
|
+
);
|
|
10339
|
+
webhookCmd.command("create").description("Create a webhook").requiredOption("--url <url>", "Webhook endpoint URL").requiredOption("--events <events>", "Comma-separated event names").option("--space <id>", "Scope to a space").option("--folder <id>", "Scope to a folder").option("--list <id>", "Scope to a list").option("--task <id>", "Scope to a task").option("--json", "Force JSON output even in terminal").action(
|
|
10340
|
+
wrapAction(
|
|
10341
|
+
async (opts) => {
|
|
10342
|
+
const config = loadConfig(getProfileName());
|
|
10343
|
+
const result = await createWebhookCommand(config, opts);
|
|
10344
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
10345
|
+
console.log(JSON.stringify(result, null, 2));
|
|
10346
|
+
} else {
|
|
10347
|
+
console.log(`Created webhook ${result.id} \u2192 ${result.endpoint}`);
|
|
10348
|
+
}
|
|
10349
|
+
}
|
|
10350
|
+
)
|
|
10351
|
+
);
|
|
10352
|
+
webhookCmd.command("update <webhookId>").description("Update a webhook").option("--url <url>", "New endpoint URL").option("--events <events>", "New comma-separated event names").option("--status <status>", "New status (active or inactive)").option("--json", "Force JSON output even in terminal").action(
|
|
10353
|
+
wrapAction(
|
|
10354
|
+
async (webhookId, opts) => {
|
|
10355
|
+
const config = loadConfig(getProfileName());
|
|
10356
|
+
const result = await updateWebhookCommand(config, webhookId, opts);
|
|
10357
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
10358
|
+
console.log(JSON.stringify(result, null, 2));
|
|
10359
|
+
} else {
|
|
10360
|
+
console.log(`Updated webhook ${result.id}`);
|
|
10361
|
+
}
|
|
10362
|
+
}
|
|
10363
|
+
)
|
|
10364
|
+
);
|
|
10365
|
+
webhookCmd.command("delete <webhookId>").description("Delete a webhook (requires confirmation)").option("--confirm", "Skip confirmation prompt (required in non-interactive mode)").option("--json", "Force JSON output even in terminal").action(
|
|
10366
|
+
wrapAction(async (webhookId, opts) => {
|
|
10367
|
+
const config = loadConfig(getProfileName());
|
|
10368
|
+
const result = await deleteWebhookCommand(config, webhookId, opts);
|
|
10369
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
10370
|
+
console.log(JSON.stringify(result, null, 2));
|
|
10371
|
+
} else {
|
|
10372
|
+
console.log(`Deleted webhook ${result.webhookId}`);
|
|
10373
|
+
}
|
|
10374
|
+
})
|
|
10375
|
+
);
|
|
9578
10376
|
program.command("completion <shell>").description("Output shell completion script (bash, zsh, fish)").action(
|
|
9579
10377
|
wrapAction(async (shell) => {
|
|
9580
10378
|
const script = generateCompletion(shell, programName);
|