@hasna/todos 0.9.59 → 0.9.60

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 +63 -0
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -2881,6 +2881,15 @@ var init_sync_utils = __esm(() => {
2881
2881
  });
2882
2882
 
2883
2883
  // src/lib/config.ts
2884
+ var exports_config = {};
2885
+ __export(exports_config, {
2886
+ loadConfig: () => loadConfig,
2887
+ getTaskPrefixConfig: () => getTaskPrefixConfig,
2888
+ getSyncAgentsFromConfig: () => getSyncAgentsFromConfig,
2889
+ getCompletionGuardConfig: () => getCompletionGuardConfig,
2890
+ getAgentTasksDir: () => getAgentTasksDir,
2891
+ getAgentTaskListId: () => getAgentTaskListId
2892
+ });
2884
2893
  import { existsSync as existsSync3 } from "fs";
2885
2894
  import { join as join3 } from "path";
2886
2895
  function getConfigPath() {
@@ -14944,6 +14953,60 @@ program2.command("summary").description("Generate a markdown summary of recent t
14944
14953
  console.log(lines.join(`
14945
14954
  `));
14946
14955
  });
14956
+ program2.command("health").description("Check todos system health \u2014 database, config, connectivity").option("--json", "Output as JSON").action(async (opts) => {
14957
+ const globalOpts = program2.opts();
14958
+ const checks = [];
14959
+ try {
14960
+ const db = getDatabase();
14961
+ const row = db.query("SELECT COUNT(*) as count FROM tasks").get();
14962
+ const { statSync: statSync2 } = __require("fs");
14963
+ const dbPath = process.env["TODOS_DB_PATH"] || __require("path").join(process.env["HOME"] || "~", ".todos", "todos.db");
14964
+ let size = "unknown";
14965
+ try {
14966
+ size = `${(statSync2(dbPath).size / 1024 / 1024).toFixed(1)} MB`;
14967
+ } catch {}
14968
+ checks.push({ name: "Database", ok: true, message: `${row.count} tasks \xB7 ${size}` });
14969
+ } catch (e) {
14970
+ checks.push({ name: "Database", ok: false, message: e instanceof Error ? e.message : "Failed" });
14971
+ }
14972
+ try {
14973
+ const db = getDatabase();
14974
+ const row = db.query("SELECT MAX(id) as max_id FROM _migrations").get();
14975
+ checks.push({ name: "Migrations", ok: true, message: `Schema at migration ${row.max_id}` });
14976
+ } catch {
14977
+ checks.push({ name: "Migrations", ok: false, message: "Could not read migration version" });
14978
+ }
14979
+ try {
14980
+ const { loadConfig: loadConfig2 } = (init_config(), __toCommonJS(exports_config));
14981
+ loadConfig2();
14982
+ checks.push({ name: "Config", ok: true, message: "Loaded successfully" });
14983
+ } catch (e) {
14984
+ checks.push({ name: "Config", ok: false, message: e instanceof Error ? e.message : "Failed" });
14985
+ }
14986
+ try {
14987
+ const allTasks = listTasks({});
14988
+ const stale = allTasks.filter((t) => t.status === "in_progress" && new Date(t.updated_at).getTime() < Date.now() - 30 * 60 * 1000);
14989
+ const overdue = allTasks.filter((t) => t.recurrence_rule && t.status === "pending" && t.due_at && t.due_at < new Date().toISOString());
14990
+ const msg = `${allTasks.length} tasks${stale.length > 0 ? ` \xB7 ${stale.length} stale` : ""}${overdue.length > 0 ? ` \xB7 ${overdue.length} overdue recurring` : ""}`;
14991
+ checks.push({ name: "Tasks", ok: stale.length === 0 && overdue.length === 0, message: msg });
14992
+ } catch (e) {
14993
+ checks.push({ name: "Tasks", ok: false, message: "Failed to read tasks" });
14994
+ }
14995
+ if (opts.json || globalOpts.json) {
14996
+ const ok = checks.every((c) => c.ok);
14997
+ console.log(JSON.stringify({ ok, checks }));
14998
+ return;
14999
+ }
15000
+ console.log(chalk.bold(`todos health
15001
+ `));
15002
+ for (const c of checks) {
15003
+ const icon = c.ok ? chalk.green("\u2713") : chalk.yellow("\u26A0");
15004
+ console.log(` ${icon} ${c.name.padEnd(14)} ${c.message}`);
15005
+ }
15006
+ const allOk = checks.every((c) => c.ok);
15007
+ console.log(`
15008
+ ${allOk ? chalk.green("All checks passed.") : chalk.yellow("Some checks need attention.")}`);
15009
+ });
14947
15010
  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) => {
14948
15011
  const globalOpts = program2.opts();
14949
15012
  const db = getDatabase();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/todos",
3
- "version": "0.9.59",
3
+ "version": "0.9.60",
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",