@hasna/todos 0.9.26 → 0.9.27
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/dist/cli/index.js +144 -36
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -8305,6 +8305,12 @@ function resolveTaskListId(agent, explicit) {
|
|
|
8305
8305
|
return process.env[key] || process.env["TODOS_TASK_LIST_ID"] || getAgentTaskListId(normalized) || "default";
|
|
8306
8306
|
}
|
|
8307
8307
|
function formatTask(task) {
|
|
8308
|
+
const id = task.short_id || task.id.slice(0, 8);
|
|
8309
|
+
const assigned = task.assigned_to ? ` -> ${task.assigned_to}` : "";
|
|
8310
|
+
const lock = task.locked_by ? ` [locked:${task.locked_by}]` : "";
|
|
8311
|
+
return `${id} ${task.status.padEnd(11)} ${task.priority.padEnd(8)} ${task.title}${assigned}${lock}`;
|
|
8312
|
+
}
|
|
8313
|
+
function formatTaskDetail(task) {
|
|
8308
8314
|
const parts = [
|
|
8309
8315
|
`ID: ${task.id}`,
|
|
8310
8316
|
`Title: ${task.title}`,
|
|
@@ -8385,8 +8391,7 @@ var init_mcp = __esm(() => {
|
|
|
8385
8391
|
if (resolved.task_list_id)
|
|
8386
8392
|
resolved.task_list_id = resolveId(resolved.task_list_id, "task_lists");
|
|
8387
8393
|
const task = createTask(resolved);
|
|
8388
|
-
return { content: [{ type: "text", text: `
|
|
8389
|
-
${formatTask(task)}` }] };
|
|
8394
|
+
return { content: [{ type: "text", text: `created: ${formatTask(task)}` }] };
|
|
8390
8395
|
} catch (e) {
|
|
8391
8396
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
8392
8397
|
}
|
|
@@ -8430,7 +8435,7 @@ ${text}` }] };
|
|
|
8430
8435
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
8431
8436
|
}
|
|
8432
8437
|
});
|
|
8433
|
-
server.tool("get_task", "Get full task details
|
|
8438
|
+
server.tool("get_task", "Get full task details with relations", {
|
|
8434
8439
|
id: exports_external.string().describe("Task ID (full or partial)")
|
|
8435
8440
|
}, async ({ id }) => {
|
|
8436
8441
|
try {
|
|
@@ -8438,7 +8443,7 @@ ${text}` }] };
|
|
|
8438
8443
|
const task = getTaskWithRelations(resolvedId);
|
|
8439
8444
|
if (!task)
|
|
8440
8445
|
return { content: [{ type: "text", text: `Task not found: ${id}` }], isError: true };
|
|
8441
|
-
const parts = [
|
|
8446
|
+
const parts = [formatTaskDetail(task)];
|
|
8442
8447
|
if (task.subtasks.length > 0) {
|
|
8443
8448
|
parts.push(`
|
|
8444
8449
|
Subtasks (${task.subtasks.length}):`);
|
|
@@ -8478,7 +8483,7 @@ Parent: ${task.parent.id.slice(0, 8)} | ${task.parent.title}`);
|
|
|
8478
8483
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
8479
8484
|
}
|
|
8480
8485
|
});
|
|
8481
|
-
server.tool("update_task", "Update task fields
|
|
8486
|
+
server.tool("update_task", "Update task fields. Version required for optimistic locking.", {
|
|
8482
8487
|
id: exports_external.string().describe("Task ID (full or partial)"),
|
|
8483
8488
|
version: exports_external.number().describe("Current version (for optimistic locking)"),
|
|
8484
8489
|
title: exports_external.string().optional().describe("New title"),
|
|
@@ -8494,8 +8499,7 @@ Parent: ${task.parent.id.slice(0, 8)} | ${task.parent.title}`);
|
|
|
8494
8499
|
try {
|
|
8495
8500
|
const resolvedId = resolveId(id);
|
|
8496
8501
|
const task = updateTask(resolvedId, rest);
|
|
8497
|
-
return { content: [{ type: "text", text: `
|
|
8498
|
-
${formatTask(task)}` }] };
|
|
8502
|
+
return { content: [{ type: "text", text: `updated: ${formatTask(task)}` }] };
|
|
8499
8503
|
} catch (e) {
|
|
8500
8504
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
8501
8505
|
}
|
|
@@ -8516,28 +8520,26 @@ ${formatTask(task)}` }] };
|
|
|
8516
8520
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
8517
8521
|
}
|
|
8518
8522
|
});
|
|
8519
|
-
server.tool("start_task", "Claim
|
|
8523
|
+
server.tool("start_task", "Claim, lock, and set task status to in_progress.", {
|
|
8520
8524
|
id: exports_external.string().describe("Task ID (full or partial)"),
|
|
8521
8525
|
agent_id: exports_external.string().describe("Agent claiming the task")
|
|
8522
8526
|
}, async ({ id, agent_id }) => {
|
|
8523
8527
|
try {
|
|
8524
8528
|
const resolvedId = resolveId(id);
|
|
8525
8529
|
const task = startTask(resolvedId, agent_id);
|
|
8526
|
-
return { content: [{ type: "text", text: `
|
|
8527
|
-
${formatTask(task)}` }] };
|
|
8530
|
+
return { content: [{ type: "text", text: `started: ${formatTask(task)}` }] };
|
|
8528
8531
|
} catch (e) {
|
|
8529
8532
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
8530
8533
|
}
|
|
8531
8534
|
});
|
|
8532
|
-
server.tool("complete_task", "Mark
|
|
8535
|
+
server.tool("complete_task", "Mark task completed and release lock.", {
|
|
8533
8536
|
id: exports_external.string().describe("Task ID (full or partial)"),
|
|
8534
8537
|
agent_id: exports_external.string().optional().describe("Agent completing the task")
|
|
8535
8538
|
}, async ({ id, agent_id }) => {
|
|
8536
8539
|
try {
|
|
8537
8540
|
const resolvedId = resolveId(id);
|
|
8538
8541
|
const task = completeTask(resolvedId, agent_id);
|
|
8539
|
-
return { content: [{ type: "text", text: `
|
|
8540
|
-
${formatTask(task)}` }] };
|
|
8542
|
+
return { content: [{ type: "text", text: `completed: ${formatTask(task)}` }] };
|
|
8541
8543
|
} catch (e) {
|
|
8542
8544
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
8543
8545
|
}
|
|
@@ -8569,7 +8571,7 @@ ${formatTask(task)}` }] };
|
|
|
8569
8571
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
8570
8572
|
}
|
|
8571
8573
|
});
|
|
8572
|
-
server.tool("add_dependency", "Add a dependency
|
|
8574
|
+
server.tool("add_dependency", "Add a dependency: task_id depends on depends_on.", {
|
|
8573
8575
|
task_id: exports_external.string().describe("Task that depends on another"),
|
|
8574
8576
|
depends_on: exports_external.string().describe("Task that must complete first")
|
|
8575
8577
|
}, async ({ task_id, depends_on }) => {
|
|
@@ -8760,7 +8762,7 @@ ${text}` }] };
|
|
|
8760
8762
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
8761
8763
|
}
|
|
8762
8764
|
});
|
|
8763
|
-
server.tool("search_tasks", "Full-text search across task titles, descriptions,
|
|
8765
|
+
server.tool("search_tasks", "Full-text search across task titles, descriptions, tags.", {
|
|
8764
8766
|
query: exports_external.string().describe("Search query"),
|
|
8765
8767
|
project_id: exports_external.string().optional().describe("Limit to project"),
|
|
8766
8768
|
task_list_id: exports_external.string().optional().describe("Filter by task list")
|
|
@@ -8780,7 +8782,7 @@ ${text}` }] };
|
|
|
8780
8782
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
8781
8783
|
}
|
|
8782
8784
|
});
|
|
8783
|
-
server.tool("sync", "Sync tasks with an agent task list
|
|
8785
|
+
server.tool("sync", "Sync tasks with an agent task list.", {
|
|
8784
8786
|
task_list_id: exports_external.string().optional().describe("Task list ID (required for Claude)"),
|
|
8785
8787
|
agent: exports_external.string().optional().describe("Agent/provider name (default: claude)"),
|
|
8786
8788
|
all_agents: exports_external.boolean().optional().describe("Sync across all configured agents"),
|
|
@@ -8828,7 +8830,7 @@ ${text}` }] };
|
|
|
8828
8830
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
8829
8831
|
}
|
|
8830
8832
|
});
|
|
8831
|
-
server.tool("register_agent", "Register an agent
|
|
8833
|
+
server.tool("register_agent", "Register an agent (idempotent by name).", {
|
|
8832
8834
|
name: exports_external.string().describe("Agent name"),
|
|
8833
8835
|
description: exports_external.string().optional().describe("Agent description")
|
|
8834
8836
|
}, async ({ name, description }) => {
|
|
@@ -8988,7 +8990,7 @@ Slug: ${list.slug}`
|
|
|
8988
8990
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
8989
8991
|
}
|
|
8990
8992
|
});
|
|
8991
|
-
server.tool("delete_task_list", "Delete a task list. Tasks
|
|
8993
|
+
server.tool("delete_task_list", "Delete a task list. Tasks lose association but keep data.", {
|
|
8992
8994
|
id: exports_external.string().describe("Task list ID (full or partial)")
|
|
8993
8995
|
}, async ({ id }) => {
|
|
8994
8996
|
try {
|
|
@@ -9004,7 +9006,7 @@ Slug: ${list.slug}`
|
|
|
9004
9006
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
9005
9007
|
}
|
|
9006
9008
|
});
|
|
9007
|
-
server.tool("get_task_history", "Get
|
|
9009
|
+
server.tool("get_task_history", "Get audit log for a task.", {
|
|
9008
9010
|
task_id: exports_external.string().describe("Task ID (full or partial)")
|
|
9009
9011
|
}, async ({ task_id }) => {
|
|
9010
9012
|
try {
|
|
@@ -9021,7 +9023,7 @@ ${text}` }] };
|
|
|
9021
9023
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
9022
9024
|
}
|
|
9023
9025
|
});
|
|
9024
|
-
server.tool("get_recent_activity", "Get recent task changes across all tasks
|
|
9026
|
+
server.tool("get_recent_activity", "Get recent task changes across all tasks.", {
|
|
9025
9027
|
limit: exports_external.number().optional().describe("Max entries (default 50)")
|
|
9026
9028
|
}, async ({ limit }) => {
|
|
9027
9029
|
try {
|
|
@@ -9037,7 +9039,7 @@ ${text}` }] };
|
|
|
9037
9039
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
9038
9040
|
}
|
|
9039
9041
|
});
|
|
9040
|
-
server.tool("create_webhook", "Register a webhook
|
|
9042
|
+
server.tool("create_webhook", "Register a webhook to receive task change events.", {
|
|
9041
9043
|
url: exports_external.string().describe("Webhook URL"),
|
|
9042
9044
|
events: exports_external.array(exports_external.string()).optional().describe("Event types to subscribe to (empty = all)"),
|
|
9043
9045
|
secret: exports_external.string().optional().describe("HMAC secret for signature verification")
|
|
@@ -9075,7 +9077,7 @@ ${text}` }] };
|
|
|
9075
9077
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
9076
9078
|
}
|
|
9077
9079
|
});
|
|
9078
|
-
server.tool("create_template", "Create a reusable task template", {
|
|
9080
|
+
server.tool("create_template", "Create a reusable task template.", {
|
|
9079
9081
|
name: exports_external.string().describe("Template name"),
|
|
9080
9082
|
title_pattern: exports_external.string().describe("Title pattern for tasks created from this template"),
|
|
9081
9083
|
description: exports_external.string().optional().describe("Default description"),
|
|
@@ -9106,7 +9108,7 @@ ${text}` }] };
|
|
|
9106
9108
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
9107
9109
|
}
|
|
9108
9110
|
});
|
|
9109
|
-
server.tool("create_task_from_template", "Create a task from a template with optional overrides", {
|
|
9111
|
+
server.tool("create_task_from_template", "Create a task from a template with optional overrides.", {
|
|
9110
9112
|
template_id: exports_external.string().describe("Template ID"),
|
|
9111
9113
|
title: exports_external.string().optional().describe("Override title"),
|
|
9112
9114
|
description: exports_external.string().optional().describe("Override description"),
|
|
@@ -9139,7 +9141,7 @@ ${task.id.slice(0, 8)} | ${task.priority} | ${task.title}` }] };
|
|
|
9139
9141
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
9140
9142
|
}
|
|
9141
9143
|
});
|
|
9142
|
-
server.tool("approve_task", "Approve a task that requires approval
|
|
9144
|
+
server.tool("approve_task", "Approve a task that requires approval.", {
|
|
9143
9145
|
id: exports_external.string().describe("Task ID (full or partial)"),
|
|
9144
9146
|
agent_id: exports_external.string().optional().describe("Agent approving the task")
|
|
9145
9147
|
}, async ({ id, agent_id }) => {
|
|
@@ -9158,7 +9160,7 @@ ${task.id.slice(0, 8)} | ${task.priority} | ${task.title}` }] };
|
|
|
9158
9160
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
9159
9161
|
}
|
|
9160
9162
|
});
|
|
9161
|
-
server.tool("get_my_tasks", "Get
|
|
9163
|
+
server.tool("get_my_tasks", "Get assigned tasks and stats for an agent.", {
|
|
9162
9164
|
agent_name: exports_external.string().describe("Your agent name")
|
|
9163
9165
|
}, async ({ agent_name }) => {
|
|
9164
9166
|
try {
|
|
@@ -9191,6 +9193,79 @@ In Progress:`);
|
|
|
9191
9193
|
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
9192
9194
|
}
|
|
9193
9195
|
});
|
|
9196
|
+
server.tool("search_tools", "List tool names matching a query.", { query: exports_external.string().optional().describe("Keyword to filter tools") }, async ({ query }) => {
|
|
9197
|
+
const all = [
|
|
9198
|
+
"create_task",
|
|
9199
|
+
"list_tasks",
|
|
9200
|
+
"get_task",
|
|
9201
|
+
"update_task",
|
|
9202
|
+
"delete_task",
|
|
9203
|
+
"start_task",
|
|
9204
|
+
"complete_task",
|
|
9205
|
+
"lock_task",
|
|
9206
|
+
"unlock_task",
|
|
9207
|
+
"approve_task",
|
|
9208
|
+
"add_dependency",
|
|
9209
|
+
"remove_dependency",
|
|
9210
|
+
"add_comment",
|
|
9211
|
+
"create_project",
|
|
9212
|
+
"list_projects",
|
|
9213
|
+
"create_plan",
|
|
9214
|
+
"list_plans",
|
|
9215
|
+
"get_plan",
|
|
9216
|
+
"update_plan",
|
|
9217
|
+
"delete_plan",
|
|
9218
|
+
"register_agent",
|
|
9219
|
+
"list_agents",
|
|
9220
|
+
"get_agent",
|
|
9221
|
+
"get_my_tasks",
|
|
9222
|
+
"create_task_list",
|
|
9223
|
+
"list_task_lists",
|
|
9224
|
+
"get_task_list",
|
|
9225
|
+
"update_task_list",
|
|
9226
|
+
"delete_task_list",
|
|
9227
|
+
"search_tasks",
|
|
9228
|
+
"sync",
|
|
9229
|
+
"get_task_history",
|
|
9230
|
+
"get_recent_activity",
|
|
9231
|
+
"create_webhook",
|
|
9232
|
+
"list_webhooks",
|
|
9233
|
+
"delete_webhook",
|
|
9234
|
+
"create_template",
|
|
9235
|
+
"list_templates",
|
|
9236
|
+
"create_task_from_template",
|
|
9237
|
+
"delete_template",
|
|
9238
|
+
"search_tools",
|
|
9239
|
+
"describe_tools"
|
|
9240
|
+
];
|
|
9241
|
+
const q = query?.toLowerCase();
|
|
9242
|
+
const matches = q ? all.filter((n) => n.includes(q)) : all;
|
|
9243
|
+
return { content: [{ type: "text", text: matches.join(", ") }] };
|
|
9244
|
+
});
|
|
9245
|
+
server.tool("describe_tools", "Get descriptions for specific tools by name.", { names: exports_external.array(exports_external.string()).describe("Tool names from search_tools") }, async ({ names }) => {
|
|
9246
|
+
const descriptions = {
|
|
9247
|
+
create_task: "Create a task. Params: title(req), description, priority, project_id, plan_id, tags, assigned_to, estimated_minutes, requires_approval",
|
|
9248
|
+
list_tasks: "List tasks. Params: status, priority, project_id, plan_id, assigned_to, tags, limit",
|
|
9249
|
+
get_task: "Get full task details. Params: id",
|
|
9250
|
+
update_task: "Update task fields. Params: id, version(req), title, description, status, priority, tags, assigned_to, due_at",
|
|
9251
|
+
delete_task: "Delete a task. Params: id",
|
|
9252
|
+
start_task: "Claim, lock, and start a task. Params: id",
|
|
9253
|
+
complete_task: "Mark task completed. Params: id, agent_id",
|
|
9254
|
+
approve_task: "Approve task requiring approval. Params: id, agent_id",
|
|
9255
|
+
create_plan: "Create a plan. Params: name, description, project_id, task_list_id, agent_id, status",
|
|
9256
|
+
list_plans: "List plans. Params: project_id",
|
|
9257
|
+
get_plan: "Get plan with tasks. Params: id",
|
|
9258
|
+
search_tasks: "Full-text search tasks. Params: query, project_id, task_list_id",
|
|
9259
|
+
get_my_tasks: "Get your tasks and stats. Params: agent_name",
|
|
9260
|
+
get_task_history: "Get task audit log. Params: task_id",
|
|
9261
|
+
get_recent_activity: "Recent changes across all tasks. Params: limit",
|
|
9262
|
+
create_template: "Create task template. Params: name, title_pattern, description, priority, tags",
|
|
9263
|
+
create_task_from_template: "Create task from template. Params: template_id, title, priority, assigned_to"
|
|
9264
|
+
};
|
|
9265
|
+
const result = names.map((n) => `${n}: ${descriptions[n] || "See tool schema"}`).join(`
|
|
9266
|
+
`);
|
|
9267
|
+
return { content: [{ type: "text", text: result }] };
|
|
9268
|
+
});
|
|
9194
9269
|
server.resource("tasks", "todos://tasks", { description: "All active tasks", mimeType: "application/json" }, async () => {
|
|
9195
9270
|
const tasks = listTasks({ status: ["pending", "in_progress"] });
|
|
9196
9271
|
return { contents: [{ uri: "todos://tasks", text: JSON.stringify(tasks, null, 2), mimeType: "application/json" }] };
|
|
@@ -9259,8 +9334,8 @@ function serveStaticFile(filePath) {
|
|
|
9259
9334
|
headers: { "Content-Type": contentType }
|
|
9260
9335
|
});
|
|
9261
9336
|
}
|
|
9262
|
-
function taskToSummary(task) {
|
|
9263
|
-
|
|
9337
|
+
function taskToSummary(task, fields) {
|
|
9338
|
+
const full = {
|
|
9264
9339
|
id: task.id,
|
|
9265
9340
|
short_id: task.short_id,
|
|
9266
9341
|
title: task.title,
|
|
@@ -9280,6 +9355,9 @@ function taskToSummary(task) {
|
|
|
9280
9355
|
completed_at: task.completed_at,
|
|
9281
9356
|
due_at: task.due_at
|
|
9282
9357
|
};
|
|
9358
|
+
if (!fields || fields.length === 0)
|
|
9359
|
+
return full;
|
|
9360
|
+
return Object.fromEntries(fields.map((f) => [f, full[f] ?? null]));
|
|
9283
9361
|
}
|
|
9284
9362
|
async function startServer(port, options) {
|
|
9285
9363
|
const shouldOpen = options?.open ?? true;
|
|
@@ -9362,12 +9440,14 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
9362
9440
|
const status = url.searchParams.get("status") || undefined;
|
|
9363
9441
|
const projectId = url.searchParams.get("project_id") || undefined;
|
|
9364
9442
|
const limitParam = url.searchParams.get("limit");
|
|
9443
|
+
const fieldsParam = url.searchParams.get("fields");
|
|
9444
|
+
const fields = fieldsParam ? fieldsParam.split(",").map((f) => f.trim()).filter(Boolean) : undefined;
|
|
9365
9445
|
const tasks = listTasks({
|
|
9366
9446
|
status,
|
|
9367
9447
|
project_id: projectId,
|
|
9368
9448
|
limit: limitParam ? parseInt(limitParam, 10) : undefined
|
|
9369
9449
|
});
|
|
9370
|
-
return json(tasks.map(taskToSummary), 200, port);
|
|
9450
|
+
return json(tasks.map((t) => taskToSummary(t, fields)), 200, port);
|
|
9371
9451
|
}
|
|
9372
9452
|
if (path === "/api/tasks" && method === "POST") {
|
|
9373
9453
|
try {
|
|
@@ -9391,7 +9471,7 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
9391
9471
|
const status = url.searchParams.get("status") || undefined;
|
|
9392
9472
|
const projectId = url.searchParams.get("project_id") || undefined;
|
|
9393
9473
|
const tasks = listTasks({ status, project_id: projectId, limit: 1e4 });
|
|
9394
|
-
const summaries = tasks.map(taskToSummary);
|
|
9474
|
+
const summaries = tasks.map((t) => taskToSummary(t));
|
|
9395
9475
|
if (format === "csv") {
|
|
9396
9476
|
const headers = ["id", "short_id", "title", "status", "priority", "project_id", "assigned_to", "agent_id", "created_at", "updated_at", "completed_at", "due_at"];
|
|
9397
9477
|
const rows = summaries.map((t) => headers.map((h) => {
|
|
@@ -9517,8 +9597,8 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
9517
9597
|
const completed = allTasks.filter((t) => t.status === "completed");
|
|
9518
9598
|
return json({
|
|
9519
9599
|
agent,
|
|
9520
|
-
pending_tasks: pending.map(taskToSummary),
|
|
9521
|
-
in_progress_tasks: inProgress.map(taskToSummary),
|
|
9600
|
+
pending_tasks: pending.map((t) => taskToSummary(t)),
|
|
9601
|
+
in_progress_tasks: inProgress.map((t) => taskToSummary(t)),
|
|
9522
9602
|
stats: {
|
|
9523
9603
|
total: allTasks.length,
|
|
9524
9604
|
pending: pending.length,
|
|
@@ -9535,7 +9615,7 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
9535
9615
|
const queue = pending.filter((t) => t.assigned_to === agentId || t.agent_id === agentId || !t.assigned_to && !t.locked_by);
|
|
9536
9616
|
const order = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
9537
9617
|
queue.sort((a, b) => (order[a.priority] ?? 4) - (order[b.priority] ?? 4) || new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
9538
|
-
return json(queue.map(taskToSummary), 200, port);
|
|
9618
|
+
return json(queue.map((t) => taskToSummary(t)), 200, port);
|
|
9539
9619
|
}
|
|
9540
9620
|
if (path === "/api/tasks/claim" && method === "POST") {
|
|
9541
9621
|
try {
|
|
@@ -9751,7 +9831,7 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
9751
9831
|
if (!plan)
|
|
9752
9832
|
return json({ error: "Plan not found" }, 404, port);
|
|
9753
9833
|
const tasks = listTasks({ plan_id: id });
|
|
9754
|
-
return json({ ...plan, tasks: tasks.map(taskToSummary) }, 200, port);
|
|
9834
|
+
return json({ ...plan, tasks: tasks.map((t) => taskToSummary(t)) }, 200, port);
|
|
9755
9835
|
}
|
|
9756
9836
|
if (method === "PATCH") {
|
|
9757
9837
|
try {
|
|
@@ -11043,7 +11123,7 @@ program2.command("add <title>").description("Create a new task").option("-d, --d
|
|
|
11043
11123
|
console.log(formatTaskLine(task));
|
|
11044
11124
|
}
|
|
11045
11125
|
});
|
|
11046
|
-
program2.command("list").description("List tasks").option("-s, --status <status>", "Filter by status").option("-p, --priority <priority>", "Filter by priority").option("--assigned <agent>", "Filter by assigned agent").option("--tags <tags>", "Filter by tags (comma-separated)").option("--tag <tags>", "Filter by tags (alias for --tags)").option("-a, --all", "Show all tasks (including completed/cancelled)").option("--list <id>", "Filter by task list ID").option("--task-list <id>", "Filter by task list ID (alias for --list)").option("--project-name <name>", "Filter by project name").option("--agent-name <name>", "Filter by agent name/assigned").option("--sort <field>", "Sort by: updated, created, priority, status").action((opts) => {
|
|
11126
|
+
program2.command("list").description("List tasks").option("-s, --status <status>", "Filter by status").option("-p, --priority <priority>", "Filter by priority").option("--assigned <agent>", "Filter by assigned agent").option("--tags <tags>", "Filter by tags (comma-separated)").option("--tag <tags>", "Filter by tags (alias for --tags)").option("-a, --all", "Show all tasks (including completed/cancelled)").option("--list <id>", "Filter by task list ID").option("--task-list <id>", "Filter by task list ID (alias for --list)").option("--project-name <name>", "Filter by project name").option("--agent-name <name>", "Filter by agent name/assigned").option("--sort <field>", "Sort by: updated, created, priority, status").option("--format <fmt>", "Output format: table (default), compact, csv, json").action((opts) => {
|
|
11047
11127
|
const globalOpts = program2.opts();
|
|
11048
11128
|
opts.tags = opts.tags || opts.tag;
|
|
11049
11129
|
opts.list = opts.list || opts.taskList;
|
|
@@ -11099,12 +11179,40 @@ program2.command("list").description("List tasks").option("-s, --status <status>
|
|
|
11099
11179
|
return 0;
|
|
11100
11180
|
});
|
|
11101
11181
|
}
|
|
11102
|
-
|
|
11182
|
+
const fmt = opts.format || (globalOpts.json ? "json" : "table");
|
|
11183
|
+
if (fmt === "json") {
|
|
11103
11184
|
output(tasks, true);
|
|
11104
11185
|
return;
|
|
11105
11186
|
}
|
|
11106
11187
|
if (tasks.length === 0) {
|
|
11107
|
-
|
|
11188
|
+
if (fmt === "compact" || fmt === "csv")
|
|
11189
|
+
process.stdout.write("");
|
|
11190
|
+
else
|
|
11191
|
+
console.log(chalk.dim("No tasks found."));
|
|
11192
|
+
return;
|
|
11193
|
+
}
|
|
11194
|
+
if (fmt === "csv") {
|
|
11195
|
+
const headers = "id,short_id,title,status,priority,assigned_to,updated_at";
|
|
11196
|
+
const rows = tasks.map((t) => [
|
|
11197
|
+
t.id,
|
|
11198
|
+
t.short_id || "",
|
|
11199
|
+
t.title.replace(/,/g, ";"),
|
|
11200
|
+
t.status,
|
|
11201
|
+
t.priority,
|
|
11202
|
+
t.assigned_to || "",
|
|
11203
|
+
t.updated_at
|
|
11204
|
+
].join(","));
|
|
11205
|
+
console.log([headers, ...rows].join(`
|
|
11206
|
+
`));
|
|
11207
|
+
return;
|
|
11208
|
+
}
|
|
11209
|
+
if (fmt === "compact") {
|
|
11210
|
+
for (const t of tasks) {
|
|
11211
|
+
const id = t.short_id || t.id.slice(0, 8);
|
|
11212
|
+
const assigned = t.assigned_to ? ` ${t.assigned_to}` : "";
|
|
11213
|
+
process.stdout.write(`${id} ${t.status} ${t.priority} ${t.title}${assigned}
|
|
11214
|
+
`);
|
|
11215
|
+
}
|
|
11108
11216
|
return;
|
|
11109
11217
|
}
|
|
11110
11218
|
console.log(chalk.bold(`${tasks.length} task(s):
|