@krodak/clickup-cli 1.2.0 → 1.3.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 cup command",
4
- "version": "1.2.0",
4
+ "version": "1.3.0",
5
5
  "author": {
6
6
  "name": "Krzysztof Rodak"
7
7
  },
package/README.md CHANGED
@@ -210,7 +210,7 @@ Status: :white_check_mark: implemented | :construction: planned | :no_entry_sign
210
210
  | Feature | Command | Status |
211
211
  | ----------------------- | -------------------- | ------------------ |
212
212
  | Add/remove tag on task | `cup tag <id>` | :white_check_mark: |
213
- | List space tags | `cup tags <spaceId>` | :construction: |
213
+ | List space tags | `cup tags <spaceId>` | :white_check_mark: |
214
214
  | Create/delete space tag | | :construction: |
215
215
 
216
216
  ### Time Tracking
@@ -222,8 +222,8 @@ Status: :white_check_mark: implemented | :construction: planned | :no_entry_sign
222
222
  | Timer status | `cup time status` | :white_check_mark: |
223
223
  | Log time entry | `cup time log <id> <duration>` | :white_check_mark: |
224
224
  | List entries | `cup time list` | :white_check_mark: |
225
- | Update entry | `cup time update <id>` | :construction: |
226
- | Delete entry | `cup time delete <id>` | :construction: |
225
+ | Update entry | `cup time update <id>` | :white_check_mark: |
226
+ | Delete entry | `cup time delete <id>` | :white_check_mark: |
227
227
 
228
228
  ### Workspace
229
229
 
package/dist/index.js CHANGED
@@ -371,6 +371,17 @@ var ClickUpClient = class {
371
371
  }
372
372
  return entries;
373
373
  }
374
+ async updateTimeEntry(teamId, timeEntryId, updates) {
375
+ const data = await this.request(
376
+ `/team/${teamId}/time_entries/${timeEntryId}`,
377
+ { method: "PUT", body: JSON.stringify(updates) }
378
+ );
379
+ return data.data;
380
+ }
381
+ async getSpaceTags(spaceId) {
382
+ const data = await this.request(`/space/${spaceId}/tag`);
383
+ return data.tags ?? [];
384
+ }
374
385
  async deleteTimeEntry(teamId, timeEntryId) {
375
386
  await this.request(`/team/${teamId}/time_entries/${timeEntryId}`, {
376
387
  method: "DELETE"
@@ -2106,7 +2117,7 @@ function bashCompletion(name) {
2106
2117
  cword=$COMP_CWORD
2107
2118
  fi
2108
2119
 
2109
- local commands="init auth tasks task update create sprint sprints subtasks comment comment-edit comment-delete comments replies reply activity lists spaces inbox assigned open search summary overdue assign depend link attach move field delete tag checklist time docs doc doc-create doc-pages doc-page-create doc-page-edit folders config completion"
2120
+ local commands="init auth tasks task update create sprint sprints subtasks comment comment-edit comment-delete comments replies reply activity lists spaces inbox assigned open search summary overdue assign depend link attach move field delete tag tags checklist time docs doc doc-create doc-pages doc-page-create doc-page-edit folders config completion"
2110
2121
 
2111
2122
  if [[ $cword -eq 1 ]]; then
2112
2123
  COMPREPLY=($(compgen -W "$commands --help --version" -- "$cur"))
@@ -2239,6 +2250,9 @@ function bashCompletion(name) {
2239
2250
  doc-pages)
2240
2251
  COMPREPLY=($(compgen -W "--json" -- "$cur"))
2241
2252
  ;;
2253
+ tags)
2254
+ COMPREPLY=($(compgen -W "--json" -- "$cur"))
2255
+ ;;
2242
2256
  folders)
2243
2257
  COMPREPLY=($(compgen -W "--name --json" -- "$cur"))
2244
2258
  ;;
@@ -2317,6 +2331,7 @@ _${name}() {
2317
2331
  'doc-pages:List all pages in a doc with content'
2318
2332
  'doc-page-create:Create a page in a doc'
2319
2333
  'doc-page-edit:Edit a doc page'
2334
+ 'tags:List tags in a space'
2320
2335
  'folders:List folders in a space'
2321
2336
  'config:Manage CLI configuration'
2322
2337
  'completion:Output shell completion script'
@@ -2656,6 +2671,11 @@ _${name}() {
2656
2671
  '1:doc_id:' \\
2657
2672
  '--json[Force JSON output]'
2658
2673
  ;;
2674
+ tags)
2675
+ _arguments \\
2676
+ '1:space_id:' \\
2677
+ '--json[Force JSON output]'
2678
+ ;;
2659
2679
  folders)
2660
2680
  _arguments \\
2661
2681
  '1:space_id:' \\
@@ -2764,6 +2784,7 @@ complete -c ${name} -n __fish_use_subcommand -a doc-create -d 'Create a new doc'
2764
2784
  complete -c ${name} -n __fish_use_subcommand -a doc-pages -d 'List all pages in a doc with content'
2765
2785
  complete -c ${name} -n __fish_use_subcommand -a doc-page-create -d 'Create a page in a doc'
2766
2786
  complete -c ${name} -n __fish_use_subcommand -a doc-page-edit -d 'Edit a doc page'
2787
+ complete -c ${name} -n __fish_use_subcommand -a tags -d 'List tags in a space'
2767
2788
  complete -c ${name} -n __fish_use_subcommand -a folders -d 'List folders in a space'
2768
2789
  complete -c ${name} -n __fish_use_subcommand -a config -d 'Manage CLI configuration'
2769
2790
  complete -c ${name} -n __fish_use_subcommand -a completion -d 'Output shell completion script'
@@ -2924,6 +2945,8 @@ complete -c ${name} -n '__fish_seen_subcommand_from doc' -l json -d 'Force JSON
2924
2945
 
2925
2946
  complete -c ${name} -n '__fish_seen_subcommand_from doc-pages' -l json -d 'Force JSON output'
2926
2947
 
2948
+ complete -c ${name} -n '__fish_seen_subcommand_from tags' -l json -d 'Force JSON output'
2949
+
2927
2950
  complete -c ${name} -n '__fish_seen_subcommand_from folders' -l name -d 'Filter by folder name'
2928
2951
  complete -c ${name} -n '__fish_seen_subcommand_from folders' -l json -d 'Force JSON output'
2929
2952
 
@@ -3492,6 +3515,20 @@ async function listTimeEntries(config, opts) {
3492
3515
  taskId: opts?.taskId
3493
3516
  });
3494
3517
  }
