@krodak/clickup-cli 1.14.2 → 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.
@@ -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.14.2",
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);
@@ -1716,6 +1731,9 @@ function buildUpdatePayload(opts) {
1716
1731
  if (opts.archive && opts.unarchive) {
1717
1732
  throw new Error("Cannot use --archive and --unarchive together");
1718
1733
  }
1734
+ if (opts.parent !== void 0 && opts.detach) {
1735
+ throw new Error("Cannot use --parent and --detach together");
1736
+ }
1719
1737
  const payload = {};
1720
1738
  if (opts.name !== void 0) {
1721
1739
  if (!opts.name.trim()) throw new Error("Task name cannot be empty");
@@ -1725,8 +1743,16 @@ function buildUpdatePayload(opts) {
1725
1743
  if (opts.status !== void 0) payload.status = opts.status;
1726
1744
  if (opts.priority !== void 0) payload.priority = parsePriority(opts.priority);
1727
1745
  if (opts.dueDate !== void 0) {
1728
- payload.due_date = parseDueDate(opts.dueDate);
1729
- payload.due_date_time = false;
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;
1730
1756
  }
1731
1757
  if (opts.assignee !== void 0) {
1732
1758
  payload.assignees = { add: [parseAssigneeId(opts.assignee)] };
@@ -1734,13 +1760,17 @@ function buildUpdatePayload(opts) {
1734
1760
  if (opts.timeEstimate !== void 0) {
1735
1761
  payload.time_estimate = parseTimeEstimate(opts.timeEstimate);
1736
1762
  }
1737
- if (opts.parent !== void 0) payload.parent = opts.parent;
1763
+ if (opts.detach) {
1764
+ payload.parent = null;
1765
+ } else if (opts.parent !== void 0) {
1766
+ payload.parent = opts.parent;
1767
+ }
1738
1768
  if (opts.archive) payload.archived = true;
1739
1769
  if (opts.unarchive) payload.archived = false;
1740
1770
  return payload;
1741
1771
  }
1742
1772
  function hasUpdateFields(options) {
1743
- 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;
1744
1774
  }
1745
1775
  async function resolveStatus(client, taskId, statusInput) {
1746
1776
  const task = await client.getTask(taskId);
@@ -1759,7 +1789,7 @@ async function resolveStatus(client, taskId, statusInput) {
1759
1789
  async function updateTask(config, taskId, options) {
1760
1790
  if (!hasUpdateFields(options))
1761
1791
  throw new Error(
1762
- "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"
1763
1793
  );
1764
1794
  const client = new ClickUpClient(config);
1765
1795
  if (options.status !== void 0) {
@@ -1798,6 +1828,10 @@ async function createTask(config, options) {
1798
1828
  payload.due_date = parseDueDate(options.dueDate);
1799
1829
  payload.due_date_time = false;
1800
1830
  }
1831
+ if (options.startDate !== void 0) {
1832
+ payload.start_date = parseDueDate(options.startDate);
1833
+ payload.start_date_time = false;
1834
+ }
1801
1835
  if (options.assignee !== void 0) {
1802
1836
  payload.assignees = [parseAssigneeId(options.assignee)];
1803
1837
  }
@@ -2765,9 +2799,11 @@ var commandMetadata = [
2765
2799
  "--status",
2766
2800
  "--priority",
2767
2801
  "--due-date",
2802
+ "--start-date",
2768
2803
  "--time-estimate",
2769
2804
  "--assignee",
2770
2805
  "--parent",
2806
+ "--detach",
2771
2807
  "--archive",
2772
2808
  "--unarchive",
2773
2809
  "--field",
@@ -2791,6 +2827,7 @@ var commandMetadata = [
2791
2827
  "--status",
2792
2828
  "--priority",
2793
2829
  "--due-date",
2830
+ "--start-date",
2794
2831
  "--assignee",
2795
2832
  "--tags",
2796
2833
  "--custom-item-id",
@@ -3295,7 +3332,7 @@ var commandMetadata = [
3295
3332
  {
3296
3333
  name: "goal-create",
3297
3334
  description: "Create a goal",
3298
- flags: ["-d", "--description", "--color", "--json"],
3335
+ flags: ["-d", "--description", "--color", "--due-date", "--json"],
3299
3336
  quickReference: [
3300
3337
  { section: "write", usage: "goal-create <name>", description: "Create a goal" }
3301
3338
  ]
@@ -3408,10 +3445,14 @@ var commandMetadata = [
3408
3445
  },
3409
3446
  {
3410
3447
  name: "views",
3411
- description: "List views on a list",
3412
- flags: ["--json"],
3448
+ description: "List views on a list, space, folder, or workspace",
3449
+ flags: ["--space", "--folder", "--workspace", "--json"],
3413
3450
  quickReference: [
3414
- { section: "read", usage: "views <listId>", description: "List views on a list" }
3451
+ {
3452
+ section: "read",
3453
+ usage: "views <id>",
3454
+ description: "List views on a list, space, folder, or workspace"
3455
+ }
3415
3456
  ]
3416
3457
  },
3417
3458
  {
@@ -3679,10 +3720,12 @@ ${renderZshTopLevelCommands(name)}
3679
3720
  '(-d --description)'{-d,--description}'[New description]:text:' \\
3680
3721
  '(-s --status)'{-s,--status}'[New status]:status:(open "in progress" "in review" done closed)' \\
3681
3722
  '--priority[Priority level]:priority:(urgent high normal low)' \\
3682
- '--due-date[Due date]:date:' \\
3723
+ '--due-date[Due date (YYYY-MM-DD or "none" to clear)]:date:' \\
3724
+ '--start-date[Start date]:date:' \\
3683
3725
  '--time-estimate[Time estimate]:duration:' \\
3684
3726
  '--assignee[Add assignee]:user_id:' \\
3685
3727
  '--parent[Set parent task]:task_id:' \\
3728
+ '--detach[Remove parent task]' \\
3686
3729
  '--archive[Archive the task]' \\
3687
3730
  '--unarchive[Unarchive the task]' \\
3688
3731
  '--field[Set custom field]:field_name_and_value:' \\
@@ -4950,7 +4993,10 @@ async function listTimeEntries(config, opts) {
4950
4993
  return client.getTimeEntries(config.teamId, {
4951
4994
  startDate,
4952
4995
  endDate,
4953
- taskId: opts?.taskId
4996
+ taskId: opts?.taskId,
4997
+ spaceId: opts?.spaceId,
4998
+ listId: opts?.listId,
4999
+ assigneeId: opts?.assigneeId
4954
5000
  });
4955
5001
  }
4956
5002
  async function updateTimeEntry(config, timeEntryId, opts) {
@@ -5030,9 +5076,12 @@ async function deleteSpaceTag(config, spaceId, tagName) {
5030
5076
  await client.deleteSpaceTag(spaceId, tagName);
5031
5077
  }
5032
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
+ }
5033
5082
  const client = new ClickUpClient(config);
5034
5083
  await client.updateSpaceTag(spaceId, tagName, {
5035
- name: updates.name,
5084
+ name: updates.name ?? tagName,
5036
5085
  tag_fg: updates.fg,
5037
5086
  tag_bg: updates.bg
5038
5087
  });
@@ -5322,9 +5371,12 @@ async function createListFromTemplate(config, name, opts) {
5322
5371
 
5323
5372
  // src/commands/views.ts
5324
5373
  import chalk19 from "chalk";
5325
- async function listViews(config, listId) {
5374
+ async function listViews(config, id, container = "list") {
5326
5375
  const client = new ClickUpClient(config);
5327
- const data = await client.getListViews(listId);
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);
5328
5380
  return data.views;
5329
5381
  }
5330
5382
  function formatViews(views) {
@@ -5520,7 +5572,7 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
5520
5572
  }
5521
5573
  })
5522
5574
  );
5523
- program.command("update <taskId>").description("Update a task").option("-n, --name <text>", "New task name").option("-d, --description <text>", "New description (markdown supported)").option("-s, --status <status>", 'New status (e.g. "in progress", "done")').option("--priority <level>", "Priority: urgent, high, normal, low (or 1-4)").option("--due-date <date>", "Due date (YYYY-MM-DD)").option("--time-estimate <duration>", 'Time estimate (e.g. "2h", "30m", "1h30m")').option("--assignee <userId>", 'Add assignee by user ID or "me"').option("--parent <taskId>", "Set parent task (makes this a subtask)").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(
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(
5524
5576
  wrapAction(
5525
5577
  async (taskId, opts) => {
5526
5578
  const config = loadConfig(getProfileName());
@@ -5560,7 +5612,7 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
5560
5612
  }
5561
5613
  )
5562
5614
  );
5563
- 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(
5564
5616
  wrapAction(async (opts) => {
5565
5617
  const config = loadConfig(getProfileName());
5566
5618
  if (opts.assignee === "me") {
@@ -6028,22 +6080,30 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
6028
6080
  }
6029
6081
  )
6030
6082
  );
6031
- 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(
6032
- wrapAction(async (opts) => {
6033
- const config = loadConfig(getProfileName());
6034
- const days = opts.days ? Number(opts.days) : 7;
6035
- if (!Number.isFinite(days) || days <= 0) {
6036
- throw new Error("--days must be a positive number");
6037
- }
6038
- const entries = await listTimeEntries(config, { days, taskId: opts.task });
6039
- if (shouldOutputJson(opts.json ?? false)) {
6040
- console.log(JSON.stringify(entries, null, 2));
6041
- } else if (isTTY()) {
6042
- console.log(formatTimeEntries(entries));
6043
- } else {
6044
- console.log(formatTimeEntriesMarkdown(entries));
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
+ }
6045
6105
  }
6046
- })
6106
+ )
6047
6107
  );
6048
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(
6049
6109
  wrapAction(
@@ -6224,13 +6284,14 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
6224
6284
  }
6225
6285
  })
6226
6286
  );
6227
- 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(
6228
6288
  wrapAction(
6229
6289
  async (name, opts) => {
6230
6290
  const config = loadConfig(getProfileName());
6231
6291
  const goal = await createGoal(config, name, {
6232
6292
  description: opts.description,
6233
- color: opts.color
6293
+ color: opts.color,
6294
+ dueDate: opts.dueDate
6234
6295
  });
6235
6296
  if (shouldOutputJson(opts.json ?? false)) {
6236
6297
  console.log(JSON.stringify(goal, null, 2));
@@ -6495,7 +6556,7 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
6495
6556
  }
6496
6557
  })
6497
6558
  );
6498
- program.command("tag-update <spaceId> <tagName>").description("Update a tag in a space").requiredOption("--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(
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(
6499
6560
  wrapAction(
6500
6561
  async (spaceId, tagName, opts) => {
6501
6562
  const config = loadConfig(getProfileName());
@@ -6504,16 +6565,15 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
6504
6565
  fg: opts.fg,
6505
6566
  bg: opts.bg
6506
6567
  });
6568
+ const newName = opts.name ?? tagName;
6507
6569
  if (shouldOutputJson(opts.json ?? false)) {
6508
6570
  console.log(
6509
- JSON.stringify(
6510
- { success: true, spaceId, oldName: tagName, newName: opts.name },
6511
- null,
6512
- 2
6513
- )
6571
+ JSON.stringify({ success: true, spaceId, oldName: tagName, newName }, null, 2)
6514
6572
  );
6515
- } else {
6573
+ } else if (opts.name && opts.name !== tagName) {
6516
6574
  console.log(`Renamed tag "${tagName}" to "${opts.name}" in space ${spaceId}`);
6575
+ } else {
6576
+ console.log(`Updated tag "${tagName}" in space ${spaceId}`);
6517
6577
  }
6518
6578
  }
6519
6579
  )
@@ -6583,18 +6643,21 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
6583
6643
  }
6584
6644
  )
6585
6645
  );
6586
- program.command("views <listId>").description("List views on a list").option("--json", "Force JSON output even in terminal").action(
6587
- wrapAction(async (listId, opts) => {
6588
- const config = loadConfig(getProfileName());
6589
- const views = await listViews(config, listId);
6590
- if (shouldOutputJson(opts.json ?? false)) {
6591
- console.log(JSON.stringify(views, null, 2));
6592
- } else if (isTTY()) {
6593
- console.log(formatViews(views));
6594
- } else {
6595
- console.log(formatViewsMarkdown(views));
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
+ }
6596
6659
  }
6597
- })
6660
+ )
6598
6661
  );
6599
6662
  program.command("view <viewId>").description("Get view details").option("--json", "Force JSON output even in terminal").action(
6600
6663
  wrapAction(async (viewId, opts) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@krodak/clickup-cli",
3
- "version": "1.14.2",
3
+ "version": "1.15.0",
4
4
  "description": "ClickUp CLI for AI agents and humans",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -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 | What it does |
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]` | Create task |
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]` | 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) |
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