@krodak/clickup-cli 1.17.0 → 1.18.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.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +24 -25
- package/dist/index.js +150 -45
- package/package.json +1 -1
- package/skills/clickup-cli/SKILL.md +3 -1
|
@@ -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.
|
|
4
|
+
"version": "1.18.0",
|
|
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
|
|
76
|
+
The package includes a [skill file](https://agentskills.io) that teaches agents all available commands. Install it with:
|
|
77
77
|
|
|
78
|
-
|
|
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> <img src="https://img.shields.io/badge/Claude_Code-D97757?logo=anthropic&logoColor=white" height="18" align="center"> <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
|
-
|
|
88
|
-
|
|
89
|
-
**Or install as a personal skill** (no namespace prefix):
|
|
96
|
+
**Or as a personal skill:**
|
|
90
97
|
|
|
91
98
|
```bash
|
|
92
|
-
|
|
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> <img src="https://img.shields.io/badge/Codex-412991?logo=openai&logoColor=white" height="18" align="center"> <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
|
-
|
|
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
|
-
|
|
111
|
+
Or for a project-level skill:
|
|
113
112
|
|
|
114
113
|
```bash
|
|
115
|
-
|
|
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> <img src="https://img.shields.io/badge/OpenCode-24292e?logoColor=white" height="18" align="center"> <strong>OpenCode</strong></summary>
|
|
126
121
|
|
|
127
122
|
```bash
|
|
128
|
-
|
|
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> <strong>Other agents</strong></summary>
|
|
137
130
|
|
|
138
|
-
|
|
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
|
@@ -5,7 +5,7 @@ import { realpathSync } from "fs";
|
|
|
5
5
|
import { basename, resolve } from "path";
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
import { createRequire } from "module";
|
|
8
|
-
import { fileURLToPath } from "url";
|
|
8
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
9
9
|
|
|
10
10
|
// src/api.ts
|
|
11
11
|
var BASE_URL = "https://api.clickup.com/api/v2";
|
|
@@ -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,81 @@ function generateCompletion(shell, name = "cup") {
|
|
|
4654
4666
|
}
|
|
4655
4667
|
}
|
|
4656
4668
|
|
|
4669
|
+
// src/commands/skill.ts
|
|
4670
|
+
import { readFileSync, mkdirSync, copyFileSync, existsSync } from "fs";
|
|
4671
|
+
import { join as join2, dirname } from "path";
|
|
4672
|
+
import { fileURLToPath } from "url";
|
|
4673
|
+
import { homedir as homedir2 } from "os";
|
|
4674
|
+
import chalk7 from "chalk";
|
|
4675
|
+
function skillPath() {
|
|
4676
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
4677
|
+
return join2(dirname(thisFile), "..", "..", "skills", "clickup-cli", "SKILL.md");
|
|
4678
|
+
}
|
|
4679
|
+
function printSkill() {
|
|
4680
|
+
return readFileSync(skillPath(), "utf-8");
|
|
4681
|
+
}
|
|
4682
|
+
function getAgentTargets() {
|
|
4683
|
+
const home = homedir2();
|
|
4684
|
+
const targets = [
|
|
4685
|
+
{ name: "Claude Code", dir: join2(home, ".claude", "skills", "clickup") },
|
|
4686
|
+
{ name: "Codex", dir: join2(home, ".agents", "skills", "clickup") },
|
|
4687
|
+
{ name: "OpenCode", dir: join2(home, ".config", "opencode", "skills", "clickup") }
|
|
4688
|
+
];
|
|
4689
|
+
return targets.map((t) => ({
|
|
4690
|
+
...t,
|
|
4691
|
+
detected: existsSync(dirname(t.dir))
|
|
4692
|
+
}));
|
|
4693
|
+
}
|
|
4694
|
+
async function installSkillInteractive() {
|
|
4695
|
+
const targets = getAgentTargets();
|
|
4696
|
+
const source = skillPath();
|
|
4697
|
+
const installed = [];
|
|
4698
|
+
if (isTTY()) {
|
|
4699
|
+
const { checkbox: checkbox2 } = await import("@inquirer/prompts");
|
|
4700
|
+
const preselected = targets.filter((t) => t.detected).map((t) => t.name);
|
|
4701
|
+
const selected = await checkbox2({
|
|
4702
|
+
message: "Install skill for which agents?",
|
|
4703
|
+
choices: targets.map((t) => ({
|
|
4704
|
+
name: `${t.name}${t.detected ? chalk7.dim(" (detected)") : ""}`,
|
|
4705
|
+
value: t.name,
|
|
4706
|
+
checked: t.detected
|
|
4707
|
+
}))
|
|
4708
|
+
});
|
|
4709
|
+
if (selected.length === 0) {
|
|
4710
|
+
throw new Error("No agents selected");
|
|
4711
|
+
}
|
|
4712
|
+
for (const name of selected) {
|
|
4713
|
+
const target = targets.find((t) => t.name === name);
|
|
4714
|
+
if (!existsSync(target.dir)) mkdirSync(target.dir, { recursive: true });
|
|
4715
|
+
const dest = join2(target.dir, "SKILL.md");
|
|
4716
|
+
copyFileSync(source, dest);
|
|
4717
|
+
installed.push(`${target.name}: ${dest}`);
|
|
4718
|
+
}
|
|
4719
|
+
} else {
|
|
4720
|
+
for (const target of targets.filter((t) => t.detected)) {
|
|
4721
|
+
if (!existsSync(target.dir)) mkdirSync(target.dir, { recursive: true });
|
|
4722
|
+
const dest = join2(target.dir, "SKILL.md");
|
|
4723
|
+
copyFileSync(source, dest);
|
|
4724
|
+
installed.push(`${target.name}: ${dest}`);
|
|
4725
|
+
}
|
|
4726
|
+
if (installed.length === 0) {
|
|
4727
|
+
const fallback = targets[0];
|
|
4728
|
+
mkdirSync(fallback.dir, { recursive: true });
|
|
4729
|
+
const dest = join2(fallback.dir, "SKILL.md");
|
|
4730
|
+
copyFileSync(source, dest);
|
|
4731
|
+
installed.push(`${fallback.name}: ${dest}`);
|
|
4732
|
+
}
|
|
4733
|
+
}
|
|
4734
|
+
return installed;
|
|
4735
|
+
}
|
|
4736
|
+
function installSkillTo(path) {
|
|
4737
|
+
const source = skillPath();
|
|
4738
|
+
const dir = dirname(path);
|
|
4739
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
4740
|
+
copyFileSync(source, path);
|
|
4741
|
+
return path;
|
|
4742
|
+
}
|
|
4743
|
+
|
|
4657
4744
|
// src/commands/auth.ts
|
|
4658
4745
|
async function checkAuth(config) {
|
|
4659
4746
|
const client = new ClickUpClient(config);
|
|
@@ -4932,7 +5019,7 @@ async function manageTags(config, taskId, opts) {
|
|
|
4932
5019
|
}
|
|
4933
5020
|
|
|
4934
5021
|
// src/commands/checklist.ts
|
|
4935
|
-
import
|
|
5022
|
+
import chalk8 from "chalk";
|
|
4936
5023
|
async function viewChecklists(config, taskId) {
|
|
4937
5024
|
const client = new ClickUpClient(config);
|
|
4938
5025
|
const task = await client.getTask(taskId);
|
|
@@ -4965,14 +5052,14 @@ function formatChecklists(checklists) {
|
|
|
4965
5052
|
const lines = [];
|
|
4966
5053
|
for (const cl of checklists) {
|
|
4967
5054
|
const resolved = cl.items.filter((i) => i.resolved).length;
|
|
4968
|
-
lines.push(
|
|
4969
|
-
lines.push(
|
|
5055
|
+
lines.push(chalk8.bold(`${cl.name} (${resolved}/${cl.items.length})`));
|
|
5056
|
+
lines.push(chalk8.dim(` ID: ${cl.id}`));
|
|
4970
5057
|
for (const item of cl.items) {
|
|
4971
|
-
const check = item.resolved ?
|
|
4972
|
-
const name = item.resolved ?
|
|
4973
|
-
const assignee = item.assignee ?
|
|
5058
|
+
const check = item.resolved ? chalk8.green("[x]") : chalk8.dim("[ ]");
|
|
5059
|
+
const name = item.resolved ? chalk8.dim(item.name) : item.name;
|
|
5060
|
+
const assignee = item.assignee ? chalk8.dim(` @${item.assignee.username}`) : "";
|
|
4974
5061
|
lines.push(` ${check} ${name}${assignee}`);
|
|
4975
|
-
lines.push(
|
|
5062
|
+
lines.push(chalk8.dim(` item-id: ${item.id}`));
|
|
4976
5063
|
}
|
|
4977
5064
|
}
|
|
4978
5065
|
return lines.join("\n");
|
|
@@ -5006,7 +5093,7 @@ async function deleteComment(config, commentId) {
|
|
|
5006
5093
|
}
|
|
5007
5094
|
|
|
5008
5095
|
// src/commands/replies.ts
|
|
5009
|
-
import
|
|
5096
|
+
import chalk9 from "chalk";
|
|
5010
5097
|
async function getReplies(config, commentId) {
|
|
5011
5098
|
const client = new ClickUpClient(config);
|
|
5012
5099
|
return client.getThreadedComments(commentId);
|
|
@@ -5021,7 +5108,7 @@ function formatReplies(replies) {
|
|
|
5021
5108
|
return replies.map((r) => {
|
|
5022
5109
|
const user = r.user?.username ?? "Unknown";
|
|
5023
5110
|
const date = formatTimestamp(Number(r.date));
|
|
5024
|
-
return `${
|
|
5111
|
+
return `${chalk9.bold(user)} ${chalk9.dim(date)}
|
|
5025
5112
|
${r.comment_text}`;
|
|
5026
5113
|
}).join("\n\n");
|
|
5027
5114
|
}
|
|
@@ -5084,7 +5171,7 @@ function formatDocsMarkdown(docs) {
|
|
|
5084
5171
|
}
|
|
5085
5172
|
|
|
5086
5173
|
// src/commands/doc.ts
|
|
5087
|
-
import
|
|
5174
|
+
import chalk10 from "chalk";
|
|
5088
5175
|
async function getDocInfo(config, docId) {
|
|
5089
5176
|
const client = new ClickUpClient(config);
|
|
5090
5177
|
const [doc, pages] = await Promise.all([
|
|
@@ -5096,14 +5183,14 @@ async function getDocInfo(config, docId) {
|
|
|
5096
5183
|
function formatDocInfo(doc, pages, indent = 0) {
|
|
5097
5184
|
const lines = [];
|
|
5098
5185
|
if (indent === 0) {
|
|
5099
|
-
lines.push(`${
|
|
5186
|
+
lines.push(`${chalk10.bold(doc.name)} ${chalk10.dim(doc.id)}`);
|
|
5100
5187
|
if (pages.length === 0) {
|
|
5101
5188
|
lines.push(" (no pages)");
|
|
5102
5189
|
}
|
|
5103
5190
|
}
|
|
5104
5191
|
for (const page of pages) {
|
|
5105
5192
|
const prefix = " ".repeat(indent + 1);
|
|
5106
|
-
lines.push(`${prefix}${page.name} ${
|
|
5193
|
+
lines.push(`${prefix}${page.name} ${chalk10.dim(page.id)}`);
|
|
5107
5194
|
if (page.pages && page.pages.length > 0) {
|
|
5108
5195
|
lines.push(formatDocInfo(doc, page.pages, indent + 1));
|
|
5109
5196
|
}
|
|
@@ -5182,7 +5269,7 @@ async function deleteDocPage(config, docId, pageId) {
|
|
|
5182
5269
|
}
|
|
5183
5270
|
|
|
5184
5271
|
// src/commands/folders.ts
|
|
5185
|
-
import
|
|
5272
|
+
import chalk11 from "chalk";
|
|
5186
5273
|
async function listFolders(config, spaceId, nameFilter) {
|
|
5187
5274
|
const client = new ClickUpClient(config);
|
|
5188
5275
|
const folders = await client.getFolders(spaceId);
|
|
@@ -5201,9 +5288,9 @@ async function listFolders(config, spaceId, nameFilter) {
|
|
|
5201
5288
|
function formatFolders(folders) {
|
|
5202
5289
|
if (folders.length === 0) return "No folders found";
|
|
5203
5290
|
return folders.map((f) => {
|
|
5204
|
-
const header = `${
|
|
5291
|
+
const header = `${chalk11.bold(f.name)} ${chalk11.dim(f.id)}`;
|
|
5205
5292
|
if (f.lists.length === 0) return header;
|
|
5206
|
-
const listLines = f.lists.map((l) => ` ${
|
|
5293
|
+
const listLines = f.lists.map((l) => ` ${chalk11.dim(">")} ${l.name} ${chalk11.dim(l.id)}`);
|
|
5207
5294
|
return [header, ...listLines].join("\n");
|
|
5208
5295
|
}).join("\n\n");
|
|
5209
5296
|
}
|
|
@@ -5218,13 +5305,13 @@ function formatFoldersMarkdown(folders) {
|
|
|
5218
5305
|
}
|
|
5219
5306
|
|
|
5220
5307
|
// src/commands/time.ts
|
|
5221
|
-
import
|
|
5308
|
+
import chalk12 from "chalk";
|
|
5222
5309
|
var TIME_COLUMNS = [
|
|
5223
5310
|
{ key: "task", label: "Task", maxWidth: 35 },
|
|
5224
5311
|
{ key: "duration", label: "Duration", maxWidth: 10 },
|
|
5225
5312
|
{ key: "date", label: "Date", maxWidth: 20 },
|
|
5226
5313
|
{ key: "description", label: "Description", maxWidth: 30 },
|
|
5227
|
-
{ key: "status", label: "", maxWidth: 10, format: (v) => v === "RUNNING" ?
|
|
5314
|
+
{ key: "status", label: "", maxWidth: 10, format: (v) => v === "RUNNING" ? chalk12.green(v) : "" }
|
|
5228
5315
|
];
|
|
5229
5316
|
async function startTimer(config, taskId, description) {
|
|
5230
5317
|
const client = new ClickUpClient(config);
|
|
@@ -5320,7 +5407,7 @@ function formatTimeEntriesMarkdown(entries) {
|
|
|
5320
5407
|
}
|
|
5321
5408
|
|
|
5322
5409
|
// src/commands/tags.ts
|
|
5323
|
-
import
|
|
5410
|
+
import chalk13 from "chalk";
|
|
5324
5411
|
var TAG_COLUMNS = [
|
|
5325
5412
|
{ key: "name", label: "Name", maxWidth: 40 },
|
|
5326
5413
|
{ key: "fg", label: "FG", maxWidth: 10 },
|
|
@@ -5353,13 +5440,13 @@ function formatTags(tags) {
|
|
|
5353
5440
|
if (tags.length === 0) return "No tags found";
|
|
5354
5441
|
if (isTTY()) {
|
|
5355
5442
|
const rows = tags.map((t) => ({
|
|
5356
|
-
name: t.tag_bg ?
|
|
5443
|
+
name: t.tag_bg ? chalk13.bgHex(t.tag_bg).hex(t.tag_fg || "#ffffff")(` ${t.name} `) : chalk13.bold(t.name),
|
|
5357
5444
|
fg: t.tag_fg || "",
|
|
5358
5445
|
bg: t.tag_bg || ""
|
|
5359
5446
|
}));
|
|
5360
5447
|
return formatTable(rows, TAG_COLUMNS);
|
|
5361
5448
|
}
|
|
5362
|
-
return tags.map((t) =>
|
|
5449
|
+
return tags.map((t) => chalk13.bold(t.name)).join(", ");
|
|
5363
5450
|
}
|
|
5364
5451
|
function formatTagsMarkdown(tags) {
|
|
5365
5452
|
if (tags.length === 0) return "No tags found";
|
|
@@ -5394,7 +5481,7 @@ function formatMembersMarkdown(members) {
|
|
|
5394
5481
|
}
|
|
5395
5482
|
|
|
5396
5483
|
// src/commands/fields.ts
|
|
5397
|
-
import
|
|
5484
|
+
import chalk14 from "chalk";
|
|
5398
5485
|
var FIELD_COLUMNS = [
|
|
5399
5486
|
{ key: "id", label: "ID", maxWidth: 20 },
|
|
5400
5487
|
{ key: "name", label: "Name", maxWidth: 30 },
|
|
@@ -5403,7 +5490,7 @@ var FIELD_COLUMNS = [
|
|
|
5403
5490
|
key: "required",
|
|
5404
5491
|
label: "Required",
|
|
5405
5492
|
maxWidth: 10,
|
|
5406
|
-
format: (v) => v === "yes" ?
|
|
5493
|
+
format: (v) => v === "yes" ? chalk14.yellow(v) : chalk14.dim(v)
|
|
5407
5494
|
},
|
|
5408
5495
|
{ key: "options", label: "Options", maxWidth: 40 }
|
|
5409
5496
|
];
|
|
@@ -5510,13 +5597,13 @@ async function bulkTag(config, tagName, taskIds, action) {
|
|
|
5510
5597
|
}
|
|
5511
5598
|
|
|
5512
5599
|
// src/commands/goals.ts
|
|
5513
|
-
import
|
|
5600
|
+
import chalk15 from "chalk";
|
|
5514
5601
|
function colorProgress(value) {
|
|
5515
5602
|
const num = parseInt(value, 10);
|
|
5516
5603
|
if (isNaN(num)) return value;
|
|
5517
|
-
if (num >= 75) return
|
|
5518
|
-
if (num >= 25) return
|
|
5519
|
-
return
|
|
5604
|
+
if (num >= 75) return chalk15.green(value);
|
|
5605
|
+
if (num >= 25) return chalk15.yellow(value);
|
|
5606
|
+
return chalk15.red(value);
|
|
5520
5607
|
}
|
|
5521
5608
|
var GOAL_COLUMNS = [
|
|
5522
5609
|
{ key: "id", label: "ID", maxWidth: 15 },
|
|
@@ -5610,14 +5697,14 @@ function formatKeyResultsMarkdown(keyResults) {
|
|
|
5610
5697
|
}
|
|
5611
5698
|
|
|
5612
5699
|
// src/commands/task-types.ts
|
|
5613
|
-
import
|
|
5700
|
+
import chalk16 from "chalk";
|
|
5614
5701
|
async function listTaskTypes(config) {
|
|
5615
5702
|
const client = new ClickUpClient(config);
|
|
5616
5703
|
return client.getCustomTaskTypes(config.teamId);
|
|
5617
5704
|
}
|
|
5618
5705
|
function formatTaskTypes(types) {
|
|
5619
5706
|
if (types.length === 0) return "No custom task types";
|
|
5620
|
-
return types.map((t) => `${
|
|
5707
|
+
return types.map((t) => `${chalk16.bold(t.name)} ${chalk16.dim(`(${t.id})`)}`).join("\n");
|
|
5621
5708
|
}
|
|
5622
5709
|
function formatTaskTypesMarkdown(types) {
|
|
5623
5710
|
if (types.length === 0) return "No custom task types";
|
|
@@ -5625,14 +5712,14 @@ function formatTaskTypesMarkdown(types) {
|
|
|
5625
5712
|
}
|
|
5626
5713
|
|
|
5627
5714
|
// src/commands/templates.ts
|
|
5628
|
-
import
|
|
5715
|
+
import chalk17 from "chalk";
|
|
5629
5716
|
async function listTemplates(config) {
|
|
5630
5717
|
const client = new ClickUpClient(config);
|
|
5631
5718
|
return client.getTaskTemplates(config.teamId);
|
|
5632
5719
|
}
|
|
5633
5720
|
function formatTemplates(templates) {
|
|
5634
5721
|
if (templates.length === 0) return "No task templates";
|
|
5635
|
-
return templates.map((t) => `${
|
|
5722
|
+
return templates.map((t) => `${chalk17.bold(t.name)} ${chalk17.dim(`(${t.id})`)}`).join("\n");
|
|
5636
5723
|
}
|
|
5637
5724
|
function formatTemplatesMarkdown(templates) {
|
|
5638
5725
|
if (templates.length === 0) return "No task templates";
|
|
@@ -5640,14 +5727,14 @@ function formatTemplatesMarkdown(templates) {
|
|
|
5640
5727
|
}
|
|
5641
5728
|
|
|
5642
5729
|
// src/commands/list-templates.ts
|
|
5643
|
-
import
|
|
5730
|
+
import chalk18 from "chalk";
|
|
5644
5731
|
async function listListTemplates(config) {
|
|
5645
5732
|
const client = new ClickUpClient(config);
|
|
5646
5733
|
return client.getListTemplates(config.teamId);
|
|
5647
5734
|
}
|
|
5648
5735
|
function formatListTemplates(templates) {
|
|
5649
5736
|
if (templates.length === 0) return "No list templates";
|
|
5650
|
-
return templates.map((t) => `${
|
|
5737
|
+
return templates.map((t) => `${chalk18.bold(t.name)} ${chalk18.dim(`(${t.id})`)}`).join("\n");
|
|
5651
5738
|
}
|
|
5652
5739
|
function formatListTemplatesMarkdown(templates) {
|
|
5653
5740
|
if (templates.length === 0) return "No list templates";
|
|
@@ -5655,14 +5742,14 @@ function formatListTemplatesMarkdown(templates) {
|
|
|
5655
5742
|
}
|
|
5656
5743
|
|
|
5657
5744
|
// src/commands/folder-templates.ts
|
|
5658
|
-
import
|
|
5745
|
+
import chalk19 from "chalk";
|
|
5659
5746
|
async function listFolderTemplates(config) {
|
|
5660
5747
|
const client = new ClickUpClient(config);
|
|
5661
5748
|
return client.getFolderTemplates(config.teamId);
|
|
5662
5749
|
}
|
|
5663
5750
|
function formatFolderTemplates(templates) {
|
|
5664
5751
|
if (templates.length === 0) return "No folder templates";
|
|
5665
|
-
return templates.map((t) => `${
|
|
5752
|
+
return templates.map((t) => `${chalk19.bold(t.name)} ${chalk19.dim(`(${t.id})`)}`).join("\n");
|
|
5666
5753
|
}
|
|
5667
5754
|
function formatFolderTemplatesMarkdown(templates) {
|
|
5668
5755
|
if (templates.length === 0) return "No folder templates";
|
|
@@ -5685,7 +5772,7 @@ async function createListFromTemplate(config, name, opts) {
|
|
|
5685
5772
|
}
|
|
5686
5773
|
|
|
5687
5774
|
// src/commands/views.ts
|
|
5688
|
-
import
|
|
5775
|
+
import chalk20 from "chalk";
|
|
5689
5776
|
async function listViews(config, id, container = "list") {
|
|
5690
5777
|
const client = new ClickUpClient(config);
|
|
5691
5778
|
if (container === "space") return client.getSpaceViews(id);
|
|
@@ -5696,7 +5783,7 @@ async function listViews(config, id, container = "list") {
|
|
|
5696
5783
|
}
|
|
5697
5784
|
function formatViews(views) {
|
|
5698
5785
|
if (views.length === 0) return "No views";
|
|
5699
|
-
return views.map((v) => `${
|
|
5786
|
+
return views.map((v) => `${chalk20.bold(v.name)} ${chalk20.dim(`(${v.id})`)} ${chalk20.dim(v.type)}`).join("\n");
|
|
5700
5787
|
}
|
|
5701
5788
|
function formatViewsMarkdown(views) {
|
|
5702
5789
|
if (views.length === 0) return "No views";
|
|
@@ -5704,20 +5791,20 @@ function formatViewsMarkdown(views) {
|
|
|
5704
5791
|
}
|
|
5705
5792
|
|
|
5706
5793
|
// src/commands/view.ts
|
|
5707
|
-
import
|
|
5794
|
+
import chalk21 from "chalk";
|
|
5708
5795
|
async function getView(config, viewId) {
|
|
5709
5796
|
const client = new ClickUpClient(config);
|
|
5710
5797
|
return client.getView(viewId);
|
|
5711
5798
|
}
|
|
5712
5799
|
function formatView(view) {
|
|
5713
5800
|
const lines = [];
|
|
5714
|
-
lines.push(
|
|
5801
|
+
lines.push(chalk21.bold.underline(view.name));
|
|
5715
5802
|
lines.push("");
|
|
5716
|
-
lines.push(` ${
|
|
5717
|
-
lines.push(` ${
|
|
5718
|
-
if (view.visibility) lines.push(` ${
|
|
5719
|
-
if (view.date_created) lines.push(` ${
|
|
5720
|
-
if (view.protected !== void 0) lines.push(` ${
|
|
5803
|
+
lines.push(` ${chalk21.bold("ID")} ${view.id}`);
|
|
5804
|
+
lines.push(` ${chalk21.bold("Type")} ${view.type}`);
|
|
5805
|
+
if (view.visibility) lines.push(` ${chalk21.bold("Visibility")} ${view.visibility}`);
|
|
5806
|
+
if (view.date_created) lines.push(` ${chalk21.bold("Created")} ${formatDate(view.date_created)}`);
|
|
5807
|
+
if (view.protected !== void 0) lines.push(` ${chalk21.bold("Protected")} ${view.protected}`);
|
|
5721
5808
|
return lines.join("\n");
|
|
5722
5809
|
}
|
|
5723
5810
|
function formatViewMarkdown(view) {
|
|
@@ -7471,6 +7558,24 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
7471
7558
|
process.stdout.write(script);
|
|
7472
7559
|
})
|
|
7473
7560
|
);
|
|
7561
|
+
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(
|
|
7562
|
+
wrapAction(async (opts) => {
|
|
7563
|
+
if (opts.print) {
|
|
7564
|
+
process.stdout.write(printSkill());
|
|
7565
|
+
return;
|
|
7566
|
+
}
|
|
7567
|
+
if (opts.path) {
|
|
7568
|
+
const dest = installSkillTo(opts.path);
|
|
7569
|
+
console.log(`Installed to ${dest}`);
|
|
7570
|
+
return;
|
|
7571
|
+
}
|
|
7572
|
+
const installed = await installSkillInteractive();
|
|
7573
|
+
console.log("");
|
|
7574
|
+
for (const entry of installed) {
|
|
7575
|
+
console.log(` Installed: ${entry}`);
|
|
7576
|
+
}
|
|
7577
|
+
})
|
|
7578
|
+
);
|
|
7474
7579
|
return program;
|
|
7475
7580
|
}
|
|
7476
7581
|
async function run(argv = process.argv) {
|
|
@@ -7484,7 +7589,7 @@ process.on("SIGINT", () => {
|
|
|
7484
7589
|
});
|
|
7485
7590
|
function checkDirectExecution() {
|
|
7486
7591
|
try {
|
|
7487
|
-
return process.argv[1] !== void 0 &&
|
|
7592
|
+
return process.argv[1] !== void 0 && fileURLToPath2(import.meta.url) === realpathSync(resolve(process.argv[1]));
|
|
7488
7593
|
} catch {
|
|
7489
7594
|
return false;
|
|
7490
7595
|
}
|
package/package.json
CHANGED
|
@@ -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.
|