@krodak/clickup-cli 0.19.0 → 0.20.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.
@@ -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 cu/cup command",
4
- "version": "0.19.0",
4
+ "version": "0.20.0",
5
5
  "author": {
6
6
  "name": "Krzysztof Rodak"
7
7
  },
package/dist/index.js CHANGED
@@ -106,10 +106,12 @@ var ClickUpClient = class {
106
106
  body: JSON.stringify(options)
107
107
  });
108
108
  }
109
- async postComment(taskId, commentText) {
109
+ async postComment(taskId, commentText, notifyAll) {
110
+ const body = { comment_text: commentText };
111
+ if (notifyAll) body.notify_all = true;
110
112
  return this.request(this.taskPath(taskId, "/comment"), {
111
113
  method: "POST",
112
- body: JSON.stringify({ comment_text: commentText })
114
+ body: JSON.stringify(body)
113
115
  });
114
116
  }
115
117
  async getTaskComments(taskId) {
@@ -235,10 +237,12 @@ var ClickUpClient = class {
235
237
  const data = await this.request(`/comment/${commentId}/reply`);
236
238
  return data.comments ?? [];
237
239
  }
238
- async createThreadedComment(commentId, text) {
240
+ async createThreadedComment(commentId, text, notifyAll) {
241
+ const body = { comment_text: text };
242
+ if (notifyAll) body.notify_all = true;
239
243
  await this.request(`/comment/${commentId}/reply`, {
240
244
  method: "POST",
241
- body: JSON.stringify({ comment_text: text })
245
+ body: JSON.stringify(body)
242
246
  });
243
247
  }
244
248
  async addTaskLink(taskId, linksTo) {
@@ -617,6 +621,20 @@ function formatTaskDetailMarkdown(task) {
617
621
  lines.push(`- [${att.title}](${att.url})`);
618
622
  }
619
623
  }
624
+ if (task.dependencies?.length) {
625
+ lines.push("", "## Dependencies", "");
626
+ for (const dep of task.dependencies) {
627
+ const direction = dep.depends_on === task.id ? "blocks" : "depends on";
628
+ const otherId = dep.depends_on === task.id ? dep.task_id : dep.depends_on;
629
+ lines.push(`- ${direction} ${otherId}`);
630
+ }
631
+ }
632
+ if (task.linked_tasks?.length) {
633
+ lines.push("", "## Linked Tasks", "");
634
+ for (const lt of task.linked_tasks) {
635
+ lines.push(`- ${lt.task_id}`);
636
+ }
637
+ }
620
638
  return lines.join("\n");
621
639
  }
622
640
  function formatUpdateConfirmation(id, name) {
@@ -770,6 +788,22 @@ function formatTaskDetail(task) {
770
788
  lines.push(` ${att.title} ${chalk2.dim(att.url)}`);
771
789
  }
772
790
  }
791
+ if (task.dependencies?.length) {
792
+ lines.push("");
793
+ lines.push(chalk2.bold("Dependencies"));
794
+ for (const dep of task.dependencies) {
795
+ const direction = dep.depends_on === task.id ? "blocks" : "depends on";
796
+ const otherId = dep.depends_on === task.id ? dep.task_id : dep.depends_on;
797
+ lines.push(` ${direction} ${chalk2.dim(otherId)}`);
798
+ }
799
+ }
800
+ if (task.linked_tasks?.length) {
801
+ lines.push("");
802
+ lines.push(chalk2.bold("Linked Tasks"));
803
+ for (const lt of task.linked_tasks) {
804
+ lines.push(` ${chalk2.dim(lt.task_id)}`);
805
+ }
806
+ }
773
807
  if (task.text_content?.trim()) {
774
808
  lines.push("");
775
809
  lines.push(descriptionPreview(task.text_content));
@@ -1337,10 +1371,10 @@ async function fetchSubtasks(config, taskId, options = {}) {
1337
1371
  }
1338
1372
 
1339
1373
  // src/commands/comment.ts
1340
- async function postComment(config, taskId, text) {
1374
+ async function postComment(config, taskId, text, notifyAll) {
1341
1375
  if (!text.trim()) throw new Error("Comment text cannot be empty");
1342
1376
  const client = new ClickUpClient(config);
1343
- return client.postComment(taskId, text);
1377
+ return client.postComment(taskId, text, notifyAll);
1344
1378
  }
1345
1379
 
1346
1380
  // src/commands/comments.ts
@@ -1948,7 +1982,7 @@ function bashCompletion(name) {
1948
1982
  COMPREPLY=($(compgen -W "--status --name --include-closed --json" -- "$cur"))
1949
1983
  ;;
1950
1984
  comment)
1951
- COMPREPLY=($(compgen -W "-m --message --json" -- "$cur"))
1985
+ COMPREPLY=($(compgen -W "-m --message --notify-all --json" -- "$cur"))
1952
1986
  ;;
1953
1987
  comments)
1954
1988
  COMPREPLY=($(compgen -W "--json" -- "$cur"))
@@ -2021,7 +2055,7 @@ function bashCompletion(name) {
2021
2055
  COMPREPLY=($(compgen -W "--json" -- "$cur"))
2022
2056
  ;;
2023
2057
  reply)
2024
- COMPREPLY=($(compgen -W "-m --message --json" -- "$cur"))
2058
+ COMPREPLY=($(compgen -W "-m --message --notify-all --json" -- "$cur"))
2025
2059
  ;;
2026
2060
  link)
2027
2061
  COMPREPLY=($(compgen -W "--remove --json" -- "$cur"))
@@ -2172,6 +2206,7 @@ _${name}() {
2172
2206
  _arguments \\
2173
2207
  '1:task_id:' \\
2174
2208
  '(-m --message)'{-m,--message}'[Comment text]:text:' \\
2209
+ '--notify-all[Notify all assignees]' \\
2175
2210
  '--json[Force JSON output]'
2176
2211
  ;;
2177
2212
  comments)
@@ -2393,6 +2428,7 @@ _${name}() {
2393
2428
  _arguments \\
2394
2429
  '1:comment_id:' \\
2395
2430
  '(-m --message)'{-m,--message}'[Reply text]:text:' \\
2431
+ '--notify-all[Notify all assignees]' \\
2396
2432
  '--json[Force JSON output]'
2397
2433
  ;;
2398
2434
  link)
@@ -2534,6 +2570,7 @@ complete -c ${name} -n '__fish_seen_subcommand_from subtasks' -l include-closed
2534
2570
  complete -c ${name} -n '__fish_seen_subcommand_from subtasks' -l json -d 'Force JSON output'
2535
2571
 
2536
2572
  complete -c ${name} -n '__fish_seen_subcommand_from comment' -s m -l message -d 'Comment text'
2573
+ complete -c ${name} -n '__fish_seen_subcommand_from comment' -l notify-all -d 'Notify all assignees'
2537
2574
  complete -c ${name} -n '__fish_seen_subcommand_from comment' -l json -d 'Force JSON output'
2538
2575
 
2539
2576
  complete -c ${name} -n '__fish_seen_subcommand_from comments' -l json -d 'Force JSON output'
@@ -2619,6 +2656,7 @@ complete -c ${name} -n '__fish_seen_subcommand_from comment-delete' -l json -d '
2619
2656
  complete -c ${name} -n '__fish_seen_subcommand_from replies' -l json -d 'Force JSON output'
2620
2657
 
2621
2658
  complete -c ${name} -n '__fish_seen_subcommand_from reply' -s m -l message -d 'Reply text'
2659
+ complete -c ${name} -n '__fish_seen_subcommand_from reply' -l notify-all -d 'Notify all assignees'
2622
2660
  complete -c ${name} -n '__fish_seen_subcommand_from reply' -l json -d 'Force JSON output'
2623
2661
 
2624
2662
  complete -c ${name} -n '__fish_seen_subcommand_from link' -l remove -d 'Remove the link'
@@ -2951,10 +2989,10 @@ async function getReplies(config, commentId) {
2951
2989
  const client = new ClickUpClient(config);
2952
2990
  return client.getThreadedComments(commentId);
2953
2991
  }
2954
- async function createReply(config, commentId, text) {
2992
+ async function createReply(config, commentId, text, notifyAll) {
2955
2993
  if (!text.trim()) throw new Error("Reply text cannot be empty");
2956
2994
  const client = new ClickUpClient(config);
2957
- await client.createThreadedComment(commentId, text);
2995
+ await client.createThreadedComment(commentId, text, notifyAll);
2958
2996
  }
2959
2997
  function formatReplies(replies) {
2960
2998
  if (replies.length === 0) return "No replies";
@@ -3178,16 +3216,18 @@ program.command("subtasks <taskId>").description("List subtasks of a task or ini
3178
3216
  }
3179
3217
  )
3180
3218
  );
3181
- program.command("comment <taskId>").description("Post a comment on a task").requiredOption("-m, --message <text>", "Comment text").option("--json", "Force JSON output even in terminal").action(
3182
- wrapAction(async (taskId, opts) => {
3183
- const config = loadConfig();
3184
- const result = await postComment(config, taskId, opts.message);
3185
- if (shouldOutputJson(opts.json ?? false)) {
3186
- console.log(JSON.stringify(result, null, 2));
3187
- } else {
3188
- console.log(formatCommentConfirmation(result.id));
3219
+ program.command("comment <taskId>").description("Post a comment on a task").requiredOption("-m, --message <text>", "Comment text").option("--notify-all", "Notify all assignees").option("--json", "Force JSON output even in terminal").action(
3220
+ wrapAction(
3221
+ async (taskId, opts) => {
3222
+ const config = loadConfig();
3223
+ const result = await postComment(config, taskId, opts.message, opts.notifyAll);
3224
+ if (shouldOutputJson(opts.json ?? false)) {
3225
+ console.log(JSON.stringify(result, null, 2));
3226
+ } else {
3227
+ console.log(formatCommentConfirmation(result.id));
3228
+ }
3189
3229
  }
3190
- })
3230
+ )
3191
3231
  );
3192
3232
  program.command("comments <taskId>").description("List comments on a task").option("--json", "Force JSON output even in terminal").action(
3193
3233
  wrapAction(async (taskId, opts) => {
@@ -3234,16 +3274,18 @@ program.command("replies <commentId>").description("List threaded replies on a c
3234
3274
  }
3235
3275
  })
3236
3276
  );
3237
- program.command("reply <commentId>").description("Reply to a comment").requiredOption("-m, --message <text>", "Reply text").option("--json", "Force JSON output even in terminal").action(
3238
- wrapAction(async (commentId, opts) => {
3239
- const config = loadConfig();
3240
- await createReply(config, commentId, opts.message);
3241
- if (shouldOutputJson(opts.json ?? false)) {
3242
- console.log(JSON.stringify({ success: true, commentId }, null, 2));
3243
- } else {
3244
- console.log(`Replied to comment ${commentId}`);
3277
+ program.command("reply <commentId>").description("Reply to a comment").requiredOption("-m, --message <text>", "Reply text").option("--notify-all", "Notify all assignees").option("--json", "Force JSON output even in terminal").action(
3278
+ wrapAction(
3279
+ async (commentId, opts) => {
3280
+ const config = loadConfig();
3281
+ await createReply(config, commentId, opts.message, opts.notifyAll);
3282
+ if (shouldOutputJson(opts.json ?? false)) {
3283
+ console.log(JSON.stringify({ success: true, commentId }, null, 2));
3284
+ } else {
3285
+ console.log(`Replied to comment ${commentId}`);
3286
+ }
3245
3287
  }
3246
- })
3288
+ )
3247
3289
  );
3248
3290
  program.command("activity <taskId>").description("Show task details and comments combined").option("--json", "Force JSON output even in terminal").action(
3249
3291
  wrapAction(async (taskId, opts) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@krodak/clickup-cli",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "description": "ClickUp CLI for AI agents and humans",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -63,7 +63,7 @@ All commands support `--help` for full flag details.
63
63
  | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
64
64
  | `cu update <id> [-n name] [-d desc] [-s status] [--priority p] [--due-date d] [--time-estimate t] [--assignee id\|me] [--parent id] [--json]` | Update task fields (desc supports markdown) |
65
65
  | `cu create -n name [-l listId] [-p parentId] [-d desc] [-s status] [--priority p] [--due-date d] [--time-estimate t] [--assignee id\|me] [--tags t] [--custom-item-id n] [--json]` | Create task (desc supports markdown) |
66
- | `cu comment <id> -m text [--json]` | Post comment on task |
66
+ | `cu comment <id> -m text [--notify-all] [--json]` | Post comment on task |
67
67
  | `cu comment-edit <commentId> -m text [--resolved] [--unresolved] [--json]` | Edit an existing comment |
68
68
  | `cu assign <id> [--to userId\|me] [--remove userId\|me] [--json]` | Assign/unassign users |
69
69
  | `cu depend <id> [--on taskId] [--blocks taskId] [--remove] [--json]` | Add/remove task dependencies |
@@ -79,7 +79,7 @@ All commands support `--help` for full flag details.
79
79
  | `cu checklist delete-item <checklistId> <itemId> [--json]` | Delete a checklist item |
80
80
  | `cu comment-delete <commentId> [--json]` | Delete a comment |
81
81
  | `cu replies <commentId> [--json]` | List threaded replies on a comment |
82
- | `cu reply <commentId> -m text [--json]` | Reply to a comment |
82
+ | `cu reply <commentId> -m text [--notify-all] [--json]` | Reply to a comment |
83
83
  | `cu link <taskId> <linksTo> [--remove] [--json]` | Add or remove link between tasks |
84
84
  | `cu attach <taskId> <filePath> [--json]` | Upload file attachment to a task |
85
85
  | `cu time start <taskId> [-d desc] [--json]` | Start tracking time on a task |
@@ -128,7 +128,7 @@ All commands support `--help` for full flag details.
128
128
  | `cu link` + custom IDs | Both IDs must be the same type (both custom or both native). Mixing may not work |
129
129
  | `cu link` | Link/unlink tasks (different from dependencies) |
130
130
  | `cu attach` | Upload files to tasks. Attachments shown in `cu task` detail view |
131
- | `cu task` | Shows custom fields, checklists, and attachments in detail view |
131
+ | `cu task` | Shows custom fields, checklists, attachments, dependencies, and linked tasks in detail view |
132
132
  | `cu lists` | Discovers list IDs needed for `--list` and `cu create -l` |
133
133
  | Errors | stderr with exit code 1 |
134
134
  | Parsing | Strict - excess/unknown arguments rejected |