@hasna/todos 0.13.11 → 0.13.12

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 (36) hide show
  1. package/dist/cli/cloud-router.d.ts.map +1 -1
  2. package/dist/cli/index.js +145 -95
  3. package/dist/contracts.js +92 -67
  4. package/dist/db/agent-metrics.d.ts.map +1 -1
  5. package/dist/db/audit.d.ts.map +1 -1
  6. package/dist/db/budgets.d.ts.map +1 -1
  7. package/dist/db/database.d.ts +44 -0
  8. package/dist/db/database.d.ts.map +1 -1
  9. package/dist/db/handoffs.d.ts.map +1 -1
  10. package/dist/db/task-crud.d.ts +1 -0
  11. package/dist/db/task-crud.d.ts.map +1 -1
  12. package/dist/db/task-files.d.ts.map +1 -1
  13. package/dist/db/task-lifecycle.d.ts.map +1 -1
  14. package/dist/db/task-relations.d.ts.map +1 -1
  15. package/dist/db/task-status.d.ts.map +1 -1
  16. package/dist/db/webhooks.d.ts.map +1 -1
  17. package/dist/index.js +119 -85
  18. package/dist/lib/capacity-forecasts.d.ts.map +1 -1
  19. package/dist/lib/completion-guard.d.ts.map +1 -1
  20. package/dist/lib/local-notifications.d.ts.map +1 -1
  21. package/dist/lib/local-reports.d.ts.map +1 -1
  22. package/dist/lib/notification-reminders.d.ts.map +1 -1
  23. package/dist/lib/search.d.ts.map +1 -1
  24. package/dist/lib/usage-ledger.d.ts.map +1 -1
  25. package/dist/mcp/index.js +136 -92
  26. package/dist/mcp/tools/agents.d.ts.map +1 -1
  27. package/dist/mcp/tools/task-adv-tools.d.ts.map +1 -1
  28. package/dist/mcp/tools/task-auto-tools.d.ts.map +1 -1
  29. package/dist/mcp/tools/task-resources.d.ts.map +1 -1
  30. package/dist/mcp.js +1 -1
  31. package/dist/registry.js +92 -67
  32. package/dist/release-provenance.json +5 -5
  33. package/dist/server/index.js +136 -92
  34. package/dist/server/routes.d.ts.map +1 -1
  35. package/dist/storage.js +57 -42
  36. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -2123,7 +2123,7 @@ var package_default;
