@hasna/todos 0.10.8 → 0.10.9

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
@@ -9812,6 +9812,7 @@ __export(exports_task_files, {
9812
9812
  listActiveFiles: () => listActiveFiles,
9813
9813
  getTaskFile: () => getTaskFile,
9814
9814
  findTasksByFile: () => findTasksByFile,
9815
+ bulkFindTasksByFiles: () => bulkFindTasksByFiles,
9815
9816
  bulkAddTaskFiles: () => bulkAddTaskFiles,
9816
9817
  addTaskFile: () => addTaskFile
9817
9818
  });
@@ -9852,6 +9853,32 @@ function removeTaskFile(taskId, path, db) {
9852
9853
  const result = d.run("DELETE FROM task_files WHERE task_id = ? AND path = ?", [taskId, path]);
9853
9854
  return result.changes > 0;
9854
9855
  }
9856
+ function bulkFindTasksByFiles(paths, db) {
9857
+ const d = db || getDatabase();
9858
+ if (paths.length === 0)
9859
+ return [];
9860
+ const placeholders = paths.map(() => "?").join(", ");
9861
+ const rows = d.query(`SELECT tf.*, t.status AS task_status FROM task_files tf
9862
+ JOIN tasks t ON tf.task_id = t.id
9863
+ WHERE tf.path IN (${placeholders}) AND tf.status != 'removed'
9864
+ ORDER BY tf.updated_at DESC`).all(...paths);
9865
+ const byPath = new Map;
9866
+ for (const path of paths)
9867
+ byPath.set(path, []);
9868
+ for (const row of rows) {
9869
+ byPath.get(row.path)?.push(row);
9870
+ }
9871
+ return paths.map((path) => {
9872
+ const tasks = byPath.get(path) ?? [];
9873
+ const inProgressCount = tasks.filter((t) => t.task_status === "in_progress").length;
9874
+ return {
9875
+ path,
9876
+ tasks,
9877
+ has_conflict: inProgressCount > 1,
9878
+ in_progress_count: inProgressCount
9879
+ };
9880
+ });
9881
+ }
9855
9882
  function listActiveFiles(db) {
9856
9883
  const d = db || getDatabase();
9857
9884
  return d.query(`
@@ -13318,6 +13345,19 @@ ${lines.join(`
13318
13345
  }
13319
13346
  });
13320
13347
  }