3518
+ async function updateTimeEntry(config, timeEntryId, opts) {
3519
+ if (!opts.description && !opts.duration) {
3520
+ throw new Error("Provide --description or --duration to update");
3521
+ }
3522
+ const client = new ClickUpClient(config);
3523
+ const updates = {};
3524
+ if (opts.description) updates.description = opts.description;
3525
+ if (opts.duration) updates.duration = parseTimeEstimate(opts.duration);
3526
+ return client.updateTimeEntry(config.teamId, timeEntryId, updates);
3527
+ }
3528
+ async function deleteTimeEntry(config, timeEntryId) {
3529
+ const client = new ClickUpClient(config);
3530
+ await client.deleteTimeEntry(config.teamId, timeEntryId);
3531
+ }
3495
3532
  function formatTimeEntry(entry) {
3496
3533
  const lines = [];
3497
3534
  const taskName = entry.task?.name ?? "No task";
@@ -3524,6 +3561,21 @@ function formatTimeEntriesMarkdown(entries) {
3524
3561
  return entries.map(formatTimeEntryMarkdown).join("\n");
3525
3562
  }
3526
3563
 
3564
+ // src/commands/tags.ts
3565
+ import chalk11 from "chalk";
3566
+ async function listSpaceTags(config, spaceId) {
3567
+ const client = new ClickUpClient(config);
3568
+ return client.getSpaceTags(spaceId);
3569
+ }
3570
+ function formatTags(tags) {
3571
+ if (tags.length === 0) return "No tags found";
3572
+ return tags.map((t) => chalk11.bold(t.name)).join(", ");
3573
+ }
3574
+ function formatTagsMarkdown(tags) {
3575
+ if (tags.length === 0) return "No tags found";
3576
+ return tags.map((t) => `- ${t.name}`).join("\n");
3577
+ }
3578
+
3527
3579
  // src/index.ts
3528
3580
  var require2 = createRequire(import.meta.url);
3529
3581
  var { version } = require2("../package.json");
@@ -4066,6 +4118,48 @@ timeCmd.command("list").description("List recent time entries (default: last 7 d
4066
4118
  }
4067
4119
  })
4068
4120
  );
