@hasna/todos 0.13.11 → 0.14.0
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/commands/agent-commands.d.ts +39 -0
- package/dist/cli/commands/agent-commands.d.ts.map +1 -1
- package/dist/cli/commands/dispatch.d.ts.map +1 -1
- package/dist/cli/commands/project-commands.d.ts.map +1 -1
- package/dist/cli/commands/task-commands.d.ts.map +1 -1
- package/dist/cli/helpers.d.ts +64 -2
- package/dist/cli/helpers.d.ts.map +1 -1
- package/dist/cli/index.js +510 -149
- package/dist/contracts.js +102 -71
- 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 +134 -93
- package/dist/lib/capacity-forecasts.d.ts.map +1 -1
- package/dist/lib/completion-guard.d.ts.map +1 -1
- package/dist/lib/enum-vocabulary.d.ts +72 -0
- package/dist/lib/enum-vocabulary.d.ts.map +1 -0
- 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/saved-search-views.d.ts +12 -1
- package/dist/lib/saved-search-views.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 +349 -115
- 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 +102 -71
- package/dist/release-provenance.json +5 -5
- package/dist/sdk/v1.generated.d.ts +2 -2
- package/dist/sdk/v1.generated.d.ts.map +1 -1
- package/dist/server/index.js +349 -115
- package/dist/server/openapi.d.ts +58 -0
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/v1.d.ts.map +1 -1
- package/dist/storage.js +69 -46
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -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;
|
|
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;AAQzE,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,CA4fjJ"}
|
|
@@ -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,QA0Z5E"}
|
|
@@ -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"}
|
package/dist/mcp.js
CHANGED
|
@@ -41,7 +41,7 @@ var __require = import.meta.require;
|
|
|
41
41
|
// package.json
|
|
42
42
|
var package_default = {
|
|
43
43
|
name: "@hasna/todos",
|
|
44
|
-
version: "0.
|
|
44
|
+
version: "0.14.0",
|
|
45
45
|
description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
46
46
|
type: "module",
|
|
47
47
|
main: "dist/index.js",
|
package/dist/registry.js
CHANGED
|
@@ -3430,6 +3430,9 @@ var init_machines = __esm(() => {
|
|
|
3430
3430
|
function isBlockingDependencyStatus(status) {
|
|
3431
3431
|
return status !== "completed" && status !== "cancelled";
|
|
3432
3432
|
}
|
|
3433
|
+
function isTerminalStatus(status) {
|
|
3434
|
+
return status === "completed" || status === "failed" || status === "cancelled";
|
|
3435
|
+
}
|
|
3433
3436
|
var TASK_STATUSES, TASK_PRIORITIES, PLAN_STATUSES, VersionConflictError, TaskNotFoundError, TaskNotStartableError, TaskReferenceAmbiguousError, ProjectNotFoundError, ResourceConflictError, PlanNotFoundError, LockError, AgentNotFoundError, IdentityAliasAmbiguousError, IdentityIdImmutableError, TaskListNotFoundError, DependencyCycleError, CompletionGuardError, DISPATCH_STATUSES, DispatchNotFoundError;
|
|
3434
3437
|
var init_types = __esm(() => {
|
|
3435
3438
|
TASK_STATUSES = [
|
|
@@ -4103,14 +4106,17 @@ var exports_database = {};
|
|
|
4103
4106
|
__export(exports_database, {
|
|
4104
4107
|
uuid: () => uuid,
|
|
4105
4108
|
resolvePartialId: () => resolvePartialId,
|
|
4109
|
+
resolveAssignedToAliases: () => resolveAssignedToAliases,
|
|
4106
4110
|
resetDatabase: () => resetDatabase,
|
|
4107
4111
|
now: () => now,
|
|
4112
|
+
lowerInClause: () => lowerInClause,
|
|
4108
4113
|
lockExpiryCutoff: () => lockExpiryCutoff,
|
|
4109
4114
|
isLockExpired: () => isLockExpired,
|
|
4110
4115
|
getDatabasePath: () => getDatabasePath,
|
|
4111
4116
|
getDatabase: () => getDatabase,
|
|
4112
4117
|
closeDatabase: () => closeDatabase,
|
|
4113
4118
|
clearExpiredLocks: () => clearExpiredLocks,
|
|
4119
|
+
assignedToAliasSet: () => assignedToAliasSet,
|
|
4114
4120
|
LOCK_EXPIRY_MINUTES: () => LOCK_EXPIRY_MINUTES
|
|
4115
4121
|
});
|
|
4116
4122
|
import { Database } from "bun:sqlite";
|
|
@@ -4339,6 +4345,33 @@ function resolvePartialId(db, table, partialId) {
|
|
|
4339
4345
|
}
|
|
4340
4346
|
return null;
|
|
4341
4347
|
}
|
|
4348
|
+
function resolveAssignedToAliases(db, ref) {
|
|
4349
|
+
const aliases = new Set([ref]);
|
|
4350
|
+
let agentId;
|
|
4351
|
+
try {
|
|
4352
|
+
agentId = resolvePartialId(db, "agents", ref);
|
|
4353
|
+
} catch (err) {
|
|
4354
|
+
if (!(err instanceof IdentityAliasAmbiguousError))
|
|
4355
|
+
throw err;
|
|
4356
|
+
agentId = null;
|
|
4357
|
+
}
|
|
4358
|
+
if (agentId) {
|
|
4359
|
+
aliases.add(agentId);
|
|
4360
|
+
const row = db.query("SELECT name FROM agents WHERE id = ?").get(agentId);
|
|
4361
|
+
if (row?.name)
|
|
4362
|
+
aliases.add(row.name);
|
|
4363
|
+
}
|
|
4364
|
+
return [...aliases];
|
|
4365
|
+
}
|
|
4366
|
+
function assignedToAliasSet(db, ref) {
|
|
4367
|
+
return new Set(resolveAssignedToAliases(db, ref).map((a) => a.toLowerCase()));
|
|
4368
|
+
}
|
|
4369
|
+
function lowerInClause(column, values, params) {
|
|
4370
|
+
if (values.length === 0)
|
|
4371
|
+
return "1=0";
|
|
4372
|
+
params.push(...values.map((v) => v.toLowerCase()));
|
|
4373
|
+
return `LOWER(${column}) IN (${values.map(() => "?").join(",")})`;
|
|
4374
|
+
}
|
|
4342
4375
|
var LOCK_EXPIRY_MINUTES = 30, _db = null, _dbPath = null, ALLOWED_TABLES;
|
|
4343
4376
|
var init_database = __esm(() => {
|
|
4344
4377
|
init_schema();
|
|
@@ -4979,17 +5012,19 @@ function checkCompletionGuard(task, agentId, db, configOverride) {
|
|
|
4979
5012
|
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);
|
|
4980
5013
|
}
|
|
4981
5014
|
}
|
|
5015
|
+
const assignedAliasParams = [];
|
|
5016
|
+
const assignedInClause = agent ? lowerInClause("assigned_to", resolveAssignedToAliases(db, agent), assignedAliasParams) : "";
|
|
4982
5017
|
if (agent && config.max_completions_per_window && config.window_minutes) {
|
|
4983
5018
|
const windowStart = new Date(Date.now() - config.window_minutes * 60 * 1000).toISOString();
|
|
4984
5019
|
const result = db.query(`SELECT COUNT(*) as count FROM tasks
|
|
4985
|
-
WHERE completed_at > ? AND (
|
|
5020
|
+
WHERE completed_at > ? AND (${assignedInClause} OR agent_id = ?)`).get(windowStart, ...assignedAliasParams, agent);
|
|
4986
5021
|
if (result.count >= config.max_completions_per_window) {
|
|
4987
5022
|
throw new CompletionGuardError(`Rate limit: ${result.count} tasks completed in the last ${config.window_minutes} minutes (max ${config.max_completions_per_window}). Slow down.`);
|
|
4988
5023
|
}
|
|
4989
5024
|
}
|
|
4990
5025
|
if (agent && config.cooldown_seconds) {
|
|
4991
5026
|
const result = db.query(`SELECT MAX(completed_at) as last_completed FROM tasks
|
|
4992
|
-
WHERE completed_at IS NOT NULL AND (
|
|
5027
|
+
WHERE completed_at IS NOT NULL AND (${assignedInClause} OR agent_id = ?) AND id != ?`).get(...assignedAliasParams, agent, task.id);
|
|
4993
5028
|
if (result.last_completed) {
|
|
4994
5029
|
const elapsedSeconds = (Date.now() - new Date(result.last_completed).getTime()) / 1000;
|
|
4995
5030
|
if (elapsedSeconds < config.cooldown_seconds) {
|
|
@@ -5003,6 +5038,7 @@ var init_completion_guard = __esm(() => {
|
|
|
5003
5038
|
init_types();
|
|
5004
5039
|
init_config2();
|
|
5005
5040
|
init_projects();
|
|
5041
|
+
init_database();
|
|
5006
5042
|
});
|
|
5007
5043
|
|
|
5008
5044
|
// src/lib/event-emission-safety.ts
|
|
@@ -7232,7 +7268,7 @@ function getRecap(hours = 8, projectId, db) {
|
|
|
7232
7268
|
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();
|
|
7233
7269
|
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();
|
|
7234
7270
|
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);
|
|
7235
|
-
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);
|
|
7271
|
+
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);
|
|
7236
7272
|
return {
|
|
7237
7273
|
hours,
|
|
7238
7274
|
since,
|
|
@@ -7385,13 +7421,17 @@ function logDelivery(d, webhookId, event, payload, statusCode, response, attempt
|
|
|
7385
7421
|
const id = uuid();
|
|
7386
7422
|
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()]);
|
|
7387
7423
|
}
|
|
7388
|
-
function matchesScope(wh, payload) {
|
|
7424
|
+
function matchesScope(wh, payload, db) {
|
|
7389
7425
|
if (wh.project_id && payload.project_id !== wh.project_id)
|
|
7390
7426
|
return false;
|
|
7391
7427
|
if (wh.task_list_id && payload.task_list_id !== wh.task_list_id)
|
|
7392
7428
|
return false;
|
|
7393
|
-
if (wh.agent_id && payload.agent_id !== wh.agent_id
|
|
7394
|
-
|
|
7429
|
+
if (wh.agent_id && payload.agent_id !== wh.agent_id) {
|
|
7430
|
+
const aliasSet = assignedToAliasSet(db, wh.agent_id);
|
|
7431
|
+
const assignedTo = typeof payload.assigned_to === "string" ? payload.assigned_to.toLowerCase() : "";
|
|
7432
|
+
if (!aliasSet.has(assignedTo))
|
|
7433
|
+
return false;
|
|
7434
|
+
}
|
|
7395
7435
|
if (wh.task_id && payload.id !== wh.task_id)
|
|
7396
7436
|
return false;
|
|
7397
7437
|
return true;
|
|
@@ -7458,7 +7498,7 @@ async function dispatchWebhook2(event, payload, db) {
|
|
|
7458
7498
|
const webhooks = listWebhooks(d).filter((w) => w.active && (w.events.length === 0 || w.events.includes(event)));
|
|
7459
7499
|
const payloadObj = typeof payload === "object" && payload !== null ? payload : {};
|
|
7460
7500
|
for (const wh of webhooks) {
|
|
7461
|
-
if (!matchesScope(wh, payloadObj))
|
|
7501
|
+
if (!matchesScope(wh, payloadObj, d))
|
|
7462
7502
|
continue;
|
|
7463
7503
|
const body = JSON.stringify({ event, payload, timestamp: now() });
|
|
7464
7504
|
deliverWebhook(wh, event, body, 1, d).catch((err) => {
|
|
@@ -8561,14 +8601,16 @@ function getNextTask(agentId, filters, db) {
|
|
|
8561
8601
|
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')");
|
|
8562
8602
|
const where = conditions.join(" AND ");
|
|
8563
8603
|
let recentProjectIds = [];
|
|
8604
|
+
const assignedAliasParams = [];
|
|
8605
|
+
const assignedInClause = agentId ? lowerInClause("assigned_to", resolveAssignedToAliases(d, agentId), assignedAliasParams) : "";
|
|
8564
8606
|
if (agentId) {
|
|
8565
|
-
const recentRows = d.query(`SELECT DISTINCT project_id FROM tasks WHERE
|
|
8607
|
+
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);
|
|
8566
8608
|
recentProjectIds = recentRows.map((r) => r.project_id);
|
|
8567
8609
|
}
|
|
8568
8610
|
let sql = `SELECT * FROM tasks WHERE ${where} ORDER BY `;
|
|
8569
8611
|
if (agentId) {
|
|
8570
|
-
sql += `CASE WHEN
|
|
8571
|
-
params.push(
|
|
8612
|
+
sql += `CASE WHEN ${assignedInClause} THEN 0 WHEN assigned_to IS NULL THEN 1 ELSE 2 END, `;
|
|
8613
|
+
params.push(...assignedAliasParams);
|
|
8572
8614
|
}
|
|
8573
8615
|
if (recentProjectIds.length > 0) {
|
|
8574
8616
|
const placeholders = recentProjectIds.map(() => "?").join(",");
|
|
@@ -8962,30 +9004,6 @@ function getTaskWithRelations(id, db) {
|
|
|
8962
9004
|
checklist
|
|
8963
9005
|
};
|
|
8964
9006
|
}
|
|
8965
|
-
function resolveAssignedToAliases(db, ref) {
|
|
8966
|
-
const aliases = new Set([ref]);
|
|
8967
|
-
let agentId;
|
|
8968
|
-
try {
|
|
8969
|
-
agentId = resolvePartialId(db, "agents", ref);
|
|
8970
|
-
} catch (err) {
|
|
8971
|
-
if (!(err instanceof IdentityAliasAmbiguousError))
|
|
8972
|
-
throw err;
|
|
8973
|
-
agentId = null;
|
|
8974
|
-
}
|
|
8975
|
-
if (agentId) {
|
|
8976
|
-
aliases.add(agentId);
|
|
8977
|
-
const row = db.query("SELECT name FROM agents WHERE id = ?").get(agentId);
|
|
8978
|
-
if (row?.name)
|
|
8979
|
-
aliases.add(row.name);
|
|
8980
|
-
}
|
|
8981
|
-
return [...aliases];
|
|
8982
|
-
}
|
|
8983
|
-
function lowerInClause(column, values, params) {
|
|
8984
|
-
if (values.length === 0)
|
|
8985
|
-
return "1=0";
|
|
8986
|
-
params.push(...values.map((v) => v.toLowerCase()));
|
|
8987
|
-
return `LOWER(${column}) IN (${values.map(() => "?").join(",")})`;
|
|
8988
|
-
}
|
|
8989
9007
|
function listTasks(filter = {}, db) {
|
|
8990
9008
|
const d = db || getDatabase();
|
|
8991
9009
|
const { clearExpiredLocks: clearExpiredLocks2 } = (init_database(), __toCommonJS(exports_database));
|
|
@@ -9271,11 +9289,13 @@ function updateTask(id, input, db) {
|
|
|
9271
9289
|
}
|
|
9272
9290
|
sets.push("status = ?");
|
|
9273
9291
|
params.push(input.status);
|
|
9292
|
+
if (isTerminalStatus(input.status)) {
|
|
9293
|
+
sets.push("locked_by = NULL");
|
|
9294
|
+
sets.push("locked_at = NULL");
|
|
9295
|
+
}
|
|
9274
9296
|
if (input.status === "completed") {
|
|
9275
9297
|
sets.push("completed_at = ?");
|
|
9276
9298
|
params.push(completionTimestamp);
|
|
9277
|
-
sets.push("locked_by = NULL");
|
|
9278
|
-
sets.push("locked_at = NULL");
|
|
9279
9299
|
} else if (task.status === "completed" && input.completed_at === undefined) {
|
|
9280
9300
|
sets.push("completed_at = NULL");
|
|
9281
9301
|
}
|
|
@@ -9399,6 +9419,7 @@ function updateTask(id, input, db) {
|
|
|
9399
9419
|
logTaskChange(id, "approve", "approved_by", null, input.approved_by, agentId, d);
|
|
9400
9420
|
const reopened = input.status !== undefined && input.status !== "completed" && task.status === "completed" && input.completed_at === undefined;
|
|
9401
9421
|
const completedNow = input.status === "completed";
|
|
9422
|
+
const terminalNow = input.status !== undefined && isTerminalStatus(input.status);
|
|
9402
9423
|
const updatedTask = {
|
|
9403
9424
|
...task,
|
|
9404
9425
|
...Object.fromEntries(Object.entries(input).filter(([, v]) => v !== undefined)),
|
|
@@ -9406,8 +9427,8 @@ function updateTask(id, input, db) {
|
|
|
9406
9427
|
metadata: input.metadata ?? task.metadata,
|
|
9407
9428
|
version: task.version + 1,
|
|
9408
9429
|
updated_at: timestamp2,
|
|
9409
|
-
locked_by:
|
|
9410
|
-
locked_at:
|
|
9430
|
+
locked_by: terminalNow ? null : task.locked_by,
|
|
9431
|
+
locked_at: terminalNow ? null : task.locked_at,
|
|
9411
9432
|
completed_at: completedNow ? completionTimestamp : reopened ? null : input.completed_at !== undefined ? input.completed_at : task.completed_at,
|
|
9412
9433
|
sla_minutes: input.sla_minutes !== undefined ? input.sla_minutes : task.sla_minutes,
|
|
9413
9434
|
actual_minutes: input.actual_minutes ?? task.actual_minutes,
|
|
@@ -9458,6 +9479,7 @@ function deleteTask(id, db) {
|
|
|
9458
9479
|
var init_task_crud = __esm(() => {
|
|
9459
9480
|
init_types();
|
|
9460
9481
|
init_database();
|
|
9482
|
+
init_database();
|
|
9461
9483
|
init_completion_guard();
|
|
9462
9484
|
init_event_emission_safety();
|
|
9463
9485
|
init_event_hooks();
|
|
@@ -9620,8 +9642,8 @@ function getTaskStats(filters, db) {
|
|
|
9620
9642
|
params.push(filters.task_list_id);
|
|
9621
9643
|
}
|
|
9622
9644
|
if (filters?.agent_id) {
|
|
9623
|
-
|
|
9624
|
-
|
|
9645
|
+
params.push(filters.agent_id);
|
|
9646
|
+
conditions.push(`(agent_id = ? OR ${lowerInClause("assigned_to", resolveAssignedToAliases(d, filters.agent_id), params)})`);
|
|
9625
9647
|
}
|
|
9626
9648
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
9627
9649
|
const totalRow = d.query(`SELECT COUNT(*) as count FROM tasks ${where}`).get(...params);
|
|
@@ -9757,8 +9779,7 @@ function getEscalatedTasks(opts = {}, db, at = new Date) {
|
|
|
9757
9779
|
params.push(opts.project_id);
|
|
9758
9780
|
}
|
|
9759
9781
|
if (opts.agent_id) {
|
|
9760
|
-
conditions.push("assigned_to
|
|
9761
|
-
params.push(opts.agent_id);
|
|
9782
|
+
conditions.push(lowerInClause("assigned_to", resolveAssignedToAliases(d, opts.agent_id), params));
|
|
9762
9783
|
}
|
|
9763
9784
|
const rows = d.query(`SELECT * FROM tasks WHERE ${conditions.join(" AND ")} ORDER BY due_at ASC, created_at ASC`).all(...params);
|
|
9764
9785
|
return rows.map(rowToTask).map((task) => {
|
|
@@ -9991,13 +10012,14 @@ function getTimeReport(opts, db) {
|
|
|
9991
10012
|
params.push(opts.plan_id);
|
|
9992
10013
|
}
|
|
9993
10014
|
if (opts?.agent_id) {
|
|
10015
|
+
const assignedInClause = lowerInClause("t.assigned_to", resolveAssignedToAliases(d, opts.agent_id), params);
|
|
9994
10016
|
conditions.push(`(
|
|
9995
|
-
|
|
10017
|
+
${assignedInClause}
|
|
9996
10018
|
OR t.agent_id = ?
|
|
9997
10019
|
OR EXISTS (SELECT 1 FROM task_time_logs ttl WHERE ttl.task_id = t.id AND ttl.agent_id = ?)
|
|
9998
10020
|
OR EXISTS (SELECT 1 FROM focus_sessions fs WHERE fs.task_id = t.id AND fs.agent_id = ?)
|
|
9999
10021
|
)`);
|
|
10000
|
-
params.push(opts.agent_id, opts.agent_id, opts.agent_id
|
|
10022
|
+
params.push(opts.agent_id, opts.agent_id, opts.agent_id);
|
|
10001
10023
|
}
|
|
10002
10024
|
if (opts?.since) {
|
|
10003
10025
|
conditions.push("(t.completed_at >= ? OR t.updated_at >= ?)");
|
|
@@ -12009,7 +12031,7 @@ var init_tasks = __esm(() => {
|
|
|
12009
12031
|
// package.json
|
|
12010
12032
|
var package_default = {
|
|
12011
12033
|
name: "@hasna/todos",
|
|
12012
|
-
version: "0.
|
|
12034
|
+
version: "0.14.0",
|
|
12013
12035
|
description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
12014
12036
|
type: "module",
|
|
12015
12037
|
main: "dist/index.js",
|
|
@@ -22021,11 +22043,12 @@ function runAlerts(input, db, checkedAt, quieted) {
|
|
|
22021
22043
|
if (input.include_runs === false)
|
|
22022
22044
|
return [];
|
|
22023
22045
|
const since = Date.parse(input.run_since || new Date(Date.parse(checkedAt) - 24 * 60 * 60000).toISOString());
|
|
22046
|
+
const runAlertAliases = input.agent_id ? assignedToAliasSet(db, input.agent_id) : null;
|
|
22024
22047
|
return listTaskRuns(undefined, db).filter((run) => run.completed_at && Date.parse(run.completed_at) >= since).map((run) => {
|
|
22025
22048
|
const task2 = getTask(run.task_id, db);
|
|
22026
22049
|
if (input.project_id && task2?.project_id !== input.project_id)
|
|
22027
22050
|
return null;
|
|
22028
|
-
if (input.agent_id && run.agent_id !== input.agent_id && task2?.assigned_to
|
|
22051
|
+
if (input.agent_id && run.agent_id !== input.agent_id && !(runAlertAliases && runAlertAliases.has((task2?.assigned_to ?? "").toLowerCase())))
|
|
22029
22052
|
return null;
|
|
22030
22053
|
const failed = ["failed", "cancelled"].includes(run.status);
|
|
22031
22054
|
return {
|
|
@@ -22070,6 +22093,7 @@ async function checkLocalNotifications(input = {}, db) {
|
|
|
22070
22093
|
const warnings = [];
|
|
22071
22094
|
if (Number.isNaN(checkedMs))
|
|
22072
22095
|
warnings.push("Invalid check timestamp; due-soon window may be incomplete.");
|
|
22096
|
+
const notifyAgentAliases = input.agent_id ? assignedToAliasSet(d, input.agent_id) : null;
|
|
22073
22097
|
const alerts = [];
|
|
22074
22098
|
for (const escalation of getEscalatedTasks({ project_id: input.project_id, agent_id: input.agent_id }, d, new Date(checkedAt))) {
|
|
22075
22099
|
for (const reason of escalation.reasons) {
|
|
@@ -22081,7 +22105,7 @@ async function checkLocalNotifications(input = {}, db) {
|
|
|
22081
22105
|
for (const task2 of listTasks({ project_id: input.project_id, include_archived: false, limit: 5000 }, d)) {
|
|
22082
22106
|
if (!unfinished(task2) || !task2.due_at)
|
|
22083
22107
|
continue;
|
|
22084
|
-
if (input.agent_id && task2.
|
|
22108
|
+
if (input.agent_id && task2.agent_id !== input.agent_id && !(notifyAgentAliases && notifyAgentAliases.has((task2.assigned_to ?? "").toLowerCase())))
|
|
22085
22109
|
continue;
|
|
22086
22110
|
if (task2.due_at > checkedAt && task2.due_at <= dueSoonUntil) {
|
|
22087
22111
|
alerts.push(taskAlert(task2, "task_due_soon", "task.due_soon", "warning", `Due soon: ${task2.title}`, task2.due_at, quieted));
|
|
@@ -22089,7 +22113,7 @@ async function checkLocalNotifications(input = {}, db) {
|
|
|
22089
22113
|
}
|
|
22090
22114
|
}
|
|
22091
22115
|
for (const task2 of getStaleTasks(staleMinutes, { project_id: input.project_id }, d)) {
|
|
22092
|
-
if (input.agent_id && task2.
|
|
22116
|
+
if (input.agent_id && task2.agent_id !== input.agent_id && !(notifyAgentAliases && notifyAgentAliases.has((task2.assigned_to ?? "").toLowerCase())))
|
|
22093
22117
|
continue;
|
|
22094
22118
|
alerts.push(taskAlert(task2, "task_stale", "task.stale", "warning", `Stale task: ${task2.title}`, checkedAt, quieted, { stale_minutes: staleMinutes }));
|
|
22095
22119
|
}
|
|
@@ -22217,14 +22241,15 @@ function millisBetween(start, end) {
|
|
|
22217
22241
|
return 0;
|
|
22218
22242
|
return endMs - startMs;
|
|
22219
22243
|
}
|
|
22220
|
-
function addTaskScope(where, params, options, alias = "t") {
|
|
22244
|
+
function addTaskScope(where, params, options, db, alias = "t") {
|
|
22221
22245
|
if (options.project_id) {
|
|
22222
22246
|
where.push(`${alias}.project_id = ?`);
|
|
22223
22247
|
params.push(options.project_id);
|
|
22224
22248
|
}
|
|
22225
22249
|
if (options.agent_id) {
|
|
22226
|
-
|
|
22227
|
-
|
|
22250
|
+
params.push(options.agent_id);
|
|
22251
|
+
const assignedInClause = lowerInClause(`${alias}.assigned_to`, resolveAssignedToAliases(db, options.agent_id), params);
|
|
22252
|
+
where.push(`(${alias}.agent_id = ? OR ${assignedInClause})`);
|
|
22228
22253
|
}
|
|
22229
22254
|
if (options.since) {
|
|
22230
22255
|
where.push(`${alias}.created_at >= ?`);
|
|
@@ -22235,14 +22260,15 @@ function addTaskScope(where, params, options, alias = "t") {
|
|
|
22235
22260
|
params.push(options.until);
|
|
22236
22261
|
}
|
|
22237
22262
|
}
|
|
22238
|
-
function addRunScope(where, params, options, runAlias = "r", taskAlias = "t") {
|
|
22263
|
+
function addRunScope(where, params, options, db, runAlias = "r", taskAlias = "t") {
|
|
22239
22264
|
if (options.project_id) {
|
|
22240
22265
|
where.push(`${taskAlias}.project_id = ?`);
|
|
22241
22266
|
params.push(options.project_id);
|
|
22242
22267
|
}
|
|
22243
22268
|
if (options.agent_id) {
|
|
22244
|
-
|
|
22245
|
-
|
|
22269
|
+
params.push(options.agent_id, options.agent_id);
|
|
22270
|
+
const assignedInClause = lowerInClause(`${taskAlias}.assigned_to`, resolveAssignedToAliases(db, options.agent_id), params);
|
|
22271
|
+
where.push(`(${runAlias}.agent_id = ? OR ${taskAlias}.agent_id = ? OR ${assignedInClause})`);
|
|
22246
22272
|
}
|
|
22247
22273
|
if (options.since) {
|
|
22248
22274
|
where.push(`${runAlias}.started_at >= ?`);
|
|
@@ -22253,14 +22279,15 @@ function addRunScope(where, params, options, runAlias = "r", taskAlias = "t") {
|
|
|
22253
22279
|
params.push(options.until);
|
|
22254
22280
|
}
|
|
22255
22281
|
}
|
|
22256
|
-
function addTraceScope(where, params, options, traceAlias = "tr", taskAlias = "t") {
|
|
22282
|
+
function addTraceScope(where, params, options, db, traceAlias = "tr", taskAlias = "t") {
|
|
22257
22283
|
if (options.project_id) {
|
|
22258
22284
|
where.push(`${taskAlias}.project_id = ?`);
|
|
22259
22285
|
params.push(options.project_id);
|
|
22260
22286
|
}
|
|
22261
22287
|
if (options.agent_id) {
|
|
22262
|
-
|
|
22263
|
-
|
|
22288
|
+
params.push(options.agent_id, options.agent_id);
|
|
22289
|
+
const assignedInClause = lowerInClause(`${taskAlias}.assigned_to`, resolveAssignedToAliases(db, options.agent_id), params);
|
|
22290
|
+
where.push(`(${traceAlias}.agent_id = ? OR ${taskAlias}.agent_id = ? OR ${assignedInClause})`);
|
|
22264
22291
|
}
|
|
22265
22292
|
if (options.since) {
|
|
22266
22293
|
where.push(`${traceAlias}.created_at >= ?`);
|
|
@@ -22320,7 +22347,7 @@ function createLocalUsageLedger(options = {}, db) {
|
|
|
22320
22347
|
const generatedAt = options.generated_at || new Date().toISOString();
|
|
22321
22348
|
const taskWhere = [];
|
|
22322
22349
|
const taskParams = [];
|
|
22323
|
-
addTaskScope(taskWhere, taskParams, options);
|
|
22350
|
+
addTaskScope(taskWhere, taskParams, options, d);
|
|
22324
22351
|
const taskClause = taskWhere.length ? `WHERE ${taskWhere.join(" AND ")}` : "";
|
|
22325
22352
|
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);
|
|
22326
22353
|
let projectCount = 0;
|
|
@@ -22329,14 +22356,14 @@ function createLocalUsageLedger(options = {}, db) {
|
|
|
22329
22356
|
} else if (options.agent_id) {
|
|
22330
22357
|
const projectWhere = ["t.project_id IS NOT NULL"];
|
|
22331
22358
|
const projectParams = [];
|
|
22332
|
-
addTaskScope(projectWhere, projectParams, options);
|
|
22359
|
+
addTaskScope(projectWhere, projectParams, options, d);
|
|
22333
22360
|
projectCount = queryOne(d, `SELECT COUNT(DISTINCT t.project_id) as count FROM tasks t WHERE ${projectWhere.join(" AND ")}`, projectParams).count;
|
|
22334
22361
|
} else {
|
|
22335
22362
|
projectCount = queryOne(d, "SELECT COUNT(*) as count FROM projects", []).count;
|
|
22336
22363
|
}
|
|
22337
22364
|
const runWhere = [];
|
|
22338
22365
|
const runParams = [];
|
|
22339
|
-
addRunScope(runWhere, runParams, options);
|
|
22366
|
+
addRunScope(runWhere, runParams, options, d);
|
|
22340
22367
|
const runClause = runWhere.length ? `WHERE ${runWhere.join(" AND ")}` : "";
|
|
22341
22368
|
const runs = queryAll(d, `SELECT r.id, r.started_at, r.completed_at, r.metadata
|
|
22342
22369
|
FROM task_runs r JOIN tasks t ON t.id = r.task_id
|
|
@@ -22353,7 +22380,7 @@ function createLocalUsageLedger(options = {}, db) {
|
|
|
22353
22380
|
${runClause}`, runParams);
|
|
22354
22381
|
const traceWhere = [];
|
|
22355
22382
|
const traceParams = [];
|
|
22356
|
-
addTraceScope(traceWhere, traceParams, options);
|
|
22383
|
+
addTraceScope(traceWhere, traceParams, options, d);
|
|
22357
22384
|
const traceClause = traceWhere.length ? `WHERE ${traceWhere.join(" AND ")}` : "";
|
|
22358
22385
|
const traceTotals = queryOne(d, `SELECT COUNT(*) as traces,
|
|
22359
22386
|
COALESCE(SUM(tr.tokens), 0) as tokens,
|
|
@@ -22485,7 +22512,6 @@ function renderLocalUsageLedgerMarkdown(report) {
|
|
|
22485
22512
|
}
|
|
22486
22513
|
// src/lib/local-reports.ts
|
|
22487
22514
|
init_database();
|
|
22488
|
-
init_database();
|
|
22489
22515
|
init_plans();
|
|
22490
22516
|
init_tasks();
|
|
22491
22517
|
var LOCAL_REPORT_SCHEMA_VERSION = 1;
|
|
@@ -22508,10 +22534,12 @@ function limitValue(value) {
|
|
|
22508
22534
|
function isTerminal(task2) {
|
|
22509
22535
|
return task2.status === "completed" || task2.status === "failed" || task2.status === "cancelled";
|
|
22510
22536
|
}
|
|
22511
|
-
function sameAgent(task2, agentId) {
|
|
22537
|
+
function sameAgent(task2, agentId, aliasSet) {
|
|
22512
22538
|
if (!agentId)
|
|
22513
22539
|
return true;
|
|
22514
|
-
|
|
22540
|
+
if (task2.agent_id === agentId)
|
|
22541
|
+
return true;
|
|
22542
|
+
return aliasSet ? aliasSet.has((task2.assigned_to ?? "").toLowerCase()) : task2.assigned_to === agentId;
|
|
22515
22543
|
}
|
|
22516
22544
|
function withinTaskWindow(task2, options) {
|
|
22517
22545
|
const time = Date.parse(task2.updated_at);
|
|
@@ -22524,11 +22552,12 @@ function withinTaskWindow(task2, options) {
|
|
|
22524
22552
|
return true;
|
|
22525
22553
|
}
|
|
22526
22554
|
function scopedTasks(options, db) {
|
|
22555
|
+
const aliasSet = options.agent_id ? assignedToAliasSet(db, options.agent_id) : undefined;
|
|
22527
22556
|
return listTasks({
|
|
22528
22557
|
project_id: options.project_id,
|
|
22529
22558
|
plan_id: options.plan_id,
|
|
22530
22559
|
include_archived: false
|
|
22531
|
-
}, db).filter((task2) => sameAgent(task2, options.agent_id) && withinTaskWindow(task2, options));
|
|
22560
|
+
}, db).filter((task2) => sameAgent(task2, options.agent_id, aliasSet) && withinTaskWindow(task2, options));
|
|
22532
22561
|
}
|
|
22533
22562
|
function summarizeTask(task2) {
|
|
22534
22563
|
return {
|
|
@@ -22594,7 +22623,7 @@ function initialAgentSummary(agentId) {
|
|
|
22594
22623
|
}
|
|
22595
22624
|
};
|
|
22596
22625
|
}
|
|
22597
|
-
function addScopeClauses(where, params, options, timeColumn) {
|
|
22626
|
+
function addScopeClauses(where, params, options, timeColumn, db) {
|
|
22598
22627
|
if (options.project_id) {
|
|
22599
22628
|
where.push("t.project_id = ?");
|
|
22600
22629
|
params.push(options.project_id);
|
|
@@ -22604,8 +22633,9 @@ function addScopeClauses(where, params, options, timeColumn) {
|
|
|
22604
22633
|
params.push(options.plan_id);
|
|
22605
22634
|
}
|
|
22606
22635
|
if (options.agent_id) {
|
|
22607
|
-
|
|
22608
|
-
|
|
22636
|
+
params.push(options.agent_id, options.agent_id);
|
|
22637
|
+
const assignedInClause = lowerInClause("t.assigned_to", resolveAssignedToAliases(db, options.agent_id), params);
|
|
22638
|
+
where.push(`(r.agent_id = ? OR t.agent_id = ? OR ${assignedInClause})`);
|
|
22609
22639
|
}
|
|
22610
22640
|
if (options.since) {
|
|
22611
22641
|
where.push(`${timeColumn} >= ?`);
|
|
@@ -22619,7 +22649,7 @@ function addScopeClauses(where, params, options, timeColumn) {
|
|
|
22619
22649
|
function loadRuns(options, db) {
|
|
22620
22650
|
const where = ["t.archived_at IS NULL"];
|
|
22621
22651
|
const params = [];
|
|
22622
|
-
addScopeClauses(where, params, options, "r.started_at");
|
|
22652
|
+
addScopeClauses(where, params, options, "r.started_at", db);
|
|
22623
22653
|
return db.query(`
|
|
22624
22654
|
SELECT
|
|
22625
22655
|
r.id,
|
|
@@ -22659,8 +22689,9 @@ function loadVerifications(options, db) {
|
|
|
22659
22689
|
params.push(options.plan_id);
|
|
22660
22690
|
}
|
|
22661
22691
|
if (options.agent_id) {
|
|
22662
|
-
|
|
22663
|
-
|
|
22692
|
+
params.push(options.agent_id, options.agent_id);
|
|
22693
|
+
const assignedInClause = lowerInClause("t.assigned_to", resolveAssignedToAliases(db, options.agent_id), params);
|
|
22694
|
+
where.push(`(v.agent_id = ? OR t.agent_id = ? OR ${assignedInClause})`);
|
|
22664
22695
|
}
|
|
22665
22696
|
if (options.since) {
|
|
22666
22697
|
where.push("v.run_at >= ?");
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"packageName": "@hasna/todos",
|
|
3
|
-
"packageVersion": "0.
|
|
3
|
+
"packageVersion": "0.14.0",
|
|
4
4
|
"repository": "https://github.com/hasna/todos.git",
|
|
5
|
-
"gitCommit": "
|
|
6
|
-
"gitTree": "
|
|
7
|
-
"sourceTreeSha256": "
|
|
8
|
-
"generatedAt": "2026-08-
|
|
5
|
+
"gitCommit": "d70f16ca424626adf5eb519e69effdcb1aef5d19",
|
|
6
|
+
"gitTree": "e00228c9804fbf411b6abb43988ce8adf336b152",
|
|
7
|
+
"sourceTreeSha256": "85edd5453eda0f9688079d7a6b7ff49cf3786f08c6b9c615afb68c7eb4604e42",
|
|
8
|
+
"generatedAt": "2026-08-02T17:22:28.000Z"
|
|
9
9
|
}
|
|
@@ -632,8 +632,8 @@ export declare class TodosV1Client {
|
|
|
632
632
|
}>;
|
|
633
633
|
/** List tasks */
|
|
634
634
|
listTasks(query?: {
|
|
635
|
-
"status"?:
|
|
636
|
-
"priority"?:
|
|
635
|
+
"status"?: "pending" | "in_progress" | "completed" | "failed" | "cancelled" | Array<"pending" | "in_progress" | "completed" | "failed" | "cancelled">;
|
|
636
|
+
"priority"?: "low" | "medium" | "high" | "critical" | Array<"low" | "medium" | "high" | "critical">;
|
|
637
637
|
"project_id"?: string;
|
|
638
638
|
"parent_id"?: string | null;
|
|
639
639
|
"include_subtasks"?: boolean;
|