13348
+ if (shouldRegisterTool("bulk_find_tasks_by_files")) {
13349
+ server.tool("bulk_find_tasks_by_files", "Check multiple file paths at once for task/agent collisions. Returns per-path task list, in-progress count, and conflict flag.", {
13350
+ paths: exports_external.array(exports_external.string()).describe("Array of file paths to check")
13351
+ }, async ({ paths }) => {
13352
+ try {
13353
+ const { bulkFindTasksByFiles: bulkFindTasksByFiles2 } = (init_task_files(), __toCommonJS(exports_task_files));
13354
+ const results = bulkFindTasksByFiles2(paths);
13355
+ return { content: [{ type: "text", text: JSON.stringify(results, null, 2) }] };
13356
+ } catch (e) {
13357
+ return { content: [{ type: "text", text: formatError(e) }], isError: true };
13358
+ }
13359
+ });
13360
+ }
13321
13361
  if (shouldRegisterTool("list_active_files")) {
13322
13362
  server.tool("list_active_files", "Return all files linked to in-progress tasks across all agents \u2014 the bird's-eye view of what's being worked on right now.", {
13323
13363
  project_id: exports_external.string().optional().describe("Filter by project")
@@ -22,6 +22,13 @@ export declare function listTaskFiles(taskId: string, db?: Database): TaskFile[]
22
22
  export declare function findTasksByFile(path: string, db?: Database): TaskFile[];
23
23
  export declare function updateTaskFileStatus(taskId: string, path: string, status: TaskFile["status"], agentId?: string, db?: Database): TaskFile | null;
24
24
  export declare function removeTaskFile(taskId: string, path: string, db?: Database): boolean;
25
+ export interface BulkFileResult {
26
+ path: string;
27
+ tasks: TaskFile[];
28
+ has_conflict: boolean;
29
+ in_progress_count: number;
30
+ }
31
+ export declare function bulkFindTasksByFiles(paths: string[], db?: Database): BulkFileResult[];
25
32
  export interface ActiveFileInfo {
26
33
  path: string;
27
34
  file_status: TaskFile["status"];
@@ -1 +1 @@
1
- {"version":3,"file":"task-files.d.ts","sourceRoot":"","sources":["../../src/db/task-files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;IACnE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAwB5E;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAGtE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAKvE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,QAAQ,EAAE,CAKvE;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAC1B,OAAO,CAAC,EAAE,MAAM,EAChB,EAAE,CAAC,EAAE,QAAQ,GACZ,QAAQ,GAAG,IAAI,CAWjB;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAOnF;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAgB,eAAe,CAAC,EAAE,CAAC,EAAE,QAAQ,GAAG,cAAc,EAAE,CAwB/D;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,CAAC,EAAE,MAAM,EAChB,EAAE,CAAC,EAAE,QAAQ,GACZ,QAAQ,EAAE,CAUZ"}
1
+ {"version":3,"file":"task-files.d.ts","sourceRoot":"","sources":["../../src/db/task-files.ts"],"names":[],"mappings":"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"}
package/dist/mcp/index.js CHANGED
@@ -1357,6 +1357,7 @@ __export(exports_task_files, {
1357
1357
  listActiveFiles: () => listActiveFiles,
1358
1358
  getTaskFile: () => getTaskFile,
1359
1359
  findTasksByFile: () => findTasksByFile,
1360
+ bulkFindTasksByFiles: () => bulkFindTasksByFiles,
1360
1361
  bulkAddTaskFiles: () => bulkAddTaskFiles,
1361
1362
  addTaskFile: () => addTaskFile
1362
1363
  });
@@ -1397,6 +1398,32 @@ function removeTaskFile(taskId, path, db) {
1397
1398
  const result = d.run("DELETE FROM task_files WHERE task_id = ? AND path = ?", [taskId, path]);
1398
1399
  return result.changes > 0;
1399
1400
  }
1401
+ function bulkFindTasksByFiles(paths, db) {
1402
+ const d = db || getDatabase();
1403
+ if (paths.length === 0)
1404
+ return [];
1405
+ const placeholders = paths.map(() => "?").join(", ");
1406
+ const rows = d.query(`SELECT tf.*, t.status AS task_status FROM task_files tf
1407
+ JOIN tasks t ON tf.task_id = t.id
1408
+ WHERE tf.path IN (${placeholders}) AND tf.status != 'removed'
1409
+ ORDER BY tf.updated_at DESC`).all(...paths);
1410
+ const byPath = new Map;
1411
+ for (const path of paths)
1412
+ byPath.set(path, []);
1413
+ for (const row of rows) {
1414
+ byPath.get(row.path)?.push(row);
1415
+ }
1416
+ return paths.map((path) => {
1417
+ const tasks = byPath.get(path) ?? [];
1418
+ const inProgressCount = tasks.filter((t) => t.task_status === "in_progress").length;
1419
+ return {
1420
+ path,
1421
+ tasks,
1422
+ has_conflict: inProgressCount > 1,
1423
+ in_progress_count: inProgressCount
1424
+ };
1425
+ });
1426
+ }
1400
1427
  function listActiveFiles(db) {
1401
1428
  const d = db || getDatabase();
1402
1429
  return d.query(`
@@ -11046,6 +11073,19 @@ ${lines.join(`
11046
11073
  }
11047
11074
  });
11048
11075
  }
11076
+ if (shouldRegisterTool("bulk_find_tasks_by_files")) {
11077
+ server.tool("bulk_find_tasks_by_files", "Check multiple file paths at once for task/agent collisions. Returns per-path task list, in-progress count, and conflict flag.", {
11078
+ paths: exports_external.array(exports_external.string()).describe("Array of file paths to check")
11079
+ }, async ({ paths }) => {
11080
+ try {
11081
+ const { bulkFindTasksByFiles: bulkFindTasksByFiles2 } = (init_task_files(), __toCommonJS(exports_task_files));
11082
+ const results = bulkFindTasksByFiles2(paths);
11083
+ return { content: [{ type: "text", text: JSON.stringify(results, null, 2) }] };
11084
+ } catch (e) {
11085
+ return { content: [{ type: "text", text: formatError(e) }], isError: true };
11086
+ }
11087
+ });
11088
+ }
11049
11089
  if (shouldRegisterTool("list_active_files")) {
11050
11090
  server.tool("list_active_files", "Return all files linked to in-progress tasks across all agents \u2014 the bird's-eye view of what's being worked on right now.", {
11051
11091
  project_id: exports_external.string().optional().describe("Filter by project")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/todos",
3
- "version": "0.10.8",
3
+ "version": "0.10.9",
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",