@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.
Files changed (2) hide show
  1. package/dist/cli/index.js +144 -36
  2. 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: `Task created:
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 including dependencies, subtasks, and comments", {
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 = [formatTask(task)];
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 (requires version for optimistic locking)", {
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: `Task updated:
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 a task, lock it, and set status to in_progress", {
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: `Task started:
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 a task as completed and release lock", {
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: `Task completed:
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 between tasks (task_id depends on depends_on)", {
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, and tags", {
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 (Claude uses native task list; others use JSON lists).", {
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 and get a short UUID. Idempotent: same name returns existing 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 in this list keep their data but lose their list association.", {
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 change history for a task (audit log)", {
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 (audit log)", {
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 URL to receive task change notifications", {
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 before completion", {
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 your assigned tasks and stats. Auto-registers if needed.", {
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
- return {
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
- if (globalOpts.json) {
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
- console.log(chalk.dim("No tasks found."));
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):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/todos",
3
- "version": "0.9.26",
3
+ "version": "0.9.27",
4
4
  "description": "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",