@hasna/todos 0.9.49 → 0.9.51

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 CHANGED
@@ -11574,16 +11574,30 @@ data: ${JSON.stringify({ type: "connected", agent_id: agentId, timestamp: new Da
11574
11574
  }
11575
11575
  }
11576
11576
  const progressMatch = path.match(/^\/api\/tasks\/([^/]+)\/progress$/);
11577
- if (progressMatch && method === "GET") {
11577
+ if (progressMatch) {
11578
11578
  const id = progressMatch[1];
11579
11579
  const task = getTask(id);
11580
11580
  if (!task)
11581
11581
  return json({ error: "Task not found" }, 404, port);
11582
- const { listComments: listComments2 } = await Promise.resolve().then(() => (init_comments(), exports_comments));
11583
- const all = listComments2(id);
11584
- const progress = all.filter((c) => c.type === "progress");
11585
- const latest = progress[progress.length - 1] || null;
11586
- return json({ task_id: id, progress_entries: progress, latest, count: progress.length }, 200, port);
11582
+ if (method === "GET") {
11583
+ const { listComments: listComments2 } = await Promise.resolve().then(() => (init_comments(), exports_comments));
11584
+ const all = listComments2(id);
11585
+ const progress = all.filter((c) => c.type === "progress");
11586
+ const latest = progress[progress.length - 1] || null;
11587
+ return json({ task_id: id, progress_entries: progress, latest, count: progress.length }, 200, port);
11588
+ }
11589
+ if (method === "POST") {
11590
+ try {
11591
+ const body = await req.json();
11592
+ if (!body.message)
11593
+ return json({ error: "message required" }, 400, port);
11594
+ const { logProgress: logProgress2 } = await Promise.resolve().then(() => (init_comments(), exports_comments));
11595
+ const comment = logProgress2(id, body.message, body.pct_complete, body.agent_id);
11596
+ return json(comment, 201, port);
11597
+ } catch (e) {
11598
+ return json({ error: e instanceof Error ? e.message : "Failed to log progress" }, 500, port);
11599
+ }
11600
+ }
11587
11601
  }
11588
11602
  const taskMatch = path.match(/^\/api\/tasks\/([^/]+)$/);
11589
11603
  if (taskMatch) {
@@ -14099,32 +14113,26 @@ function writeTomlFile(path, content) {
14099
14113
  writeFileSync3(path, content);
14100
14114
  }
14101
14115
  function registerClaude(binPath, global) {
14102
- const configPath = global ? join7(HOME2, ".claude", ".mcp.json") : join7(process.cwd(), ".mcp.json");
14103
- const config = readJsonFile2(configPath);
14104
- if (!config["mcpServers"]) {
14105
- config["mcpServers"] = {};
14116
+ const scope = global ? "user" : "project";
14117
+ const cmd = `claude mcp add --transport stdio --scope ${scope} todos -- ${binPath}`;
14118
+ try {
14119
+ const { execSync: execSync2 } = __require("child_process");
14120
+ execSync2(cmd, { stdio: "pipe" });
14121
+ console.log(chalk.green(`Claude Code (${scope}): registered via 'claude mcp add'`));
14122
+ } catch {
14123
+ console.log(chalk.yellow(`Claude Code: could not auto-register. Run this command manually:`));
14124
+ console.log(chalk.cyan(` ${cmd}`));
14106
14125
  }
14107
- const servers = config["mcpServers"];
14108
- servers["todos"] = {
14109
- command: binPath,
14110
- args: []
14111
- };
14112
- writeJsonFile2(configPath, config);
14113
- const scope = global ? "global" : "project";
14114
- console.log(chalk.green(`Claude Code (${scope}): registered in ${configPath}`));
14115
14126
  }
14116
- function unregisterClaude(global) {
14117
- const configPath = global ? join7(HOME2, ".claude", ".mcp.json") : join7(process.cwd(), ".mcp.json");
14118
- const config = readJsonFile2(configPath);
14119
- const servers = config["mcpServers"];
14120
- if (!servers || !("todos" in servers)) {
14121
- console.log(chalk.dim(`Claude Code: todos not found in ${configPath}`));
14122
- return;
14127
+ function unregisterClaude(_global) {
14128
+ try {
14129
+ const { execSync: execSync2 } = __require("child_process");
14130
+ execSync2("claude mcp remove todos", { stdio: "pipe" });
14131
+ console.log(chalk.green(`Claude Code: removed todos MCP server`));
14132
+ } catch {
14133
+ console.log(chalk.yellow(`Claude Code: could not auto-remove. Run manually:`));
14134
+ console.log(chalk.cyan(" claude mcp remove todos"));
14123
14135
  }
14124
- delete servers["todos"];
14125
- writeJsonFile2(configPath, config);
14126
- const scope = global ? "global" : "project";
14127
- console.log(chalk.green(`Claude Code (${scope}): unregistered from ${configPath}`));
14128
14136
  }
14129
14137
  function registerCodex(binPath) {
14130
14138
  const configPath = join7(HOME2, ".codex", "config.toml");
package/dist/index.js CHANGED
@@ -103,6 +103,34 @@ class TodosClient {
103
103
  params.set("project_id", projectId);
104
104
  return this.fetch(`/api/tasks/changed?${params}`);
105
105
  }
106
+ async startTask(id, agentId) {
107
+ return this.fetch(`/api/tasks/${id}/start`, {
108
+ method: "POST",
109
+ headers: { "Content-Type": "application/json" },
110
+ body: JSON.stringify({ agent_id: agentId })
111
+ });
112
+ }
113
+ async logProgress(taskId, message, pctComplete, agentId) {
114
+ return this.fetch(`/api/tasks/${taskId}/progress`, {
115
+ method: "POST",
116
+ headers: { "Content-Type": "application/json" },
117
+ body: JSON.stringify({ message, pct_complete: pctComplete, agent_id: agentId })
118
+ });
119
+ }
120
+ async exportTasks(filter = {}) {
121
+ const params = new URLSearchParams;
122
+ if (filter.status)
123
+ params.set("status", filter.status);
124
+ if (filter.project_id)
125
+ params.set("project_id", filter.project_id);
126
+ const fmt = filter.format || "json";
127
+ if (fmt === "csv")
128
+ params.set("format", "csv");
129
+ return this.fetch(`/api/tasks/export?${params}`);
130
+ }
131
+ async getProjects() {
132
+ return this.fetch("/api/projects");
133
+ }
106
134
  }
107
135
  function createClient(options) {
108
136
  return new TodosClient(options);
package/dist/sdk.d.ts CHANGED
@@ -2,11 +2,75 @@
2
2
  * @hasna/todos REST SDK Client
3
3
  * Zero-dependency HTTP client for the todos REST API (todos serve).
4
4
  * Use when you need to interact with todos from another machine or process.
5
+ *
6
+ * Default port: 19427
7
+ * Env var: TODOS_URL (e.g. http://localhost:19427)
5
8
  */
6
9
  export interface TodosClientOptions {
7
10
  baseUrl?: string;
8
11
  timeout?: number;
9
12
  }
13
+ export interface TaskSummary {
14
+ id: string;
15
+ short_id: string | null;
16
+ title: string;
17
+ description: string | null;
18
+ status: "pending" | "in_progress" | "completed" | "failed" | "cancelled";
19
+ priority: "low" | "medium" | "high" | "critical";
20
+ project_id: string | null;
21
+ plan_id: string | null;
22
+ task_list_id: string | null;
23
+ agent_id: string | null;
24
+ assigned_to: string | null;
25
+ locked_by: string | null;
26
+ tags: string[];
27
+ version: number;
28
+ created_at: string;
29
+ updated_at: string;
30
+ completed_at: string | null;
31
+ due_at: string | null;
32
+ recurrence_rule: string | null;
33
+ }
34
+ export interface StatusSummaryResponse {
35
+ pending: number;
36
+ in_progress: number;
37
+ completed: number;
38
+ total: number;
39
+ active_work: {
40
+ id: string;
41
+ short_id: string | null;
42
+ title: string;
43
+ priority: string;
44
+ assigned_to: string | null;
45
+ locked_by: string | null;
46
+ updated_at: string;
47
+ }[];
48
+ next_task: TaskSummary | null;
49
+ stale_count: number;
50
+ overdue_recurring: number;
51
+ }
52
+ export interface ProgressEntry {
53
+ id: string;
54
+ task_id: string;
55
+ content: string;
56
+ type: "comment" | "progress" | "note";
57
+ progress_pct: number | null;
58
+ agent_id: string | null;
59
+ created_at: string;
60
+ }
61
+ export interface DashboardStats {
62
+ total_tasks: number;
63
+ pending: number;
64
+ in_progress: number;
65
+ completed: number;
66
+ failed: number;
67
+ cancelled: number;
68
+ projects: number;
69
+ agents: number;
70
+ stale_count?: number;
71
+ overdue_recurring?: number;
72
+ recurring_tasks?: number;
73
+ }
10
74
  export declare class TodosClient {
11
75
  private baseUrl;
12
76
  private timeout;
@@ -14,7 +78,7 @@ export declare class TodosClient {
14
78
  static fromEnv(): TodosClient;
15
79
  private fetch;
16
80
  isAlive(): Promise<boolean>;
17
- getStatus(projectId?: string, agentId?: string): Promise<any>;
81
+ getStatus(projectId?: string, agentId?: string): Promise<StatusSummaryResponse>;
18
82
  listTasks(filter?: {
19
83
  status?: string;
20
84
  project_id?: string;
@@ -22,8 +86,10 @@ export declare class TodosClient {
22
86
  limit?: number;
23
87
  offset?: number;
24
88
  session_id?: string;
25
- }): Promise<any[]>;
26
- getTask(id: string): Promise<any>;
89
+ due_today?: boolean;
90
+ overdue?: boolean;
91
+ }): Promise<TaskSummary[]>;
92
+ getTask(id: string): Promise<TaskSummary>;
27
93
  getTaskHistory(id: string): Promise<any[]>;
28
94
  getTaskProgress(id: string): Promise<any>;
29
95
  claimNextTask(agentId: string, projectId?: string): Promise<any>;
@@ -40,9 +106,17 @@ export declare class TodosClient {
40
106
  }): Promise<any>;
41
107
  updateTask(id: string, data: Record<string, unknown>): Promise<any>;
42
108
  deleteTask(id: string): Promise<void>;
43
- getStats(): Promise<any>;
109
+ getStats(): Promise<DashboardStats>;
44
110
  getActiveWork(projectId?: string): Promise<any[]>;
45
111
  getTasksChangedSince(since: string, projectId?: string): Promise<any>;
112
+ startTask(id: string, agentId: string): Promise<any>;
113
+ logProgress(taskId: string, message: string, pctComplete?: number, agentId?: string): Promise<any>;
114
+ exportTasks(filter?: {
115
+ status?: string;
116
+ project_id?: string;
117
+ format?: "json" | "csv";
118
+ }): Promise<any>;
119
+ getProjects(): Promise<any[]>;
46
120
  }
47
121
  export declare function createClient(options?: TodosClientOptions): TodosClient;
48
122
  //# sourceMappingURL=sdk.d.ts.map
package/dist/sdk.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,kBAAuB;IAK5C,MAAM,CAAC,OAAO,IAAI,WAAW;YAIf,KAAK;IAeb,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAO3B,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAO7D,SAAS,CAAC,MAAM,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAQ5J,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAIjC,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAI1C,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAIzC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAQhE,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAQxD,UAAU,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAQjM,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAQnE,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC;IAIxB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAMjD,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;CAK5E;AAED,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,WAAW,CAEtE"}
1
+ {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"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"}
@@ -2788,16 +2788,30 @@ data: ${JSON.stringify({ type: "connected", agent_id: agentId, timestamp: new Da
2788
2788
  }
2789
2789
  }
2790
2790
  const progressMatch = path.match(/^\/api\/tasks\/([^/]+)\/progress$/);
2791
- if (progressMatch && method === "GET") {
2791
+ if (progressMatch) {
2792
2792
  const id = progressMatch[1];
2793
2793
  const task = getTask(id);
2794
2794
  if (!task)
2795
2795
  return json({ error: "Task not found" }, 404, port);
2796
- const { listComments: listComments2 } = await Promise.resolve().then(() => (init_comments(), exports_comments));
2797
- const all = listComments2(id);
2798
- const progress = all.filter((c) => c.type === "progress");
2799
- const latest = progress[progress.length - 1] || null;
2800
- return json({ task_id: id, progress_entries: progress, latest, count: progress.length }, 200, port);
2796
+ if (method === "GET") {
2797
+ const { listComments: listComments2 } = await Promise.resolve().then(() => (init_comments(), exports_comments));
2798
+ const all = listComments2(id);
2799
+ const progress = all.filter((c) => c.type === "progress");
2800
+ const latest = progress[progress.length - 1] || null;
2801
+ return json({ task_id: id, progress_entries: progress, latest, count: progress.length }, 200, port);
2802
+ }
2803
+ if (method === "POST") {
2804
+ try {
2805
+ const body = await req.json();
2806
+ if (!body.message)
2807
+ return json({ error: "message required" }, 400, port);
2808
+ const { logProgress: logProgress2 } = await Promise.resolve().then(() => (init_comments(), exports_comments));
2809
+ const comment = logProgress2(id, body.message, body.pct_complete, body.agent_id);
2810
+ return json(comment, 201, port);
2811
+ } catch (e) {
2812
+ return json({ error: e instanceof Error ? e.message : "Failed to log progress" }, 500, port);
2813
+ }
2814
+ }
2801
2815
  }
2802
2816
  const taskMatch = path.match(/^\/api\/tasks\/([^/]+)$/);
2803
2817
  if (taskMatch) {
@@ -1 +1 @@
1
- {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/server/serve.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiHH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0uB1G"}
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/server/serve.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiHH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuvB1G"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/todos",
3
- "version": "0.9.49",
3
+ "version": "0.9.51",
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",