@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.
@@ -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.1",
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(["text", "number", "drop_down", "checkbox", "date", "url", "email"]);
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 (!text.trim()) throw new Error("Comment text cannot be empty");
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) => `- ${t.name}`).join("\n");
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
- return `- **${g.name}** (${g.id}) - ${pct}%${owner}`;
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 result = await updateTask(config, taskId, payload);
5488
- if (opts.field?.length) {
5489
- if (opts.field.length % 2 !== 0) {
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.length; i += 2) {
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").requiredOption("-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(
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());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@krodak/clickup-cli",
3
- "version": "1.14.1",
3
+ "version": "1.14.2",
4
4
  "description": "ClickUp CLI for AI agents and humans",
5
5
  "type": "module",
6
6
  "license": "MIT",