clickup-agent-cli 0.4.0 → 0.4.2

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.
@@ -11,7 +11,7 @@
11
11
  "name": "clickup",
12
12
  "source": "./",
13
13
  "description": "ClickUp CLI with 25 agent skills covering the full API -- token-efficient alternative to MCP with chat, time tracking, docs, and project management workflows",
14
- "version": "0.4.0",
14
+ "version": "0.4.2",
15
15
  "homepage": "https://github.com/henryreith/clickup-cli",
16
16
  "keywords": ["clickup", "project-management", "tasks", "time-tracking"],
17
17
  "category": "productivity"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "clickup",
3
3
  "description": "ClickUp CLI with 25 agent skills covering the full API -- token-efficient alternative to MCP with chat, time tracking, docs, and project management workflows",
4
- "version": "0.4.0",
4
+ "version": "0.4.2",
5
5
  "author": {
6
6
  "name": "Henry Reith"
7
7
  },
package/README.md CHANGED
@@ -112,7 +112,7 @@ import { query } from "@anthropic-ai/claude-agent-sdk";
112
112
  for await (const message of query({
113
113
  prompt: "Create a task for the login bug fix and assign to the backend team",
114
114
  options: {
115
- plugins: [{ type: "local", path: "./node_modules/clickup-cli" }],
115
+ plugins: [{ type: "local", path: "./node_modules/clickup-agent-cli" }],
116
116
  allowedTools: ["Skill", "Bash"],
117
117
  settingSources: ["project"]
118
118
  }
@@ -133,7 +133,7 @@ clickup skill show clickup
133
133
  clickup skill show clickup-tasks
134
134
 
135
135
  # Or asks the CLI what fields are needed (~50 tokens in response)
136
- clickup schema tasks.create
136
+ clickup schema task.create
137
137
 
138
138
  # For complex workflows, load a recipe skill
139
139
  clickup skill show clickup-weekly-review
@@ -180,11 +180,34 @@ This creates `/marketing-weekly` alongside the built-in `/clickup:*` skills.
180
180
  | Platform | How to use |
181
181
  |----------|-----------|
182
182
  | Claude Code | Plugin via marketplace (see above) |
183
- | Claude Agent SDK | `plugins: [{ type: "local", path: "./node_modules/clickup-cli" }]` |
183
+ | Claude Agent SDK | `plugins: [{ type: "local", path: "./node_modules/clickup-agent-cli" }]` |
184
184
  | Gemini CLI | `npm install -g clickup-agent-cli`, read skills via `clickup skill show` |
185
185
  | OpenAI Codex | `npm install -g clickup-agent-cli`, execute commands via bash |
186
186
  | Custom agents | `clickup skill list` for discovery, `clickup schema` for field info |
187
187
 
188
+ ### Bootstrap From Any Agent
189
+
190
+ Any agent that can run shell commands can set up and use the CLI in five steps, no plugin system required:
191
+
192
+ ```bash
193
+ # 1. Install
194
+ npm install -g clickup-agent-cli
195
+
196
+ # 2. Authenticate non-interactively (env var, or --token-file / --token per call)
197
+ export CLICKUP_API_TOKEN=pk_your_token
198
+
199
+ # 3. Verify auth and workspace
200
+ clickup config validate
201
+
202
+ # 4. Discover capabilities: the root skill indexes everything
203
+ clickup skill show clickup # start here (~150 tokens)
204
+ clickup skill list # all 25 skills
205
+ clickup skill show clickup-tasks # per-resource command reference
206
+
207
+ # 5. Discover exact fields before calling a command
208
+ clickup schema task.create
209
+ ```
210
+
188
211
  ### Agent-Friendly Design
189
212
 
190
213
  - JSON is the default output when stdout is not a TTY
@@ -199,10 +222,10 @@ This creates `/marketing-weekly` alongside the built-in `/clickup:*` skills.
199
222
 
200
223
  ```bash
201
224
  # Discover what's available
202
- clickup schema tasks
225
+ clickup schema task
203
226
 
204
227
  # Check what fields task create needs
205
- clickup schema tasks.create --format json
228
+ clickup schema task.create --format json
206
229
 
207
230
  # Create a task (JSON output automatic in non-TTY)
208
231
  clickup task create --list-id 998877 --name "Review PR" --priority 2
package/dist/clickup.js CHANGED
@@ -1545,8 +1545,9 @@ function registerFolderCommands(program, getClient) {
1545
1545
  }
1546
1546
 
1547
1547
  // src/dates.ts
1548
- var RELATIVE_OFFSET_RE = /^([+-]\d+)([dwmh])$/;
1548
+ var RELATIVE_OFFSET_RE = /^([+-]?\d+)([dwmh])$/;
1549
1549
  var UNIX_MS_RE = /^\d{13,}$/;
1550
+ var UNIX_SECONDS_RE = /^\d{10}$/;
1550
1551
  var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
1551
1552
  var ISO_DATETIME_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/;
1552
1553
  var DAY_NAMES = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
@@ -1556,6 +1557,9 @@ function parseDate(input) {
1556
1557
  if (UNIX_MS_RE.test(raw)) {
1557
1558
  return parseInt(raw, 10);
1558
1559
  }
1560
+ if (UNIX_SECONDS_RE.test(raw)) {
1561
+ return parseInt(raw, 10) * 1e3;
1562
+ }
1559
1563
  const now = /* @__PURE__ */ new Date();
1560
1564
  switch (lower) {
1561
1565
  case "today": {
@@ -1579,17 +1583,15 @@ function parseDate(input) {
1579
1583
  const ms = unitToMs(unit, amount);
1580
1584
  return now.getTime() + ms;
1581
1585
  }
1582
- if (lower.startsWith("next ")) {
1583
- const dayName = lower.slice(5);
1584
- const dayIndex = DAY_NAMES.indexOf(dayName);
1585
- if (dayIndex !== -1) {
1586
- const today = now.getDay();
1587
- let daysAhead = dayIndex - today;
1588
- if (daysAhead <= 0) daysAhead += 7;
1589
- const target = startOfDay(now);
1590
- target.setDate(target.getDate() + daysAhead);
1591
- return target.getTime();
1592
- }
1586
+ const dayName = lower.startsWith("next ") ? lower.slice(5) : lower;
1587
+ const dayIndex = DAY_NAMES.indexOf(dayName);
1588
+ if (dayIndex !== -1) {
1589
+ const today = now.getDay();
1590
+ let daysAhead = dayIndex - today;
1591
+ if (daysAhead <= 0) daysAhead += 7;
1592
+ const target = startOfDay(now);
1593
+ target.setDate(target.getDate() + daysAhead);
1594
+ return target.getTime();
1593
1595
  }
1594
1596
  if (ISO_DATE_RE.test(raw)) {
1595
1597
  const d = /* @__PURE__ */ new Date(raw + "T00:00:00");
@@ -1641,7 +1643,7 @@ function parseDateStrict(value, flag) {
1641
1643
  try {
1642
1644
  return parseDate(value);
1643
1645
  } catch {
1644
- fail(`${flag} must be a date (ISO 8601, relative like +3d, or Unix ms), got "${value}"`);
1646
+ fail(`${flag} must be a date (ISO 8601, relative like 3d or friday, or a Unix timestamp), got "${value}"`);
1645
1647
  }
1646
1648
  }
1647
1649
  function parseBoolStrict(value, flag) {
@@ -3091,7 +3093,7 @@ function registerGoalCommands(program, getClient) {
3091
3093
  if (!workspaceId) return;
3092
3094
  const client = getClient();
3093
3095
  const body = { name: opts.name };
3094
- if (opts.dueDate !== void 0) body["due_date"] = opts.dueDate;
3096
+ if (opts.dueDate !== void 0) body["due_date"] = parseDateStrict(opts.dueDate, "--due-date");
3095
3097
  if (opts.description !== void 0) body["description"] = opts.description;
3096
3098
  if (opts.multipleOwners) body["multiple_owners"] = true;
3097
3099
  if (opts.owner.length) body["owners"] = opts.owner.map((id) => parseIntStrict(id, "--owner"));
@@ -3104,7 +3106,7 @@ function registerGoalCommands(program, getClient) {
3104
3106
  const client = getClient();
3105
3107
  const body = {};
3106
3108
  if (opts.name !== void 0) body["name"] = opts.name;
3107
- if (opts.dueDate !== void 0) body["due_date"] = opts.dueDate;
3109
+ if (opts.dueDate !== void 0) body["due_date"] = parseDateStrict(opts.dueDate, "--due-date");
3108
3110
  if (opts.description !== void 0) body["description"] = opts.description;
3109
3111
  if (opts.color !== void 0) body["color"] = opts.color;
3110
3112
  await client.put(`/goal/${goalId}`, body);
@@ -4533,13 +4535,14 @@ function registerSkillCommands(program) {
4533
4535
  const outputOpts = getOutputOptions(program);
4534
4536
  const format = outputOpts.format ?? (process.stdout.isTTY ? "table" : "json");
4535
4537
  if (format === "json") {
4536
- const { frontmatter } = parseFrontmatter(result.content);
4538
+ const { frontmatter, body } = parseFrontmatter(result.content);
4537
4539
  const output = {
4538
4540
  name: frontmatter["name"] || name,
4539
4541
  description: frontmatter["description"] || "",
4540
4542
  type: classifySkill(frontmatter),
4541
4543
  path: result.skillDir,
4542
- frontmatter
4544
+ frontmatter,
4545
+ content: body
4543
4546
  };
4544
4547
  process.stdout.write(JSON.stringify(output, null, 2) + "\n");
4545
4548
  return;
@@ -4626,7 +4629,7 @@ function registerChatCommands(program, getClient) {
4626
4629
  }
4627
4630
 
4628
4631
  // src/cli.ts
4629
- var VERSION = "0.4.0";
4632
+ var VERSION = "0.4.2";
4630
4633
  function createProgram() {
4631
4634
  const program = new Command();
4632
4635
  program.name("clickup").description("ClickUp CLI - Manage ClickUp workspaces from the terminal").version(VERSION).option("--token <token>", "API token").option("--token-file <path>", "Read API token from this file path").option("--profile <name>", "Profile to use (key, workspace name, or nickname)").option("--workspace-id <id>", "Workspace ID").addOption(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clickup-agent-cli",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "CLI covering the entire ClickUp API v2 surface",
5
5
  "type": "module",
6
6
  "bin": {
@@ -27,6 +27,13 @@ clickup schema <resource>.<action> # Show required/optional fields
27
27
  clickup <resource> <action> --help # Full help text
28
28
  ```
29
29
 
30
+ Agents without a skill-loading system (any platform other than Claude Code) can read every skill in this table directly from the CLI:
31
+
32
+ ```bash
33
+ clickup skill list # All available skills
34
+ clickup skill show <name> # Print a skill's full contents (e.g. clickup-tasks)
35
+ ```
36
+
30
37
  ## Sub-Skills (load when needed)
31
38
 
32
39
  | Skill | What it covers |
@@ -120,6 +120,6 @@ These all work with this recipe:
120
120
  ## Tips
121
121
 
122
122
  - Combine multiple searches if a single query can't capture everything
123
- - Use `clickup schema tasks.search` to discover available filter flags
123
+ - Use `clickup schema task.search` to discover available filter flags
124
124
  - For complex comparisons, run separate searches and merge the results
125
125
  - If the user asks for something the CLI can't filter directly, fetch a broader set and filter in post-processing
@@ -76,8 +76,8 @@ For a task template result, set assignees, dates, and custom fields:
76
76
  # Assign team members
77
77
  clickup task update "$TASK_ID" --assignee-add <user-id>
78
78
 
79
- # Set start and due dates (Unix milliseconds)
80
- clickup task update "$TASK_ID" --start-date <ms> --due-date <ms>
79
+ # Set start and due dates (Unix ms, ISO 8601, or relative like "3d", "friday")
80
+ clickup task update "$TASK_ID" --start-date <date> --due-date <date>
81
81
 
82
82
  # Fill in custom fields
83
83
  clickup field set --task-id "$TASK_ID" --field-id <field-id> --value "<value>"
@@ -45,7 +45,7 @@ clickup task update <task-id> --priority 2 --assignee-add 112233 --status "to do
45
45
  clickup tag add --task-id <task-id> --name "bug"
46
46
 
47
47
  # Set a due date if time-sensitive
48
- clickup task update <task-id> --due-date <timestamp-ms>
48
+ clickup task update <task-id> --due-date <date> # Unix ms, ISO 8601, or relative like "3d", "friday"
49
49
  ```
50
50
 
51
51
  ### Step 4: Route to appropriate lists (optional)
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: clickup-tasks
3
3
  description: Creates, updates, searches, and manages ClickUp tasks, subtasks, checklists, dependencies, and attachments. Use when the user asks about tasks, wants to create or find work items, manage subtasks, add checklists, set dependencies, or upload files to tasks.
4
- allowed-tools: Bash(clickup task *), Bash(clickup checklist *), Bash(clickup dependency *), Bash(clickup relation *), Bash(clickup attachment *), Bash(clickup schema tasks*), Bash(clickup schema checklist*)
4
+ allowed-tools: Bash(clickup task *), Bash(clickup checklist *), Bash(clickup dependency *), Bash(clickup relation *), Bash(clickup attachment *), Bash(clickup schema task*), Bash(clickup schema checklist*)
5
5
  ---
6
6
 
7
7
  # ClickUp Tasks
@@ -47,6 +47,8 @@ clickup task update <task-id> [--name <name>] [--description <text>]
47
47
 
48
48
  Priority accepts both integers (`1`-`4`) and strings (`urgent`, `high`, `normal`, `low`). Mapping: urgent=1, high=2, normal=3, low=4.
49
49
 
50
+ `--due-date` and `--start-date` accept Unix timestamps (ms or seconds), ISO 8601 dates (`2026-07-10`), or relative dates (`tomorrow`, `3d`, `friday`, `next monday`).
51
+
50
52
  ### Delete a task
51
53
  ```bash
52
54
  clickup task delete <task-id> --confirm
@@ -104,8 +106,12 @@ clickup relation remove --task-id <id> --links-to <id>
104
106
 
105
107
  ```bash
106
108
  clickup attachment upload --task-id <id> --file <path> [--filename <name>]
109
+ clickup attachment list --task-id <id>
110
+ clickup attachment download --task-id <id> --attachment-id <id> [--output <path>] [--force]
107
111
  ```
108
112
 
113
+ `attachment download` refuses to overwrite an existing file unless `--force` is passed.
114
+
109
115
  ## Common Patterns
110
116
 
111
117
  ```bash
@@ -132,7 +138,7 @@ clickup chat send --channel-id <id> --message "$(clickup task list --list-id <id
132
138
  ## Discovery
133
139
 
134
140
  ```bash
135
- clickup schema tasks # List all task actions
136
- clickup schema tasks.create # Show create fields
137
- clickup schema tasks.list # Show list filter flags
141
+ clickup schema task # List all task actions
142
+ clickup schema task.create # Show create fields
143
+ clickup schema task.list # Show list filter flags
138
144
  ```