@hasna/todos 0.9.38 → 0.9.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +111 -26
- package/dist/db/tasks.d.ts +1 -0
- package/dist/db/tasks.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/mcp/index.js +11 -5
- package/dist/server/index.js +1337 -726
- package/dist/server/serve.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -3153,6 +3153,38 @@ var init_webhooks = __esm(() => {
|
|
|
3153
3153
|
});
|
|
3154
3154
|
|
|
3155
3155
|
// src/db/tasks.ts
|
|
3156
|
+
var exports_tasks = {};
|
|
3157
|
+
__export(exports_tasks, {
|
|
3158
|
+
updateTask: () => updateTask,
|
|
3159
|
+
unlockTask: () => unlockTask,
|
|
3160
|
+
startTask: () => startTask,
|
|
3161
|
+
removeDependency: () => removeDependency,
|
|
3162
|
+
moveTask: () => moveTask,
|
|
3163
|
+
lockTask: () => lockTask,
|
|
3164
|
+
listTasks: () => listTasks,
|
|
3165
|
+
getTasksChangedSince: () => getTasksChangedSince,
|
|
3166
|
+
getTaskWithRelations: () => getTaskWithRelations,
|
|
3167
|
+
getTaskStats: () => getTaskStats,
|
|
3168
|
+
getTaskGraph: () => getTaskGraph,
|
|
3169
|
+
getTaskDependents: () => getTaskDependents,
|
|
3170
|
+
getTaskDependencies: () => getTaskDependencies,
|
|
3171
|
+
getTask: () => getTask,
|
|
3172
|
+
getStatus: () => getStatus,
|
|
3173
|
+
getStaleTasks: () => getStaleTasks,
|
|
3174
|
+
getNextTask: () => getNextTask,
|
|
3175
|
+
getBlockingDeps: () => getBlockingDeps,
|
|
3176
|
+
getActiveWork: () => getActiveWork,
|
|
3177
|
+
failTask: () => failTask,
|
|
3178
|
+
deleteTask: () => deleteTask,
|
|
3179
|
+
createTask: () => createTask,
|
|
3180
|
+
countTasks: () => countTasks,
|
|
3181
|
+
completeTask: () => completeTask,
|
|
3182
|
+
cloneTask: () => cloneTask,
|
|
3183
|
+
claimNextTask: () => claimNextTask,
|
|
3184
|
+
bulkUpdateTasks: () => bulkUpdateTasks,
|
|
3185
|
+
bulkCreateTasks: () => bulkCreateTasks,
|
|
3186
|
+
addDependency: () => addDependency
|
|
3187
|
+
});
|
|
3156
3188
|
function rowToTask(row) {
|
|
3157
3189
|
return {
|
|
3158
3190
|
...row,
|
|
@@ -3558,8 +3590,8 @@ function completeTask(id, agentId, db, options) {
|
|
|
3558
3590
|
throw new LockError(id, task.locked_by);
|
|
3559
3591
|
}
|
|
3560
3592
|
checkCompletionGuard(task, agentId || null, d);
|
|
3561
|
-
const evidence = options ? { files_changed: options.files_changed, test_results: options.test_results, commit_hash: options.commit_hash, notes: options.notes } : undefined;
|
|
3562
|
-
const hasEvidence = evidence && (evidence.files_changed || evidence.test_results || evidence.commit_hash || evidence.notes);
|
|
3593
|
+
const evidence = options ? { files_changed: options.files_changed, test_results: options.test_results, commit_hash: options.commit_hash, notes: options.notes, attachment_ids: options.attachment_ids } : undefined;
|
|
3594
|
+
const hasEvidence = evidence && (evidence.files_changed || evidence.test_results || evidence.commit_hash || evidence.notes || evidence.attachment_ids);
|
|
3563
3595
|
if (hasEvidence) {
|
|
3564
3596
|
const meta2 = { ...task.metadata, _evidence: evidence };
|
|
3565
3597
|
d.run("UPDATE tasks SET metadata = ? WHERE id = ?", [JSON.stringify(meta2), id]);
|
|
@@ -3639,6 +3671,10 @@ function getTaskDependencies(taskId, db) {
|
|
|
3639
3671
|
const d = db || getDatabase();
|
|
3640
3672
|
return d.query("SELECT * FROM task_dependencies WHERE task_id = ?").all(taskId);
|
|
3641
3673
|
}
|
|
3674
|
+
function getTaskDependents(taskId, db) {
|
|
3675
|
+
const d = db || getDatabase();
|
|
3676
|
+
return d.query("SELECT * FROM task_dependencies WHERE depends_on = ?").all(taskId);
|
|
3677
|
+
}
|
|
3642
3678
|
function cloneTask(taskId, overrides, db) {
|
|
3643
3679
|
const d = db || getDatabase();
|
|
3644
3680
|
const source = getTask(taskId, d);
|
|
@@ -9298,11 +9334,17 @@ Parent: ${task.parent.id.slice(0, 8)} | ${task.parent.title}`);
|
|
|
9298
9334
|
server.tool("complete_task", "Complete a task. For recurring tasks, auto-spawns next instance.", {
|
|
9299
9335
|
id: exports_external.string(),
|
|
9300
9336
|
agent_id: exports_external.string().optional(),
|
|
9301
|
-
skip_recurrence: exports_external.boolean().optional()
|
|
9302
|
-
|
|
9337
|
+
skip_recurrence: exports_external.boolean().optional(),
|
|
9338
|
+
files_changed: exports_external.array(exports_external.string()).optional().describe("List of files changed as part of completing this task"),
|
|
9339
|
+
test_results: exports_external.string().optional().describe("Summary of test results"),
|
|
9340
|
+
commit_hash: exports_external.string().optional().describe("Git commit hash associated with this completion"),
|
|
9341
|
+
notes: exports_external.string().optional().describe("Notes about the completion"),
|
|
9342
|
+
attachment_ids: exports_external.array(exports_external.string()).optional().describe("IDs of attachments uploaded via @hasna/attachments to link as evidence")
|
|
9343
|
+
}, async ({ id, agent_id, skip_recurrence, files_changed, test_results, commit_hash, notes, attachment_ids }) => {
|
|
9303
9344
|
try {
|
|
9304
9345
|
const resolvedId = resolveId(id);
|
|
9305
|
-
const
|
|
9346
|
+
const evidence = files_changed || test_results || commit_hash || notes || attachment_ids ? { files_changed, test_results, commit_hash, notes, attachment_ids } : undefined;
|
|
9347
|
+
const task = completeTask(resolvedId, agent_id, undefined, { skip_recurrence, ...evidence });
|
|
9306
9348
|
let text = `completed: ${formatTask(task)}`;
|
|
9307
9349
|
if (task.metadata._next_recurrence) {
|
|
9308
9350
|
const next = task.metadata._next_recurrence;
|
|
@@ -11027,6 +11069,62 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
11027
11069
|
return json({ error: e instanceof Error ? e.message : "Failed" }, 500, port);
|
|
11028
11070
|
}
|
|
11029
11071
|
}
|
|
11072
|
+
if (path === "/api/tasks/status" && method === "GET") {
|
|
11073
|
+
try {
|
|
11074
|
+
const projectId = url.searchParams.get("project_id") || undefined;
|
|
11075
|
+
const agentId = url.searchParams.get("agent_id") || undefined;
|
|
11076
|
+
const { getStatus: getStatus2 } = await Promise.resolve().then(() => (init_tasks(), exports_tasks));
|
|
11077
|
+
const status = getStatus2(projectId ? { project_id: projectId } : undefined, agentId);
|
|
11078
|
+
return json(status, 200, port);
|
|
11079
|
+
} catch (e) {
|
|
11080
|
+
return json({ error: e instanceof Error ? e.message : "Failed" }, 500, port);
|
|
11081
|
+
}
|
|
11082
|
+
}
|
|
11083
|
+
if (path === "/api/tasks/next" && method === "GET") {
|
|
11084
|
+
try {
|
|
11085
|
+
const projectId = url.searchParams.get("project_id") || undefined;
|
|
11086
|
+
const agentId = url.searchParams.get("agent_id") || undefined;
|
|
11087
|
+
const { getNextTask: getNextTask2 } = await Promise.resolve().then(() => (init_tasks(), exports_tasks));
|
|
11088
|
+
const task = getNextTask2(agentId, projectId ? { project_id: projectId } : undefined);
|
|
11089
|
+
return json({ task: task ? taskToSummary(task) : null }, 200, port);
|
|
11090
|
+
} catch (e) {
|
|
11091
|
+
return json({ error: e instanceof Error ? e.message : "Failed" }, 500, port);
|
|
11092
|
+
}
|
|
11093
|
+
}
|
|
11094
|
+
if (path === "/api/tasks/active" && method === "GET") {
|
|
11095
|
+
try {
|
|
11096
|
+
const projectId = url.searchParams.get("project_id") || undefined;
|
|
11097
|
+
const { getActiveWork: getActiveWork2 } = await Promise.resolve().then(() => (init_tasks(), exports_tasks));
|
|
11098
|
+
const work = getActiveWork2(projectId ? { project_id: projectId } : undefined);
|
|
11099
|
+
return json({ active: work, count: work.length }, 200, port);
|
|
11100
|
+
} catch (e) {
|
|
11101
|
+
return json({ error: e instanceof Error ? e.message : "Failed" }, 500, port);
|
|
11102
|
+
}
|
|
11103
|
+
}
|
|
11104
|
+
if (path === "/api/tasks/stale" && method === "GET") {
|
|
11105
|
+
try {
|
|
11106
|
+
const projectId = url.searchParams.get("project_id") || undefined;
|
|
11107
|
+
const minutes = parseInt(url.searchParams.get("minutes") || "30", 10);
|
|
11108
|
+
const { getStaleTasks: getStaleTasks2 } = await Promise.resolve().then(() => (init_tasks(), exports_tasks));
|
|
11109
|
+
const tasks = getStaleTasks2(minutes, projectId ? { project_id: projectId } : undefined);
|
|
11110
|
+
return json({ tasks: tasks.map((t) => taskToSummary(t)), count: tasks.length }, 200, port);
|
|
11111
|
+
} catch (e) {
|
|
11112
|
+
return json({ error: e instanceof Error ? e.message : "Failed" }, 500, port);
|
|
11113
|
+
}
|
|
11114
|
+
}
|
|
11115
|
+
if (path === "/api/tasks/changed" && method === "GET") {
|
|
11116
|
+
try {
|
|
11117
|
+
const since = url.searchParams.get("since");
|
|
11118
|
+
if (!since)
|
|
11119
|
+
return json({ error: "since parameter required (ISO date string)" }, 400, port);
|
|
11120
|
+
const projectId = url.searchParams.get("project_id") || undefined;
|
|
11121
|
+
const { getTasksChangedSince: getTasksChangedSince2 } = await Promise.resolve().then(() => (init_tasks(), exports_tasks));
|
|
11122
|
+
const tasks = getTasksChangedSince2(since, projectId ? { project_id: projectId } : undefined);
|
|
11123
|
+
return json({ tasks: tasks.map((t) => taskToSummary(t)), count: tasks.length, since }, 200, port);
|
|
11124
|
+
} catch (e) {
|
|
11125
|
+
return json({ error: e instanceof Error ? e.message : "Failed" }, 500, port);
|
|
11126
|
+
}
|
|
11127
|
+
}
|
|
11030
11128
|
const taskMatch = path.match(/^\/api\/tasks\/([^/]+)$/);
|
|
11031
11129
|
if (taskMatch) {
|
|
11032
11130
|
const id = taskMatch[1];
|
|
@@ -11121,25 +11219,9 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
11121
11219
|
try {
|
|
11122
11220
|
const body = await req.json();
|
|
11123
11221
|
const agentId = body.agent_id || "anonymous";
|
|
11124
|
-
const
|
|
11125
|
-
const
|
|
11126
|
-
|
|
11127
|
-
return json({ task: null }, 200, port);
|
|
11128
|
-
const order = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
11129
|
-
available.sort((a, b) => (order[a.priority] ?? 4) - (order[b.priority] ?? 4));
|
|
11130
|
-
const target = available[0];
|
|
11131
|
-
try {
|
|
11132
|
-
const claimed = startTask(target.id, agentId);
|
|
11133
|
-
return json({ task: taskToSummary(claimed) }, 200, port);
|
|
11134
|
-
} catch (e) {
|
|
11135
|
-
const next = available[1] || null;
|
|
11136
|
-
return json({
|
|
11137
|
-
task: null,
|
|
11138
|
-
locked_by: target.locked_by,
|
|
11139
|
-
locked_since: target.locked_at,
|
|
11140
|
-
suggested_task: next ? taskToSummary(next) : null
|
|
11141
|
-
}, 200, port);
|
|
11142
|
-
}
|
|
11222
|
+
const { claimNextTask: claimNextTask2 } = await Promise.resolve().then(() => (init_tasks(), exports_tasks));
|
|
11223
|
+
const task = claimNextTask2(agentId, body.project_id ? { project_id: body.project_id } : undefined);
|
|
11224
|
+
return json({ task: task ? taskToSummary(task) : null }, 200, port);
|
|
11143
11225
|
} catch (e) {
|
|
11144
11226
|
return json({ error: e instanceof Error ? e.message : "Failed to claim" }, 500, port);
|
|
11145
11227
|
}
|
|
@@ -12925,12 +13007,15 @@ program2.command("update <id>").description("Update a task").option("--title <te
|
|
|
12925
13007
|
console.log(formatTaskLine(task));
|
|
12926
13008
|
}
|
|
12927
13009
|
});
|
|
12928
|
-
program2.command("done <id>").description("Mark a task as completed").action((id) => {
|
|
13010
|
+
program2.command("done <id>").description("Mark a task as completed").option("--attach-ids <ids>", "Comma-separated @hasna/attachments IDs to link as evidence").option("--files-changed <files>", "Comma-separated list of files changed").option("--test-results <results>", "Test results summary").option("--commit-hash <hash>", "Git commit hash").option("--notes <notes>", "Completion notes").action((id, opts) => {
|
|
12929
13011
|
const globalOpts = program2.opts();
|
|
12930
13012
|
const resolvedId = resolveTaskId(id);
|
|
13013
|
+
const attachmentIds = opts.attachIds ? opts.attachIds.split(",").map((s) => s.trim()) : undefined;
|
|
13014
|
+
const filesChanged = opts.filesChanged ? opts.filesChanged.split(",").map((s) => s.trim()) : undefined;
|
|
13015
|
+
const evidence = attachmentIds || filesChanged || opts.testResults || opts.commitHash || opts.notes ? { attachment_ids: attachmentIds, files_changed: filesChanged, test_results: opts.testResults, commit_hash: opts.commitHash, notes: opts.notes } : undefined;
|
|
12931
13016
|
let task;
|
|
12932
13017
|
try {
|
|
12933
|
-
task = completeTask(resolvedId, globalOpts.agent);
|
|
13018
|
+
task = completeTask(resolvedId, globalOpts.agent, undefined, evidence);
|
|
12934
13019
|
} catch (e) {
|
|
12935
13020
|
handleError(e);
|
|
12936
13021
|
}
|
package/dist/db/tasks.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare function completeTask(id: string, agentId?: string, db?: Database
|
|
|
14
14
|
test_results?: string;
|
|
15
15
|
commit_hash?: string;
|
|
16
16
|
notes?: string;
|
|
17
|
+
attachment_ids?: string[];
|
|
17
18
|
skip_recurrence?: boolean;
|
|
18
19
|
}): Task;
|
|
19
20
|
export declare function lockTask(id: string, agentId: string, db?: Database): LockResult;
|
package/dist/db/tasks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/db/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,YAAY,CAAC;AAC7D,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EACV,IAAI,EACJ,cAAc,EACd,UAAU,EAEV,iBAAiB,EACjB,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAsC3B,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAmDtE;AAED,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,GAAG,IAAI,CAK9D;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,MAAM,EACV,EAAE,CAAC,EAAE,QAAQ,GACZ,iBAAiB,GAAG,IAAI,CAiD1B;AAED,wBAAgB,SAAS,CAAC,MAAM,GAAE,UAAe,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,EAAE,CAoGxE;AAED,wBAAgB,UAAU,CAAC,MAAM,GAAE,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,QAAQ,CAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CA2EnG;AAED,wBAAgB,UAAU,CACxB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,eAAe,EACtB,EAAE,CAAC,EAAE,QAAQ,GACZ,IAAI,CAiIN;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAI7D;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,EAAE,CAUjE;AAED,wBAAgB,SAAS,CACvB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,EAAE,CAAC,EAAE,QAAQ,GACZ,IAAI,CA+BN;AAED,wBAAgB,YAAY,CAC1B,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,MAAM,EAChB,EAAE,CAAC,EAAE,QAAQ,EACb,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/db/tasks.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1461,8 +1461,8 @@ function completeTask(id, agentId, db, options) {
|
|
|
1461
1461
|
throw new LockError(id, task.locked_by);
|
|
1462
1462
|
}
|
|
1463
1463
|
checkCompletionGuard(task, agentId || null, d);
|
|
1464
|
-
const evidence = options ? { files_changed: options.files_changed, test_results: options.test_results, commit_hash: options.commit_hash, notes: options.notes } : undefined;
|
|
1465
|
-
const hasEvidence = evidence && (evidence.files_changed || evidence.test_results || evidence.commit_hash || evidence.notes);
|
|
1464
|
+
const evidence = options ? { files_changed: options.files_changed, test_results: options.test_results, commit_hash: options.commit_hash, notes: options.notes, attachment_ids: options.attachment_ids } : undefined;
|
|
1465
|
+
const hasEvidence = evidence && (evidence.files_changed || evidence.test_results || evidence.commit_hash || evidence.notes || evidence.attachment_ids);
|
|
1466
1466
|
if (hasEvidence) {
|
|
1467
1467
|
const meta2 = { ...task.metadata, _evidence: evidence };
|
|
1468
1468
|
d.run("UPDATE tasks SET metadata = ? WHERE id = ?", [JSON.stringify(meta2), id]);
|
package/dist/mcp/index.js
CHANGED
|
@@ -5618,8 +5618,8 @@ function completeTask(id, agentId, db, options) {
|
|
|
5618
5618
|
throw new LockError(id, task.locked_by);
|
|
5619
5619
|
}
|
|
5620
5620
|
checkCompletionGuard(task, agentId || null, d);
|
|
5621
|
-
const evidence = options ? { files_changed: options.files_changed, test_results: options.test_results, commit_hash: options.commit_hash, notes: options.notes } : undefined;
|
|
5622
|
-
const hasEvidence = evidence && (evidence.files_changed || evidence.test_results || evidence.commit_hash || evidence.notes);
|
|
5621
|
+
const evidence = options ? { files_changed: options.files_changed, test_results: options.test_results, commit_hash: options.commit_hash, notes: options.notes, attachment_ids: options.attachment_ids } : undefined;
|
|
5622
|
+
const hasEvidence = evidence && (evidence.files_changed || evidence.test_results || evidence.commit_hash || evidence.notes || evidence.attachment_ids);
|
|
5623
5623
|
if (hasEvidence) {
|
|
5624
5624
|
const meta2 = { ...task.metadata, _evidence: evidence };
|
|
5625
5625
|
d.run("UPDATE tasks SET metadata = ? WHERE id = ?", [JSON.stringify(meta2), id]);
|
|
@@ -7128,11 +7128,17 @@ server.tool("start_task", "Claim, lock, and set task to in_progress.", {
|
|
|
7128
7128
|
server.tool("complete_task", "Complete a task. For recurring tasks, auto-spawns next instance.", {
|
|
7129
7129
|
id: exports_external.string(),
|
|
7130
7130
|
agent_id: exports_external.string().optional(),
|
|
7131
|
-
skip_recurrence: exports_external.boolean().optional()
|
|
7132
|
-
|
|
7131
|
+
skip_recurrence: exports_external.boolean().optional(),
|
|
7132
|
+
files_changed: exports_external.array(exports_external.string()).optional().describe("List of files changed as part of completing this task"),
|
|
7133
|
+
test_results: exports_external.string().optional().describe("Summary of test results"),
|
|
7134
|
+
commit_hash: exports_external.string().optional().describe("Git commit hash associated with this completion"),
|
|
7135
|
+
notes: exports_external.string().optional().describe("Notes about the completion"),
|
|
7136
|
+
attachment_ids: exports_external.array(exports_external.string()).optional().describe("IDs of attachments uploaded via @hasna/attachments to link as evidence")
|
|
7137
|
+
}, async ({ id, agent_id, skip_recurrence, files_changed, test_results, commit_hash, notes, attachment_ids }) => {
|
|
7133
7138
|
try {
|
|
7134
7139
|
const resolvedId = resolveId(id);
|
|
7135
|
-
const
|
|
7140
|
+
const evidence = files_changed || test_results || commit_hash || notes || attachment_ids ? { files_changed, test_results, commit_hash, notes, attachment_ids } : undefined;
|
|
7141
|
+
const task = completeTask(resolvedId, agent_id, undefined, { skip_recurrence, ...evidence });
|
|
7136
7142
|
let text = `completed: ${formatTask(task)}`;
|
|
7137
7143
|
if (task.metadata._next_recurrence) {
|
|
7138
7144
|
const next = task.metadata._next_recurrence;
|