@hasna/todos 0.9.42 → 0.9.43
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 +127 -1
- package/dist/db/tasks.d.ts +3 -1
- package/dist/db/tasks.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -0
- package/dist/mcp/index.js +73 -0
- package/dist/server/index.js +90 -1
- package/dist/server/serve.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -3158,6 +3158,8 @@ __export(exports_tasks, {
|
|
|
3158
3158
|
updateTask: () => updateTask,
|
|
3159
3159
|
unlockTask: () => unlockTask,
|
|
3160
3160
|
startTask: () => startTask,
|
|
3161
|
+
setTaskStatus: () => setTaskStatus,
|
|
3162
|
+
setTaskPriority: () => setTaskPriority,
|
|
3161
3163
|
removeDependency: () => removeDependency,
|
|
3162
3164
|
moveTask: () => moveTask,
|
|
3163
3165
|
lockTask: () => lockTask,
|
|
@@ -3998,6 +4000,42 @@ function decomposeTasks(parentId, subtasks, options, db) {
|
|
|
3998
4000
|
tx();
|
|
3999
4001
|
return { parent, subtasks: created };
|
|
4000
4002
|
}
|
|
4003
|
+
function setTaskStatus(id, status, _agentId, db) {
|
|
4004
|
+
const d = db || getDatabase();
|
|
4005
|
+
for (let attempt = 0;attempt < 3; attempt++) {
|
|
4006
|
+
const task = getTask(id, d);
|
|
4007
|
+
if (!task)
|
|
4008
|
+
throw new TaskNotFoundError(id);
|
|
4009
|
+
if (task.status === status)
|
|
4010
|
+
return task;
|
|
4011
|
+
try {
|
|
4012
|
+
return updateTask(id, { status, version: task.version }, d);
|
|
4013
|
+
} catch (e) {
|
|
4014
|
+
if (e instanceof VersionConflictError && attempt < 2)
|
|
4015
|
+
continue;
|
|
4016
|
+
throw e;
|
|
4017
|
+
}
|
|
4018
|
+
}
|
|
4019
|
+
throw new Error(`Failed to set status after 3 attempts`);
|
|
4020
|
+
}
|
|
4021
|
+
function setTaskPriority(id, priority, _agentId, db) {
|
|
4022
|
+
const d = db || getDatabase();
|
|
4023
|
+
for (let attempt = 0;attempt < 3; attempt++) {
|
|
4024
|
+
const task = getTask(id, d);
|
|
4025
|
+
if (!task)
|
|
4026
|
+
throw new TaskNotFoundError(id);
|
|
4027
|
+
if (task.priority === priority)
|
|
4028
|
+
return task;
|
|
4029
|
+
try {
|
|
4030
|
+
return updateTask(id, { priority, version: task.version }, d);
|
|
4031
|
+
} catch (e) {
|
|
4032
|
+
if (e instanceof VersionConflictError && attempt < 2)
|
|
4033
|
+
continue;
|
|
4034
|
+
throw e;
|
|
4035
|
+
}
|
|
4036
|
+
}
|
|
4037
|
+
throw new Error(`Failed to set priority after 3 attempts`);
|
|
4038
|
+
}
|
|
4001
4039
|
function wouldCreateCycle(taskId, dependsOn, db) {
|
|
4002
4040
|
const visited = new Set;
|
|
4003
4041
|
const queue = [dependsOn];
|
|
@@ -10707,6 +10745,35 @@ No pending tasks available.`);
|
|
|
10707
10745
|
}
|
|
10708
10746
|
});
|
|
10709
10747
|
}
|
|
10748
|
+
if (shouldRegisterTool("set_task_status")) {
|
|
10749
|
+
server.tool("set_task_status", "Set task status without needing version. Auto-retries on conflict.", {
|
|
10750
|
+
id: exports_external.string(),
|
|
10751
|
+
status: exports_external.enum(["pending", "in_progress", "completed", "failed", "cancelled"]),
|
|
10752
|
+
agent_id: exports_external.string().optional()
|
|
10753
|
+
}, async ({ id, status, agent_id }) => {
|
|
10754
|
+
try {
|
|
10755
|
+
const resolvedId = resolveId(id);
|
|
10756
|
+
const task = setTaskStatus(resolvedId, status, agent_id);
|
|
10757
|
+
return { content: [{ type: "text", text: `set: ${formatTask(task)}` }] };
|
|
10758
|
+
} catch (e) {
|
|
10759
|
+
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
10760
|
+
}
|
|
10761
|
+
});
|
|
10762
|
+
}
|
|
10763
|
+
if (shouldRegisterTool("set_task_priority")) {
|
|
10764
|
+
server.tool("set_task_priority", "Set task priority without needing version. Auto-retries on conflict.", {
|
|
10765
|
+
id: exports_external.string(),
|
|
10766
|
+
priority: exports_external.enum(["low", "medium", "high", "critical"])
|
|
10767
|
+
}, async ({ id, priority }) => {
|
|
10768
|
+
try {
|
|
10769
|
+
const resolvedId = resolveId(id);
|
|
10770
|
+
const task = setTaskPriority(resolvedId, priority);
|
|
10771
|
+
return { content: [{ type: "text", text: `set: ${formatTask(task)}` }] };
|
|
10772
|
+
} catch (e) {
|
|
10773
|
+
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
10774
|
+
}
|
|
10775
|
+
});
|
|
10776
|
+
}
|
|
10710
10777
|
if (shouldRegisterTool("search_tools")) {
|
|
10711
10778
|
server.tool("search_tools", "List all tool names, optionally filtered by substring.", { query: exports_external.string().optional() }, async ({ query }) => {
|
|
10712
10779
|
const all = [
|
|
@@ -10768,6 +10835,8 @@ No pending tasks available.`);
|
|
|
10768
10835
|
"get_stale_tasks",
|
|
10769
10836
|
"get_status",
|
|
10770
10837
|
"decompose_task",
|
|
10838
|
+
"set_task_status",
|
|
10839
|
+
"set_task_priority",
|
|
10771
10840
|
"search_tools",
|
|
10772
10841
|
"describe_tools"
|
|
10773
10842
|
].filter((name) => shouldRegisterTool(name));
|
|
@@ -10943,6 +11012,12 @@ No pending tasks available.`);
|
|
|
10943
11012
|
decompose_task: `Break a task into subtasks in one call. Subtasks inherit project/plan/list from parent.
|
|
10944
11013
|
Params: parent_id(string, req), subtasks(array, req \u2014 [{title, description, priority, assigned_to, estimated_minutes, tags}]), depends_on_prev(boolean \u2014 chain subtasks sequentially)
|
|
10945
11014
|
Example: {parent_id: 'a1b2c3d4', subtasks: [{title: 'Research'}, {title: 'Implement'}, {title: 'Test'}], depends_on_prev: true}`,
|
|
11015
|
+
set_task_status: `Set task status without needing version. Auto-retries on conflict (up to 3 attempts). Use instead of update_task when you only need to change status.
|
|
11016
|
+
Params: id(string, req), status(pending|in_progress|completed|failed|cancelled, req), agent_id(string)
|
|
11017
|
+
Example: {id: 'a1b2c3d4', status: 'completed'}`,
|
|
11018
|
+
set_task_priority: `Set task priority without needing version. Auto-retries on conflict (up to 3 attempts). Use instead of update_task when you only need to change priority.
|
|
11019
|
+
Params: id(string, req), priority(low|medium|high|critical, req)
|
|
11020
|
+
Example: {id: 'a1b2c3d4', priority: 'high'}`,
|
|
10946
11021
|
search_tools: `List all tool names or filter by substring.
|
|
10947
11022
|
Params: query(string, optional)
|
|
10948
11023
|
Example: {query: 'task'}`,
|
|
@@ -11123,6 +11198,7 @@ async function startServer(port, options) {
|
|
|
11123
11198
|
const shouldOpen = options?.open ?? true;
|
|
11124
11199
|
getDatabase();
|
|
11125
11200
|
const sseClients = new Set;
|
|
11201
|
+
const filteredSseClients = new Set;
|
|
11126
11202
|
function broadcastEvent(event) {
|
|
11127
11203
|
const data = JSON.stringify({ ...event, timestamp: new Date().toISOString() });
|
|
11128
11204
|
for (const controller of sseClients) {
|
|
@@ -11134,6 +11210,21 @@ async function startServer(port, options) {
|
|
|
11134
11210
|
sseClients.delete(controller);
|
|
11135
11211
|
}
|
|
11136
11212
|
}
|
|
11213
|
+
const eventName = `task.${event.action}`;
|
|
11214
|
+
for (const client of filteredSseClients) {
|
|
11215
|
+
if (client.events && !client.events.has(eventName) && !client.events.has("*"))
|
|
11216
|
+
continue;
|
|
11217
|
+
if (client.agentId && event.agent_id !== client.agentId)
|
|
11218
|
+
continue;
|
|
11219
|
+
try {
|
|
11220
|
+
client.controller.enqueue(`event: ${eventName}
|
|
11221
|
+
data: ${data}
|
|
11222
|
+
|
|
11223
|
+
`);
|
|
11224
|
+
} catch {
|
|
11225
|
+
filteredSseClients.delete(client);
|
|
11226
|
+
}
|
|
11227
|
+
}
|
|
11137
11228
|
}
|
|
11138
11229
|
const dashboardDir = resolveDashboardDir();
|
|
11139
11230
|
const dashboardExists = existsSync6(dashboardDir);
|
|
@@ -11181,6 +11272,35 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
11181
11272
|
}
|
|
11182
11273
|
});
|
|
11183
11274
|
}
|
|
11275
|
+
if (path === "/api/tasks/stream" && method === "GET") {
|
|
11276
|
+
const agentId = url.searchParams.get("agent_id") || undefined;
|
|
11277
|
+
const projectId = url.searchParams.get("project_id") || undefined;
|
|
11278
|
+
const eventsParam = url.searchParams.get("events");
|
|
11279
|
+
const eventFilter = eventsParam ? new Set(eventsParam.split(",").map((e) => e.trim())) : undefined;
|
|
11280
|
+
const client = { controller: null, agentId, projectId, events: eventFilter };
|
|
11281
|
+
const stream = new ReadableStream({
|
|
11282
|
+
start(controller) {
|
|
11283
|
+
client.controller = controller;
|
|
11284
|
+
filteredSseClients.add(client);
|
|
11285
|
+
controller.enqueue(`: connected
|
|
11286
|
+
|
|
11287
|
+
data: ${JSON.stringify({ type: "connected", agent_id: agentId, timestamp: new Date().toISOString() })}
|
|
11288
|
+
|
|
11289
|
+
`);
|
|
11290
|
+
},
|
|
11291
|
+
cancel() {
|
|
11292
|
+
filteredSseClients.delete(client);
|
|
11293
|
+
}
|
|
11294
|
+
});
|
|
11295
|
+
return new Response(stream, {
|
|
11296
|
+
headers: {
|
|
11297
|
+
"Content-Type": "text/event-stream",
|
|
11298
|
+
"Cache-Control": "no-cache",
|
|
11299
|
+
Connection: "keep-alive",
|
|
11300
|
+
"Access-Control-Allow-Origin": "*"
|
|
11301
|
+
}
|
|
11302
|
+
});
|
|
11303
|
+
}
|
|
11184
11304
|
if (path === "/api/stats" && method === "GET") {
|
|
11185
11305
|
const all = listTasks({ limit: 1e4 });
|
|
11186
11306
|
const projects = listProjects();
|
|
@@ -11199,13 +11319,19 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
11199
11319
|
if (path === "/api/tasks" && method === "GET") {
|
|
11200
11320
|
const status = url.searchParams.get("status") || undefined;
|
|
11201
11321
|
const projectId = url.searchParams.get("project_id") || undefined;
|
|
11322
|
+
const sessionId = url.searchParams.get("session_id") || undefined;
|
|
11323
|
+
const agentId = url.searchParams.get("agent_id") || undefined;
|
|
11202
11324
|
const limitParam = url.searchParams.get("limit");
|
|
11325
|
+
const offsetParam = url.searchParams.get("offset");
|
|
11203
11326
|
const fieldsParam = url.searchParams.get("fields");
|
|
11204
11327
|
const fields = fieldsParam ? fieldsParam.split(",").map((f) => f.trim()).filter(Boolean) : undefined;
|
|
11205
11328
|
const tasks = listTasks({
|
|
11206
11329
|
status,
|
|
11207
11330
|
project_id: projectId,
|
|
11208
|
-
|
|
11331
|
+
session_id: sessionId,
|
|
11332
|
+
agent_id: agentId,
|
|
11333
|
+
limit: limitParam ? parseInt(limitParam, 10) : undefined,
|
|
11334
|
+
offset: offsetParam ? parseInt(offsetParam, 10) : undefined
|
|
11209
11335
|
});
|
|
11210
11336
|
return json(tasks.map((t) => taskToSummary(t, fields)), 200, port);
|
|
11211
11337
|
}
|
package/dist/db/tasks.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Database } from "bun:sqlite";
|
|
2
|
-
import type { CreateTaskInput, LockResult, Task, TaskDependency, TaskFilter, TaskWithRelations, UpdateTaskInput } from "../types/index.js";
|
|
2
|
+
import type { CreateTaskInput, LockResult, Task, TaskDependency, TaskFilter, TaskPriority, TaskStatus, TaskWithRelations, UpdateTaskInput } from "../types/index.js";
|
|
3
3
|
export declare function createTask(input: CreateTaskInput, db?: Database): Task;
|
|
4
4
|
export declare function getTask(id: string, db?: Database): Task | null;
|
|
5
5
|
export declare function getTaskWithRelations(id: string, db?: Database): TaskWithRelations | null;
|
|
@@ -113,6 +113,8 @@ export declare function decomposeTasks(parentId: string, subtasks: DecomposeSubt
|
|
|
113
113
|
parent: Task;
|
|
114
114
|
subtasks: Task[];
|
|
115
115
|
};
|
|
116
|
+
export declare function setTaskStatus(id: string, status: TaskStatus, _agentId?: string, db?: Database): Task;
|
|
117
|
+
export declare function setTaskPriority(id: string, priority: TaskPriority, _agentId?: string, db?: Database): Task;
|
|
116
118
|
export declare function getTaskStats(filters?: {
|
|
117
119
|
project_id?: string;
|
|
118
120
|
task_list_id?: string;
|
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,
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/db/tasks.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { getDatabase, closeDatabase, resetDatabase, resolvePartialId, now, uuid } from "./db/database.js";
|
|
2
|
-
export { createTask, getTask, getTaskWithRelations, listTasks, countTasks, updateTask, deleteTask, startTask, completeTask, lockTask, unlockTask, addDependency, removeDependency, getTaskDependencies, getTaskDependents, getBlockingDeps, bulkUpdateTasks, bulkCreateTasks, cloneTask, getTaskStats, getTaskGraph, moveTask, getNextTask, claimNextTask, getActiveWork, failTask, getTasksChangedSince, getStaleTasks, getStatus, decomposeTasks, } from "./db/tasks.js";
|
|
2
|
+
export { createTask, getTask, getTaskWithRelations, listTasks, countTasks, updateTask, deleteTask, startTask, completeTask, lockTask, unlockTask, addDependency, removeDependency, getTaskDependencies, getTaskDependents, getBlockingDeps, bulkUpdateTasks, bulkCreateTasks, cloneTask, getTaskStats, getTaskGraph, moveTask, getNextTask, claimNextTask, getActiveWork, failTask, getTasksChangedSince, getStaleTasks, getStatus, decomposeTasks, setTaskStatus, setTaskPriority, } from "./db/tasks.js";
|
|
3
3
|
export type { TaskGraphNode, TaskGraph, BulkCreateTaskInput, ActiveWorkItem, StatusSummary, DecomposeSubtaskInput } from "./db/tasks.js";
|
|
4
4
|
export { createProject, getProject, getProjectByPath, listProjects, updateProject, deleteProject, ensureProject, nextTaskShortId, slugify, } from "./db/projects.js";
|
|
5
5
|
export { createPlan, getPlan, listPlans, updatePlan, deletePlan, } from "./db/plans.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAG1G,OAAO,EACL,UAAU,EACV,OAAO,EACP,oBAAoB,EACpB,SAAS,EACT,UAAU,EACV,UAAU,EACV,UAAU,EACV,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,eAAe,EACf,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,aAAa,EACb,aAAa,EACb,QAAQ,EACR,oBAAoB,EACpB,aAAa,EACb,SAAS,EACT,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1868,6 +1868,42 @@ function decomposeTasks(parentId, subtasks, options, db) {
|
|
|
1868
1868
|
tx();
|
|
1869
1869
|
return { parent, subtasks: created };
|
|
1870
1870
|
}
|
|
1871
|
+
function setTaskStatus(id, status, _agentId, db) {
|
|
1872
|
+
const d = db || getDatabase();
|
|
1873
|
+
for (let attempt = 0;attempt < 3; attempt++) {
|
|
1874
|
+
const task = getTask(id, d);
|
|
1875
|
+
if (!task)
|
|
1876
|
+
throw new TaskNotFoundError(id);
|
|
1877
|
+
if (task.status === status)
|
|
1878
|
+
return task;
|
|
1879
|
+
try {
|
|
1880
|
+
return updateTask(id, { status, version: task.version }, d);
|
|
1881
|
+
} catch (e) {
|
|
1882
|
+
if (e instanceof VersionConflictError && attempt < 2)
|
|
1883
|
+
continue;
|
|
1884
|
+
throw e;
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
throw new Error(`Failed to set status after 3 attempts`);
|
|
1888
|
+
}
|
|
1889
|
+
function setTaskPriority(id, priority, _agentId, db) {
|
|
1890
|
+
const d = db || getDatabase();
|
|
1891
|
+
for (let attempt = 0;attempt < 3; attempt++) {
|
|
1892
|
+
const task = getTask(id, d);
|
|
1893
|
+
if (!task)
|
|
1894
|
+
throw new TaskNotFoundError(id);
|
|
1895
|
+
if (task.priority === priority)
|
|
1896
|
+
return task;
|
|
1897
|
+
try {
|
|
1898
|
+
return updateTask(id, { priority, version: task.version }, d);
|
|
1899
|
+
} catch (e) {
|
|
1900
|
+
if (e instanceof VersionConflictError && attempt < 2)
|
|
1901
|
+
continue;
|
|
1902
|
+
throw e;
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
throw new Error(`Failed to set priority after 3 attempts`);
|
|
1906
|
+
}
|
|
1871
1907
|
function wouldCreateCycle(taskId, dependsOn, db) {
|
|
1872
1908
|
const visited = new Set;
|
|
1873
1909
|
const queue = [dependsOn];
|
|
@@ -3033,6 +3069,8 @@ export {
|
|
|
3033
3069
|
syncWithAgent,
|
|
3034
3070
|
startTask,
|
|
3035
3071
|
slugify,
|
|
3072
|
+
setTaskStatus,
|
|
3073
|
+
setTaskPriority,
|
|
3036
3074
|
searchTasks,
|
|
3037
3075
|
resolvePartialId,
|
|
3038
3076
|
resetDatabase,
|
package/dist/mcp/index.js
CHANGED
|
@@ -6021,6 +6021,42 @@ function decomposeTasks(parentId, subtasks, options, db) {
|
|
|
6021
6021
|
tx();
|
|
6022
6022
|
return { parent, subtasks: created };
|
|
6023
6023
|
}
|
|
6024
|
+
function setTaskStatus(id, status, _agentId, db) {
|
|
6025
|
+
const d = db || getDatabase();
|
|
6026
|
+
for (let attempt = 0;attempt < 3; attempt++) {
|
|
6027
|
+
const task = getTask(id, d);
|
|
6028
|
+
if (!task)
|
|
6029
|
+
throw new TaskNotFoundError(id);
|
|
6030
|
+
if (task.status === status)
|
|
6031
|
+
return task;
|
|
6032
|
+
try {
|
|
6033
|
+
return updateTask(id, { status, version: task.version }, d);
|
|
6034
|
+
} catch (e) {
|
|
6035
|
+
if (e instanceof VersionConflictError && attempt < 2)
|
|
6036
|
+
continue;
|
|
6037
|
+
throw e;
|
|
6038
|
+
}
|
|
6039
|
+
}
|
|
6040
|
+
throw new Error(`Failed to set status after 3 attempts`);
|
|
6041
|
+
}
|
|
6042
|
+
function setTaskPriority(id, priority, _agentId, db) {
|
|
6043
|
+
const d = db || getDatabase();
|
|
6044
|
+
for (let attempt = 0;attempt < 3; attempt++) {
|
|
6045
|
+
const task = getTask(id, d);
|
|
6046
|
+
if (!task)
|
|
6047
|
+
throw new TaskNotFoundError(id);
|
|
6048
|
+
if (task.priority === priority)
|
|
6049
|
+
return task;
|
|
6050
|
+
try {
|
|
6051
|
+
return updateTask(id, { priority, version: task.version }, d);
|
|
6052
|
+
} catch (e) {
|
|
6053
|
+
if (e instanceof VersionConflictError && attempt < 2)
|
|
6054
|
+
continue;
|
|
6055
|
+
throw e;
|
|
6056
|
+
}
|
|
6057
|
+
}
|
|
6058
|
+
throw new Error(`Failed to set priority after 3 attempts`);
|
|
6059
|
+
}
|
|
6024
6060
|
function wouldCreateCycle(taskId, dependsOn, db) {
|
|
6025
6061
|
const visited = new Set;
|
|
6026
6062
|
const queue = [dependsOn];
|
|
@@ -8500,6 +8536,35 @@ if (shouldRegisterTool("decompose_task")) {
|
|
|
8500
8536
|
}
|
|
8501
8537
|
});
|
|
8502
8538
|
}
|
|
8539
|
+
if (shouldRegisterTool("set_task_status")) {
|
|
8540
|
+
server.tool("set_task_status", "Set task status without needing version. Auto-retries on conflict.", {
|
|
8541
|
+
id: exports_external.string(),
|
|
8542
|
+
status: exports_external.enum(["pending", "in_progress", "completed", "failed", "cancelled"]),
|
|
8543
|
+
agent_id: exports_external.string().optional()
|
|
8544
|
+
}, async ({ id, status, agent_id }) => {
|
|
8545
|
+
try {
|
|
8546
|
+
const resolvedId = resolveId(id);
|
|
8547
|
+
const task = setTaskStatus(resolvedId, status, agent_id);
|
|
8548
|
+
return { content: [{ type: "text", text: `set: ${formatTask(task)}` }] };
|
|
8549
|
+
} catch (e) {
|
|
8550
|
+
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
8551
|
+
}
|
|
8552
|
+
});
|
|
8553
|
+
}
|
|
8554
|
+
if (shouldRegisterTool("set_task_priority")) {
|
|
8555
|
+
server.tool("set_task_priority", "Set task priority without needing version. Auto-retries on conflict.", {
|
|
8556
|
+
id: exports_external.string(),
|
|
8557
|
+
priority: exports_external.enum(["low", "medium", "high", "critical"])
|
|
8558
|
+
}, async ({ id, priority }) => {
|
|
8559
|
+
try {
|
|
8560
|
+
const resolvedId = resolveId(id);
|
|
8561
|
+
const task = setTaskPriority(resolvedId, priority);
|
|
8562
|
+
return { content: [{ type: "text", text: `set: ${formatTask(task)}` }] };
|
|
8563
|
+
} catch (e) {
|
|
8564
|
+
return { content: [{ type: "text", text: formatError(e) }], isError: true };
|
|
8565
|
+
}
|
|
8566
|
+
});
|
|
8567
|
+
}
|
|
8503
8568
|
if (shouldRegisterTool("search_tools")) {
|
|
8504
8569
|
server.tool("search_tools", "List all tool names, optionally filtered by substring.", { query: exports_external.string().optional() }, async ({ query }) => {
|
|
8505
8570
|
const all = [
|
|
@@ -8561,6 +8626,8 @@ if (shouldRegisterTool("search_tools")) {
|
|
|
8561
8626
|
"get_stale_tasks",
|
|
8562
8627
|
"get_status",
|
|
8563
8628
|
"decompose_task",
|
|
8629
|
+
"set_task_status",
|
|
8630
|
+
"set_task_priority",
|
|
8564
8631
|
"search_tools",
|
|
8565
8632
|
"describe_tools"
|
|
8566
8633
|
].filter((name) => shouldRegisterTool(name));
|
|
@@ -8736,6 +8803,12 @@ if (shouldRegisterTool("describe_tools")) {
|
|
|
8736
8803
|
decompose_task: `Break a task into subtasks in one call. Subtasks inherit project/plan/list from parent.
|
|
8737
8804
|
Params: parent_id(string, req), subtasks(array, req \u2014 [{title, description, priority, assigned_to, estimated_minutes, tags}]), depends_on_prev(boolean \u2014 chain subtasks sequentially)
|
|
8738
8805
|
Example: {parent_id: 'a1b2c3d4', subtasks: [{title: 'Research'}, {title: 'Implement'}, {title: 'Test'}], depends_on_prev: true}`,
|
|
8806
|
+
set_task_status: `Set task status without needing version. Auto-retries on conflict (up to 3 attempts). Use instead of update_task when you only need to change status.
|
|
8807
|
+
Params: id(string, req), status(pending|in_progress|completed|failed|cancelled, req), agent_id(string)
|
|
8808
|
+
Example: {id: 'a1b2c3d4', status: 'completed'}`,
|
|
8809
|
+
set_task_priority: `Set task priority without needing version. Auto-retries on conflict (up to 3 attempts). Use instead of update_task when you only need to change priority.
|
|
8810
|
+
Params: id(string, req), priority(low|medium|high|critical, req)
|
|
8811
|
+
Example: {id: 'a1b2c3d4', priority: 'high'}`,
|
|
8739
8812
|
search_tools: `List all tool names or filter by substring.
|
|
8740
8813
|
Params: query(string, optional)
|
|
8741
8814
|
Example: {query: 'task'}`,
|
package/dist/server/index.js
CHANGED
|
@@ -1002,6 +1002,8 @@ __export(exports_tasks, {
|
|
|
1002
1002
|
updateTask: () => updateTask,
|
|
1003
1003
|
unlockTask: () => unlockTask,
|
|
1004
1004
|
startTask: () => startTask,
|
|
1005
|
+
setTaskStatus: () => setTaskStatus,
|
|
1006
|
+
setTaskPriority: () => setTaskPriority,
|
|
1005
1007
|
removeDependency: () => removeDependency,
|
|
1006
1008
|
moveTask: () => moveTask,
|
|
1007
1009
|
lockTask: () => lockTask,
|
|
@@ -1842,6 +1844,42 @@ function decomposeTasks(parentId, subtasks, options, db) {
|
|
|
1842
1844
|
tx();
|
|
1843
1845
|
return { parent, subtasks: created };
|
|
1844
1846
|
}
|
|
1847
|
+
function setTaskStatus(id, status, _agentId, db) {
|
|
1848
|
+
const d = db || getDatabase();
|
|
1849
|
+
for (let attempt = 0;attempt < 3; attempt++) {
|
|
1850
|
+
const task = getTask(id, d);
|
|
1851
|
+
if (!task)
|
|
1852
|
+
throw new TaskNotFoundError(id);
|
|
1853
|
+
if (task.status === status)
|
|
1854
|
+
return task;
|
|
1855
|
+
try {
|
|
1856
|
+
return updateTask(id, { status, version: task.version }, d);
|
|
1857
|
+
} catch (e) {
|
|
1858
|
+
if (e instanceof VersionConflictError && attempt < 2)
|
|
1859
|
+
continue;
|
|
1860
|
+
throw e;
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
throw new Error(`Failed to set status after 3 attempts`);
|
|
1864
|
+
}
|
|
1865
|
+
function setTaskPriority(id, priority, _agentId, db) {
|
|
1866
|
+
const d = db || getDatabase();
|
|
1867
|
+
for (let attempt = 0;attempt < 3; attempt++) {
|
|
1868
|
+
const task = getTask(id, d);
|
|
1869
|
+
if (!task)
|
|
1870
|
+
throw new TaskNotFoundError(id);
|
|
1871
|
+
if (task.priority === priority)
|
|
1872
|
+
return task;
|
|
1873
|
+
try {
|
|
1874
|
+
return updateTask(id, { priority, version: task.version }, d);
|
|
1875
|
+
} catch (e) {
|
|
1876
|
+
if (e instanceof VersionConflictError && attempt < 2)
|
|
1877
|
+
continue;
|
|
1878
|
+
throw e;
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
throw new Error(`Failed to set priority after 3 attempts`);
|
|
1882
|
+
}
|
|
1845
1883
|
function wouldCreateCycle(taskId, dependsOn, db) {
|
|
1846
1884
|
const visited = new Set;
|
|
1847
1885
|
const queue = [dependsOn];
|
|
@@ -2392,6 +2430,7 @@ async function startServer(port, options) {
|
|
|
2392
2430
|
const shouldOpen = options?.open ?? true;
|
|
2393
2431
|
getDatabase();
|
|
2394
2432
|
const sseClients = new Set;
|
|
2433
|
+
const filteredSseClients = new Set;
|
|
2395
2434
|
function broadcastEvent(event) {
|
|
2396
2435
|
const data = JSON.stringify({ ...event, timestamp: new Date().toISOString() });
|
|
2397
2436
|
for (const controller of sseClients) {
|
|
@@ -2403,6 +2442,21 @@ async function startServer(port, options) {
|
|
|
2403
2442
|
sseClients.delete(controller);
|
|
2404
2443
|
}
|
|
2405
2444
|
}
|
|
2445
|
+
const eventName = `task.${event.action}`;
|
|
2446
|
+
for (const client of filteredSseClients) {
|
|
2447
|
+
if (client.events && !client.events.has(eventName) && !client.events.has("*"))
|
|
2448
|
+
continue;
|
|
2449
|
+
if (client.agentId && event.agent_id !== client.agentId)
|
|
2450
|
+
continue;
|
|
2451
|
+
try {
|
|
2452
|
+
client.controller.enqueue(`event: ${eventName}
|
|
2453
|
+
data: ${data}
|
|
2454
|
+
|
|
2455
|
+
`);
|
|
2456
|
+
} catch {
|
|
2457
|
+
filteredSseClients.delete(client);
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2406
2460
|
}
|
|
2407
2461
|
const dashboardDir = resolveDashboardDir();
|
|
2408
2462
|
const dashboardExists = existsSync4(dashboardDir);
|
|
@@ -2450,6 +2504,35 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
2450
2504
|
}
|
|
2451
2505
|
});
|
|
2452
2506
|
}
|
|
2507
|
+
if (path === "/api/tasks/stream" && method === "GET") {
|
|
2508
|
+
const agentId = url.searchParams.get("agent_id") || undefined;
|
|
2509
|
+
const projectId = url.searchParams.get("project_id") || undefined;
|
|
2510
|
+
const eventsParam = url.searchParams.get("events");
|
|
2511
|
+
const eventFilter = eventsParam ? new Set(eventsParam.split(",").map((e) => e.trim())) : undefined;
|
|
2512
|
+
const client = { controller: null, agentId, projectId, events: eventFilter };
|
|
2513
|
+
const stream = new ReadableStream({
|
|
2514
|
+
start(controller) {
|
|
2515
|
+
client.controller = controller;
|
|
2516
|
+
filteredSseClients.add(client);
|
|
2517
|
+
controller.enqueue(`: connected
|
|
2518
|
+
|
|
2519
|
+
data: ${JSON.stringify({ type: "connected", agent_id: agentId, timestamp: new Date().toISOString() })}
|
|
2520
|
+
|
|
2521
|
+
`);
|
|
2522
|
+
},
|
|
2523
|
+
cancel() {
|
|
2524
|
+
filteredSseClients.delete(client);
|
|
2525
|
+
}
|
|
2526
|
+
});
|
|
2527
|
+
return new Response(stream, {
|
|
2528
|
+
headers: {
|
|
2529
|
+
"Content-Type": "text/event-stream",
|
|
2530
|
+
"Cache-Control": "no-cache",
|
|
2531
|
+
Connection: "keep-alive",
|
|
2532
|
+
"Access-Control-Allow-Origin": "*"
|
|
2533
|
+
}
|
|
2534
|
+
});
|
|
2535
|
+
}
|
|
2453
2536
|
if (path === "/api/stats" && method === "GET") {
|
|
2454
2537
|
const all = listTasks({ limit: 1e4 });
|
|
2455
2538
|
const projects = listProjects();
|
|
@@ -2468,13 +2551,19 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
2468
2551
|
if (path === "/api/tasks" && method === "GET") {
|
|
2469
2552
|
const status = url.searchParams.get("status") || undefined;
|
|
2470
2553
|
const projectId = url.searchParams.get("project_id") || undefined;
|
|
2554
|
+
const sessionId = url.searchParams.get("session_id") || undefined;
|
|
2555
|
+
const agentId = url.searchParams.get("agent_id") || undefined;
|
|
2471
2556
|
const limitParam = url.searchParams.get("limit");
|
|
2557
|
+
const offsetParam = url.searchParams.get("offset");
|
|
2472
2558
|
const fieldsParam = url.searchParams.get("fields");
|
|
2473
2559
|
const fields = fieldsParam ? fieldsParam.split(",").map((f) => f.trim()).filter(Boolean) : undefined;
|
|
2474
2560
|
const tasks = listTasks({
|
|
2475
2561
|
status,
|
|
2476
2562
|
project_id: projectId,
|
|
2477
|
-
|
|
2563
|
+
session_id: sessionId,
|
|
2564
|
+
agent_id: agentId,
|
|
2565
|
+
limit: limitParam ? parseInt(limitParam, 10) : undefined,
|
|
2566
|
+
offset: offsetParam ? parseInt(offsetParam, 10) : undefined
|
|
2478
2567
|
});
|
|
2479
2568
|
return json(tasks.map((t) => taskToSummary(t, fields)), 200, port);
|
|
2480
2569
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/server/serve.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAgHH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/server/serve.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAgHH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA6sB3F"}
|