@krodak/clickup-cli 0.9.1 → 0.10.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/README.md +47 -22
- package/dist/index.js +81 -4
- package/package.json +1 -1
- package/skills/clickup-cli/SKILL.md +16 -8
package/README.md
CHANGED
|
@@ -98,7 +98,7 @@ When output is piped (no TTY), all commands output **Markdown** by default - opt
|
|
|
98
98
|
|
|
99
99
|
## Commands
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
25 commands total. All support `--help` for full flag details.
|
|
102
102
|
|
|
103
103
|
### `cu init`
|
|
104
104
|
|
|
@@ -206,18 +206,20 @@ cu update abc123 --priority high
|
|
|
206
206
|
cu update abc123 --due-date 2025-03-15
|
|
207
207
|
cu update abc123 --assignee 12345
|
|
208
208
|
cu update abc123 -n "New name" -s "done" --priority urgent
|
|
209
|
+
cu update abc123 --time-estimate 2h
|
|
209
210
|
cu update abc123 -s "in progress" --json
|
|
210
211
|
```
|
|
211
212
|
|
|
212
|
-
| Flag
|
|
213
|
-
|
|
|
214
|
-
| `-n, --name <text>`
|
|
215
|
-
| `-d, --description <text>`
|
|
216
|
-
| `-s, --status <status>`
|
|
217
|
-
| `--priority <level>`
|
|
218
|
-
| `--due-date <date>`
|
|
219
|
-
| `--
|
|
220
|
-
| `--
|
|
213
|
+
| Flag | Description |
|
|
214
|
+
| ---------------------------- | --------------------------------------------------------------------------- |
|
|
215
|
+
| `-n, --name <text>` | New task name |
|
|
216
|
+
| `-d, --description <text>` | New description (markdown supported) |
|
|
217
|
+
| `-s, --status <status>` | New status, supports fuzzy matching (e.g. `"prog"` matches `"in progress"`) |
|
|
218
|
+
| `--priority <level>` | Priority: `urgent`, `high`, `normal`, `low` (or 1-4) |
|
|
219
|
+
| `--due-date <date>` | Due date (`YYYY-MM-DD`) |
|
|
220
|
+
| `--time-estimate <duration>` | Time estimate (e.g. `"2h"`, `"30m"`, `"1h30m"`) |
|
|
221
|
+
| `--assignee <userId>` | Add assignee by numeric user ID |
|
|
222
|
+
| `--json` | Force JSON output even in terminal |
|
|
221
223
|
|
|
222
224
|
### `cu create`
|
|
223
225
|
|
|
@@ -229,21 +231,25 @@ cu create -n "Subtask name" -p <parentTaskId> # --list auto-detected
|
|
|
229
231
|
cu create -n "Task" -l <listId> -d "desc" -s "open"
|
|
230
232
|
cu create -n "Task" -l <listId> --priority high --due-date 2025-06-01
|
|
231
233
|
cu create -n "Task" -l <listId> --assignee 12345 --tags "bug,frontend"
|
|
234
|
+
cu create -n "Initiative" -l <listId> --custom-item-id 1
|
|
235
|
+
cu create -n "Task" -l <listId> --time-estimate 2h
|
|
232
236
|
cu create -n "Fix bug" -l <listId> --json
|
|
233
237
|
```
|
|
234
238
|
|
|
235
|
-
| Flag
|
|
236
|
-
|
|
|
237
|
-
| `-n, --name <name>`
|
|
238
|
-
| `-l, --list <listId>`
|
|
239
|
-
| `-p, --parent <taskId>`
|
|
240
|
-
| `-d, --description <text>`
|
|
241
|
-
| `-s, --status <status>`
|
|
242
|
-
| `--priority <level>`
|
|
243
|
-
| `--due-date <date>`
|
|
244
|
-
| `--
|
|
245
|
-
| `--
|
|
246
|
-
| `--
|
|
239
|
+
| Flag | Required | Description |
|
|
240
|
+
| ---------------------------- | ---------------- | ---------------------------------------------------- |
|
|
241
|
+
| `-n, --name <name>` | yes | Task name |
|
|
242
|
+
| `-l, --list <listId>` | if no `--parent` | Target list ID |
|
|
243
|
+
| `-p, --parent <taskId>` | no | Parent task (list auto-detected) |
|
|
244
|
+
| `-d, --description <text>` | no | Description (markdown) |
|
|
245
|
+
| `-s, --status <status>` | no | Initial status |
|
|
246
|
+
| `--priority <level>` | no | Priority: `urgent`, `high`, `normal`, `low` (or 1-4) |
|
|
247
|
+
| `--due-date <date>` | no | Due date (`YYYY-MM-DD`) |
|
|
248
|
+
| `--time-estimate <duration>` | no | Time estimate (e.g. `"2h"`, `"30m"`, `"1h30m"`) |
|
|
249
|
+
| `--assignee <userId>` | no | Assignee by numeric user ID |
|
|
250
|
+
| `--tags <tags>` | no | Comma-separated tag names |
|
|
251
|
+
| `--custom-item-id <id>` | no | Custom task type ID (for creating initiatives) |
|
|
252
|
+
| `--json` | no | Force JSON output even in terminal |
|
|
247
253
|
|
|
248
254
|
### `cu comment <id>`
|
|
249
255
|
|
|
@@ -368,6 +374,25 @@ cu assign abc123 --to me --json
|
|
|
368
374
|
| `--remove <userId>` | Remove assignee (user ID or `me`) |
|
|
369
375
|
| `--json` | Force JSON output |
|
|
370
376
|
|
|
377
|
+
### `cu depend <id>`
|
|
378
|
+
|
|
379
|
+
Add or remove task dependencies. Set a task as waiting on or blocking another task.
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
cu depend abc123 --on def456 # abc123 depends on (waits for) def456
|
|
383
|
+
cu depend abc123 --blocks def456 # abc123 blocks def456
|
|
384
|
+
cu depend abc123 --on def456 --remove # remove the dependency
|
|
385
|
+
cu depend abc123 --blocks def456 --remove
|
|
386
|
+
cu depend abc123 --on def456 --json
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
| Flag | Description |
|
|
390
|
+
| ------------------- | ------------------------------------------- |
|
|
391
|
+
| `--on <taskId>` | Task that this task depends on (waiting on) |
|
|
392
|
+
| `--blocks <taskId>` | Task that this task blocks |
|
|
393
|
+
| `--remove` | Remove the dependency instead of adding it |
|
|
394
|
+
| `--json` | Force JSON output |
|
|
395
|
+
|
|
371
396
|
### `cu auth`
|
|
372
397
|
|
|
373
398
|
Check authentication status. Validates your API token and shows your user info.
|
package/dist/index.js
CHANGED
|
@@ -223,6 +223,23 @@ var ClickUpClient = class {
|
|
|
223
223
|
async getViewTasks(viewId) {
|
|
224
224
|
return this.paginate((page) => `/view/${viewId}/task?page=${page}`);
|
|
225
225
|
}
|
|
226
|
+
async addDependency(taskId, opts) {
|
|
227
|
+
const body = {};
|
|
228
|
+
if (opts.dependsOn) body.depends_on = opts.dependsOn;
|
|
229
|
+
if (opts.dependencyOf) body.dependency_of = opts.dependencyOf;
|
|
230
|
+
await this.request(`/task/${taskId}/dependency`, {
|
|
231
|
+
method: "POST",
|
|
232
|
+
body: JSON.stringify(body)
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
async deleteDependency(taskId, opts) {
|
|
236
|
+
const params = new URLSearchParams();
|
|
237
|
+
if (opts.dependsOn) params.set("depends_on", opts.dependsOn);
|
|
238
|
+
if (opts.dependencyOf) params.set("dependency_of", opts.dependencyOf);
|
|
239
|
+
await this.request(`/task/${taskId}/dependency?${params.toString()}`, {
|
|
240
|
+
method: "DELETE"
|
|
241
|
+
});
|
|
242
|
+
}
|
|
226
243
|
};
|
|
227
244
|
|
|
228
245
|
// src/output.ts
|
|
@@ -680,6 +697,18 @@ function parseAssigneeId(value) {
|
|
|
680
697
|
if (!Number.isInteger(id)) throw new Error("Assignee must be a numeric user ID");
|
|
681
698
|
return id;
|
|
682
699
|
}
|
|
700
|
+
function parseTimeEstimate(value) {
|
|
701
|
+
const pattern = /^(?:(\d+)h)?(?:(\d+)m)?$/i;
|
|
702
|
+
const match = value.match(pattern);
|
|
703
|
+
if (match && (match[1] || match[2])) {
|
|
704
|
+
const hours = Number(match[1] ?? 0);
|
|
705
|
+
const minutes = Number(match[2] ?? 0);
|
|
706
|
+
return (hours * 60 + minutes) * 60 * 1e3;
|
|
707
|
+
}
|
|
708
|
+
const ms = Number(value);
|
|
709
|
+
if (Number.isFinite(ms) && ms > 0) return ms;
|
|
710
|
+
throw new Error('Time estimate must be a duration (e.g. "2h", "30m", "1h30m") or milliseconds');
|
|
711
|
+
}
|
|
683
712
|
function buildUpdatePayload(opts) {
|
|
684
713
|
const payload = {};
|
|
685
714
|
if (opts.name !== void 0) payload.name = opts.name;
|
|
@@ -693,10 +722,13 @@ function buildUpdatePayload(opts) {
|
|
|
693
722
|
if (opts.assignee !== void 0) {
|
|
694
723
|
payload.assignees = { add: [parseAssigneeId(opts.assignee)] };
|
|
695
724
|
}
|
|
725
|
+
if (opts.timeEstimate !== void 0) {
|
|
726
|
+
payload.time_estimate = parseTimeEstimate(opts.timeEstimate);
|
|
727
|
+
}
|
|
696
728
|
return payload;
|
|
697
729
|
}
|
|
698
730
|
function hasUpdateFields(options) {
|
|
699
|
-
return options.name !== void 0 || options.description !== void 0 || options.status !== void 0 || options.priority !== void 0 || options.due_date !== void 0 || options.assignees !== void 0;
|
|
731
|
+
return options.name !== void 0 || options.description !== void 0 || options.status !== void 0 || options.priority !== void 0 || options.due_date !== void 0 || options.time_estimate !== void 0 || options.assignees !== void 0;
|
|
700
732
|
}
|
|
701
733
|
async function resolveStatus(client, taskId, statusInput) {
|
|
702
734
|
const task = await client.getTask(taskId);
|
|
@@ -716,7 +748,7 @@ async function resolveStatus(client, taskId, statusInput) {
|
|
|
716
748
|
async function updateTask(config, taskId, options) {
|
|
717
749
|
if (!hasUpdateFields(options))
|
|
718
750
|
throw new Error(
|
|
719
|
-
"Provide at least one of: --name, --description, --status, --priority, --due-date, --assignee"
|
|
751
|
+
"Provide at least one of: --name, --description, --status, --priority, --due-date, --time-estimate, --assignee"
|
|
720
752
|
);
|
|
721
753
|
const client = new ClickUpClient(config);
|
|
722
754
|
if (options.status !== void 0) {
|
|
@@ -756,6 +788,15 @@ async function createTask(config, options) {
|
|
|
756
788
|
if (options.tags !== void 0) {
|
|
757
789
|
payload.tags = options.tags.split(",").map((t) => t.trim());
|
|
758
790
|
}
|
|
791
|
+
if (options.customItemId !== void 0) {
|
|
792
|
+
const id = Number(options.customItemId);
|
|
793
|
+
if (!Number.isInteger(id) || id < 0)
|
|
794
|
+
throw new Error("Custom item ID must be a non-negative integer");
|
|
795
|
+
payload.custom_item_id = id;
|
|
796
|
+
}
|
|
797
|
+
if (options.timeEstimate !== void 0) {
|
|
798
|
+
payload.time_estimate = parseTimeEstimate(options.timeEstimate);
|
|
799
|
+
}
|
|
759
800
|
const task = await client.createTask(listId, payload);
|
|
760
801
|
return { id: task.id, name: task.name, url: task.url };
|
|
761
802
|
}
|
|
@@ -1979,6 +2020,31 @@ async function searchTasks(config, query, opts = {}) {
|
|
|
1979
2020
|
return matched.map(summarize);
|
|
1980
2021
|
}
|
|
1981
2022
|
|
|
2023
|
+
// src/commands/depend.ts
|
|
2024
|
+
async function manageDependency(config, taskId, opts) {
|
|
2025
|
+
if (!opts.on && !opts.blocks) {
|
|
2026
|
+
throw new Error("Provide --on <taskId> or --blocks <taskId>");
|
|
2027
|
+
}
|
|
2028
|
+
if (opts.on && opts.blocks) {
|
|
2029
|
+
throw new Error("Provide only one of --on or --blocks per invocation");
|
|
2030
|
+
}
|
|
2031
|
+
const client = new ClickUpClient(config);
|
|
2032
|
+
if (opts.remove) {
|
|
2033
|
+
await client.deleteDependency(taskId, {
|
|
2034
|
+
dependsOn: opts.on,
|
|
2035
|
+
dependencyOf: opts.blocks
|
|
2036
|
+
});
|
|
2037
|
+
if (opts.on) return `Removed dependency: ${taskId} no longer depends on ${opts.on}`;
|
|
2038
|
+
return `Removed dependency: ${taskId} no longer blocks ${opts.blocks}`;
|
|
2039
|
+
}
|
|
2040
|
+
await client.addDependency(taskId, {
|
|
2041
|
+
dependsOn: opts.on,
|
|
2042
|
+
dependencyOf: opts.blocks
|
|
2043
|
+
});
|
|
2044
|
+
if (opts.on) return `Added dependency: ${taskId} depends on ${opts.on}`;
|
|
2045
|
+
return `Added dependency: ${taskId} blocks ${opts.blocks}`;
|
|
2046
|
+
}
|
|
2047
|
+
|
|
1982
2048
|
// src/index.ts
|
|
1983
2049
|
var require2 = createRequire(import.meta.url);
|
|
1984
2050
|
var { version } = require2("../package.json");
|
|
@@ -2050,7 +2116,7 @@ program.command("task <taskId>").description("Get task details").option("--json"
|
|
|
2050
2116
|
}
|
|
2051
2117
|
})
|
|
2052
2118
|
);
|
|
2053
|
-
program.command("update <taskId>").description("Update a task").option("-n, --name <text>", "New task name").option("-d, --description <text>", "New description (markdown supported)").option("-s, --status <status>", 'New status (e.g. "in progress", "done")').option("--priority <level>", "Priority: urgent, high, normal, low (or 1-4)").option("--due-date <date>", "Due date (YYYY-MM-DD)").option("--assignee <userId>", "Add assignee by user ID").option("--json", "Force JSON output even in terminal").action(
|
|
2119
|
+
program.command("update <taskId>").description("Update a task").option("-n, --name <text>", "New task name").option("-d, --description <text>", "New description (markdown supported)").option("-s, --status <status>", 'New status (e.g. "in progress", "done")').option("--priority <level>", "Priority: urgent, high, normal, low (or 1-4)").option("--due-date <date>", "Due date (YYYY-MM-DD)").option("--time-estimate <duration>", 'Time estimate (e.g. "2h", "30m", "1h30m")').option("--assignee <userId>", "Add assignee by user ID").option("--json", "Force JSON output even in terminal").action(
|
|
2054
2120
|
wrapAction(async (taskId, opts) => {
|
|
2055
2121
|
const config = loadConfig();
|
|
2056
2122
|
const payload = buildUpdatePayload(opts);
|
|
@@ -2062,7 +2128,7 @@ program.command("update <taskId>").description("Update a task").option("-n, --na
|
|
|
2062
2128
|
}
|
|
2063
2129
|
})
|
|
2064
2130
|
);
|
|
2065
|
-
program.command("create").description("Create a new task").option("-l, --list <listId>", "Target list ID (auto-detected from --parent if omitted)").requiredOption("-n, --name <name>", "Task name").option("-d, --description <text>", "Task description").option("-p, --parent <taskId>", "Parent task ID (list auto-detected from parent)").option("-s, --status <status>", "Initial status").option("--priority <level>", "Priority: urgent, high, normal, low (or 1-4)").option("--due-date <date>", "Due date (YYYY-MM-DD)").option("--assignee <userId>", "Assignee user ID").option("--tags <tags>", "Comma-separated tag names").option("--json", "Force JSON output even in terminal").action(
|
|
2131
|
+
program.command("create").description("Create a new task").option("-l, --list <listId>", "Target list ID (auto-detected from --parent if omitted)").requiredOption("-n, --name <name>", "Task name").option("-d, --description <text>", "Task description").option("-p, --parent <taskId>", "Parent task ID (list auto-detected from parent)").option("-s, --status <status>", "Initial status").option("--priority <level>", "Priority: urgent, high, normal, low (or 1-4)").option("--due-date <date>", "Due date (YYYY-MM-DD)").option("--assignee <userId>", "Assignee user ID").option("--tags <tags>", "Comma-separated tag names").option("--custom-item-id <id>", "Custom task type ID (use to create initiatives)").option("--time-estimate <duration>", 'Time estimate (e.g. "2h", "30m", "1h30m")').option("--json", "Force JSON output even in terminal").action(
|
|
2066
2132
|
wrapAction(async (opts) => {
|
|
2067
2133
|
const config = loadConfig();
|
|
2068
2134
|
const result = await createTask(config, opts);
|
|
@@ -2190,6 +2256,17 @@ program.command("assign <taskId>").description("Assign or unassign users from a
|
|
|
2190
2256
|
}
|
|
2191
2257
|
})
|
|
2192
2258
|
);
|
|
2259
|
+
program.command("depend <taskId>").description("Add or remove task dependencies").option("--on <taskId>", "Task that this task depends on (waiting on)").option("--blocks <taskId>", "Task that this task blocks").option("--remove", "Remove the dependency instead of adding it").option("--json", "Force JSON output even in terminal").action(
|
|
2260
|
+
wrapAction(async (taskId, opts) => {
|
|
2261
|
+
const config = loadConfig();
|
|
2262
|
+
const message = await manageDependency(config, taskId, opts);
|
|
2263
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
2264
|
+
console.log(JSON.stringify({ taskId, ...opts, message }, null, 2));
|
|
2265
|
+
} else {
|
|
2266
|
+
console.log(message);
|
|
2267
|
+
}
|
|
2268
|
+
})
|
|
2269
|
+
);
|
|
2193
2270
|
var configCmd = program.command("config").description("Manage CLI configuration");
|
|
2194
2271
|
configCmd.command("get <key>").description("Print a config value").action(
|
|
2195
2272
|
wrapAction(async (key) => {
|
package/package.json
CHANGED
|
@@ -56,14 +56,15 @@ All commands support `--help` for full flag details.
|
|
|
56
56
|
|
|
57
57
|
### Write
|
|
58
58
|
|
|
59
|
-
| Command
|
|
60
|
-
|
|
|
61
|
-
| `cu update <id> [-n name] [-d desc] [-s status] [--priority p] [--due-date d] [--assignee id] [--json]`
|
|
62
|
-
| `cu create -n name [-l listId] [-p parentId] [-d desc] [-s status] [--priority p] [--due-date d] [--assignee id] [--tags t] [--json]` | Create task (list auto-detected from parent) |
|
|
63
|
-
| `cu comment <id> -m text`
|
|
64
|
-
| `cu assign <id> [--to userId\|me] [--remove userId\|me] [--json]`
|
|
65
|
-
| `cu
|
|
66
|
-
| `cu
|
|
59
|
+
| Command | What it does |
|
|
60
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------- |
|
|
61
|
+
| `cu update <id> [-n name] [-d desc] [-s status] [--priority p] [--due-date d] [--time-estimate t] [--assignee id] [--json]` | Update task fields |
|
|
62
|
+
| `cu create -n name [-l listId] [-p parentId] [-d desc] [-s status] [--priority p] [--due-date d] [--time-estimate t] [--assignee id] [--tags t] [--custom-item-id n] [--json]` | Create task (list auto-detected from parent) |
|
|
63
|
+
| `cu comment <id> -m text` | Post comment on task |
|
|
64
|
+
| `cu assign <id> [--to userId\|me] [--remove userId\|me] [--json]` | Assign/unassign users |
|
|
65
|
+
| `cu depend <id> [--on taskId] [--blocks taskId] [--remove] [--json]` | Add/remove task dependencies |
|
|
66
|
+
| `cu config get <key>` / `cu config set <key> <value>` / `cu config path` | Manage CLI config |
|
|
67
|
+
| `cu completion <shell>` | Shell completions (bash/zsh/fish) |
|
|
67
68
|
|
|
68
69
|
## Quick Reference
|
|
69
70
|
|
|
@@ -77,6 +78,9 @@ All commands support `--help` for full flag details.
|
|
|
77
78
|
| `--due-date` | `YYYY-MM-DD` format |
|
|
78
79
|
| `--assignee` | Numeric user ID (find via `cu task <id> --json`) |
|
|
79
80
|
| `--tags` | Comma-separated (e.g. `--tags "bug,frontend"`) |
|
|
81
|
+
| `--time-estimate` | Duration format: `"2h"`, `"30m"`, `"1h30m"`, or raw milliseconds |
|
|
82
|
+
| `--custom-item-id` | Custom task type ID (e.g. `1` for initiative) |
|
|
83
|
+
| `--on` / `--blocks` | Task dependency direction (used with `cu depend`) |
|
|
80
84
|
| `--space` | Partial name match or exact ID |
|
|
81
85
|
| `--name` | Partial match, case-insensitive |
|
|
82
86
|
| `--include-closed` | Include closed/done tasks (on `subtasks` and `assigned`) |
|
|
@@ -121,10 +125,14 @@ cu inbox --days 7 # recently updated
|
|
|
121
125
|
```bash
|
|
122
126
|
cu update abc123def -s "done"
|
|
123
127
|
cu update abc123def --priority high --due-date 2025-03-15
|
|
128
|
+
cu update abc123def --time-estimate 2h
|
|
124
129
|
cu create -n "Fix the thing" -p abc123def
|
|
125
130
|
cu create -n "Fix bug" -l <listId> --priority urgent --tags "bug,frontend"
|
|
131
|
+
cu create -n "Q3 Roadmap" -l <listId> --custom-item-id 1 # create initiative
|
|
126
132
|
cu comment abc123def -m "Completed in PR #42"
|
|
127
133
|
cu assign abc123def --to me
|
|
134
|
+
cu depend task3 --on task2 # task3 waits for task2
|
|
135
|
+
cu depend task1 --blocks task2 # task1 blocks task2
|
|
128
136
|
```
|
|
129
137
|
|
|
130
138
|
### Discover workspace structure
|