@krodak/clickup-cli 0.10.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/index.js +90 -44
- package/package.json +1 -1
- package/skills/clickup-cli/SKILL.md +45 -45
package/README.md
CHANGED
|
@@ -118,6 +118,7 @@ cu tasks --status "in progress"
|
|
|
118
118
|
cu tasks --name "login"
|
|
119
119
|
cu tasks --list <listId>
|
|
120
120
|
cu tasks --space <spaceId>
|
|
121
|
+
cu tasks --include-closed
|
|
121
122
|
cu tasks --json
|
|
122
123
|
```
|
|
123
124
|
|
|
@@ -131,6 +132,7 @@ cu initiatives --status "to do"
|
|
|
131
132
|
cu initiatives --name "auth"
|
|
132
133
|
cu initiatives --list <listId>
|
|
133
134
|
cu initiatives --space <spaceId>
|
|
135
|
+
cu initiatives --include-closed
|
|
134
136
|
cu initiatives --json
|
|
135
137
|
```
|
|
136
138
|
|
|
@@ -141,6 +143,7 @@ List my tasks in the currently active sprint (auto-detected from sprint folder d
|
|
|
141
143
|
```bash
|
|
142
144
|
cu sprint
|
|
143
145
|
cu sprint --status "in progress"
|
|
146
|
+
cu sprint --include-closed
|
|
144
147
|
cu sprint --json
|
|
145
148
|
```
|
|
146
149
|
|
|
@@ -159,6 +162,7 @@ All tasks assigned to me, grouped by pipeline stage (code review, in progress, t
|
|
|
159
162
|
|
|
160
163
|
```bash
|
|
161
164
|
cu assigned
|
|
165
|
+
cu assigned --status "in progress"
|
|
162
166
|
cu assigned --include-closed
|
|
163
167
|
cu assigned --json
|
|
164
168
|
```
|
|
@@ -190,6 +194,8 @@ List subtasks of a task or initiative.
|
|
|
190
194
|
|
|
191
195
|
```bash
|
|
192
196
|
cu subtasks abc123
|
|
197
|
+
cu subtasks abc123 --status "in progress"
|
|
198
|
+
cu subtasks abc123 --name "auth"
|
|
193
199
|
cu subtasks abc123 --include-closed
|
|
194
200
|
cu subtasks abc123 --json
|
|
195
201
|
```
|
|
@@ -330,6 +336,7 @@ cu search "login bug"
|
|
|
330
336
|
cu search auth
|
|
331
337
|
cu search "payment flow" --json
|
|
332
338
|
cu search auth --status "prog" # fuzzy matches "in progress"
|
|
339
|
+
cu search "old task" --include-closed
|
|
333
340
|
```
|
|
334
341
|
|
|
335
342
|
### `cu summary`
|
package/dist/index.js
CHANGED
|
@@ -177,8 +177,8 @@ var ClickUpClient = class {
|
|
|
177
177
|
async getTask(taskId) {
|
|
178
178
|
return this.request(`/task/${taskId}`);
|
|
179
179
|
}
|
|
180
|
-
async
|
|
181
|
-
return this.updateTask(taskId, {
|
|
180
|
+
async updateTaskMarkdown(taskId, markdown) {
|
|
181
|
+
return this.updateTask(taskId, { markdown_content: markdown });
|
|
182
182
|
}
|
|
183
183
|
async createTask(listId, options) {
|
|
184
184
|
return this.request(`/list/${listId}/task`, {
|
|
@@ -712,7 +712,7 @@ function parseTimeEstimate(value) {
|
|
|
712
712
|
function buildUpdatePayload(opts) {
|
|
713
713
|
const payload = {};
|
|
714
714
|
if (opts.name !== void 0) payload.name = opts.name;
|
|
715
|
-
if (opts.description !== void 0) payload.
|
|
715
|
+
if (opts.description !== void 0) payload.markdown_content = opts.description;
|
|
716
716
|
if (opts.status !== void 0) payload.status = opts.status;
|
|
717
717
|
if (opts.priority !== void 0) payload.priority = parsePriority(opts.priority);
|
|
718
718
|
if (opts.dueDate !== void 0) {
|
|
@@ -728,7 +728,7 @@ function buildUpdatePayload(opts) {
|
|
|
728
728
|
return payload;
|
|
729
729
|
}
|
|
730
730
|
function hasUpdateFields(options) {
|
|
731
|
-
return options.name !== void 0 || options.description !== void 0 || options.status !== void 0 || options.priority !== void 0 || options.due_date !== void 0 || options.time_estimate !== void 0 || options.assignees !== void 0;
|
|
731
|
+
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;
|
|
732
732
|
}
|
|
733
733
|
async function resolveStatus(client, taskId, statusInput) {
|
|
734
734
|
const task = await client.getTask(taskId);
|
|
@@ -771,7 +771,7 @@ async function createTask(config, options) {
|
|
|
771
771
|
}
|
|
772
772
|
const payload = {
|
|
773
773
|
name: options.name,
|
|
774
|
-
...options.description !== void 0 ? {
|
|
774
|
+
...options.description !== void 0 ? { markdown_content: options.description } : {},
|
|
775
775
|
...options.parent !== void 0 ? { parent: options.parent } : {},
|
|
776
776
|
...options.status !== void 0 ? { status: options.status } : {}
|
|
777
777
|
};
|
|
@@ -934,7 +934,10 @@ async function runSprintCommand(config, opts) {
|
|
|
934
934
|
} else {
|
|
935
935
|
allTasks = await client.getTasksFromList(activeList.id);
|
|
936
936
|
}
|
|
937
|
-
|
|
937
|
+
let sprintTasks = allTasks.filter((t) => t.assignees.some((a) => Number(a.id) === me.id));
|
|
938
|
+
if (!opts.includeClosed) {
|
|
939
|
+
sprintTasks = sprintTasks.filter((t) => !isDoneStatus(t.status.status));
|
|
940
|
+
}
|
|
938
941
|
const filtered = opts.status ? sprintTasks.filter((t) => t.status.status.toLowerCase() === opts.status.toLowerCase()) : sprintTasks;
|
|
939
942
|
const summaries = filtered.map(summarize);
|
|
940
943
|
await printTasks(summaries, opts.json ?? false, config);
|
|
@@ -997,7 +1000,7 @@ async function listSprints(config, opts = {}) {
|
|
|
997
1000
|
const lists = listsByFolder[i];
|
|
998
1001
|
allSprints.push(...buildSprintInfos(lists, folder.name, today));
|
|
999
1002
|
}
|
|
1000
|
-
if (opts.json
|
|
1003
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
1001
1004
|
console.log(JSON.stringify(allSprints, null, 2));
|
|
1002
1005
|
return;
|
|
1003
1006
|
}
|
|
@@ -1014,6 +1017,15 @@ async function listSprints(config, opts = {}) {
|
|
|
1014
1017
|
dates: dateStr
|
|
1015
1018
|
};
|
|
1016
1019
|
});
|
|
1020
|
+
if (!isTTY()) {
|
|
1021
|
+
const mdColumns = [
|
|
1022
|
+
{ key: "id", label: "ID" },
|
|
1023
|
+
{ key: "sprint", label: "Sprint" },
|
|
1024
|
+
{ key: "dates", label: "Dates" }
|
|
1025
|
+
];
|
|
1026
|
+
console.log(formatMarkdownTable(rows, mdColumns));
|
|
1027
|
+
return;
|
|
1028
|
+
}
|
|
1017
1029
|
console.log(formatTable(rows, SPRINT_COLUMNS));
|
|
1018
1030
|
}
|
|
1019
1031
|
|
|
@@ -1231,6 +1243,8 @@ async function listSpaces(config, opts) {
|
|
|
1231
1243
|
console.log(JSON.stringify(spaces, null, 2));
|
|
1232
1244
|
} else if (!isTTY()) {
|
|
1233
1245
|
console.log(formatSpacesMarkdown(spaces.map((s) => ({ id: s.id, name: s.name }))));
|
|
1246
|
+
} else if (spaces.length === 0) {
|
|
1247
|
+
console.log("No spaces found.");
|
|
1234
1248
|
} else {
|
|
1235
1249
|
const table = formatTable(
|
|
1236
1250
|
spaces.map((s) => ({ id: s.id, name: s.name })),
|
|
@@ -1295,7 +1309,11 @@ async function runAssignedCommand(config, opts) {
|
|
|
1295
1309
|
const allTasks = await client.getMyTasks(config.teamId, {
|
|
1296
1310
|
includeClosed: opts.includeClosed
|
|
1297
1311
|
});
|
|
1298
|
-
|
|
1312
|
+
let groups = groupByStatus(allTasks, opts.includeClosed ?? false);
|
|
1313
|
+
if (opts.status) {
|
|
1314
|
+
const lower = opts.status.toLowerCase();
|
|
1315
|
+
groups = groups.filter((g) => g.status.toLowerCase() === lower);
|
|
1316
|
+
}
|
|
1299
1317
|
if (shouldOutputJson(opts.json ?? false)) {
|
|
1300
1318
|
const result = {};
|
|
1301
1319
|
for (const group of groups) {
|
|
@@ -1552,10 +1570,20 @@ async function fetchActivity(config, taskId) {
|
|
|
1552
1570
|
return { task, comments };
|
|
1553
1571
|
}
|
|
1554
1572
|
function printActivity(result, forceJson) {
|
|
1555
|
-
if (forceJson
|
|
1573
|
+
if (shouldOutputJson(forceJson)) {
|
|
1556
1574
|
console.log(JSON.stringify(result, null, 2));
|
|
1557
1575
|
return;
|
|
1558
1576
|
}
|
|
1577
|
+
if (!isTTY()) {
|
|
1578
|
+
const taskMd = formatTaskDetailMarkdown(result.task);
|
|
1579
|
+
const commentsMd = formatCommentsMarkdown(result.comments);
|
|
1580
|
+
console.log(`${taskMd}
|
|
1581
|
+
|
|
1582
|
+
## Comments
|
|
1583
|
+
|
|
1584
|
+
${commentsMd}`);
|
|
1585
|
+
return;
|
|
1586
|
+
}
|
|
1559
1587
|
console.log(formatTaskDetail(result.task));
|
|
1560
1588
|
console.log("");
|
|
1561
1589
|
console.log(chalk4.bold("Comments"));
|
|
@@ -1998,7 +2026,9 @@ async function searchTasks(config, query, opts = {}) {
|
|
|
1998
2026
|
throw new Error("Search query cannot be empty");
|
|
1999
2027
|
}
|
|
2000
2028
|
const client = new ClickUpClient(config);
|
|
2001
|
-
const allTasks = await client.getMyTasks(config.teamId
|
|
2029
|
+
const allTasks = await client.getMyTasks(config.teamId, {
|
|
2030
|
+
includeClosed: opts.includeClosed
|
|
2031
|
+
});
|
|
2002
2032
|
const words = trimmed.toLowerCase().split(/\s+/);
|
|
2003
2033
|
let matched = allTasks.filter((task) => {
|
|
2004
2034
|
const name = task.name.toLowerCase();
|
|
@@ -2067,17 +2097,16 @@ program.command("auth").description("Validate API token and show current user").
|
|
|
2067
2097
|
wrapAction(async (opts) => {
|
|
2068
2098
|
const config = loadConfig();
|
|
2069
2099
|
const result = await checkAuth(config);
|
|
2070
|
-
if (opts.json
|
|
2100
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
2071
2101
|
console.log(JSON.stringify(result, null, 2));
|
|
2072
2102
|
} else if (result.authenticated && result.user) {
|
|
2073
2103
|
console.log(`Authenticated as @${result.user.username} (id: ${result.user.id})`);
|
|
2074
2104
|
} else {
|
|
2075
|
-
|
|
2076
|
-
process.exit(1);
|
|
2105
|
+
throw new Error(`Authentication failed: ${result.error ?? "unknown error"}`);
|
|
2077
2106
|
}
|
|
2078
2107
|
})
|
|
2079
2108
|
);
|
|
2080
|
-
program.command("tasks").description("List tasks assigned to me").option("--status <status>", 'Filter by status (e.g. "in progress")').option("--list <listId>", "Filter by list ID").option("--space <spaceId>", "Filter by space ID").option("--name <partial>", "Filter by name (case-insensitive contains)").option("--json", "Force JSON output even in terminal").action(
|
|
2109
|
+
program.command("tasks").description("List tasks assigned to me").option("--status <status>", 'Filter by status (e.g. "in progress")').option("--list <listId>", "Filter by list ID").option("--space <spaceId>", "Filter by space ID").option("--name <partial>", "Filter by name (case-insensitive contains)").option("--include-closed", "Include done/closed tasks").option("--json", "Force JSON output even in terminal").action(
|
|
2081
2110
|
wrapAction(async (opts) => {
|
|
2082
2111
|
const config = loadConfig();
|
|
2083
2112
|
const tasks = await fetchMyTasks(config, {
|
|
@@ -2085,12 +2114,13 @@ program.command("tasks").description("List tasks assigned to me").option("--stat
|
|
|
2085
2114
|
statuses: opts.status ? [opts.status] : void 0,
|
|
2086
2115
|
listIds: opts.list ? [opts.list] : void 0,
|
|
2087
2116
|
spaceIds: opts.space ? [opts.space] : void 0,
|
|
2088
|
-
name: opts.name
|
|
2117
|
+
name: opts.name,
|
|
2118
|
+
includeClosed: opts.includeClosed
|
|
2089
2119
|
});
|
|
2090
2120
|
await printTasks(tasks, opts.json ?? false, config);
|
|
2091
2121
|
})
|
|
2092
2122
|
);
|
|
2093
|
-
program.command("initiatives").description("List initiatives assigned to me").option("--status <status>", "Filter by status").option("--list <listId>", "Filter by list ID").option("--space <spaceId>", "Filter by space ID").option("--name <partial>", "Filter by name (case-insensitive contains)").option("--json", "Force JSON output even in terminal").action(
|
|
2123
|
+
program.command("initiatives").description("List initiatives assigned to me").option("--status <status>", "Filter by status").option("--list <listId>", "Filter by list ID").option("--space <spaceId>", "Filter by space ID").option("--name <partial>", "Filter by name (case-insensitive contains)").option("--include-closed", "Include done/closed tasks").option("--json", "Force JSON output even in terminal").action(
|
|
2094
2124
|
wrapAction(async (opts) => {
|
|
2095
2125
|
const config = loadConfig();
|
|
2096
2126
|
const tasks = await fetchMyTasks(config, {
|
|
@@ -2098,7 +2128,8 @@ program.command("initiatives").description("List initiatives assigned to me").op
|
|
|
2098
2128
|
statuses: opts.status ? [opts.status] : void 0,
|
|
2099
2129
|
listIds: opts.list ? [opts.list] : void 0,
|
|
2100
2130
|
spaceIds: opts.space ? [opts.space] : void 0,
|
|
2101
|
-
name: opts.name
|
|
2131
|
+
name: opts.name,
|
|
2132
|
+
includeClosed: opts.includeClosed
|
|
2102
2133
|
});
|
|
2103
2134
|
await printTasks(tasks, opts.json ?? false, config);
|
|
2104
2135
|
})
|
|
@@ -2121,29 +2152,31 @@ program.command("update <taskId>").description("Update a task").option("-n, --na
|
|
|
2121
2152
|
const config = loadConfig();
|
|
2122
2153
|
const payload = buildUpdatePayload(opts);
|
|
2123
2154
|
const result = await updateTask(config, taskId, payload);
|
|
2124
|
-
if (shouldOutputJson(false)) {
|
|
2155
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
2125
2156
|
console.log(JSON.stringify(result, null, 2));
|
|
2126
2157
|
} else {
|
|
2127
2158
|
console.log(formatUpdateConfirmation(result.id, result.name));
|
|
2128
2159
|
}
|
|
2129
2160
|
})
|
|
2130
2161
|
);
|
|
2131
|
-
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").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").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("--json", "Force JSON output even in terminal").action(
|
|
2162
|
+
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").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("--json", "Force JSON output even in terminal").action(
|
|
2132
2163
|
wrapAction(async (opts) => {
|
|
2133
2164
|
const config = loadConfig();
|
|
2134
2165
|
const result = await createTask(config, opts);
|
|
2135
|
-
if (shouldOutputJson(false)) {
|
|
2166
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
2136
2167
|
console.log(JSON.stringify(result, null, 2));
|
|
2137
2168
|
} else {
|
|
2138
2169
|
console.log(formatCreateConfirmation(result.id, result.name, result.url));
|
|
2139
2170
|
}
|
|
2140
2171
|
})
|
|
2141
2172
|
);
|
|
2142
|
-
program.command("sprint").description("List my tasks in the current active sprint (auto-detected)").option("--status <status>", "Filter by status").option("--space <nameOrId>", "Narrow sprint search to a specific space (partial name or ID)").option("--json", "Force JSON output even in terminal").action(
|
|
2143
|
-
wrapAction(
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2173
|
+
program.command("sprint").description("List my tasks in the current active sprint (auto-detected)").option("--status <status>", "Filter by status").option("--space <nameOrId>", "Narrow sprint search to a specific space (partial name or ID)").option("--include-closed", "Include done/closed tasks").option("--json", "Force JSON output even in terminal").action(
|
|
2174
|
+
wrapAction(
|
|
2175
|
+
async (opts) => {
|
|
2176
|
+
const config = loadConfig();
|
|
2177
|
+
await runSprintCommand(config, opts);
|
|
2178
|
+
}
|
|
2179
|
+
)
|
|
2147
2180
|
);
|
|
2148
2181
|
program.command("sprints").description("List all sprints in sprint folders").option("--space <nameOrId>", "Filter by space (partial name or ID)").option("--json", "Force JSON output even in terminal").action(
|
|
2149
2182
|
wrapAction(async (opts) => {
|
|
@@ -2151,18 +2184,28 @@ program.command("sprints").description("List all sprints in sprint folders").opt
|
|
|
2151
2184
|
await listSprints(config, opts);
|
|
2152
2185
|
})
|
|
2153
2186
|
);
|
|
2154
|
-
program.command("subtasks <taskId>").description("List subtasks of a task or initiative").option("--include-closed", "Include closed/done subtasks").option("--json", "Force JSON output even in terminal").action(
|
|
2155
|
-
wrapAction(
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2187
|
+
program.command("subtasks <taskId>").description("List subtasks of a task or initiative").option("--status <status>", "Filter by status").option("--name <partial>", "Filter by name (case-insensitive contains)").option("--include-closed", "Include closed/done subtasks").option("--json", "Force JSON output even in terminal").action(
|
|
2188
|
+
wrapAction(
|
|
2189
|
+
async (taskId, opts) => {
|
|
2190
|
+
const config = loadConfig();
|
|
2191
|
+
let tasks = await fetchSubtasks(config, taskId, { includeClosed: opts.includeClosed });
|
|
2192
|
+
if (opts.status) {
|
|
2193
|
+
const lower = opts.status.toLowerCase();
|
|
2194
|
+
tasks = tasks.filter((t) => t.status.toLowerCase() === lower);
|
|
2195
|
+
}
|
|
2196
|
+
if (opts.name) {
|
|
2197
|
+
const query = opts.name.toLowerCase();
|
|
2198
|
+
tasks = tasks.filter((t) => t.name.toLowerCase().includes(query));
|
|
2199
|
+
}
|
|
2200
|
+
await printTasks(tasks, opts.json ?? false, config);
|
|
2201
|
+
}
|
|
2202
|
+
)
|
|
2160
2203
|
);
|
|
2161
|
-
program.command("comment <taskId>").description("Post a comment on a task").requiredOption("-m, --message <text>", "Comment text").action(
|
|
2204
|
+
program.command("comment <taskId>").description("Post a comment on a task").requiredOption("-m, --message <text>", "Comment text").option("--json", "Force JSON output even in terminal").action(
|
|
2162
2205
|
wrapAction(async (taskId, opts) => {
|
|
2163
2206
|
const config = loadConfig();
|
|
2164
2207
|
const result = await postComment(config, taskId, opts.message);
|
|
2165
|
-
if (shouldOutputJson(false)) {
|
|
2208
|
+
if (shouldOutputJson(opts.json ?? false)) {
|
|
2166
2209
|
console.log(JSON.stringify(result, null, 2));
|
|
2167
2210
|
} else {
|
|
2168
2211
|
console.log(formatCommentConfirmation(result.id));
|
|
@@ -2201,14 +2244,13 @@ program.command("inbox").description("Recently updated tasks grouped by time per
|
|
|
2201
2244
|
const config = loadConfig();
|
|
2202
2245
|
const days = Number(opts.days ?? 30);
|
|
2203
2246
|
if (!Number.isFinite(days) || days <= 0) {
|
|
2204
|
-
|
|
2205
|
-
process.exit(1);
|
|
2247
|
+
throw new Error("--days must be a positive number");
|
|
2206
2248
|
}
|
|
2207
2249
|
const tasks = await fetchInbox(config, days);
|
|
2208
2250
|
await printInbox(tasks, opts.json ?? false, config);
|
|
2209
2251
|
})
|
|
2210
2252
|
);
|
|
2211
|
-
program.command("assigned").description("Show all tasks assigned to me, grouped by status").option("--include-closed", "Include done/closed tasks").option("--json", "Force JSON output even in terminal").action(
|
|
2253
|
+
program.command("assigned").description("Show all tasks assigned to me, grouped by status").option("--status <status>", "Show only tasks with this status").option("--include-closed", "Include done/closed tasks").option("--json", "Force JSON output even in terminal").action(
|
|
2212
2254
|
wrapAction(async (opts) => {
|
|
2213
2255
|
const config = loadConfig();
|
|
2214
2256
|
await runAssignedCommand(config, opts);
|
|
@@ -2220,20 +2262,24 @@ program.command("open <query>").description("Open a task in the browser by ID or
|
|
|
2220
2262
|
await openTask(config, query, opts);
|
|
2221
2263
|
})
|
|
2222
2264
|
);
|
|
2223
|
-
program.command("search <query>").description("Search my tasks by name").option("--status <status>", "Filter by status").option("--json", "Force JSON output even in terminal").action(
|
|
2224
|
-
wrapAction(
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2265
|
+
program.command("search <query>").description("Search my tasks by name").option("--status <status>", "Filter by status").option("--include-closed", "Include done/closed tasks in search").option("--json", "Force JSON output even in terminal").action(
|
|
2266
|
+
wrapAction(
|
|
2267
|
+
async (query, opts) => {
|
|
2268
|
+
const config = loadConfig();
|
|
2269
|
+
const tasks = await searchTasks(config, query, {
|
|
2270
|
+
status: opts.status,
|
|
2271
|
+
includeClosed: opts.includeClosed
|
|
2272
|
+
});
|
|
2273
|
+
await printTasks(tasks, opts.json ?? false, config);
|
|
2274
|
+
}
|
|
2275
|
+
)
|
|
2229
2276
|
);
|
|
2230
2277
|
program.command("summary").description("Daily standup summary: completed, in-progress, overdue").option("--hours <n>", "Completed-tasks lookback in hours", "24").option("--json", "Force JSON output even in terminal").action(
|
|
2231
2278
|
wrapAction(async (opts) => {
|
|
2232
2279
|
const config = loadConfig();
|
|
2233
2280
|
const hours = Number(opts.hours ?? 24);
|
|
2234
2281
|
if (!Number.isFinite(hours) || hours <= 0) {
|
|
2235
|
-
|
|
2236
|
-
process.exit(1);
|
|
2282
|
+
throw new Error("--hours must be a positive number");
|
|
2237
2283
|
}
|
|
2238
2284
|
await runSummaryCommand(config, { hours, json: opts.json ?? false });
|
|
2239
2285
|
})
|
package/package.json
CHANGED
|
@@ -34,25 +34,25 @@ All commands support `--help` for full flag details.
|
|
|
34
34
|
|
|
35
35
|
### Read
|
|
36
36
|
|
|
37
|
-
| Command
|
|
38
|
-
|
|
|
39
|
-
| `cu tasks [--status s] [--name q] [--list id] [--space id] [--json]` | My tasks (workspace-wide) |
|
|
40
|
-
| `cu initiatives [--status s] [--name q] [--list id] [--space id] [--json]` | My initiatives |
|
|
41
|
-
| `cu assigned [--include-closed] [--json]`
|
|
42
|
-
| `cu sprint [--status s] [--space nameOrId] [--json]` | Tasks in active sprint (auto-detected) |
|
|
43
|
-
| `cu sprints [--space nameOrId] [--json]`
|
|
44
|
-
| `cu search <query> [--status s] [--json]` | Search my tasks by name (multi-word, fuzzy status) |
|
|
45
|
-
| `cu task <id> [--json]`
|
|
46
|
-
| `cu subtasks <id> [--include-closed] [--json]`
|
|
47
|
-
| `cu comments <id> [--json]`
|
|
48
|
-
| `cu activity <id> [--json]`
|
|
49
|
-
| `cu inbox [--days n] [--json]`
|
|
50
|
-
| `cu summary [--hours n] [--json]`
|
|
51
|
-
| `cu overdue [--json]`
|
|
52
|
-
| `cu spaces [--name partial] [--my] [--json]`
|
|
53
|
-
| `cu lists <spaceId> [--name partial] [--json]`
|
|
54
|
-
| `cu open <query> [--json]`
|
|
55
|
-
| `cu auth [--json]`
|
|
37
|
+
| Command | What it returns |
|
|
38
|
+
| --------------------------------------------------------------------------------------------- | -------------------------------------------------- |
|
|
39
|
+
| `cu tasks [--status s] [--name q] [--list id] [--space id] [--include-closed] [--json]` | My tasks (workspace-wide) |
|
|
40
|
+
| `cu initiatives [--status s] [--name q] [--list id] [--space id] [--include-closed] [--json]` | My initiatives |
|
|
41
|
+
| `cu assigned [--status s] [--include-closed] [--json]` | All my tasks grouped by status |
|
|
42
|
+
| `cu sprint [--status s] [--space nameOrId] [--include-closed] [--json]` | Tasks in active sprint (auto-detected) |
|
|
43
|
+
| `cu sprints [--space nameOrId] [--json]` | List all sprints (marks active with \*) |
|
|
44
|
+
| `cu search <query> [--status s] [--include-closed] [--json]` | Search my tasks by name (multi-word, fuzzy status) |
|
|
45
|
+
| `cu task <id> [--json]` | Single task details |
|
|
46
|
+
| `cu subtasks <id> [--status s] [--name q] [--include-closed] [--json]` | Subtasks of a task or initiative |
|
|
47
|
+
| `cu comments <id> [--json]` | Comments on a task |
|
|
48
|
+
| `cu activity <id> [--json]` | Task details + comment history combined |
|
|
49
|
+
| `cu inbox [--days n] [--json]` | Tasks updated in last n days (default 30) |
|
|
50
|
+
| `cu summary [--hours n] [--json]` | Standup helper: completed, in-progress, overdue |
|
|
51
|
+
| `cu overdue [--json]` | Tasks past their due date |
|
|
52
|
+
| `cu spaces [--name partial] [--my] [--json]` | List/filter workspace spaces |
|
|
53
|
+
| `cu lists <spaceId> [--name partial] [--json]` | Lists in a space (including folder lists) |
|
|
54
|
+
| `cu open <query> [--json]` | Open task in browser by ID or name |
|
|
55
|
+
| `cu auth [--json]` | Check authentication status |
|
|
56
56
|
|
|
57
57
|
### Write
|
|
58
58
|
|
|
@@ -68,32 +68,32 @@ All commands support `--help` for full flag details.
|
|
|
68
68
|
|
|
69
69
|
## Quick Reference
|
|
70
70
|
|
|
71
|
-
| Topic | Detail
|
|
72
|
-
| ------------------- |
|
|
73
|
-
| Task IDs | Stable alphanumeric strings (e.g. `abc123def`)
|
|
74
|
-
| Initiatives | Detected via `custom_item_id !== 0`
|
|
75
|
-
| `--list` on create | Optional when `--parent` is given (auto-detected)
|
|
76
|
-
| `--status` | Fuzzy matching: exact > starts-with > contains. Prints match to stderr.
|
|
77
|
-
| `--priority` | Names (`urgent`, `high`, `normal`, `low`) or numbers (1-4)
|
|
78
|
-
| `--due-date` | `YYYY-MM-DD` format
|
|
79
|
-
| `--assignee` | Numeric user ID (find via `cu task <id> --json`)
|
|
80
|
-
| `--tags` | Comma-separated (e.g. `--tags "bug,frontend"`)
|
|
81
|
-
| `--time-estimate` | Duration format: `"2h"`, `"30m"`, `"1h30m"`, or raw milliseconds
|
|
82
|
-
| `--custom-item-id` | Custom task type ID (e.g. `1` for initiative)
|
|
83
|
-
| `--on` / `--blocks` | Task dependency direction (used with `cu depend`)
|
|
84
|
-
| `--space` | Partial name match or exact ID
|
|
85
|
-
| `--name` | Partial match, case-insensitive
|
|
86
|
-
| `--include-closed` | Include closed/done tasks (on `
|
|
87
|
-
| `cu assign --to me` | Shorthand for your own user ID
|
|
88
|
-
| `cu search` | Matches all query words against task name, case-insensitive
|
|
89
|
-
| `cu sprint` | Auto-detects active sprint via view API and date range parsing
|
|
90
|
-
| `cu summary` | Categories: completed (done/complete/closed within N hours), in progress, overdue
|
|
91
|
-
| `cu overdue` | Excludes closed tasks, sorted most overdue first
|
|
92
|
-
| `cu open` | Tries task ID first, falls back to name search
|
|
93
|
-
| `cu task` | Shows custom fields in detail view
|
|
94
|
-
| `cu lists` | Discovers list IDs needed for `--list` and `cu create -l`
|
|
95
|
-
| Errors | stderr with exit code 1
|
|
96
|
-
| Parsing | Strict - excess/unknown arguments rejected
|
|
71
|
+
| Topic | Detail |
|
|
72
|
+
| ------------------- | ------------------------------------------------------------------------------------------------- |
|
|
73
|
+
| Task IDs | Stable alphanumeric strings (e.g. `abc123def`) |
|
|
74
|
+
| Initiatives | Detected via `custom_item_id !== 0` |
|
|
75
|
+
| `--list` on create | Optional when `--parent` is given (auto-detected) |
|
|
76
|
+
| `--status` | Fuzzy matching: exact > starts-with > contains. Prints match to stderr. |
|
|
77
|
+
| `--priority` | Names (`urgent`, `high`, `normal`, `low`) or numbers (1-4) |
|
|
78
|
+
| `--due-date` | `YYYY-MM-DD` format |
|
|
79
|
+
| `--assignee` | Numeric user ID (find via `cu task <id> --json`) |
|
|
80
|
+
| `--tags` | Comma-separated (e.g. `--tags "bug,frontend"`) |
|
|
81
|
+
| `--time-estimate` | Duration format: `"2h"`, `"30m"`, `"1h30m"`, or raw milliseconds |
|
|
82
|
+
| `--custom-item-id` | Custom task type ID (e.g. `1` for initiative) |
|
|
83
|
+
| `--on` / `--blocks` | Task dependency direction (used with `cu depend`) |
|
|
84
|
+
| `--space` | Partial name match or exact ID |
|
|
85
|
+
| `--name` | Partial match, case-insensitive |
|
|
86
|
+
| `--include-closed` | Include closed/done tasks (on `tasks`, `initiatives`, `assigned`, `subtasks`, `sprint`, `search`) |
|
|
87
|
+
| `cu assign --to me` | Shorthand for your own user ID |
|
|
88
|
+
| `cu search` | Matches all query words against task name, case-insensitive |
|
|
89
|
+
| `cu sprint` | Auto-detects active sprint via view API and date range parsing |
|
|
90
|
+
| `cu summary` | Categories: completed (done/complete/closed within N hours), in progress, overdue |
|
|
91
|
+
| `cu overdue` | Excludes closed tasks, sorted most overdue first |
|
|
92
|
+
| `cu open` | Tries task ID first, falls back to name search |
|
|
93
|
+
| `cu task` | Shows custom fields in detail view |
|
|
94
|
+
| `cu lists` | Discovers list IDs needed for `--list` and `cu create -l` |
|
|
95
|
+
| Errors | stderr with exit code 1 |
|
|
96
|
+
| Parsing | Strict - excess/unknown arguments rejected |
|
|
97
97
|
|
|
98
98
|
## Agent Workflow Examples
|
|
99
99
|
|