@krodak/clickup-cli 1.14.1 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/dist/index.js +187 -65
- package/package.json +1 -1
- package/skills/clickup-cli/SKILL.md +60 -60
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clickup-cli",
|
|
3
3
|
"description": "ClickUp CLI skills for managing tasks, sprints, comments, checklists, custom fields, tags, and time tracking via the cup command",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.15.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Krzysztof Rodak"
|
|
7
7
|
},
|
package/dist/index.js
CHANGED
|
@@ -281,6 +281,18 @@ var ClickUpClient = class {
|
|
|
281
281
|
async getListViews(listId) {
|
|
282
282
|
return this.request(`/list/${listId}/view`);
|
|
283
283
|
}
|
|
284
|
+
async getSpaceViews(spaceId) {
|
|
285
|
+
const data = await this.request(`/space/${spaceId}/view`);
|
|
286
|
+
return readCollectionField(data, "views", "views");
|
|
287
|
+
}
|
|
288
|
+
async getFolderViews(folderId) {
|
|
289
|
+
const data = await this.request(`/folder/${folderId}/view`);
|
|
290
|
+
return readCollectionField(data, "views", "views");
|
|
291
|
+
}
|
|
292
|
+
async getWorkspaceViews(teamId) {
|
|
293
|
+
const data = await this.request(`/team/${teamId}/view`);
|
|
294
|
+
return readCollectionField(data, "views", "views");
|
|
295
|
+
}
|
|
284
296
|
async getViewTasks(viewId) {
|
|
285
297
|
return this.paginate((page) => `/view/${viewId}/task?page=${page}`);
|
|
286
298
|
}
|
|
@@ -510,6 +522,9 @@ var ClickUpClient = class {
|
|
|
510
522
|
const params = new URLSearchParams();
|
|
511
523
|
if (opts?.startDate != null) params.set("start_date", String(opts.startDate));
|
|
512
524
|
if (opts?.endDate != null) params.set("end_date", String(opts.endDate));
|
|
525
|
+
if (opts?.spaceId) params.set("space_id", opts.spaceId);
|
|
526
|
+
if (opts?.listId) params.set("list_id", opts.listId);
|
|
527
|
+
if (opts?.assigneeId) params.set("assignee", opts.assigneeId);
|
|
513
528
|
const query = params.toString();
|
|
514
529
|
const url = `/team/${teamId}/time_entries${query ? `?${query}` : ""}`;
|
|
515
530
|
const data = await this.request(url);
|
|
@@ -1225,7 +1240,7 @@ function formatTasksMarkdown(tasks) {
|
|
|
1225
1240
|
}
|
|
1226
1241
|
function formatCommentsMarkdown(comments) {
|
|
1227
1242
|
if (comments.length === 0) return "No comments found.";
|
|
1228
|
-
return comments.map((c) => `**${c.user}** (${c.date})
|
|
1243
|
+
return comments.map((c) => `**${c.user}** (${formatDateISO(c.date)})
|
|
1229
1244
|
|
|
1230
1245
|
${c.text}`).join("\n\n---\n\n");
|
|
1231
1246
|
}
|
|
@@ -1279,6 +1294,10 @@ function formatTaskDetailMarkdown(task) {
|
|
|
1279
1294
|
task.time_spent != null && task.time_spent > 0 ? formatDuration(task.time_spent) : void 0
|
|
1280
1295
|
],
|
|
1281
1296
|
["Tags", task.tags && task.tags.length > 0 ? task.tags.map((t) => t.name).join(", ") : void 0],
|
|
1297
|
+
[
|
|
1298
|
+
"Lists",
|
|
1299
|
+
task.locations && task.locations.length > 0 ? task.locations.map((l) => l.name).join(", ") : void 0
|
|
1300
|
+
],
|
|
1282
1301
|
["Created", task.date_created ? formatDateISO(task.date_created) : void 0],
|
|
1283
1302
|
["Updated", task.date_updated ? formatDateISO(task.date_updated) : void 0]
|
|
1284
1303
|
];
|
|
@@ -1420,6 +1439,7 @@ function formatTaskDetail(task) {
|
|
|
1420
1439
|
["Estimate", task.time_estimate ? formatDuration(task.time_estimate) : void 0],
|
|
1421
1440
|
["Tracked", task.time_spent ? formatDuration(task.time_spent) : void 0],
|
|
1422
1441
|
["Tags", task.tags?.length ? task.tags.map((t) => t.name).join(", ") : void 0],
|
|
1442
|
+
["Lists", task.locations?.length ? task.locations.map((l) => l.name).join(", ") : void 0],
|
|
1423
1443
|
["Parent", task.parent || void 0],
|
|
1424
1444
|
["URL", task.url]
|
|
1425
1445
|
];
|
|
@@ -1711,6 +1731,9 @@ function buildUpdatePayload(opts) {
|
|
|
1711
1731
|
if (opts.archive && opts.unarchive) {
|
|
1712
1732
|
throw new Error("Cannot use --archive and --unarchive together");
|
|
1713
1733
|
}
|
|
1734
|
+
if (opts.parent !== void 0 && opts.detach) {
|
|
1735
|
+
throw new Error("Cannot use --parent and --detach together");
|
|
1736
|
+
}
|
|
1714
1737
|
const payload = {};
|
|
1715
1738
|
if (opts.name !== void 0) {
|
|
1716
1739
|
if (!opts.name.trim()) throw new Error("Task name cannot be empty");
|
|
@@ -1720,8 +1743,16 @@ function buildUpdatePayload(opts) {
|
|
|
1720
1743
|
if (opts.status !== void 0) payload.status = opts.status;
|
|
1721
1744
|
if (opts.priority !== void 0) payload.priority = parsePriority(opts.priority);
|
|
1722
1745
|
if (opts.dueDate !== void 0) {
|
|
1723
|
-
|
|
1724
|
-
|
|
1746
|
+
if (opts.dueDate === "none" || opts.dueDate === "clear") {
|
|
1747
|
+
payload.due_date = null;
|
|
1748
|
+
} else {
|
|
1749
|
+
payload.due_date = parseDueDate(opts.dueDate);
|
|
1750
|
+
payload.due_date_time = false;
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
if (opts.startDate !== void 0) {
|
|
1754
|
+
payload.start_date = parseDueDate(opts.startDate);
|
|
1755
|
+
payload.start_date_time = false;
|
|
1725
1756
|
}
|
|
1726
1757
|
if (opts.assignee !== void 0) {
|
|
1727
1758
|
payload.assignees = { add: [parseAssigneeId(opts.assignee)] };
|
|
@@ -1729,13 +1760,17 @@ function buildUpdatePayload(opts) {
|
|
|
1729
1760
|
if (opts.timeEstimate !== void 0) {
|
|
1730
1761
|
payload.time_estimate = parseTimeEstimate(opts.timeEstimate);
|
|
1731
1762
|
}
|
|
1732
|
-
if (opts.
|
|
1763
|
+
if (opts.detach) {
|
|
1764
|
+
payload.parent = null;
|
|
1765
|
+
} else if (opts.parent !== void 0) {
|
|
1766
|
+
payload.parent = opts.parent;
|
|
1767
|
+
}
|
|
1733
1768
|
if (opts.archive) payload.archived = true;
|
|
1734
1769
|
if (opts.unarchive) payload.archived = false;
|
|
1735
1770
|
return payload;
|
|
1736
1771
|
}
|
|
1737
1772
|
function hasUpdateFields(options) {
|
|
1738
|
-
return options.name !== void 0 || options.description !== void 0 || options.markdown_content !== void 0 || options.status !== void 0 || options.priority !== void 0 || options.due_date !== void 0 || options.time_estimate !== void 0 || options.assignees !== void 0 || options.parent !== void 0 || options.archived !== void 0;
|
|
1773
|
+
return options.name !== void 0 || options.description !== void 0 || options.markdown_content !== void 0 || options.status !== void 0 || options.priority !== void 0 || options.due_date !== void 0 || options.start_date !== void 0 || options.time_estimate !== void 0 || options.assignees !== void 0 || options.parent !== void 0 || options.archived !== void 0;
|
|
1739
1774
|
}
|
|
1740
1775
|
async function resolveStatus(client, taskId, statusInput) {
|
|
1741
1776
|
const task = await client.getTask(taskId);
|
|
@@ -1754,7 +1789,7 @@ async function resolveStatus(client, taskId, statusInput) {
|
|
|
1754
1789
|
async function updateTask(config, taskId, options) {
|
|
1755
1790
|
if (!hasUpdateFields(options))
|
|
1756
1791
|
throw new Error(
|
|
1757
|
-
"Provide at least one of: --name, --description, --status, --priority, --due-date, --time-estimate, --assignee, --parent, --archive, --unarchive"
|
|
1792
|
+
"Provide at least one of: --name, --description, --status, --priority, --due-date, --start-date, --time-estimate, --assignee, --parent, --detach, --archive, --unarchive"
|
|
1758
1793
|
);
|
|
1759
1794
|
const client = new ClickUpClient(config);
|
|
1760
1795
|
if (options.status !== void 0) {
|
|
@@ -1793,6 +1828,10 @@ async function createTask(config, options) {
|
|
|
1793
1828
|
payload.due_date = parseDueDate(options.dueDate);
|
|
1794
1829
|
payload.due_date_time = false;
|
|
1795
1830
|
}
|
|
1831
|
+
if (options.startDate !== void 0) {
|
|
1832
|
+
payload.start_date = parseDueDate(options.startDate);
|
|
1833
|
+
payload.start_date_time = false;
|
|
1834
|
+
}
|
|
1796
1835
|
if (options.assignee !== void 0) {
|
|
1797
1836
|
payload.assignees = [parseAssigneeId(options.assignee)];
|
|
1798
1837
|
}
|
|
@@ -2760,9 +2799,11 @@ var commandMetadata = [
|
|
|
2760
2799
|
"--status",
|
|
2761
2800
|
"--priority",
|
|
2762
2801
|
"--due-date",
|
|
2802
|
+
"--start-date",
|
|
2763
2803
|
"--time-estimate",
|
|
2764
2804
|
"--assignee",
|
|
2765
2805
|
"--parent",
|
|
2806
|
+
"--detach",
|
|
2766
2807
|
"--archive",
|
|
2767
2808
|
"--unarchive",
|
|
2768
2809
|
"--field",
|
|
@@ -2786,6 +2827,7 @@ var commandMetadata = [
|
|
|
2786
2827
|
"--status",
|
|
2787
2828
|
"--priority",
|
|
2788
2829
|
"--due-date",
|
|
2830
|
+
"--start-date",
|
|
2789
2831
|
"--assignee",
|
|
2790
2832
|
"--tags",
|
|
2791
2833
|
"--custom-item-id",
|
|
@@ -3290,7 +3332,7 @@ var commandMetadata = [
|
|
|
3290
3332
|
{
|
|
3291
3333
|
name: "goal-create",
|
|
3292
3334
|
description: "Create a goal",
|
|
3293
|
-
flags: ["-d", "--description", "--color", "--json"],
|
|
3335
|
+
flags: ["-d", "--description", "--color", "--due-date", "--json"],
|
|
3294
3336
|
quickReference: [
|
|
3295
3337
|
{ section: "write", usage: "goal-create <name>", description: "Create a goal" }
|
|
3296
3338
|
]
|
|
@@ -3403,10 +3445,14 @@ var commandMetadata = [
|
|
|
3403
3445
|
},
|
|
3404
3446
|
{
|
|
3405
3447
|
name: "views",
|
|
3406
|
-
description: "List views on a list",
|
|
3407
|
-
flags: ["--json"],
|
|
3448
|
+
description: "List views on a list, space, folder, or workspace",
|
|
3449
|
+
flags: ["--space", "--folder", "--workspace", "--json"],
|
|
3408
3450
|
quickReference: [
|
|
3409
|
-
{
|
|
3451
|
+
{
|
|
3452
|
+
section: "read",
|
|
3453
|
+
usage: "views <id>",
|
|
3454
|
+
description: "List views on a list, space, folder, or workspace"
|
|
3455
|
+
}
|
|
3410
3456
|
]
|
|
3411
3457
|
},
|
|
3412
3458
|
{
|
|
@@ -3674,10 +3720,12 @@ ${renderZshTopLevelCommands(name)}
|
|
|
3674
3720
|
'(-d --description)'{-d,--description}'[New description]:text:' \\
|
|
3675
3721
|
'(-s --status)'{-s,--status}'[New status]:status:(open "in progress" "in review" done closed)' \\
|
|
3676
3722
|
'--priority[Priority level]:priority:(urgent high normal low)' \\
|
|
3677
|
-
'--due-date[Due date]:date:' \\
|
|
3723
|
+
'--due-date[Due date (YYYY-MM-DD or "none" to clear)]:date:' \\
|
|
3724
|
+
'--start-date[Start date]:date:' \\
|
|
3678
3725
|
'--time-estimate[Time estimate]:duration:' \\
|
|
3679
3726
|
'--assignee[Add assignee]:user_id:' \\
|
|
3680
3727
|
'--parent[Set parent task]:task_id:' \\
|
|
3728
|
+
'--detach[Remove parent task]' \\
|
|
3681
3729
|
'--archive[Archive the task]' \\
|
|
3682
3730
|
'--unarchive[Unarchive the task]' \\
|
|
3683
3731
|
'--field[Set custom field]:field_name_and_value:' \\
|
|
@@ -3771,6 +3819,7 @@ ${renderZshTopLevelCommands(name)}
|
|
|
3771
3819
|
'1:query:' \\
|
|
3772
3820
|
'--status[Filter by status]:status:(open "in progress" "in review" done closed)' \\
|
|
3773
3821
|
'--include-closed[Include done/closed tasks in search]' \\
|
|
3822
|
+
'--all[Search all workspace tasks, not just mine]' \\
|
|
3774
3823
|
'--json[Force JSON output]'
|
|
3775
3824
|
;;
|
|
3776
3825
|
summary)
|
|
@@ -3781,6 +3830,7 @@ ${renderZshTopLevelCommands(name)}
|
|
|
3781
3830
|
overdue)
|
|
3782
3831
|
_arguments \\
|
|
3783
3832
|
'--include-closed[Include done/closed overdue tasks]' \\
|
|
3833
|
+
'--all[Check all workspace tasks, not just mine]' \\
|
|
3784
3834
|
'--json[Force JSON output]'
|
|
3785
3835
|
;;
|
|
3786
3836
|
assign)
|
|
@@ -4458,7 +4508,18 @@ async function moveTask(config, taskId, opts) {
|
|
|
4458
4508
|
}
|
|
4459
4509
|
|
|
4460
4510
|
// src/commands/field.ts
|
|
4461
|
-
var SUPPORTED_TYPES = /* @__PURE__ */ new Set([
|
|
4511
|
+
var SUPPORTED_TYPES = /* @__PURE__ */ new Set([
|
|
4512
|
+
"text",
|
|
4513
|
+
"short_text",
|
|
4514
|
+
"number",
|
|
4515
|
+
"currency",
|
|
4516
|
+
"phone",
|
|
4517
|
+
"drop_down",
|
|
4518
|
+
"checkbox",
|
|
4519
|
+
"date",
|
|
4520
|
+
"url",
|
|
4521
|
+
"email"
|
|
4522
|
+
]);
|
|
4462
4523
|
function findFieldByName(fields, name) {
|
|
4463
4524
|
const lower = name.toLowerCase();
|
|
4464
4525
|
const match = fields.find((f) => f.name.toLowerCase() === lower);
|
|
@@ -4672,9 +4733,12 @@ function formatChecklistsMarkdown(checklists) {
|
|
|
4672
4733
|
|
|
4673
4734
|
// src/commands/comment-edit.ts
|
|
4674
4735
|
async function editComment(config, commentId, text, resolved) {
|
|
4675
|
-
if (
|
|
4736
|
+
if (text === void 0 && resolved === void 0) {
|
|
4737
|
+
throw new Error("Provide at least one of: --message, --resolved, --unresolved");
|
|
4738
|
+
}
|
|
4739
|
+
if (text !== void 0 && !text.trim()) throw new Error("Comment text cannot be empty");
|
|
4676
4740
|
const client = new ClickUpClient(config);
|
|
4677
|
-
await client.updateComment(commentId, text, resolved);
|
|
4741
|
+
await client.updateComment(commentId, text ?? "", resolved);
|
|
4678
4742
|
}
|
|
4679
4743
|
|
|
4680
4744
|
// src/commands/comment-delete.ts
|
|
@@ -4929,7 +4993,10 @@ async function listTimeEntries(config, opts) {
|
|
|
4929
4993
|
return client.getTimeEntries(config.teamId, {
|
|
4930
4994
|
startDate,
|
|
4931
4995
|
endDate,
|
|
4932
|
-
taskId: opts?.taskId
|
|
4996
|
+
taskId: opts?.taskId,
|
|
4997
|
+
spaceId: opts?.spaceId,
|
|
4998
|
+
listId: opts?.listId,
|
|
4999
|
+
assigneeId: opts?.assigneeId
|
|
4933
5000
|
});
|
|
4934
5001
|
}
|
|
4935
5002
|
async function updateTimeEntry(config, timeEntryId, opts) {
|
|
@@ -4991,6 +5058,11 @@ function formatTimeEntriesMarkdown(entries) {
|
|
|
4991
5058
|
|
|
4992
5059
|
// src/commands/tags.ts
|
|
4993
5060
|
import chalk12 from "chalk";
|
|
5061
|
+
var TAG_COLUMNS = [
|
|
5062
|
+
{ key: "name", label: "Name", maxWidth: 40 },
|
|
5063
|
+
{ key: "fg", label: "FG", maxWidth: 10 },
|
|
5064
|
+
{ key: "bg", label: "BG", maxWidth: 10 }
|
|
5065
|
+
];
|
|
4994
5066
|
async function listSpaceTags(config, spaceId) {
|
|
4995
5067
|
const client = new ClickUpClient(config);
|
|
4996
5068
|
return client.getSpaceTags(spaceId);
|
|
@@ -5004,20 +5076,34 @@ async function deleteSpaceTag(config, spaceId, tagName) {
|
|
|
5004
5076
|
await client.deleteSpaceTag(spaceId, tagName);
|
|
5005
5077
|
}
|
|
5006
5078
|
async function updateSpaceTag(config, spaceId, tagName, updates) {
|
|
5079
|
+
if (!updates.name && !updates.fg && !updates.bg) {
|
|
5080
|
+
throw new Error("Provide at least one of: --name, --fg, --bg");
|
|
5081
|
+
}
|
|
5007
5082
|
const client = new ClickUpClient(config);
|
|
5008
5083
|
await client.updateSpaceTag(spaceId, tagName, {
|
|
5009
|
-
name: updates.name,
|
|
5084
|
+
name: updates.name ?? tagName,
|
|
5010
5085
|
tag_fg: updates.fg,
|
|
5011
5086
|
tag_bg: updates.bg
|
|
5012
5087
|
});
|
|
5013
5088
|
}
|
|
5014
5089
|
function formatTags(tags) {
|
|
5015
5090
|
if (tags.length === 0) return "No tags found";
|
|
5091
|
+
if (isTTY()) {
|
|
5092
|
+
const rows = tags.map((t) => ({
|
|
5093
|
+
name: t.tag_bg ? chalk12.bgHex(t.tag_bg).hex(t.tag_fg || "#ffffff")(` ${t.name} `) : chalk12.bold(t.name),
|
|
5094
|
+
fg: t.tag_fg || "",
|
|
5095
|
+
bg: t.tag_bg || ""
|
|
5096
|
+
}));
|
|
5097
|
+
return formatTable(rows, TAG_COLUMNS);
|
|
5098
|
+
}
|
|
5016
5099
|
return tags.map((t) => chalk12.bold(t.name)).join(", ");
|
|
5017
5100
|
}
|
|
5018
5101
|
function formatTagsMarkdown(tags) {
|
|
5019
5102
|
if (tags.length === 0) return "No tags found";
|
|
5020
|
-
return tags.map((t) =>
|
|
5103
|
+
return tags.map((t) => {
|
|
5104
|
+
const colors = t.tag_bg ? ` (bg: ${t.tag_bg}${t.tag_fg ? `, fg: ${t.tag_fg}` : ""})` : "";
|
|
5105
|
+
return `- ${t.name}${colors}`;
|
|
5106
|
+
}).join("\n");
|
|
5021
5107
|
}
|
|
5022
5108
|
|
|
5023
5109
|
// src/commands/members.ts
|
|
@@ -5047,6 +5133,7 @@ function formatMembersMarkdown(members) {
|
|
|
5047
5133
|
// src/commands/fields.ts
|
|
5048
5134
|
import chalk13 from "chalk";
|
|
5049
5135
|
var FIELD_COLUMNS = [
|
|
5136
|
+
{ key: "id", label: "ID", maxWidth: 20 },
|
|
5050
5137
|
{ key: "name", label: "Name", maxWidth: 30 },
|
|
5051
5138
|
{ key: "type", label: "Type", maxWidth: 15 },
|
|
5052
5139
|
{
|
|
@@ -5064,6 +5151,7 @@ async function listFields(config, listId) {
|
|
|
5064
5151
|
function formatFields(fields) {
|
|
5065
5152
|
if (fields.length === 0) return "No custom fields";
|
|
5066
5153
|
const rows = fields.map((f) => ({
|
|
5154
|
+
id: f.id,
|
|
5067
5155
|
name: f.name,
|
|
5068
5156
|
type: f.type,
|
|
5069
5157
|
required: f.required ? "yes" : "no",
|
|
@@ -5076,7 +5164,7 @@ function formatFieldsMarkdown(fields) {
|
|
|
5076
5164
|
return fields.map((f) => {
|
|
5077
5165
|
const options = f.type_config?.options?.map((o) => o.name).join(", ");
|
|
5078
5166
|
const optStr = options ? ` [${options}]` : "";
|
|
5079
|
-
return `- **${f.name}** (${f.type})${f.required ? " - required" : ""}${optStr}`;
|
|
5167
|
+
return `- **${f.name}** \`${f.id}\` (${f.type})${f.required ? " - required" : ""}${optStr}`;
|
|
5080
5168
|
}).join("\n");
|
|
5081
5169
|
}
|
|
5082
5170
|
|
|
@@ -5124,7 +5212,8 @@ var GOAL_COLUMNS = [
|
|
|
5124
5212
|
{ key: "id", label: "ID", maxWidth: 15 },
|
|
5125
5213
|
{ key: "name", label: "Name", maxWidth: 40 },
|
|
5126
5214
|
{ key: "progress", label: "Progress", maxWidth: 10, format: (v) => colorProgress(v) },
|
|
5127
|
-
{ key: "owner", label: "Owner", maxWidth: 20 }
|
|
5215
|
+
{ key: "owner", label: "Owner", maxWidth: 20 },
|
|
5216
|
+
{ key: "due_date", label: "Due", maxWidth: 12 }
|
|
5128
5217
|
];
|
|
5129
5218
|
var KEY_RESULT_COLUMNS = [
|
|
5130
5219
|
{ key: "id", label: "ID", maxWidth: 15 },
|
|
@@ -5173,7 +5262,8 @@ function formatGoals(goals) {
|
|
|
5173
5262
|
name: g.name,
|
|
5174
5263
|
id: g.id,
|
|
5175
5264
|
progress: `${Math.round(g.percent_completed * 100)}%`,
|
|
5176
|
-
owner: g.owner ? `@${g.owner.username}` : ""
|
|
5265
|
+
owner: g.owner ? `@${g.owner.username}` : "",
|
|
5266
|
+
due_date: g.due_date ? formatDateISO(g.due_date) : ""
|
|
5177
5267
|
}));
|
|
5178
5268
|
return formatTable(rows, GOAL_COLUMNS);
|
|
5179
5269
|
}
|
|
@@ -5182,7 +5272,8 @@ function formatGoalsMarkdown(goals) {
|
|
|
5182
5272
|
return goals.map((g) => {
|
|
5183
5273
|
const pct = Math.round(g.percent_completed * 100);
|
|
5184
5274
|
const owner = g.owner ? ` - @${g.owner.username}` : "";
|
|
5185
|
-
|
|
5275
|
+
const due = g.due_date ? ` - due ${formatDateISO(g.due_date)}` : "";
|
|
5276
|
+
return `- **${g.name}** (${g.id}) - ${pct}%${owner}${due}`;
|
|
5186
5277
|
}).join("\n");
|
|
5187
5278
|
}
|
|
5188
5279
|
function formatKeyResults(keyResults) {
|
|
@@ -5280,9 +5371,12 @@ async function createListFromTemplate(config, name, opts) {
|
|
|
5280
5371
|
|
|
5281
5372
|
// src/commands/views.ts
|
|
5282
5373
|
import chalk19 from "chalk";
|
|
5283
|
-
async function listViews(config,
|
|
5374
|
+
async function listViews(config, id, container = "list") {
|
|
5284
5375
|
const client = new ClickUpClient(config);
|
|
5285
|
-
|
|
5376
|
+
if (container === "space") return client.getSpaceViews(id);
|
|
5377
|
+
if (container === "folder") return client.getFolderViews(id);
|
|
5378
|
+
if (container === "workspace") return client.getWorkspaceViews(config.teamId);
|
|
5379
|
+
const data = await client.getListViews(id);
|
|
5286
5380
|
return data.views;
|
|
5287
5381
|
}
|
|
5288
5382
|
function formatViews(views) {
|
|
@@ -5364,6 +5458,9 @@ var VALID_GROUP_BY_FIELDS2 = [
|
|
|
5364
5458
|
"sprint"
|
|
5365
5459
|
];
|
|
5366
5460
|
async function updateView(config, viewId, opts) {
|
|
5461
|
+
if (opts.name === void 0 && opts.groupBy === void 0) {
|
|
5462
|
+
throw new Error("Provide at least one of: --name, --group-by");
|
|
5463
|
+
}
|
|
5367
5464
|
if (opts.name !== void 0 && !opts.name.trim()) {
|
|
5368
5465
|
throw new Error("View name cannot be empty");
|
|
5369
5466
|
}
|
|
@@ -5475,7 +5572,7 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
5475
5572
|
}
|
|
5476
5573
|
})
|
|
5477
5574
|
);
|
|
5478
|
-
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>",
|
|
5575
|
+
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, or "none"/"clear" to remove)').option("--start-date <date>", "Start date (YYYY-MM-DD)").option("--time-estimate <duration>", 'Time estimate (e.g. "2h", "30m", "1h30m")').option("--assignee <userId>", 'Add assignee by user ID or "me"').option("--parent <taskId>", "Set parent task (makes this a subtask)").option("--detach", "Remove parent task (promote subtask to top-level)").option("--archive", "Archive the task").option("--unarchive", "Unarchive the task").option("--field <nameAndValue...>", 'Set custom field: --field "Name" value').option("--json", "Force JSON output even in terminal").action(
|
|
5479
5576
|
wrapAction(
|
|
5480
5577
|
async (taskId, opts) => {
|
|
5481
5578
|
const config = loadConfig(getProfileName());
|
|
@@ -5484,14 +5581,28 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
5484
5581
|
opts.assignee = String(await resolveAssigneeId(client, "me"));
|
|
5485
5582
|
}
|
|
5486
5583
|
const payload = buildUpdatePayload(opts);
|
|
5487
|
-
const
|
|
5488
|
-
if (
|
|
5489
|
-
|
|
5584
|
+
const hasFields = (opts.field?.length ?? 0) > 0;
|
|
5585
|
+
if (!hasFields && Object.keys(payload).length === 0) {
|
|
5586
|
+
throw new Error(
|
|
5587
|
+
"Provide at least one of: --name, --description, --status, --priority, --due-date, --time-estimate, --assignee, --parent, --archive, --unarchive, --field"
|
|
5588
|
+
);
|
|
5589
|
+
}
|
|
5590
|
+
let result;
|
|
5591
|
+
if (Object.keys(payload).length > 0) {
|
|
5592
|
+
result = await updateTask(config, taskId, payload);
|
|
5593
|
+
}
|
|
5594
|
+
if (hasFields) {
|
|
5595
|
+
if ((opts.field?.length ?? 0) % 2 !== 0) {
|
|
5490
5596
|
throw new Error('--field requires pairs: --field "Name" value');
|
|
5491
5597
|
}
|
|
5492
|
-
for (let i = 0; i < opts.field
|
|
5598
|
+
for (let i = 0; i < (opts.field?.length ?? 0); i += 2) {
|
|
5493
5599
|
await setCustomField(config, taskId, { set: [opts.field[i], opts.field[i + 1]] });
|
|
5494
5600
|
}
|
|
5601
|
+
if (!result) {
|
|
5602
|
+
const client = new ClickUpClient(config);
|
|
5603
|
+
const task = await client.getTask(taskId);
|
|
5604
|
+
result = { id: task.id, name: task.name };
|
|
5605
|
+
}
|
|
5495
5606
|
}
|
|
5496
5607
|
if (shouldOutputJson(opts.json ?? false)) {
|
|
5497
5608
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -5501,7 +5612,7 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
5501
5612
|
}
|
|
5502
5613
|
)
|
|
5503
5614
|
);
|
|
5504
|
-
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 (markdown supported)").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 or "me"').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("--template <id>", "Create from a task template").option("--json", "Force JSON output even in terminal").action(
|
|
5615
|
+
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 (markdown supported)").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("--start-date <date>", "Start date (YYYY-MM-DD)").option("--assignee <userId>", 'Assignee user ID or "me"').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("--template <id>", "Create from a task template").option("--json", "Force JSON output even in terminal").action(
|
|
5505
5616
|
wrapAction(async (opts) => {
|
|
5506
5617
|
const config = loadConfig(getProfileName());
|
|
5507
5618
|
if (opts.assignee === "me") {
|
|
@@ -5567,7 +5678,7 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
5567
5678
|
printComments(comments, opts.json ?? false);
|
|
5568
5679
|
})
|
|
5569
5680
|
);
|
|
5570
|
-
program.command("comment-edit <commentId>").description("Edit an existing comment").
|
|
5681
|
+
program.command("comment-edit <commentId>").description("Edit an existing comment").option("-m, --message <text>", "New comment text").option("--resolved", "Mark comment as resolved").option("--unresolved", "Mark comment as unresolved").option("--json", "Force JSON output even in terminal").action(
|
|
5571
5682
|
wrapAction(
|
|
5572
5683
|
async (commentId, opts) => {
|
|
5573
5684
|
const config = loadConfig(getProfileName());
|
|
@@ -5969,22 +6080,30 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
5969
6080
|
}
|
|
5970
6081
|
)
|
|
5971
6082
|
);
|
|
5972
|
-
timeCmd.command("list").description("List recent time entries (default: last 7 days)").option("--days <n>", "Number of days to look back", "7").option("--task <taskId>", "Filter by task ID").option("--json", "Force JSON output even in terminal").action(
|
|
5973
|
-
wrapAction(
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
6083
|
+
timeCmd.command("list").description("List recent time entries (default: last 7 days)").option("--days <n>", "Number of days to look back", "7").option("--task <taskId>", "Filter by task ID").option("--space <spaceId>", "Filter by space ID").option("--list <listId>", "Filter by list ID").option("--assignee <userId>", "Filter by assignee user ID").option("--json", "Force JSON output even in terminal").action(
|
|
6084
|
+
wrapAction(
|
|
6085
|
+
async (opts) => {
|
|
6086
|
+
const config = loadConfig(getProfileName());
|
|
6087
|
+
const days = opts.days ? Number(opts.days) : 7;
|
|
6088
|
+
if (!Number.isFinite(days) || days <= 0) {
|
|
6089
|
+
throw new Error("--days must be a positive number");
|
|
6090
|
+
}
|
|
6091
|
+
const entries = await listTimeEntries(config, {
|
|
6092
|
+
days,
|
|
6093
|
+
taskId: opts.task,
|
|
6094
|
+
spaceId: opts.space,
|
|
6095
|
+
listId: opts.list,
|
|
6096
|
+
assigneeId: opts.assignee
|
|
6097
|
+
});
|
|
6098
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
6099
|
+
console.log(JSON.stringify(entries, null, 2));
|
|
6100
|
+
} else if (isTTY()) {
|
|
6101
|
+
console.log(formatTimeEntries(entries));
|
|
6102
|
+
} else {
|
|
6103
|
+
console.log(formatTimeEntriesMarkdown(entries));
|
|
6104
|
+
}
|
|
5986
6105
|
}
|
|
5987
|
-
|
|
6106
|
+
)
|
|
5988
6107
|
);
|
|
5989
6108
|
timeCmd.command("update <timeEntryId>").description("Update a time entry").option("-d, --description <text>", "New description").option("--duration <duration>", 'New duration (e.g. "2h", "30m")').option("--json", "Force JSON output even in terminal").action(
|
|
5990
6109
|
wrapAction(
|
|
@@ -6165,13 +6284,14 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
6165
6284
|
}
|
|
6166
6285
|
})
|
|
6167
6286
|
);
|
|
6168
|
-
program.command("goal-create <name>").description("Create a goal").option("-d, --description <text>", "Goal description").option("--color <hex>", "Goal color (hex)").option("--json", "Force JSON output even in terminal").action(
|
|
6287
|
+
program.command("goal-create <name>").description("Create a goal").option("-d, --description <text>", "Goal description").option("--color <hex>", "Goal color (hex)").option("--due-date <date>", "Due date (YYYY-MM-DD)").option("--json", "Force JSON output even in terminal").action(
|
|
6169
6288
|
wrapAction(
|
|
6170
6289
|
async (name, opts) => {
|
|
6171
6290
|
const config = loadConfig(getProfileName());
|
|
6172
6291
|
const goal = await createGoal(config, name, {
|
|
6173
6292
|
description: opts.description,
|
|
6174
|
-
color: opts.color
|
|
6293
|
+
color: opts.color,
|
|
6294
|
+
dueDate: opts.dueDate
|
|
6175
6295
|
});
|
|
6176
6296
|
if (shouldOutputJson(opts.json ?? false)) {
|
|
6177
6297
|
console.log(JSON.stringify(goal, null, 2));
|
|
@@ -6436,7 +6556,7 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
6436
6556
|
}
|
|
6437
6557
|
})
|
|
6438
6558
|
);
|
|
6439
|
-
program.command("tag-update <spaceId> <tagName>").description("Update a tag in a space").
|
|
6559
|
+
program.command("tag-update <spaceId> <tagName>").description("Update a tag in a space").option("--name <newName>", "New tag name").option("--fg <color>", "New foreground color (hex)").option("--bg <color>", "New background color (hex)").option("--json", "Force JSON output even in terminal").action(
|
|
6440
6560
|
wrapAction(
|
|
6441
6561
|
async (spaceId, tagName, opts) => {
|
|
6442
6562
|
const config = loadConfig(getProfileName());
|
|
@@ -6445,16 +6565,15 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
6445
6565
|
fg: opts.fg,
|
|
6446
6566
|
bg: opts.bg
|
|
6447
6567
|
});
|
|
6568
|
+
const newName = opts.name ?? tagName;
|
|
6448
6569
|
if (shouldOutputJson(opts.json ?? false)) {
|
|
6449
6570
|
console.log(
|
|
6450
|
-
JSON.stringify(
|
|
6451
|
-
{ success: true, spaceId, oldName: tagName, newName: opts.name },
|
|
6452
|
-
null,
|
|
6453
|
-
2
|
|
6454
|
-
)
|
|
6571
|
+
JSON.stringify({ success: true, spaceId, oldName: tagName, newName }, null, 2)
|
|
6455
6572
|
);
|
|
6456
|
-
} else {
|
|
6573
|
+
} else if (opts.name && opts.name !== tagName) {
|
|
6457
6574
|
console.log(`Renamed tag "${tagName}" to "${opts.name}" in space ${spaceId}`);
|
|
6575
|
+
} else {
|
|
6576
|
+
console.log(`Updated tag "${tagName}" in space ${spaceId}`);
|
|
6458
6577
|
}
|
|
6459
6578
|
}
|
|
6460
6579
|
)
|
|
@@ -6524,18 +6643,21 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
6524
6643
|
}
|
|
6525
6644
|
)
|
|
6526
6645
|
);
|
|
6527
|
-
program.command("views <
|
|
6528
|
-
wrapAction(
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6646
|
+
program.command("views <id>").description("List views on a list, space, folder, or workspace").option("--space", "Treat <id> as a space ID").option("--folder", "Treat <id> as a folder ID").option("--workspace", "List workspace-level views (ignores <id>)").option("--json", "Force JSON output even in terminal").action(
|
|
6647
|
+
wrapAction(
|
|
6648
|
+
async (id, opts) => {
|
|
6649
|
+
const config = loadConfig(getProfileName());
|
|
6650
|
+
const container = opts.workspace ? "workspace" : opts.space ? "space" : opts.folder ? "folder" : "list";
|
|
6651
|
+
const views = await listViews(config, id, container);
|
|
6652
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
6653
|
+
console.log(JSON.stringify(views, null, 2));
|
|
6654
|
+
} else if (isTTY()) {
|
|
6655
|
+
console.log(formatViews(views));
|
|
6656
|
+
} else {
|
|
6657
|
+
console.log(formatViewsMarkdown(views));
|
|
6658
|
+
}
|
|
6537
6659
|
}
|
|
6538
|
-
|
|
6660
|
+
)
|
|
6539
6661
|
);
|
|
6540
6662
|
program.command("view <viewId>").description("Get view details").option("--json", "Force JSON output even in terminal").action(
|
|
6541
6663
|
wrapAction(async (viewId, opts) => {
|
package/package.json
CHANGED
|
@@ -69,66 +69,66 @@ All commands support `--help` for full flag details. All commands support `--jso
|
|
|
69
69
|
|
|
70
70
|
### Write
|
|
71
71
|
|
|
72
|
-
| Command
|
|
73
|
-
|
|
|
74
|
-
| `cup create -n name [-l listId] [-p parentId] [-d desc] [-s status] [--priority p] [--due-date d] [--time-estimate t] [--assignee id\|me] [--tags t] [--custom-item-id n] [--template id]`
|
|
75
|
-
| `cup update <id> [-n name] [-d desc] [-s status] [--priority p] [--due-date d] [--time-estimate t] [--assignee id\|me] [--parent id] [--archive] [--unarchive] [--field "Name" val]`
|
|
76
|
-
| `cup comment <id> -m text [--notify-all]`
|
|
77
|
-
| `cup comment-edit <commentId> -m text [--resolved] [--unresolved]`
|
|
78
|
-
| `cup comment-delete <commentId>`
|
|
79
|
-
| `cup replies <commentId>`
|
|
80
|
-
| `cup reply <commentId> -m text [--notify-all]`
|
|
81
|
-
| `cup assign <id> [--to userId\|me] [--remove userId\|me]`
|
|
82
|
-
| `cup depend <id> [--on taskId] [--blocks taskId] [--remove]`
|
|
83
|
-
| `cup move <id> [--to listId] [--remove listId]`
|
|
84
|
-
| `cup field <id> [--set "Name" value] [--remove "Name"]`
|
|
85
|
-
| `cup field-create <name> -t <type> [-d desc] [--options "a,b,c"] [--required]`
|
|
86
|
-
| `cup tag <id> [--add tags] [--remove tags]`
|
|
87
|
-
| `cup link <taskId> <linksTo> [--remove]`
|
|
88
|
-
| `cup attach <taskId> <filePath>`
|
|
89
|
-
| `cup delete <id> [--confirm]`
|
|
90
|
-
| `cup duplicate <taskId>`
|
|
91
|
-
| `cup bulk status <status> <taskIds...>`
|
|
92
|
-
| `cup checklist view <id>`
|
|
93
|
-
| `cup checklist create <id> <name>`
|
|
94
|
-
| `cup checklist delete <checklistId>`
|
|
95
|
-
| `cup checklist add-item <checklistId> <name>`
|
|
96
|
-
| `cup checklist edit-item <checklistId> <itemId> [--name n] [--resolved] [--unresolved] [--assignee id]`
|
|
97
|
-
| `cup checklist delete-item <checklistId> <itemId>`
|
|
98
|
-
| `cup time start <taskId> [-d desc]`
|
|
99
|
-
| `cup time stop`
|
|
100
|
-
| `cup time status`
|
|
101
|
-
| `cup time log <taskId> <duration> [-d desc]`
|
|
102
|
-
| `cup time list [--days n] [--task id]`
|
|
103
|
-
| `cup time update <timeEntryId> [-d desc] [--duration dur]`
|
|
104
|
-
| `cup time delete <timeEntryId>`
|
|
105
|
-
| `cup goal-create <name> [-d desc] [--color hex]`
|
|
106
|
-
| `cup goal-update <goalId> [-n name] [-d desc] [--color hex]`
|
|
107
|
-
| `cup goal-delete <goalId>`
|
|
108
|
-
| `cup key-result-create <goalId> <name> [--type t] [--target n]`
|
|
109
|
-
| `cup key-result-update <keyResultId> [--progress n] [--note text]`
|
|
110
|
-
| `cup key-result-delete <keyResultId>`
|
|
111
|
-
| `cup doc-create <title> [-c content]`
|
|
112
|
-
| `cup doc-page-create <docId> <name> [-c content] [--parent-page pageId]`
|
|
113
|
-
| `cup doc-page-edit <docId> <pageId> [--name text] [-c content]`
|
|
114
|
-
| `cup doc-delete <docId>`
|
|
115
|
-
| `cup doc-page-delete <docId> <pageId>`
|
|
116
|
-
| `cup space-create <name>`
|
|
117
|
-
| `cup list-create <spaceId> <name> [--folder folderId]`
|
|
118
|
-
| `cup folder-create <spaceId> <name>`
|
|
119
|
-
| `cup tag-create <spaceId> <name> [--fg color] [--bg color]`
|
|
120
|
-
| `cup tag-update <spaceId> <tagName> --name <newName> [--fg c] [--bg c]`
|
|
121
|
-
| `cup tag-delete <spaceId> <name>`
|
|
122
|
-
| `cup list-from-template <name> --template <id> [--space id] [--folder id]`
|
|
123
|
-
| `cup view-create <listId> <name> -t <type> [--group-by field]`
|
|
124
|
-
| `cup view-update <viewId> [-n name] [--group-by field]`
|
|
125
|
-
| `cup view-delete <viewId> [--confirm]`
|
|
126
|
-
| `cup profile list [--json]`
|
|
127
|
-
| `cup profile add <name>`
|
|
128
|
-
| `cup profile remove <name>`
|
|
129
|
-
| `cup profile use <name>`
|
|
130
|
-
| `cup config get <key>` / `set <key> <value>` / `path`
|
|
131
|
-
| `cup completion <shell>`
|
|
72
|
+
| Command | What it does |
|
|
73
|
+
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
|
|
74
|
+
| `cup create -n name [-l listId] [-p parentId] [-d desc] [-s status] [--priority p] [--due-date d] [--start-date d] [--time-estimate t] [--assignee id\|me] [--tags t] [--custom-item-id n] [--template id]` | Create task |
|
|
75
|
+
| `cup update <id> [-n name] [-d desc] [-s status] [--priority p] [--due-date d\|none] [--start-date d] [--time-estimate t] [--assignee id\|me] [--parent id] [--detach] [--archive] [--unarchive] [--field "Name" val]` | Update task fields (including custom fields) |
|
|
76
|
+
| `cup comment <id> -m text [--notify-all]` | Post comment on task |
|
|
77
|
+
| `cup comment-edit <commentId> -m text [--resolved] [--unresolved]` | Edit a comment |
|
|
78
|
+
| `cup comment-delete <commentId>` | Delete a comment |
|
|
79
|
+
| `cup replies <commentId>` | List threaded replies |
|
|
80
|
+
| `cup reply <commentId> -m text [--notify-all]` | Reply to a comment |
|
|
81
|
+
| `cup assign <id> [--to userId\|me] [--remove userId\|me]` | Assign/unassign users |
|
|
82
|
+
| `cup depend <id> [--on taskId] [--blocks taskId] [--remove]` | Add/remove dependencies |
|
|
83
|
+
| `cup move <id> [--to listId] [--remove listId]` | Add/remove task from lists |
|
|
84
|
+
| `cup field <id> [--set "Name" value] [--remove "Name"]` | Set/remove custom field values |
|
|
85
|
+
| `cup field-create <name> -t <type> [-d desc] [--options "a,b,c"] [--required]` | Create a custom field |
|
|
86
|
+
| `cup tag <id> [--add tags] [--remove tags]` | Add/remove tags on a task |
|
|
87
|
+
| `cup link <taskId> <linksTo> [--remove]` | Link/unlink tasks |
|
|
88
|
+
| `cup attach <taskId> <filePath>` | Upload file attachment |
|
|
89
|
+
| `cup delete <id> [--confirm]` | Delete task (DESTRUCTIVE) |
|
|
90
|
+
| `cup duplicate <taskId>` | Duplicate a task |
|
|
91
|
+
| `cup bulk status <status> <taskIds...>` | Bulk update status |
|
|
92
|
+
| `cup checklist view <id>` | View checklists on a task |
|
|
93
|
+
| `cup checklist create <id> <name>` | Create a checklist |
|
|
94
|
+
| `cup checklist delete <checklistId>` | Delete a checklist |
|
|
95
|
+
| `cup checklist add-item <checklistId> <name>` | Add item to checklist |
|
|
96
|
+
| `cup checklist edit-item <checklistId> <itemId> [--name n] [--resolved] [--unresolved] [--assignee id]` | Edit checklist item |
|
|
97
|
+
| `cup checklist delete-item <checklistId> <itemId>` | Delete checklist item |
|
|
98
|
+
| `cup time start <taskId> [-d desc]` | Start timer |
|
|
99
|
+
| `cup time stop` | Stop running timer |
|
|
100
|
+
| `cup time status` | Show running timer |
|
|
101
|
+
| `cup time log <taskId> <duration> [-d desc]` | Log manual entry (e.g. "2h", "30m") |
|
|
102
|
+
| `cup time list [--days n] [--task id]` | List recent time entries |
|
|
103
|
+
| `cup time update <timeEntryId> [-d desc] [--duration dur]` | Update time entry |
|
|
104
|
+
| `cup time delete <timeEntryId>` | Delete time entry |
|
|
105
|
+
| `cup goal-create <name> [-d desc] [--color hex]` | Create a goal |
|
|
106
|
+
| `cup goal-update <goalId> [-n name] [-d desc] [--color hex]` | Update a goal |
|
|
107
|
+
| `cup goal-delete <goalId>` | Delete a goal |
|
|
108
|
+
| `cup key-result-create <goalId> <name> [--type t] [--target n]` | Create key result |
|
|
109
|
+
| `cup key-result-update <keyResultId> [--progress n] [--note text]` | Update key result |
|
|
110
|
+
| `cup key-result-delete <keyResultId>` | Delete key result |
|
|
111
|
+
| `cup doc-create <title> [-c content]` | Create a doc |
|
|
112
|
+
| `cup doc-page-create <docId> <name> [-c content] [--parent-page pageId]` | Create doc page |
|
|
113
|
+
| `cup doc-page-edit <docId> <pageId> [--name text] [-c content]` | Edit doc page |
|
|
114
|
+
| `cup doc-delete <docId>` | Delete a doc |
|
|
115
|
+
| `cup doc-page-delete <docId> <pageId>` | Delete doc page |
|
|
116
|
+
| `cup space-create <name>` | Create a space |
|
|
117
|
+
| `cup list-create <spaceId> <name> [--folder folderId]` | Create a list in a space or folder |
|
|
118
|
+
| `cup folder-create <spaceId> <name>` | Create a folder in a space |
|
|
119
|
+
| `cup tag-create <spaceId> <name> [--fg color] [--bg color]` | Create space tag |
|
|
120
|
+
| `cup tag-update <spaceId> <tagName> --name <newName> [--fg c] [--bg c]` | Update space tag |
|
|
121
|
+
| `cup tag-delete <spaceId> <name>` | Delete space tag |
|
|
122
|
+
| `cup list-from-template <name> --template <id> [--space id] [--folder id]` | Create list from template |
|
|
123
|
+
| `cup view-create <listId> <name> -t <type> [--group-by field]` | Create a view on a list |
|
|
124
|
+
| `cup view-update <viewId> [-n name] [--group-by field]` | Update a view |
|
|
125
|
+
| `cup view-delete <viewId> [--confirm]` | Delete a view (DESTRUCTIVE) |
|
|
126
|
+
| `cup profile list [--json]` | List all profiles |
|
|
127
|
+
| `cup profile add <name>` | Add a new profile (interactive) |
|
|
128
|
+
| `cup profile remove <name>` | Remove a profile |
|
|
129
|
+
| `cup profile use <name>` | Set the default profile |
|
|
130
|
+
| `cup config get <key>` / `set <key> <value>` / `path` | Manage config |
|
|
131
|
+
| `cup completion <shell>` | Shell completions (bash/zsh/fish) |
|
|
132
132
|
|
|
133
133
|
## Global Flags
|
|
134
134
|
|