@krodak/clickup-cli 0.12.2 → 0.13.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 +61 -1
- package/dist/index.js +382 -46
- package/package.json +1 -1
- package/skills/clickup-cli/SKILL.md +45 -28
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
|
+
30 commands total. All support `--help` for full flag details.
|
|
102
102
|
|
|
103
103
|
### `cu init`
|
|
104
104
|
|
|
@@ -261,6 +261,48 @@ cu create -n "Fix bug" -l <listId> --json
|
|
|
261
261
|
| `--custom-item-id <id>` | no | Custom task type ID (for creating initiatives) |
|
|
262
262
|
| `--json` | no | Force JSON output even in terminal |
|
|
263
263
|
|
|
264
|
+
### `cu delete <id>`
|
|
265
|
+
|
|
266
|
+
Delete a task. **DESTRUCTIVE - cannot be undone.**
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
cu delete abc123
|
|
270
|
+
cu delete abc123 --confirm
|
|
271
|
+
cu delete abc123 --confirm --json
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
In TTY mode without `--confirm`: shows the task name and prompts for confirmation (default: No). In non-interactive/piped mode, `--confirm` is required.
|
|
275
|
+
|
|
276
|
+
| Flag | Description |
|
|
277
|
+
| ----------- | ----------------------------------------------------------- |
|
|
278
|
+
| `--confirm` | Skip confirmation prompt (required in non-interactive mode) |
|
|
279
|
+
| `--json` | Force JSON output |
|
|
280
|
+
|
|
281
|
+
### `cu field <id>`
|
|
282
|
+
|
|
283
|
+
Set or remove a custom field value. Field names are resolved case-insensitively; errors list available fields/options.
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
cu field abc123 --set "Priority Level" high
|
|
287
|
+
cu field abc123 --set "Story Points" 5
|
|
288
|
+
cu field abc123 --set "Approved" true
|
|
289
|
+
cu field abc123 --set "Category" "Bug Fix"
|
|
290
|
+
cu field abc123 --set "Due" 2025-06-01
|
|
291
|
+
cu field abc123 --set "Website" "https://example.com"
|
|
292
|
+
cu field abc123 --set "Contact" "user@example.com"
|
|
293
|
+
cu field abc123 --remove "Priority Level"
|
|
294
|
+
cu field abc123 --set "Points" 3 --remove "Old Field"
|
|
295
|
+
cu field abc123 --set "Points" 3 --json
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
| Flag | Description |
|
|
299
|
+
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
300
|
+
| `--set "Field Name" <val>` | Set a custom field by name. Supports: text, number, checkbox (true/false), dropdown (option name), date (YYYY-MM-DD), url, email |
|
|
301
|
+
| `--remove "Field Name"` | Remove a custom field value |
|
|
302
|
+
| `--json` | Force JSON output |
|
|
303
|
+
|
|
304
|
+
Both `--set` and `--remove` can be used together in one invocation.
|
|
305
|
+
|
|
264
306
|
### `cu comment <id>`
|
|
265
307
|
|
|
266
308
|
Post a comment on a task.
|
|
@@ -423,6 +465,24 @@ cu move abc123 --to <listId> --json
|
|
|
423
465
|
| `--remove <listId>` | Remove task from this list |
|
|
424
466
|
| `--json` | Force JSON output |
|
|
425
467
|
|
|
468
|
+
### `cu tag <id>`
|
|
469
|
+
|
|
470
|
+
Add or remove tags on a task. Both `--add` and `--remove` can be used together.
|
|
471
|
+
|
|
472
|
+
```bash
|
|
473
|
+
cu tag abc123 --add "bug"
|
|
474
|
+
cu tag abc123 --add "bug,frontend,urgent"
|
|
475
|
+
cu tag abc123 --remove "wontfix"
|
|
476
|
+
cu tag abc123 --add "bug" --remove "triage"
|
|
477
|
+
cu tag abc123 --add "bug" --json
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
| Flag | Description |
|
|
481
|
+
| ----------------- | ----------------------------------- |
|
|
482
|
+
| `--add <tags>` | Comma-separated tag names to add |
|
|
483
|
+
| `--remove <tags>` | Comma-separated tag names to remove |
|
|
484
|
+
| `--json` | Force JSON output |
|
|
485
|
+
|
|
426
486
|
### `cu auth`
|
|
427
487
|
|
|
428
488
|
Check authentication status. Validates your API token and shows your user info.
|
package/dist/index.js
CHANGED
|
@@ -170,26 +170,15 @@ var ClickUpClient = class {
|
|
|
170
170
|
return `/list/${listId}/task?${qs}`;
|
|
171
171
|
});
|
|
172
172
|
}
|
|
173
|
-
async getMyTasksFromList(listId) {
|
|
174
|
-
const me = await this.getMe();
|
|
175
|
-
return this.getTasksFromList(listId, { "assignees[]": String(me.id) });
|
|
176
|
-
}
|
|
177
173
|
async getTask(taskId) {
|
|
178
174
|
return this.request(`/task/${taskId}?include_markdown_description=true`);
|
|
179
175
|
}
|
|
180
|
-
async updateTaskMarkdown(taskId, markdown) {
|
|
181
|
-
return this.updateTask(taskId, { markdown_content: markdown });
|
|
182
|
-
}
|
|
183
176
|
async createTask(listId, options) {
|
|
184
177
|
return this.request(`/list/${listId}/task`, {
|
|
185
178
|
method: "POST",
|
|
186
179
|
body: JSON.stringify(options)
|
|
187
180
|
});
|
|
188
181
|
}
|
|
189
|
-
async getAssignedListIds(teamId) {
|
|
190
|
-
const tasks = await this.getMyTasks(teamId);
|
|
191
|
-
return new Set(tasks.map((t) => t.list.id));
|
|
192
|
-
}
|
|
193
182
|
async getTeams() {
|
|
194
183
|
const data = await this.request("/team");
|
|
195
184
|
return data.teams ?? [];
|
|
@@ -229,6 +218,24 @@ var ClickUpClient = class {
|
|
|
229
218
|
async removeTaskFromList(taskId, listId) {
|
|
230
219
|
await this.request(`/list/${listId}/task/${taskId}`, { method: "DELETE" });
|
|
231
220
|
}
|
|
221
|
+
async setCustomFieldValue(taskId, fieldId, value) {
|
|
222
|
+
await this.request(`/task/${taskId}/field/${fieldId}`, {
|
|
223
|
+
method: "POST",
|
|
224
|
+
body: JSON.stringify({ value })
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
async removeCustomFieldValue(taskId, fieldId) {
|
|
228
|
+
await this.request(`/task/${taskId}/field/${fieldId}`, { method: "DELETE" });
|
|
229
|
+
}
|
|
230
|
+
async deleteTask(taskId) {
|
|
231
|
+
await this.request(`/task/${taskId}`, { method: "DELETE" });
|
|
232
|
+
}
|
|
233
|
+
async addTagToTask(taskId, tagName) {
|
|
234
|
+
await this.request(`/task/${taskId}/tag/${encodeURIComponent(tagName)}`, { method: "POST" });
|
|
235
|
+
}
|
|
236
|
+
async removeTagFromTask(taskId, tagName) {
|
|
237
|
+
await this.request(`/task/${taskId}/tag/${encodeURIComponent(tagName)}`, { method: "DELETE" });
|
|
238
|
+
}
|
|
232
239
|
async addDependency(taskId, opts) {
|
|
233
240
|
const body = {};
|
|
234
241
|
if (opts.dependsOn) body.depends_on = opts.dependsOn;
|
|
@@ -1626,7 +1633,7 @@ function bashCompletion() {
|
|
|
1626
1633
|
cword=$COMP_CWORD
|
|
1627
1634
|
fi
|
|
1628
1635
|
|
|
1629
|
-
local commands="init tasks initiatives task update create sprint subtasks comment comments lists spaces inbox assigned open summary overdue assign config completion"
|
|
1636
|
+
local commands="init auth tasks initiatives task update create sprint sprints subtasks comment comments activity lists spaces inbox assigned open search summary overdue assign depend move field delete tag config completion"
|
|
1630
1637
|
|
|
1631
1638
|
if [[ $cword -eq 1 ]]; then
|
|
1632
1639
|
COMPREPLY=($(compgen -W "$commands --help --version" -- "$cur"))
|
|
@@ -1648,29 +1655,35 @@ function bashCompletion() {
|
|
|
1648
1655
|
|
|
1649
1656
|
case "$cmd" in
|
|
1650
1657
|
tasks|initiatives)
|
|
1651
|
-
COMPREPLY=($(compgen -W "--status --list --space --name --json" -- "$cur"))
|
|
1658
|
+
COMPREPLY=($(compgen -W "--status --list --space --name --include-closed --json" -- "$cur"))
|
|
1652
1659
|
;;
|
|
1653
1660
|
task)
|
|
1654
1661
|
COMPREPLY=($(compgen -W "--json" -- "$cur"))
|
|
1655
1662
|
;;
|
|
1656
1663
|
update)
|
|
1657
|
-
COMPREPLY=($(compgen -W "--name --description --status --priority --due-date --assignee" -- "$cur"))
|
|
1664
|
+
COMPREPLY=($(compgen -W "-n --name -d --description -s --status --priority --due-date --time-estimate --assignee --parent --json" -- "$cur"))
|
|
1658
1665
|
;;
|
|
1659
1666
|
create)
|
|
1660
|
-
COMPREPLY=($(compgen -W "--list --name --description --parent --status --priority --due-date --assignee --tags" -- "$cur"))
|
|
1667
|
+
COMPREPLY=($(compgen -W "-l --list -n --name -d --description -p --parent -s --status --priority --due-date --assignee --tags --custom-item-id --time-estimate --json" -- "$cur"))
|
|
1661
1668
|
;;
|
|
1662
1669
|
sprint)
|
|
1663
|
-
COMPREPLY=($(compgen -W "--status --space --json" -- "$cur"))
|
|
1670
|
+
COMPREPLY=($(compgen -W "--status --space --include-closed --json" -- "$cur"))
|
|
1671
|
+
;;
|
|
1672
|
+
sprints)
|
|
1673
|
+
COMPREPLY=($(compgen -W "--space --json" -- "$cur"))
|
|
1664
1674
|
;;
|
|
1665
1675
|
subtasks)
|
|
1666
|
-
COMPREPLY=($(compgen -W "--json" -- "$cur"))
|
|
1676
|
+
COMPREPLY=($(compgen -W "--status --name --include-closed --json" -- "$cur"))
|
|
1667
1677
|
;;
|
|
1668
1678
|
comment)
|
|
1669
|
-
COMPREPLY=($(compgen -W "--message" -- "$cur"))
|
|
1679
|
+
COMPREPLY=($(compgen -W "-m --message --json" -- "$cur"))
|
|
1670
1680
|
;;
|
|
1671
1681
|
comments)
|
|
1672
1682
|
COMPREPLY=($(compgen -W "--json" -- "$cur"))
|
|
1673
1683
|
;;
|
|
1684
|
+
activity)
|
|
1685
|
+
COMPREPLY=($(compgen -W "--json" -- "$cur"))
|
|
1686
|
+
;;
|
|
1674
1687
|
lists)
|
|
1675
1688
|
COMPREPLY=($(compgen -W "--name --json" -- "$cur"))
|
|
1676
1689
|
;;
|
|
@@ -1678,23 +1691,44 @@ function bashCompletion() {
|
|
|
1678
1691
|
COMPREPLY=($(compgen -W "--name --my --json" -- "$cur"))
|
|
1679
1692
|
;;
|
|
1680
1693
|
inbox)
|
|
1681
|
-
COMPREPLY=($(compgen -W "--json --days" -- "$cur"))
|
|
1694
|
+
COMPREPLY=($(compgen -W "--include-closed --json --days" -- "$cur"))
|
|
1682
1695
|
;;
|
|
1683
1696
|
assigned)
|
|
1684
|
-
COMPREPLY=($(compgen -W "--include-closed --json" -- "$cur"))
|
|
1697
|
+
COMPREPLY=($(compgen -W "--status --include-closed --json" -- "$cur"))
|
|
1685
1698
|
;;
|
|
1686
1699
|
open)
|
|
1687
1700
|
COMPREPLY=($(compgen -W "--json" -- "$cur"))
|
|
1688
1701
|
;;
|
|
1702
|
+
search)
|
|
1703
|
+
COMPREPLY=($(compgen -W "--status --include-closed --json" -- "$cur"))
|
|
1704
|
+
;;
|
|
1689
1705
|
summary)
|
|
1690
1706
|
COMPREPLY=($(compgen -W "--hours --json" -- "$cur"))
|
|
1691
1707
|
;;
|
|
1692
1708
|
overdue)
|
|
1693
|
-
COMPREPLY=($(compgen -W "--json" -- "$cur"))
|
|
1709
|
+
COMPREPLY=($(compgen -W "--include-closed --json" -- "$cur"))
|
|
1694
1710
|
;;
|
|
1695
1711
|
assign)
|
|
1696
1712
|
COMPREPLY=($(compgen -W "--to --remove --json" -- "$cur"))
|
|
1697
1713
|
;;
|
|
1714
|
+
auth)
|
|
1715
|
+
COMPREPLY=($(compgen -W "--json" -- "$cur"))
|
|
1716
|
+
;;
|
|
1717
|
+
depend)
|
|
1718
|
+
COMPREPLY=($(compgen -W "--on --blocks --remove --json" -- "$cur"))
|
|
1719
|
+
;;
|
|
1720
|
+
move)
|
|
1721
|
+
COMPREPLY=($(compgen -W "--to --remove --json" -- "$cur"))
|
|
1722
|
+
;;
|
|
1723
|
+
field)
|
|
1724
|
+
COMPREPLY=($(compgen -W "--set --remove --json" -- "$cur"))
|
|
1725
|
+
;;
|
|
1726
|
+
delete)
|
|
1727
|
+
COMPREPLY=($(compgen -W "--confirm --json" -- "$cur"))
|
|
1728
|
+
;;
|
|
1729
|
+
tag)
|
|
1730
|
+
COMPREPLY=($(compgen -W "--add --remove --json" -- "$cur"))
|
|
1731
|
+
;;
|
|
1698
1732
|
config)
|
|
1699
1733
|
if [[ $cword -eq 2 ]]; then
|
|
1700
1734
|
COMPREPLY=($(compgen -W "get set path" -- "$cur"))
|
|
@@ -1722,23 +1756,32 @@ _cu() {
|
|
|
1722
1756
|
local -a commands
|
|
1723
1757
|
commands=(
|
|
1724
1758
|
'init:Set up cu for the first time'
|
|
1759
|
+
'auth:Validate API token and show current user'
|
|
1725
1760
|
'tasks:List tasks assigned to me'
|
|
1726
1761
|
'initiatives:List initiatives assigned to me'
|
|
1727
1762
|
'task:Get task details'
|
|
1728
1763
|
'update:Update a task'
|
|
1729
1764
|
'create:Create a new task'
|
|
1730
1765
|
'sprint:List my tasks in the current active sprint'
|
|
1766
|
+
'sprints:List all sprints in sprint folders'
|
|
1731
1767
|
'subtasks:List subtasks of a task or initiative'
|
|
1732
1768
|
'comment:Post a comment on a task'
|
|
1733
1769
|
'comments:List comments on a task'
|
|
1770
|
+
'activity:Show task details and comments combined'
|
|
1734
1771
|
'lists:List all lists in a space'
|
|
1735
1772
|
'spaces:List spaces in your workspace'
|
|
1736
1773
|
'inbox:Recently updated tasks grouped by time period'
|
|
1737
1774
|
'assigned:Show all tasks assigned to me'
|
|
1738
1775
|
'open:Open a task in the browser by ID or name'
|
|
1776
|
+
'search:Search my tasks by name'
|
|
1739
1777
|
'summary:Daily standup summary'
|
|
1740
1778
|
'overdue:List tasks that are past their due date'
|
|
1741
1779
|
'assign:Assign or unassign users from a task'
|
|
1780
|
+
'depend:Add or remove task dependencies'
|
|
1781
|
+
'move:Add or remove a task from a list'
|
|
1782
|
+
'field:Set or remove a custom field value on a task'
|
|
1783
|
+
'delete:Delete a task'
|
|
1784
|
+
'tag:Add or remove tags from a task'
|
|
1742
1785
|
'config:Manage CLI configuration'
|
|
1743
1786
|
'completion:Output shell completion script'
|
|
1744
1787
|
)
|
|
@@ -1761,6 +1804,7 @@ _cu() {
|
|
|
1761
1804
|
'--list[Filter by list ID]:list_id:' \\
|
|
1762
1805
|
'--space[Filter by space ID]:space_id:' \\
|
|
1763
1806
|
'--name[Filter by name]:query:' \\
|
|
1807
|
+
'--include-closed[Include done/closed tasks]' \\
|
|
1764
1808
|
'--json[Force JSON output]'
|
|
1765
1809
|
;;
|
|
1766
1810
|
task)
|
|
@@ -1776,7 +1820,10 @@ _cu() {
|
|
|
1776
1820
|
'(-s --status)'{-s,--status}'[New status]:status:(open "in progress" "in review" done closed)' \\
|
|
1777
1821
|
'--priority[Priority level]:priority:(urgent high normal low)' \\
|
|
1778
1822
|
'--due-date[Due date]:date:' \\
|
|
1779
|
-
'--
|
|
1823
|
+
'--time-estimate[Time estimate]:duration:' \\
|
|
1824
|
+
'--assignee[Add assignee]:user_id:' \\
|
|
1825
|
+
'--parent[Set parent task]:task_id:' \\
|
|
1826
|
+
'--json[Force JSON output]'
|
|
1780
1827
|
;;
|
|
1781
1828
|
create)
|
|
1782
1829
|
_arguments \\
|
|
@@ -1788,29 +1835,47 @@ _cu() {
|
|
|
1788
1835
|
'--priority[Priority level]:priority:(urgent high normal low)' \\
|
|
1789
1836
|
'--due-date[Due date]:date:' \\
|
|
1790
1837
|
'--assignee[Assignee user ID]:user_id:' \\
|
|
1791
|
-
'--tags[Comma-separated tag names]:tags:'
|
|
1838
|
+
'--tags[Comma-separated tag names]:tags:' \\
|
|
1839
|
+
'--custom-item-id[Custom task type ID]:id:' \\
|
|
1840
|
+
'--time-estimate[Time estimate]:duration:' \\
|
|
1841
|
+
'--json[Force JSON output]'
|
|
1792
1842
|
;;
|
|
1793
1843
|
sprint)
|
|
1794
1844
|
_arguments \\
|
|
1795
1845
|
'--status[Filter by status]:status:(open "in progress" "in review" done closed)' \\
|
|
1796
1846
|
'--space[Narrow sprint search to a space]:space:' \\
|
|
1847
|
+
'--include-closed[Include done/closed tasks]' \\
|
|
1848
|
+
'--json[Force JSON output]'
|
|
1849
|
+
;;
|
|
1850
|
+
sprints)
|
|
1851
|
+
_arguments \\
|
|
1852
|
+
'--space[Filter by space]:space:' \\
|
|
1797
1853
|
'--json[Force JSON output]'
|
|
1798
1854
|
;;
|
|
1799
1855
|
subtasks)
|
|
1800
1856
|
_arguments \\
|
|
1801
1857
|
'1:task_id:' \\
|
|
1858
|
+
'--status[Filter by status]:status:(open "in progress" "in review" done closed)' \\
|
|
1859
|
+
'--name[Filter by name]:query:' \\
|
|
1860
|
+
'--include-closed[Include closed/done subtasks]' \\
|
|
1802
1861
|
'--json[Force JSON output]'
|
|
1803
1862
|
;;
|
|
1804
1863
|
comment)
|
|
1805
1864
|
_arguments \\
|
|
1806
1865
|
'1:task_id:' \\
|
|
1807
|
-
'(-m --message)'{-m,--message}'[Comment text]:text:'
|
|
1866
|
+
'(-m --message)'{-m,--message}'[Comment text]:text:' \\
|
|
1867
|
+
'--json[Force JSON output]'
|
|
1808
1868
|
;;
|
|
1809
1869
|
comments)
|
|
1810
1870
|
_arguments \\
|
|
1811
1871
|
'1:task_id:' \\
|
|
1812
1872
|
'--json[Force JSON output]'
|
|
1813
1873
|
;;
|
|
1874
|
+
activity)
|
|
1875
|
+
_arguments \\
|
|
1876
|
+
'1:task_id:' \\
|
|
1877
|
+
'--json[Force JSON output]'
|
|
1878
|
+
;;
|
|
1814
1879
|
lists)
|
|
1815
1880
|
_arguments \\
|
|
1816
1881
|
'1:space_id:' \\
|
|
@@ -1825,11 +1890,13 @@ _cu() {
|
|
|
1825
1890
|
;;
|
|
1826
1891
|
inbox)
|
|
1827
1892
|
_arguments \\
|
|
1893
|
+
'--include-closed[Include done/closed tasks]' \\
|
|
1828
1894
|
'--json[Force JSON output]' \\
|
|
1829
1895
|
'--days[Lookback period in days]:days:'
|
|
1830
1896
|
;;
|
|
1831
1897
|
assigned)
|
|
1832
1898
|
_arguments \\
|
|
1899
|
+
'--status[Show only tasks with this status]:status:(open "in progress" "in review" done closed)' \\
|
|
1833
1900
|
'--include-closed[Include done/closed tasks]' \\
|
|
1834
1901
|
'--json[Force JSON output]'
|
|
1835
1902
|
;;
|
|
@@ -1838,6 +1905,13 @@ _cu() {
|
|
|
1838
1905
|
'1:query:' \\
|
|
1839
1906
|
'--json[Output task JSON instead of opening]'
|
|
1840
1907
|
;;
|
|
1908
|
+
search)
|
|
1909
|
+
_arguments \\
|
|
1910
|
+
'1:query:' \\
|
|
1911
|
+
'--status[Filter by status]:status:(open "in progress" "in review" done closed)' \\
|
|
1912
|
+
'--include-closed[Include done/closed tasks in search]' \\
|
|
1913
|
+
'--json[Force JSON output]'
|
|
1914
|
+
;;
|
|
1841
1915
|
summary)
|
|
1842
1916
|
_arguments \\
|
|
1843
1917
|
'--hours[Completed-tasks lookback in hours]:hours:' \\
|
|
@@ -1845,6 +1919,7 @@ _cu() {
|
|
|
1845
1919
|
;;
|
|
1846
1920
|
overdue)
|
|
1847
1921
|
_arguments \\
|
|
1922
|
+
'--include-closed[Include done/closed overdue tasks]' \\
|
|
1848
1923
|
'--json[Force JSON output]'
|
|
1849
1924
|
;;
|
|
1850
1925
|
assign)
|
|
@@ -1854,6 +1929,45 @@ _cu() {
|
|
|
1854
1929
|
'--remove[Remove assignee]:user_id:' \\
|
|
1855
1930
|
'--json[Force JSON output]'
|
|
1856
1931
|
;;
|
|
1932
|
+
auth)
|
|
1933
|
+
_arguments \\
|
|
1934
|
+
'--json[Force JSON output]'
|
|
1935
|
+
;;
|
|
1936
|
+
depend)
|
|
1937
|
+
_arguments \\
|
|
1938
|
+
'1:task_id:' \\
|
|
1939
|
+
'--on[Task that this task depends on]:task_id:' \\
|
|
1940
|
+
'--blocks[Task that this task blocks]:task_id:' \\
|
|
1941
|
+
'--remove[Remove the dependency instead of adding it]' \\
|
|
1942
|
+
'--json[Force JSON output]'
|
|
1943
|
+
;;
|
|
1944
|
+
move)
|
|
1945
|
+
_arguments \\
|
|
1946
|
+
'1:task_id:' \\
|
|
1947
|
+
'--to[Add task to this list]:list_id:' \\
|
|
1948
|
+
'--remove[Remove task from this list]:list_id:' \\
|
|
1949
|
+
'--json[Force JSON output]'
|
|
1950
|
+
;;
|
|
1951
|
+
field)
|
|
1952
|
+
_arguments \\
|
|
1953
|
+
'1:task_id:' \\
|
|
1954
|
+
'--set[Set field name and value]:name_and_value:' \\
|
|
1955
|
+
'--remove[Remove field value by name]:field_name:' \\
|
|
1956
|
+
'--json[Force JSON output]'
|
|
1957
|
+
;;
|
|
1958
|
+
delete)
|
|
1959
|
+
_arguments \\
|
|
1960
|
+
'1:task_id:' \\
|
|
1961
|
+
'--confirm[Skip confirmation prompt]' \\
|
|
1962
|
+
'--json[Force JSON output]'
|
|
1963
|
+
;;
|
|
1964
|
+
tag)
|
|
1965
|
+
_arguments \\
|
|
1966
|
+
'1:task_id:' \\
|
|
1967
|
+
'--add[Comma-separated tag names to add]:tags:' \\
|
|
1968
|
+
'--remove[Comma-separated tag names to remove]:tags:' \\
|
|
1969
|
+
'--json[Force JSON output]'
|
|
1970
|
+
;;
|
|
1857
1971
|
config)
|
|
1858
1972
|
local -a config_cmds
|
|
1859
1973
|
config_cmds=(
|
|
@@ -1889,54 +2003,62 @@ _cu
|
|
|
1889
2003
|
`;
|
|
1890
2004
|
}
|
|
1891
2005
|
function fishCompletion() {
|
|
1892
|
-
return
|
|
1893
|
-
complete -c cu -f
|
|
2006
|
+
return `complete -c cu -f
|
|
1894
2007
|
|
|
1895
|
-
# Global flags
|
|
1896
2008
|
complete -c cu -n __fish_use_subcommand -s h -l help -d 'Show help'
|
|
1897
2009
|
complete -c cu -n __fish_use_subcommand -s V -l version -d 'Show version'
|
|
1898
2010
|
|
|
1899
|
-
# Commands
|
|
1900
2011
|
complete -c cu -n __fish_use_subcommand -a init -d 'Set up cu for the first time'
|
|
2012
|
+
complete -c cu -n __fish_use_subcommand -a auth -d 'Validate API token and show current user'
|
|
1901
2013
|
complete -c cu -n __fish_use_subcommand -a tasks -d 'List tasks assigned to me'
|
|
1902
2014
|
complete -c cu -n __fish_use_subcommand -a initiatives -d 'List initiatives assigned to me'
|
|
1903
2015
|
complete -c cu -n __fish_use_subcommand -a task -d 'Get task details'
|
|
1904
2016
|
complete -c cu -n __fish_use_subcommand -a update -d 'Update a task'
|
|
1905
2017
|
complete -c cu -n __fish_use_subcommand -a create -d 'Create a new task'
|
|
1906
2018
|
complete -c cu -n __fish_use_subcommand -a sprint -d 'List my tasks in the current active sprint'
|
|
2019
|
+
complete -c cu -n __fish_use_subcommand -a sprints -d 'List all sprints in sprint folders'
|
|
1907
2020
|
complete -c cu -n __fish_use_subcommand -a subtasks -d 'List subtasks of a task or initiative'
|
|
1908
2021
|
complete -c cu -n __fish_use_subcommand -a comment -d 'Post a comment on a task'
|
|
1909
2022
|
complete -c cu -n __fish_use_subcommand -a comments -d 'List comments on a task'
|
|
2023
|
+
complete -c cu -n __fish_use_subcommand -a activity -d 'Show task details and comments combined'
|
|
1910
2024
|
complete -c cu -n __fish_use_subcommand -a lists -d 'List all lists in a space'
|
|
1911
2025
|
complete -c cu -n __fish_use_subcommand -a spaces -d 'List spaces in your workspace'
|
|
1912
2026
|
complete -c cu -n __fish_use_subcommand -a inbox -d 'Recently updated tasks grouped by time period'
|
|
1913
2027
|
complete -c cu -n __fish_use_subcommand -a assigned -d 'Show all tasks assigned to me'
|
|
1914
2028
|
complete -c cu -n __fish_use_subcommand -a open -d 'Open a task in the browser by ID or name'
|
|
2029
|
+
complete -c cu -n __fish_use_subcommand -a search -d 'Search my tasks by name'
|
|
1915
2030
|
complete -c cu -n __fish_use_subcommand -a summary -d 'Daily standup summary'
|
|
1916
2031
|
complete -c cu -n __fish_use_subcommand -a overdue -d 'List tasks that are past their due date'
|
|
1917
2032
|
complete -c cu -n __fish_use_subcommand -a assign -d 'Assign or unassign users from a task'
|
|
2033
|
+
complete -c cu -n __fish_use_subcommand -a depend -d 'Add or remove task dependencies'
|
|
2034
|
+
complete -c cu -n __fish_use_subcommand -a move -d 'Add or remove a task from a list'
|
|
2035
|
+
complete -c cu -n __fish_use_subcommand -a field -d 'Set or remove a custom field value on a task'
|
|
2036
|
+
complete -c cu -n __fish_use_subcommand -a delete -d 'Delete a task'
|
|
2037
|
+
complete -c cu -n __fish_use_subcommand -a tag -d 'Add or remove tags from a task'
|
|
1918
2038
|
complete -c cu -n __fish_use_subcommand -a config -d 'Manage CLI configuration'
|
|
1919
2039
|
complete -c cu -n __fish_use_subcommand -a completion -d 'Output shell completion script'
|
|
1920
2040
|
|
|
1921
|
-
|
|
2041
|
+
complete -c cu -n '__fish_seen_subcommand_from auth' -l json -d 'Force JSON output'
|
|
2042
|
+
|
|
1922
2043
|
complete -c cu -n '__fish_seen_subcommand_from tasks initiatives' -l status -d 'Filter by status'
|
|
1923
2044
|
complete -c cu -n '__fish_seen_subcommand_from tasks initiatives' -l list -d 'Filter by list ID'
|
|
1924
2045
|
complete -c cu -n '__fish_seen_subcommand_from tasks initiatives' -l space -d 'Filter by space ID'
|
|
1925
2046
|
complete -c cu -n '__fish_seen_subcommand_from tasks initiatives' -l name -d 'Filter by name'
|
|
2047
|
+
complete -c cu -n '__fish_seen_subcommand_from tasks initiatives' -l include-closed -d 'Include done/closed tasks'
|
|
1926
2048
|
complete -c cu -n '__fish_seen_subcommand_from tasks initiatives' -l json -d 'Force JSON output'
|
|
1927
2049
|
|
|
1928
|
-
# task flags
|
|
1929
2050
|
complete -c cu -n '__fish_seen_subcommand_from task' -l json -d 'Force JSON output'
|
|
1930
2051
|
|
|
1931
|
-
# update flags
|
|
1932
2052
|
complete -c cu -n '__fish_seen_subcommand_from update' -s n -l name -d 'New task name'
|
|
1933
2053
|
complete -c cu -n '__fish_seen_subcommand_from update' -s d -l description -d 'New description'
|
|
1934
2054
|
complete -c cu -n '__fish_seen_subcommand_from update' -s s -l status -d 'New status'
|
|
1935
2055
|
complete -c cu -n '__fish_seen_subcommand_from update' -l priority -d 'Priority level' -a 'urgent high normal low'
|
|
1936
2056
|
complete -c cu -n '__fish_seen_subcommand_from update' -l due-date -d 'Due date'
|
|
2057
|
+
complete -c cu -n '__fish_seen_subcommand_from update' -l time-estimate -d 'Time estimate'
|
|
1937
2058
|
complete -c cu -n '__fish_seen_subcommand_from update' -l assignee -d 'Add assignee'
|
|
2059
|
+
complete -c cu -n '__fish_seen_subcommand_from update' -l parent -d 'Set parent task'
|
|
2060
|
+
complete -c cu -n '__fish_seen_subcommand_from update' -l json -d 'Force JSON output'
|
|
1938
2061
|
|
|
1939
|
-
# create flags
|
|
1940
2062
|
complete -c cu -n '__fish_seen_subcommand_from create' -s l -l list -d 'Target list ID'
|
|
1941
2063
|
complete -c cu -n '__fish_seen_subcommand_from create' -s n -l name -d 'Task name'
|
|
1942
2064
|
complete -c cu -n '__fish_seen_subcommand_from create' -s d -l description -d 'Task description'
|
|
@@ -1946,60 +2068,86 @@ complete -c cu -n '__fish_seen_subcommand_from create' -l priority -d 'Priority
|
|
|
1946
2068
|
complete -c cu -n '__fish_seen_subcommand_from create' -l due-date -d 'Due date'
|
|
1947
2069
|
complete -c cu -n '__fish_seen_subcommand_from create' -l assignee -d 'Assignee user ID'
|
|
1948
2070
|
complete -c cu -n '__fish_seen_subcommand_from create' -l tags -d 'Comma-separated tag names'
|
|
2071
|
+
complete -c cu -n '__fish_seen_subcommand_from create' -l custom-item-id -d 'Custom task type ID'
|
|
2072
|
+
complete -c cu -n '__fish_seen_subcommand_from create' -l time-estimate -d 'Time estimate'
|
|
2073
|
+
complete -c cu -n '__fish_seen_subcommand_from create' -l json -d 'Force JSON output'
|
|
1949
2074
|
|
|
1950
|
-
# sprint flags
|
|
1951
2075
|
complete -c cu -n '__fish_seen_subcommand_from sprint' -l status -d 'Filter by status'
|
|
1952
2076
|
complete -c cu -n '__fish_seen_subcommand_from sprint' -l space -d 'Narrow sprint search to a space'
|
|
2077
|
+
complete -c cu -n '__fish_seen_subcommand_from sprint' -l include-closed -d 'Include done/closed tasks'
|
|
1953
2078
|
complete -c cu -n '__fish_seen_subcommand_from sprint' -l json -d 'Force JSON output'
|
|
1954
2079
|
|
|
1955
|
-
|
|
2080
|
+
complete -c cu -n '__fish_seen_subcommand_from sprints' -l space -d 'Filter by space'
|
|
2081
|
+
complete -c cu -n '__fish_seen_subcommand_from sprints' -l json -d 'Force JSON output'
|
|
2082
|
+
|
|
2083
|
+
complete -c cu -n '__fish_seen_subcommand_from subtasks' -l status -d 'Filter by status'
|
|
2084
|
+
complete -c cu -n '__fish_seen_subcommand_from subtasks' -l name -d 'Filter by name'
|
|
2085
|
+
complete -c cu -n '__fish_seen_subcommand_from subtasks' -l include-closed -d 'Include closed/done subtasks'
|
|
1956
2086
|
complete -c cu -n '__fish_seen_subcommand_from subtasks' -l json -d 'Force JSON output'
|
|
1957
2087
|
|
|
1958
|
-
# comment flags
|
|
1959
2088
|
complete -c cu -n '__fish_seen_subcommand_from comment' -s m -l message -d 'Comment text'
|
|
2089
|
+
complete -c cu -n '__fish_seen_subcommand_from comment' -l json -d 'Force JSON output'
|
|
1960
2090
|
|
|
1961
|
-
# comments flags
|
|
1962
2091
|
complete -c cu -n '__fish_seen_subcommand_from comments' -l json -d 'Force JSON output'
|
|
1963
2092
|
|
|
1964
|
-
|
|
2093
|
+
complete -c cu -n '__fish_seen_subcommand_from activity' -l json -d 'Force JSON output'
|
|
2094
|
+
|
|
1965
2095
|
complete -c cu -n '__fish_seen_subcommand_from lists' -l name -d 'Filter by name'
|
|
1966
2096
|
complete -c cu -n '__fish_seen_subcommand_from lists' -l json -d 'Force JSON output'
|
|
1967
2097
|
|
|
1968
|
-
# spaces flags
|
|
1969
2098
|
complete -c cu -n '__fish_seen_subcommand_from spaces' -l name -d 'Filter spaces by name'
|
|
1970
2099
|
complete -c cu -n '__fish_seen_subcommand_from spaces' -l my -d 'Show only spaces where I have assigned tasks'
|
|
1971
2100
|
complete -c cu -n '__fish_seen_subcommand_from spaces' -l json -d 'Force JSON output'
|
|
1972
2101
|
|
|
1973
|
-
|
|
2102
|
+
complete -c cu -n '__fish_seen_subcommand_from inbox' -l include-closed -d 'Include done/closed tasks'
|
|
1974
2103
|
complete -c cu -n '__fish_seen_subcommand_from inbox' -l json -d 'Force JSON output'
|
|
1975
2104
|
complete -c cu -n '__fish_seen_subcommand_from inbox' -l days -d 'Lookback period in days'
|
|
1976
2105
|
|
|
1977
|
-
|
|
2106
|
+
complete -c cu -n '__fish_seen_subcommand_from assigned' -l status -d 'Show only tasks with this status'
|
|
1978
2107
|
complete -c cu -n '__fish_seen_subcommand_from assigned' -l include-closed -d 'Include done/closed tasks'
|
|
1979
2108
|
complete -c cu -n '__fish_seen_subcommand_from assigned' -l json -d 'Force JSON output'
|
|
1980
2109
|
|
|
1981
|
-
# open flags
|
|
1982
2110
|
complete -c cu -n '__fish_seen_subcommand_from open' -l json -d 'Output task JSON instead of opening'
|
|
1983
2111
|
|
|
1984
|
-
|
|
2112
|
+
complete -c cu -n '__fish_seen_subcommand_from search' -l status -d 'Filter by status'
|
|
2113
|
+
complete -c cu -n '__fish_seen_subcommand_from search' -l include-closed -d 'Include done/closed tasks in search'
|
|
2114
|
+
complete -c cu -n '__fish_seen_subcommand_from search' -l json -d 'Force JSON output'
|
|
2115
|
+
|
|
1985
2116
|
complete -c cu -n '__fish_seen_subcommand_from summary' -l hours -d 'Completed-tasks lookback in hours'
|
|
1986
2117
|
complete -c cu -n '__fish_seen_subcommand_from summary' -l json -d 'Force JSON output'
|
|
1987
2118
|
|
|
1988
|
-
|
|
2119
|
+
complete -c cu -n '__fish_seen_subcommand_from overdue' -l include-closed -d 'Include done/closed overdue tasks'
|
|
1989
2120
|
complete -c cu -n '__fish_seen_subcommand_from overdue' -l json -d 'Force JSON output'
|
|
1990
2121
|
|
|
1991
|
-
# assign flags
|
|
1992
2122
|
complete -c cu -n '__fish_seen_subcommand_from assign' -l to -d 'Add assignee'
|
|
1993
2123
|
complete -c cu -n '__fish_seen_subcommand_from assign' -l remove -d 'Remove assignee'
|
|
1994
2124
|
complete -c cu -n '__fish_seen_subcommand_from assign' -l json -d 'Force JSON output'
|
|
1995
2125
|
|
|
1996
|
-
|
|
2126
|
+
complete -c cu -n '__fish_seen_subcommand_from depend' -l on -d 'Task that this task depends on'
|
|
2127
|
+
complete -c cu -n '__fish_seen_subcommand_from depend' -l blocks -d 'Task that this task blocks'
|
|
2128
|
+
complete -c cu -n '__fish_seen_subcommand_from depend' -l remove -d 'Remove the dependency'
|
|
2129
|
+
complete -c cu -n '__fish_seen_subcommand_from depend' -l json -d 'Force JSON output'
|
|
2130
|
+
|
|
2131
|
+
complete -c cu -n '__fish_seen_subcommand_from move' -l to -d 'Add task to this list'
|
|
2132
|
+
complete -c cu -n '__fish_seen_subcommand_from move' -l remove -d 'Remove task from this list'
|
|
2133
|
+
complete -c cu -n '__fish_seen_subcommand_from move' -l json -d 'Force JSON output'
|
|
2134
|
+
|
|
2135
|
+
complete -c cu -n '__fish_seen_subcommand_from field' -l set -d 'Set field name and value'
|
|
2136
|
+
complete -c cu -n '__fish_seen_subcommand_from field' -l remove -d 'Remove field value by name'
|
|
2137
|
+
complete -c cu -n '__fish_seen_subcommand_from field' -l json -d 'Force JSON output'
|
|
2138
|
+
|
|
2139
|
+
complete -c cu -n '__fish_seen_subcommand_from delete' -l confirm -d 'Skip confirmation prompt'
|
|
2140
|
+
complete -c cu -n '__fish_seen_subcommand_from delete' -l json -d 'Force JSON output'
|
|
2141
|
+
|
|
2142
|
+
complete -c cu -n '__fish_seen_subcommand_from tag' -l add -d 'Comma-separated tag names to add'
|
|
2143
|
+
complete -c cu -n '__fish_seen_subcommand_from tag' -l remove -d 'Comma-separated tag names to remove'
|
|
2144
|
+
complete -c cu -n '__fish_seen_subcommand_from tag' -l json -d 'Force JSON output'
|
|
2145
|
+
|
|
1997
2146
|
complete -c cu -n '__fish_seen_subcommand_from config; and not __fish_seen_subcommand_from get set path' -a get -d 'Print a config value'
|
|
1998
2147
|
complete -c cu -n '__fish_seen_subcommand_from config; and not __fish_seen_subcommand_from get set path' -a set -d 'Set a config value'
|
|
1999
2148
|
complete -c cu -n '__fish_seen_subcommand_from config; and not __fish_seen_subcommand_from get set path' -a path -d 'Print config file path'
|
|
2000
2149
|
complete -c cu -n '__fish_seen_subcommand_from get set' -a 'apiToken teamId' -d 'Config key'
|
|
2001
2150
|
|
|
2002
|
-
# completion subcommand
|
|
2003
2151
|
complete -c cu -n '__fish_seen_subcommand_from completion' -a 'bash zsh fish' -d 'Shell type'
|
|
2004
2152
|
`;
|
|
2005
2153
|
}
|
|
@@ -2113,6 +2261,140 @@ async function moveTask(config, taskId, opts) {
|
|
|
2113
2261
|
return messages.join("; ");
|
|
2114
2262
|
}
|
|
2115
2263
|
|
|
2264
|
+
// src/commands/field.ts
|
|
2265
|
+
var SUPPORTED_TYPES = /* @__PURE__ */ new Set(["text", "number", "drop_down", "checkbox", "date", "url", "email"]);
|
|
2266
|
+
function findFieldByName(fields, name) {
|
|
2267
|
+
const lower = name.toLowerCase();
|
|
2268
|
+
const match = fields.find((f) => f.name.toLowerCase() === lower);
|
|
2269
|
+
if (!match) {
|
|
2270
|
+
const available = fields.map((f) => f.name).join(", ");
|
|
2271
|
+
throw new Error(`Field "${name}" not found. Available fields: ${available}`);
|
|
2272
|
+
}
|
|
2273
|
+
return match;
|
|
2274
|
+
}
|
|
2275
|
+
function parseFieldValue(field, rawValue) {
|
|
2276
|
+
if (!SUPPORTED_TYPES.has(field.type)) {
|
|
2277
|
+
throw new Error(
|
|
2278
|
+
`Field type "${field.type}" is not supported. Supported types: ${[...SUPPORTED_TYPES].join(", ")}`
|
|
2279
|
+
);
|
|
2280
|
+
}
|
|
2281
|
+
switch (field.type) {
|
|
2282
|
+
case "number": {
|
|
2283
|
+
const n = Number(rawValue);
|
|
2284
|
+
if (!Number.isFinite(n)) throw new Error(`Value "${rawValue}" is not a valid numeric value`);
|
|
2285
|
+
return n;
|
|
2286
|
+
}
|
|
2287
|
+
case "checkbox":
|
|
2288
|
+
if (rawValue !== "true" && rawValue !== "false") {
|
|
2289
|
+
throw new Error('Checkbox value must be "true" or "false"');
|
|
2290
|
+
}
|
|
2291
|
+
return rawValue === "true";
|
|
2292
|
+
case "drop_down": {
|
|
2293
|
+
const options = field.type_config?.options;
|
|
2294
|
+
if (!options?.length) throw new Error("Dropdown field has no configured options");
|
|
2295
|
+
const lower = rawValue.toLowerCase();
|
|
2296
|
+
const option = options.find((o) => o.name.toLowerCase() === lower);
|
|
2297
|
+
if (!option) {
|
|
2298
|
+
const available = options.map((o) => o.name).join(", ");
|
|
2299
|
+
throw new Error(`Option "${rawValue}" not found. Available options: ${available}`);
|
|
2300
|
+
}
|
|
2301
|
+
if (option.orderindex === void 0) {
|
|
2302
|
+
throw new Error(`Dropdown option "${option.name}" has no orderindex`);
|
|
2303
|
+
}
|
|
2304
|
+
return option.orderindex;
|
|
2305
|
+
}
|
|
2306
|
+
case "date": {
|
|
2307
|
+
const ms = new Date(rawValue).getTime();
|
|
2308
|
+
if (!Number.isFinite(ms))
|
|
2309
|
+
throw new Error(`Value "${rawValue}" is not a valid date (use YYYY-MM-DD)`);
|
|
2310
|
+
return ms;
|
|
2311
|
+
}
|
|
2312
|
+
default:
|
|
2313
|
+
return rawValue;
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
async function setCustomField(config, taskId, opts) {
|
|
2317
|
+
if (!opts.set && !opts.remove) {
|
|
2318
|
+
throw new Error("Provide at least one of: --set, --remove");
|
|
2319
|
+
}
|
|
2320
|
+
const client = new ClickUpClient(config);
|
|
2321
|
+
const task = await client.getTask(taskId);
|
|
2322
|
+
const fields = task.custom_fields ?? [];
|
|
2323
|
+
const results = [];
|
|
2324
|
+
if (opts.set) {
|
|
2325
|
+
const [fieldName, rawValue] = opts.set;
|
|
2326
|
+
const field = findFieldByName(fields, fieldName);
|
|
2327
|
+
const parsed = parseFieldValue(field, rawValue);
|
|
2328
|
+
await client.setCustomFieldValue(taskId, field.id, parsed);
|
|
2329
|
+
results.push({ taskId, field: field.name, action: "set", value: parsed });
|
|
2330
|
+
}
|
|
2331
|
+
if (opts.remove) {
|
|
2332
|
+
const field = findFieldByName(fields, opts.remove);
|
|
2333
|
+
await client.removeCustomFieldValue(taskId, field.id);
|
|
2334
|
+
results.push({ taskId, field: field.name, action: "removed" });
|
|
2335
|
+
}
|
|
2336
|
+
return { results };
|
|
2337
|
+
}
|
|
2338
|
+
|
|
2339
|
+
// src/commands/delete.ts
|
|
2340
|
+
async function deleteTaskCommand(config, taskId, opts) {
|
|
2341
|
+
const client = new ClickUpClient(config);
|
|
2342
|
+
if (!opts.confirm) {
|
|
2343
|
+
if (!isTTY()) {
|
|
2344
|
+
throw new Error("Destructive operation requires --confirm flag in non-interactive mode");
|
|
2345
|
+
}
|
|
2346
|
+
const task = await client.getTask(taskId);
|
|
2347
|
+
const { confirm: confirm3 } = await import("@inquirer/prompts");
|
|
2348
|
+
const confirmed = await confirm3({
|
|
2349
|
+
message: `Delete task "${task.name}" (${task.id})? This cannot be undone.`,
|
|
2350
|
+
default: false
|
|
2351
|
+
});
|
|
2352
|
+
if (!confirmed) {
|
|
2353
|
+
throw new Error("Cancelled");
|
|
2354
|
+
}
|
|
2355
|
+
}
|
|
2356
|
+
await client.deleteTask(taskId);
|
|
2357
|
+
return { taskId, deleted: true };
|
|
2358
|
+
}
|
|
2359
|
+
|
|
2360
|
+
// src/commands/tag.ts
|
|
2361
|
+
function parseTags(input) {
|
|
2362
|
+
return input.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
2363
|
+
}
|
|
2364
|
+
async function manageTags(config, taskId, opts) {
|
|
2365
|
+
if (!opts.add && !opts.remove) {
|
|
2366
|
+
throw new Error("Provide at least one of: --add, --remove");
|
|
2367
|
+
}
|
|
2368
|
+
const client = new ClickUpClient(config);
|
|
2369
|
+
const added = [];
|
|
2370
|
+
const removed = [];
|
|
2371
|
+
if (opts.add) {
|
|
2372
|
+
const tags = parseTags(opts.add);
|
|
2373
|
+
for (const tag of tags) {
|
|
2374
|
+
await client.addTagToTask(taskId, tag);
|
|
2375
|
+
added.push(tag);
|
|
2376
|
+
}
|
|
2377
|
+
}
|
|
2378
|
+
if (opts.remove) {
|
|
2379
|
+
const tags = parseTags(opts.remove);
|
|
2380
|
+
try {
|
|
2381
|
+
for (const tag of tags) {
|
|
2382
|
+
await client.removeTagFromTask(taskId, tag);
|
|
2383
|
+
removed.push(tag);
|
|
2384
|
+
}
|
|
2385
|
+
} catch (err) {
|
|
2386
|
+
if (added.length > 0) {
|
|
2387
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
2388
|
+
throw new Error(`Added tags: ${added.join(", ")}; but failed to remove: ${reason}`, {
|
|
2389
|
+
cause: err
|
|
2390
|
+
});
|
|
2391
|
+
}
|
|
2392
|
+
throw err;
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
return { taskId, added, removed };
|
|
2396
|
+
}
|
|
2397
|
+
|
|
2116
2398
|
// src/index.ts
|
|
2117
2399
|
var require2 = createRequire(import.meta.url);
|
|
2118
2400
|
var { version } = require2("../package.json");
|
|
@@ -2368,6 +2650,60 @@ program.command("move <taskId>").description("Add or remove a task from a list")
|
|
|
2368
2650
|
}
|
|
2369
2651
|
})
|
|
2370
2652
|
);
|
|
2653
|
+
program.command("field <taskId>").description("Set or remove a custom field value on a task").option("--set <nameAndValue...>", 'Set field: --set "Field Name" value').option("--remove <fieldName>", "Remove field value by name").option("--json", "Force JSON output even in terminal").action(
|
|
2654
|
+
wrapAction(
|
|
2655
|
+
async (taskId, opts) => {
|
|
2656
|
+
const config = loadConfig();
|
|
2657
|
+
const fieldOpts = {};
|
|
2658
|
+
if (opts.set) {
|
|
2659
|
+
if (opts.set.length !== 2) {
|
|
2660
|
+
throw new Error("--set requires exactly two arguments: field name and value");
|
|
2661
|
+
}
|
|
2662
|
+
fieldOpts.set = [opts.set[0], opts.set[1]];
|
|
2663
|
+
}
|
|
2664
|
+
if (opts.remove) {
|
|
2665
|
+
fieldOpts.remove = opts.remove;
|
|
2666
|
+
}
|
|
2667
|
+
const { results } = await setCustomField(config, taskId, fieldOpts);
|
|
2668
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
2669
|
+
console.log(JSON.stringify(results, null, 2));
|
|
2670
|
+
} else {
|
|
2671
|
+
for (const r of results) {
|
|
2672
|
+
if (r.action === "set") {
|
|
2673
|
+
console.log(`Set "${r.field}" to ${JSON.stringify(r.value)} on ${r.taskId}`);
|
|
2674
|
+
} else {
|
|
2675
|
+
console.log(`Removed "${r.field}" from ${r.taskId}`);
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2680
|
+
)
|
|
2681
|
+
);
|
|
2682
|
+
program.command("delete <taskId>").description("Delete a task (requires confirmation)").option("--confirm", "Skip confirmation prompt (required in non-interactive mode)").option("--json", "Force JSON output even in terminal").action(
|
|
2683
|
+
wrapAction(async (taskId, opts) => {
|
|
2684
|
+
const config = loadConfig();
|
|
2685
|
+
const result = await deleteTaskCommand(config, taskId, opts);
|
|
2686
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
2687
|
+
console.log(JSON.stringify(result, null, 2));
|
|
2688
|
+
} else {
|
|
2689
|
+
console.log(`Deleted task ${result.taskId}`);
|
|
2690
|
+
}
|
|
2691
|
+
})
|
|
2692
|
+
);
|
|
2693
|
+
program.command("tag <taskId>").description("Add or remove tags from a task").option("--add <tags>", "Comma-separated tag names to add").option("--remove <tags>", "Comma-separated tag names to remove").option("--json", "Force JSON output even in terminal").action(
|
|
2694
|
+
wrapAction(async (taskId, opts) => {
|
|
2695
|
+
const config = loadConfig();
|
|
2696
|
+
const result = await manageTags(config, taskId, opts);
|
|
2697
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
2698
|
+
console.log(JSON.stringify(result, null, 2));
|
|
2699
|
+
} else {
|
|
2700
|
+
const parts = [];
|
|
2701
|
+
if (result.added.length > 0) parts.push(`Added tags: ${result.added.join(", ")}`);
|
|
2702
|
+
if (result.removed.length > 0) parts.push(`Removed tags: ${result.removed.join(", ")}`);
|
|
2703
|
+
console.log(parts.join("; "));
|
|
2704
|
+
}
|
|
2705
|
+
})
|
|
2706
|
+
);
|
|
2371
2707
|
var configCmd = program.command("config").description("Manage CLI configuration");
|
|
2372
2708
|
configCmd.command("get <key>").description("Print a config value").action(
|
|
2373
2709
|
wrapAction(async (key) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: clickup
|
|
3
|
-
description: 'Use when managing ClickUp tasks, initiatives, sprints, or comments via the `cu` CLI tool. Triggers: task queries, status updates, sprint tracking, creating subtasks, posting comments, standup summaries, searching tasks, checking overdue items, assigning tasks, listing spaces and lists, opening tasks in browser, checking auth or config.'
|
|
3
|
+
description: 'Use when managing ClickUp tasks, initiatives, sprints, or comments via the `cu` CLI tool. Triggers: task queries, status updates, sprint tracking, creating subtasks, posting comments, 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.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# ClickUp CLI (`cu`)
|
|
@@ -64,38 +64,45 @@ All commands support `--help` for full flag details.
|
|
|
64
64
|
| `cu assign <id> [--to userId\|me] [--remove userId\|me] [--json]` | Assign/unassign users |
|
|
65
65
|
| `cu depend <id> [--on taskId] [--blocks taskId] [--remove] [--json]` | Add/remove task dependencies |
|
|
66
66
|
| `cu move <id> [--to listId] [--remove listId] [--json]` | Add/remove task from lists |
|
|
67
|
+
| `cu field <id> [--set "Name" value] [--remove "Name"] [--json]` | Set/remove custom field values |
|
|
68
|
+
| `cu delete <id> [--confirm] [--json]` | Delete a task (DESTRUCTIVE, irreversible) |
|
|
69
|
+
| `cu tag <id> [--add tags] [--remove tags] [--json]` | Add/remove tags on a task |
|
|
67
70
|
| `cu config get <key>` / `cu config set <key> <value>` / `cu config path` | Manage CLI config |
|
|
68
71
|
| `cu completion <shell>` | Shell completions (bash/zsh/fish) |
|
|
69
72
|
|
|
70
73
|
## Quick Reference
|
|
71
74
|
|
|
72
|
-
| Topic
|
|
73
|
-
|
|
|
74
|
-
| Task IDs
|
|
75
|
-
| Initiatives
|
|
76
|
-
| `--list` on create
|
|
77
|
-
| `--status`
|
|
78
|
-
| `--priority`
|
|
79
|
-
| `--due-date`
|
|
80
|
-
| `--assignee`
|
|
81
|
-
| `--tags`
|
|
82
|
-
| `--time-estimate`
|
|
83
|
-
| `--custom-item-id`
|
|
84
|
-
| `--on` / `--blocks`
|
|
85
|
-
| `--to` / `--remove`
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
|
|
|
89
|
-
| `cu
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `cu
|
|
94
|
-
| `cu
|
|
95
|
-
| `cu
|
|
96
|
-
| `cu
|
|
97
|
-
|
|
|
98
|
-
|
|
|
75
|
+
| Topic | Detail |
|
|
76
|
+
| ----------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
77
|
+
| Task IDs | Stable alphanumeric strings (e.g. `abc123def`) |
|
|
78
|
+
| Initiatives | Detected via `custom_item_id !== 0` |
|
|
79
|
+
| `--list` on create | Optional when `--parent` is given (auto-detected) |
|
|
80
|
+
| `--status` | Fuzzy matching: exact > starts-with > contains. Prints match to stderr. |
|
|
81
|
+
| `--priority` | Names (`urgent`, `high`, `normal`, `low`) or numbers (1-4) |
|
|
82
|
+
| `--due-date` | `YYYY-MM-DD` format |
|
|
83
|
+
| `--assignee` | Numeric user ID (find via `cu task <id> --json`) |
|
|
84
|
+
| `--tags` | Comma-separated (e.g. `--tags "bug,frontend"`) |
|
|
85
|
+
| `--time-estimate` | Duration format: `"2h"`, `"30m"`, `"1h30m"`, or raw milliseconds |
|
|
86
|
+
| `--custom-item-id` | Custom task type ID (e.g. `1` for initiative) |
|
|
87
|
+
| `--on` / `--blocks` | Task dependency direction (used with `cu depend`) |
|
|
88
|
+
| `--to` / `--remove` | List ID to add/remove task (used with `cu move`) |
|
|
89
|
+
| `cu field --set` | Supports: text, number, checkbox (true/false), dropdown (option name), date (YYYY-MM-DD), url, email |
|
|
90
|
+
| `cu field` | Field names resolved case-insensitively; errors list available fields/options |
|
|
91
|
+
| `cu delete` | DESTRUCTIVE. Requires `--confirm` in non-interactive mode. Cannot be undone |
|
|
92
|
+
| `cu tag --add/--remove` | Comma-separated tag names (e.g. `--add "bug,frontend"`) |
|
|
93
|
+
| `--space` | Partial name match or exact ID |
|
|
94
|
+
| `--name` | Partial match, case-insensitive |
|
|
95
|
+
| `--include-closed` | Include closed/done tasks (on `tasks`, `initiatives`, `assigned`, `subtasks`, `sprint`, `search`, `inbox`, `overdue`) |
|
|
96
|
+
| `cu assign --to me` | Shorthand for your own user ID |
|
|
97
|
+
| `cu search` | Matches all query words against task name, case-insensitive |
|
|
98
|
+
| `cu sprint` | Auto-detects active sprint via view API and date range parsing |
|
|
99
|
+
| `cu summary` | Categories: completed (done/complete/closed within N hours), in progress, overdue |
|
|
100
|
+
| `cu overdue` | Excludes closed tasks, sorted most overdue first |
|
|
101
|
+
| `cu open` | Tries task ID first, falls back to name search |
|
|
102
|
+
| `cu task` | Shows custom fields in detail view |
|
|
103
|
+
| `cu lists` | Discovers list IDs needed for `--list` and `cu create -l` |
|
|
104
|
+
| Errors | stderr with exit code 1 |
|
|
105
|
+
| Parsing | Strict - excess/unknown arguments rejected |
|
|
99
106
|
|
|
100
107
|
## Agent Workflow Examples
|
|
101
108
|
|
|
@@ -137,6 +144,12 @@ cu assign abc123def --to me
|
|
|
137
144
|
cu depend task3 --on task2 # task3 waits for task2
|
|
138
145
|
cu depend task1 --blocks task2 # task1 blocks task2
|
|
139
146
|
cu move task1 --to list2 --remove list1 # move between lists
|
|
147
|
+
cu field abc123def --set "Story Points" 5
|
|
148
|
+
cu field abc123def --set "Category" "Bug Fix"
|
|
149
|
+
cu field abc123def --remove "Old Field"
|
|
150
|
+
cu tag abc123def --add "bug,frontend"
|
|
151
|
+
cu tag abc123def --remove "triage"
|
|
152
|
+
cu delete abc123def --confirm # irreversible!
|
|
140
153
|
```
|
|
141
154
|
|
|
142
155
|
### Discover workspace structure
|
|
@@ -155,3 +168,7 @@ cu auth # verify token works
|
|
|
155
168
|
cu summary # completed / in progress / overdue
|
|
156
169
|
cu summary --hours 48 # wider window
|
|
157
170
|
```
|
|
171
|
+
|
|
172
|
+
## DELETE SAFETY
|
|
173
|
+
|
|
174
|
+
IMPORTANT: Always confirm with the user before running `cu delete`. This is a destructive, irreversible operation. Even when using `--confirm` flag, verify the task ID is correct with the user first.
|