@krodak/clickup-cli 1.38.1 → 1.38.3

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.38.1",
4
+ "version": "1.38.3",
5
5
  "author": {
6
6
  "name": "Krzysztof Rodak"
7
7
  },
package/dist/index.js CHANGED
@@ -291,6 +291,24 @@ var ClickUpClient = class {
291
291
  async getTask(taskId) {
292
292
  return this.request(this.taskPath(taskId, "?include_markdown_description=true"));
293
293
  }
294
+ /**
295
+ * Resolve any accepted task-id form to a native ClickUp task id.
296
+ * - Task URLs are reduced to their id segment.
297
+ * - Workspace custom ids (e.g. PROD-811) are resolved to the native id via GET.
298
+ * - Native ids pass through without an API call.
299
+ *
300
+ * Use this for task ids that appear in request bodies, query params, or
301
+ * secondary path segments, where ClickUp's custom_task_ids handling
302
+ * (applied by taskPath to the primary path id) does not reach.
303
+ */
304
+ async resolveTaskId(input) {
305
+ const normalized = normalizeTaskId(input);
306
+ if (isCustomTaskId(normalized) && this.teamId) {
307
+ const task = await this.getTask(normalized);
308
+ return task.id;
309
+ }
310
+ return normalized;
311
+ }
294
312
  async getTimeInStatus(taskId) {
295
313
  return this.request(this.taskPath(taskId, "/time_in_status"));
296
314
  }
@@ -522,19 +540,21 @@ var ClickUpClient = class {
522
540
  });
523
541
  }
