@hasna/todos 0.9.53 → 0.9.55

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
@@ -9154,6 +9154,18 @@ var init_zod = __esm(() => {
9154
9154
  var exports_mcp = {};
9155
9155
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9156
9156
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
9157
+ import { readFileSync as readFileSync3 } from "fs";
9158
+ import { join as join6, dirname as dirname2 } from "path";
9159
+ import { fileURLToPath } from "url";
9160
+ function getMcpVersion() {
9161
+ try {
9162
+ const __dir = dirname2(fileURLToPath(import.meta.url));
9163
+ const pkgPath = join6(__dir, "..", "package.json");
9164
+ return JSON.parse(readFileSync3(pkgPath, "utf-8")).version || "0.0.0";
9165
+ } catch {
9166
+ return "0.0.0";
9167
+ }
9168
+ }
9157
9169
  function shouldRegisterTool(name) {
9158
9170
  if (TODOS_PROFILE === "minimal")
9159
9171
  return MINIMAL_TOOLS.has(name);
@@ -9273,7 +9285,7 @@ var init_mcp = __esm(() => {
9273
9285
  init_types();
9274
9286
  server = new McpServer({
9275
9287
  name: "todos",
9276
- version: "0.9.35"
9288
+ version: getMcpVersion()
9277
9289
  });
9278
9290
  TODOS_PROFILE = (process.env["TODOS_PROFILE"] || "full").toLowerCase();
9279
9291
  MINIMAL_TOOLS = new Set([
@@ -11229,26 +11241,26 @@ __export(exports_serve, {
11229
11241
  startServer: () => startServer
11230
11242
  });
11231
11243
  import { existsSync as existsSync6 } from "fs";
11232
- import { join as join6, dirname as dirname2, extname, resolve as resolve2, sep } from "path";
11233
- import { fileURLToPath } from "url";
11244
+ import { join as join7, dirname as dirname3, extname, resolve as resolve2, sep } from "path";
11245
+ import { fileURLToPath as fileURLToPath2 } from "url";
11234
11246
  function resolveDashboardDir() {
11235
11247
  const candidates = [];
11236
11248
  try {
11237
- const scriptDir = dirname2(fileURLToPath(import.meta.url));
11238
- candidates.push(join6(scriptDir, "..", "dashboard", "dist"));
11239
- candidates.push(join6(scriptDir, "..", "..", "dashboard", "dist"));
11249
+ const scriptDir = dirname3(fileURLToPath2(import.meta.url));
11250
+ candidates.push(join7(scriptDir, "..", "dashboard", "dist"));
11251
+ candidates.push(join7(scriptDir, "..", "..", "dashboard", "dist"));
11240
11252
  } catch {}
11241
11253
  if (process.argv[1]) {
11242
- const mainDir = dirname2(process.argv[1]);
11243
- candidates.push(join6(mainDir, "..", "dashboard", "dist"));
11244
- candidates.push(join6(mainDir, "..", "..", "dashboard", "dist"));
11254
+ const mainDir = dirname3(process.argv[1]);
11255
+ candidates.push(join7(mainDir, "..", "dashboard", "dist"));
11256
+ candidates.push(join7(mainDir, "..", "..", "dashboard", "dist"));
11245
11257
  }
11246
- candidates.push(join6(process.cwd(), "dashboard", "dist"));
11258
+ candidates.push(join7(process.cwd(), "dashboard", "dist"));
11247
11259
  for (const candidate of candidates) {
11248
11260
  if (existsSync6(candidate))
11249
11261
  return candidate;
11250
11262
  }
11251
- return join6(process.cwd(), "dashboard", "dist");
11263
+ return join7(process.cwd(), "dashboard", "dist");
11252
11264
  }
11253
11265
  function json(data, status = 200, port) {
11254
11266
  return new Response(JSON.stringify(data), {
@@ -11648,6 +11660,19 @@ data: ${JSON.stringify({ type: "connected", agent_id: agentId, timestamp: new Da
11648
11660
  return json({ error: e instanceof Error ? e.message : "Failed to start task" }, 500, port);
11649
11661
  }
11650
11662
  }
11663
+ const failMatch = path.match(/^\/api\/tasks\/([^/]+)\/fail$/);
11664
+ if (failMatch && method === "POST") {
11665
+ const id = failMatch[1];
11666
+ try {
11667
+ const body = await req.json().catch(() => ({}));
11668
+ const { failTask: failTask2 } = await Promise.resolve().then(() => (init_tasks(), exports_tasks));
11669
+ const result = failTask2(id, body.agent_id, body.reason, { retry: body.retry, error_code: body.error_code });
11670
+ broadcastEvent({ type: "task", task_id: id, action: "failed", agent_id: body.agent_id || null });
11671
+ return json({ task: taskToSummary(result.task), retry_task: result.retryTask ? taskToSummary(result.retryTask) : null }, 200, port);
11672
+ } catch (e) {
11673
+ return json({ error: e instanceof Error ? e.message : "Failed to fail task" }, 500, port);
11674
+ }
11675
+ }
11651
11676
  const completeMatch = path.match(/^\/api\/tasks\/([^/]+)\/complete$/);
11652
11677
  if (completeMatch && method === "POST") {
11653
11678
  const id = completeMatch[1];
@@ -11960,7 +11985,7 @@ data: ${JSON.stringify({ type: "connected", agent_id: agentId, timestamp: new Da
11960
11985
  }
11961
11986
  if (dashboardExists && (method === "GET" || method === "HEAD")) {
11962
11987
  if (path !== "/") {
11963
- const filePath = join6(dashboardDir, path);
11988
+ const filePath = join7(dashboardDir, path);
11964
11989
  const resolvedFile = resolve2(filePath);
11965
11990
  const resolvedBase = resolve2(dashboardDir);
11966
11991
  if (!resolvedFile.startsWith(resolvedBase + sep) && resolvedFile !== resolvedBase) {
@@ -11970,7 +11995,7 @@ data: ${JSON.stringify({ type: "connected", agent_id: agentId, timestamp: new Da
11970
11995
  if (res2)
11971
11996
  return res2;
11972
11997
  }
11973
- const indexPath = join6(dashboardDir, "index.html");
11998
+ const indexPath = join7(dashboardDir, "index.html");
11974
11999
  const res = serveStaticFile(indexPath);
11975
12000
  if (res)
11976
12001
  return res;
@@ -13105,13 +13130,13 @@ init_sync();
13105
13130
  init_config();
13106
13131
  import chalk from "chalk";
13107
13132
  import { execSync } from "child_process";
13108
- import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
13109
- import { basename, dirname as dirname3, join as join7, resolve as resolve3 } from "path";
13110
- import { fileURLToPath as fileURLToPath2 } from "url";
13133
+ import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
13134
+ import { basename, dirname as dirname4, join as join8, resolve as resolve3 } from "path";
13135
+ import { fileURLToPath as fileURLToPath3 } from "url";
13111
13136
  function getPackageVersion() {
13112
13137
  try {
13113
- const pkgPath = join7(dirname3(fileURLToPath2(import.meta.url)), "..", "..", "package.json");
13114
- return JSON.parse(readFileSync3(pkgPath, "utf-8")).version || "0.0.0";
13138
+ const pkgPath = join8(dirname4(fileURLToPath3(import.meta.url)), "..", "..", "package.json");
13139
+ return JSON.parse(readFileSync4(pkgPath, "utf-8")).version || "0.0.0";
13115
13140
  } catch {
13116
13141
  return "0.0.0";
13117
13142
  }
@@ -14016,7 +14041,7 @@ hooks.command("install").description("Install Claude Code hooks for auto-sync").
14016
14041
  if (p)
14017
14042
  todosBin = p;
14018
14043
  } catch {}
14019
- const hooksDir = join7(process.cwd(), ".claude", "hooks");
14044
+ const hooksDir = join8(process.cwd(), ".claude", "hooks");
14020
14045
  if (!existsSync7(hooksDir))
14021
14046
  mkdirSync3(hooksDir, { recursive: true });
14022
14047
  const hookScript = `#!/usr/bin/env bash
@@ -14042,11 +14067,11 @@ esac
14042
14067
 
14043
14068
  exit 0
14044
14069
  `;
14045
- const hookPath = join7(hooksDir, "todos-sync.sh");
14070
+ const hookPath = join8(hooksDir, "todos-sync.sh");
14046
14071
  writeFileSync3(hookPath, hookScript);
14047
14072
  execSync(`chmod +x "${hookPath}"`);
14048
14073
  console.log(chalk.green(`Hook script created: ${hookPath}`));
14049
- const settingsPath = join7(process.cwd(), ".claude", "settings.json");
14074
+ const settingsPath = join8(process.cwd(), ".claude", "settings.json");
14050
14075
  const settings = readJsonFile2(settingsPath);
14051
14076
  if (!settings["hooks"]) {
14052
14077
  settings["hooks"] = {};
@@ -14093,7 +14118,7 @@ function getMcpBinaryPath() {
14093
14118
  if (p)
14094
14119
  return p;
14095
14120
  } catch {}
14096
- const bunBin = join7(HOME2, ".bun", "bin", "todos-mcp");
14121
+ const bunBin = join8(HOME2, ".bun", "bin", "todos-mcp");
14097
14122
  if (existsSync7(bunBin))
14098
14123
  return bunBin;
14099
14124
  return "todos-mcp";
@@ -14102,13 +14127,13 @@ function readJsonFile2(path) {
14102
14127
  if (!existsSync7(path))
14103
14128
  return {};
14104
14129
  try {
14105
- return JSON.parse(readFileSync3(path, "utf-8"));
14130
+ return JSON.parse(readFileSync4(path, "utf-8"));
14106
14131
  } catch {
14107
14132
  return {};
14108
14133
  }
14109
14134
  }
14110
14135
  function writeJsonFile2(path, data) {
14111
- const dir = dirname3(path);
14136
+ const dir = dirname4(path);
14112
14137
  if (!existsSync7(dir))
14113
14138
  mkdirSync3(dir, { recursive: true });
14114
14139
  writeFileSync3(path, JSON.stringify(data, null, 2) + `
@@ -14117,10 +14142,10 @@ function writeJsonFile2(path, data) {
14117
14142
  function readTomlFile(path) {
14118
14143
  if (!existsSync7(path))
14119
14144
  return "";
14120
- return readFileSync3(path, "utf-8");
14145
+ return readFileSync4(path, "utf-8");
14121
14146
  }
14122
14147
  function writeTomlFile(path, content) {
14123
- const dir = dirname3(path);
14148
+ const dir = dirname4(path);
14124
14149
  if (!existsSync7(dir))
14125
14150
  mkdirSync3(dir, { recursive: true });
14126
14151
  writeFileSync3(path, content);
@@ -14148,7 +14173,7 @@ function unregisterClaude(_global) {
14148
14173
  }
14149
14174
  }
14150
14175
  function registerCodex(binPath) {
14151
- const configPath = join7(HOME2, ".codex", "config.toml");
14176
+ const configPath = join8(HOME2, ".codex", "config.toml");
14152
14177
  let content = readTomlFile(configPath);
14153
14178
  content = removeTomlBlock(content, "mcp_servers.todos");
14154
14179
  const block = `
@@ -14162,7 +14187,7 @@ args = []
14162
14187
  console.log(chalk.green(`Codex CLI: registered in ${configPath}`));
14163
14188
  }
14164
14189
  function unregisterCodex() {
14165
- const configPath = join7(HOME2, ".codex", "config.toml");
14190
+ const configPath = join8(HOME2, ".codex", "config.toml");
14166
14191
  let content = readTomlFile(configPath);
14167
14192
  if (!content.includes("[mcp_servers.todos]")) {
14168
14193
  console.log(chalk.dim(`Codex CLI: todos not found in ${configPath}`));
@@ -14195,7 +14220,7 @@ function removeTomlBlock(content, blockName) {
14195
14220
  `);
14196
14221
  }
14197
14222
  function registerGemini(binPath) {
14198
- const configPath = join7(HOME2, ".gemini", "settings.json");
14223
+ const configPath = join8(HOME2, ".gemini", "settings.json");
14199
14224
  const config = readJsonFile2(configPath);
14200
14225
  if (!config["mcpServers"]) {
14201
14226
  config["mcpServers"] = {};
@@ -14209,7 +14234,7 @@ function registerGemini(binPath) {
14209
14234
  console.log(chalk.green(`Gemini CLI: registered in ${configPath}`));
14210
14235
  }
14211
14236
  function unregisterGemini() {
14212
- const configPath = join7(HOME2, ".gemini", "settings.json");
14237
+ const configPath = join8(HOME2, ".gemini", "settings.json");
14213
14238
  const config = readJsonFile2(configPath);
14214
14239
  const servers = config["mcpServers"];
14215
14240
  if (!servers || !("todos" in servers)) {
@@ -14422,7 +14447,7 @@ Updated to ${latestVersion}!`));
14422
14447
  });
14423
14448
  program2.command("config").description("View or update configuration").option("--get <key>", "Get a config value").option("--set <key=value>", "Set a config value (e.g. completion_guard.enabled=true)").action((opts) => {
14424
14449
  const globalOpts = program2.opts();
14425
- const configPath = join7(process.env["HOME"] || "~", ".todos", "config.json");
14450
+ const configPath = join8(process.env["HOME"] || "~", ".todos", "config.json");
14426
14451
  if (opts.get) {
14427
14452
  const config2 = loadConfig();
14428
14453
  const keys = opts.get.split(".");
@@ -14448,7 +14473,7 @@ program2.command("config").description("View or update configuration").option("-
14448
14473
  }
14449
14474
  let config2 = {};
14450
14475
  try {
14451
- config2 = JSON.parse(readFileSync3(configPath, "utf-8"));
14476
+ config2 = JSON.parse(readFileSync4(configPath, "utf-8"));
14452
14477
  } catch {}
14453
14478
  const keys = key.split(".");
14454
14479
  let obj = config2;
@@ -14458,7 +14483,7 @@ program2.command("config").description("View or update configuration").option("-
14458
14483
  obj = obj[keys[i]];
14459
14484
  }
14460
14485
  obj[keys[keys.length - 1]] = parsedValue;
14461
- const dir = dirname3(configPath);
14486
+ const dir = dirname4(configPath);
14462
14487
  if (!existsSync7(dir))
14463
14488
  mkdirSync3(dir, { recursive: true });
14464
14489
  writeFileSync3(configPath, JSON.stringify(config2, null, 2));
package/dist/index.js CHANGED
@@ -110,6 +110,13 @@ class TodosClient {
110
110
  body: JSON.stringify({ agent_id: agentId })
111
111
  });
112
112
  }
113
+ async failTask(id, options = {}) {
114
+ return this.fetch(`/api/tasks/${id}/fail`, {
115
+ method: "POST",
116
+ headers: { "Content-Type": "application/json" },
117
+ body: JSON.stringify(options)
118
+ });
119
+ }
113
120
  async logProgress(taskId, message, pctComplete, agentId) {
114
121
  return this.fetch(`/api/tasks/${taskId}/progress`, {
115
122
  method: "POST",
@@ -131,6 +138,40 @@ class TodosClient {
131
138
  async getProjects() {
132
139
  return this.fetch("/api/projects");
133
140
  }
141
+ async* subscribeToStream(options = {}) {
142
+ const params = new URLSearchParams;
143
+ if (options.agentId)
144
+ params.set("agent_id", options.agentId);
145
+ if (options.projectId)
146
+ params.set("project_id", options.projectId);
147
+ if (options.events)
148
+ params.set("events", options.events.join(","));
149
+ const url = `${this.baseUrl}/api/tasks/stream?${params}`;
150
+ const resp = await fetch(url);
151
+ if (!resp.ok || !resp.body)
152
+ throw new Error(`SSE connection failed: ${resp.status}`);
153
+ const reader = resp.body.getReader();
154
+ const decoder = new TextDecoder;
155
+ let buffer = "";
156
+ while (true) {
157
+ const { done, value } = await reader.read();
158
+ if (done)
159
+ break;
160
+ buffer += decoder.decode(value, { stream: true });
161
+ const lines = buffer.split(`
162
+ `);
163
+ buffer = lines.pop() || "";
164
+ for (const line of lines) {
165
+ if (line.startsWith("data: ")) {
166
+ try {
167
+ const data = JSON.parse(line.slice(6));
168
+ if (data.type !== "connected")
169
+ yield data;
170
+ } catch {}
171
+ }
172
+ }
173
+ }
174
+ }
134
175
  }
135
176
  function createClient(options) {
136
177
  return new TodosClient(options);
package/dist/mcp/index.js CHANGED
@@ -6946,9 +6946,21 @@ function syncWithAgents(agents, taskListIdByAgent, projectId, direction = "both"
6946
6946
 
6947
6947
  // src/mcp/index.ts
6948
6948
  init_database();
6949
+ import { readFileSync as readFileSync3 } from "fs";
6950
+ import { join as join6, dirname as dirname2 } from "path";
6951
+ import { fileURLToPath } from "url";
6952
+ function getMcpVersion() {
6953
+ try {
6954
+ const __dir = dirname2(fileURLToPath(import.meta.url));
6955
+ const pkgPath = join6(__dir, "..", "package.json");
6956
+ return JSON.parse(readFileSync3(pkgPath, "utf-8")).version || "0.0.0";
6957
+ } catch {
6958
+ return "0.0.0";
6959
+ }
6960
+ }
6949
6961
  var server = new McpServer({
6950
6962
  name: "todos",
6951
- version: "0.9.35"
6963
+ version: getMcpVersion()
6952
6964
  });
6953
6965
  var TODOS_PROFILE = (process.env["TODOS_PROFILE"] || "full").toLowerCase();
6954
6966
  var MINIMAL_TOOLS = new Set([
package/dist/sdk.d.ts CHANGED
@@ -110,6 +110,15 @@ export declare class TodosClient {
110
110
  getActiveWork(projectId?: string): Promise<any[]>;
111
111
  getTasksChangedSince(since: string, projectId?: string): Promise<any>;
112
112
  startTask(id: string, agentId: string): Promise<any>;
113
+ failTask(id: string, options?: {
114
+ reason?: string;
115
+ agent_id?: string;
116
+ retry?: boolean;
117
+ error_code?: string;
118
+ }): Promise<{
119
+ task: TaskSummary;
120
+ retry_task: TaskSummary | null;
121
+ }>;
113
122
  logProgress(taskId: string, message: string, pctComplete?: number, agentId?: string): Promise<any>;
114
123
  exportTasks(filter?: {
115
124
  status?: string;
@@ -117,6 +126,26 @@ export declare class TodosClient {
117
126
  format?: "json" | "csv";
118
127
  }): Promise<any>;
119
128
  getProjects(): Promise<any[]>;
129
+ /**
130
+ * Subscribe to task events via SSE. Returns an AsyncGenerator that yields events.
131
+ * Events: task.created, task.started, task.completed, task.failed, task.assigned, task.status_changed
132
+ *
133
+ * @example
134
+ * for await (const event of client.subscribeToStream({ agentId: "aurelius" })) {
135
+ * console.log(event.action, event.task_id);
136
+ * }
137
+ */
138
+ subscribeToStream(options?: {
139
+ agentId?: string;
140
+ projectId?: string;
141
+ events?: string[];
142
+ }): AsyncGenerator<{
143
+ type: string;
144
+ action: string;
145
+ task_id?: string;
146
+ agent_id?: string | null;
147
+ timestamp: string;
148
+ }, void, unknown>;
120
149
  }
121
150
  export declare function createClient(options?: TodosClientOptions): TodosClient;
122
151
  //# 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":"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"}
1
+ {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"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"}
@@ -2855,6 +2855,19 @@ data: ${JSON.stringify({ type: "connected", agent_id: agentId, timestamp: new Da
2855
2855
  return json({ error: e instanceof Error ? e.message : "Failed to start task" }, 500, port);
2856
2856
  }
2857
2857
  }
2858
+ const failMatch = path.match(/^\/api\/tasks\/([^/]+)\/fail$/);
2859
+ if (failMatch && method === "POST") {
2860
+ const id = failMatch[1];
2861
+ try {
2862
+ const body = await req.json().catch(() => ({}));
2863
+ const { failTask: failTask2 } = await Promise.resolve().then(() => (init_tasks(), exports_tasks));
2864
+ const result = failTask2(id, body.agent_id, body.reason, { retry: body.retry, error_code: body.error_code });
2865
+ broadcastEvent({ type: "task", task_id: id, action: "failed", agent_id: body.agent_id || null });
2866
+ return json({ task: taskToSummary(result.task), retry_task: result.retryTask ? taskToSummary(result.retryTask) : null }, 200, port);
2867
+ } catch (e) {
2868
+ return json({ error: e instanceof Error ? e.message : "Failed to fail task" }, 500, port);
2869
+ }
2870
+ }
2858
2871
  const completeMatch = path.match(/^\/api\/tasks\/([^/]+)\/complete$/);
2859
2872
  if (completeMatch && method === "POST") {
2860
2873
  const id = completeMatch[1];
@@ -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,CA6vB1G"}
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,CA4wB1G"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/todos",
3
- "version": "0.9.53",
3
+ "version": "0.9.55",
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",