@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.
- package/dist/cli/cloud-router.d.ts.map +1 -1
- package/dist/cli/index.js +145 -95
- package/dist/contracts.js +92 -67
- package/dist/db/agent-metrics.d.ts.map +1 -1
- package/dist/db/audit.d.ts.map +1 -1
- package/dist/db/budgets.d.ts.map +1 -1
- package/dist/db/database.d.ts +44 -0
- package/dist/db/database.d.ts.map +1 -1
- package/dist/db/handoffs.d.ts.map +1 -1
- package/dist/db/task-crud.d.ts +1 -0
- package/dist/db/task-crud.d.ts.map +1 -1
- package/dist/db/task-files.d.ts.map +1 -1
- package/dist/db/task-lifecycle.d.ts.map +1 -1
- package/dist/db/task-relations.d.ts.map +1 -1
- package/dist/db/task-status.d.ts.map +1 -1
- package/dist/db/webhooks.d.ts.map +1 -1
- package/dist/index.js +119 -85
- package/dist/lib/capacity-forecasts.d.ts.map +1 -1
- package/dist/lib/completion-guard.d.ts.map +1 -1
- package/dist/lib/local-notifications.d.ts.map +1 -1
- package/dist/lib/local-reports.d.ts.map +1 -1
- package/dist/lib/notification-reminders.d.ts.map +1 -1
- package/dist/lib/search.d.ts.map +1 -1
- package/dist/lib/usage-ledger.d.ts.map +1 -1
- package/dist/mcp/index.js +136 -92
- package/dist/mcp/tools/agents.d.ts.map +1 -1
- package/dist/mcp/tools/task-adv-tools.d.ts.map +1 -1
- package/dist/mcp/tools/task-auto-tools.d.ts.map +1 -1
- package/dist/mcp/tools/task-resources.d.ts.map +1 -1
- package/dist/mcp.js +1 -1
- package/dist/registry.js +92 -67
- package/dist/release-provenance.json +5 -5
- package/dist/server/index.js +136 -92
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/storage.js +57 -42
- package/package.json +1 -1
package/dist/server/index.js
CHANGED
|
@@ -70,7 +70,7 @@ var package_default;
|
|
|
70
70
|
var init_package = __esm(() => {
|
|
71
71
|
package_default = {
|
|
72
72
|
name: "@hasna/todos",
|
|
73
|
-
version: "0.13.
|
|
73
|
+
version: "0.13.12",
|
|
74
74
|
description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
75
75
|
type: "module",
|
|
76
76
|
main: "dist/index.js",
|
|
@@ -9312,14 +9312,17 @@ var exports_database = {};
|
|
|
9312
9312
|
__export(exports_database, {
|
|
9313
9313
|
uuid: () => uuid,
|
|
9314
9314
|
resolvePartialId: () => resolvePartialId,
|
|
9315
|
+
resolveAssignedToAliases: () => resolveAssignedToAliases,
|
|
9315
9316
|
resetDatabase: () => resetDatabase,
|
|
9316
9317
|
now: () => now,
|
|
9318
|
+
lowerInClause: () => lowerInClause,
|
|
9317
9319
|
lockExpiryCutoff: () => lockExpiryCutoff,
|
|
9318
9320
|
isLockExpired: () => isLockExpired,
|
|
9319
9321
|
getDatabasePath: () => getDatabasePath,
|
|
9320
9322
|
getDatabase: () => getDatabase,
|
|
9321
9323
|
closeDatabase: () => closeDatabase,
|
|
9322
9324
|
clearExpiredLocks: () => clearExpiredLocks,
|
|
9325
|
+
assignedToAliasSet: () => assignedToAliasSet,
|
|
9323
9326
|
LOCK_EXPIRY_MINUTES: () => LOCK_EXPIRY_MINUTES
|
|
9324
9327
|
});
|
|
9325
9328
|
import { Database } from "bun:sqlite";
|
|
@@ -9548,6 +9551,33 @@ function resolvePartialId(db, table, partialId) {
|
|
|
9548
9551
|
}
|
|
9549
9552
|
return null;
|
|
9550
9553
|
}
|
|
9554
|
+
function resolveAssignedToAliases(db, ref) {
|
|
9555
|
+
const aliases = new Set([ref]);
|
|
9556
|
+
let agentId;
|
|
9557
|
+
try {
|
|
9558
|
+
agentId = resolvePartialId(db, "agents", ref);
|
|
9559
|
+
} catch (err) {
|
|
9560
|
+
if (!(err instanceof IdentityAliasAmbiguousError))
|
|
9561
|
+
throw err;
|
|
9562
|
+
agentId = null;
|
|
9563
|
+
}
|
|
9564
|
+
if (agentId) {
|
|
9565
|
+
aliases.add(agentId);
|
|
9566
|
+
const row = db.query("SELECT name FROM agents WHERE id = ?").get(agentId);
|
|
9567
|
+
if (row?.name)
|
|
9568
|
+
aliases.add(row.name);
|
|
9569
|
+
}
|
|
9570
|
+
return [...aliases];
|
|
9571
|
+
}
|
|
9572
|
+
function assignedToAliasSet(db, ref) {
|
|
9573
|
+
return new Set(resolveAssignedToAliases(db, ref).map((a) => a.toLowerCase()));
|
|
9574
|
+
}
|
|
9575
|
+
function lowerInClause(column, values, params) {
|
|
9576
|
+
if (values.length === 0)
|
|
9577
|
+
return "1=0";
|
|
9578
|
+
params.push(...values.map((v) => v.toLowerCase()));
|
|
9579
|
+
return `LOWER(${column}) IN (${values.map(() => "?").join(",")})`;
|
|
9580
|
+
}
|
|
9551
9581
|
var LOCK_EXPIRY_MINUTES = 30, _db = null, _dbPath = null, ALLOWED_TABLES;
|
|
9552
9582
|
var init_database = __esm(() => {
|
|
9553
9583
|
init_schema();
|
|
@@ -10117,17 +10147,19 @@ function checkCompletionGuard(task, agentId, db, configOverride) {
|
|
|
10117
10147
|
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);
|
|
10118
10148
|
}
|
|
10119
10149
|
}
|
|
10150
|
+
const assignedAliasParams = [];
|
|
10151
|
+
const assignedInClause = agent ? lowerInClause("assigned_to", resolveAssignedToAliases(db, agent), assignedAliasParams) : "";
|
|
10120
10152
|
if (agent && config.max_completions_per_window && config.window_minutes) {
|
|
10121
10153
|
const windowStart = new Date(Date.now() - config.window_minutes * 60 * 1000).toISOString();
|
|
10122
10154
|
const result = db.query(`SELECT COUNT(*) as count FROM tasks
|
|
10123
|
-
WHERE completed_at > ? AND (
|
|
10155
|
+
WHERE completed_at > ? AND (${assignedInClause} OR agent_id = ?)`).get(windowStart, ...assignedAliasParams, agent);
|
|
10124
10156
|
if (result.count >= config.max_completions_per_window) {
|
|
10125
10157
|
throw new CompletionGuardError(`Rate limit: ${result.count} tasks completed in the last ${config.window_minutes} minutes (max ${config.max_completions_per_window}). Slow down.`);
|
|
10126
10158
|
}
|
|
10127
10159
|
}
|
|
10128
10160
|
if (agent && config.cooldown_seconds) {
|
|
10129
10161
|
const result = db.query(`SELECT MAX(completed_at) as last_completed FROM tasks
|
|
10130
|
-
WHERE completed_at IS NOT NULL AND (
|
|
10162
|
+
WHERE completed_at IS NOT NULL AND (${assignedInClause} OR agent_id = ?) AND id != ?`).get(...assignedAliasParams, agent, task.id);
|
|
10131
10163
|
if (result.last_completed) {
|
|
10132
10164
|
const elapsedSeconds = (Date.now() - new Date(result.last_completed).getTime()) / 1000;
|
|
10133
10165
|
if (elapsedSeconds < config.cooldown_seconds) {
|
|
@@ -10141,6 +10173,7 @@ var init_completion_guard = __esm(() => {
|
|
|
10141
10173
|
init_types();
|
|
10142
10174
|
init_config2();
|
|
10143
10175
|
init_projects();
|
|
10176
|
+
init_database();
|
|
10144
10177
|
});
|
|
10145
10178
|
|
|
10146
10179
|
// src/lib/event-emission-safety.ts
|
|
@@ -12318,13 +12351,17 @@ function logDelivery(d, webhookId, event, payload, statusCode, response, attempt
|
|
|
12318
12351
|
const id = uuid();
|
|
12319
12352
|
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()]);
|
|
12320
12353
|
}
|
|
12321
|
-
function matchesScope(wh, payload) {
|
|
12354
|
+
function matchesScope(wh, payload, db) {
|
|
12322
12355
|
if (wh.project_id && payload.project_id !== wh.project_id)
|
|
12323
12356
|
return false;
|
|
12324
12357
|
if (wh.task_list_id && payload.task_list_id !== wh.task_list_id)
|
|
12325
12358
|
return false;
|
|
12326
|
-
if (wh.agent_id && payload.agent_id !== wh.agent_id
|
|
12327
|
-
|
|
12359
|
+
if (wh.agent_id && payload.agent_id !== wh.agent_id) {
|
|
12360
|
+
const aliasSet = assignedToAliasSet(db, wh.agent_id);
|
|
12361
|
+
const assignedTo = typeof payload.assigned_to === "string" ? payload.assigned_to.toLowerCase() : "";
|
|
12362
|
+
if (!aliasSet.has(assignedTo))
|
|
12363
|
+
return false;
|
|
12364
|
+
}
|
|
12328
12365
|
if (wh.task_id && payload.id !== wh.task_id)
|
|
12329
12366
|
return false;
|
|
12330
12367
|
return true;
|
|
@@ -12391,7 +12428,7 @@ async function dispatchWebhook2(event, payload, db) {
|
|
|
12391
12428
|
const webhooks = listWebhooks(d).filter((w) => w.active && (w.events.length === 0 || w.events.includes(event)));
|
|
12392
12429
|
const payloadObj = typeof payload === "object" && payload !== null ? payload : {};
|
|
12393
12430
|
for (const wh of webhooks) {
|
|
12394
|
-
if (!matchesScope(wh, payloadObj))
|
|
12431
|
+
if (!matchesScope(wh, payloadObj, d))
|
|
12395
12432
|
continue;
|
|
12396
12433
|
const body = JSON.stringify({ event, payload, timestamp: now() });
|
|
12397
12434
|
deliverWebhook(wh, event, body, 1, d).catch((err) => {
|
|
@@ -13463,14 +13500,16 @@ function getNextTask2(agentId, filters, db) {
|
|
|
13463
13500
|
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')");
|
|
13464
13501
|
const where = conditions.join(" AND ");
|
|
13465
13502
|
let recentProjectIds = [];
|
|
13503
|
+
const assignedAliasParams = [];
|
|
13504
|
+
const assignedInClause = agentId ? lowerInClause("assigned_to", resolveAssignedToAliases(d, agentId), assignedAliasParams) : "";
|
|
13466
13505
|
if (agentId) {
|
|
13467
|
-
const recentRows = d.query(`SELECT DISTINCT project_id FROM tasks WHERE
|
|
13506
|
+
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);
|
|
13468
13507
|
recentProjectIds = recentRows.map((r) => r.project_id);
|
|
13469
13508
|
}
|
|
13470
13509
|
let sql = `SELECT * FROM tasks WHERE ${where} ORDER BY `;
|
|
13471
13510
|
if (agentId) {
|
|
13472
|
-
sql += `CASE WHEN
|
|
13473
|
-
params.push(
|
|
13511
|
+
sql += `CASE WHEN ${assignedInClause} THEN 0 WHEN assigned_to IS NULL THEN 1 ELSE 2 END, `;
|
|
13512
|
+
params.push(...assignedAliasParams);
|
|
13474
13513
|
}
|
|
13475
13514
|
if (recentProjectIds.length > 0) {
|
|
13476
13515
|
const placeholders = recentProjectIds.map(() => "?").join(",");
|
|
@@ -13864,30 +13903,6 @@ function getTaskWithRelations(id, db) {
|
|
|
13864
13903
|
checklist
|
|
13865
13904
|
};
|
|
13866
13905
|
}
|
|
13867
|
-
function resolveAssignedToAliases(db, ref) {
|
|
13868
|
-
const aliases = new Set([ref]);
|
|
13869
|
-
let agentId;
|
|
13870
|
-
try {
|
|
13871
|
-
agentId = resolvePartialId(db, "agents", ref);
|
|
13872
|
-
} catch (err) {
|
|
13873
|
-
if (!(err instanceof IdentityAliasAmbiguousError))
|
|
13874
|
-
throw err;
|
|
13875
|
-
agentId = null;
|
|
13876
|
-
}
|
|
13877
|
-
if (agentId) {
|
|
13878
|
-
aliases.add(agentId);
|
|
13879
|
-
const row = db.query("SELECT name FROM agents WHERE id = ?").get(agentId);
|
|
13880
|
-
if (row?.name)
|
|
13881
|
-
aliases.add(row.name);
|
|
13882
|
-
}
|
|
13883
|
-
return [...aliases];
|
|
13884
|
-
}
|
|
13885
|
-
function lowerInClause(column, values, params) {
|
|
13886
|
-
if (values.length === 0)
|
|
13887
|
-
return "1=0";
|
|
13888
|
-
params.push(...values.map((v) => v.toLowerCase()));
|
|
13889
|
-
return `LOWER(${column}) IN (${values.map(() => "?").join(",")})`;
|
|
13890
|
-
}
|
|
13891
13906
|
function listTasks2(filter = {}, db) {
|
|
13892
13907
|
const d = db || getDatabase();
|
|
13893
13908
|
const { clearExpiredLocks: clearExpiredLocks2 } = (init_database(), __toCommonJS(exports_database));
|
|
@@ -14360,6 +14375,7 @@ function deleteTask(id, db) {
|
|
|
14360
14375
|
var init_task_crud = __esm(() => {
|
|
14361
14376
|
init_types();
|
|
14362
14377
|
init_database();
|
|
14378
|
+
init_database();
|
|
14363
14379
|
init_completion_guard();
|
|
14364
14380
|
init_event_emission_safety();
|
|
14365
14381
|
init_event_hooks();
|
|
@@ -14522,8 +14538,8 @@ function getTaskStats(filters, db) {
|
|
|
14522
14538
|
params.push(filters.task_list_id);
|
|
14523
14539
|
}
|
|
14524
14540
|
if (filters?.agent_id) {
|
|
14525
|
-
|
|
14526
|
-
|
|
14541
|
+
params.push(filters.agent_id);
|
|
14542
|
+
conditions.push(`(agent_id = ? OR ${lowerInClause("assigned_to", resolveAssignedToAliases(d, filters.agent_id), params)})`);
|
|
14527
14543
|
}
|
|
14528
14544
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
14529
14545
|
const totalRow = d.query(`SELECT COUNT(*) as count FROM tasks ${where}`).get(...params);
|
|
@@ -14706,8 +14722,7 @@ function getEscalatedTasks(opts = {}, db, at = new Date) {
|
|
|
14706
14722
|
params.push(opts.project_id);
|
|
14707
14723
|
}
|
|
14708
14724
|
if (opts.agent_id) {
|
|
14709
|
-
conditions.push("assigned_to
|
|
14710
|
-
params.push(opts.agent_id);
|
|
14725
|
+
conditions.push(lowerInClause("assigned_to", resolveAssignedToAliases(d, opts.agent_id), params));
|
|
14711
14726
|
}
|
|
14712
14727
|
const rows = d.query(`SELECT * FROM tasks WHERE ${conditions.join(" AND ")} ORDER BY due_at ASC, created_at ASC`).all(...params);
|
|
14713
14728
|
return rows.map(rowToTask).map((task) => {
|
|
@@ -14755,8 +14770,7 @@ function notifyUpcomingDeadlines(opts = {}, db) {
|
|
|
14755
14770
|
params.push(opts.project_id);
|
|
14756
14771
|
}
|
|
14757
14772
|
if (opts.agent_id) {
|
|
14758
|
-
conditions.push("assigned_to
|
|
14759
|
-
params.push(opts.agent_id);
|
|
14773
|
+
conditions.push(lowerInClause("assigned_to", resolveAssignedToAliases(d, opts.agent_id), params));
|
|
14760
14774
|
}
|
|
14761
14775
|
const rows = d.query(`SELECT * FROM tasks WHERE ${conditions.join(" AND ")} ORDER BY due_at ASC`).all(...params);
|
|
14762
14776
|
return rows.map(rowToTask);
|
|
@@ -15014,13 +15028,14 @@ function getTimeReport(opts, db) {
|
|
|
15014
15028
|
params.push(opts.plan_id);
|
|
15015
15029
|
}
|
|
15016
15030
|
if (opts?.agent_id) {
|
|
15031
|
+
const assignedInClause = lowerInClause("t.assigned_to", resolveAssignedToAliases(d, opts.agent_id), params);
|
|
15017
15032
|
conditions.push(`(
|
|
15018
|
-
|
|
15033
|
+
${assignedInClause}
|
|
15019
15034
|
OR t.agent_id = ?
|
|
15020
15035
|
OR EXISTS (SELECT 1 FROM task_time_logs ttl WHERE ttl.task_id = t.id AND ttl.agent_id = ?)
|
|
15021
15036
|
OR EXISTS (SELECT 1 FROM focus_sessions fs WHERE fs.task_id = t.id AND fs.agent_id = ?)
|
|
15022
15037
|
)`);
|
|
15023
|
-
params.push(opts.agent_id, opts.agent_id, opts.agent_id
|
|
15038
|
+
params.push(opts.agent_id, opts.agent_id, opts.agent_id);
|
|
15024
15039
|
}
|
|
15025
15040
|
if (opts?.since) {
|
|
15026
15041
|
conditions.push("(t.completed_at >= ? OR t.updated_at >= ?)");
|
|
@@ -16016,7 +16031,7 @@ function listActiveFiles(db) {
|
|
|
16016
16031
|
a.name AS agent_name
|
|
16017
16032
|
FROM task_files tf
|
|
16018
16033
|
JOIN tasks t ON tf.task_id = t.id
|
|
16019
|
-
LEFT JOIN agents a ON (tf.agent_id = a.id OR (tf.agent_id IS NULL AND t.assigned_to = a.id))
|
|
16034
|
+
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))))
|
|
16020
16035
|
WHERE t.status = 'in_progress'
|
|
16021
16036
|
AND tf.status != 'removed'
|
|
16022
16037
|
ORDER BY tf.updated_at DESC
|
|
@@ -19048,8 +19063,9 @@ async function handleAgentMe(_req, url, _ctx, json2, taskToSummary2) {
|
|
|
19048
19063
|
}
|
|
19049
19064
|
}
|
|
19050
19065
|
function handleAgentQueue(agentId, _ctx, json2, taskToSummary2) {
|
|
19066
|
+
const aliasSet = assignedToAliasSet(getDatabase(), agentId);
|
|
19051
19067
|
const pending = listTasks2({ status: "pending" });
|
|
19052
|
-
const queue = pending.filter((t) => t.assigned_to
|
|
19068
|
+
const queue = pending.filter((t) => aliasSet.has((t.assigned_to ?? "").toLowerCase()) || t.agent_id === agentId || !t.assigned_to && !t.locked_by);
|
|
19053
19069
|
const order = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
19054
19070
|
queue.sort((a, b) => (order[a.priority] ?? 4) - (order[b.priority] ?? 4) || new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
19055
19071
|
return json2(queue.map((t) => taskToSummary2(t)));
|
|
@@ -19441,8 +19457,7 @@ function searchTasks(options, projectId, taskListId, db) {
|
|
|
19441
19457
|
}
|
|
19442
19458
|
}
|
|
19443
19459
|
if (opts.assigned_to) {
|
|
19444
|
-
sql +=
|
|
19445
|
-
params.push(opts.assigned_to);
|
|
19460
|
+
sql += ` AND ${lowerInClause("t.assigned_to", resolveAssignedToAliases(d, opts.assigned_to), params)}`;
|
|
19446
19461
|
}
|
|
19447
19462
|
if (opts.agent_id) {
|
|
19448
19463
|
sql += " AND t.agent_id = ?";
|
|
@@ -60747,11 +60762,12 @@ function runAlerts(input, db, checkedAt, quieted) {
|
|
|
60747
60762
|
if (input.include_runs === false)
|
|
60748
60763
|
return [];
|
|
60749
60764
|
const since = Date.parse(input.run_since || new Date(Date.parse(checkedAt) - 24 * 60 * 60000).toISOString());
|
|
60765
|
+
const runAlertAliases = input.agent_id ? assignedToAliasSet(db, input.agent_id) : null;
|
|
60750
60766
|
return listTaskRuns(undefined, db).filter((run) => run.completed_at && Date.parse(run.completed_at) >= since).map((run) => {
|
|
60751
60767
|
const task = getTask(run.task_id, db);
|
|
60752
60768
|
if (input.project_id && task?.project_id !== input.project_id)
|
|
60753
60769
|
return null;
|
|
60754
|
-
if (input.agent_id && run.agent_id !== input.agent_id && task?.assigned_to
|
|
60770
|
+
if (input.agent_id && run.agent_id !== input.agent_id && !(runAlertAliases && runAlertAliases.has((task?.assigned_to ?? "").toLowerCase())))
|
|
60755
60771
|
return null;
|
|
60756
60772
|
const failed = ["failed", "cancelled"].includes(run.status);
|
|
60757
60773
|
return {
|
|
@@ -60796,6 +60812,7 @@ async function checkLocalNotifications(input = {}, db) {
|
|
|
60796
60812
|
const warnings = [];
|
|
60797
60813
|
if (Number.isNaN(checkedMs))
|
|
60798
60814
|
warnings.push("Invalid check timestamp; due-soon window may be incomplete.");
|
|
60815
|
+
const notifyAgentAliases = input.agent_id ? assignedToAliasSet(d, input.agent_id) : null;
|
|
60799
60816
|
const alerts = [];
|
|
60800
60817
|
for (const escalation of getEscalatedTasks({ project_id: input.project_id, agent_id: input.agent_id }, d, new Date(checkedAt))) {
|
|
60801
60818
|
for (const reason of escalation.reasons) {
|
|
@@ -60807,7 +60824,7 @@ async function checkLocalNotifications(input = {}, db) {
|
|
|
60807
60824
|
for (const task of listTasks2({ project_id: input.project_id, include_archived: false, limit: 5000 }, d)) {
|
|
60808
60825
|
if (!unfinished(task) || !task.due_at)
|
|
60809
60826
|
continue;
|
|
60810
|
-
if (input.agent_id && task.
|
|
60827
|
+
if (input.agent_id && task.agent_id !== input.agent_id && !(notifyAgentAliases && notifyAgentAliases.has((task.assigned_to ?? "").toLowerCase())))
|
|
60811
60828
|
continue;
|
|
60812
60829
|
if (task.due_at > checkedAt && task.due_at <= dueSoonUntil) {
|
|
60813
60830
|
alerts.push(taskAlert(task, "task_due_soon", "task.due_soon", "warning", `Due soon: ${task.title}`, task.due_at, quieted));
|
|
@@ -60815,7 +60832,7 @@ async function checkLocalNotifications(input = {}, db) {
|
|
|
60815
60832
|
}
|
|
60816
60833
|
}
|
|
60817
60834
|
for (const task of getStaleTasks(staleMinutes, { project_id: input.project_id }, d)) {
|
|
60818
|
-
if (input.agent_id && task.
|
|
60835
|
+
if (input.agent_id && task.agent_id !== input.agent_id && !(notifyAgentAliases && notifyAgentAliases.has((task.assigned_to ?? "").toLowerCase())))
|
|
60819
60836
|
continue;
|
|
60820
60837
|
alerts.push(taskAlert(task, "task_stale", "task.stale", "warning", `Stale task: ${task.title}`, checkedAt, quieted, { stale_minutes: staleMinutes }));
|
|
60821
60838
|
}
|
|
@@ -62835,10 +62852,12 @@ function matchesProfile(profile, query) {
|
|
|
62835
62852
|
return false;
|
|
62836
62853
|
return true;
|
|
62837
62854
|
}
|
|
62838
|
-
function taskMatchesAgent(task, agentId) {
|
|
62855
|
+
function taskMatchesAgent(task, agentId, aliasSet) {
|
|
62839
62856
|
if (!agentId)
|
|
62840
62857
|
return true;
|
|
62841
|
-
|
|
62858
|
+
if (task.agent_id === agentId)
|
|
62859
|
+
return true;
|
|
62860
|
+
return aliasSet ? aliasSet.has((task.assigned_to ?? "").toLowerCase()) : task.assigned_to === agentId;
|
|
62842
62861
|
}
|
|
62843
62862
|
function estimateRemaining(task) {
|
|
62844
62863
|
if (task.status === "completed" || task.status === "cancelled")
|
|
@@ -62908,7 +62927,8 @@ function removeCapacityProfile(idOrAgent, projectId) {
|
|
|
62908
62927
|
}
|
|
62909
62928
|
function getPlanningForecast(input = {}, db) {
|
|
62910
62929
|
const startDate = input.start_date ? dateOnly(input.start_date) : todayIso();
|
|
62911
|
-
const
|
|
62930
|
+
const aliasSet = input.agent_id ? assignedToAliasSet(db || getDatabase(), input.agent_id) : undefined;
|
|
62931
|
+
const tasks = listTasks2({ project_id: input.project_id, plan_id: input.plan_id, limit: 1e4 }, db).filter((task) => taskMatchesAgent(task, input.agent_id, aliasSet));
|
|
62912
62932
|
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]));
|
|
62913
62933
|
const profiles = listCapacityProfiles({ agent_id: input.agent_id, project_id: input.project_id });
|
|
62914
62934
|
const globalProfiles = input.project_id ? listCapacityProfiles({ agent_id: input.agent_id }).filter((profile) => profile.project_id === null) : [];
|
|
@@ -63006,6 +63026,7 @@ function renderPlanningForecastMarkdown(forecast) {
|
|
|
63006
63026
|
}
|
|
63007
63027
|
var LOCAL_CAPACITY_SCHEMA_VERSION = 1;
|
|
63008
63028
|
var init_capacity_forecasts = __esm(() => {
|
|
63029
|
+
init_database();
|
|
63009
63030
|
init_tasks();
|
|
63010
63031
|
init_task_relations();
|
|
63011
63032
|
init_config2();
|
|
@@ -66439,8 +66460,10 @@ function getLatestHandoff(agentId, projectId, db) {
|
|
|
66439
66460
|
function createSessionRecoveryHandoff(input, db) {
|
|
66440
66461
|
const d = db || getDatabase();
|
|
66441
66462
|
const limit = input.limit || 20;
|
|
66442
|
-
const
|
|
66443
|
-
const
|
|
66463
|
+
const params = [];
|
|
66464
|
+
const assignedInClause = lowerInClause("assigned_to", resolveAssignedToAliases(d, input.agent_id), params);
|
|
66465
|
+
const conditions = ["status = 'in_progress'", `(${assignedInClause} OR agent_id = ? OR locked_by = ?)`];
|
|
66466
|
+
params.push(input.agent_id, input.agent_id);
|
|
66444
66467
|
if (input.session_id) {
|
|
66445
66468
|
conditions.push("session_id = ?");
|
|
66446
66469
|
params.push(input.session_id);
|
|
@@ -67032,7 +67055,8 @@ function registerTaskAutoTools(server, ctx) {
|
|
|
67032
67055
|
const assigned = listTasks4({ assigned_to: effectiveAgentId, limit: 500 }, undefined);
|
|
67033
67056
|
const now4 = Date.now();
|
|
67034
67057
|
const dueSoonCutoff = now4 + 24 * 60 * 60 * 1000;
|
|
67035
|
-
const
|
|
67058
|
+
const blockedAliases = assignedToAliasSet(getDatabase(), effectiveAgentId);
|
|
67059
|
+
const blocked = getBlockedTasks2().filter((t) => blockedAliases.has((t.assigned_to ?? "").toLowerCase()));
|
|
67036
67060
|
const workload = {
|
|
67037
67061
|
in_progress: assigned.filter((t) => t.status === "in_progress").length,
|
|
67038
67062
|
pending: assigned.filter((t) => t.status === "pending").length,
|
|
@@ -67069,17 +67093,25 @@ function registerTaskAutoTools(server, ctx) {
|
|
|
67069
67093
|
if (agents.length === 0)
|
|
67070
67094
|
return { content: [{ type: "text", text: "No active agents available for rebalancing." }] };
|
|
67071
67095
|
const activeTasks = listTasks4({ project_id: resolvedProjectId, status: ["pending", "in_progress"], limit: 1000 }, undefined);
|
|
67072
|
-
const
|
|
67096
|
+
const agentKeyByAlias = new Map;
|
|
67097
|
+
for (const agent of agents) {
|
|
67098
|
+
agentKeyByAlias.set(String(agent.id).toLowerCase(), agent.id);
|
|
67099
|
+
if (agent.name)
|
|
67100
|
+
agentKeyByAlias.set(String(agent.name).toLowerCase(), agent.id);
|
|
67101
|
+
}
|
|
67102
|
+
const canonicalAgentKey = (assignedTo) => assignedTo ? agentKeyByAlias.get(assignedTo.toLowerCase()) : undefined;
|
|
67103
|
+
const load = new Map(agents.map((agent) => [agent.id, activeTasks.filter((t) => canonicalAgentKey(t.assigned_to) === agent.id).length]));
|
|
67073
67104
|
let moved = 0;
|
|
67074
67105
|
let skipped = 0;
|
|
67075
|
-
for (const task of activeTasks.filter((t) => t.status === "pending" && t.assigned_to && (load.get(t.assigned_to) ?? 0) > limit)) {
|
|
67076
|
-
const
|
|
67106
|
+
for (const task of activeTasks.filter((t) => t.status === "pending" && canonicalAgentKey(t.assigned_to) && (load.get(canonicalAgentKey(t.assigned_to)) ?? 0) > limit)) {
|
|
67107
|
+
const currentAgentKey = canonicalAgentKey(task.assigned_to);
|
|
67108
|
+
const target = agents.filter((agent) => agent.id !== currentAgentKey).sort((a, b) => (load.get(a.id) ?? 0) - (load.get(b.id) ?? 0))[0];
|
|
67077
67109
|
if (!target || (load.get(target.id) ?? 0) >= limit) {
|
|
67078
67110
|
skipped++;
|
|
67079
67111
|
continue;
|
|
67080
67112
|
}
|
|
67081
67113
|
updateTask3(task.id, { assigned_to: target.id, version: task.version });
|
|
67082
|
-
load.set(
|
|
67114
|
+
load.set(currentAgentKey, (load.get(currentAgentKey) ?? 1) - 1);
|
|
67083
67115
|
load.set(target.id, (load.get(target.id) ?? 0) + 1);
|
|
67084
67116
|
moved++;
|
|
67085
67117
|
}
|
|
@@ -67258,6 +67290,7 @@ ${lines.join(`
|
|
|
67258
67290
|
var init_task_auto_tools = __esm(() => {
|
|
67259
67291
|
init_zod();
|
|
67260
67292
|
init_cloud_router();
|
|
67293
|
+
init_database();
|
|
67261
67294
|
});
|
|
67262
67295
|
|
|
67263
67296
|
// src/lib/context-packs.ts
|
|
@@ -68437,7 +68470,8 @@ ${JSON.stringify(task.metadata, null, 2)}` : null
|
|
|
68437
68470
|
}, undefined);
|
|
68438
68471
|
const completedYesterday = completed.filter((t) => t.completed_at && t.completed_at.startsWith(yesterdayStr));
|
|
68439
68472
|
const { getBlockedTasks: getBlockedTasks2 } = (init_tasks(), __toCommonJS(exports_tasks));
|
|
68440
|
-
const
|
|
68473
|
+
const blockedAliases = effectiveAgentId ? assignedToAliasSet(getDatabase(), effectiveAgentId) : null;
|
|
68474
|
+
const blocked = getBlockedTasks2(effectiveProjectId ? resolveId(effectiveProjectId, "projects") : undefined).filter((t) => blockedAliases ? blockedAliases.has((t.assigned_to ?? "").toLowerCase()) : false);
|
|
68441
68475
|
const lines = [
|
|
68442
68476
|
`Standup for ${effectiveAgentId} (${effectiveProjectId ? `project: ${effectiveProjectId.slice(0, 8)}` : "all projects"})`,
|
|
68443
68477
|
inProgress.length > 0 ? `
|
|
@@ -68665,6 +68699,7 @@ var init_task_adv_tools = __esm(() => {
|
|
|
68665
68699
|
init_zod();
|
|
68666
68700
|
init_token_utils();
|
|
68667
68701
|
init_cloud_router();
|
|
68702
|
+
init_database();
|
|
68668
68703
|
});
|
|
68669
68704
|
|
|
68670
68705
|
// node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/util.cjs
|
|
@@ -94356,27 +94391,29 @@ function getAgentMetrics(agentId, opts, db) {
|
|
|
94356
94391
|
const agent = d.query("SELECT id, name FROM agents WHERE id = ? OR LOWER(name) = LOWER(?)").get(agentId, agentId);
|
|
94357
94392
|
if (!agent)
|
|
94358
94393
|
return null;
|
|
94394
|
+
const assignedAliases = resolveAssignedToAliases(d, agent.id).map((a) => a.toLowerCase());
|
|
94395
|
+
const assignedInClause = `LOWER(assigned_to) IN (${assignedAliases.map(() => "?").join(",")})`;
|
|
94359
94396
|
let projectFilter = "";
|
|
94360
|
-
const params = [agent.id,
|
|
94397
|
+
const params = [agent.id, ...assignedAliases];
|
|
94361
94398
|
if (opts?.project_id) {
|
|
94362
94399
|
projectFilter = " AND project_id = ?";
|
|
94363
94400
|
params.push(opts.project_id);
|
|
94364
94401
|
}
|
|
94365
|
-
const completed = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR
|
|
94366
|
-
const failed = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR
|
|
94367
|
-
const inProgress = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR
|
|
94402
|
+
const completed = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'completed'${projectFilter}`).get(...params).count;
|
|
94403
|
+
const failed = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'failed'${projectFilter}`).get(...params).count;
|
|
94404
|
+
const inProgress = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'in_progress'${projectFilter}`).get(...params).count;
|
|
94368
94405
|
const total = completed + failed;
|
|
94369
94406
|
const completionRate = total > 0 ? completed / total : 0;
|
|
94370
94407
|
const avgTime = d.query(`SELECT AVG(
|
|
94371
94408
|
(julianday(completed_at) - julianday(created_at)) * 24 * 60
|
|
94372
94409
|
) as avg_minutes
|
|
94373
94410
|
FROM tasks
|
|
94374
|
-
WHERE (agent_id = ? OR
|
|
94411
|
+
WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'completed' AND completed_at IS NOT NULL${projectFilter}`).get(...params);
|
|
94375
94412
|
const avgConf = d.query(`SELECT AVG(confidence) as avg_confidence
|
|
94376
94413
|
FROM tasks
|
|
94377
|
-
WHERE (agent_id = ? OR
|
|
94414
|
+
WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'completed' AND confidence IS NOT NULL${projectFilter}`).get(...params);
|
|
94378
94415
|
const reviewTasks = d.query(`SELECT metadata FROM tasks
|
|
94379
|
-
WHERE (agent_id = ? OR
|
|
94416
|
+
WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'completed'${projectFilter}
|
|
94380
94417
|
AND metadata LIKE '%_review_score%'`).all(...params);
|
|
94381
94418
|
let reviewScoreAvg = null;
|
|
94382
94419
|
if (reviewTasks.length > 0) {
|
|
@@ -94840,14 +94877,15 @@ function millisBetween(start, end) {
|
|
|
94840
94877
|
return 0;
|
|
94841
94878
|
return endMs - startMs;
|
|
94842
94879
|
}
|
|
94843
|
-
function addTaskScope(where, params, options, alias = "t") {
|
|
94880
|
+
function addTaskScope(where, params, options, db, alias = "t") {
|
|
94844
94881
|
if (options.project_id) {
|
|
94845
94882
|
where.push(`${alias}.project_id = ?`);
|
|
94846
94883
|
params.push(options.project_id);
|
|
94847
94884
|
}
|
|
94848
94885
|
if (options.agent_id) {
|
|
94849
|
-
|
|
94850
|
-
|
|
94886
|
+
params.push(options.agent_id);
|
|
94887
|
+
const assignedInClause = lowerInClause(`${alias}.assigned_to`, resolveAssignedToAliases(db, options.agent_id), params);
|
|
94888
|
+
where.push(`(${alias}.agent_id = ? OR ${assignedInClause})`);
|
|
94851
94889
|
}
|
|
94852
94890
|
if (options.since) {
|
|
94853
94891
|
where.push(`${alias}.created_at >= ?`);
|
|
@@ -94858,14 +94896,15 @@ function addTaskScope(where, params, options, alias = "t") {
|
|
|
94858
94896
|
params.push(options.until);
|
|
94859
94897
|
}
|
|
94860
94898
|
}
|
|
94861
|
-
function addRunScope(where, params, options, runAlias = "r", taskAlias = "t") {
|
|
94899
|
+
function addRunScope(where, params, options, db, runAlias = "r", taskAlias = "t") {
|
|
94862
94900
|
if (options.project_id) {
|
|
94863
94901
|
where.push(`${taskAlias}.project_id = ?`);
|
|
94864
94902
|
params.push(options.project_id);
|
|
94865
94903
|
}
|
|
94866
94904
|
if (options.agent_id) {
|
|
94867
|
-
|
|
94868
|
-
|
|
94905
|
+
params.push(options.agent_id, options.agent_id);
|
|
94906
|
+
const assignedInClause = lowerInClause(`${taskAlias}.assigned_to`, resolveAssignedToAliases(db, options.agent_id), params);
|
|
94907
|
+
where.push(`(${runAlias}.agent_id = ? OR ${taskAlias}.agent_id = ? OR ${assignedInClause})`);
|
|
94869
94908
|
}
|
|
94870
94909
|
if (options.since) {
|
|
94871
94910
|
where.push(`${runAlias}.started_at >= ?`);
|
|
@@ -94876,14 +94915,15 @@ function addRunScope(where, params, options, runAlias = "r", taskAlias = "t") {
|
|
|
94876
94915
|
params.push(options.until);
|
|
94877
94916
|
}
|
|
94878
94917
|
}
|
|
94879
|
-
function addTraceScope(where, params, options, traceAlias = "tr", taskAlias = "t") {
|
|
94918
|
+
function addTraceScope(where, params, options, db, traceAlias = "tr", taskAlias = "t") {
|
|
94880
94919
|
if (options.project_id) {
|
|
94881
94920
|
where.push(`${taskAlias}.project_id = ?`);
|
|
94882
94921
|
params.push(options.project_id);
|
|
94883
94922
|
}
|
|
94884
94923
|
if (options.agent_id) {
|
|
94885
|
-
|
|
94886
|
-
|
|
94924
|
+
params.push(options.agent_id, options.agent_id);
|
|
94925
|
+
const assignedInClause = lowerInClause(`${taskAlias}.assigned_to`, resolveAssignedToAliases(db, options.agent_id), params);
|
|
94926
|
+
where.push(`(${traceAlias}.agent_id = ? OR ${taskAlias}.agent_id = ? OR ${assignedInClause})`);
|
|
94887
94927
|
}
|
|
94888
94928
|
if (options.since) {
|
|
94889
94929
|
where.push(`${traceAlias}.created_at >= ?`);
|
|
@@ -94943,7 +94983,7 @@ function createLocalUsageLedger(options = {}, db) {
|
|
|
94943
94983
|
const generatedAt = options.generated_at || new Date().toISOString();
|
|
94944
94984
|
const taskWhere = [];
|
|
94945
94985
|
const taskParams = [];
|
|
94946
|
-
addTaskScope(taskWhere, taskParams, options);
|
|
94986
|
+
addTaskScope(taskWhere, taskParams, options, d);
|
|
94947
94987
|
const taskClause = taskWhere.length ? `WHERE ${taskWhere.join(" AND ")}` : "";
|
|
94948
94988
|
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);
|
|
94949
94989
|
let projectCount = 0;
|
|
@@ -94952,14 +94992,14 @@ function createLocalUsageLedger(options = {}, db) {
|
|
|
94952
94992
|
} else if (options.agent_id) {
|
|
94953
94993
|
const projectWhere = ["t.project_id IS NOT NULL"];
|
|
94954
94994
|
const projectParams = [];
|
|
94955
|
-
addTaskScope(projectWhere, projectParams, options);
|
|
94995
|
+
addTaskScope(projectWhere, projectParams, options, d);
|
|
94956
94996
|
projectCount = queryOne(d, `SELECT COUNT(DISTINCT t.project_id) as count FROM tasks t WHERE ${projectWhere.join(" AND ")}`, projectParams).count;
|
|
94957
94997
|
} else {
|
|
94958
94998
|
projectCount = queryOne(d, "SELECT COUNT(*) as count FROM projects", []).count;
|
|
94959
94999
|
}
|
|
94960
95000
|
const runWhere = [];
|
|
94961
95001
|
const runParams = [];
|
|
94962
|
-
addRunScope(runWhere, runParams, options);
|
|
95002
|
+
addRunScope(runWhere, runParams, options, d);
|
|
94963
95003
|
const runClause = runWhere.length ? `WHERE ${runWhere.join(" AND ")}` : "";
|
|
94964
95004
|
const runs = queryAll(d, `SELECT r.id, r.started_at, r.completed_at, r.metadata
|
|
94965
95005
|
FROM task_runs r JOIN tasks t ON t.id = r.task_id
|
|
@@ -94976,7 +95016,7 @@ function createLocalUsageLedger(options = {}, db) {
|
|
|
94976
95016
|
${runClause}`, runParams);
|
|
94977
95017
|
const traceWhere = [];
|
|
94978
95018
|
const traceParams = [];
|
|
94979
|
-
addTraceScope(traceWhere, traceParams, options);
|
|
95019
|
+
addTraceScope(traceWhere, traceParams, options, d);
|
|
94980
95020
|
const traceClause = traceWhere.length ? `WHERE ${traceWhere.join(" AND ")}` : "";
|
|
94981
95021
|
const traceTotals = queryOne(d, `SELECT COUNT(*) as traces,
|
|
94982
95022
|
COALESCE(SUM(tr.tokens), 0) as tokens,
|
|
@@ -95120,10 +95160,12 @@ function limitValue(value) {
|
|
|
95120
95160
|
function isTerminal2(task) {
|
|
95121
95161
|
return task.status === "completed" || task.status === "failed" || task.status === "cancelled";
|
|
95122
95162
|
}
|
|
95123
|
-
function sameAgent(task, agentId) {
|
|
95163
|
+
function sameAgent(task, agentId, aliasSet) {
|
|
95124
95164
|
if (!agentId)
|
|
95125
95165
|
return true;
|
|
95126
|
-
|
|
95166
|
+
if (task.agent_id === agentId)
|
|
95167
|
+
return true;
|
|
95168
|
+
return aliasSet ? aliasSet.has((task.assigned_to ?? "").toLowerCase()) : task.assigned_to === agentId;
|
|
95127
95169
|
}
|
|
95128
95170
|
function withinTaskWindow(task, options) {
|
|
95129
95171
|
const time3 = Date.parse(task.updated_at);
|
|
@@ -95136,11 +95178,12 @@ function withinTaskWindow(task, options) {
|
|
|
95136
95178
|
return true;
|
|
95137
95179
|
}
|
|
95138
95180
|
function scopedTasks(options, db) {
|
|
95181
|
+
const aliasSet = options.agent_id ? assignedToAliasSet(db, options.agent_id) : undefined;
|
|
95139
95182
|
return listTasks2({
|
|
95140
95183
|
project_id: options.project_id,
|
|
95141
95184
|
plan_id: options.plan_id,
|
|
95142
95185
|
include_archived: false
|
|
95143
|
-
}, db).filter((task) => sameAgent(task, options.agent_id) && withinTaskWindow(task, options));
|
|
95186
|
+
}, db).filter((task) => sameAgent(task, options.agent_id, aliasSet) && withinTaskWindow(task, options));
|
|
95144
95187
|
}
|
|
95145
95188
|
function summarizeTask(task) {
|
|
95146
95189
|
return {
|
|
@@ -95206,7 +95249,7 @@ function initialAgentSummary(agentId) {
|
|
|
95206
95249
|
}
|
|
95207
95250
|
};
|
|
95208
95251
|
}
|
|
95209
|
-
function addScopeClauses(where, params, options, timeColumn) {
|
|
95252
|
+
function addScopeClauses(where, params, options, timeColumn, db) {
|
|
95210
95253
|
if (options.project_id) {
|
|
95211
95254
|
where.push("t.project_id = ?");
|
|
95212
95255
|
params.push(options.project_id);
|
|
@@ -95216,8 +95259,9 @@ function addScopeClauses(where, params, options, timeColumn) {
|
|
|
95216
95259
|
params.push(options.plan_id);
|
|
95217
95260
|
}
|
|
95218
95261
|
if (options.agent_id) {
|
|
95219
|
-
|
|
95220
|
-
|
|
95262
|
+
params.push(options.agent_id, options.agent_id);
|
|
95263
|
+
const assignedInClause = lowerInClause("t.assigned_to", resolveAssignedToAliases(db, options.agent_id), params);
|
|
95264
|
+
where.push(`(r.agent_id = ? OR t.agent_id = ? OR ${assignedInClause})`);
|
|
95221
95265
|
}
|
|
95222
95266
|
if (options.since) {
|
|
95223
95267
|
where.push(`${timeColumn} >= ?`);
|
|
@@ -95231,7 +95275,7 @@ function addScopeClauses(where, params, options, timeColumn) {
|
|
|
95231
95275
|
function loadRuns(options, db) {
|
|
95232
95276
|
const where = ["t.archived_at IS NULL"];
|
|
95233
95277
|
const params = [];
|
|
95234
|
-
addScopeClauses(where, params, options, "r.started_at");
|
|
95278
|
+
addScopeClauses(where, params, options, "r.started_at", db);
|
|
95235
95279
|
return db.query(`
|
|
95236
95280
|
SELECT
|
|
95237
95281
|
r.id,
|
|
@@ -95271,8 +95315,9 @@ function loadVerifications(options, db) {
|
|
|
95271
95315
|
params.push(options.plan_id);
|
|
95272
95316
|
}
|
|
95273
95317
|
if (options.agent_id) {
|
|
95274
|
-
|
|
95275
|
-
|
|
95318
|
+
params.push(options.agent_id, options.agent_id);
|
|
95319
|
+
const assignedInClause = lowerInClause("t.assigned_to", resolveAssignedToAliases(db, options.agent_id), params);
|
|
95320
|
+
where.push(`(v.agent_id = ? OR t.agent_id = ? OR ${assignedInClause})`);
|
|
95276
95321
|
}
|
|
95277
95322
|
if (options.since) {
|
|
95278
95323
|
where.push("v.run_at >= ?");
|
|
@@ -95494,7 +95539,6 @@ function renderLocalReportMarkdown(report) {
|
|
|
95494
95539
|
}
|
|
95495
95540
|
var LOCAL_REPORT_SCHEMA_VERSION = 1, LOCAL_REPORT_TYPES;
|
|
95496
95541
|
var init_local_reports = __esm(() => {
|
|
95497
|
-
init_database();
|
|
95498
95542
|
init_database();
|
|
95499
95543
|
init_plans();
|
|
95500
95544
|
init_tasks();
|
|
@@ -99597,7 +99641,7 @@ ${lines.join(`
|
|
|
99597
99641
|
a.name AS agent_name
|
|
99598
99642
|
FROM task_files tf
|
|
99599
99643
|
JOIN tasks t ON tf.task_id = t.id
|
|
99600
|
-
LEFT JOIN agents a ON (tf.agent_id = a.id OR (tf.agent_id IS NULL AND t.assigned_to = a.id))
|
|
99644
|
+
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))))
|
|
99601
99645
|
WHERE t.status = 'in_progress'
|
|
99602
99646
|
AND tf.status != 'removed'
|
|
99603
99647
|
AND t.project_id = ?
|
|
@@ -103361,7 +103405,7 @@ ${text2}` }] };
|
|
|
103361
103405
|
const oldName = agent.name;
|
|
103362
103406
|
const updated = updateAgent2(agent.id, { name: new_name });
|
|
103363
103407
|
const db = getDatabase();
|
|
103364
|
-
const tasksResult = db.run("UPDATE tasks SET assigned_to = ? WHERE assigned_to = ?", [new_name, oldName]);
|
|
103408
|
+
const tasksResult = db.run("UPDATE tasks SET assigned_to = ? WHERE LOWER(assigned_to) = LOWER(?)", [new_name, oldName]);
|
|
103365
103409
|
const taskNote = tasksResult.changes > 0 ? `
|
|
103366
103410
|
Updated assigned_to on ${tasksResult.changes} task(s).` : "";
|
|
103367
103411
|
return {
|