4121
+ timeCmd.command("update <timeEntryId>").description("Update a time entry").option("-d, --description <text>", "New description").option("--duration <duration>", 'New duration (e.g. "2h", "30m")').option("--json", "Force JSON output even in terminal").action(
4122
+ wrapAction(
4123
+ async (timeEntryId, opts) => {
4124
+ const config = loadConfig();
4125
+ const entry = await updateTimeEntry(config, timeEntryId, {
4126
+ description: opts.description,
4127
+ duration: opts.duration
4128
+ });
4129
+ if (shouldOutputJson(opts.json ?? false)) {
4130
+ console.log(JSON.stringify(entry, null, 2));
4131
+ } else if (isTTY()) {
4132
+ console.log(formatTimeEntry(entry));
4133
+ } else {
4134
+ console.log(formatTimeEntryMarkdown(entry));
4135
+ }
4136
+ }
4137
+ )
4138
+ );
4139
+ timeCmd.command("delete <timeEntryId>").description("Delete a time entry").option("--json", "Force JSON output even in terminal").action(
4140
+ wrapAction(async (timeEntryId, opts) => {
4141
+ const config = loadConfig();
4142
+ await deleteTimeEntry(config, timeEntryId);
4143
+ if (shouldOutputJson(opts.json ?? false)) {
4144
+ console.log(JSON.stringify({ deleted: timeEntryId }));
4145
+ } else {
4146
+ console.log(`Deleted time entry ${timeEntryId}`);
4147
+ }
4148
+ })
4149
+ );
4150
+ program.command("tags <spaceId>").description("List tags in a space").option("--json", "Force JSON output even in terminal").action(
4151
+ wrapAction(async (spaceId, opts) => {
4152
+ const config = loadConfig();
4153
+ const tags = await listSpaceTags(config, spaceId);
4154
+ if (shouldOutputJson(opts.json ?? false)) {
4155
+ console.log(JSON.stringify(tags, null, 2));
4156
+ } else if (isTTY()) {
4157
+ console.log(formatTags(tags));
4158
+ } else {
4159
+ console.log(formatTagsMarkdown(tags));
4160
+ }
4161
+ })
4162
+ );
4069
4163
  program.command("docs [query]").description("List workspace docs (optionally filter by name)").option("--json", "Force JSON output even in terminal").action(
4070
4164
  wrapAction(async (query, opts) => {
4071
4165
  const config = loadConfig();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@krodak/clickup-cli",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "ClickUp CLI for AI agents and humans",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -53,6 +53,7 @@ All commands support `--help` for full flag details.
53
53
  | `cup open <query> [--json]` | Open task in browser by ID or name |
54
54
  | `cup auth [--json]` | Check authentication status |
55
55
  | `cup folders <spaceId> [--name partial] [--json]` | Folders in a space (with their lists) |
56
+ | `cup tags <spaceId> [--json]` | List tags available in a space |
56
57
  | `cup docs [query] [--json]` | List workspace docs (optionally filter by name) |
57
58
  | `cup doc <docId> [pageId] [--json]` | View doc metadata + page tree, or a specific page |
58
59
  | `cup doc-pages <docId> [--json]` | All pages in a doc with content |
@@ -87,6 +88,8 @@ All commands support `--help` for full flag details.
87
88
  | `cup time status [--json]` | Show currently running timer |
88
89
  | `cup time log <taskId> <duration> [-d desc] [--json]` | Log manual time entry (e.g. "2h", "30m") |
89
90
  | `cup time list [--days n] [--task id] [--json]` | List recent time entries |
91
+ | `cup time update <timeEntryId> [-d desc] [--duration dur] [--json]` | Update a time entry |
92
+ | `cup time delete <timeEntryId> [--json]` | Delete a time entry |
90
93
  | `cup doc-create <title> [-c content] [--json]` | Create a new doc |
91
94
  | `cup doc-page-create <docId> <name> [-c content] [--parent-page pageId] [--json]` | Create a page in a doc |
92
95
  | `cup doc-page-edit <docId> <pageId> [--name text] [-c content] [--json]` | Edit a doc page |
@@ -123,7 +126,10 @@ All commands support `--help` for full flag details.
123
126
  | `cup overdue` | Excludes closed tasks, sorted most overdue first |
124
127
  | `cup open` | Tries task ID first, falls back to name search |
125
128
  | `cup checklist` | Full CRUD for task checklists: view, create, delete, add-item, edit-item, delete-item |
126
- | `cup time` | Track time: start/stop timer, log entries, list history. Duration format: "2h", "30m", "1h30m" |
129
+ | `cup tags` | List available tags in a space. Useful for discovering valid tag names before using `cup tag` |
130
+ | `cup time` | Track time: start/stop timer, log entries, list history, update/delete entries. Duration format: "2h", "30m", "1h30m" |
131
+ | `cup time update` | Update a time entry description or duration |
132
+ | `cup time delete` | Delete a time entry |
127
133
  | `cup comment-edit` | Edit comment text and resolution status |
128
134
  | `cup comment-delete` | Delete a comment |
129
135
  | `cup replies` / `cup reply` | View and post threaded comment replies |