@hasna/todos 0.11.50 → 0.11.52

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
@@ -4533,6 +4533,11 @@ function resolvePartialId(db, table, partialId) {
4533
4533
  if (nameRow)
4534
4534
  return nameRow.id;
4535
4535
  }
4536
+ if (table === "agents") {
4537
+ const nameRow = db.query("SELECT id FROM agents WHERE lower(name) = ?").get(partialId.toLowerCase());
4538
+ if (nameRow)
4539
+ return nameRow.id;
4540
+ }
4536
4541
  return null;
4537
4542
  }
4538
4543
  var LOCK_EXPIRY_MINUTES = 30, _db = null, ALLOWED_TABLES;
@@ -25081,6 +25086,21 @@ var init_task_crud2 = __esm(() => {
25081
25086
  init_token_utils();
25082
25087
  });
25083
25088
 
25089
+ // src/db/labels.ts
25090
+ function rowToLabel(row) {
25091
+ return { ...row };
25092
+ }
25093
+ function listLabels(projectId, db) {
25094
+ const d = db || getDatabase();
25095
+ if (projectId) {
25096
+ return d.query("SELECT * FROM labels WHERE project_id IS NULL OR project_id = ? ORDER BY name").all(projectId).map(rowToLabel);
25097
+ }
25098
+ return d.query("SELECT * FROM labels ORDER BY name").all().map(rowToLabel);
25099
+ }
25100
+ var init_labels = __esm(() => {
25101
+ init_database();
25102
+ });
25103
+
25084
25104
  // src/lib/mention-resolver.ts
25085
25105
  var exports_mention_resolver = {};
