@krodak/clickup-cli 1.27.0 → 1.28.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 +151 -55
- package/package.json +1 -1
- package/skills/clickup-cli/SKILL.md +5 -3
|
@@ -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.28.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Krzysztof Rodak"
|
|
7
7
|
},
|
package/dist/index.js
CHANGED
|
@@ -1841,12 +1841,12 @@ async function groupedTaskPicker(groups) {
|
|
|
1841
1841
|
}
|
|
1842
1842
|
async function showDetailsAndOpen(tasks, fetchTask) {
|
|
1843
1843
|
if (tasks.length === 0) return;
|
|
1844
|
-
const
|
|
1844
|
+
const separator2 = chalk2.dim("\u2500".repeat(60));
|
|
1845
1845
|
for (let i = 0; i < tasks.length; i++) {
|
|
1846
1846
|
const task = tasks[i];
|
|
1847
1847
|
if (i > 0) {
|
|
1848
1848
|
console.log("");
|
|
1849
|
-
console.log(
|
|
1849
|
+
console.log(separator2);
|
|
1850
1850
|
}
|
|
1851
1851
|
console.log("");
|
|
1852
1852
|
if (fetchTask) {
|
|
@@ -1993,27 +1993,54 @@ function parsePriority(value) {
|
|
|
1993
1993
|
if (Number.isInteger(num) && num >= 1 && num <= 4) return num;
|
|
1994
1994
|
throw new Error("Priority must be urgent, high, normal, low, or 1-4");
|
|
1995
1995
|
}
|
|
1996
|
+
var DATE_ONLY_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
1997
|
+
var LOCAL_DATETIME_RE = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2}))?$/;
|
|
1998
|
+
var ISO_WITH_OFFSET_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2})?(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})$/;
|
|
1996
1999
|
function parseDueDate(value, timezone) {
|
|
1997
|
-
if (
|
|
1998
|
-
|
|
2000
|
+
if (DATE_ONLY_RE.test(value)) {
|
|
2001
|
+
const parts = value.split("-").map(Number);
|
|
2002
|
+
const y = parts[0];
|
|
2003
|
+
const m = parts[1];
|
|
2004
|
+
const d = parts[2];
|
|
2005
|
+
return { ms: wallClockToMs(y, m, d, 0, 0, 0, timezone, value), hasTime: false };
|
|
2006
|
+
}
|
|
2007
|
+
const localMatch = LOCAL_DATETIME_RE.exec(value);
|
|
2008
|
+
if (localMatch) {
|
|
2009
|
+
const y = Number(localMatch[1]);
|
|
2010
|
+
const m = Number(localMatch[2]);
|
|
2011
|
+
const d = Number(localMatch[3]);
|
|
2012
|
+
const hh = Number(localMatch[4]);
|
|
2013
|
+
const mm = Number(localMatch[5]);
|
|
2014
|
+
const ss = localMatch[6] !== void 0 ? Number(localMatch[6]) : 0;
|
|
2015
|
+
if (hh > 23 || mm > 59 || ss > 59) {
|
|
2016
|
+
throw new Error(
|
|
2017
|
+
"Date must be in YYYY-MM-DD, YYYY-MM-DDTHH:MM[:SS], or full ISO 8601 format (time component out of range)"
|
|
2018
|
+
);
|
|
2019
|
+
}
|
|
2020
|
+
return { ms: wallClockToMs(y, m, d, hh, mm, ss, timezone, value), hasTime: true };
|
|
2021
|
+
}
|
|
2022
|
+
if (ISO_WITH_OFFSET_RE.test(value)) {
|
|
2023
|
+
const ms = Date.parse(value);
|
|
2024
|
+
if (!isNaN(ms)) return { ms, hasTime: true };
|
|
1999
2025
|
}
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2026
|
+
throw new Error(
|
|
2027
|
+
"Date must be in YYYY-MM-DD, YYYY-MM-DDTHH:MM[:SS], or full ISO 8601 format (e.g. 2025-03-15T14:30 or 2025-03-15T14:30:00+08:00)"
|
|
2028
|
+
);
|
|
2029
|
+
}
|
|
2030
|
+
function wallClockToMs(year, month, day, hour, minute, second, timezone, rawValue) {
|
|
2004
2031
|
if (timezone) {
|
|
2005
2032
|
try {
|
|
2006
|
-
const ms2 =
|
|
2033
|
+
const ms2 = wallClockToTimezoneMs(year, month, day, hour, minute, second, timezone);
|
|
2007
2034
|
if (!isNaN(ms2)) return ms2;
|
|
2008
2035
|
} catch {
|
|
2009
2036
|
}
|
|
2010
2037
|
}
|
|
2011
|
-
const ms = Date.UTC(
|
|
2012
|
-
if (isNaN(ms)) throw new Error(`Invalid date: ${
|
|
2038
|
+
const ms = Date.UTC(year, month - 1, day, hour, minute, second);
|
|
2039
|
+
if (isNaN(ms)) throw new Error(`Invalid date: ${rawValue}`);
|
|
2013
2040
|
return ms;
|
|
2014
2041
|
}
|
|
2015
|
-
function
|
|
2016
|
-
const approxUtc = new Date(Date.UTC(year, month - 1, day));
|
|
2042
|
+
function wallClockToTimezoneMs(year, month, day, hour, minute, second, timezone) {
|
|
2043
|
+
const approxUtc = new Date(Date.UTC(year, month - 1, day, hour, minute, second));
|
|
2017
2044
|
const tzStr = approxUtc.toLocaleString("en-US", {
|
|
2018
2045
|
timeZone: timezone,
|
|
2019
2046
|
year: "numeric",
|
|
@@ -2074,13 +2101,15 @@ function buildUpdatePayload(opts, timezone) {
|
|
|
2074
2101
|
if (opts.dueDate === "none" || opts.dueDate === "clear") {
|
|
2075
2102
|
payload.due_date = null;
|
|
2076
2103
|
} else {
|
|
2077
|
-
|
|
2078
|
-
payload.
|
|
2104
|
+
const parsed = parseDueDate(opts.dueDate, timezone);
|
|
2105
|
+
payload.due_date = parsed.ms;
|
|
2106
|
+
payload.due_date_time = parsed.hasTime;
|
|
2079
2107
|
}
|
|
2080
2108
|
}
|
|
2081
2109
|
if (opts.startDate !== void 0) {
|
|
2082
|
-
|
|
2083
|
-
payload.
|
|
2110
|
+
const parsed = parseDueDate(opts.startDate, timezone);
|
|
2111
|
+
payload.start_date = parsed.ms;
|
|
2112
|
+
payload.start_date_time = parsed.hasTime;
|
|
2084
2113
|
}
|
|
2085
2114
|
if (opts.assignee !== void 0 || opts.removeAssignee !== void 0) {
|
|
2086
2115
|
payload.assignees = {};
|
|
@@ -2180,12 +2209,14 @@ async function createTask(config, options) {
|
|
|
2180
2209
|
payload.priority = parsePriority(options.priority);
|
|
2181
2210
|
}
|
|
2182
2211
|
if (options.dueDate !== void 0) {
|
|
2183
|
-
|
|
2184
|
-
payload.
|
|
2212
|
+
const parsed = parseDueDate(options.dueDate, timezone);
|
|
2213
|
+
payload.due_date = parsed.ms;
|
|
2214
|
+
payload.due_date_time = parsed.hasTime;
|
|
2185
2215
|
}
|
|
2186
2216
|
if (options.startDate !== void 0) {
|
|
2187
|
-
|
|
2188
|
-
payload.
|
|
2217
|
+
const parsed = parseDueDate(options.startDate, timezone);
|
|
2218
|
+
payload.start_date = parsed.ms;
|
|
2219
|
+
payload.start_date_time = parsed.hasTime;
|
|
2189
2220
|
}
|
|
2190
2221
|
if (options.assignee !== void 0) {
|
|
2191
2222
|
payload.assignees = [parseAssigneeId(options.assignee)];
|
|
@@ -2876,10 +2907,10 @@ function printComments(comments, forceJson) {
|
|
|
2876
2907
|
console.log("No comments found.");
|
|
2877
2908
|
return;
|
|
2878
2909
|
}
|
|
2879
|
-
const
|
|
2910
|
+
const separator2 = chalk4.dim("-".repeat(60));
|
|
2880
2911
|
for (let i = 0; i < comments.length; i++) {
|
|
2881
2912
|
const c = comments[i];
|
|
2882
|
-
if (i > 0) console.log(
|
|
2913
|
+
if (i > 0) console.log(separator2);
|
|
2883
2914
|
console.log(`${chalk4.bold(c.user)} ${chalk4.dim(formatTimestamp(c.date))}`);
|
|
2884
2915
|
console.log(c.text);
|
|
2885
2916
|
if (i < comments.length - 1) console.log("");
|
|
@@ -6804,7 +6835,13 @@ async function bulkAssign(config, userIdOrMe, taskIds, action) {
|
|
|
6804
6835
|
async function bulkDueDate(config, date, taskIds) {
|
|
6805
6836
|
const client = new ClickUpClient(config);
|
|
6806
6837
|
const timezone = await client.getUserTimezone();
|
|
6807
|
-
|
|
6838
|
+
let payload;
|
|
6839
|
+
if (date === "none" || date === "clear") {
|
|
6840
|
+
payload = { due_date: null };
|
|
6841
|
+
} else {
|
|
6842
|
+
const parsed = parseDueDate(date, timezone);
|
|
6843
|
+
payload = { due_date: parsed.ms, due_date_time: parsed.hasTime };
|
|
6844
|
+
}
|
|
6808
6845
|
const outcomes = await runInBatches(
|
|
6809
6846
|
taskIds,
|
|
6810
6847
|
BULK_CONCURRENCY,
|
|
@@ -6888,7 +6925,7 @@ async function createGoal(config, name, opts) {
|
|
|
6888
6925
|
return client.createGoal(config.teamId, name, {
|
|
6889
6926
|
description: opts?.description,
|
|
6890
6927
|
color: opts?.color,
|
|
6891
|
-
...opts?.dueDate ? { dueDate: parseDueDate(opts.dueDate, timezone) } : {}
|
|
6928
|
+
...opts?.dueDate ? { dueDate: parseDueDate(opts.dueDate, timezone).ms } : {}
|
|
6892
6929
|
});
|
|
6893
6930
|
}
|
|
6894
6931
|
async function updateGoal(config, goalId, updates) {
|
|
@@ -7052,18 +7089,31 @@ function formatViewsMarkdown(views) {
|
|
|
7052
7089
|
|
|
7053
7090
|
// src/commands/chat.ts
|
|
7054
7091
|
import chalk22 from "chalk";
|
|
7092
|
+
function channelName(c) {
|
|
7093
|
+
return c.name || "DM";
|
|
7094
|
+
}
|
|
7095
|
+
function colorChannelType(type) {
|
|
7096
|
+
if (type === "CHANNEL") return chalk22.cyan(type);
|
|
7097
|
+
if (type === "DM") return chalk22.dim(type);
|
|
7098
|
+
if (type === "GROUP_DM") return chalk22.blue(type);
|
|
7099
|
+
return type;
|
|
7100
|
+
}
|
|
7101
|
+
function colorVisibility(v) {
|
|
7102
|
+
if (v === "PUBLIC") return chalk22.green(v);
|
|
7103
|
+
return chalk22.dim(v);
|
|
7104
|
+
}
|
|
7055
7105
|
var CHANNEL_COLUMNS = [
|
|
7056
|
-
{ key: "
|
|
7057
|
-
{ key: "
|
|
7058
|
-
{ key: "type", label: "Type", maxWidth: 12 },
|
|
7059
|
-
{ key: "visibility", label: "Visibility", maxWidth: 10 },
|
|
7106
|
+
{ key: "name", label: "Name", maxWidth: 40, format: (v) => chalk22.bold(v) },
|
|
7107
|
+
{ key: "id", label: "ID", maxWidth: 20, format: (v) => chalk22.dim(v) },
|
|
7108
|
+
{ key: "type", label: "Type", maxWidth: 12, format: (v) => colorChannelType(v) },
|
|
7109
|
+
{ key: "visibility", label: "Visibility", maxWidth: 10, format: (v) => colorVisibility(v) },
|
|
7060
7110
|
{ key: "topic", label: "Topic", maxWidth: 40 }
|
|
7061
7111
|
];
|
|
7062
7112
|
function formatChannelsTable(channels) {
|
|
7063
7113
|
if (channels.length === 0) return "No channels found";
|
|
7064
7114
|
const rows = channels.map((c) => ({
|
|
7065
7115
|
id: c.id,
|
|
7066
|
-
name: c
|
|
7116
|
+
name: channelName(c),
|
|
7067
7117
|
type: c.type,
|
|
7068
7118
|
visibility: c.visibility,
|
|
7069
7119
|
topic: c.topic ?? ""
|
|
@@ -7073,25 +7123,32 @@ function formatChannelsTable(channels) {
|
|
|
7073
7123
|
function formatChannelsMarkdown(channels) {
|
|
7074
7124
|
if (channels.length === 0) return "No channels found";
|
|
7075
7125
|
return channels.map((c) => {
|
|
7076
|
-
const name = c
|
|
7126
|
+
const name = channelName(c);
|
|
7077
7127
|
return `- **${name}** (${c.id}) \u2014 ${c.type}${c.topic ? `, ${c.topic}` : ""}`;
|
|
7078
7128
|
}).join("\n");
|
|
7079
7129
|
}
|
|
7080
7130
|
function formatChannelDetail(channel) {
|
|
7081
7131
|
const lines = [];
|
|
7082
|
-
lines.push(chalk22.bold(channel
|
|
7083
|
-
lines.push(
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7132
|
+
lines.push(chalk22.bold.underline(channelName(channel)));
|
|
7133
|
+
lines.push("");
|
|
7134
|
+
const fields = [
|
|
7135
|
+
["ID", chalk22.dim(channel.id)],
|
|
7136
|
+
["Type", colorChannelType(channel.type)],
|
|
7137
|
+
["Visibility", colorVisibility(channel.visibility)]
|
|
7138
|
+
];
|
|
7139
|
+
if (channel.topic) fields.push(["Topic", channel.topic]);
|
|
7140
|
+
if (channel.description) fields.push(["Description", channel.description]);
|
|
7141
|
+
fields.push(["Archived", channel.archived ? chalk22.yellow("Yes") : "No"]);
|
|
7142
|
+
fields.push(["Created", formatDate(channel.created_at)]);
|
|
7143
|
+
const maxLabel = Math.max(...fields.map(([k]) => k.length));
|
|
7144
|
+
for (const [label, value] of fields) {
|
|
7145
|
+
lines.push(` ${chalk22.bold(label.padEnd(maxLabel + 1))} ${value}`);
|
|
7146
|
+
}
|
|
7090
7147
|
return lines.join("\n");
|
|
7091
7148
|
}
|
|
7092
7149
|
var CHAT_MEMBER_COLUMNS = [
|
|
7093
|
-
{ key: "name", label: "Name", maxWidth: 30 },
|
|
7094
|
-
{ key: "id", label: "ID", maxWidth: 15 },
|
|
7150
|
+
{ key: "name", label: "Name", maxWidth: 30, format: (v) => chalk22.bold(v) },
|
|
7151
|
+
{ key: "id", label: "ID", maxWidth: 15, format: (v) => chalk22.dim(v) },
|
|
7095
7152
|
{ key: "email", label: "Email", maxWidth: 40 },
|
|
7096
7153
|
{ key: "type", label: "Type", maxWidth: 12 }
|
|
7097
7154
|
];
|
|
@@ -7115,23 +7172,25 @@ function formatChatMembersMarkdown(members) {
|
|
|
7115
7172
|
|
|
7116
7173
|
// src/commands/chat-message.ts
|
|
7117
7174
|
import chalk23 from "chalk";
|
|
7175
|
+
var separator = chalk23.dim("-".repeat(60));
|
|
7118
7176
|
function formatMessages(messages) {
|
|
7119
7177
|
if (messages.length === 0) return "No messages";
|
|
7120
7178
|
const lines = [];
|
|
7121
|
-
for (
|
|
7122
|
-
const
|
|
7123
|
-
|
|
7124
|
-
|
|
7125
|
-
header.push(chalk23.cyan(`[${msg.post_data.title}]`));
|
|
7126
|
-
}
|
|
7179
|
+
for (let i = 0; i < messages.length; i++) {
|
|
7180
|
+
const msg = messages[i];
|
|
7181
|
+
if (i > 0) lines.push(separator);
|
|
7182
|
+
const meta = [chalk23.bold(`@${msg.user_id}`), chalk23.dim(formatTimestamp(msg.date))];
|
|
7127
7183
|
if (msg.replies_count) {
|
|
7128
|
-
|
|
7184
|
+
meta.push(chalk23.dim(`${msg.replies_count} replies`));
|
|
7129
7185
|
}
|
|
7130
|
-
|
|
7131
|
-
lines.push(
|
|
7132
|
-
|
|
7186
|
+
meta.push(chalk23.dim(`(${msg.id})`));
|
|
7187
|
+
lines.push(meta.join(" "));
|
|
7188
|
+
if (msg.type === "post" && msg.post_data?.title) {
|
|
7189
|
+
lines.push(chalk23.cyan.bold(msg.post_data.title));
|
|
7190
|
+
}
|
|
7191
|
+
lines.push(msg.content);
|
|
7133
7192
|
}
|
|
7134
|
-
return lines.join("\n")
|
|
7193
|
+
return lines.join("\n");
|
|
7135
7194
|
}
|
|
7136
7195
|
function formatMessagesMarkdown(messages) {
|
|
7137
7196
|
if (messages.length === 0) return "No messages";
|
|
@@ -7147,6 +7206,29 @@ ${msg.content}`;
|
|
|
7147
7206
|
|
|
7148
7207
|
// src/commands/chat-reaction.ts
|
|
7149
7208
|
import chalk24 from "chalk";
|
|
7209
|
+
var EMOJI_MAP = {
|
|
7210
|
+
thumbsup: "\u{1F44D}",
|
|
7211
|
+
thumbsdown: "\u{1F44E}",
|
|
7212
|
+
heart: "\u2764\uFE0F",
|
|
7213
|
+
fire: "\u{1F525}",
|
|
7214
|
+
eyes: "\u{1F440}",
|
|
7215
|
+
rocket: "\u{1F680}",
|
|
7216
|
+
tada: "\u{1F389}",
|
|
7217
|
+
check: "\u2705",
|
|
7218
|
+
x: "\u274C",
|
|
7219
|
+
warning: "\u26A0\uFE0F",
|
|
7220
|
+
laugh: "\u{1F602}",
|
|
7221
|
+
smile: "\u{1F60A}",
|
|
7222
|
+
thinking: "\u{1F914}",
|
|
7223
|
+
clap: "\u{1F44F}",
|
|
7224
|
+
pray: "\u{1F64F}",
|
|
7225
|
+
100: "\u{1F4AF}",
|
|
7226
|
+
star: "\u2B50",
|
|
7227
|
+
wave: "\u{1F44B}"
|
|
7228
|
+
};
|
|
7229
|
+
function emojiChar(name) {
|
|
7230
|
+
return EMOJI_MAP[name] ?? `:${name}:`;
|
|
7231
|
+
}
|
|
7150
7232
|
function groupByEmoji(reactions) {
|
|
7151
7233
|
const groups = /* @__PURE__ */ new Map();
|
|
7152
7234
|
for (const r of reactions) {
|
|
@@ -7161,7 +7243,9 @@ function formatReactions(reactions) {
|
|
|
7161
7243
|
const groups = groupByEmoji(reactions);
|
|
7162
7244
|
const lines = [];
|
|
7163
7245
|
for (const [emoji, users] of groups) {
|
|
7164
|
-
|
|
7246
|
+
const icon = emojiChar(emoji);
|
|
7247
|
+
const userList = users.map((u) => chalk24.bold(`@${u}`)).join(", ");
|
|
7248
|
+
lines.push(`${icon} ${chalk24.dim(emoji)} ${chalk24.dim(`(${users.length})`)} \u2014 ${userList}`);
|
|
7165
7249
|
}
|
|
7166
7250
|
return lines.join("\n");
|
|
7167
7251
|
}
|
|
@@ -7607,7 +7691,13 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
7607
7691
|
program.command("update <taskId>").description("Update a task").option("-n, --name <text>", "New task name").option("-d, --description <text>", "New description (markdown supported)").option(
|
|
7608
7692
|
"-s, --status <status>",
|
|
7609
7693
|
'New status (fuzzy matched, e.g. "prog" matches "in progress")'
|
|
7610
|
-
).option("--priority <level>", "Priority: urgent, high, normal, low (or 1-4)").option(
|
|
7694
|
+
).option("--priority <level>", "Priority: urgent, high, normal, low (or 1-4)").option(
|
|
7695
|
+
"--due-date <date>",
|
|
7696
|
+
'Due date (YYYY-MM-DD, YYYY-MM-DDTHH:MM[:SS], or full ISO 8601 with offset; or "none"/"clear" to remove)'
|
|
7697
|
+
).option(
|
|
7698
|
+
"--start-date <date>",
|
|
7699
|
+
"Start date (YYYY-MM-DD, YYYY-MM-DDTHH:MM[:SS], or full ISO 8601 with offset)"
|
|
7700
|
+
).option(
|
|
7611
7701
|
"--time-estimate <duration>",
|
|
7612
7702
|
'Time estimate (e.g. "2h", "30m", "1h30m", "0" or "none" to clear)'
|
|
7613
7703
|
).option("--assignee <userId>", 'Add assignee by user ID or "me"').option("--remove-assignee <userId>", 'Remove 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("--type <type>", "Change task type (name or custom_item_id)").option("--field <nameAndValue...>", 'Set custom field: --field "Name" value').option("--json", "Force JSON output even in terminal").action(
|
|
@@ -7657,7 +7747,13 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
|
|
|
7657
7747
|
}
|
|
7658
7748
|
)
|
|
7659
7749
|
);
|
|
7660
|
-
program.command("create").description("Create a new task").option("-l, --list <listId>", 'Target list ID or "sprint:current" for active sprint').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(
|
|
7750
|
+
program.command("create").description("Create a new task").option("-l, --list <listId>", 'Target list ID or "sprint:current" for active sprint').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(
|
|
7751
|
+
"--due-date <date>",
|
|
7752
|
+
"Due date (YYYY-MM-DD, YYYY-MM-DDTHH:MM[:SS], or full ISO 8601 with offset)"
|
|
7753
|
+
).option(
|
|
7754
|
+
"--start-date <date>",
|
|
7755
|
+
"Start date (YYYY-MM-DD, YYYY-MM-DDTHH:MM[:SS], or full ISO 8601 with offset)"
|
|
7756
|
+
).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 (find IDs with cup templates)").option("--field <nameAndValue...>", 'Set custom field: --field "Name" value (can repeat)').option("--json", "Force JSON output even in terminal").action(
|
|
7661
7757
|
wrapAction(async (opts) => {
|
|
7662
7758
|
const config = loadConfig(getProfileName());
|
|
7663
7759
|
if (opts.list === "sprint:current") {
|
package/package.json
CHANGED
|
@@ -3,11 +3,11 @@ name: clickup
|
|
|
3
3
|
description: 'Use when managing ClickUp tasks, sprints, or comments via the `cup` CLI tool. Triggers: task queries, status updates, sprint tracking, creating subtasks, posting comments, threaded replies, standup summaries, searching tasks, checking overdue items, assigning tasks, listing spaces and lists, opening tasks in browser, checking auth or config, setting custom fields, deleting tasks, managing tags, managing checklists, editing comments, task links, time tracking, attachments, file uploads, listing members, listing fields, duplicating tasks, bulk operations, goals, key results, saved filters, favorites.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# ClickUp CLI (`cup`) - skill version 1.
|
|
6
|
+
# ClickUp CLI (`cup`) - skill version 1.28.0
|
|
7
7
|
|
|
8
8
|
Reference for AI agents using the `cup` CLI tool. Covers task management, sprint tracking, comments, time tracking, custom fields, goals, docs, and project workflows.
|
|
9
9
|
|
|
10
|
-
> **Version check:** Run `cup --version`. If your installed version is older than 1.
|
|
10
|
+
> **Version check:** Run `cup --version`. If your installed version is older than 1.28.0, update with `npm install -g @krodak/clickup-cli` and refresh this skill with `cup skill`.
|
|
11
11
|
|
|
12
12
|
## Install & Configure
|
|
13
13
|
|
|
@@ -248,7 +248,7 @@ All commands support `--help` for full flag details. All commands support `--jso
|
|
|
248
248
|
| Task IDs | Native (`abc123def`) or custom (`PROJ-123`). Custom IDs auto-detected by `PREFIX-DIGITS` format |
|
|
249
249
|
| `--status` | Fuzzy matching: exact > starts-with > contains. Prints match to stderr |
|
|
250
250
|
| `--priority` | Names (`urgent`, `high`, `normal`, `low`) or numbers (1-4) |
|
|
251
|
-
| `--due-date` | `YYYY-MM-DD`
|
|
251
|
+
| `--due-date` | `YYYY-MM-DD` (date only), `YYYY-MM-DDTHH:MM` (with time), or full ISO 8601 with offset. Time-of-day formats set `due_date_time: true` in ClickUp |
|
|
252
252
|
| `--assignee` | User ID or `me` |
|
|
253
253
|
| `--tags` | Comma-separated (e.g. `--tags "bug,frontend"`) |
|
|
254
254
|
| `--time-estimate` | Duration: `"2h"`, `"30m"`, `"1h30m"`, or raw milliseconds |
|
|
@@ -323,6 +323,8 @@ cup inbox --days 7 # recently updated
|
|
|
323
323
|
```bash
|
|
324
324
|
cup update abc123def -s "done"
|
|
325
325
|
cup update abc123def --priority high --due-date 2025-03-15
|
|
326
|
+
cup update abc123def --due-date 2025-03-15T14:30 # date + time (user's timezone)
|
|
327
|
+
cup update abc123def --due-date 2025-03-15T14:30:00Z # UTC
|
|
326
328
|
cup create -n "Fix the thing" -p abc123def
|
|
327
329
|
cup create -n "Fix bug" -l <listId> --priority urgent --tags "bug,frontend"
|
|
328
330
|
cup create -n "Bug fix" -l sprint:current # create in active sprint
|