2123
2123
  var init_package = __esm(() => {
2124
2124
  package_default = {
2125
2125
  name: "@hasna/todos",
2126
- version: "0.13.11",
2126
+ version: "0.13.12",
2127
2127
  description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
2128
2128
  type: "module",
2129
2129
  main: "dist/index.js",
@@ -6045,8 +6045,10 @@ async function cloudEscalatedTasks(client, opts = {}, at = new Date) {
6045
6045
  const filter = {};
6046
6046
  if (opts.project_id)
6047
6047
  filter.project_id = opts.project_id;
6048
+ if (opts.agent_id)
6049
+ filter.assigned_to = opts.agent_id;
6048
6050
  const active = await cloudActiveTasks(client, filter);
6049
- return active.filter((t) => !t.archived_at && (opts.agent_id ? t.assigned_to === opts.agent_id : true)).map((task) => {
6051
+ return active.filter((t) => !t.archived_at).map((task) => {
6050
6052
  const reasons = [];
6051
6053
  const breachedTimes = [];
6052
6054
  if (task.due_at) {
@@ -6258,7 +6260,11 @@ async function cloudRecap(client, hours, projectId) {
6258
6260
  const blocked = pending.filter((t) => blockedMap.has(t.id));
6259
6261
  const sinceMs = new Date(since).getTime();
6260
6262
  const agentSummaries = agents.map((agent) => {
6261
- const owned = all.filter((t) => t.assigned_to === agent.id || t.agent_id === agent.id);
6263
+ const assignedName = agent.name?.toLowerCase();
6264
+ const owned = all.filter((t) => {
6265
+ const assignedTo = t.assigned_to?.toLowerCase();
6266
+ return assignedTo === agent.id.toLowerCase() || assignedName && assignedTo === assignedName || t.agent_id === agent.id;
6267
+ });
6262
6268
  return {
6263
6269
  name: agent.name,
6264
6270
  completed_count: owned.filter((t) => t.status === "completed" && t.completed_at != null && t.completed_at > since).length,
@@ -10714,14 +10720,17 @@ var exports_database = {};
10714
10720
  __export(exports_database, {
10715
10721
  uuid: () => uuid,
10716
10722
  resolvePartialId: () => resolvePartialId,
10723
+ resolveAssignedToAliases: () => resolveAssignedToAliases,
10717
10724
  resetDatabase: () => resetDatabase,
10718
10725
  now: () => now,
10726
+ lowerInClause: () => lowerInClause,
10719
10727
  lockExpiryCutoff: () => lockExpiryCutoff,
10720
10728
  isLockExpired: () => isLockExpired,
10721
10729
  getDatabasePath: () => getDatabasePath,
10722
10730
  getDatabase: () => getDatabase,
10723
10731
  closeDatabase: () => closeDatabase,
10724
10732
  clearExpiredLocks: () => clearExpiredLocks,
10733
+ assignedToAliasSet: () => assignedToAliasSet,
10725
10734
  LOCK_EXPIRY_MINUTES: () => LOCK_EXPIRY_MINUTES
10726
10735
  });
10727
10736
  import { Database } from "bun:sqlite";
@@ -10950,6 +10959,33 @@ function resolvePartialId(db, table, partialId) {
10950
10959
  }
10951
10960
  return null;
10952
10961
  }
10962
+ function resolveAssignedToAliases(db, ref) {
10963
+ const aliases = new Set([ref]);
10964
+ let agentId;
10965
+ try {
10966
+ agentId = resolvePartialId(db, "agents", ref);
10967
+ } catch (err) {
10968
+ if (!(err instanceof IdentityAliasAmbiguousError))
10969
+ throw err;
10970
+ agentId = null;
10971
+ }
10972
+ if (agentId) {
10973
+ aliases.add(agentId);
10974
+ const row = db.query("SELECT name FROM agents WHERE id = ?").get(agentId);
10975
+ if (row?.name)
10976
+ aliases.add(row.name);
10977
+ }
10978
+ return [...aliases];
10979
+ }
10980
+ function assignedToAliasSet(db, ref) {
10981
+ return new Set(resolveAssignedToAliases(db, ref).map((a) => a.toLowerCase()));
10982
+ }
10983
+ function lowerInClause(column, values, params) {
10984
+ if (values.length === 0)
10985
+ return "1=0";
10986
+ params.push(...values.map((v) => v.toLowerCase()));
10987
+ return `LOWER(${column}) IN (${values.map(() => "?").join(",")})`;
10988
+ }
10953
10989
  var LOCK_EXPIRY_MINUTES = 30, _db = null, _dbPath = null, ALLOWED_TABLES;
10954
10990
  var init_database = __esm(() => {
10955
10991
  init_schema();
@@ -11740,17 +11776,19 @@ function checkCompletionGuard(task, agentId, db, configOverride) {
11740
11776
  throw new CompletionGuardError(`Too fast: task was started ${Math.floor(elapsedSeconds)}s ago. Minimum work duration is ${config.min_work_seconds}s. Wait ${remaining}s.`, remaining);
11741
11777
  }
11742
11778
  }
11779
+ const assignedAliasParams = [];
11780
+ const assignedInClause = agent ? lowerInClause("assigned_to", resolveAssignedToAliases(db, agent), assignedAliasParams) : "";
11743
11781
  if (agent && config.max_completions_per_window && config.window_minutes) {
11744
11782
  const windowStart = new Date(Date.now() - config.window_minutes * 60 * 1000).toISOString();
11745
11783
  const result = db.query(`SELECT COUNT(*) as count FROM tasks
11746
- WHERE completed_at > ? AND (assigned_to = ? OR agent_id = ?)`).get(windowStart, agent, agent);
11784
+ WHERE completed_at > ? AND (${assignedInClause} OR agent_id = ?)`).get(windowStart, ...assignedAliasParams, agent);
11747
11785
  if (result.count >= config.max_completions_per_window) {
11748
11786
  throw new CompletionGuardError(`Rate limit: ${result.count} tasks completed in the last ${config.window_minutes} minutes (max ${config.max_completions_per_window}). Slow down.`);
11749
11787
  }
11750
11788
  }
11751
11789
  if (agent && config.cooldown_seconds) {
11752
11790
  const result = db.query(`SELECT MAX(completed_at) as last_completed FROM tasks
11753
- WHERE completed_at IS NOT NULL AND (assigned_to = ? OR agent_id = ?) AND id != ?`).get(agent, agent, task.id);
11791
+ WHERE completed_at IS NOT NULL AND (${assignedInClause} OR agent_id = ?) AND id != ?`).get(...assignedAliasParams, agent, task.id);
11754
11792
  if (result.last_completed) {
11755
11793
  const elapsedSeconds = (Date.now() - new Date(result.last_completed).getTime()) / 1000;
11756
11794
  if (elapsedSeconds < config.cooldown_seconds) {
@@ -11764,6 +11802,7 @@ var init_completion_guard = __esm(() => {
11764
11802
  init_types();
11765
11803
  init_config();
11766
11804
  init_projects();
11805
+ init_database();
11767
11806
  });
11768
11807
 
11769
11808
  // src/lib/event-emission-safety.ts
@@ -13862,7 +13901,7 @@ function getRecap(hours = 8, projectId, db) {
13862
13901
  const in_progress = projectId ? d.query(`SELECT id, short_id, title, assigned_to, started_at FROM tasks WHERE status = 'in_progress' AND project_id = ? ORDER BY updated_at DESC`).all(projectId) : d.query(`SELECT id, short_id, title, assigned_to, started_at FROM tasks WHERE status = 'in_progress' ORDER BY updated_at DESC`).all();
13863
13902
  const blocked = projectId ? d.query(`SELECT DISTINCT t.id, t.short_id, t.title, t.assigned_to FROM tasks t JOIN task_dependencies td ON td.task_id = t.id JOIN tasks dep ON dep.id = td.depends_on AND dep.status NOT IN ('completed','cancelled') WHERE t.status = 'pending'${tpf}`).all(projectId) : d.query(`SELECT DISTINCT t.id, t.short_id, t.title, t.assigned_to FROM tasks t JOIN task_dependencies td ON td.task_id = t.id JOIN tasks dep ON dep.id = td.depends_on AND dep.status NOT IN ('completed','cancelled') WHERE t.status = 'pending'`).all();
13864
13903
  const stale = projectId ? d.query(`SELECT id, short_id, title, assigned_to, updated_at FROM tasks WHERE status = 'in_progress' AND updated_at < ? AND project_id = ? ORDER BY updated_at ASC`).all(staleWindow, projectId) : d.query(`SELECT id, short_id, title, assigned_to, updated_at FROM tasks WHERE status = 'in_progress' AND updated_at < ? ORDER BY updated_at ASC`).all(staleWindow);
13865
- const agents = projectId ? d.query(`SELECT a.name, a.last_seen_at, (SELECT COUNT(*) FROM tasks t WHERE (t.assigned_to = a.id OR t.agent_id = a.id) AND t.status = 'completed' AND t.completed_at > ?${tpf}) as completed_count, (SELECT COUNT(*) FROM tasks t WHERE (t.assigned_to = a.id OR t.agent_id = a.id) AND t.status = 'in_progress'${tpf}) as in_progress_count FROM agents a WHERE a.status = 'active' AND a.last_seen_at > ? ORDER BY completed_count DESC`).all(since, projectId, projectId, since) : d.query(`SELECT a.name, a.last_seen_at, (SELECT COUNT(*) FROM tasks t WHERE (t.assigned_to = a.id OR t.agent_id = a.id) AND t.status = 'completed' AND t.completed_at > ?) as completed_count, (SELECT COUNT(*) FROM tasks t WHERE (t.assigned_to = a.id OR t.agent_id = a.id) AND t.status = 'in_progress') as in_progress_count FROM agents a WHERE a.status = 'active' AND a.last_seen_at > ? ORDER BY completed_count DESC`).all(since, since);
13904
+ const agents = projectId ? d.query(`SELECT a.name, a.last_seen_at, (SELECT COUNT(*) FROM tasks t WHERE (t.assigned_to = a.id OR LOWER(t.assigned_to) = LOWER(a.name) OR t.agent_id = a.id) AND t.status = 'completed' AND t.completed_at > ?${tpf}) as completed_count, (SELECT COUNT(*) FROM tasks t WHERE (t.assigned_to = a.id OR LOWER(t.assigned_to) = LOWER(a.name) OR t.agent_id = a.id) AND t.status = 'in_progress'${tpf}) as in_progress_count FROM agents a WHERE a.status = 'active' AND a.last_seen_at > ? ORDER BY completed_count DESC`).all(since, projectId, projectId, since) : d.query(`SELECT a.name, a.last_seen_at, (SELECT COUNT(*) FROM tasks t WHERE (t.assigned_to = a.id OR LOWER(t.assigned_to) = LOWER(a.name) OR t.agent_id = a.id) AND t.status = 'completed' AND t.completed_at > ?) as completed_count, (SELECT COUNT(*) FROM tasks t WHERE (t.assigned_to = a.id OR LOWER(t.assigned_to) = LOWER(a.name) OR t.agent_id = a.id) AND t.status = 'in_progress') as in_progress_count FROM agents a WHERE a.status = 'active' AND a.last_seen_at > ? ORDER BY completed_count DESC`).all(since, since);
13866
13905
  return {
13867
13906
  hours,
13868
13907
  since,
@@ -14008,13 +14047,17 @@ function logDelivery(d, webhookId, event, payload, statusCode, response, attempt
14008
14047
  const id = uuid();
14009
14048
  d.run(`INSERT INTO webhook_deliveries (id, webhook_id, event, payload, status_code, response, attempt, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [id, webhookId, event, payload, statusCode, response, attempt, now()]);
14010
14049
  }
14011
- function matchesScope(wh, payload) {
14050
+ function matchesScope(wh, payload, db) {
14012
14051
  if (wh.project_id && payload.project_id !== wh.project_id)
14013
14052
  return false;
14014
14053
  if (wh.task_list_id && payload.task_list_id !== wh.task_list_id)
14015
14054
  return false;
14016
- if (wh.agent_id && payload.agent_id !== wh.agent_id && payload.assigned_to !== wh.agent_id)
14017
- return false;
14055
+ if (wh.agent_id && payload.agent_id !== wh.agent_id) {
14056
+ const aliasSet = assignedToAliasSet(db, wh.agent_id);
14057
+ const assignedTo = typeof payload.assigned_to === "string" ? payload.assigned_to.toLowerCase() : "";
14058
+ if (!aliasSet.has(assignedTo))
14059
+ return false;
14060
+ }
14018
14061
  if (wh.task_id && payload.id !== wh.task_id)
14019
14062
  return false;
14020
14063
  return true;
@@ -14081,7 +14124,7 @@ async function dispatchWebhook2(event, payload, db) {
14081
14124
  const webhooks = listWebhooks(d).filter((w) => w.active && (w.events.length === 0 || w.events.includes(event)));
14082
14125
  const payloadObj = typeof payload === "object" && payload !== null ? payload : {};
14083
14126
  for (const wh of webhooks) {
14084
- if (!matchesScope(wh, payloadObj))
14127
+ if (!matchesScope(wh, payloadObj, d))
14085
14128
  continue;
14086
14129
  const body = JSON.stringify({ event, payload, timestamp: now() });
14087
14130
  deliverWebhook(wh, event, body, 1, d).catch((err) => {
@@ -15229,14 +15272,16 @@ function getNextTask(agentId, filters, db) {
15229
15272
  conditions.push("id NOT IN (SELECT td.task_id FROM task_dependencies td JOIN tasks dep ON dep.id = td.depends_on WHERE dep.status != 'completed')");
15230
15273
  const where = conditions.join(" AND ");
15231
15274
  let recentProjectIds = [];
15275
+ const assignedAliasParams = [];
15276
+ const assignedInClause = agentId ? lowerInClause("assigned_to", resolveAssignedToAliases(d, agentId), assignedAliasParams) : "";
15232
15277
  if (agentId) {
15233
- const recentRows = d.query(`SELECT DISTINCT project_id FROM tasks WHERE assigned_to = ? AND status = 'completed' AND project_id IS NOT NULL ORDER BY completed_at DESC LIMIT 3`).all(agentId);
15278
+ const recentRows = d.query(`SELECT DISTINCT project_id FROM tasks WHERE ${assignedInClause} AND status = 'completed' AND project_id IS NOT NULL ORDER BY completed_at DESC LIMIT 3`).all(...assignedAliasParams);
15234
15279
  recentProjectIds = recentRows.map((r) => r.project_id);
15235
15280
  }
15236
15281
  let sql = `SELECT * FROM tasks WHERE ${where} ORDER BY `;
15237
15282
  if (agentId) {
15238
- sql += `CASE WHEN assigned_to = ? THEN 0 WHEN assigned_to IS NULL THEN 1 ELSE 2 END, `;
15239
- params.push(agentId);
15283
+ sql += `CASE WHEN ${assignedInClause} THEN 0 WHEN assigned_to IS NULL THEN 1 ELSE 2 END, `;
15284
+ params.push(...assignedAliasParams);
15240
15285
  }
15241
15286
  if (recentProjectIds.length > 0) {
15242
15287
  const placeholders = recentProjectIds.map(() => "?").join(",");
@@ -15630,30 +15675,6 @@ function getTaskWithRelations(id, db) {
15630
15675
  checklist
15631
15676
  };
15632
15677
  }
15633
- function resolveAssignedToAliases(db, ref) {
15634
- const aliases = new Set([ref]);
15635
- let agentId;
15636
- try {
15637
- agentId = resolvePartialId(db, "agents", ref);
15638
- } catch (err) {
15639
- if (!(err instanceof IdentityAliasAmbiguousError))
15640
- throw err;
15641
- agentId = null;
15642
- }
15643
- if (agentId) {
15644
- aliases.add(agentId);
15645
- const row = db.query("SELECT name FROM agents WHERE id = ?").get(agentId);
15646
- if (row?.name)
15647
- aliases.add(row.name);
15648
- }
15649
- return [...aliases];
15650
- }
15651
- function lowerInClause(column, values, params) {
15652
- if (values.length === 0)
15653
- return "1=0";
15654
- params.push(...values.map((v) => v.toLowerCase()));
15655
- return `LOWER(${column}) IN (${values.map(() => "?").join(",")})`;
15656
- }
15657
15678
  function listTasks(filter = {}, db) {
15658
15679
  const d = db || getDatabase();
15659
15680
  const { clearExpiredLocks: clearExpiredLocks2 } = (init_database(), __toCommonJS(exports_database));
@@ -16126,6 +16147,7 @@ function deleteTask(id, db) {
16126
16147
  var init_task_crud = __esm(() => {
16127
16148
  init_types();
16128
16149
  init_database();
16150
+ init_database();
16129
16151
  init_completion_guard();
16130
16152
  init_event_emission_safety();
16131
16153
  init_event_hooks();
@@ -16288,8 +16310,8 @@ function getTaskStats(filters, db) {
16288
16310
  params.push(filters.task_list_id);
16289
16311
  }
16290
16312
  if (filters?.agent_id) {
16291
- conditions.push("(agent_id = ? OR assigned_to = ?)");
16292
- params.push(filters.agent_id, filters.agent_id);
16313
+ params.push(filters.agent_id);
16314
+ conditions.push(`(agent_id = ? OR ${lowerInClause("assigned_to", resolveAssignedToAliases(d, filters.agent_id), params)})`);
16293
16315
  }
16294
16316
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
16295
16317
  const totalRow = d.query(`SELECT COUNT(*) as count FROM tasks ${where}`).get(...params);
@@ -16472,8 +16494,7 @@ function getEscalatedTasks(opts = {}, db, at = new Date) {
16472
16494
  params.push(opts.project_id);
16473
16495
  }
16474
16496
  if (opts.agent_id) {
16475
- conditions.push("assigned_to = ?");
16476
- params.push(opts.agent_id);
16497
+ conditions.push(lowerInClause("assigned_to", resolveAssignedToAliases(d, opts.agent_id), params));
16477
16498
  }
16478
16499
  const rows = d.query(`SELECT * FROM tasks WHERE ${conditions.join(" AND ")} ORDER BY due_at ASC, created_at ASC`).all(...params);
16479
16500
  return rows.map(rowToTask).map((task) => {
@@ -16521,8 +16542,7 @@ function notifyUpcomingDeadlines(opts = {}, db) {
16521
16542
  params.push(opts.project_id);
16522
16543
  }
16523
16544
  if (opts.agent_id) {
16524
- conditions.push("assigned_to = ?");
16525
- params.push(opts.agent_id);
16545
+ conditions.push(lowerInClause("assigned_to", resolveAssignedToAliases(d, opts.agent_id), params));
16526
16546
  }
16527
16547
  const rows = d.query(`SELECT * FROM tasks WHERE ${conditions.join(" AND ")} ORDER BY due_at ASC`).all(...params);
16528
16548
  return rows.map(rowToTask);
@@ -16780,13 +16800,14 @@ function getTimeReport(opts, db) {
16780
16800
  params.push(opts.plan_id);
16781
16801
  }
16782
16802
  if (opts?.agent_id) {
16803
+ const assignedInClause = lowerInClause("t.assigned_to", resolveAssignedToAliases(d, opts.agent_id), params);
16783
16804
  conditions.push(`(
16784
- t.assigned_to = ?
16805
+ ${assignedInClause}
16785
16806
  OR t.agent_id = ?
16786
16807
  OR EXISTS (SELECT 1 FROM task_time_logs ttl WHERE ttl.task_id = t.id AND ttl.agent_id = ?)
16787
16808
  OR EXISTS (SELECT 1 FROM focus_sessions fs WHERE fs.task_id = t.id AND fs.agent_id = ?)
16788
16809
  )`);
16789
- params.push(opts.agent_id, opts.agent_id, opts.agent_id, opts.agent_id);
16810
+ params.push(opts.agent_id, opts.agent_id, opts.agent_id);
16790
16811
  }
16791
16812
  if (opts?.since) {
16792
16813
  conditions.push("(t.completed_at >= ? OR t.updated_at >= ?)");
@@ -17799,7 +17820,7 @@ function listActiveFiles(db) {
17799
17820
  a.name AS agent_name
17800
17821
  FROM task_files tf
17801
17822
  JOIN tasks t ON tf.task_id = t.id
17802
- LEFT JOIN agents a ON (tf.agent_id = a.id OR (tf.agent_id IS NULL AND t.assigned_to = a.id))
17823
+ LEFT JOIN agents a ON (tf.agent_id = a.id OR (tf.agent_id IS NULL AND (t.assigned_to = a.id OR LOWER(t.assigned_to) = LOWER(a.name))))
17803
17824
  WHERE t.status = 'in_progress'
17804
17825
  AND tf.status != 'removed'
17805
17826
  ORDER BY tf.updated_at DESC
@@ -23368,8 +23389,7 @@ function searchTasks(options, projectId, taskListId, db) {
23368
23389
  }
23369
23390
  }
23370
23391
  if (opts.assigned_to) {
23371
- sql += " AND t.assigned_to = ?";
23372
- params.push(opts.assigned_to);
23392
+ sql += ` AND ${lowerInClause("t.assigned_to", resolveAssignedToAliases(d, opts.assigned_to), params)}`;
23373
23393
  }
23374
23394
  if (opts.agent_id) {
23375
23395
  sql += " AND t.agent_id = ?";
@@ -34899,8 +34919,9 @@ async function handleAgentMe(_req, url, _ctx, json2, taskToSummary2) {
34899
34919
  }
34900
34920
  }
34901
34921
  function handleAgentQueue(agentId, _ctx, json2, taskToSummary2) {
34922
+ const aliasSet = assignedToAliasSet(getDatabase(), agentId);
34902
34923
  const pending = listTasks({ status: "pending" });
34903
- const queue = pending.filter((t) => t.assigned_to === agentId || t.agent_id === agentId || !t.assigned_to && !t.locked_by);
34924
+ const queue = pending.filter((t) => aliasSet.has((t.assigned_to ?? "").toLowerCase()) || t.agent_id === agentId || !t.assigned_to && !t.locked_by);
34904
34925
  const order = { critical: 0, high: 1, medium: 2, low: 3 };
34905
34926
  queue.sort((a, b) => (order[a.priority] ?? 4) - (order[b.priority] ?? 4) || new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
34906
34927
  return json2(queue.map((t) => taskToSummary2(t)));
@@ -44587,11 +44608,12 @@ function runAlerts(input, db, checkedAt, quieted) {
44587
44608
  if (input.include_runs === false)
44588
44609
  return [];
44589
44610
  const since = Date.parse(input.run_since || new Date(Date.parse(checkedAt) - 24 * 60 * 60000).toISOString());
44611
+ const runAlertAliases = input.agent_id ? assignedToAliasSet(db, input.agent_id) : null;
44590
44612
  return listTaskRuns(undefined, db).filter((run) => run.completed_at && Date.parse(run.completed_at) >= since).map((run) => {
44591
44613
  const task = getTask(run.task_id, db);
44592
44614
  if (input.project_id && task?.project_id !== input.project_id)
44593
44615
  return null;
44594
- if (input.agent_id && run.agent_id !== input.agent_id && task?.assigned_to !== input.agent_id)
44616
+ if (input.agent_id && run.agent_id !== input.agent_id && !(runAlertAliases && runAlertAliases.has((task?.assigned_to ?? "").toLowerCase())))
44595
44617
  return null;
44596
44618
  const failed = ["failed", "cancelled"].includes(run.status);
44597
44619
  return {
@@ -44636,6 +44658,7 @@ async function checkLocalNotifications(input = {}, db) {
44636
44658
  const warnings = [];
44637
44659
  if (Number.isNaN(checkedMs))
44638
44660
  warnings.push("Invalid check timestamp; due-soon window may be incomplete.");
44661
+ const notifyAgentAliases = input.agent_id ? assignedToAliasSet(d, input.agent_id) : null;
44639
44662
  const alerts = [];
44640
44663
  for (const escalation of getEscalatedTasks({ project_id: input.project_id, agent_id: input.agent_id }, d, new Date(checkedAt))) {
44641
44664
  for (const reason of escalation.reasons) {
@@ -44647,7 +44670,7 @@ async function checkLocalNotifications(input = {}, db) {
44647
44670
  for (const task of listTasks({ project_id: input.project_id, include_archived: false, limit: 5000 }, d)) {
44648
44671
  if (!unfinished(task) || !task.due_at)
44649
44672
  continue;
44650
- if (input.agent_id && task.assigned_to !== input.agent_id && task.agent_id !== input.agent_id)
44673
+ if (input.agent_id && task.agent_id !== input.agent_id && !(notifyAgentAliases && notifyAgentAliases.has((task.assigned_to ?? "").toLowerCase())))
44651
44674
  continue;
44652
44675
  if (task.due_at > checkedAt && task.due_at <= dueSoonUntil) {
44653
44676
  alerts.push(taskAlert(task, "task_due_soon", "task.due_soon", "warning", `Due soon: ${task.title}`, task.due_at, quieted));
@@ -44655,7 +44678,7 @@ async function checkLocalNotifications(input = {}, db) {
44655
44678
  }
44656
44679
  }
44657
44680
  for (const task of getStaleTasks(staleMinutes, { project_id: input.project_id }, d)) {
44658
- if (input.agent_id && task.assigned_to !== input.agent_id && task.agent_id !== input.agent_id)
44681
+ if (input.agent_id && task.agent_id !== input.agent_id && !(notifyAgentAliases && notifyAgentAliases.has((task.assigned_to ?? "").toLowerCase())))
44659
44682
  continue;
44660
44683
  alerts.push(taskAlert(task, "task_stale", "task.stale", "warning", `Stale task: ${task.title}`, checkedAt, quieted, { stale_minutes: staleMinutes }));
44661
44684
  }
@@ -46480,10 +46503,12 @@ function matchesProfile(profile, query) {
46480
46503
  return false;
46481
46504
  return true;
46482
46505
  }
46483
- function taskMatchesAgent(task, agentId) {
46506
+ function taskMatchesAgent(task, agentId, aliasSet) {
46484
46507
  if (!agentId)
46485
46508
  return true;
46486
- return task.assigned_to === agentId || task.agent_id === agentId;
46509
+ if (task.agent_id === agentId)
46510
+ return true;
46511
+ return aliasSet ? aliasSet.has((task.assigned_to ?? "").toLowerCase()) : task.assigned_to === agentId;
46487
46512
  }
46488
46513
  function estimateRemaining(task) {
46489
46514
  if (task.status === "completed" || task.status === "cancelled")
@@ -46553,7 +46578,8 @@ function removeCapacityProfile(idOrAgent, projectId) {
46553
46578
  }
46554
46579
  function getPlanningForecast(input = {}, db) {
46555
46580
  const startDate = input.start_date ? dateOnly(input.start_date) : todayIso();
46556
- const tasks = listTasks({ project_id: input.project_id, plan_id: input.plan_id, limit: 1e4 }, db).filter((task) => taskMatchesAgent(task, input.agent_id));
46581
+ const aliasSet = input.agent_id ? assignedToAliasSet(db || getDatabase(), input.agent_id) : undefined;
46582
+ const tasks = listTasks({ project_id: input.project_id, plan_id: input.plan_id, limit: 1e4 }, db).filter((task) => taskMatchesAgent(task, input.agent_id, aliasSet));
46557
46583
  const reportByTask = new Map(getTimeReport({ project_id: input.project_id, plan_id: input.plan_id, agent_id: input.agent_id, include_open: true }, db).map((entry2) => [entry2.task_id, entry2]));
46558
46584
  const profiles = listCapacityProfiles({ agent_id: input.agent_id, project_id: input.project_id });
46559
46585
  const globalProfiles = input.project_id ? listCapacityProfiles({ agent_id: input.agent_id }).filter((profile) => profile.project_id === null) : [];
@@ -46651,6 +46677,7 @@ function renderPlanningForecastMarkdown(forecast) {
46651
46677
  }
46652
46678
  var LOCAL_CAPACITY_SCHEMA_VERSION = 1;
46653
46679
  var init_capacity_forecasts = __esm(() => {
46680
+ init_database();
46654
46681
  init_tasks();
46655
46682
  init_task_relations();
46656
46683
  init_config();
@@ -49760,8 +49787,10 @@ function getLatestHandoff(agentId, projectId, db) {
49760
49787
  function createSessionRecoveryHandoff(input, db) {
49761
49788
  const d = db || getDatabase();
49762
49789
  const limit = input.limit || 20;
49763
- const conditions = ["status = 'in_progress'", "(assigned_to = ? OR agent_id = ? OR locked_by = ?)"];
49764
- const params = [input.agent_id, input.agent_id, input.agent_id];
49790
+ const params = [];
49791
+ const assignedInClause = lowerInClause("assigned_to", resolveAssignedToAliases(d, input.agent_id), params);
49792
+ const conditions = ["status = 'in_progress'", `(${assignedInClause} OR agent_id = ? OR locked_by = ?)`];
49793
+ params.push(input.agent_id, input.agent_id);
49765
49794
  if (input.session_id) {
49766
49795
  conditions.push("session_id = ?");
49767
49796
  params.push(input.session_id);
@@ -50353,7 +50382,8 @@ function registerTaskAutoTools(server, ctx) {
50353
50382
  const assigned = listTasks4({ assigned_to: effectiveAgentId, limit: 500 }, undefined);
50354
50383
  const now4 = Date.now();
50355
50384
  const dueSoonCutoff = now4 + 24 * 60 * 60 * 1000;
50356
- const blocked = getBlockedTasks2().filter((t) => t.assigned_to === effectiveAgentId);
50385
+ const blockedAliases = assignedToAliasSet(getDatabase(), effectiveAgentId);
50386
+ const blocked = getBlockedTasks2().filter((t) => blockedAliases.has((t.assigned_to ?? "").toLowerCase()));
50357
50387
  const workload = {
50358
50388
  in_progress: assigned.filter((t) => t.status === "in_progress").length,
50359
50389
  pending: assigned.filter((t) => t.status === "pending").length,
@@ -50390,17 +50420,25 @@ function registerTaskAutoTools(server, ctx) {
50390
50420
  if (agents.length === 0)
50391
50421
  return { content: [{ type: "text", text: "No active agents available for rebalancing." }] };
50392
50422
  const activeTasks = listTasks4({ project_id: resolvedProjectId, status: ["pending", "in_progress"], limit: 1000 }, undefined);
50393
- const load = new Map(agents.map((agent) => [agent.id, activeTasks.filter((t) => t.assigned_to === agent.id).length]));
50423
+ const agentKeyByAlias = new Map;
50424
+ for (const agent of agents) {
50425
+ agentKeyByAlias.set(String(agent.id).toLowerCase(), agent.id);
50426
+ if (agent.name)
50427
+ agentKeyByAlias.set(String(agent.name).toLowerCase(), agent.id);
50428
+ }
50429
+ const canonicalAgentKey = (assignedTo) => assignedTo ? agentKeyByAlias.get(assignedTo.toLowerCase()) : undefined;
50430
+ const load = new Map(agents.map((agent) => [agent.id, activeTasks.filter((t) => canonicalAgentKey(t.assigned_to) === agent.id).length]));
50394
50431
  let moved = 0;
50395
50432
  let skipped = 0;
50396
- for (const task of activeTasks.filter((t) => t.status === "pending" && t.assigned_to && (load.get(t.assigned_to) ?? 0) > limit)) {
50397
- const target = agents.filter((agent) => agent.id !== task.assigned_to).sort((a, b) => (load.get(a.id) ?? 0) - (load.get(b.id) ?? 0))[0];
50433
+ for (const task of activeTasks.filter((t) => t.status === "pending" && canonicalAgentKey(t.assigned_to) && (load.get(canonicalAgentKey(t.assigned_to)) ?? 0) > limit)) {
50434
+ const currentAgentKey = canonicalAgentKey(task.assigned_to);
50435
+ const target = agents.filter((agent) => agent.id !== currentAgentKey).sort((a, b) => (load.get(a.id) ?? 0) - (load.get(b.id) ?? 0))[0];
50398
50436
  if (!target || (load.get(target.id) ?? 0) >= limit) {
50399
50437
  skipped++;
50400
50438
  continue;
50401
50439
  }
50402
50440
  updateTask3(task.id, { assigned_to: target.id, version: task.version });
50403
- load.set(task.assigned_to, (load.get(task.assigned_to) ?? 1) - 1);
50441
+ load.set(currentAgentKey, (load.get(currentAgentKey) ?? 1) - 1);
50404
50442
  load.set(target.id, (load.get(target.id) ?? 0) + 1);
50405
50443
  moved++;
50406
50444
  }
@@ -50579,6 +50617,7 @@ ${lines.join(`
50579
50617
  var init_task_auto_tools = __esm(() => {
50580
50618
  init_zod();
50581
50619
  init_cloud_router();
50620
+ init_database();
50582
50621
  });
50583
50622
 
50584
50623
  // src/lib/context-packs.ts
@@ -51758,7 +51797,8 @@ ${JSON.stringify(task.metadata, null, 2)}` : null
51758
51797
  }, undefined);
51759
51798
  const completedYesterday = completed.filter((t) => t.completed_at && t.completed_at.startsWith(yesterdayStr));
51760
51799
  const { getBlockedTasks: getBlockedTasks2 } = (init_tasks(), __toCommonJS(exports_tasks));
51761
- const blocked = getBlockedTasks2(effectiveProjectId ? resolveId(effectiveProjectId, "projects") : undefined).filter((t) => t.assigned_to === effectiveAgentId);
51800
+ const blockedAliases = effectiveAgentId ? assignedToAliasSet(getDatabase(), effectiveAgentId) : null;
51801
+ const blocked = getBlockedTasks2(effectiveProjectId ? resolveId(effectiveProjectId, "projects") : undefined).filter((t) => blockedAliases ? blockedAliases.has((t.assigned_to ?? "").toLowerCase()) : false);
51762
51802
  const lines = [
51763
51803
  `Standup for ${effectiveAgentId} (${effectiveProjectId ? `project: ${effectiveProjectId.slice(0, 8)}` : "all projects"})`,
51764
51804
  inProgress.length > 0 ? `
@@ -51986,6 +52026,7 @@ var init_task_adv_tools = __esm(() => {
51986
52026
  init_zod();
51987
52027
  init_token_utils();
51988
52028
  init_cloud_router();
52029
+ init_database();
51989
52030
  });
51990
52031
 
51991
52032
  // src/mcp/tools/task-meta-tools.ts
@@ -54182,27 +54223,29 @@ function getAgentMetrics(agentId, opts, db) {
54182
54223
  const agent = d.query("SELECT id, name FROM agents WHERE id = ? OR LOWER(name) = LOWER(?)").get(agentId, agentId);
54183
54224
  if (!agent)
54184
54225
  return null;
54226
+ const assignedAliases = resolveAssignedToAliases(d, agent.id).map((a) => a.toLowerCase());
54227
+ const assignedInClause = `LOWER(assigned_to) IN (${assignedAliases.map(() => "?").join(",")})`;
54185
54228
  let projectFilter = "";
54186
- const params = [agent.id, agent.id];
54229
+ const params = [agent.id, ...assignedAliases];
54187
54230
  if (opts?.project_id) {
54188
54231
  projectFilter = " AND project_id = ?";
54189
54232
  params.push(opts.project_id);
54190
54233
  }
54191
- const completed = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR assigned_to = ?) AND status = 'completed'${projectFilter}`).get(...params).count;
54192
- const failed = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR assigned_to = ?) AND status = 'failed'${projectFilter}`).get(...params).count;
54193
- const inProgress = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR assigned_to = ?) AND status = 'in_progress'${projectFilter}`).get(...params).count;
54234
+ const completed = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'completed'${projectFilter}`).get(...params).count;
54235
+ const failed = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'failed'${projectFilter}`).get(...params).count;
54236
+ const inProgress = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'in_progress'${projectFilter}`).get(...params).count;
54194
54237
  const total = completed + failed;
54195
54238
  const completionRate = total > 0 ? completed / total : 0;
54196
54239
  const avgTime = d.query(`SELECT AVG(
54197
54240
  (julianday(completed_at) - julianday(created_at)) * 24 * 60
54198
54241
  ) as avg_minutes
54199
54242
  FROM tasks
54200
- WHERE (agent_id = ? OR assigned_to = ?) AND status = 'completed' AND completed_at IS NOT NULL${projectFilter}`).get(...params);
54243
+ WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'completed' AND completed_at IS NOT NULL${projectFilter}`).get(...params);
54201
54244
  const avgConf = d.query(`SELECT AVG(confidence) as avg_confidence
54202
54245
  FROM tasks
54203
- WHERE (agent_id = ? OR assigned_to = ?) AND status = 'completed' AND confidence IS NOT NULL${projectFilter}`).get(...params);
54246
+ WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'completed' AND confidence IS NOT NULL${projectFilter}`).get(...params);
54204
54247
  const reviewTasks = d.query(`SELECT metadata FROM tasks
54205
- WHERE (agent_id = ? OR assigned_to = ?) AND status = 'completed'${projectFilter}
54248
+ WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'completed'${projectFilter}
54206
54249
  AND metadata LIKE '%_review_score%'`).all(...params);
54207
54250
  let reviewScoreAvg = null;
54208
54251
  if (reviewTasks.length > 0) {
@@ -54672,14 +54715,15 @@ function millisBetween(start, end) {
54672
54715
  return 0;
54673
54716
  return endMs - startMs;
54674
54717
  }
54675
- function addTaskScope(where, params, options, alias = "t") {
54718
+ function addTaskScope(where, params, options, db, alias = "t") {
54676
54719
  if (options.project_id) {
54677
54720
  where.push(`${alias}.project_id = ?`);
54678
54721
  params.push(options.project_id);
54679
54722
  }
54680
54723
  if (options.agent_id) {
54681
- where.push(`(${alias}.agent_id = ? OR ${alias}.assigned_to = ?)`);
54682
- params.push(options.agent_id, options.agent_id);
54724
+ params.push(options.agent_id);
54725
+ const assignedInClause = lowerInClause(`${alias}.assigned_to`, resolveAssignedToAliases(db, options.agent_id), params);
54726
+ where.push(`(${alias}.agent_id = ? OR ${assignedInClause})`);
54683
54727
  }
54684
54728
  if (options.since) {
54685
54729
  where.push(`${alias}.created_at >= ?`);
@@ -54690,14 +54734,15 @@ function addTaskScope(where, params, options, alias = "t") {
54690
54734
  params.push(options.until);
54691
54735
  }
54692
54736
  }
54693
- function addRunScope(where, params, options, runAlias = "r", taskAlias = "t") {
54737
+ function addRunScope(where, params, options, db, runAlias = "r", taskAlias = "t") {
54694
54738
  if (options.project_id) {
54695
54739
  where.push(`${taskAlias}.project_id = ?`);
54696
54740
  params.push(options.project_id);
54697
54741
  }
54698
54742
  if (options.agent_id) {
54699
- where.push(`(${runAlias}.agent_id = ? OR ${taskAlias}.agent_id = ? OR ${taskAlias}.assigned_to = ?)`);
54700
- params.push(options.agent_id, options.agent_id, options.agent_id);
54743
+ params.push(options.agent_id, options.agent_id);
54744
+ const assignedInClause = lowerInClause(`${taskAlias}.assigned_to`, resolveAssignedToAliases(db, options.agent_id), params);
54745
+ where.push(`(${runAlias}.agent_id = ? OR ${taskAlias}.agent_id = ? OR ${assignedInClause})`);
54701
54746
  }
54702
54747
  if (options.since) {
54703
54748
  where.push(`${runAlias}.started_at >= ?`);
@@ -54708,14 +54753,15 @@ function addRunScope(where, params, options, runAlias = "r", taskAlias = "t") {
54708
54753
  params.push(options.until);
54709
54754
  }
54710
54755
  }
54711
- function addTraceScope(where, params, options, traceAlias = "tr", taskAlias = "t") {
54756
+ function addTraceScope(where, params, options, db, traceAlias = "tr", taskAlias = "t") {
54712
54757
  if (options.project_id) {
54713
54758
  where.push(`${taskAlias}.project_id = ?`);
54714
54759
  params.push(options.project_id);
54715
54760
  }
54716
54761
  if (options.agent_id) {
54717
- where.push(`(${traceAlias}.agent_id = ? OR ${taskAlias}.agent_id = ? OR ${taskAlias}.assigned_to = ?)`);
54718
- params.push(options.agent_id, options.agent_id, options.agent_id);
54762
+ params.push(options.agent_id, options.agent_id);
54763
+ const assignedInClause = lowerInClause(`${taskAlias}.assigned_to`, resolveAssignedToAliases(db, options.agent_id), params);
54764
+ where.push(`(${traceAlias}.agent_id = ? OR ${taskAlias}.agent_id = ? OR ${assignedInClause})`);
54719
54765
  }
54720
54766
  if (options.since) {
54721
54767
  where.push(`${traceAlias}.created_at >= ?`);
@@ -54775,7 +54821,7 @@ function createLocalUsageLedger(options = {}, db) {
54775
54821
  const generatedAt = options.generated_at || new Date().toISOString();
54776
54822
  const taskWhere = [];
54777
54823
  const taskParams = [];
54778
- addTaskScope(taskWhere, taskParams, options);
54824
+ addTaskScope(taskWhere, taskParams, options, d);
54779
54825
  const taskClause = taskWhere.length ? `WHERE ${taskWhere.join(" AND ")}` : "";
54780
54826
  const taskTotals = queryOne(d, `SELECT COUNT(*) as tasks, COALESCE(SUM(cost_tokens), 0) as task_tokens, COALESCE(SUM(cost_usd), 0) as task_cost_usd FROM tasks t ${taskClause}`, taskParams);
54781
54827
  let projectCount = 0;
@@ -54784,14 +54830,14 @@ function createLocalUsageLedger(options = {}, db) {
54784
54830
  } else if (options.agent_id) {
54785
54831
  const projectWhere = ["t.project_id IS NOT NULL"];
54786
54832
  const projectParams = [];
54787
- addTaskScope(projectWhere, projectParams, options);
54833
+ addTaskScope(projectWhere, projectParams, options, d);
54788
54834
  projectCount = queryOne(d, `SELECT COUNT(DISTINCT t.project_id) as count FROM tasks t WHERE ${projectWhere.join(" AND ")}`, projectParams).count;
54789
54835
  } else {
54790
54836
  projectCount = queryOne(d, "SELECT COUNT(*) as count FROM projects", []).count;
54791
54837
  }
54792
54838
  const runWhere = [];
54793
54839
  const runParams = [];
54794
- addRunScope(runWhere, runParams, options);
54840
+ addRunScope(runWhere, runParams, options, d);
54795
54841
  const runClause = runWhere.length ? `WHERE ${runWhere.join(" AND ")}` : "";
54796
54842
  const runs = queryAll(d, `SELECT r.id, r.started_at, r.completed_at, r.metadata
54797
54843
  FROM task_runs r JOIN tasks t ON t.id = r.task_id
@@ -54808,7 +54854,7 @@ function createLocalUsageLedger(options = {}, db) {
54808
54854
  ${runClause}`, runParams);
54809
54855
  const traceWhere = [];
54810
54856
  const traceParams = [];
54811
- addTraceScope(traceWhere, traceParams, options);
54857
+ addTraceScope(traceWhere, traceParams, options, d);
54812
54858
  const traceClause = traceWhere.length ? `WHERE ${traceWhere.join(" AND ")}` : "";
54813
54859
  const traceTotals = queryOne(d, `SELECT COUNT(*) as traces,
54814
54860
  COALESCE(SUM(tr.tokens), 0) as tokens,
@@ -54952,10 +54998,12 @@ function limitValue(value) {
54952
54998
  function isTerminal2(task) {
54953
54999
  return task.status === "completed" || task.status === "failed" || task.status === "cancelled";
54954
55000
  }
54955
- function sameAgent(task, agentId) {
55001
+ function sameAgent(task, agentId, aliasSet) {
54956
55002
  if (!agentId)
54957
55003
  return true;
54958
- return task.assigned_to === agentId || task.agent_id === agentId;
55004
+ if (task.agent_id === agentId)
55005
+ return true;
55006
+ return aliasSet ? aliasSet.has((task.assigned_to ?? "").toLowerCase()) : task.assigned_to === agentId;
54959
55007
  }
54960
55008
  function withinTaskWindow(task, options) {
54961
55009
  const time = Date.parse(task.updated_at);
@@ -54968,11 +55016,12 @@ function withinTaskWindow(task, options) {
54968
55016
  return true;
54969
55017
  }
54970
55018
  function scopedTasks(options, db) {
55019
+ const aliasSet = options.agent_id ? assignedToAliasSet(db, options.agent_id) : undefined;
54971
55020
  return listTasks({
54972
55021
  project_id: options.project_id,
54973
55022
  plan_id: options.plan_id,
54974
55023
  include_archived: false
54975
- }, db).filter((task) => sameAgent(task, options.agent_id) && withinTaskWindow(task, options));
55024
+ }, db).filter((task) => sameAgent(task, options.agent_id, aliasSet) && withinTaskWindow(task, options));
54976
55025
  }
54977
55026
  function summarizeTask(task) {
54978
55027
  return {
@@ -55038,7 +55087,7 @@ function initialAgentSummary(agentId) {
55038
55087
  }
55039
55088
  };
55040
55089
  }
55041
- function addScopeClauses(where, params, options, timeColumn) {
55090
+ function addScopeClauses(where, params, options, timeColumn, db) {
55042
55091
  if (options.project_id) {
55043
55092
  where.push("t.project_id = ?");
55044
55093
  params.push(options.project_id);
@@ -55048,8 +55097,9 @@ function addScopeClauses(where, params, options, timeColumn) {
55048
55097
  params.push(options.plan_id);
55049
55098
  }
55050
55099
  if (options.agent_id) {
55051
- where.push("(r.agent_id = ? OR t.agent_id = ? OR t.assigned_to = ?)");
55052
- params.push(options.agent_id, options.agent_id, options.agent_id);
55100
+ params.push(options.agent_id, options.agent_id);
55101
+ const assignedInClause = lowerInClause("t.assigned_to", resolveAssignedToAliases(db, options.agent_id), params);
55102
+ where.push(`(r.agent_id = ? OR t.agent_id = ? OR ${assignedInClause})`);
55053
55103
  }
55054
55104
  if (options.since) {
55055
55105
  where.push(`${timeColumn} >= ?`);
@@ -55063,7 +55113,7 @@ function addScopeClauses(where, params, options, timeColumn) {
55063
55113
  function loadRuns(options, db) {
55064
55114
  const where = ["t.archived_at IS NULL"];
55065
55115
  const params = [];
55066
- addScopeClauses(where, params, options, "r.started_at");
55116
+ addScopeClauses(where, params, options, "r.started_at", db);
55067
55117
  return db.query(`
55068
55118
  SELECT
55069
55119
  r.id,
@@ -55103,8 +55153,9 @@ function loadVerifications(options, db) {
55103
55153
  params.push(options.plan_id);
55104
55154
  }
55105
55155
  if (options.agent_id) {
55106
- where.push("(v.agent_id = ? OR t.agent_id = ? OR t.assigned_to = ?)");
55107
- params.push(options.agent_id, options.agent_id, options.agent_id);
55156
+ params.push(options.agent_id, options.agent_id);
55157
+ const assignedInClause = lowerInClause("t.assigned_to", resolveAssignedToAliases(db, options.agent_id), params);
55158
+ where.push(`(v.agent_id = ? OR t.agent_id = ? OR ${assignedInClause})`);
55108
55159
  }
55109
55160
  if (options.since) {
55110
55161
  where.push("v.run_at >= ?");
@@ -55326,7 +55377,6 @@ function renderLocalReportMarkdown(report) {
55326
55377
  }
55327
55378
  var LOCAL_REPORT_SCHEMA_VERSION = 1, LOCAL_REPORT_TYPES;
55328
55379
  var init_local_reports = __esm(() => {
55329
- init_database();
55330
55380
  init_database();
55331
55381
  init_plans();
55332
55382
  init_tasks();
@@ -58382,7 +58432,7 @@ ${lines.join(`
58382
58432
  a.name AS agent_name
58383
58433
  FROM task_files tf
58384
58434
  JOIN tasks t ON tf.task_id = t.id
58385
- LEFT JOIN agents a ON (tf.agent_id = a.id OR (tf.agent_id IS NULL AND t.assigned_to = a.id))
58435
+ LEFT JOIN agents a ON (tf.agent_id = a.id OR (tf.agent_id IS NULL AND (t.assigned_to = a.id OR LOWER(t.assigned_to) = LOWER(a.name))))
58386
58436
  WHERE t.status = 'in_progress'
58387
58437
  AND tf.status != 'removed'
58388
58438
  AND t.project_id = ?
@@ -61762,7 +61812,7 @@ ${text2}` }] };
61762
61812
  const oldName = agent.name;
61763
61813
  const updated = updateAgent(agent.id, { name: new_name });
61764
61814
  const db = getDatabase();
61765
- const tasksResult = db.run("UPDATE tasks SET assigned_to = ? WHERE assigned_to = ?", [new_name, oldName]);
61815
+ const tasksResult = db.run("UPDATE tasks SET assigned_to = ? WHERE LOWER(assigned_to) = LOWER(?)", [new_name, oldName]);
61766
61816
  const taskNote = tasksResult.changes > 0 ? `
61767
61817
  Updated assigned_to on ${tasksResult.changes} task(s).` : "";
61768
61818
  return {