524
542
  async addDependency(taskId, opts) {
543
+ const primary = await this.resolveTaskId(taskId);
525
544
  const body = {};
526
- if (opts.dependsOn) body.depends_on = opts.dependsOn;
527
- if (opts.dependencyOf) body.dependency_of = opts.dependencyOf;
528
- await this.request(this.taskPath(taskId, "/dependency"), {
545
+ if (opts.dependsOn) body.depends_on = await this.resolveTaskId(opts.dependsOn);
546
+ if (opts.dependencyOf) body.dependency_of = await this.resolveTaskId(opts.dependencyOf);
547
+ await this.request(`/task/${primary}/dependency`, {
529
548
  method: "POST",
530
549
  body: JSON.stringify(body)
531
550
  });
532
551
  }
533
552
  async deleteDependency(taskId, opts) {
553
+ const primary = await this.resolveTaskId(taskId);
534
554
  const params = new URLSearchParams();
535
- if (opts.dependsOn) params.set("depends_on", opts.dependsOn);
536
- if (opts.dependencyOf) params.set("dependency_of", opts.dependencyOf);
537
- await this.request(this.taskPath(taskId, `/dependency?${params.toString()}`), {
555
+ if (opts.dependsOn) params.set("depends_on", await this.resolveTaskId(opts.dependsOn));
556
+ if (opts.dependencyOf) params.set("dependency_of", await this.resolveTaskId(opts.dependencyOf));
557
+ await this.request(`/task/${primary}/dependency?${params.toString()}`, {
538
558
  method: "DELETE"
539
559
  });
540
560
  }
@@ -562,16 +582,12 @@ var ClickUpClient = class {
562
582
  });
563
583
  }
564
584
  async addTaskLink(taskId, linksTo) {
565
- await this.request(
566
- this.taskPath(taskId, `/link/${normalizeTaskId(linksTo)}`),
567
- { method: "POST" }
568
- );
585
+ const [a, b] = await Promise.all([this.resolveTaskId(taskId), this.resolveTaskId(linksTo)]);
586
+ await this.request(`/task/${a}/link/${b}`, { method: "POST" });
569
587
  }
570
588
  async deleteTaskLink(taskId, linksTo) {
571
- await this.request(
572
- this.taskPath(taskId, `/link/${normalizeTaskId(linksTo)}`),
573
- { method: "DELETE" }
574
- );
589
+ const [a, b] = await Promise.all([this.resolveTaskId(taskId), this.resolveTaskId(linksTo)]);
590
+ await this.request(`/task/${a}/link/${b}`, { method: "DELETE" });
575
591
  }
576
592
  async getListCustomFields(listId) {
577
593
  const data = await this.request(`/list/${listId}/field`);
@@ -1012,7 +1028,7 @@ var ClickUpClient = class {
1012
1028
  content,
1013
1029
  content_format: "text/md"
1014
1030
  };
1015
- if (opts?.postTitle) body.post_data = { title: opts.postTitle };
1031
+ if (opts?.postTitle) body.title = opts.postTitle;
1016
1032
  return this.requestV3(this.chatChannelsPath(`/${channelId}/messages`), {
1017
1033
  method: "POST",
1018
1034
  body: JSON.stringify(body)
@@ -1062,9 +1078,11 @@ var ClickUpClient = class {
1062
1078
  );
1063
1079
  }
1064
1080
  async mergeTasks(taskId, mergeWithTaskIds) {
1065
- await this.request(this.taskPath(taskId, "/merge"), {
1081
+ const primary = await this.resolveTaskId(taskId);
1082
+ const mergeWith = await Promise.all(mergeWithTaskIds.map((id) => this.resolveTaskId(id)));
1083
+ await this.request(`/task/${primary}/merge`, {
1066
1084
  method: "POST",
1067
- body: JSON.stringify({ merge_with: mergeWithTaskIds.map(normalizeTaskId) })
1085
+ body: JSON.stringify({ merge_with: mergeWith })
1068
1086
  });
1069
1087
  }
1070
1088
  async updateTimeEstimatesByUser(taskId, estimates) {
@@ -2355,6 +2373,9 @@ async function updateTask(config, taskId, options, typeInput) {
2355
2373
  if (resolved.status !== void 0) {
2356
2374
  resolved.status = await resolveStatus(client, taskId, resolved.status);
2357
2375
  }
2376
+ if (typeof resolved.parent === "string") {
2377
+ resolved.parent = await client.resolveTaskId(resolved.parent);
2378
+ }
2358
2379
  if (resolved.custom_item_id === void 0 && typeInput !== void 0) {
2359
2380
  resolved.custom_item_id = await resolveTaskType2(client, config.teamId, typeInput);
2360
2381
  }
@@ -2367,9 +2388,15 @@ async function createTask(config, options) {
2367
2388
  if (!options.name.trim()) throw new Error("Task name cannot be empty");
2368
2389
  const client = new ClickUpClient(config);
2369
2390
  let listId = options.list;
2370
- if (!listId && options.parent) {
2371
- const parentTask = await client.getTask(options.parent);
2372
- listId = parentTask.list.id;
2391
+ let parentId = options.parent;
2392
+ if (options.parent) {
2393
+ if (!listId) {
2394
+ const parentTask = await client.getTask(options.parent);
2395
+ parentId = parentTask.id;
2396
+ listId = parentTask.list.id;
2397
+ } else {
2398
+ parentId = await client.resolveTaskId(options.parent);
2399
+ }
2373
2400
  }
2374
2401
  if (!listId) {
2375
2402
  throw new Error("Provide --list or --parent (list is auto-detected from parent task)");
@@ -2382,7 +2409,7 @@ async function createTask(config, options) {
2382
2409
  const payload = {
2383
2410
  name: options.name,
2384
2411
  ...options.description !== void 0 ? { markdown_content: options.description } : {},
2385
- ...options.parent !== void 0 ? { parent: options.parent } : {},
2412
+ ...parentId !== void 0 ? { parent: parentId } : {},
2386
2413
  ...options.status !== void 0 ? { status: options.status } : {}
2387
2414
  };
2388
2415
  if (options.priority !== void 0) {
@@ -8723,7 +8750,10 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
8723
8750
  ).option(
8724
8751
  "--remove-group-assignee <groupIds...>",
8725
8752
  "Remove group assignee (UUID or @handle, can repeat or comma-separated)"
8726
- ).option("--parent <taskId>", "Set parent task (makes this a subtask)").option("--archive", "Archive the task").option("--unarchive", "Unarchive the task").option("--type <type>", "Change task type (name or custom_item_id)").option("--field <nameAndValue...>", 'Set custom field: --field "Name" value').option("--json", "Force JSON output even in terminal").action(
8753
+ ).option(
8754
+ "--parent <taskId>",
8755
+ "Set parent task (makes this a subtask): native id, custom id, or task URL"
8756
+ ).option("--archive", "Archive the task").option("--unarchive", "Unarchive the task").option("--type <type>", "Change task type (name or custom_item_id)").option("--field <nameAndValue...>", 'Set custom field: --field "Name" value').option("--json", "Force JSON output even in terminal").action(
8727
8757
  wrapAction(
8728
8758
  async (taskId, opts) => {
8729
8759
  const config = loadConfig(getProfileName());
@@ -8783,7 +8813,10 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
8783
8813
  }
8784
8814
  )
8785
8815
  );
8786
- program.command("create").description("Create a new task").option("-l, --list <listId>", 'Target list ID or "sprint:current" for active sprint').requiredOption("-n, --name <name>", "Task name").option("-d, --description <text>", "Task description (markdown supported)").option("-p, --parent <taskId>", "Parent task ID (list auto-detected from parent)").option("-s, --status <status>", "Initial status").option("--priority <level>", "Priority: urgent, high, normal, low (or 1-4)").option(
8816
+ program.command("create").description("Create a new task").option("-l, --list <listId>", 'Target list ID or "sprint:current" for active sprint').requiredOption("-n, --name <name>", "Task name").option("-d, --description <text>", "Task description (markdown supported)").option(
8817
+ "-p, --parent <taskId>",
8818
+ "Parent task: native id, custom id (e.g. PROD-811), or task URL (list auto-detected)"
8819
+ ).option("-s, --status <status>", "Initial status").option("--priority <level>", "Priority: urgent, high, normal, low (or 1-4)").option(
8787
8820
  "--due-date <date>",
8788
8821
  "Due date (YYYY-MM-DD, YYYY-MM-DDTHH:MM[:SS], or full ISO 8601 with offset)"
8789
8822
  ).option(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@krodak/clickup-cli",
3
- "version": "1.38.1",
3
+ "version": "1.38.3",
4
4
  "description": "ClickUp CLI for AI agents and humans",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -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.38.1
6
+ # ClickUp CLI (`cup`) - skill version 1.38.3
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.38.1, update with `npm install -g @krodak/clickup-cli` and refresh this skill with `cup skill`.
10
+ > **Version check:** Run `cup --version`. If your installed version is older than 1.38.3, update with `npm install -g @krodak/clickup-cli` and refresh this skill with `cup skill`.
11
11
 
12
12
  ## Install & Configure
13
13