25086
25106
  __export(exports_mention_resolver, {
@@ -29182,6 +29202,7 @@ function registerTaskProjectTools(server, ctx) {
29182
29202
  if (shouldRegisterTool("create_project")) {
29183
29203
  server.tool("create_project", "Create a new project.", {
29184
29204
  name: exports_external.string().describe("Project name"),
29205
+ path: exports_external.string().describe("Unique filesystem path for the project"),
29185
29206
  description: exports_external.string().optional(),
29186
29207
  status: exports_external.enum(["active", "completed", "on_hold", "archived"]).optional(),
29187
29208
  short_id: exports_external.string().nullable().optional().describe("Short ID (auto-generated if omitted)"),
@@ -29201,7 +29222,11 @@ function registerTaskProjectTools(server, ctx) {
29201
29222
  limit: exports_external.number().optional()
29202
29223
  }, async ({ status, limit }) => {
29203
29224
  try {
29204
- const projects = listProjects({ status, limit });
29225
+ let projects = listProjects();
29226
+ if (status)
29227
+ projects = projects.filter((p) => p.status === status);
29228
+ if (limit)
29229
+ projects = projects.slice(0, limit);
29205
29230
  if (projects.length === 0)
29206
29231
  return { content: [{ type: "text", text: "No projects found." }] };
29207
29232
  const lines = projects.map((p) => `[${p.status}] ${p.short_id || p.id.slice(0, 8)} ${p.name}`);
@@ -29831,12 +29856,12 @@ Tasks:` : null,
29831
29856
  });
29832
29857
  }
29833
29858
  if (shouldRegisterTool("list_tags")) {
29834
- server.tool("list_tags", "List all tags.", async () => {
29859
+ server.tool("list_tags", "List all distinct task tags in use, with task counts.", async () => {
29835
29860
  try {
29836
- const tags = listTags();
29837
- if (tags.length === 0)
29861
+ const rows = getDatabase().query("SELECT tag, COUNT(*) AS count FROM task_tags GROUP BY tag ORDER BY tag").all();
29862
+ if (rows.length === 0)
29838
29863
  return { content: [{ type: "text", text: "No tags found." }] };
29839
- const lines = tags.map((t) => `${t.color ? "[" + t.color + "] " : ""}${t.name}`);
29864
+ const lines = rows.map((r) => `${r.tag} (${r.count})`);
29840
29865
  return { content: [{ type: "text", text: lines.join(`
29841
29866
  `) }] };
29842
29867
  } catch (e) {
@@ -30405,6 +30430,8 @@ var init_task_project_tools = __esm(() => {
30405
30430
  init_comments();
30406
30431
  init_task_runs();
30407
30432
  init_project_bootstrap();
30433
+ init_database();
30434
+ init_labels();
30408
30435
  init_redaction();
30409
30436
  init_retention_cleanup();
30410
30437
  init_mention_resolver();
@@ -42855,8 +42882,17 @@ function buildServer() {
42855
42882
  version: getMcpVersion()
42856
42883
  });
42857
42884
  installMcpTokenDiagnostics(server);
42885
+ const registeredToolNames = new Set;
42886
+ const shouldRegisterToolOnce = (name) => {
42887
+ if (!shouldRegisterTool(name))
42888
+ return false;
42889
+ if (registeredToolNames.has(name))
42890
+ return false;
42891
+ registeredToolNames.add(name);
42892
+ return true;
42893
+ };
42858
42894
  const toolContext = {
42859
- shouldRegisterTool,
42895
+ shouldRegisterTool: shouldRegisterToolOnce,
42860
42896
  resolveId,
42861
42897
  formatError,
42862
42898
  formatTask,
@@ -42876,8 +42912,8 @@ function buildServer() {
42876
42912
  registerTemplateTools(server, toolContext);
42877
42913
  registerEnvironmentSnapshotTools(server, toolContext);
42878
42914
  registerWorkflowPrompts(server);
42879
- registerMachineTools(server, { shouldRegisterTool, formatError });
42880
- registerDispatchTools(server, { shouldRegisterTool, resolveId, formatError });
42915
+ registerMachineTools(server, { shouldRegisterTool: shouldRegisterToolOnce, formatError });
42916
+ registerDispatchTools(server, { shouldRegisterTool: shouldRegisterToolOnce, resolveId, formatError });
42881
42917
  return server;
42882
42918
  }
42883
42919
  async function main() {
package/dist/contracts.js CHANGED
@@ -2389,6 +2389,11 @@ function resolvePartialId(db, table, partialId) {
2389
2389
  if (nameRow)
2390
2390
  return nameRow.id;
2391
2391
  }
2392
+ if (table === "agents") {
2393
+ const nameRow = db.query("SELECT id FROM agents WHERE lower(name) = ?").get(partialId.toLowerCase());
2394
+ if (nameRow)
2395
+ return nameRow.id;
2396
+ }
2392
2397
  return null;
2393
2398
  }
2394
2399
  var LOCK_EXPIRY_MINUTES = 30, _db = null, ALLOWED_TABLES;
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAMtC,eAAO,MAAM,mBAAmB,KAAK,CAAC;AA2DtC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAYD,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAmBrD;AAED,wBAAgB,aAAa,IAAI,IAAI,CAKpC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED,wBAAgB,GAAG,IAAI,MAAM,CAE5B;AAED,wBAAgB,IAAI,IAAI,MAAM,CAE7B;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,SAAa,GAAG,OAAO,CAKlF;AAED,wBAAgB,gBAAgB,CAAC,KAAK,SAAa,GAAG,MAAM,CAG3D;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAGpD;AAID,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAyC9F"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAMtC,eAAO,MAAM,mBAAmB,KAAK,CAAC;AA2DtC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAYD,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAmBrD;AAED,wBAAgB,aAAa,IAAI,IAAI,CAKpC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED,wBAAgB,GAAG,IAAI,MAAM,CAE5B;AAED,wBAAgB,IAAI,IAAI,MAAM,CAE7B;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,SAAa,GAAG,OAAO,CAKlF;AAED,wBAAgB,gBAAgB,CAAC,KAAK,SAAa,GAAG,MAAM,CAG3D;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAGpD;AAID,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiD9F"}
package/dist/index.js CHANGED
@@ -2389,6 +2389,11 @@ function resolvePartialId(db, table, partialId) {
2389
2389
  if (nameRow)
2390
2390
  return nameRow.id;
2391
2391
  }
2392
+ if (table === "agents") {
2393
+ const nameRow = db.query("SELECT id FROM agents WHERE lower(name) = ?").get(partialId.toLowerCase());
2394
+ if (nameRow)
2395
+ return nameRow.id;
2396
+ }
2392
2397
  return null;
2393
2398
  }
2394
2399
  var LOCK_EXPIRY_MINUTES = 30, _db = null, ALLOWED_TABLES;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA+EpE,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAO9E;AA8GD,wBAAgB,WAAW,cAuC1B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA+EpE,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAO9E;AA8GD,wBAAgB,WAAW,cAsD1B"}
package/dist/mcp/index.js CHANGED
@@ -2405,6 +2405,11 @@ function resolvePartialId(db, table, partialId) {
2405
2405
  if (nameRow)
2406
2406
  return nameRow.id;
2407
2407
  }
2408
+ if (table === "agents") {
2409
+ const nameRow = db.query("SELECT id FROM agents WHERE lower(name) = ?").get(partialId.toLowerCase());
2410
+ if (nameRow)
2411
+ return nameRow.id;
2412
+ }
2408
2413
  return null;
2409
2414
  }
2410
2415
  var LOCK_EXPIRY_MINUTES = 30, _db = null, ALLOWED_TABLES;
@@ -14437,6 +14442,21 @@ var init_project_bootstrap = __esm(() => {
14437
14442
  init_task_lists();
14438
14443
  });
14439
14444
 
14445
+ // src/db/labels.ts
14446
+ function rowToLabel(row) {
14447
+ return { ...row };
14448
+ }
14449
+ function listLabels(projectId, db) {
14450
+ const d = db || getDatabase();
14451
+ if (projectId) {
14452
+ return d.query("SELECT * FROM labels WHERE project_id IS NULL OR project_id = ? ORDER BY name").all(projectId).map(rowToLabel);
14453
+ }
14454
+ return d.query("SELECT * FROM labels ORDER BY name").all().map(rowToLabel);
14455
+ }
14456
+ var init_labels = __esm(() => {
14457
+ init_database();
14458
+ });
14459
+
14440
14460
  // src/lib/retention-cleanup.ts
14441
14461
  import { existsSync as existsSync7, unlinkSync } from "fs";
14442
14462
  function normalizeScopes(scopes) {
@@ -20142,6 +20162,7 @@ function registerTaskProjectTools(server, ctx) {
20142
20162
  if (shouldRegisterTool("create_project")) {
20143
20163
  server.tool("create_project", "Create a new project.", {
20144
20164
  name: exports_external.string().describe("Project name"),
20165
+ path: exports_external.string().describe("Unique filesystem path for the project"),
20145
20166
  description: exports_external.string().optional(),
20146
20167
  status: exports_external.enum(["active", "completed", "on_hold", "archived"]).optional(),
20147
20168
  short_id: exports_external.string().nullable().optional().describe("Short ID (auto-generated if omitted)"),
@@ -20161,7 +20182,11 @@ function registerTaskProjectTools(server, ctx) {
20161
20182
  limit: exports_external.number().optional()
20162
20183
  }, async ({ status, limit }) => {
20163
20184
  try {
20164
- const projects = listProjects({ status, limit });
20185
+ let projects = listProjects();
20186
+ if (status)
20187
+ projects = projects.filter((p) => p.status === status);
20188
+ if (limit)
20189
+ projects = projects.slice(0, limit);
20165
20190
  if (projects.length === 0)
20166
20191
  return { content: [{ type: "text", text: "No projects found." }] };
20167
20192
  const lines = projects.map((p) => `[${p.status}] ${p.short_id || p.id.slice(0, 8)} ${p.name}`);
@@ -20791,12 +20816,12 @@ Tasks:` : null,
20791
20816
  });
20792
20817
  }
20793
20818
  if (shouldRegisterTool("list_tags")) {
20794
- server.tool("list_tags", "List all tags.", async () => {
20819
+ server.tool("list_tags", "List all distinct task tags in use, with task counts.", async () => {
20795
20820
  try {
20796
- const tags = listTags();
20797
- if (tags.length === 0)
20821
+ const rows = getDatabase().query("SELECT tag, COUNT(*) AS count FROM task_tags GROUP BY tag ORDER BY tag").all();
20822
+ if (rows.length === 0)
20798
20823
  return { content: [{ type: "text", text: "No tags found." }] };
20799
- const lines = tags.map((t) => `${t.color ? "[" + t.color + "] " : ""}${t.name}`);
20824
+ const lines = rows.map((r) => `${r.tag} (${r.count})`);
20800
20825
  return { content: [{ type: "text", text: lines.join(`
20801
20826
  `) }] };
20802
20827
  } catch (e) {
@@ -21365,6 +21390,8 @@ var init_task_project_tools = __esm(() => {
21365
21390
  init_comments();
21366
21391
  init_task_runs();
21367
21392
  init_project_bootstrap();
21393
+ init_database();
21394
+ init_labels();
21368
21395
  init_redaction();
21369
21396
  init_retention_cleanup();
21370
21397
  init_mention_resolver();
@@ -37307,8 +37334,17 @@ function buildServer() {
37307
37334
  version: getMcpVersion()
37308
37335
  });
37309
37336
  installMcpTokenDiagnostics(server);
37337
+ const registeredToolNames = new Set;
37338
+ const shouldRegisterToolOnce = (name) => {
37339
+ if (!shouldRegisterTool(name))
37340
+ return false;
37341
+ if (registeredToolNames.has(name))
37342
+ return false;
37343
+ registeredToolNames.add(name);
37344
+ return true;
37345
+ };
37310
37346
  const toolContext = {
37311
- shouldRegisterTool,
37347
+ shouldRegisterTool: shouldRegisterToolOnce,
37312
37348
  resolveId,
37313
37349
  formatError,
37314
37350
  formatTask,
@@ -37328,8 +37364,8 @@ function buildServer() {
37328
37364
  registerTemplateTools(server, toolContext);
37329
37365
  registerEnvironmentSnapshotTools(server, toolContext);
37330
37366
  registerWorkflowPrompts(server);
37331
- registerMachineTools(server, { shouldRegisterTool, formatError });
37332
- registerDispatchTools(server, { shouldRegisterTool, resolveId, formatError });
37367
+ registerMachineTools(server, { shouldRegisterTool: shouldRegisterToolOnce, formatError });
37368
+ registerDispatchTools(server, { shouldRegisterTool: shouldRegisterToolOnce, resolveId, formatError });
37333
37369
  return server;
37334
37370
  }
37335
37371
  async function main() {
@@ -1 +1 @@
1
- {"version":3,"file":"task-project-tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/task-project-tools.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAkIjD,UAAU,kBAAkB;IAC1B,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACzD,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC;IACxC,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;IACnC,gBAAgB,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,mBAAmB,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACvE,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CAC3F;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,kBAAkB,QA41FlF"}
1
+ {"version":3,"file":"task-project-tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/task-project-tools.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAoIjD,UAAU,kBAAkB;IAC1B,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACzD,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC;IACxC,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;IACnC,gBAAgB,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,mBAAmB,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACvE,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CAC3F;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,kBAAkB,QAi2FlF"}
@@ -1 +1 @@
1
- {"version":3,"file":"verification.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/verification.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,KAAK,OAAO,GAAG;IACb,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC/D,WAAW,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;CACrC,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,kBAAkB,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,OAAO,GAAG,IAAI,CAyH1H"}
1
+ {"version":3,"file":"verification.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/verification.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,KAAK,OAAO,GAAG;IACb,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC/D,WAAW,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;CACrC,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,kBAAkB,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,OAAO,GAAG,IAAI,CA+H1H"}
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-trust.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/workspace-trust.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,KAAK,OAAO,GAAG;IACb,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,WAAW,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;CACrC,CAAC;AAEF,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,kBAAkB,EAAE,WAAW,EAAE,EAAE,OAAO,GAAG,IAAI,CAqDjH"}
1
+ {"version":3,"file":"workspace-trust.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/workspace-trust.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,KAAK,OAAO,GAAG;IACb,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,WAAW,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;CACrC,CAAC;AAEF,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,kBAAkB,EAAE,WAAW,EAAE,EAAE,OAAO,GAAG,IAAI,CA0DjH"}
package/dist/registry.js CHANGED
@@ -2389,6 +2389,11 @@ function resolvePartialId(db, table, partialId) {
2389
2389
  if (nameRow)
2390
2390
  return nameRow.id;
2391
2391
  }
2392
+ if (table === "agents") {
2393
+ const nameRow = db.query("SELECT id FROM agents WHERE lower(name) = ?").get(partialId.toLowerCase());
2394
+ if (nameRow)
2395
+ return nameRow.id;
2396
+ }
2392
2397
  return null;
2393
2398
  }
2394
2399
  var LOCK_EXPIRY_MINUTES = 30, _db = null, ALLOWED_TABLES;
@@ -2454,6 +2454,11 @@ function resolvePartialId(db, table, partialId) {
2454
2454
  if (nameRow)
2455
2455
  return nameRow.id;
2456
2456
  }
2457
+ if (table === "agents") {
2458
+ const nameRow = db.query("SELECT id FROM agents WHERE lower(name) = ?").get(partialId.toLowerCase());
2459
+ if (nameRow)
2460
+ return nameRow.id;
2461
+ }
2457
2462
  return null;
2458
2463
  }
2459
2464
  var LOCK_EXPIRY_MINUTES = 30, _db = null, ALLOWED_TABLES;
@@ -32084,6 +32089,21 @@ var init_project_bootstrap = __esm(() => {
32084
32089
  init_task_lists();
32085
32090
  });
32086
32091
 
32092
+ // src/db/labels.ts
32093
+ function rowToLabel(row) {
32094
+ return { ...row };
32095
+ }
32096
+ function listLabels(projectId, db) {
32097
+ const d = db || getDatabase();
32098
+ if (projectId) {
32099
+ return d.query("SELECT * FROM labels WHERE project_id IS NULL OR project_id = ? ORDER BY name").all(projectId).map(rowToLabel);
32100
+ }
32101
+ return d.query("SELECT * FROM labels ORDER BY name").all().map(rowToLabel);
32102
+ }
32103
+ var init_labels = __esm(() => {
32104
+ init_database();
32105
+ });
32106
+
32087
32107
  // src/lib/retention-cleanup.ts
32088
32108
  import { existsSync as existsSync9, unlinkSync } from "fs";
32089
32109
  function normalizeScopes(scopes) {
@@ -37789,6 +37809,7 @@ function registerTaskProjectTools(server, ctx) {
37789
37809
  if (shouldRegisterTool("create_project")) {
37790
37810
  server.tool("create_project", "Create a new project.", {
37791
37811
  name: exports_external.string().describe("Project name"),
37812
+ path: exports_external.string().describe("Unique filesystem path for the project"),
37792
37813
  description: exports_external.string().optional(),
37793
37814
  status: exports_external.enum(["active", "completed", "on_hold", "archived"]).optional(),
37794
37815
  short_id: exports_external.string().nullable().optional().describe("Short ID (auto-generated if omitted)"),
@@ -37808,7 +37829,11 @@ function registerTaskProjectTools(server, ctx) {
37808
37829
  limit: exports_external.number().optional()
37809
37830
  }, async ({ status, limit }) => {
37810
37831
  try {
37811
- const projects = listProjects({ status, limit });
37832
+ let projects = listProjects();
37833
+ if (status)
37834
+ projects = projects.filter((p) => p.status === status);
37835
+ if (limit)
37836
+ projects = projects.slice(0, limit);
37812
37837
  if (projects.length === 0)
37813
37838
  return { content: [{ type: "text", text: "No projects found." }] };
37814
37839
  const lines = projects.map((p) => `[${p.status}] ${p.short_id || p.id.slice(0, 8)} ${p.name}`);
@@ -38438,12 +38463,12 @@ Tasks:` : null,
38438
38463
  });
38439
38464
  }
38440
38465
  if (shouldRegisterTool("list_tags")) {
38441
- server.tool("list_tags", "List all tags.", async () => {
38466
+ server.tool("list_tags", "List all distinct task tags in use, with task counts.", async () => {
38442
38467
  try {
38443
- const tags = listTags();
38444
- if (tags.length === 0)
38468
+ const rows = getDatabase().query("SELECT tag, COUNT(*) AS count FROM task_tags GROUP BY tag ORDER BY tag").all();
38469
+ if (rows.length === 0)
38445
38470
  return { content: [{ type: "text", text: "No tags found." }] };
38446
- const lines = tags.map((t) => `${t.color ? "[" + t.color + "] " : ""}${t.name}`);
38471
+ const lines = rows.map((r) => `${r.tag} (${r.count})`);
38447
38472
  return { content: [{ type: "text", text: lines.join(`
38448
38473
  `) }] };
38449
38474
  } catch (e) {
@@ -39012,6 +39037,8 @@ var init_task_project_tools = __esm(() => {
39012
39037
  init_comments();
39013
39038
  init_task_runs();
39014
39039
  init_project_bootstrap();
39040
+ init_database();
39041
+ init_labels();
39015
39042
  init_redaction();
39016
39043
  init_retention_cleanup();
39017
39044
  init_mention_resolver();
@@ -76853,8 +76880,17 @@ function buildServer() {
76853
76880
  version: getMcpVersion()
76854
76881
  });
76855
76882
  installMcpTokenDiagnostics(server);
76883
+ const registeredToolNames = new Set;
76884
+ const shouldRegisterToolOnce = (name) => {
76885
+ if (!shouldRegisterTool(name))
76886
+ return false;
76887
+ if (registeredToolNames.has(name))
76888
+ return false;
76889
+ registeredToolNames.add(name);
76890
+ return true;
76891
+ };
76856
76892
  const toolContext = {
76857
- shouldRegisterTool,
76893
+ shouldRegisterTool: shouldRegisterToolOnce,
76858
76894
  resolveId,
76859
76895
  formatError: formatError2,
76860
76896
  formatTask,
@@ -76874,8 +76910,8 @@ function buildServer() {
76874
76910
  registerTemplateTools(server, toolContext);
76875
76911
  registerEnvironmentSnapshotTools(server, toolContext);
76876
76912
  registerWorkflowPrompts(server);
76877
- registerMachineTools(server, { shouldRegisterTool, formatError: formatError2 });
76878
- registerDispatchTools(server, { shouldRegisterTool, resolveId, formatError: formatError2 });
76913
+ registerMachineTools(server, { shouldRegisterTool: shouldRegisterToolOnce, formatError: formatError2 });
76914
+ registerDispatchTools(server, { shouldRegisterTool: shouldRegisterToolOnce, resolveId, formatError: formatError2 });
76879
76915
  return server;
76880
76916
  }
76881
76917
  async function main() {
package/dist/storage.js CHANGED
@@ -2519,6 +2519,11 @@ function resolvePartialId(db, table, partialId) {
2519
2519
  if (nameRow)
2520
2520
  return nameRow.id;
2521
2521
  }
2522
+ if (table === "agents") {
2523
+ const nameRow = db.query("SELECT id FROM agents WHERE lower(name) = ?").get(partialId.toLowerCase());
2524
+ if (nameRow)
2525
+ return nameRow.id;
2526
+ }
2522
2527
  return null;
2523
2528
  }
2524
2529
  var LOCK_EXPIRY_MINUTES = 30, _db = null, ALLOWED_TABLES;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/todos",
3
- "version": "0.11.50",
3
+ "version": "0.11.52",
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",