@krodak/clickup-cli 1.17.0 → 1.18.1

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.17.0",
4
+ "version": "1.18.1",
5
5
  "author": {
6
6
  "name": "Krzysztof Rodak"
7
7
  },
package/README.md CHANGED
@@ -73,9 +73,18 @@ cup init
73
73
 
74
74
  ## Set up your agent
75
75
 
76
- The package includes a [skill file](https://agentskills.io) that teaches agents all available commands and when to use them. All three major coding agents support skills natively:
76
+ The package includes a [skill file](https://agentskills.io) that teaches agents all available commands. Install it with:
77
77
 
78
- <details open>
78
+ ```bash
79
+ cup skill
80
+ ```
81
+
82
+ This detects which agents you have (Claude Code, Codex, OpenCode) and installs the skill to the right locations. Run it again after updating `cup` to refresh the skill.
83
+
84
+ <details>
85
+ <summary>Manual install options</summary>
86
+
87
+ <details>
79
88
  <summary>&nbsp;<img src="https://img.shields.io/badge/Claude_Code-D97757?logo=anthropic&logoColor=white" height="18" align="center">&nbsp;<strong>Claude Code</strong></summary>
80
89
 
81
90
  **Install as a [plugin](https://docs.anthropic.com/en/docs/claude-code/plugins)** (recommended):
@@ -84,14 +93,10 @@ The package includes a [skill file](https://agentskills.io) that teaches agents
84
93
  claude plugin add $(npm root -g)/@krodak/clickup-cli
85
94
  ```
86
95
 
87
- This registers the skill under the `clickup-cli:` namespace. Claude loads it automatically when you work with ClickUp tasks.
88
-
89
- **Or install as a personal skill** (no namespace prefix):
96
+ **Or as a personal skill:**
90
97
 
91
98
  ```bash
92
- SKILL=$(npm root -g)/@krodak/clickup-cli/skills/clickup-cli
93
- mkdir -p ~/.claude/skills/clickup
94
- cp "$SKILL/SKILL.md" ~/.claude/skills/clickup/SKILL.md
99
+ cup skill --path ~/.claude/skills/clickup/SKILL.md
95
100
  ```
96
101
 
97
102
  </details>
@@ -99,35 +104,23 @@ cp "$SKILL/SKILL.md" ~/.claude/skills/clickup/SKILL.md
99
104
  <details>
100
105
  <summary>&nbsp;<img src="https://img.shields.io/badge/Codex-412991?logo=openai&logoColor=white" height="18" align="center">&nbsp;<strong>Codex</strong></summary>
101
106
 
102
- Codex supports [agent skills](https://developers.openai.com/codex/skills) across CLI, IDE extension, and web. Skills use the same `SKILL.md` format with YAML frontmatter.
103
-
104
- **Install as a user skill** (available across all your projects):
105
-
106
107
  ```bash
107
- SKILL=$(npm root -g)/@krodak/clickup-cli/skills/clickup-cli
108
- mkdir -p ~/.agents/skills/clickup
109
- cp "$SKILL/SKILL.md" ~/.agents/skills/clickup/SKILL.md
108
+ cup skill --path ~/.agents/skills/clickup/SKILL.md
110
109
  ```
111
110
 
112
- **Or install as a project skill** (checked into your repo):
111
+ Or for a project-level skill:
113
112
 
114
113
  ```bash
115
- SKILL=$(npm root -g)/@krodak/clickup-cli/skills/clickup-cli
116
- mkdir -p .agents/skills/clickup
117
- cp "$SKILL/SKILL.md" .agents/skills/clickup/SKILL.md
114
+ cup skill --path .agents/skills/clickup/SKILL.md
118
115
  ```
119
116
 
120
- You can also use the built-in installer: `$skill-installer clickup`
121
-
122
117
  </details>
123
118
 
124
119
  <details>
125
120
  <summary>&nbsp;<img src="https://img.shields.io/badge/OpenCode-24292e?logoColor=white" height="18" align="center">&nbsp;<strong>OpenCode</strong></summary>
126
121
 
127
122
  ```bash
128
- SKILL=$(npm root -g)/@krodak/clickup-cli/skills/clickup-cli
129
- mkdir -p ~/.config/opencode/skills/clickup
130
- cp "$SKILL/SKILL.md" ~/.config/opencode/skills/clickup/SKILL.md
123
+ cup skill --path ~/.config/opencode/skills/clickup/SKILL.md
131
124
  ```
132
125
 
133
126
  </details>
@@ -135,7 +128,13 @@ cp "$SKILL/SKILL.md" ~/.config/opencode/skills/clickup/SKILL.md
135
128
  <details>
136
129
  <summary>&nbsp;<strong>Other agents</strong></summary>
137
130
 
138
- The skill file follows the [Agent Skills](https://agentskills.io) open standard. Copy `skills/clickup-cli/SKILL.md` into your agent's skill directory, system prompt, or `AGENTS.md`.
131
+ ```bash
132
+ cup skill --print > SKILL.md # output skill content to a file
133
+ ```
134
+
135
+ Or copy `skills/clickup-cli/SKILL.md` into your agent's skill directory or `AGENTS.md`.
136
+
137
+ </details>
139
138
 
140
139
  </details>
141
140
 
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { realpathSync } from "fs";
4
+ import { realpathSync as realpathSync2 } from "fs";
5
5
  import { basename, resolve } from "path";
6
6
  import { Command } from "commander";
7
7
  import { createRequire } from "module";
@@ -3363,6 +3363,18 @@ var commandMetadata = [
3363
3363
  { section: "read", usage: "folders <spaceId>", description: "List folders in a space" }
3364
3364
  ]
3365
3365
  },
3366
+ {
3367
+ name: "skill",
3368
+ description: "Install the agent skill file for your coding agents",
3369
+ flags: ["--print", "--path"],
3370
+ quickReference: [
3371
+ {
3372
+ section: "setup",
3373
+ usage: "skill",
3374
+ description: "Install skill for your agents"
3375
+ }
3376
+ ]
3377
+ },
3366
3378
  {
3367
3379
  name: "space-create",
3368
3380
  description: "Create a new space in your workspace",
@@ -4654,6 +4666,85 @@ function generateCompletion(shell, name = "cup") {
4654
4666
  }
4655
4667
  }
4656
4668
 
4669
+ // src/commands/skill.ts
4670
+ import { readFileSync, realpathSync, mkdirSync, copyFileSync, existsSync } from "fs";
4671
+ import { join as join2, dirname } from "path";
4672
+ import { homedir as homedir2 } from "os";
4673
+ import chalk7 from "chalk";
4674
+ function skillPath() {
4675
+ const entryPoint = realpathSync(process.argv[1] ?? "");
4676
+ const packageRoot = dirname(dirname(entryPoint));
4677
+ const candidate = join2(packageRoot, "skills", "clickup-cli", "SKILL.md");
4678
+ if (existsSync(candidate)) return candidate;
4679
+ const altCandidate = join2(dirname(entryPoint), "..", "skills", "clickup-cli", "SKILL.md");
4680
+ if (existsSync(altCandidate)) return altCandidate;
4681
+ throw new Error("SKILL.md not found. Reinstall with: npm install -g @krodak/clickup-cli");
4682
+ }
4683
+ function printSkill() {
4684
+ return readFileSync(skillPath(), "utf-8");
4685
+ }
4686
+ function getAgentTargets() {
4687
+ const home = homedir2();
4688
+ const targets = [
4689
+ { name: "Claude Code", dir: join2(home, ".claude", "skills", "clickup") },
4690
+ { name: "Codex", dir: join2(home, ".agents", "skills", "clickup") },
4691
+ { name: "OpenCode", dir: join2(home, ".config", "opencode", "skills", "clickup") }
4692
+ ];
4693
+ return targets.map((t) => ({
4694
+ ...t,
4695
+ detected: existsSync(dirname(t.dir))
4696
+ }));
4697
+ }
4698
+ async function installSkillInteractive() {
4699
+ const targets = getAgentTargets();
4700
+ const source = skillPath();
4701
+ const installed = [];
4702
+ if (isTTY()) {
4703
+ const { checkbox: checkbox2 } = await import("@inquirer/prompts");
4704
+ const preselected = targets.filter((t) => t.detected).map((t) => t.name);
4705
+ const selected = await checkbox2({
4706
+ message: "Install skill for which agents?",
4707
+ choices: targets.map((t) => ({
4708
+ name: `${t.name}${t.detected ? chalk7.dim(" (detected)") : ""}`,
4709
+ value: t.name,
4710
+ checked: t.detected
4711
+ }))
4712
+ });
4713
+ if (selected.length === 0) {
4714
+ throw new Error("No agents selected");
4715
+ }
4716
+ for (const name of selected) {
4717
+ const target = targets.find((t) => t.name === name);
4718
+ if (!existsSync(target.dir)) mkdirSync(target.dir, { recursive: true });
4719
+ const dest = join2(target.dir, "SKILL.md");
4720
+ copyFileSync(source, dest);
4721
+ installed.push(`${target.name}: ${dest}`);
4722
+ }
4723
+ } else {
4724
+ for (const target of targets.filter((t) => t.detected)) {
4725
+ if (!existsSync(target.dir)) mkdirSync(target.dir, { recursive: true });
4726
+ const dest = join2(target.dir, "SKILL.md");
4727
+ copyFileSync(source, dest);
4728
+ installed.push(`${target.name}: ${dest}`);
4729
+ }
4730
+ if (installed.length === 0) {
4731
+ const fallback = targets[0];
4732
+ mkdirSync(fallback.dir, { recursive: true });
4733
+ const dest = join2(fallback.dir, "SKILL.md");
4734
+ copyFileSync(source, dest);
4735
+ installed.push(`${fallback.name}: ${dest}`);
4736
+ }
4737
+ }
4738
+ return installed;
4739
+ }
4740
+ function installSkillTo(path) {
4741
+ const source = skillPath();
4742
+ const dir = dirname(path);
4743
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
4744
+ copyFileSync(source, path);
4745
+ return path;
4746
+ }
4747
+
4657
4748
  // src/commands/auth.ts
4658
4749
  async function checkAuth(config) {
4659
4750
  const client = new ClickUpClient(config);
@@ -4932,7 +5023,7 @@ async function manageTags(config, taskId, opts) {
4932
5023
  }
4933
5024
 
4934
5025
  // src/commands/checklist.ts
4935
- import chalk7 from "chalk";
5026
+ import chalk8 from "chalk";
4936
5027
  async function viewChecklists(config, taskId) {
4937
5028
  const client = new ClickUpClient(config);
4938
5029
  const task = await client.getTask(taskId);
@@ -4965,14 +5056,14 @@ function formatChecklists(checklists) {
4965
5056
  const lines = [];
4966
5057
  for (const cl of checklists) {
4967
5058
  const resolved = cl.items.filter((i) => i.resolved).length;
4968
- lines.push(chalk7.bold(`${cl.name} (${resolved}/${cl.items.length})`));
4969
- lines.push(chalk7.dim(` ID: ${cl.id}`));
5059
+ lines.push(chalk8.bold(`${cl.name} (${resolved}/${cl.items.length})`));
5060
+ lines.push(chalk8.dim(` ID: ${cl.id}`));
4970
5061
  for (const item of cl.items) {
4971
- const check = item.resolved ? chalk7.green("[x]") : chalk7.dim("[ ]");
4972
- const name = item.resolved ? chalk7.dim(item.name) : item.name;
4973
- const assignee = item.assignee ? chalk7.dim(` @${item.assignee.username}`) : "";
5062
+ const check = item.resolved ? chalk8.green("[x]") : chalk8.dim("[ ]");
5063
+ const name = item.resolved ? chalk8.dim(item.name) : item.name;
5064
+ const assignee = item.assignee ? chalk8.dim(` @${item.assignee.username}`) : "";
4974
5065
  lines.push(` ${check} ${name}${assignee}`);
4975
- lines.push(chalk7.dim(` item-id: ${item.id}`));
5066
+ lines.push(chalk8.dim(` item-id: ${item.id}`));
4976
5067
  }
4977
5068
  }
4978
5069
  return lines.join("\n");
@@ -5006,7 +5097,7 @@ async function deleteComment(config, commentId) {
5006
5097
  }
5007
5098
 
5008
5099
  // src/commands/replies.ts
5009
- import chalk8 from "chalk";
5100
+ import chalk9 from "chalk";
5010
5101
  async function getReplies(config, commentId) {
5011
5102
  const client = new ClickUpClient(config);
5012
5103
  return client.getThreadedComments(commentId);
@@ -5021,7 +5112,7 @@ function formatReplies(replies) {
5021
5112
  return replies.map((r) => {
5022
5113
  const user = r.user?.username ?? "Unknown";
5023
5114
  const date = formatTimestamp(Number(r.date));
5024
- return `${chalk8.bold(user)} ${chalk8.dim(date)}
5115
+ return `${chalk9.bold(user)} ${chalk9.dim(date)}
5025
5116
  ${r.comment_text}`;
5026
5117
  }).join("\n\n");
5027
5118
  }
@@ -5084,7 +5175,7 @@ function formatDocsMarkdown(docs) {
5084
5175
  }
5085
5176
 
5086
5177
  // src/commands/doc.ts
5087
- import chalk9 from "chalk";
5178
+ import chalk10 from "chalk";
5088
5179
  async function getDocInfo(config, docId) {
5089
5180
  const client = new ClickUpClient(config);
5090
5181
  const [doc, pages] = await Promise.all([
@@ -5096,14 +5187,14 @@ async function getDocInfo(config, docId) {
5096
5187
  function formatDocInfo(doc, pages, indent = 0) {
5097
5188
  const lines = [];
5098
5189
  if (indent === 0) {
5099
- lines.push(`${chalk9.bold(doc.name)} ${chalk9.dim(doc.id)}`);
5190
+ lines.push(`${chalk10.bold(doc.name)} ${chalk10.dim(doc.id)}`);
5100
5191
  if (pages.length === 0) {
5101
5192
  lines.push(" (no pages)");
5102
5193
  }
5103
5194
  }
5104
5195
  for (const page of pages) {
5105
5196
  const prefix = " ".repeat(indent + 1);
5106
- lines.push(`${prefix}${page.name} ${chalk9.dim(page.id)}`);
5197
+ lines.push(`${prefix}${page.name} ${chalk10.dim(page.id)}`);
5107
5198
  if (page.pages && page.pages.length > 0) {
5108
5199
  lines.push(formatDocInfo(doc, page.pages, indent + 1));
5109
5200
  }
@@ -5182,7 +5273,7 @@ async function deleteDocPage(config, docId, pageId) {
5182
5273
  }
5183
5274
 
5184
5275
  // src/commands/folders.ts
5185
- import chalk10 from "chalk";
5276
+ import chalk11 from "chalk";
5186
5277
  async function listFolders(config, spaceId, nameFilter) {
5187
5278
  const client = new ClickUpClient(config);
5188
5279
  const folders = await client.getFolders(spaceId);
@@ -5201,9 +5292,9 @@ async function listFolders(config, spaceId, nameFilter) {
5201
5292
  function formatFolders(folders) {
5202
5293
  if (folders.length === 0) return "No folders found";
5203
5294
  return folders.map((f) => {
5204
- const header = `${chalk10.bold(f.name)} ${chalk10.dim(f.id)}`;
5295
+ const header = `${chalk11.bold(f.name)} ${chalk11.dim(f.id)}`;
5205
5296
  if (f.lists.length === 0) return header;
5206
- const listLines = f.lists.map((l) => ` ${chalk10.dim(">")} ${l.name} ${chalk10.dim(l.id)}`);
5297
+ const listLines = f.lists.map((l) => ` ${chalk11.dim(">")} ${l.name} ${chalk11.dim(l.id)}`);
5207
5298
  return [header, ...listLines].join("\n");
5208
5299
  }).join("\n\n");
5209
5300
  }
@@ -5218,13 +5309,13 @@ function formatFoldersMarkdown(folders) {
5218
5309
  }
5219
5310
 
5220
5311
  // src/commands/time.ts
5221
- import chalk11 from "chalk";
5312
+ import chalk12 from "chalk";
5222
5313
  var TIME_COLUMNS = [
5223
5314
  { key: "task", label: "Task", maxWidth: 35 },
5224
5315
  { key: "duration", label: "Duration", maxWidth: 10 },
5225
5316
  { key: "date", label: "Date", maxWidth: 20 },
5226
5317
  { key: "description", label: "Description", maxWidth: 30 },
5227
- { key: "status", label: "", maxWidth: 10, format: (v) => v === "RUNNING" ? chalk11.green(v) : "" }
5318
+ { key: "status", label: "", maxWidth: 10, format: (v) => v === "RUNNING" ? chalk12.green(v) : "" }
5228
5319
  ];
5229
5320
  async function startTimer(config, taskId, description) {
5230
5321
  const client = new ClickUpClient(config);
@@ -5320,7 +5411,7 @@ function formatTimeEntriesMarkdown(entries) {
5320
5411
  }
5321
5412
 
5322
5413
  // src/commands/tags.ts
5323
- import chalk12 from "chalk";
5414
+ import chalk13 from "chalk";
5324
5415
  var TAG_COLUMNS = [
5325
5416
  { key: "name", label: "Name", maxWidth: 40 },
5326
5417
  { key: "fg", label: "FG", maxWidth: 10 },
@@ -5353,13 +5444,13 @@ function formatTags(tags) {
5353
5444
  if (tags.length === 0) return "No tags found";
5354
5445
  if (isTTY()) {
5355
5446
  const rows = tags.map((t) => ({
5356
- name: t.tag_bg ? chalk12.bgHex(t.tag_bg).hex(t.tag_fg || "#ffffff")(` ${t.name} `) : chalk12.bold(t.name),
5447
+ name: t.tag_bg ? chalk13.bgHex(t.tag_bg).hex(t.tag_fg || "#ffffff")(` ${t.name} `) : chalk13.bold(t.name),
5357
5448
  fg: t.tag_fg || "",
5358
5449
  bg: t.tag_bg || ""
5359
5450
  }));
5360
5451
  return formatTable(rows, TAG_COLUMNS);
5361
5452
  }
5362
- return tags.map((t) => chalk12.bold(t.name)).join(", ");
5453
+ return tags.map((t) => chalk13.bold(t.name)).join(", ");
5363
5454
  }
5364
5455
  function formatTagsMarkdown(tags) {
5365
5456
  if (tags.length === 0) return "No tags found";
@@ -5394,7 +5485,7 @@ function formatMembersMarkdown(members) {
5394
5485
  }
5395
5486
 
5396
5487
  // src/commands/fields.ts
5397
- import chalk13 from "chalk";
5488
+ import chalk14 from "chalk";
5398
5489
  var FIELD_COLUMNS = [
5399
5490
  { key: "id", label: "ID", maxWidth: 20 },
5400
5491
  { key: "name", label: "Name", maxWidth: 30 },
@@ -5403,7 +5494,7 @@ var FIELD_COLUMNS = [
5403
5494
  key: "required",
5404
5495
  label: "Required",
5405
5496
  maxWidth: 10,
5406
- format: (v) => v === "yes" ? chalk13.yellow(v) : chalk13.dim(v)
5497
+ format: (v) => v === "yes" ? chalk14.yellow(v) : chalk14.dim(v)
5407
5498
  },
5408
5499
  { key: "options", label: "Options", maxWidth: 40 }
5409
5500
  ];
@@ -5510,13 +5601,13 @@ async function bulkTag(config, tagName, taskIds, action) {
5510
5601
  }
5511
5602
 
5512
5603
  // src/commands/goals.ts
5513
- import chalk14 from "chalk";
5604
+ import chalk15 from "chalk";
5514
5605
  function colorProgress(value) {
5515
5606
  const num = parseInt(value, 10);
5516
5607
  if (isNaN(num)) return value;
5517
- if (num >= 75) return chalk14.green(value);
5518
- if (num >= 25) return chalk14.yellow(value);
5519
- return chalk14.red(value);
5608
+ if (num >= 75) return chalk15.green(value);
5609
+ if (num >= 25) return chalk15.yellow(value);
5610
+ return chalk15.red(value);
5520
5611
  }
5521
5612
  var GOAL_COLUMNS = [
5522
5613
  { key: "id", label: "ID", maxWidth: 15 },
@@ -5610,14 +5701,14 @@ function formatKeyResultsMarkdown(keyResults) {
5610
5701
  }
5611
5702
 
5612
5703
  // src/commands/task-types.ts
5613
- import chalk15 from "chalk";
5704
+ import chalk16 from "chalk";
5614
5705
  async function listTaskTypes(config) {
5615
5706
  const client = new ClickUpClient(config);
5616
5707
  return client.getCustomTaskTypes(config.teamId);
5617
5708
  }
5618
5709
  function formatTaskTypes(types) {
5619
5710
  if (types.length === 0) return "No custom task types";
5620
- return types.map((t) => `${chalk15.bold(t.name)} ${chalk15.dim(`(${t.id})`)}`).join("\n");
5711
+ return types.map((t) => `${chalk16.bold(t.name)} ${chalk16.dim(`(${t.id})`)}`).join("\n");
5621
5712
  }
5622
5713
  function formatTaskTypesMarkdown(types) {
5623
5714
  if (types.length === 0) return "No custom task types";
@@ -5625,14 +5716,14 @@ function formatTaskTypesMarkdown(types) {
5625
5716
  }
5626
5717
 
5627
5718
  // src/commands/templates.ts
5628
- import chalk16 from "chalk";
5719
+ import chalk17 from "chalk";
5629
5720
  async function listTemplates(config) {
5630
5721
  const client = new ClickUpClient(config);
5631
5722
  return client.getTaskTemplates(config.teamId);
5632
5723
  }
5633
5724
  function formatTemplates(templates) {
5634
5725
  if (templates.length === 0) return "No task templates";
5635
- return templates.map((t) => `${chalk16.bold(t.name)} ${chalk16.dim(`(${t.id})`)}`).join("\n");
5726
+ return templates.map((t) => `${chalk17.bold(t.name)} ${chalk17.dim(`(${t.id})`)}`).join("\n");
5636
5727
  }
5637
5728
  function formatTemplatesMarkdown(templates) {
5638
5729
  if (templates.length === 0) return "No task templates";
@@ -5640,14 +5731,14 @@ function formatTemplatesMarkdown(templates) {
5640
5731
  }
5641
5732
 
5642
5733
  // src/commands/list-templates.ts
5643
- import chalk17 from "chalk";
5734
+ import chalk18 from "chalk";
5644
5735
  async function listListTemplates(config) {
5645
5736
  const client = new ClickUpClient(config);
5646
5737
  return client.getListTemplates(config.teamId);
5647
5738
  }
5648
5739
  function formatListTemplates(templates) {
5649
5740
  if (templates.length === 0) return "No list templates";
5650
- return templates.map((t) => `${chalk17.bold(t.name)} ${chalk17.dim(`(${t.id})`)}`).join("\n");
5741
+ return templates.map((t) => `${chalk18.bold(t.name)} ${chalk18.dim(`(${t.id})`)}`).join("\n");
5651
5742
  }
5652
5743
  function formatListTemplatesMarkdown(templates) {
5653
5744
  if (templates.length === 0) return "No list templates";
@@ -5655,14 +5746,14 @@ function formatListTemplatesMarkdown(templates) {
5655
5746
  }
5656
5747
 
5657
5748
  // src/commands/folder-templates.ts
5658
- import chalk18 from "chalk";
5749
+ import chalk19 from "chalk";
5659
5750
  async function listFolderTemplates(config) {
5660
5751
  const client = new ClickUpClient(config);
5661
5752
  return client.getFolderTemplates(config.teamId);
5662
5753
  }
5663
5754
  function formatFolderTemplates(templates) {
5664
5755
  if (templates.length === 0) return "No folder templates";
5665
- return templates.map((t) => `${chalk18.bold(t.name)} ${chalk18.dim(`(${t.id})`)}`).join("\n");
5756
+ return templates.map((t) => `${chalk19.bold(t.name)} ${chalk19.dim(`(${t.id})`)}`).join("\n");
5666
5757
  }
5667
5758
  function formatFolderTemplatesMarkdown(templates) {
5668
5759
  if (templates.length === 0) return "No folder templates";
@@ -5685,7 +5776,7 @@ async function createListFromTemplate(config, name, opts) {
5685
5776
  }
5686
5777
 
5687
5778
  // src/commands/views.ts
5688
- import chalk19 from "chalk";
5779
+ import chalk20 from "chalk";
5689
5780
  async function listViews(config, id, container = "list") {
5690
5781
  const client = new ClickUpClient(config);
5691
5782
  if (container === "space") return client.getSpaceViews(id);
@@ -5696,7 +5787,7 @@ async function listViews(config, id, container = "list") {
5696
5787
  }
5697
5788
  function formatViews(views) {
5698
5789
  if (views.length === 0) return "No views";
5699
- return views.map((v) => `${chalk19.bold(v.name)} ${chalk19.dim(`(${v.id})`)} ${chalk19.dim(v.type)}`).join("\n");
5790
+ return views.map((v) => `${chalk20.bold(v.name)} ${chalk20.dim(`(${v.id})`)} ${chalk20.dim(v.type)}`).join("\n");
5700
5791
  }
5701
5792
  function formatViewsMarkdown(views) {
5702
5793
  if (views.length === 0) return "No views";
@@ -5704,20 +5795,20 @@ function formatViewsMarkdown(views) {
5704
5795
  }
5705
5796
 
5706
5797
  // src/commands/view.ts
5707
- import chalk20 from "chalk";
5798
+ import chalk21 from "chalk";
5708
5799
  async function getView(config, viewId) {
5709
5800
  const client = new ClickUpClient(config);
5710
5801
  return client.getView(viewId);
5711
5802
  }
5712
5803
  function formatView(view) {
5713
5804
  const lines = [];
5714
- lines.push(chalk20.bold.underline(view.name));
5805
+ lines.push(chalk21.bold.underline(view.name));
5715
5806
  lines.push("");
5716
- lines.push(` ${chalk20.bold("ID")} ${view.id}`);
5717
- lines.push(` ${chalk20.bold("Type")} ${view.type}`);
5718
- if (view.visibility) lines.push(` ${chalk20.bold("Visibility")} ${view.visibility}`);
5719
- if (view.date_created) lines.push(` ${chalk20.bold("Created")} ${formatDate(view.date_created)}`);
5720
- if (view.protected !== void 0) lines.push(` ${chalk20.bold("Protected")} ${view.protected}`);
5807
+ lines.push(` ${chalk21.bold("ID")} ${view.id}`);
5808
+ lines.push(` ${chalk21.bold("Type")} ${view.type}`);
5809
+ if (view.visibility) lines.push(` ${chalk21.bold("Visibility")} ${view.visibility}`);
5810
+ if (view.date_created) lines.push(` ${chalk21.bold("Created")} ${formatDate(view.date_created)}`);
5811
+ if (view.protected !== void 0) lines.push(` ${chalk21.bold("Protected")} ${view.protected}`);
5721
5812
  return lines.join("\n");
5722
5813
  }
5723
5814
  function formatViewMarkdown(view) {
@@ -7471,6 +7562,24 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
7471
7562
  process.stdout.write(script);
7472
7563
  })
7473
7564
  );
7565
+ program.command("skill").description("Install the agent skill file for your coding agents").option("--print", "Print the skill file content instead of installing").option("--path <path>", "Install to a specific path").action(
7566
+ wrapAction(async (opts) => {
7567
+ if (opts.print) {
7568
+ process.stdout.write(printSkill());
7569
+ return;
7570
+ }
7571
+ if (opts.path) {
7572
+ const dest = installSkillTo(opts.path);
7573
+ console.log(`Installed to ${dest}`);
7574
+ return;
7575
+ }
7576
+ const installed = await installSkillInteractive();
7577
+ console.log("");
7578
+ for (const entry of installed) {
7579
+ console.log(` Installed: ${entry}`);
7580
+ }
7581
+ })
7582
+ );
7474
7583
  return program;
7475
7584
  }
7476
7585
  async function run(argv = process.argv) {
@@ -7484,7 +7593,7 @@ process.on("SIGINT", () => {
7484
7593
  });
7485
7594
  function checkDirectExecution() {
7486
7595
  try {
7487
- return process.argv[1] !== void 0 && fileURLToPath(import.meta.url) === realpathSync(resolve(process.argv[1]));
7596
+ return process.argv[1] !== void 0 && fileURLToPath(import.meta.url) === realpathSync2(resolve(process.argv[1]));
7488
7597
  } catch {
7489
7598
  return false;
7490
7599
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@krodak/clickup-cli",
3
- "version": "1.17.0",
3
+ "version": "1.18.1",
4
4
  "description": "ClickUp CLI for AI agents and humans",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -3,10 +3,12 @@ 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.'
4
4
  ---
5
5
 
6
- # ClickUp CLI (`cup`)
6
+ # ClickUp CLI (`cup`) - skill version 1.17.0
7
7
 
8
8
  Reference for AI agents using the `cup` CLI tool. Covers task management, sprint tracking, comments, and project workflows.
9
9
 
10
+ > **Version check:** Run `cup --version`. If your installed version is older than 1.18.0, update with `npm install -g @krodak/clickup-cli` and refresh this skill with `cup skill`.
11
+
10
12
  ## Setup
11
13
 
12
14
  Config at `~/.config/cup/config.json` with named profiles. Each profile has `apiToken` and `teamId`. Optional: `sprintFolderId` to pin sprint detection to a specific folder. Run `cup init` to set up interactively.