@hasna/todos 0.9.55 → 0.9.56
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 +80 -2
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -13262,7 +13262,7 @@ program2.command("add <title>").description("Create a new task").option("-d, --d
|
|
|
13262
13262
|
console.log(formatTaskLine(task));
|
|
13263
13263
|
}
|
|
13264
13264
|
});
|
|
13265
|
-
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) => {
|
|
13265
|
+
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").option("--due-today", "Only tasks due today or earlier").option("--overdue", "Only overdue tasks (past due_at)").option("--recurring", "Only recurring tasks").option("--limit <n>", "Max tasks to return").action((opts) => {
|
|
13266
13266
|
const globalOpts = program2.opts();
|
|
13267
13267
|
opts.tags = opts.tags || opts.tag;
|
|
13268
13268
|
opts.list = opts.list || opts.taskList;
|
|
@@ -13303,7 +13303,20 @@ program2.command("list").description("List tasks").option("-s, --status <status>
|
|
|
13303
13303
|
if (opts.agentName) {
|
|
13304
13304
|
filter["assigned_to"] = opts.agentName;
|
|
13305
13305
|
}
|
|
13306
|
-
|
|
13306
|
+
if (opts.recurring)
|
|
13307
|
+
filter["has_recurrence"] = true;
|
|
13308
|
+
if (opts.limit)
|
|
13309
|
+
filter["limit"] = parseInt(opts.limit, 10);
|
|
13310
|
+
let tasks = listTasks(filter);
|
|
13311
|
+
if (opts.dueToday) {
|
|
13312
|
+
const todayEnd = new Date;
|
|
13313
|
+
todayEnd.setHours(23, 59, 59, 999);
|
|
13314
|
+
tasks = tasks.filter((t) => t.due_at && t.due_at <= todayEnd.toISOString());
|
|
13315
|
+
}
|
|
13316
|
+
if (opts.overdue) {
|
|
13317
|
+
const now2 = new Date().toISOString();
|
|
13318
|
+
tasks = tasks.filter((t) => t.due_at && t.due_at < now2 && t.status !== "completed");
|
|
13319
|
+
}
|
|
13307
13320
|
if (opts.sort) {
|
|
13308
13321
|
const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
13309
13322
|
tasks.sort((a, b) => {
|
|
@@ -14908,6 +14921,71 @@ program2.command("summary").description("Generate a markdown summary of recent t
|
|
|
14908
14921
|
console.log(lines.join(`
|
|
14909
14922
|
`));
|
|
14910
14923
|
});
|
|
14924
|
+
program2.command("report").description("Analytics report: task activity, completion rates, agent breakdown").option("--days <n>", "Days to include in report", "7").option("--project <id>", "Filter to project").option("--markdown", "Output as markdown").option("--json", "Output as JSON").action(async (opts) => {
|
|
14925
|
+
const globalOpts = program2.opts();
|
|
14926
|
+
const db = getDatabase();
|
|
14927
|
+
const days = parseInt(opts.days, 10);
|
|
14928
|
+
const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
14929
|
+
const projectId = opts.project || autoProject(globalOpts);
|
|
14930
|
+
const filter = {};
|
|
14931
|
+
if (projectId)
|
|
14932
|
+
filter.project_id = projectId;
|
|
14933
|
+
const { getTasksChangedSince: getTasksChangedSince2, getTaskStats: getTaskStats2 } = (init_tasks(), __toCommonJS(exports_tasks));
|
|
14934
|
+
const changed = getTasksChangedSince2(since, Object.keys(filter).length ? filter : undefined, db);
|
|
14935
|
+
const completed = changed.filter((t) => t.status === "completed");
|
|
14936
|
+
const failed = changed.filter((t) => t.status === "failed");
|
|
14937
|
+
const all = listTasks(filter);
|
|
14938
|
+
const stats = getTaskStats2(Object.keys(filter).length ? filter : undefined, db);
|
|
14939
|
+
const byDay = {};
|
|
14940
|
+
for (const t of changed) {
|
|
14941
|
+
const day = t.updated_at.slice(0, 10);
|
|
14942
|
+
byDay[day] = (byDay[day] || 0) + 1;
|
|
14943
|
+
}
|
|
14944
|
+
const dayValues = Object.values(byDay);
|
|
14945
|
+
const maxDay = Math.max(...dayValues, 1);
|
|
14946
|
+
const sparkline = dayValues.map((v) => "\u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588"[Math.min(7, Math.floor(v / maxDay * 7))] || "\u2581").join("");
|
|
14947
|
+
const byAgent = {};
|
|
14948
|
+
for (const t of completed) {
|
|
14949
|
+
const agent = t.assigned_to || "unassigned";
|
|
14950
|
+
byAgent[agent] = (byAgent[agent] || 0) + 1;
|
|
14951
|
+
}
|
|
14952
|
+
const completionRate = changed.length > 0 ? Math.round(completed.length / changed.length * 100) : 0;
|
|
14953
|
+
if (opts.json || globalOpts.json) {
|
|
14954
|
+
console.log(JSON.stringify({ days, period_since: since, changed: changed.length, completed: completed.length, failed: failed.length, completion_rate: completionRate, total: all.length, stats, by_agent: byAgent, by_day: byDay }, null, 2));
|
|
14955
|
+
return;
|
|
14956
|
+
}
|
|
14957
|
+
const lines = [];
|
|
14958
|
+
if (opts.markdown) {
|
|
14959
|
+
lines.push(`## Todos Report \u2014 last ${days} days`);
|
|
14960
|
+
lines.push(`*${new Date().toLocaleDateString()}*
|
|
14961
|
+
`);
|
|
14962
|
+
lines.push(`| Metric | Value |`);
|
|
14963
|
+
lines.push(`|--------|-------|`);
|
|
14964
|
+
lines.push(`| Active tasks | ${all.length} total (${stats.pending} pending, ${stats.in_progress} active) |`);
|
|
14965
|
+
lines.push(`| Changed (${days}d) | ${changed.length} tasks |`);
|
|
14966
|
+
lines.push(`| Completed (${days}d) | ${completed.length} (${completionRate}% rate) |`);
|
|
14967
|
+
lines.push(`| Failed (${days}d) | ${failed.length} |`);
|
|
14968
|
+
if (sparkline)
|
|
14969
|
+
lines.push(`| Activity | \`${sparkline}\` |`);
|
|
14970
|
+
} else {
|
|
14971
|
+
lines.push(chalk.bold(`todos report \u2014 last ${days} day${days !== 1 ? "s" : ""}`));
|
|
14972
|
+
lines.push("");
|
|
14973
|
+
lines.push(` Total: ${chalk.bold(String(all.length))} tasks (${chalk.yellow(String(stats.pending))} pending, ${chalk.blue(String(stats.in_progress))} active)`);
|
|
14974
|
+
lines.push(` Changed: ${chalk.bold(String(changed.length))} in period`);
|
|
14975
|
+
lines.push(` Completed: ${chalk.green(String(completed.length))} (${completionRate}% rate)`);
|
|
14976
|
+
if (failed.length > 0)
|
|
14977
|
+
lines.push(` Failed: ${chalk.red(String(failed.length))}`);
|
|
14978
|
+
if (sparkline)
|
|
14979
|
+
lines.push(` Activity: ${chalk.dim(sparkline)}`);
|
|
14980
|
+
if (Object.keys(byAgent).length > 0) {
|
|
14981
|
+
lines.push(` By agent: ${Object.entries(byAgent).map(([a, n]) => `${a}=${n}`).join(" ")}`);
|
|
14982
|
+
}
|
|
14983
|
+
if (stats.in_progress > 0)
|
|
14984
|
+
lines.push(` Stale risk: check \`todos stale\` for stuck tasks`);
|
|
14985
|
+
}
|
|
14986
|
+
console.log(lines.join(`
|
|
14987
|
+
`));
|
|
14988
|
+
});
|
|
14911
14989
|
program2.action(async () => {
|
|
14912
14990
|
if (process.stdout.isTTY) {
|
|
14913
14991
|
try {
|