@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/mcp/index.js
CHANGED
|
@@ -4111,14 +4111,17 @@ var exports_database = {};
|
|
|
4111
4111
|
__export(exports_database, {
|
|
4112
4112
|
uuid: () => uuid,
|
|
4113
4113
|
resolvePartialId: () => resolvePartialId,
|
|
4114
|
+
resolveAssignedToAliases: () => resolveAssignedToAliases,
|
|
4114
4115
|
resetDatabase: () => resetDatabase,
|
|
4115
4116
|
now: () => now,
|
|
4117
|
+
lowerInClause: () => lowerInClause,
|
|
4116
4118
|
lockExpiryCutoff: () => lockExpiryCutoff,
|
|
4117
4119
|
isLockExpired: () => isLockExpired,
|
|
4118
4120
|
getDatabasePath: () => getDatabasePath,
|
|
4119
4121
|
getDatabase: () => getDatabase,
|
|
4120
4122
|
closeDatabase: () => closeDatabase,
|
|
4121
4123
|
clearExpiredLocks: () => clearExpiredLocks,
|
|
4124
|
+
assignedToAliasSet: () => assignedToAliasSet,
|
|
4122
4125
|
LOCK_EXPIRY_MINUTES: () => LOCK_EXPIRY_MINUTES
|
|
4123
4126
|
});
|
|
4124
4127
|
import { Database } from "bun:sqlite";
|
|
@@ -4347,6 +4350,33 @@ function resolvePartialId(db, table, partialId) {
|
|
|
4347
4350
|
}
|
|
4348
4351
|
return null;
|
|
4349
4352
|
}
|
|
4353
|
+
function resolveAssignedToAliases(db, ref) {
|
|
4354
|
+
const aliases = new Set([ref]);
|
|
4355
|
+
let agentId;
|
|
4356
|
+
try {
|
|
4357
|
+
agentId = resolvePartialId(db, "agents", ref);
|
|
4358
|
+
} catch (err) {
|
|
4359
|
+
if (!(err instanceof IdentityAliasAmbiguousError))
|
|
4360
|
+
throw err;
|
|
4361
|
+
agentId = null;
|
|
4362
|
+
}
|
|
4363
|
+
if (agentId) {
|
|
4364
|
+
aliases.add(agentId);
|
|
4365
|
+
const row = db.query("SELECT name FROM agents WHERE id = ?").get(agentId);
|
|
4366
|
+
if (row?.name)
|
|
4367
|
+
aliases.add(row.name);
|
|
4368
|
+
}
|
|
4369
|
+
return [...aliases];
|
|
4370
|
+
}
|
|
4371
|
+
function assignedToAliasSet(db, ref) {
|
|
4372
|
+
return new Set(resolveAssignedToAliases(db, ref).map((a) => a.toLowerCase()));
|
|
4373
|
+
}
|
|
4374
|
+
function lowerInClause(column, values, params) {
|
|
4375
|
+
if (values.length === 0)
|
|
4376
|
+
return "1=0";
|
|
4377
|
+
params.push(...values.map((v) => v.toLowerCase()));
|
|
4378
|
+
return `LOWER(${column}) IN (${values.map(() => "?").join(",")})`;
|
|
4379
|
+
}
|
|
4350
4380
|
var LOCK_EXPIRY_MINUTES = 30, _db = null, _dbPath = null, ALLOWED_TABLES;
|
|
4351
4381
|
var init_database = __esm(() => {
|
|
4352
4382
|
init_schema();
|
|
@@ -9991,17 +10021,19 @@ function checkCompletionGuard(task, agentId, db, configOverride) {
|
|
|
9991
10021
|
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);
|
|
9992
10022
|
}
|
|
9993
10023
|
}
|
|
10024
|
+
const assignedAliasParams = [];
|
|
10025
|
+
const assignedInClause = agent ? lowerInClause("assigned_to", resolveAssignedToAliases(db, agent), assignedAliasParams) : "";
|
|
9994
10026
|
if (agent && config.max_completions_per_window && config.window_minutes) {
|
|
9995
10027
|
const windowStart = new Date(Date.now() - config.window_minutes * 60 * 1000).toISOString();
|
|
9996
10028
|
const result = db.query(`SELECT COUNT(*) as count FROM tasks
|
|
9997
|
-
WHERE completed_at > ? AND (
|
|
10029
|
+
WHERE completed_at > ? AND (${assignedInClause} OR agent_id = ?)`).get(windowStart, ...assignedAliasParams, agent);
|
|
9998
10030
|
if (result.count >= config.max_completions_per_window) {
|
|
9999
10031
|
throw new CompletionGuardError(`Rate limit: ${result.count} tasks completed in the last ${config.window_minutes} minutes (max ${config.max_completions_per_window}). Slow down.`);
|
|
10000
10032
|
}
|
|
10001
10033
|
}
|
|
10002
10034
|
if (agent && config.cooldown_seconds) {
|
|
10003
10035
|
const result = db.query(`SELECT MAX(completed_at) as last_completed FROM tasks
|
|
10004
|
-
WHERE completed_at IS NOT NULL AND (
|
|
10036
|
+
WHERE completed_at IS NOT NULL AND (${assignedInClause} OR agent_id = ?) AND id != ?`).get(...assignedAliasParams, agent, task.id);
|
|
10005
10037
|
if (result.last_completed) {
|
|
10006
10038
|
const elapsedSeconds = (Date.now() - new Date(result.last_completed).getTime()) / 1000;
|
|
10007
10039
|
if (elapsedSeconds < config.cooldown_seconds) {
|
|
@@ -10015,6 +10047,7 @@ var init_completion_guard = __esm(() => {
|
|
|
10015
10047
|
init_types();
|
|
10016
10048
|
init_config2();
|
|
10017
10049
|
init_projects();
|
|
10050
|
+
init_database();
|
|
10018
10051
|
});
|
|
10019
10052
|
|
|
10020
10053
|
// src/lib/event-emission-safety.ts
|
|
@@ -12013,13 +12046,17 @@ function logDelivery(d, webhookId, event, payload, statusCode, response, attempt
|
|
|
12013
12046
|
const id = uuid();
|
|
12014
12047
|
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()]);
|
|
12015
12048
|
}
|
|
12016
|
-
function matchesScope(wh, payload) {
|
|
12049
|
+
function matchesScope(wh, payload, db) {
|
|
12017
12050
|
if (wh.project_id && payload.project_id !== wh.project_id)
|
|
12018
12051
|
return false;
|
|
12019
12052
|
if (wh.task_list_id && payload.task_list_id !== wh.task_list_id)
|
|
12020
12053
|
return false;
|
|
12021
|
-
if (wh.agent_id && payload.agent_id !== wh.agent_id
|
|
12022
|
-
|
|
12054
|
+
if (wh.agent_id && payload.agent_id !== wh.agent_id) {
|
|
12055
|
+
const aliasSet = assignedToAliasSet(db, wh.agent_id);
|
|
12056
|
+
const assignedTo = typeof payload.assigned_to === "string" ? payload.assigned_to.toLowerCase() : "";
|
|
12057
|
+
if (!aliasSet.has(assignedTo))
|
|
12058
|
+
return false;
|
|
12059
|
+
}
|
|
12023
12060
|
if (wh.task_id && payload.id !== wh.task_id)
|
|
12024
12061
|
return false;
|
|
12025
12062
|
return true;
|
|
@@ -12086,7 +12123,7 @@ async function dispatchWebhook2(event, payload, db) {
|
|
|
12086
12123
|
const webhooks = listWebhooks(d).filter((w) => w.active && (w.events.length === 0 || w.events.includes(event)));
|
|
12087
12124
|
const payloadObj = typeof payload === "object" && payload !== null ? payload : {};
|
|
12088
12125
|
for (const wh of webhooks) {
|
|
12089
|
-
if (!matchesScope(wh, payloadObj))
|
|
12126
|
+
if (!matchesScope(wh, payloadObj, d))
|
|
12090
12127
|
continue;
|
|
12091
12128
|
const body = JSON.stringify({ event, payload, timestamp: now() });
|
|
12092
12129
|
deliverWebhook(wh, event, body, 1, d).catch((err) => {
|
|
@@ -13202,14 +13239,16 @@ function getNextTask(agentId, filters, db) {
|
|
|
13202
13239
|
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')");
|
|
13203
13240
|
const where = conditions.join(" AND ");
|
|
13204
13241
|
let recentProjectIds = [];
|
|
13242
|
+
const assignedAliasParams = [];
|
|
13243
|
+
const assignedInClause = agentId ? lowerInClause("assigned_to", resolveAssignedToAliases(d, agentId), assignedAliasParams) : "";
|
|
13205
13244
|
if (agentId) {
|
|
13206
|
-
const recentRows = d.query(`SELECT DISTINCT project_id FROM tasks WHERE
|
|
13245
|
+
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);
|
|
13207
13246
|
recentProjectIds = recentRows.map((r) => r.project_id);
|
|
13208
13247
|
}
|
|
13209
13248
|
let sql = `SELECT * FROM tasks WHERE ${where} ORDER BY `;
|
|
13210
13249
|
if (agentId) {
|
|
13211
|
-
sql += `CASE WHEN
|
|
13212
|
-
params.push(
|
|
13250
|
+
sql += `CASE WHEN ${assignedInClause} THEN 0 WHEN assigned_to IS NULL THEN 1 ELSE 2 END, `;
|
|
13251
|
+
params.push(...assignedAliasParams);
|
|
13213
13252
|
}
|
|
13214
13253
|
if (recentProjectIds.length > 0) {
|
|
13215
13254
|
const placeholders = recentProjectIds.map(() => "?").join(",");
|
|
@@ -13603,30 +13642,6 @@ function getTaskWithRelations(id, db) {
|
|
|
13603
13642
|
checklist
|
|
13604
13643
|
};
|
|
13605
13644
|
}
|
|
13606
|
-
function resolveAssignedToAliases(db, ref) {
|
|
13607
|
-
const aliases = new Set([ref]);
|
|
13608
|
-
let agentId;
|
|
13609
|
-
try {
|
|
13610
|
-
agentId = resolvePartialId(db, "agents", ref);
|
|
13611
|
-
} catch (err) {
|
|
13612
|
-
if (!(err instanceof IdentityAliasAmbiguousError))
|
|
13613
|
-
throw err;
|
|
13614
|
-
agentId = null;
|
|
13615
|
-
}
|
|
13616
|
-
if (agentId) {
|
|
13617
|
-
aliases.add(agentId);
|
|
13618
|
-
const row = db.query("SELECT name FROM agents WHERE id = ?").get(agentId);
|
|
13619
|
-
if (row?.name)
|
|
13620
|
-
aliases.add(row.name);
|
|
13621
|
-
}
|
|
13622
|
-
return [...aliases];
|
|
13623
|
-
}
|
|
13624
|
-
function lowerInClause(column, values, params) {
|
|
13625
|
-
if (values.length === 0)
|
|
13626
|
-
return "1=0";
|
|
13627
|
-
params.push(...values.map((v) => v.toLowerCase()));
|
|
13628
|
-
return `LOWER(${column}) IN (${values.map(() => "?").join(",")})`;
|
|
13629
|
-
}
|
|
13630
13645
|
function listTasks(filter = {}, db) {
|
|
13631
13646
|
const d = db || getDatabase();
|
|
13632
13647
|
const { clearExpiredLocks: clearExpiredLocks2 } = (init_database(), __toCommonJS(exports_database));
|
|
@@ -14099,6 +14114,7 @@ function deleteTask(id, db) {
|
|
|
14099
14114
|
var init_task_crud = __esm(() => {
|
|
14100
14115
|
init_types();
|
|
14101
14116
|
init_database();
|
|
14117
|
+
init_database();
|
|
14102
14118
|
init_completion_guard();
|
|
14103
14119
|
init_event_emission_safety();
|
|
14104
14120
|
init_event_hooks();
|
|
@@ -14261,8 +14277,8 @@ function getTaskStats(filters, db) {
|
|
|
14261
14277
|
params.push(filters.task_list_id);
|
|
14262
14278
|
}
|
|
14263
14279
|
if (filters?.agent_id) {
|
|
14264
|
-
|
|
14265
|
-
|
|
14280
|
+
params.push(filters.agent_id);
|
|
14281
|
+
conditions.push(`(agent_id = ? OR ${lowerInClause("assigned_to", resolveAssignedToAliases(d, filters.agent_id), params)})`);
|
|
14266
14282
|
}
|
|
14267
14283
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
14268
14284
|
const totalRow = d.query(`SELECT COUNT(*) as count FROM tasks ${where}`).get(...params);
|
|
@@ -14445,8 +14461,7 @@ function getEscalatedTasks(opts = {}, db, at = new Date) {
|
|
|
14445
14461
|
params.push(opts.project_id);
|
|
14446
14462
|
}
|
|
14447
14463
|
if (opts.agent_id) {
|
|
14448
|
-
conditions.push("assigned_to
|
|
14449
|
-
params.push(opts.agent_id);
|
|
14464
|
+
conditions.push(lowerInClause("assigned_to", resolveAssignedToAliases(d, opts.agent_id), params));
|
|
14450
14465
|
}
|
|
14451
14466
|
const rows = d.query(`SELECT * FROM tasks WHERE ${conditions.join(" AND ")} ORDER BY due_at ASC, created_at ASC`).all(...params);
|
|
14452
14467
|
return rows.map(rowToTask).map((task) => {
|
|
@@ -14494,8 +14509,7 @@ function notifyUpcomingDeadlines(opts = {}, db) {
|
|
|
14494
14509
|
params.push(opts.project_id);
|
|
14495
14510
|
}
|
|
14496
14511
|
if (opts.agent_id) {
|
|
14497
|
-
conditions.push("assigned_to
|
|
14498
|
-
params.push(opts.agent_id);
|
|
14512
|
+
conditions.push(lowerInClause("assigned_to", resolveAssignedToAliases(d, opts.agent_id), params));
|
|
14499
14513
|
}
|
|
14500
14514
|
const rows = d.query(`SELECT * FROM tasks WHERE ${conditions.join(" AND ")} ORDER BY due_at ASC`).all(...params);
|
|
14501
14515
|
return rows.map(rowToTask);
|
|
@@ -14753,13 +14767,14 @@ function getTimeReport(opts, db) {
|
|
|
14753
14767
|
params.push(opts.plan_id);
|
|
14754
14768
|
}
|
|
14755
14769
|
if (opts?.agent_id) {
|
|
14770
|
+
const assignedInClause = lowerInClause("t.assigned_to", resolveAssignedToAliases(d, opts.agent_id), params);
|
|
14756
14771
|
conditions.push(`(
|
|
14757
|
-
|
|
14772
|
+
${assignedInClause}
|
|
14758
14773
|
OR t.agent_id = ?
|
|
14759
14774
|
OR EXISTS (SELECT 1 FROM task_time_logs ttl WHERE ttl.task_id = t.id AND ttl.agent_id = ?)
|
|
14760
14775
|
OR EXISTS (SELECT 1 FROM focus_sessions fs WHERE fs.task_id = t.id AND fs.agent_id = ?)
|
|
14761
14776
|
)`);
|
|
14762
|
-
params.push(opts.agent_id, opts.agent_id, opts.agent_id
|
|
14777
|
+
params.push(opts.agent_id, opts.agent_id, opts.agent_id);
|
|
14763
14778
|
}
|
|
14764
14779
|
if (opts?.since) {
|
|
14765
14780
|
conditions.push("(t.completed_at >= ? OR t.updated_at >= ?)");
|
|
@@ -15755,7 +15770,7 @@ function listActiveFiles(db) {
|
|
|
15755
15770
|
a.name AS agent_name
|
|
15756
15771
|
FROM task_files tf
|
|
15757
15772
|
JOIN tasks t ON tf.task_id = t.id
|
|
15758
|
-
LEFT JOIN agents a ON (tf.agent_id = a.id OR (tf.agent_id IS NULL AND t.assigned_to = a.id))
|
|
15773
|
+
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))))
|
|
15759
15774
|
WHERE t.status = 'in_progress'
|
|
15760
15775
|
AND tf.status != 'removed'
|
|
15761
15776
|
ORDER BY tf.updated_at DESC
|
|
@@ -23056,11 +23071,12 @@ function runAlerts(input, db, checkedAt, quieted) {
|
|
|
23056
23071
|
if (input.include_runs === false)
|
|
23057
23072
|
return [];
|
|
23058
23073
|
const since = Date.parse(input.run_since || new Date(Date.parse(checkedAt) - 24 * 60 * 60000).toISOString());
|
|
23074
|
+
const runAlertAliases = input.agent_id ? assignedToAliasSet(db, input.agent_id) : null;
|
|
23059
23075
|
return listTaskRuns(undefined, db).filter((run) => run.completed_at && Date.parse(run.completed_at) >= since).map((run) => {
|
|
23060
23076
|
const task = getTask(run.task_id, db);
|
|
23061
23077
|
if (input.project_id && task?.project_id !== input.project_id)
|
|
23062
23078
|
return null;
|
|
23063
|
-
if (input.agent_id && run.agent_id !== input.agent_id && task?.assigned_to
|
|
23079
|
+
if (input.agent_id && run.agent_id !== input.agent_id && !(runAlertAliases && runAlertAliases.has((task?.assigned_to ?? "").toLowerCase())))
|
|
23064
23080
|
return null;
|
|
23065
23081
|
const failed = ["failed", "cancelled"].includes(run.status);
|
|
23066
23082
|
return {
|
|
@@ -23105,6 +23121,7 @@ async function checkLocalNotifications(input = {}, db) {
|
|
|
23105
23121
|
const warnings = [];
|
|
23106
23122
|
if (Number.isNaN(checkedMs))
|
|
23107
23123
|
warnings.push("Invalid check timestamp; due-soon window may be incomplete.");
|
|
23124
|
+
const notifyAgentAliases = input.agent_id ? assignedToAliasSet(d, input.agent_id) : null;
|
|
23108
23125
|
const alerts = [];
|
|
23109
23126
|
for (const escalation of getEscalatedTasks({ project_id: input.project_id, agent_id: input.agent_id }, d, new Date(checkedAt))) {
|
|
23110
23127
|
for (const reason of escalation.reasons) {
|
|
@@ -23116,7 +23133,7 @@ async function checkLocalNotifications(input = {}, db) {
|
|
|
23116
23133
|
for (const task of listTasks({ project_id: input.project_id, include_archived: false, limit: 5000 }, d)) {
|
|
23117
23134
|
if (!unfinished(task) || !task.due_at)
|
|
23118
23135
|
continue;
|
|
23119
|
-
if (input.agent_id && task.
|
|
23136
|
+
if (input.agent_id && task.agent_id !== input.agent_id && !(notifyAgentAliases && notifyAgentAliases.has((task.assigned_to ?? "").toLowerCase())))
|
|
23120
23137
|
continue;
|
|
23121
23138
|
if (task.due_at > checkedAt && task.due_at <= dueSoonUntil) {
|
|
23122
23139
|
alerts.push(taskAlert(task, "task_due_soon", "task.due_soon", "warning", `Due soon: ${task.title}`, task.due_at, quieted));
|
|
@@ -23124,7 +23141,7 @@ async function checkLocalNotifications(input = {}, db) {
|
|
|
23124
23141
|
}
|
|
23125
23142
|
}
|
|
23126
23143
|
for (const task of getStaleTasks(staleMinutes, { project_id: input.project_id }, d)) {
|
|
23127
|
-
if (input.agent_id && task.
|
|
23144
|
+
if (input.agent_id && task.agent_id !== input.agent_id && !(notifyAgentAliases && notifyAgentAliases.has((task.assigned_to ?? "").toLowerCase())))
|
|
23128
23145
|
continue;
|
|
23129
23146
|
alerts.push(taskAlert(task, "task_stale", "task.stale", "warning", `Stale task: ${task.title}`, checkedAt, quieted, { stale_minutes: staleMinutes }));
|
|
23130
23147
|
}
|
|
@@ -25144,10 +25161,12 @@ function matchesProfile(profile, query) {
|
|
|
25144
25161
|
return false;
|
|
25145
25162
|
return true;
|
|
25146
25163
|
}
|
|
25147
|
-
function taskMatchesAgent(task, agentId) {
|
|
25164
|
+
function taskMatchesAgent(task, agentId, aliasSet) {
|
|
25148
25165
|
if (!agentId)
|
|
25149
25166
|
return true;
|
|
25150
|
-
|
|
25167
|
+
if (task.agent_id === agentId)
|
|
25168
|
+
return true;
|
|
25169
|
+
return aliasSet ? aliasSet.has((task.assigned_to ?? "").toLowerCase()) : task.assigned_to === agentId;
|
|
25151
25170
|
}
|
|
25152
25171
|
function estimateRemaining(task) {
|
|
25153
25172
|
if (task.status === "completed" || task.status === "cancelled")
|
|
@@ -25217,7 +25236,8 @@ function removeCapacityProfile(idOrAgent, projectId) {
|
|
|
25217
25236
|
}
|
|
25218
25237
|
function getPlanningForecast(input = {}, db) {
|
|
25219
25238
|
const startDate = input.start_date ? dateOnly(input.start_date) : todayIso();
|
|
25220
|
-
const
|
|
25239
|
+
const aliasSet = input.agent_id ? assignedToAliasSet(db || getDatabase(), input.agent_id) : undefined;
|
|
25240
|
+
const tasks = listTasks({ project_id: input.project_id, plan_id: input.plan_id, limit: 1e4 }, db).filter((task) => taskMatchesAgent(task, input.agent_id, aliasSet));
|
|
25221
25241
|
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((entry) => [entry.task_id, entry]));
|
|
25222
25242
|
const profiles = listCapacityProfiles({ agent_id: input.agent_id, project_id: input.project_id });
|
|
25223
25243
|
const globalProfiles = input.project_id ? listCapacityProfiles({ agent_id: input.agent_id }).filter((profile) => profile.project_id === null) : [];
|
|
@@ -25315,6 +25335,7 @@ function renderPlanningForecastMarkdown(forecast) {
|
|
|
25315
25335
|
}
|
|
25316
25336
|
var LOCAL_CAPACITY_SCHEMA_VERSION = 1;
|
|
25317
25337
|
var init_capacity_forecasts = __esm(() => {
|
|
25338
|
+
init_database();
|
|
25318
25339
|
init_tasks();
|
|
25319
25340
|
init_task_relations();
|
|
25320
25341
|
init_config2();
|
|
@@ -25976,8 +25997,7 @@ function searchTasks(options, projectId, taskListId, db) {
|
|
|
25976
25997
|
}
|
|
25977
25998
|
}
|
|
25978
25999
|
if (opts.assigned_to) {
|
|
25979
|
-
sql +=
|
|
25980
|
-
params.push(opts.assigned_to);
|
|
26000
|
+
sql += ` AND ${lowerInClause("t.assigned_to", resolveAssignedToAliases(d, opts.assigned_to), params)}`;
|
|
25981
26001
|
}
|
|
25982
26002
|
if (opts.agent_id) {
|
|
25983
26003
|
sql += " AND t.agent_id = ?";
|
|
@@ -28908,8 +28928,10 @@ function getLatestHandoff(agentId, projectId, db) {
|
|
|
28908
28928
|
function createSessionRecoveryHandoff(input, db) {
|
|
28909
28929
|
const d = db || getDatabase();
|
|
28910
28930
|
const limit = input.limit || 20;
|
|
28911
|
-
const
|
|
28912
|
-
const
|
|
28931
|
+
const params = [];
|
|
28932
|
+
const assignedInClause = lowerInClause("assigned_to", resolveAssignedToAliases(d, input.agent_id), params);
|
|
28933
|
+
const conditions = ["status = 'in_progress'", `(${assignedInClause} OR agent_id = ? OR locked_by = ?)`];
|
|
28934
|
+
params.push(input.agent_id, input.agent_id);
|
|
28913
28935
|
if (input.session_id) {
|
|
28914
28936
|
conditions.push("session_id = ?");
|
|
28915
28937
|
params.push(input.session_id);
|
|
@@ -30133,7 +30155,8 @@ function registerTaskAutoTools(server, ctx) {
|
|
|
30133
30155
|
const assigned = listTasks3({ assigned_to: effectiveAgentId, limit: 500 }, undefined);
|
|
30134
30156
|
const now4 = Date.now();
|
|
30135
30157
|
const dueSoonCutoff = now4 + 24 * 60 * 60 * 1000;
|
|
30136
|
-
const
|
|
30158
|
+
const blockedAliases = assignedToAliasSet(getDatabase(), effectiveAgentId);
|
|
30159
|
+
const blocked = getBlockedTasks2().filter((t) => blockedAliases.has((t.assigned_to ?? "").toLowerCase()));
|
|
30137
30160
|
const workload = {
|
|
30138
30161
|
in_progress: assigned.filter((t) => t.status === "in_progress").length,
|
|
30139
30162
|
pending: assigned.filter((t) => t.status === "pending").length,
|
|
@@ -30170,17 +30193,25 @@ function registerTaskAutoTools(server, ctx) {
|
|
|
30170
30193
|
if (agents.length === 0)
|
|
30171
30194
|
return { content: [{ type: "text", text: "No active agents available for rebalancing." }] };
|
|
30172
30195
|
const activeTasks = listTasks3({ project_id: resolvedProjectId, status: ["pending", "in_progress"], limit: 1000 }, undefined);
|
|
30173
|
-
const
|
|
30196
|
+
const agentKeyByAlias = new Map;
|
|
30197
|
+
for (const agent of agents) {
|
|
30198
|
+
agentKeyByAlias.set(String(agent.id).toLowerCase(), agent.id);
|
|
30199
|
+
if (agent.name)
|
|
30200
|
+
agentKeyByAlias.set(String(agent.name).toLowerCase(), agent.id);
|
|
30201
|
+
}
|
|
30202
|
+
const canonicalAgentKey = (assignedTo) => assignedTo ? agentKeyByAlias.get(assignedTo.toLowerCase()) : undefined;
|
|
30203
|
+
const load = new Map(agents.map((agent) => [agent.id, activeTasks.filter((t) => canonicalAgentKey(t.assigned_to) === agent.id).length]));
|
|
30174
30204
|
let moved = 0;
|
|
30175
30205
|
let skipped = 0;
|
|
30176
|
-
for (const task of activeTasks.filter((t) => t.status === "pending" && t.assigned_to && (load.get(t.assigned_to) ?? 0) > limit)) {
|
|
30177
|
-
const
|
|
30206
|
+
for (const task of activeTasks.filter((t) => t.status === "pending" && canonicalAgentKey(t.assigned_to) && (load.get(canonicalAgentKey(t.assigned_to)) ?? 0) > limit)) {
|
|
30207
|
+
const currentAgentKey = canonicalAgentKey(task.assigned_to);
|
|
30208
|
+
const target = agents.filter((agent) => agent.id !== currentAgentKey).sort((a, b) => (load.get(a.id) ?? 0) - (load.get(b.id) ?? 0))[0];
|
|
30178
30209
|
if (!target || (load.get(target.id) ?? 0) >= limit) {
|
|
30179
30210
|
skipped++;
|
|
30180
30211
|
continue;
|
|
30181
30212
|
}
|
|
30182
30213
|
updateTask2(task.id, { assigned_to: target.id, version: task.version });
|
|
30183
|
-
load.set(
|
|
30214
|
+
load.set(currentAgentKey, (load.get(currentAgentKey) ?? 1) - 1);
|
|
30184
30215
|
load.set(target.id, (load.get(target.id) ?? 0) + 1);
|
|
30185
30216
|
moved++;
|
|
30186
30217
|
}
|
|
@@ -30359,6 +30390,7 @@ ${lines.join(`
|
|
|
30359
30390
|
var init_task_auto_tools = __esm(() => {
|
|
30360
30391
|
init_zod();
|
|
30361
30392
|
init_cloud_router();
|
|
30393
|
+
init_database();
|
|
30362
30394
|
});
|
|
30363
30395
|
|
|
30364
30396
|
// src/lib/context-packs.ts
|
|
@@ -31538,7 +31570,8 @@ ${JSON.stringify(task.metadata, null, 2)}` : null
|
|
|
31538
31570
|
}, undefined);
|
|
31539
31571
|
const completedYesterday = completed.filter((t) => t.completed_at && t.completed_at.startsWith(yesterdayStr));
|
|
31540
31572
|
const { getBlockedTasks: getBlockedTasks2 } = (init_tasks(), __toCommonJS(exports_tasks));
|
|
31541
|
-
const
|
|
31573
|
+
const blockedAliases = effectiveAgentId ? assignedToAliasSet(getDatabase(), effectiveAgentId) : null;
|
|
31574
|
+
const blocked = getBlockedTasks2(effectiveProjectId ? resolveId(effectiveProjectId, "projects") : undefined).filter((t) => blockedAliases ? blockedAliases.has((t.assigned_to ?? "").toLowerCase()) : false);
|
|
31542
31575
|
const lines = [
|
|
31543
31576
|
`Standup for ${effectiveAgentId} (${effectiveProjectId ? `project: ${effectiveProjectId.slice(0, 8)}` : "all projects"})`,
|
|
31544
31577
|
inProgress.length > 0 ? `
|
|
@@ -31766,6 +31799,7 @@ var init_task_adv_tools = __esm(() => {
|
|
|
31766
31799
|
init_zod();
|
|
31767
31800
|
init_token_utils();
|
|
31768
31801
|
init_cloud_router();
|
|
31802
|
+
init_database();
|
|
31769
31803
|
});
|
|
31770
31804
|
|
|
31771
31805
|
// src/mcp/tools/task-meta-tools.ts
|
|
@@ -33683,27 +33717,29 @@ function getAgentMetrics(agentId, opts, db) {
|
|
|
33683
33717
|
const agent = d.query("SELECT id, name FROM agents WHERE id = ? OR LOWER(name) = LOWER(?)").get(agentId, agentId);
|
|
33684
33718
|
if (!agent)
|
|
33685
33719
|
return null;
|
|
33720
|
+
const assignedAliases = resolveAssignedToAliases(d, agent.id).map((a) => a.toLowerCase());
|
|
33721
|
+
const assignedInClause = `LOWER(assigned_to) IN (${assignedAliases.map(() => "?").join(",")})`;
|
|
33686
33722
|
let projectFilter = "";
|
|
33687
|
-
const params = [agent.id,
|
|
33723
|
+
const params = [agent.id, ...assignedAliases];
|
|
33688
33724
|
if (opts?.project_id) {
|
|
33689
33725
|
projectFilter = " AND project_id = ?";
|
|
33690
33726
|
params.push(opts.project_id);
|
|
33691
33727
|
}
|
|
33692
|
-
const completed = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR
|
|
33693
|
-
const failed = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR
|
|
33694
|
-
const inProgress = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR
|
|
33728
|
+
const completed = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'completed'${projectFilter}`).get(...params).count;
|
|
33729
|
+
const failed = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'failed'${projectFilter}`).get(...params).count;
|
|
33730
|
+
const inProgress = d.query(`SELECT COUNT(*) as count FROM tasks WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'in_progress'${projectFilter}`).get(...params).count;
|
|
33695
33731
|
const total = completed + failed;
|
|
33696
33732
|
const completionRate = total > 0 ? completed / total : 0;
|
|
33697
33733
|
const avgTime = d.query(`SELECT AVG(
|
|
33698
33734
|
(julianday(completed_at) - julianday(created_at)) * 24 * 60
|
|
33699
33735
|
) as avg_minutes
|
|
33700
33736
|
FROM tasks
|
|
33701
|
-
WHERE (agent_id = ? OR
|
|
33737
|
+
WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'completed' AND completed_at IS NOT NULL${projectFilter}`).get(...params);
|
|
33702
33738
|
const avgConf = d.query(`SELECT AVG(confidence) as avg_confidence
|
|
33703
33739
|
FROM tasks
|
|
33704
|
-
WHERE (agent_id = ? OR
|
|
33740
|
+
WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'completed' AND confidence IS NOT NULL${projectFilter}`).get(...params);
|
|
33705
33741
|
const reviewTasks = d.query(`SELECT metadata FROM tasks
|
|
33706
|
-
WHERE (agent_id = ? OR
|
|
33742
|
+
WHERE (agent_id = ? OR ${assignedInClause}) AND status = 'completed'${projectFilter}
|
|
33707
33743
|
AND metadata LIKE '%_review_score%'`).all(...params);
|
|
33708
33744
|
let reviewScoreAvg = null;
|
|
33709
33745
|
if (reviewTasks.length > 0) {
|
|
@@ -34167,14 +34203,15 @@ function millisBetween(start, end) {
|
|
|
34167
34203
|
return 0;
|
|
34168
34204
|
return endMs - startMs;
|
|
34169
34205
|
}
|
|
34170
|
-
function addTaskScope(where, params, options, alias = "t") {
|
|
34206
|
+
function addTaskScope(where, params, options, db, alias = "t") {
|
|
34171
34207
|
if (options.project_id) {
|
|
34172
34208
|
where.push(`${alias}.project_id = ?`);
|
|
34173
34209
|
params.push(options.project_id);
|
|
34174
34210
|
}
|
|
34175
34211
|
if (options.agent_id) {
|
|
34176
|
-
|
|
34177
|
-
|
|
34212
|
+
params.push(options.agent_id);
|
|
34213
|
+
const assignedInClause = lowerInClause(`${alias}.assigned_to`, resolveAssignedToAliases(db, options.agent_id), params);
|
|
34214
|
+
where.push(`(${alias}.agent_id = ? OR ${assignedInClause})`);
|
|
34178
34215
|
}
|
|
34179
34216
|
if (options.since) {
|
|
34180
34217
|
where.push(`${alias}.created_at >= ?`);
|
|
@@ -34185,14 +34222,15 @@ function addTaskScope(where, params, options, alias = "t") {
|
|
|
34185
34222
|
params.push(options.until);
|
|
34186
34223
|
}
|
|
34187
34224
|
}
|
|
34188
|
-
function addRunScope(where, params, options, runAlias = "r", taskAlias = "t") {
|
|
34225
|
+
function addRunScope(where, params, options, db, runAlias = "r", taskAlias = "t") {
|
|
34189
34226
|
if (options.project_id) {
|
|
34190
34227
|
where.push(`${taskAlias}.project_id = ?`);
|
|
34191
34228
|
params.push(options.project_id);
|
|
34192
34229
|
}
|
|
34193
34230
|
if (options.agent_id) {
|
|
34194
|
-
|
|
34195
|
-
|
|
34231
|
+
params.push(options.agent_id, options.agent_id);
|
|
34232
|
+
const assignedInClause = lowerInClause(`${taskAlias}.assigned_to`, resolveAssignedToAliases(db, options.agent_id), params);
|
|
34233
|
+
where.push(`(${runAlias}.agent_id = ? OR ${taskAlias}.agent_id = ? OR ${assignedInClause})`);
|
|
34196
34234
|
}
|
|
34197
34235
|
if (options.since) {
|
|
34198
34236
|
where.push(`${runAlias}.started_at >= ?`);
|
|
@@ -34203,14 +34241,15 @@ function addRunScope(where, params, options, runAlias = "r", taskAlias = "t") {
|
|
|
34203
34241
|
params.push(options.until);
|
|
34204
34242
|
}
|
|
34205
34243
|
}
|
|
34206
|
-
function addTraceScope(where, params, options, traceAlias = "tr", taskAlias = "t") {
|
|
34244
|
+
function addTraceScope(where, params, options, db, traceAlias = "tr", taskAlias = "t") {
|
|
34207
34245
|
if (options.project_id) {
|
|
34208
34246
|
where.push(`${taskAlias}.project_id = ?`);
|
|
34209
34247
|
params.push(options.project_id);
|
|
34210
34248
|
}
|
|
34211
34249
|
if (options.agent_id) {
|
|
34212
|
-
|
|
34213
|
-
|
|
34250
|
+
params.push(options.agent_id, options.agent_id);
|
|
34251
|
+
const assignedInClause = lowerInClause(`${taskAlias}.assigned_to`, resolveAssignedToAliases(db, options.agent_id), params);
|
|
34252
|
+
where.push(`(${traceAlias}.agent_id = ? OR ${taskAlias}.agent_id = ? OR ${assignedInClause})`);
|
|
34214
34253
|
}
|
|
34215
34254
|
if (options.since) {
|
|
34216
34255
|
where.push(`${traceAlias}.created_at >= ?`);
|
|
@@ -34270,7 +34309,7 @@ function createLocalUsageLedger(options = {}, db) {
|
|
|
34270
34309
|
const generatedAt = options.generated_at || new Date().toISOString();
|
|
34271
34310
|
const taskWhere = [];
|
|
34272
34311
|
const taskParams = [];
|
|
34273
|
-
addTaskScope(taskWhere, taskParams, options);
|
|
34312
|
+
addTaskScope(taskWhere, taskParams, options, d);
|
|
34274
34313
|
const taskClause = taskWhere.length ? `WHERE ${taskWhere.join(" AND ")}` : "";
|
|
34275
34314
|
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);
|
|
34276
34315
|
let projectCount = 0;
|
|
@@ -34279,14 +34318,14 @@ function createLocalUsageLedger(options = {}, db) {
|
|
|
34279
34318
|
} else if (options.agent_id) {
|
|
34280
34319
|
const projectWhere = ["t.project_id IS NOT NULL"];
|
|
34281
34320
|
const projectParams = [];
|
|
34282
|
-
addTaskScope(projectWhere, projectParams, options);
|
|
34321
|
+
addTaskScope(projectWhere, projectParams, options, d);
|
|
34283
34322
|
projectCount = queryOne(d, `SELECT COUNT(DISTINCT t.project_id) as count FROM tasks t WHERE ${projectWhere.join(" AND ")}`, projectParams).count;
|
|
34284
34323
|
} else {
|
|
34285
34324
|
projectCount = queryOne(d, "SELECT COUNT(*) as count FROM projects", []).count;
|
|
34286
34325
|
}
|
|
34287
34326
|
const runWhere = [];
|
|
34288
34327
|
const runParams = [];
|
|
34289
|
-
addRunScope(runWhere, runParams, options);
|
|
34328
|
+
addRunScope(runWhere, runParams, options, d);
|
|
34290
34329
|
const runClause = runWhere.length ? `WHERE ${runWhere.join(" AND ")}` : "";
|
|
34291
34330
|
const runs = queryAll(d, `SELECT r.id, r.started_at, r.completed_at, r.metadata
|
|
34292
34331
|
FROM task_runs r JOIN tasks t ON t.id = r.task_id
|
|
@@ -34303,7 +34342,7 @@ function createLocalUsageLedger(options = {}, db) {
|
|
|
34303
34342
|
${runClause}`, runParams);
|
|
34304
34343
|
const traceWhere = [];
|
|
34305
34344
|
const traceParams = [];
|
|
34306
|
-
addTraceScope(traceWhere, traceParams, options);
|
|
34345
|
+
addTraceScope(traceWhere, traceParams, options, d);
|
|
34307
34346
|
const traceClause = traceWhere.length ? `WHERE ${traceWhere.join(" AND ")}` : "";
|
|
34308
34347
|
const traceTotals = queryOne(d, `SELECT COUNT(*) as traces,
|
|
34309
34348
|
COALESCE(SUM(tr.tokens), 0) as tokens,
|
|
@@ -34447,10 +34486,12 @@ function limitValue(value) {
|
|
|
34447
34486
|
function isTerminal(task) {
|
|
34448
34487
|
return task.status === "completed" || task.status === "failed" || task.status === "cancelled";
|
|
34449
34488
|
}
|
|
34450
|
-
function sameAgent(task, agentId) {
|
|
34489
|
+
function sameAgent(task, agentId, aliasSet) {
|
|
34451
34490
|
if (!agentId)
|
|
34452
34491
|
return true;
|
|
34453
|
-
|
|
34492
|
+
if (task.agent_id === agentId)
|
|
34493
|
+
return true;
|
|
34494
|
+
return aliasSet ? aliasSet.has((task.assigned_to ?? "").toLowerCase()) : task.assigned_to === agentId;
|
|
34454
34495
|
}
|
|
34455
34496
|
function withinTaskWindow(task, options) {
|
|
34456
34497
|
const time = Date.parse(task.updated_at);
|
|
@@ -34463,11 +34504,12 @@ function withinTaskWindow(task, options) {
|
|
|
34463
34504
|
return true;
|
|
34464
34505
|
}
|
|
34465
34506
|
function scopedTasks(options, db) {
|
|
34507
|
+
const aliasSet = options.agent_id ? assignedToAliasSet(db, options.agent_id) : undefined;
|
|
34466
34508
|
return listTasks({
|
|
34467
34509
|
project_id: options.project_id,
|
|
34468
34510
|
plan_id: options.plan_id,
|
|
34469
34511
|
include_archived: false
|
|
34470
|
-
}, db).filter((task) => sameAgent(task, options.agent_id) && withinTaskWindow(task, options));
|
|
34512
|
+
}, db).filter((task) => sameAgent(task, options.agent_id, aliasSet) && withinTaskWindow(task, options));
|
|
34471
34513
|
}
|
|
34472
34514
|
function summarizeTask(task) {
|
|
34473
34515
|
return {
|
|
@@ -34533,7 +34575,7 @@ function initialAgentSummary(agentId) {
|
|
|
34533
34575
|
}
|
|
34534
34576
|
};
|
|
34535
34577
|
}
|
|
34536
|
-
function addScopeClauses(where, params, options, timeColumn) {
|
|
34578
|
+
function addScopeClauses(where, params, options, timeColumn, db) {
|
|
34537
34579
|
if (options.project_id) {
|
|
34538
34580
|
where.push("t.project_id = ?");
|
|
34539
34581
|
params.push(options.project_id);
|
|
@@ -34543,8 +34585,9 @@ function addScopeClauses(where, params, options, timeColumn) {
|
|
|
34543
34585
|
params.push(options.plan_id);
|
|
34544
34586
|
}
|
|
34545
34587
|
if (options.agent_id) {
|
|
34546
|
-
|
|
34547
|
-
|
|
34588
|
+
params.push(options.agent_id, options.agent_id);
|
|
34589
|
+
const assignedInClause = lowerInClause("t.assigned_to", resolveAssignedToAliases(db, options.agent_id), params);
|
|
34590
|
+
where.push(`(r.agent_id = ? OR t.agent_id = ? OR ${assignedInClause})`);
|
|
34548
34591
|
}
|
|
34549
34592
|
if (options.since) {
|
|
34550
34593
|
where.push(`${timeColumn} >= ?`);
|
|
@@ -34558,7 +34601,7 @@ function addScopeClauses(where, params, options, timeColumn) {
|
|
|
34558
34601
|
function loadRuns(options, db) {
|
|
34559
34602
|
const where = ["t.archived_at IS NULL"];
|
|
34560
34603
|
const params = [];
|
|
34561
|
-
addScopeClauses(where, params, options, "r.started_at");
|
|
34604
|
+
addScopeClauses(where, params, options, "r.started_at", db);
|
|
34562
34605
|
return db.query(`
|
|
34563
34606
|
SELECT
|
|
34564
34607
|
r.id,
|
|
@@ -34598,8 +34641,9 @@ function loadVerifications(options, db) {
|
|
|
34598
34641
|
params.push(options.plan_id);
|
|
34599
34642
|
}
|
|
34600
34643
|
if (options.agent_id) {
|
|
34601
|
-
|
|
34602
|
-
|
|
34644
|
+
params.push(options.agent_id, options.agent_id);
|
|
34645
|
+
const assignedInClause = lowerInClause("t.assigned_to", resolveAssignedToAliases(db, options.agent_id), params);
|
|
34646
|
+
where.push(`(v.agent_id = ? OR t.agent_id = ? OR ${assignedInClause})`);
|
|
34603
34647
|
}
|
|
34604
34648
|
if (options.since) {
|
|
34605
34649
|
where.push("v.run_at >= ?");
|
|
@@ -34821,7 +34865,6 @@ function renderLocalReportMarkdown(report) {
|
|
|
34821
34865
|
}
|
|
34822
34866
|
var LOCAL_REPORT_SCHEMA_VERSION = 1, LOCAL_REPORT_TYPES;
|
|
34823
34867
|
var init_local_reports = __esm(() => {
|
|
34824
|
-
init_database();
|
|
34825
34868
|
init_database();
|
|
34826
34869
|
init_plans();
|
|
34827
34870
|
init_tasks();
|
|
@@ -34843,7 +34886,7 @@ var package_default;
|
|
|
34843
34886
|
var init_package = __esm(() => {
|
|
34844
34887
|
package_default = {
|
|
34845
34888
|
name: "@hasna/todos",
|
|
34846
|
-
version: "0.13.
|
|
34889
|
+
version: "0.13.12",
|
|
34847
34890
|
description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
34848
34891
|
type: "module",
|
|
34849
34892
|
main: "dist/index.js",
|
|
@@ -39060,7 +39103,7 @@ ${lines.join(`
|
|
|
39060
39103
|
a.name AS agent_name
|
|
39061
39104
|
FROM task_files tf
|
|
39062
39105
|
JOIN tasks t ON tf.task_id = t.id
|
|
39063
|
-
LEFT JOIN agents a ON (tf.agent_id = a.id OR (tf.agent_id IS NULL AND t.assigned_to = a.id))
|
|
39106
|
+
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))))
|
|
39064
39107
|
WHERE t.status = 'in_progress'
|
|
39065
39108
|
AND tf.status != 'removed'
|
|
39066
39109
|
AND t.project_id = ?
|
|
@@ -42824,7 +42867,7 @@ ${text2}` }] };
|
|
|
42824
42867
|
const oldName = agent.name;
|
|
42825
42868
|
const updated = updateAgent(agent.id, { name: new_name });
|
|
42826
42869
|
const db = getDatabase();
|
|
42827
|
-
const tasksResult = db.run("UPDATE tasks SET assigned_to = ? WHERE assigned_to = ?", [new_name, oldName]);
|
|
42870
|
+
const tasksResult = db.run("UPDATE tasks SET assigned_to = ? WHERE LOWER(assigned_to) = LOWER(?)", [new_name, oldName]);
|
|
42828
42871
|
const taskNote = tasksResult.changes > 0 ? `
|
|
42829
42872
|
Updated assigned_to on ${tasksResult.changes} task(s).` : "";
|
|
42830
42873
|
return {
|
|
@@ -48682,8 +48725,9 @@ async function handleAgentMe(_req, url, _ctx, json2, taskToSummary2) {
|
|
|
48682
48725
|
}
|
|
48683
48726
|
}
|
|
48684
48727
|
function handleAgentQueue(agentId, _ctx, json2, taskToSummary2) {
|
|
48728
|
+
const aliasSet = assignedToAliasSet(getDatabase(), agentId);
|
|
48685
48729
|
const pending = listTasks({ status: "pending" });
|
|
48686
|
-
const queue = pending.filter((t) => t.assigned_to
|
|
48730
|
+
const queue = pending.filter((t) => aliasSet.has((t.assigned_to ?? "").toLowerCase()) || t.agent_id === agentId || !t.assigned_to && !t.locked_by);
|
|
48687
48731
|
const order = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
48688
48732
|
queue.sort((a, b) => (order[a.priority] ?? 4) - (order[b.priority] ?? 4) || new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
48689
48733
|
return json2(queue.map((t) => taskToSummary2(t)));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/agents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,UAAU,UAAU;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,KAAK,OAAO,GAAG;IACb,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD,WAAW,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;IACpC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAC;CAC5D,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,kBAAkB,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/agents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,UAAU,UAAU;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,KAAK,OAAO,GAAG;IACb,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD,WAAW,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;IACpC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAC;CAC5D,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,kBAAkB,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,EAAE,OAAO,GAAG,IAAI,CAqfjJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-adv-tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/task-adv-tools.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"task-adv-tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/task-adv-tools.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAKjD,UAAU,cAAc;IACtB,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,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,cAAc,QA2nB1E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-auto-tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/task-auto-tools.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"task-auto-tools.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/task-auto-tools.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAIjD,UAAU,eAAe;IACvB,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,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,QA2Y5E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-resources.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/task-resources.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAwHpE,UAAU,oBAAoB;IAC5B,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;CACzC;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"task-resources.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/task-resources.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAwHpE,UAAU,oBAAoB;IAC5B,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;CACzC;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,oBAAoB,QA26DjF"}
|