@krodak/clickup-cli 0.16.0 → 0.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 +2 -2
- package/README.md +6 -4
- package/dist/index.js +287 -203
- package/package.json +3 -2
- package/skills/clickup-cli/SKILL.md +10 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clickup-cli",
|
|
3
|
-
"description": "ClickUp CLI skills for managing tasks, sprints, comments, checklists, custom fields, tags, and time tracking via the cu command",
|
|
4
|
-
"version": "0.
|
|
3
|
+
"description": "ClickUp CLI skills for managing tasks, sprints, comments, checklists, custom fields, tags, and time tracking via the cu/cup command",
|
|
4
|
+
"version": "0.18.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Krzysztof Rodak"
|
|
7
7
|
},
|
package/README.md
CHANGED
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
npm install -g @krodak/clickup-cli && cu init
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
+
Both `cu` and `cup` are installed as binaries. Use `cup` if `cu` conflicts with the Unix [cu(1)](<https://en.wikipedia.org/wiki/Cu_(Unix_utility)>) utility on your system. All examples below use `cu` but `cup` works identically.
|
|
15
|
+
|
|
14
16
|
## Talk to your agent
|
|
15
17
|
|
|
16
18
|
Install the CLI, add the skill file to your agent, and it works with ClickUp. No API knowledge needed.
|
|
@@ -246,10 +248,10 @@ Status: :white_check_mark: implemented | :construction: planned | :no_entry_sign
|
|
|
246
248
|
|
|
247
249
|
### Attachments
|
|
248
250
|
|
|
249
|
-
| Feature | Command
|
|
250
|
-
| ---------------- |
|
|
251
|
-
| Upload file | `cu attach <id> <file>`
|
|
252
|
-
| List attachments |
|
|
251
|
+
| Feature | Command | Status |
|
|
252
|
+
| ---------------- | ------------------------- | ------------------ |
|
|
253
|
+
| Upload file | `cu attach <id> <file>` | :white_check_mark: |
|
|
254
|
+
| List attachments | shown inline in `cu task` | :white_check_mark: |
|
|
253
255
|
|
|
254
256
|
### :no_entry_sign: Won't add
|
|
255
257
|
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
+
import { basename } from "path";
|
|
4
5
|
import { Command } from "commander";
|
|
5
6
|
import { createRequire } from "module";
|
|
6
7
|
|
|
@@ -314,6 +315,37 @@ var ClickUpClient = class {
|
|
|
314
315
|
method: "DELETE"
|
|
315
316
|
});
|
|
316
317
|
}
|
|
318
|
+
async createTaskAttachment(taskId, filePath) {
|
|
319
|
+
const { readFile } = await import("fs/promises");
|
|
320
|
+
const { basename: basename2 } = await import("path");
|
|
321
|
+
const fileBuffer = await readFile(filePath);
|
|
322
|
+
const fileName = basename2(filePath);
|
|
323
|
+
const formData = new FormData();
|
|
324
|
+
formData.append("attachment", new Blob([fileBuffer]), fileName);
|
|
325
|
+
const res = await fetch(`${BASE_URL}/task/${taskId}/attachment`, {
|
|
326
|
+
method: "POST",
|
|
327
|
+
headers: { Authorization: this.apiToken },
|
|
328
|
+
body: formData,
|
|
329
|
+
signal: AbortSignal.timeout(6e4)
|
|
330
|
+
});
|
|
331
|
+
if (!res.ok) {
|
|
332
|
+
let msg;
|
|
333
|
+
try {
|
|
334
|
+
const data2 = await res.json();
|
|
335
|
+
msg = data2.err ?? `HTTP ${res.status}`;
|
|
336
|
+
} catch {
|
|
337
|
+
msg = `HTTP ${res.status}`;
|
|
338
|
+
}
|
|
339
|
+
throw new Error(`ClickUp API error ${res.status}: ${msg}`);
|
|
340
|
+
}
|
|
341
|
+
let data;
|
|
342
|
+
try {
|
|
343
|
+
data = await res.json();
|
|
344
|
+
} catch {
|
|
345
|
+
throw new Error(`ClickUp API error ${res.status}: response was not valid JSON`);
|
|
346
|
+
}
|
|
347
|
+
return data;
|
|
348
|
+
}
|
|
317
349
|
};
|
|
318
350
|
|
|
319
351
|
// src/config.ts
|
|
@@ -546,6 +578,12 @@ function formatTaskDetailMarkdown(task) {
|
|
|
546
578
|
lines.push("");
|
|
547
579
|
}
|
|
548
580
|
}
|
|
581
|
+
if (task.attachments?.length) {
|
|
582
|
+
lines.push("", "## Attachments", "");
|
|
583
|
+
for (const att of task.attachments) {
|
|
584
|
+
lines.push(`- [${att.title}](${att.url})`);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
549
587
|
return lines.join("\n");
|
|
550
588
|
}
|
|
551
589
|
function formatUpdateConfirmation(id, name) {
|
|
@@ -692,6 +730,13 @@ function formatTaskDetail(task) {
|
|
|
692
730
|
}
|
|
693
731
|
}
|
|
694
732
|
}
|
|
733
|
+
if (task.attachments?.length) {
|
|
734
|
+
lines.push("");
|
|
735
|
+
lines.push(chalk2.bold("Attachments"));
|
|
736
|
+
for (const att of task.attachments) {
|
|
737
|
+
lines.push(` ${att.title} ${chalk2.dim(att.url)}`);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
695
740
|
if (task.text_content?.trim()) {
|
|
696
741
|
lines.push("");
|
|
697
742
|
lines.push(descriptionPreview(task.text_content));
|
|
@@ -1814,8 +1859,8 @@ ${commentsMd}`);
|
|
|
1814
1859
|
}
|
|
1815
1860
|
|
|
1816
1861
|
// src/commands/completion.ts
|
|
1817
|
-
function bashCompletion() {
|
|
1818
|
-
return `
|
|
1862
|
+
function bashCompletion(name) {
|
|
1863
|
+
return `_${name}_completions() {
|
|
1819
1864
|
local cur prev words cword
|
|
1820
1865
|
|
|
1821
1866
|
if type _init_completion &>/dev/null; then
|
|
@@ -1827,7 +1872,7 @@ function bashCompletion() {
|
|
|
1827
1872
|
cword=$COMP_CWORD
|
|
1828
1873
|
fi
|
|
1829
1874
|
|
|
1830
|
-
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 move field delete tag checklist time config completion"
|
|
1875
|
+
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 config completion"
|
|
1831
1876
|
|
|
1832
1877
|
if [[ $cword -eq 1 ]]; then
|
|
1833
1878
|
COMPREPLY=($(compgen -W "$commands --help --version" -- "$cur"))
|
|
@@ -1948,6 +1993,9 @@ function bashCompletion() {
|
|
|
1948
1993
|
link)
|
|
1949
1994
|
COMPREPLY=($(compgen -W "--remove --json" -- "$cur"))
|
|
1950
1995
|
;;
|
|
1996
|
+
attach)
|
|
1997
|
+
COMPREPLY=($(compgen -f -- "$cur"))
|
|
1998
|
+
;;
|
|
1951
1999
|
config)
|
|
1952
2000
|
if [[ $cword -eq 2 ]]; then
|
|
1953
2001
|
COMPREPLY=($(compgen -W "get set path" -- "$cur"))
|
|
@@ -1965,16 +2013,16 @@ function bashCompletion() {
|
|
|
1965
2013
|
;;
|
|
1966
2014
|
esac
|
|
1967
2015
|
}
|
|
1968
|
-
complete -F
|
|
2016
|
+
complete -F _${name}_completions ${name}
|
|
1969
2017
|
`;
|
|
1970
2018
|
}
|
|
1971
|
-
function zshCompletion() {
|
|
1972
|
-
return `#compdef
|
|
2019
|
+
function zshCompletion(name) {
|
|
2020
|
+
return `#compdef ${name}
|
|
1973
2021
|
|
|
1974
|
-
|
|
2022
|
+
_${name}() {
|
|
1975
2023
|
local -a commands
|
|
1976
2024
|
commands=(
|
|
1977
|
-
'init:Set up
|
|
2025
|
+
'init:Set up ${name} for the first time'
|
|
1978
2026
|
'auth:Validate API token and show current user'
|
|
1979
2027
|
'tasks:List tasks assigned to me'
|
|
1980
2028
|
'task:Get task details'
|
|
@@ -2007,6 +2055,7 @@ _cu() {
|
|
|
2007
2055
|
'replies:List threaded replies on a comment'
|
|
2008
2056
|
'reply:Reply to a comment'
|
|
2009
2057
|
'link:Add or remove a link between two tasks'
|
|
2058
|
+
'attach:Upload a file attachment to a task'
|
|
2010
2059
|
'config:Manage CLI configuration'
|
|
2011
2060
|
'completion:Output shell completion script'
|
|
2012
2061
|
)
|
|
@@ -2320,6 +2369,12 @@ _cu() {
|
|
|
2320
2369
|
'--remove[Remove the link instead of adding it]' \\
|
|
2321
2370
|
'--json[Force JSON output]'
|
|
2322
2371
|
;;
|
|
2372
|
+
attach)
|
|
2373
|
+
_arguments \\
|
|
2374
|
+
'1:task_id:' \\
|
|
2375
|
+
'2:file_path:_files' \\
|
|
2376
|
+
'--json[Force JSON output]'
|
|
2377
|
+
;;
|
|
2323
2378
|
config)
|
|
2324
2379
|
local -a config_cmds
|
|
2325
2380
|
config_cmds=(
|
|
@@ -2351,211 +2406,215 @@ _cu() {
|
|
|
2351
2406
|
esac
|
|
2352
2407
|
}
|
|
2353
2408
|
|
|
2354
|
-
|
|
2409
|
+
_${name}
|
|
2355
2410
|
`;
|
|
2356
2411
|
}
|
|
2357
|
-
function fishCompletion() {
|
|
2358
|
-
return `complete -c
|
|
2359
|
-
|
|
2360
|
-
complete -c
|
|
2361
|
-
complete -c
|
|
2362
|
-
|
|
2363
|
-
complete -c
|
|
2364
|
-
complete -c
|
|
2365
|
-
complete -c
|
|
2366
|
-
complete -c
|
|
2367
|
-
complete -c
|
|
2368
|
-
complete -c
|
|
2369
|
-
complete -c
|
|
2370
|
-
complete -c
|
|
2371
|
-
complete -c
|
|
2372
|
-
complete -c
|
|
2373
|
-
complete -c
|
|
2374
|
-
complete -c
|
|
2375
|
-
complete -c
|
|
2376
|
-
complete -c
|
|
2377
|
-
complete -c
|
|
2378
|
-
complete -c
|
|
2379
|
-
complete -c
|
|
2380
|
-
complete -c
|
|
2381
|
-
complete -c
|
|
2382
|
-
complete -c
|
|
2383
|
-
complete -c
|
|
2384
|
-
complete -c
|
|
2385
|
-
complete -c
|
|
2386
|
-
complete -c
|
|
2387
|
-
complete -c
|
|
2388
|
-
complete -c
|
|
2389
|
-
complete -c
|
|
2390
|
-
complete -c
|
|
2391
|
-
complete -c
|
|
2392
|
-
complete -c
|
|
2393
|
-
complete -c
|
|
2394
|
-
complete -c
|
|
2395
|
-
complete -c
|
|
2396
|
-
complete -c
|
|
2397
|
-
complete -c
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
complete -c
|
|
2403
|
-
complete -c
|
|
2404
|
-
complete -c
|
|
2405
|
-
complete -c
|
|
2406
|
-
complete -c
|
|
2407
|
-
complete -c
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
complete -c
|
|
2413
|
-
complete -c
|
|
2414
|
-
complete -c
|
|
2415
|
-
complete -c
|
|
2416
|
-
complete -c
|
|
2417
|
-
complete -c
|
|
2418
|
-
complete -c
|
|
2419
|
-
complete -c
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
complete -c
|
|
2423
|
-
complete -c
|
|
2424
|
-
complete -c
|
|
2425
|
-
complete -c
|
|
2426
|
-
complete -c
|
|
2427
|
-
complete -c
|
|
2428
|
-
complete -c
|
|
2429
|
-
complete -c
|
|
2430
|
-
complete -c
|
|
2431
|
-
complete -c
|
|
2432
|
-
complete -c
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
complete -c
|
|
2436
|
-
complete -c
|
|
2437
|
-
complete -c
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
complete -c
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
complete -c
|
|
2444
|
-
complete -c
|
|
2445
|
-
complete -c
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
complete -c
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
complete -c
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
complete -c
|
|
2459
|
-
complete -c
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
complete -c
|
|
2463
|
-
complete -c
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
complete -c
|
|
2467
|
-
complete -c
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
complete -c
|
|
2473
|
-
complete -c
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
complete -c
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
complete -c
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
complete -c
|
|
2483
|
-
complete -c
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
complete -c
|
|
2487
|
-
complete -c
|
|
2488
|
-
complete -c
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
complete -c
|
|
2492
|
-
complete -c
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
complete -c
|
|
2496
|
-
complete -c
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
complete -c
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
complete -c
|
|
2503
|
-
complete -c
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
complete -c
|
|
2507
|
-
complete -c
|
|
2508
|
-
complete -c
|
|
2509
|
-
complete -c
|
|
2510
|
-
complete -c
|
|
2511
|
-
complete -c
|
|
2512
|
-
complete -c
|
|
2513
|
-
complete -c
|
|
2514
|
-
complete -c
|
|
2515
|
-
complete -c
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
complete -c
|
|
2519
|
-
complete -c
|
|
2520
|
-
complete -c
|
|
2521
|
-
complete -c
|
|
2522
|
-
complete -c
|
|
2523
|
-
complete -c
|
|
2524
|
-
complete -c
|
|
2525
|
-
complete -c
|
|
2526
|
-
complete -c
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2412
|
+
function fishCompletion(name) {
|
|
2413
|
+
return `complete -c ${name} -f
|
|
2414
|
+
|
|
2415
|
+
complete -c ${name} -n __fish_use_subcommand -s h -l help -d 'Show help'
|
|
2416
|
+
complete -c ${name} -n __fish_use_subcommand -s V -l version -d 'Show version'
|
|
2417
|
+
|
|
2418
|
+
complete -c ${name} -n __fish_use_subcommand -a init -d 'Set up ${name} for the first time'
|
|
2419
|
+
complete -c ${name} -n __fish_use_subcommand -a auth -d 'Validate API token and show current user'
|
|
2420
|
+
complete -c ${name} -n __fish_use_subcommand -a tasks -d 'List tasks assigned to me'
|
|
2421
|
+
complete -c ${name} -n __fish_use_subcommand -a task -d 'Get task details'
|
|
2422
|
+
complete -c ${name} -n __fish_use_subcommand -a update -d 'Update a task'
|
|
2423
|
+
complete -c ${name} -n __fish_use_subcommand -a create -d 'Create a new task'
|
|
2424
|
+
complete -c ${name} -n __fish_use_subcommand -a sprint -d 'List my tasks in the current active sprint'
|
|
2425
|
+
complete -c ${name} -n __fish_use_subcommand -a sprints -d 'List all sprints in sprint folders'
|
|
2426
|
+
complete -c ${name} -n __fish_use_subcommand -a subtasks -d 'List subtasks of a task or initiative'
|
|
2427
|
+
complete -c ${name} -n __fish_use_subcommand -a comment -d 'Post a comment on a task'
|
|
2428
|
+
complete -c ${name} -n __fish_use_subcommand -a comments -d 'List comments on a task'
|
|
2429
|
+
complete -c ${name} -n __fish_use_subcommand -a activity -d 'Show task details and comments combined'
|
|
2430
|
+
complete -c ${name} -n __fish_use_subcommand -a lists -d 'List all lists in a space'
|
|
2431
|
+
complete -c ${name} -n __fish_use_subcommand -a spaces -d 'List spaces in your workspace'
|
|
2432
|
+
complete -c ${name} -n __fish_use_subcommand -a inbox -d 'Recently updated tasks grouped by time period'
|
|
2433
|
+
complete -c ${name} -n __fish_use_subcommand -a assigned -d 'Show all tasks assigned to me'
|
|
2434
|
+
complete -c ${name} -n __fish_use_subcommand -a open -d 'Open a task in the browser by ID or name'
|
|
2435
|
+
complete -c ${name} -n __fish_use_subcommand -a search -d 'Search my tasks by name'
|
|
2436
|
+
complete -c ${name} -n __fish_use_subcommand -a summary -d 'Daily standup summary'
|
|
2437
|
+
complete -c ${name} -n __fish_use_subcommand -a overdue -d 'List tasks that are past their due date'
|
|
2438
|
+
complete -c ${name} -n __fish_use_subcommand -a assign -d 'Assign or unassign users from a task'
|
|
2439
|
+
complete -c ${name} -n __fish_use_subcommand -a depend -d 'Add or remove task dependencies'
|
|
2440
|
+
complete -c ${name} -n __fish_use_subcommand -a move -d 'Add or remove a task from a list'
|
|
2441
|
+
complete -c ${name} -n __fish_use_subcommand -a field -d 'Set or remove a custom field value on a task'
|
|
2442
|
+
complete -c ${name} -n __fish_use_subcommand -a delete -d 'Delete a task'
|
|
2443
|
+
complete -c ${name} -n __fish_use_subcommand -a tag -d 'Add or remove tags from a task'
|
|
2444
|
+
complete -c ${name} -n __fish_use_subcommand -a checklist -d 'Manage checklists on a task'
|
|
2445
|
+
complete -c ${name} -n __fish_use_subcommand -a time -d 'Track time on tasks'
|
|
2446
|
+
complete -c ${name} -n __fish_use_subcommand -a comment-edit -d 'Edit an existing comment'
|
|
2447
|
+
complete -c ${name} -n __fish_use_subcommand -a comment-delete -d 'Delete a comment'
|
|
2448
|
+
complete -c ${name} -n __fish_use_subcommand -a replies -d 'List threaded replies on a comment'
|
|
2449
|
+
complete -c ${name} -n __fish_use_subcommand -a reply -d 'Reply to a comment'
|
|
2450
|
+
complete -c ${name} -n __fish_use_subcommand -a link -d 'Add or remove a link between two tasks'
|
|
2451
|
+
complete -c ${name} -n __fish_use_subcommand -a attach -d 'Upload a file attachment to a task'
|
|
2452
|
+
complete -c ${name} -n __fish_use_subcommand -a config -d 'Manage CLI configuration'
|
|
2453
|
+
complete -c ${name} -n __fish_use_subcommand -a completion -d 'Output shell completion script'
|
|
2454
|
+
|
|
2455
|
+
complete -c ${name} -n '__fish_seen_subcommand_from auth' -l json -d 'Force JSON output'
|
|
2456
|
+
|
|
2457
|
+
complete -c ${name} -n '__fish_seen_subcommand_from tasks' -l status -d 'Filter by status'
|
|
2458
|
+
complete -c ${name} -n '__fish_seen_subcommand_from tasks' -l list -d 'Filter by list ID'
|
|
2459
|
+
complete -c ${name} -n '__fish_seen_subcommand_from tasks' -l space -d 'Filter by space ID'
|
|
2460
|
+
complete -c ${name} -n '__fish_seen_subcommand_from tasks' -l name -d 'Filter by name'
|
|
2461
|
+
complete -c ${name} -n '__fish_seen_subcommand_from tasks' -l type -d 'Filter by task type'
|
|
2462
|
+
complete -c ${name} -n '__fish_seen_subcommand_from tasks' -l include-closed -d 'Include done/closed tasks'
|
|
2463
|
+
complete -c ${name} -n '__fish_seen_subcommand_from tasks' -l json -d 'Force JSON output'
|
|
2464
|
+
|
|
2465
|
+
complete -c ${name} -n '__fish_seen_subcommand_from task' -l json -d 'Force JSON output'
|
|
2466
|
+
|
|
2467
|
+
complete -c ${name} -n '__fish_seen_subcommand_from update' -s n -l name -d 'New task name'
|
|
2468
|
+
complete -c ${name} -n '__fish_seen_subcommand_from update' -s d -l description -d 'New description'
|
|
2469
|
+
complete -c ${name} -n '__fish_seen_subcommand_from update' -s s -l status -d 'New status'
|
|
2470
|
+
complete -c ${name} -n '__fish_seen_subcommand_from update' -l priority -d 'Priority level' -a 'urgent high normal low'
|
|
2471
|
+
complete -c ${name} -n '__fish_seen_subcommand_from update' -l due-date -d 'Due date'
|
|
2472
|
+
complete -c ${name} -n '__fish_seen_subcommand_from update' -l time-estimate -d 'Time estimate'
|
|
2473
|
+
complete -c ${name} -n '__fish_seen_subcommand_from update' -l assignee -d 'Add assignee'
|
|
2474
|
+
complete -c ${name} -n '__fish_seen_subcommand_from update' -l parent -d 'Set parent task'
|
|
2475
|
+
complete -c ${name} -n '__fish_seen_subcommand_from update' -l json -d 'Force JSON output'
|
|
2476
|
+
|
|
2477
|
+
complete -c ${name} -n '__fish_seen_subcommand_from create' -s l -l list -d 'Target list ID'
|
|
2478
|
+
complete -c ${name} -n '__fish_seen_subcommand_from create' -s n -l name -d 'Task name'
|
|
2479
|
+
complete -c ${name} -n '__fish_seen_subcommand_from create' -s d -l description -d 'Task description'
|
|
2480
|
+
complete -c ${name} -n '__fish_seen_subcommand_from create' -s p -l parent -d 'Parent task ID'
|
|
2481
|
+
complete -c ${name} -n '__fish_seen_subcommand_from create' -s s -l status -d 'Initial status'
|
|
2482
|
+
complete -c ${name} -n '__fish_seen_subcommand_from create' -l priority -d 'Priority level' -a 'urgent high normal low'
|
|
2483
|
+
complete -c ${name} -n '__fish_seen_subcommand_from create' -l due-date -d 'Due date'
|
|
2484
|
+
complete -c ${name} -n '__fish_seen_subcommand_from create' -l assignee -d 'Assignee user ID'
|
|
2485
|
+
complete -c ${name} -n '__fish_seen_subcommand_from create' -l tags -d 'Comma-separated tag names'
|
|
2486
|
+
complete -c ${name} -n '__fish_seen_subcommand_from create' -l custom-item-id -d 'Custom task type ID'
|
|
2487
|
+
complete -c ${name} -n '__fish_seen_subcommand_from create' -l time-estimate -d 'Time estimate'
|
|
2488
|
+
complete -c ${name} -n '__fish_seen_subcommand_from create' -l json -d 'Force JSON output'
|
|
2489
|
+
|
|
2490
|
+
complete -c ${name} -n '__fish_seen_subcommand_from sprint' -l status -d 'Filter by status'
|
|
2491
|
+
complete -c ${name} -n '__fish_seen_subcommand_from sprint' -l space -d 'Narrow sprint search to a space'
|
|
2492
|
+
complete -c ${name} -n '__fish_seen_subcommand_from sprint' -l include-closed -d 'Include done/closed tasks'
|
|
2493
|
+
complete -c ${name} -n '__fish_seen_subcommand_from sprint' -l json -d 'Force JSON output'
|
|
2494
|
+
|
|
2495
|
+
complete -c ${name} -n '__fish_seen_subcommand_from sprints' -l space -d 'Filter by space'
|
|
2496
|
+
complete -c ${name} -n '__fish_seen_subcommand_from sprints' -l json -d 'Force JSON output'
|
|
2497
|
+
|
|
2498
|
+
complete -c ${name} -n '__fish_seen_subcommand_from subtasks' -l status -d 'Filter by status'
|
|
2499
|
+
complete -c ${name} -n '__fish_seen_subcommand_from subtasks' -l name -d 'Filter by name'
|
|
2500
|
+
complete -c ${name} -n '__fish_seen_subcommand_from subtasks' -l include-closed -d 'Include closed/done subtasks'
|
|
2501
|
+
complete -c ${name} -n '__fish_seen_subcommand_from subtasks' -l json -d 'Force JSON output'
|
|
2502
|
+
|
|
2503
|
+
complete -c ${name} -n '__fish_seen_subcommand_from comment' -s m -l message -d 'Comment text'
|
|
2504
|
+
complete -c ${name} -n '__fish_seen_subcommand_from comment' -l json -d 'Force JSON output'
|
|
2505
|
+
|
|
2506
|
+
complete -c ${name} -n '__fish_seen_subcommand_from comments' -l json -d 'Force JSON output'
|
|
2507
|
+
|
|
2508
|
+
complete -c ${name} -n '__fish_seen_subcommand_from activity' -l json -d 'Force JSON output'
|
|
2509
|
+
|
|
2510
|
+
complete -c ${name} -n '__fish_seen_subcommand_from lists' -l name -d 'Filter by name'
|
|
2511
|
+
complete -c ${name} -n '__fish_seen_subcommand_from lists' -l json -d 'Force JSON output'
|
|
2512
|
+
|
|
2513
|
+
complete -c ${name} -n '__fish_seen_subcommand_from spaces' -l name -d 'Filter spaces by name'
|
|
2514
|
+
complete -c ${name} -n '__fish_seen_subcommand_from spaces' -l my -d 'Show only spaces where I have assigned tasks'
|
|
2515
|
+
complete -c ${name} -n '__fish_seen_subcommand_from spaces' -l json -d 'Force JSON output'
|
|
2516
|
+
|
|
2517
|
+
complete -c ${name} -n '__fish_seen_subcommand_from inbox' -l include-closed -d 'Include done/closed tasks'
|
|
2518
|
+
complete -c ${name} -n '__fish_seen_subcommand_from inbox' -l json -d 'Force JSON output'
|
|
2519
|
+
complete -c ${name} -n '__fish_seen_subcommand_from inbox' -l days -d 'Lookback period in days'
|
|
2520
|
+
|
|
2521
|
+
complete -c ${name} -n '__fish_seen_subcommand_from assigned' -l status -d 'Show only tasks with this status'
|
|
2522
|
+
complete -c ${name} -n '__fish_seen_subcommand_from assigned' -l include-closed -d 'Include done/closed tasks'
|
|
2523
|
+
complete -c ${name} -n '__fish_seen_subcommand_from assigned' -l json -d 'Force JSON output'
|
|
2524
|
+
|
|
2525
|
+
complete -c ${name} -n '__fish_seen_subcommand_from open' -l json -d 'Output task JSON instead of opening'
|
|
2526
|
+
|
|
2527
|
+
complete -c ${name} -n '__fish_seen_subcommand_from search' -l status -d 'Filter by status'
|
|
2528
|
+
complete -c ${name} -n '__fish_seen_subcommand_from search' -l include-closed -d 'Include done/closed tasks in search'
|
|
2529
|
+
complete -c ${name} -n '__fish_seen_subcommand_from search' -l json -d 'Force JSON output'
|
|
2530
|
+
|
|
2531
|
+
complete -c ${name} -n '__fish_seen_subcommand_from summary' -l hours -d 'Completed-tasks lookback in hours'
|
|
2532
|
+
complete -c ${name} -n '__fish_seen_subcommand_from summary' -l json -d 'Force JSON output'
|
|
2533
|
+
|
|
2534
|
+
complete -c ${name} -n '__fish_seen_subcommand_from overdue' -l include-closed -d 'Include done/closed overdue tasks'
|
|
2535
|
+
complete -c ${name} -n '__fish_seen_subcommand_from overdue' -l json -d 'Force JSON output'
|
|
2536
|
+
|
|
2537
|
+
complete -c ${name} -n '__fish_seen_subcommand_from assign' -l to -d 'Add assignee'
|
|
2538
|
+
complete -c ${name} -n '__fish_seen_subcommand_from assign' -l remove -d 'Remove assignee'
|
|
2539
|
+
complete -c ${name} -n '__fish_seen_subcommand_from assign' -l json -d 'Force JSON output'
|
|
2540
|
+
|
|
2541
|
+
complete -c ${name} -n '__fish_seen_subcommand_from depend' -l on -d 'Task that this task depends on'
|
|
2542
|
+
complete -c ${name} -n '__fish_seen_subcommand_from depend' -l blocks -d 'Task that this task blocks'
|
|
2543
|
+
complete -c ${name} -n '__fish_seen_subcommand_from depend' -l remove -d 'Remove the dependency'
|
|
2544
|
+
complete -c ${name} -n '__fish_seen_subcommand_from depend' -l json -d 'Force JSON output'
|
|
2545
|
+
|
|
2546
|
+
complete -c ${name} -n '__fish_seen_subcommand_from move' -l to -d 'Add task to this list'
|
|
2547
|
+
complete -c ${name} -n '__fish_seen_subcommand_from move' -l remove -d 'Remove task from this list'
|
|
2548
|
+
complete -c ${name} -n '__fish_seen_subcommand_from move' -l json -d 'Force JSON output'
|
|
2549
|
+
|
|
2550
|
+
complete -c ${name} -n '__fish_seen_subcommand_from field' -l set -d 'Set field name and value'
|
|
2551
|
+
complete -c ${name} -n '__fish_seen_subcommand_from field' -l remove -d 'Remove field value by name'
|
|
2552
|
+
complete -c ${name} -n '__fish_seen_subcommand_from field' -l json -d 'Force JSON output'
|
|
2553
|
+
|
|
2554
|
+
complete -c ${name} -n '__fish_seen_subcommand_from delete' -l confirm -d 'Skip confirmation prompt'
|
|
2555
|
+
complete -c ${name} -n '__fish_seen_subcommand_from delete' -l json -d 'Force JSON output'
|
|
2556
|
+
|
|
2557
|
+
complete -c ${name} -n '__fish_seen_subcommand_from tag' -l add -d 'Comma-separated tag names to add'
|
|
2558
|
+
complete -c ${name} -n '__fish_seen_subcommand_from tag' -l remove -d 'Comma-separated tag names to remove'
|
|
2559
|
+
complete -c ${name} -n '__fish_seen_subcommand_from tag' -l json -d 'Force JSON output'
|
|
2560
|
+
|
|
2561
|
+
complete -c ${name} -n '__fish_seen_subcommand_from checklist; and not __fish_seen_subcommand_from view create delete add-item edit-item delete-item' -a view -d 'View checklists on a task'
|
|
2562
|
+
complete -c ${name} -n '__fish_seen_subcommand_from checklist; and not __fish_seen_subcommand_from view create delete add-item edit-item delete-item' -a create -d 'Create a checklist on a task'
|
|
2563
|
+
complete -c ${name} -n '__fish_seen_subcommand_from checklist; and not __fish_seen_subcommand_from view create delete add-item edit-item delete-item' -a delete -d 'Delete a checklist'
|
|
2564
|
+
complete -c ${name} -n '__fish_seen_subcommand_from checklist; and not __fish_seen_subcommand_from view create delete add-item edit-item delete-item' -a add-item -d 'Add an item to a checklist'
|
|
2565
|
+
complete -c ${name} -n '__fish_seen_subcommand_from checklist; and not __fish_seen_subcommand_from view create delete add-item edit-item delete-item' -a edit-item -d 'Edit a checklist item'
|
|
2566
|
+
complete -c ${name} -n '__fish_seen_subcommand_from checklist; and not __fish_seen_subcommand_from view create delete add-item edit-item delete-item' -a delete-item -d 'Delete a checklist item'
|
|
2567
|
+
complete -c ${name} -n '__fish_seen_subcommand_from view create delete add-item edit-item delete-item' -l json -d 'Force JSON output'
|
|
2568
|
+
complete -c ${name} -n '__fish_seen_subcommand_from edit-item' -l name -d 'New item name'
|
|
2569
|
+
complete -c ${name} -n '__fish_seen_subcommand_from edit-item' -l resolved -d 'Mark item as resolved'
|
|
2570
|
+
complete -c ${name} -n '__fish_seen_subcommand_from edit-item' -l unresolved -d 'Mark item as unresolved'
|
|
2571
|
+
complete -c ${name} -n '__fish_seen_subcommand_from edit-item' -l assignee -d 'Assign user by ID'
|
|
2572
|
+
|
|
2573
|
+
complete -c ${name} -n '__fish_seen_subcommand_from time; and not __fish_seen_subcommand_from start stop status log list' -a start -d 'Start tracking time on a task'
|
|
2574
|
+
complete -c ${name} -n '__fish_seen_subcommand_from time; and not __fish_seen_subcommand_from start stop status log list' -a stop -d 'Stop the running timer'
|
|
2575
|
+
complete -c ${name} -n '__fish_seen_subcommand_from time; and not __fish_seen_subcommand_from start stop status log list' -a status -d 'Show the currently running timer'
|
|
2576
|
+
complete -c ${name} -n '__fish_seen_subcommand_from time; and not __fish_seen_subcommand_from start stop status log list' -a log -d 'Log a manual time entry'
|
|
2577
|
+
complete -c ${name} -n '__fish_seen_subcommand_from time; and not __fish_seen_subcommand_from start stop status log list' -a list -d 'List recent time entries'
|
|
2578
|
+
complete -c ${name} -n '__fish_seen_subcommand_from start stop status log list; and __fish_seen_subcommand_from time' -l json -d 'Force JSON output'
|
|
2579
|
+
complete -c ${name} -n '__fish_seen_subcommand_from start; and __fish_seen_subcommand_from time' -s d -l description -d 'Description'
|
|
2580
|
+
complete -c ${name} -n '__fish_seen_subcommand_from log; and __fish_seen_subcommand_from time' -s d -l description -d 'Description'
|
|
2581
|
+
complete -c ${name} -n '__fish_seen_subcommand_from list; and __fish_seen_subcommand_from time' -l days -d 'Number of days to look back'
|
|
2582
|
+
complete -c ${name} -n '__fish_seen_subcommand_from list; and __fish_seen_subcommand_from time' -l task -d 'Filter by task ID'
|
|
2583
|
+
|
|
2584
|
+
complete -c ${name} -n '__fish_seen_subcommand_from comment-delete' -l json -d 'Force JSON output'
|
|
2585
|
+
|
|
2586
|
+
complete -c ${name} -n '__fish_seen_subcommand_from replies' -l json -d 'Force JSON output'
|
|
2531
2587
|
|
|
2532
|
-
complete -c
|
|
2533
|
-
complete -c
|
|
2588
|
+
complete -c ${name} -n '__fish_seen_subcommand_from reply' -s m -l message -d 'Reply text'
|
|
2589
|
+
complete -c ${name} -n '__fish_seen_subcommand_from reply' -l json -d 'Force JSON output'
|
|
2534
2590
|
|
|
2535
|
-
complete -c
|
|
2536
|
-
complete -c
|
|
2591
|
+
complete -c ${name} -n '__fish_seen_subcommand_from link' -l remove -d 'Remove the link'
|
|
2592
|
+
complete -c ${name} -n '__fish_seen_subcommand_from link' -l json -d 'Force JSON output'
|
|
2537
2593
|
|
|
2538
|
-
complete -c
|
|
2539
|
-
complete -c
|
|
2540
|
-
complete -c cu -n '__fish_seen_subcommand_from comment-edit' -l unresolved -d 'Mark comment as unresolved'
|
|
2541
|
-
complete -c cu -n '__fish_seen_subcommand_from comment-edit' -l json -d 'Force JSON output'
|
|
2594
|
+
complete -c ${name} -n '__fish_seen_subcommand_from attach' -l json -d 'Force JSON output'
|
|
2595
|
+
complete -c ${name} -n '__fish_seen_subcommand_from attach' -F
|
|
2542
2596
|
|
|
2543
|
-
complete -c
|
|
2544
|
-
complete -c
|
|
2545
|
-
complete -c
|
|
2546
|
-
complete -c
|
|
2597
|
+
complete -c ${name} -n '__fish_seen_subcommand_from comment-edit' -s m -l message -d 'New comment text'
|
|
2598
|
+
complete -c ${name} -n '__fish_seen_subcommand_from comment-edit' -l resolved -d 'Mark comment as resolved'
|
|
2599
|
+
complete -c ${name} -n '__fish_seen_subcommand_from comment-edit' -l unresolved -d 'Mark comment as unresolved'
|
|
2600
|
+
complete -c ${name} -n '__fish_seen_subcommand_from comment-edit' -l json -d 'Force JSON output'
|
|
2547
2601
|
|
|
2548
|
-
complete -c
|
|
2602
|
+
complete -c ${name} -n '__fish_seen_subcommand_from config; and not __fish_seen_subcommand_from get set path' -a get -d 'Print a config value'
|
|
2603
|
+
complete -c ${name} -n '__fish_seen_subcommand_from config; and not __fish_seen_subcommand_from get set path' -a set -d 'Set a config value'
|
|
2604
|
+
complete -c ${name} -n '__fish_seen_subcommand_from config; and not __fish_seen_subcommand_from get set path' -a path -d 'Print config file path'
|
|
2605
|
+
complete -c ${name} -n '__fish_seen_subcommand_from get set' -a 'apiToken teamId' -d 'Config key'
|
|
2606
|
+
|
|
2607
|
+
complete -c ${name} -n '__fish_seen_subcommand_from completion' -a 'bash zsh fish' -d 'Shell type'
|
|
2549
2608
|
`;
|
|
2550
2609
|
}
|
|
2551
|
-
function generateCompletion(shell) {
|
|
2610
|
+
function generateCompletion(shell, name = "cu") {
|
|
2552
2611
|
switch (shell) {
|
|
2553
2612
|
case "bash":
|
|
2554
|
-
return bashCompletion();
|
|
2613
|
+
return bashCompletion(name);
|
|
2555
2614
|
case "zsh":
|
|
2556
|
-
return zshCompletion();
|
|
2615
|
+
return zshCompletion(name);
|
|
2557
2616
|
case "fish":
|
|
2558
|
-
return fishCompletion();
|
|
2617
|
+
return fishCompletion(name);
|
|
2559
2618
|
default:
|
|
2560
2619
|
throw new Error(`Unsupported shell: ${shell}. Supported shells: bash, zsh, fish`);
|
|
2561
2620
|
}
|
|
@@ -2885,6 +2944,18 @@ async function manageTaskLink(config, taskId, linksTo, remove) {
|
|
|
2885
2944
|
return `Linked ${taskId} to ${linksTo}`;
|
|
2886
2945
|
}
|
|
2887
2946
|
|
|
2947
|
+
// src/commands/attach.ts
|
|
2948
|
+
async function attachFile(config, taskId, filePath) {
|
|
2949
|
+
const { access } = await import("fs/promises");
|
|
2950
|
+
try {
|
|
2951
|
+
await access(filePath);
|
|
2952
|
+
} catch {
|
|
2953
|
+
throw new Error(`File not found: ${filePath}`);
|
|
2954
|
+
}
|
|
2955
|
+
const client = new ClickUpClient(config);
|
|
2956
|
+
return client.createTaskAttachment(taskId, filePath);
|
|
2957
|
+
}
|
|
2958
|
+
|
|
2888
2959
|
// src/commands/time.ts
|
|
2889
2960
|
import chalk7 from "chalk";
|
|
2890
2961
|
function formatDuration2(ms) {
|
|
@@ -2953,6 +3024,7 @@ function formatTimeEntries(entries) {
|
|
|
2953
3024
|
// src/index.ts
|
|
2954
3025
|
var require2 = createRequire(import.meta.url);
|
|
2955
3026
|
var { version } = require2("../package.json");
|
|
3027
|
+
var programName = basename(process.argv[1] ?? "cu");
|
|
2956
3028
|
function wrapAction(fn) {
|
|
2957
3029
|
return (...args) => {
|
|
2958
3030
|
fn(...args).catch((err) => {
|
|
@@ -2962,8 +3034,8 @@ function wrapAction(fn) {
|
|
|
2962
3034
|
};
|
|
2963
3035
|
}
|
|
2964
3036
|
var program = new Command();
|
|
2965
|
-
program.name(
|
|
2966
|
-
program.command("init").description(
|
|
3037
|
+
program.name(programName).description("ClickUp CLI for AI agents").version(version).allowExcessArguments(false);
|
|
3038
|
+
program.command("init").description(`Set up ${programName} for the first time`).action(
|
|
2967
3039
|
wrapAction(async () => {
|
|
2968
3040
|
await runInitCommand();
|
|
2969
3041
|
})
|
|
@@ -3259,6 +3331,18 @@ program.command("link <taskId> <linksTo>").description("Add or remove a link bet
|
|
|
3259
3331
|
}
|
|
3260
3332
|
)
|
|
3261
3333
|
);
|
|
3334
|
+
program.command("attach <taskId> <filePath>").description("Upload a file attachment to a task").option("--json", "Force JSON output even in terminal").action(
|
|
3335
|
+
wrapAction(async (taskId, filePath, opts) => {
|
|
3336
|
+
const config = loadConfig();
|
|
3337
|
+
const result = await attachFile(config, taskId, filePath);
|
|
3338
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
3339
|
+
console.log(JSON.stringify(result, null, 2));
|
|
3340
|
+
} else {
|
|
3341
|
+
console.log(`Uploaded "${result.title}" to task ${taskId}`);
|
|
3342
|
+
console.log(` ${result.url}`);
|
|
3343
|
+
}
|
|
3344
|
+
})
|
|
3345
|
+
);
|
|
3262
3346
|
program.command("move <taskId>").description("Add or remove a task from a list").option("--to <listId>", "Add task to this list").option("--remove <listId>", "Remove task from this list").option("--json", "Force JSON output even in terminal").action(
|
|
3263
3347
|
wrapAction(async (taskId, opts) => {
|
|
3264
3348
|
const config = loadConfig();
|
|
@@ -3486,7 +3570,7 @@ configCmd.command("path").description("Print config file path").action(
|
|
|
3486
3570
|
);
|
|
3487
3571
|
program.command("completion <shell>").description("Output shell completion script (bash, zsh, fish)").action(
|
|
3488
3572
|
wrapAction(async (shell) => {
|
|
3489
|
-
const script = generateCompletion(shell);
|
|
3573
|
+
const script = generateCompletion(shell, programName);
|
|
3490
3574
|
process.stdout.write(script);
|
|
3491
3575
|
})
|
|
3492
3576
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@krodak/clickup-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "ClickUp CLI for AI agents and humans",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
"initiative"
|
|
21
21
|
],
|
|
22
22
|
"bin": {
|
|
23
|
-
"cu": "./dist/index.js"
|
|
23
|
+
"cu": "./dist/index.js",
|
|
24
|
+
"cup": "./dist/index.js"
|
|
24
25
|
},
|
|
25
26
|
"files": [
|
|
26
27
|
"dist",
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: clickup
|
|
3
|
-
description: 'Use when managing ClickUp tasks, sprints, or comments via the `cu` 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.'
|
|
3
|
+
description: 'Use when managing ClickUp tasks, sprints, or comments via the `cu` / `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.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# ClickUp CLI (`cu`)
|
|
6
|
+
# ClickUp CLI (`cu` / `cup`)
|
|
7
7
|
|
|
8
8
|
Reference for AI agents using the `cu` CLI tool. Covers task management, sprint tracking, comments, and project workflows.
|
|
9
9
|
|
|
10
10
|
Keywords: ClickUp, task management, sprint, project management, agile, backlog, subtasks, standup, overdue, search
|
|
11
11
|
|
|
12
|
+
## Binary Names
|
|
13
|
+
|
|
14
|
+
Both `cu` and `cup` are available as binary names. They are identical. Use `cup` if `cu` conflicts with the Unix `cu(1)` utility on your system. All examples below use `cu`, but `cup` works the same way.
|
|
15
|
+
|
|
12
16
|
## Setup
|
|
13
17
|
|
|
14
18
|
Config at `~/.config/cu/config.json` with `apiToken` and `teamId`. Run `cu init` to set up interactively.
|
|
@@ -77,6 +81,7 @@ All commands support `--help` for full flag details.
|
|
|
77
81
|
| `cu replies <commentId> [--json]` | List threaded replies on a comment |
|
|
78
82
|
| `cu reply <commentId> -m text [--json]` | Reply to a comment |
|
|
79
83
|
| `cu link <taskId> <linksTo> [--remove] [--json]` | Add or remove link between tasks |
|
|
84
|
+
| `cu attach <taskId> <filePath> [--json]` | Upload file attachment to a task |
|
|
80
85
|
| `cu time start <taskId> [-d desc] [--json]` | Start tracking time on a task |
|
|
81
86
|
| `cu time stop [--json]` | Stop the running timer |
|
|
82
87
|
| `cu time status [--json]` | Show currently running timer |
|
|
@@ -120,7 +125,8 @@ All commands support `--help` for full flag details.
|
|
|
120
125
|
| `cu comment-delete` | Delete a comment |
|
|
121
126
|
| `cu replies` / `cu reply` | View and post threaded comment replies |
|
|
122
127
|
| `cu link` | Link/unlink tasks (different from dependencies) |
|
|
123
|
-
| `cu
|
|
128
|
+
| `cu attach` | Upload files to tasks. Attachments shown in `cu task` detail view |
|
|
129
|
+
| `cu task` | Shows custom fields, checklists, and attachments in detail view |
|
|
124
130
|
| `cu lists` | Discovers list IDs needed for `--list` and `cu create -l` |
|
|
125
131
|
| Errors | stderr with exit code 1 |
|
|
126
132
|
| Parsing | Strict - excess/unknown arguments rejected |
|
|
@@ -182,6 +188,7 @@ cu replies <commentId> # view threaded replies
|
|
|
182
188
|
cu reply <commentId> -m "Agreed, fixing" # reply to a comment
|
|
183
189
|
cu link abc123 def456 # link two tasks
|
|
184
190
|
cu link abc123 def456 --remove # unlink two tasks
|
|
191
|
+
cu attach abc123def ./screenshot.png # upload file to task
|
|
185
192
|
cu time start abc123def -d "Working on feature" # start timer
|
|
186
193
|
cu time status # check running timer
|
|
187
194
|
cu time stop # stop timer
|