@krodak/clickup-cli 1.14.1 → 1.14.2
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/dist/index.js +73 -14
- package/package.json +1 -1
|
@@ -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.14.
|
|
4
|
+
"version": "1.14.2",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Krzysztof Rodak"
|
|
7
7
|
},
|
package/dist/index.js
CHANGED
|
@@ -1225,7 +1225,7 @@ function formatTasksMarkdown(tasks) {
|
|
|
1225
1225
|
}
|
|
1226
1226
|
function formatCommentsMarkdown(comments) {
|
|
1227
1227
|
if (comments.length === 0) return "No comments found.";
|
|
1228
|
-
return comments.map((c) => `**${c.user}** (${c.date})
|
|
1228
|
+
return comments.map((c) => `**${c.user}** (${formatDateISO(c.date)})
|
|
1229
1229
|
|
|
1230
1230
|
${c.text}`).join("\n\n---\n\n");
|
|
1231
1231
|
}
|
|
@@ -1279,6 +1279,10 @@ function formatTaskDetailMarkdown(task) {
|
|
|
1279
1279
|
task.time_spent != null && task.time_spent > 0 ? formatDuration(task.time_spent) : void 0
|
|
1280
1280
|
],
|
|
1281
1281
|
["Tags", task.tags && task.tags.length > 0 ? task.tags.map((t) => t.name).join(", ") : void 0],
|
|
1282
|
+
[
|
|
1283
|
+
"Lists",
|
|
1284
|
+
task.locations && task.locations.length > 0 ? task.locations.map((l) => l.name).join(", ") : void 0
|
|
1285
|
+
],
|
|
1282
1286
|
["Created", task.date_created ? formatDateISO(task.date_created) : void 0],
|
|
1283
1287
|
["Updated", task.date_updated ? formatDateISO(task.date_updated) : void 0]
|
|
1284
1288
|
];
|
|
@@ -1420,6 +1424,7 @@ function formatTaskDetail(task) {
|
|
|
1420
1424
|
["Estimate", task.time_estimate ? formatDuration(task.time_estimate) : void 0],
|
|
1421
1425
|
["Tracked", task.time_spent ? formatDuration(task.time_spent) : void 0],
|
|
1422
1426
|
["Tags", task.tags?.length ? task.tags.map((t) => t.name).join(", ") : void 0],
|
|
1427
|
+
["Lists", task.locations?.length ? task.locations.map((l) => l.name).join(", ") : void 0],
|
|
1423
1428
|
["Parent", task.parent || void 0],
|
|
1424
1429
|
["URL", task.url]
|
|
1425
1430
|
];
|
|
@@ -3771,6 +3776,7 @@ ${renderZshTopLevelCommands(name)}
|
|
|
3771
3776
|
'1:query:' \\
|
|
3772
3777
|
'--status[Filter by status]:status:(open "in progress" "in review" done closed)' \\
|
|
3773
3778
|
'--include-closed[Include done/closed tasks in search]' \\
|
|
3779
|
+
'--all[Search all workspace tasks, not just mine]' \\
|
|
3774
3780
|
'--json[Force JSON output]'
|
|
3775
3781
|
;;
|
|
3776
3782
|
summary)
|
|
@@ -3781,6 +3787,7 @@ ${renderZshTopLevelCommands(name)}
|
|
|
3781
3787
|
overdue)
|
|
3782
3788
|
_arguments \\
|
|
3783
3789
|
'--include-closed[Include done/closed overdue tasks]' \\
|
|
3790
|
+
'--all[Check all workspace tasks, not just mine]' \\
|
|
3784
3791
|
'--json[Force JSON output]'
|
|
3785
3792
|
;;
|
|
3786
3793
|
assign)
|
|
@@ -4458,7 +4465,18 @@ async function moveTask(config, taskId, opts) {
|
|
|
4458
4465
|
}
|
|
4459
4466
|
|
|
4460
4467
|
// src/commands/field.ts
|
|
4461
|
-
var SUPPORTED_TYPES = /* @__PURE__ */ new Set([
|
|
4468
|
+
var SUPPORTED_TYPES = /* @__PURE__ */ new Set([
|
|
4469
|
+
"text",
|
|
4470
|
+
"short_text",
|
|
4471
|
+
"number",
|
|
4472
|
+
"currency",
|
|
4473
|
+
"phone",
|
|
4474
|
+
"drop_down",
|
|
4475
|
+
"checkbox",
|
|
4476
|
+
"date",
|
|
4477
|
+
"url",
|
|
4478
|
+
"email"
|
|
4479
|
+
]);
|
|
4462
4480
|
function findFieldByName(fields, name) {
|
|
4463
4481
|
const lower = name.toLowerCase();
|
|
4464
4482
|
const match = fields.find((f) => f.name.toLowerCase() === lower);
|
|
@@ -4672,9 +4690,12 @@ function formatChecklistsMarkdown(checklists) {
|
|
|
4672
4690
|
|
|
4673
4691
|
// src/commands/comment-edit.ts
|
|
4674
4692
|
async function editComment(config, commentId, text, resolved) {
|
|
4675
|
-
if (
|
|
4693
|
+
if (text === void 0 && resolved === void 0) {
|
|
4694
|
+
throw new Error("Provide at least one of: --message, --resolved, --unresolved");
|
|
4695
|
+
}
|
|
4696
|
+
if (text !== void 0 && !text.trim()) throw new Error("Comment text cannot be empty");
|
|
4676
4697
|
const client = new ClickUpClient(config);
|
|
4677
|
-
await client.updateComment(commentId, text, resolved);
|
|
4698
|
+
await client.updateComment(commentId, text ?? "", resolved);
|
|
4678
4699
|
}
|
|
4679
4700
|
|
|
4680
4701
|
// src/commands/comment-delete.ts
|
|
@@ -4991,6 +5012,11 @@ function formatTimeEntriesMarkdown(entries) {
|
|
|
4991
5012
|
|
|
4992
5013
|
// src/commands/tags.ts
|
|
4993
5014
|
import chalk12 from "chalk";
|
|
5015
|
+
var TAG_COLUMNS = [
|
|
5016
|
+
{ key: "name", label: "Name", maxWidth: 40 },
|
|
5017
|
+
{ key: "fg", label: "FG", maxWidth: 10 },
|
|
5018
|
+
{ key: "bg", label: "BG", maxWidth: 10 }
|
|
5019
|
+
];
|
|
4994
5020
|
async function listSpaceTags(config, spaceId) {
|
|
4995
5021
|
const client = new ClickUpClient(config);
|
|
4996
5022
|
return client.getSpaceTags(spaceId);
|
|
@@ -5013,11 +5039,22 @@ async function updateSpaceTag(config, spaceId, tagName, updates) {
|
|
|
5013
5039
|
}
|
|
5014
5040
|
function formatTags(tags) {
|
|
5015
5041
|
if (tags.length === 0) return "No tags found";
|
|
5042
|
+
if (isTTY()) {
|
|
5043
|
+
const rows = tags.map((t) => ({
|
|
5044
|
+
name: t.tag_bg ? chalk12.bgHex(t.tag_bg).hex(t.tag_fg || "#ffffff")(` ${t.name} `) : chalk12.bold(t.name),
|
|
5045
|
+
fg: t.tag_fg || "",
|
|
5046
|
+
bg: t.tag_bg || ""
|
|
5047
|
+
}));
|
|
5048
|
+
return formatTable(rows, TAG_COLUMNS);
|
|
5049
|
+
}
|
|
5016
5050
|
return tags.map((t) => chalk12.bold(t.name)).join(", ");
|
|
5017
5051
|
}
|
|
5018
5052
|
function formatTagsMarkdown(tags) {
|
|
5019
5053
|
if (tags.length === 0) return "No tags found";
|
|
5020
|
-
return tags.map((t) =>
|
|
5054
|
+
return tags.map((t) => {
|
|
5055
|
+
const colors = t.tag_bg ? ` (bg: ${t.tag_bg}${t.tag_fg ? `, fg: ${t.tag_fg}` : ""})` : "";
|
|
5056
|
+
return `- ${t.name}${colors}`;
|
|
5057
|
+
}).join("\n");
|
|
5021
5058
|
}
|
|
5022
5059
|
|
|
5023
5060
|
// src/commands/members.ts
|
|
@@ -5047,6 +5084,7 @@ function formatMembersMarkdown(members) {
|
|
|
5047
5084
|
// src/commands/fields.ts
|
|
5048
5085
|
import chalk13 from "chalk";
|
|
5049
5086
|
var FIELD_COLUMNS = [
|
|
5087
|
+
{ key: "id", label: "ID", maxWidth: 20 },
|
|
5050
5088
|
{ key: "name", label: "Name", maxWidth: 30 },
|
|
5051
5089
|
{ key: "type", label: "Type", maxWidth: 15 },
|
|
5052
5090
|
{
|
|
@@ -5064,6 +5102,7 @@ async function listFields(config, listId) {
|
|
|
5064
5102
|
function formatFields(fields) {
|
|
5065
5103
|
if (fields.length === 0) return "No custom fields";
|
|
5066
5104
|
const rows = fields.map((f) => ({
|
|
5105
|
+
id: f.id,
|
|
5067
5106
|
name: f.name,
|
|
5068
5107
|
type: f.type,
|
|
5069
5108
|
required: f.required ? "yes" : "no",
|
|
@@ -5076,7 +5115,7 @@ function formatFieldsMarkdown(fields) {
|
|
|
5076
5115
|
return fields.map((f) => {
|
|
5077
5116
|
const options = f.type_config?.options?.map((o) => o.name).join(", ");
|
|
5078
5117
|
const optStr = options ? ` [${options}]` : "";
|
|
5079
|
-
return `- **${f.name}** (${f.type})${f.required ? " - required" : ""}${optStr}`;
|
|
5118
|
+
return `- **${f.name}** \`${f.id}\` (${f.type})${f.required ? " - required" : ""}${optStr}`;
|
|
5080
5119
|
}).join("\n");
|
|
5081
5120
|
}
|
|
5082
5121
|
|
|
@@ -5124,7 +5163,8 @@ var GOAL_COLUMNS = [
|
|
|
5124
5163
|
{ key: "id", label: "ID", maxWidth: 15 },
|
|
5125
5164
|
{ key: "name", label: "Name", maxWidth: 40 },
|
|
5126
5165
|
{ key: "progress", label: "Progress", maxWidth: 10, format: (v) => colorProgress(v) },
|
|
5127
|
-
{ key: "owner", label: "Owner", maxWidth: 20 }
|
|
5166
|
+
{ key: "owner", label: "Owner", maxWidth: 20 },
|
|
5167
|
+
{ key: "due_date", label: "Due", maxWidth: 12 }
|
|
5128
5168
|
];
|
|
5129
5169
|
var KEY_RESULT_COLUMNS = [
|
|
5130
5170
|
{ key: "id", label: "ID", maxWidth: 15 },
|
|
@@ -5173,7 +5213,8 @@ function formatGoals(goals) {
|
|
|
5173
5213
|
name: g.name,
|
|
5174
5214
|
id: g.id,
|
|
5175
5215
|
progress: `${Math.round(g.percent_completed * 100)}%`,
|
|
5176
|
-
owner: g.owner ? `@${g.owner.username}` : ""
|
|
5216
|
+
owner: g.owner ? `@${g.owner.username}` : "",
|
|
5217
|
+
due_date: g.due_date ? formatDateISO(g.due_date) : ""
|
|
5177
5218
|
}));
|
|
5178
5219
|
return formatTable(rows, GOAL_COLUMNS);
|
|
5179
5220
|
}
|
|
@@ -5182,7 +5223,8 @@ function formatGoalsMarkdown(goals) {
|
|
|
5182
5223
|
return goals.map((g) => {
|
|
5183
5224
|
const pct = Math.round(g.percent_completed * 100);
|
|
5184
5225
|
const owner = g.owner ? ` - @${g.owner.username}` : "";
|
|
5185
|
-
|
|
5226
|
+
const due = g.due_date ? ` - due ${formatDateISO(g.due_date)}` : "";
|
|
5227
|
+
return `- **${g.name}** (${g.id}) - ${pct}%${owner}${due}`;
|
|
5186
5228
|
}).join("\n");
|
|
5187
5229
|
}
|
|
5188
5230
|
function formatKeyResults(keyResults) {
|
|
@@ -5364,6 +5406,9 @@ var VALID_GROUP_BY_FIELDS2 = [
|
|
|
5364
5406
|
"sprint"
|
|
5365
5407
|
];
|
|
5366
5408
|
async function updateView(config, viewId, opts) {
|
|
5409
|
+
if (opts.name === void 0 && opts.groupBy === void 0) {
|
|
5410
|
+
throw new Error("Provide at least one of: --name, --group-by");
|
|
5411
|
+
}
|
|
5367
5412
|
if (opts.name !== void 0 && !opts.name.trim()) {
|
|
5368
5413
|
throw new Error("View name cannot be empty");
|
|
5369
5414
|
}
|
|
@@ -5484,14 +5529,28 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
5484
5529
|
opts.assignee = String(await resolveAssigneeId(client, "me"));
|
|
5485
5530
|
}
|
|
5486
5531
|
const payload = buildUpdatePayload(opts);
|
|
5487
|
-
const
|
|
5488
|
-
if (
|
|
5489
|
-
|
|
5532
|
+
const hasFields = (opts.field?.length ?? 0) > 0;
|
|
5533
|
+
if (!hasFields && Object.keys(payload).length === 0) {
|
|
5534
|
+
throw new Error(
|
|
5535
|
+
"Provide at least one of: --name, --description, --status, --priority, --due-date, --time-estimate, --assignee, --parent, --archive, --unarchive, --field"
|
|
5536
|
+
);
|
|
5537
|
+
}
|
|
5538
|
+
let result;
|
|
5539
|
+
if (Object.keys(payload).length > 0) {
|
|
5540
|
+
result = await updateTask(config, taskId, payload);
|
|
5541
|
+
}
|
|
5542
|
+
if (hasFields) {
|
|
5543
|
+
if ((opts.field?.length ?? 0) % 2 !== 0) {
|
|
5490
5544
|
throw new Error('--field requires pairs: --field "Name" value');
|
|
5491
5545
|
}
|
|
5492
|
-
for (let i = 0; i < opts.field
|
|
5546
|
+
for (let i = 0; i < (opts.field?.length ?? 0); i += 2) {
|
|
5493
5547
|
await setCustomField(config, taskId, { set: [opts.field[i], opts.field[i + 1]] });
|
|
5494
5548
|
}
|
|
5549
|
+
if (!result) {
|
|
5550
|
+
const client = new ClickUpClient(config);
|
|
5551
|
+
const task = await client.getTask(taskId);
|
|
5552
|
+
result = { id: task.id, name: task.name };
|
|
5553
|
+
}
|
|
5495
5554
|
}
|
|
5496
5555
|
if (shouldOutputJson(opts.json ?? false)) {
|
|
5497
5556
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -5567,7 +5626,7 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
5567
5626
|
printComments(comments, opts.json ?? false);
|
|
5568
5627
|
})
|
|
5569
5628
|
);
|
|
5570
|
-
program.command("comment-edit <commentId>").description("Edit an existing comment").
|
|
5629
|
+
program.command("comment-edit <commentId>").description("Edit an existing comment").option("-m, --message <text>", "New comment text").option("--resolved", "Mark comment as resolved").option("--unresolved", "Mark comment as unresolved").option("--json", "Force JSON output even in terminal").action(
|
|
5571
5630
|
wrapAction(
|
|
5572
5631
|
async (commentId, opts) => {
|
|
5573
5632
|
const config = loadConfig(getProfileName());
|