@hasna/todos 0.9.46 → 0.9.48
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 +86 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +93 -0
- package/dist/sdk.d.ts +36 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/server/index.js +65 -1
- package/dist/server/serve.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -4455,6 +4455,14 @@ var init_plans = __esm(() => {
|
|
|
4455
4455
|
});
|
|
4456
4456
|
|
|
4457
4457
|
// src/db/comments.ts
|
|
4458
|
+
var exports_comments = {};
|
|
4459
|
+
__export(exports_comments, {
|
|
4460
|
+
logProgress: () => logProgress,
|
|
4461
|
+
listComments: () => listComments,
|
|
4462
|
+
getComment: () => getComment,
|
|
4463
|
+
deleteComment: () => deleteComment,
|
|
4464
|
+
addComment: () => addComment
|
|
4465
|
+
});
|
|
4458
4466
|
function addComment(input, db) {
|
|
4459
4467
|
const d = db || getDatabase();
|
|
4460
4468
|
if (!getTask(input.task_id, d)) {
|
|
@@ -4482,6 +4490,15 @@ function getComment(id, db) {
|
|
|
4482
4490
|
const d = db || getDatabase();
|
|
4483
4491
|
return d.query("SELECT * FROM task_comments WHERE id = ?").get(id);
|
|
4484
4492
|
}
|
|
4493
|
+
function listComments(taskId, db) {
|
|
4494
|
+
const d = db || getDatabase();
|
|
4495
|
+
return d.query("SELECT * FROM task_comments WHERE task_id = ? ORDER BY created_at").all(taskId);
|
|
4496
|
+
}
|
|
4497
|
+
function deleteComment(id, db) {
|
|
4498
|
+
const d = db || getDatabase();
|
|
4499
|
+
const result = d.run("DELETE FROM task_comments WHERE id = ?", [id]);
|
|
4500
|
+
return result.changes > 0;
|
|
4501
|
+
}
|
|
4485
4502
|
var init_comments = __esm(() => {
|
|
4486
4503
|
init_types();
|
|
4487
4504
|
init_database();
|
|
@@ -11264,7 +11281,8 @@ function taskToSummary(task, fields) {
|
|
|
11264
11281
|
created_at: task.created_at,
|
|
11265
11282
|
updated_at: task.updated_at,
|
|
11266
11283
|
completed_at: task.completed_at,
|
|
11267
|
-
due_at: task.due_at
|
|
11284
|
+
due_at: task.due_at,
|
|
11285
|
+
recurrence_rule: task.recurrence_rule
|
|
11268
11286
|
};
|
|
11269
11287
|
if (!fields || fields.length === 0)
|
|
11270
11288
|
return full;
|
|
@@ -11555,6 +11573,18 @@ data: ${JSON.stringify({ type: "connected", agent_id: agentId, timestamp: new Da
|
|
|
11555
11573
|
return json({ error: e instanceof Error ? e.message : "Failed" }, 500, port);
|
|
11556
11574
|
}
|
|
11557
11575
|
}
|
|
11576
|
+
const progressMatch = path.match(/^\/api\/tasks\/([^/]+)\/progress$/);
|
|
11577
|
+
if (progressMatch && method === "GET") {
|
|
11578
|
+
const id = progressMatch[1];
|
|
11579
|
+
const task = getTask(id);
|
|
11580
|
+
if (!task)
|
|
11581
|
+
return json({ error: "Task not found" }, 404, port);
|
|
11582
|
+
const { listComments: listComments2 } = await Promise.resolve().then(() => (init_comments(), exports_comments));
|
|
11583
|
+
const all = listComments2(id);
|
|
11584
|
+
const progress = all.filter((c) => c.type === "progress");
|
|
11585
|
+
const latest = progress[progress.length - 1] || null;
|
|
11586
|
+
return json({ task_id: id, progress_entries: progress, latest, count: progress.length }, 200, port);
|
|
11587
|
+
}
|
|
11558
11588
|
const taskMatch = path.match(/^\/api\/tasks\/([^/]+)$/);
|
|
11559
11589
|
if (taskMatch) {
|
|
11560
11590
|
const id = taskMatch[1];
|
|
@@ -14777,6 +14807,61 @@ program2.command("pin <id>").description("Escalate task to critical priority").o
|
|
|
14777
14807
|
handleError(new Error("Failed to pin"));
|
|
14778
14808
|
}
|
|
14779
14809
|
});
|
|
14810
|
+
program2.command("summary").description("Generate a markdown summary of recent task activity").option("--days <n>", "Days of history to include", "7").option("--project <id>", "Filter to project").option("--agent <id>", "Filter to agent").option("--json", "Output as JSON").action(async (opts) => {
|
|
14811
|
+
const globalOpts = program2.opts();
|
|
14812
|
+
const db = getDatabase();
|
|
14813
|
+
const days = parseInt(opts.days, 10);
|
|
14814
|
+
const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
14815
|
+
const projectId = opts.project || autoProject(globalOpts);
|
|
14816
|
+
const filter = {};
|
|
14817
|
+
if (projectId)
|
|
14818
|
+
filter.project_id = projectId;
|
|
14819
|
+
if (opts.agent)
|
|
14820
|
+
filter.assigned_to = opts.agent;
|
|
14821
|
+
const { getTasksChangedSince: getTasksChangedSince2 } = (init_tasks(), __toCommonJS(exports_tasks));
|
|
14822
|
+
const changed = getTasksChangedSince2(since, Object.keys(filter).length ? filter : undefined, db);
|
|
14823
|
+
const completed = changed.filter((t) => t.status === "completed");
|
|
14824
|
+
const inProgress = changed.filter((t) => t.status === "in_progress");
|
|
14825
|
+
const failed = changed.filter((t) => t.status === "failed");
|
|
14826
|
+
const allTasks = listTasks({ ...filter, status: "pending" });
|
|
14827
|
+
if (opts.json || globalOpts.json) {
|
|
14828
|
+
console.log(JSON.stringify({ completed, in_progress: inProgress, failed, pending: allTasks.length, period_days: days }, null, 2));
|
|
14829
|
+
return;
|
|
14830
|
+
}
|
|
14831
|
+
const lines = [];
|
|
14832
|
+
lines.push(`## Task Summary \u2014 Last ${days} day${days !== 1 ? "s" : ""}`);
|
|
14833
|
+
lines.push(`*${new Date().toLocaleDateString()}*
|
|
14834
|
+
`);
|
|
14835
|
+
if (completed.length > 0) {
|
|
14836
|
+
lines.push(`### \u2705 Completed (${completed.length})`);
|
|
14837
|
+
for (const t of completed) {
|
|
14838
|
+
const id = t.short_id || t.id.slice(0, 8);
|
|
14839
|
+
const who = t.assigned_to ? ` \u2014 ${t.assigned_to}` : "";
|
|
14840
|
+
lines.push(`- **${id}**: ${t.title}${who}`);
|
|
14841
|
+
}
|
|
14842
|
+
lines.push("");
|
|
14843
|
+
}
|
|
14844
|
+
if (inProgress.length > 0) {
|
|
14845
|
+
lines.push(`### \uD83D\uDD04 In Progress (${inProgress.length})`);
|
|
14846
|
+
for (const t of inProgress) {
|
|
14847
|
+
const id = t.short_id || t.id.slice(0, 8);
|
|
14848
|
+
const who = t.assigned_to ? ` \u2014 ${t.assigned_to}` : "";
|
|
14849
|
+
lines.push(`- **${id}**: ${t.title}${who}`);
|
|
14850
|
+
}
|
|
14851
|
+
lines.push("");
|
|
14852
|
+
}
|
|
14853
|
+
if (failed.length > 0) {
|
|
14854
|
+
lines.push(`### \u274C Failed (${failed.length})`);
|
|
14855
|
+
for (const t of failed) {
|
|
14856
|
+
const id = t.short_id || t.id.slice(0, 8);
|
|
14857
|
+
lines.push(`- **${id}**: ${t.title}`);
|
|
14858
|
+
}
|
|
14859
|
+
lines.push("");
|
|
14860
|
+
}
|
|
14861
|
+
lines.push(`### \uD83D\uDCCB Pending: ${allTasks.length} task${allTasks.length !== 1 ? "s" : ""} remaining`);
|
|
14862
|
+
console.log(lines.join(`
|
|
14863
|
+
`));
|
|
14864
|
+
});
|
|
14780
14865
|
program2.action(async () => {
|
|
14781
14866
|
if (process.stdout.isTTY) {
|
|
14782
14867
|
try {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { TodosClient, createClient } from "./sdk.js";
|
|
2
|
+
export type { TodosClientOptions } from "./sdk.js";
|
|
1
3
|
export { getDatabase, closeDatabase, resetDatabase, resolvePartialId, now, uuid } from "./db/database.js";
|
|
2
4
|
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
5
|
export type { TaskGraphNode, TaskGraph, BulkCreateTaskInput, ActiveWorkItem, StatusSummary, DecomposeSubtaskInput } from "./db/tasks.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,95 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
// src/sdk.ts
|
|
3
|
+
class TodosClient {
|
|
4
|
+
baseUrl;
|
|
5
|
+
timeout;
|
|
6
|
+
constructor(options = {}) {
|
|
7
|
+
this.baseUrl = options.baseUrl || process.env["TODOS_URL"] || "http://localhost:19427";
|
|
8
|
+
this.timeout = options.timeout || 1e4;
|
|
9
|
+
}
|
|
10
|
+
static fromEnv() {
|
|
11
|
+
return new TodosClient({ baseUrl: process.env["TODOS_URL"] });
|
|
12
|
+
}
|
|
13
|
+
async fetch(path, init) {
|
|
14
|
+
const controller = new AbortController;
|
|
15
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
16
|
+
try {
|
|
17
|
+
const res = await fetch(`${this.baseUrl}${path}`, { ...init, signal: controller.signal });
|
|
18
|
+
if (!res.ok) {
|
|
19
|
+
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
20
|
+
throw new Error(err.error || `HTTP ${res.status}`);
|
|
21
|
+
}
|
|
22
|
+
return res.json();
|
|
23
|
+
} finally {
|
|
24
|
+
clearTimeout(timer);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async isAlive() {
|
|
28
|
+
try {
|
|
29
|
+
await this.fetch("/api/stats");
|
|
30
|
+
return true;
|
|
31
|
+
} catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async getStatus(projectId, agentId) {
|
|
36
|
+
const params = new URLSearchParams;
|
|
37
|
+
if (projectId)
|
|
38
|
+
params.set("project_id", projectId);
|
|
39
|
+
if (agentId)
|
|
40
|
+
params.set("agent_id", agentId);
|
|
41
|
+
return this.fetch(`/api/tasks/status?${params}`);
|
|
42
|
+
}
|
|
43
|
+
async listTasks(filter = {}) {
|
|
44
|
+
const params = new URLSearchParams;
|
|
45
|
+
for (const [k, v] of Object.entries(filter)) {
|
|
46
|
+
if (v !== undefined)
|
|
47
|
+
params.set(k, String(v));
|
|
48
|
+
}
|
|
49
|
+
return this.fetch(`/api/tasks?${params}`);
|
|
50
|
+
}
|
|
51
|
+
async getTask(id) {
|
|
52
|
+
return this.fetch(`/api/tasks/${id}`);
|
|
53
|
+
}
|
|
54
|
+
async getTaskHistory(id) {
|
|
55
|
+
return this.fetch(`/api/tasks/${id}/history`);
|
|
56
|
+
}
|
|
57
|
+
async getTaskProgress(id) {
|
|
58
|
+
return this.fetch(`/api/tasks/${id}/progress`);
|
|
59
|
+
}
|
|
60
|
+
async claimNextTask(agentId, projectId) {
|
|
61
|
+
return this.fetch("/api/tasks/claim", {
|
|
62
|
+
method: "POST",
|
|
63
|
+
headers: { "Content-Type": "application/json" },
|
|
64
|
+
body: JSON.stringify({ agent_id: agentId, project_id: projectId })
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
async completeTask(id, agentId) {
|
|
68
|
+
return this.fetch(`/api/tasks/${id}/complete`, {
|
|
69
|
+
method: "POST",
|
|
70
|
+
headers: { "Content-Type": "application/json" },
|
|
71
|
+
body: JSON.stringify({ agent_id: agentId })
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async getStats() {
|
|
75
|
+
return this.fetch("/api/stats");
|
|
76
|
+
}
|
|
77
|
+
async getActiveWork(projectId) {
|
|
78
|
+
const params = new URLSearchParams;
|
|
79
|
+
if (projectId)
|
|
80
|
+
params.set("project_id", projectId);
|
|
81
|
+
return this.fetch(`/api/tasks/active?${params}`);
|
|
82
|
+
}
|
|
83
|
+
async getTasksChangedSince(since, projectId) {
|
|
84
|
+
const params = new URLSearchParams({ since });
|
|
85
|
+
if (projectId)
|
|
86
|
+
params.set("project_id", projectId);
|
|
87
|
+
return this.fetch(`/api/tasks/changed?${params}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function createClient(options) {
|
|
91
|
+
return new TodosClient(options);
|
|
92
|
+
}
|
|
2
93
|
// src/db/database.ts
|
|
3
94
|
import { Database } from "bun:sqlite";
|
|
4
95
|
import { existsSync, mkdirSync } from "fs";
|
|
@@ -3180,6 +3271,7 @@ export {
|
|
|
3180
3271
|
createProject,
|
|
3181
3272
|
createPlan,
|
|
3182
3273
|
createOrg,
|
|
3274
|
+
createClient,
|
|
3183
3275
|
countTasks,
|
|
3184
3276
|
completeTask,
|
|
3185
3277
|
closeDatabase,
|
|
@@ -3191,6 +3283,7 @@ export {
|
|
|
3191
3283
|
addDependency,
|
|
3192
3284
|
addComment,
|
|
3193
3285
|
VersionConflictError,
|
|
3286
|
+
TodosClient,
|
|
3194
3287
|
TaskNotFoundError,
|
|
3195
3288
|
TaskListNotFoundError,
|
|
3196
3289
|
TASK_STATUSES,
|
package/dist/sdk.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hasna/todos REST SDK Client
|
|
3
|
+
* Zero-dependency HTTP client for the todos REST API (todos serve).
|
|
4
|
+
* Use when you need to interact with todos from another machine or process.
|
|
5
|
+
*/
|
|
6
|
+
export interface TodosClientOptions {
|
|
7
|
+
baseUrl?: string;
|
|
8
|
+
timeout?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class TodosClient {
|
|
11
|
+
private baseUrl;
|
|
12
|
+
private timeout;
|
|
13
|
+
constructor(options?: TodosClientOptions);
|
|
14
|
+
static fromEnv(): TodosClient;
|
|
15
|
+
private fetch;
|
|
16
|
+
isAlive(): Promise<boolean>;
|
|
17
|
+
getStatus(projectId?: string, agentId?: string): Promise<any>;
|
|
18
|
+
listTasks(filter?: {
|
|
19
|
+
status?: string;
|
|
20
|
+
project_id?: string;
|
|
21
|
+
assigned_to?: string;
|
|
22
|
+
limit?: number;
|
|
23
|
+
offset?: number;
|
|
24
|
+
session_id?: string;
|
|
25
|
+
}): Promise<any[]>;
|
|
26
|
+
getTask(id: string): Promise<any>;
|
|
27
|
+
getTaskHistory(id: string): Promise<any[]>;
|
|
28
|
+
getTaskProgress(id: string): Promise<any>;
|
|
29
|
+
claimNextTask(agentId: string, projectId?: string): Promise<any>;
|
|
30
|
+
completeTask(id: string, agentId?: string): Promise<any>;
|
|
31
|
+
getStats(): Promise<any>;
|
|
32
|
+
getActiveWork(projectId?: string): Promise<any[]>;
|
|
33
|
+
getTasksChangedSince(since: string, projectId?: string): Promise<any>;
|
|
34
|
+
}
|
|
35
|
+
export declare function createClient(options?: TodosClientOptions): TodosClient;
|
|
36
|
+
//# sourceMappingURL=sdk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,kBAAuB;IAK5C,MAAM,CAAC,OAAO,IAAI,WAAW;YAIf,KAAK;IAeb,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAO3B,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAO7D,SAAS,CAAC,MAAM,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAQ5J,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAIjC,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAI1C,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAIzC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAQhE,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAQxD,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC;IAIxB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAMjD,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;CAK5E;AAED,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,WAAW,CAEtE"}
|
package/dist/server/index.js
CHANGED
|
@@ -2159,6 +2159,57 @@ var init_agents = __esm(() => {
|
|
|
2159
2159
|
init_database();
|
|
2160
2160
|
});
|
|
2161
2161
|
|
|
2162
|
+
// src/db/comments.ts
|
|
2163
|
+
var exports_comments = {};
|
|
2164
|
+
__export(exports_comments, {
|
|
2165
|
+
logProgress: () => logProgress,
|
|
2166
|
+
listComments: () => listComments,
|
|
2167
|
+
getComment: () => getComment,
|
|
2168
|
+
deleteComment: () => deleteComment,
|
|
2169
|
+
addComment: () => addComment
|
|
2170
|
+
});
|
|
2171
|
+
function addComment(input, db) {
|
|
2172
|
+
const d = db || getDatabase();
|
|
2173
|
+
if (!getTask(input.task_id, d)) {
|
|
2174
|
+
throw new TaskNotFoundError(input.task_id);
|
|
2175
|
+
}
|
|
2176
|
+
const id = uuid();
|
|
2177
|
+
const timestamp = now();
|
|
2178
|
+
d.run(`INSERT INTO task_comments (id, task_id, agent_id, session_id, content, type, progress_pct, created_at)
|
|
2179
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
2180
|
+
id,
|
|
2181
|
+
input.task_id,
|
|
2182
|
+
input.agent_id || null,
|
|
2183
|
+
input.session_id || null,
|
|
2184
|
+
input.content,
|
|
2185
|
+
input.type || "comment",
|
|
2186
|
+
input.progress_pct ?? null,
|
|
2187
|
+
timestamp
|
|
2188
|
+
]);
|
|
2189
|
+
return getComment(id, d);
|
|
2190
|
+
}
|
|
2191
|
+
function logProgress(taskId, message, pct, agentId, db) {
|
|
2192
|
+
return addComment({ task_id: taskId, content: message, type: "progress", progress_pct: pct, agent_id: agentId }, db);
|
|
2193
|
+
}
|
|
2194
|
+
function getComment(id, db) {
|
|
2195
|
+
const d = db || getDatabase();
|
|
2196
|
+
return d.query("SELECT * FROM task_comments WHERE id = ?").get(id);
|
|
2197
|
+
}
|
|
2198
|
+
function listComments(taskId, db) {
|
|
2199
|
+
const d = db || getDatabase();
|
|
2200
|
+
return d.query("SELECT * FROM task_comments WHERE task_id = ? ORDER BY created_at").all(taskId);
|
|
2201
|
+
}
|
|
2202
|
+
function deleteComment(id, db) {
|
|
2203
|
+
const d = db || getDatabase();
|
|
2204
|
+
const result = d.run("DELETE FROM task_comments WHERE id = ?", [id]);
|
|
2205
|
+
return result.changes > 0;
|
|
2206
|
+
}
|
|
2207
|
+
var init_comments = __esm(() => {
|
|
2208
|
+
init_types();
|
|
2209
|
+
init_database();
|
|
2210
|
+
init_tasks();
|
|
2211
|
+
});
|
|
2212
|
+
|
|
2162
2213
|
// src/db/orgs.ts
|
|
2163
2214
|
var exports_orgs = {};
|
|
2164
2215
|
__export(exports_orgs, {
|
|
@@ -2444,7 +2495,8 @@ function taskToSummary(task, fields) {
|
|
|
2444
2495
|
created_at: task.created_at,
|
|
2445
2496
|
updated_at: task.updated_at,
|
|
2446
2497
|
completed_at: task.completed_at,
|
|
2447
|
-
due_at: task.due_at
|
|
2498
|
+
due_at: task.due_at,
|
|
2499
|
+
recurrence_rule: task.recurrence_rule
|
|
2448
2500
|
};
|
|
2449
2501
|
if (!fields || fields.length === 0)
|
|
2450
2502
|
return full;
|
|
@@ -2735,6 +2787,18 @@ data: ${JSON.stringify({ type: "connected", agent_id: agentId, timestamp: new Da
|
|
|
2735
2787
|
return json({ error: e instanceof Error ? e.message : "Failed" }, 500, port);
|
|
2736
2788
|
}
|
|
2737
2789
|
}
|
|
2790
|
+
const progressMatch = path.match(/^\/api\/tasks\/([^/]+)\/progress$/);
|
|
2791
|
+
if (progressMatch && method === "GET") {
|
|
2792
|
+
const id = progressMatch[1];
|
|
2793
|
+
const task = getTask(id);
|
|
2794
|
+
if (!task)
|
|
2795
|
+
return json({ error: "Task not found" }, 404, port);
|
|
2796
|
+
const { listComments: listComments2 } = await Promise.resolve().then(() => (init_comments(), exports_comments));
|
|
2797
|
+
const all = listComments2(id);
|
|
2798
|
+
const progress = all.filter((c) => c.type === "progress");
|
|
2799
|
+
const latest = progress[progress.length - 1] || null;
|
|
2800
|
+
return json({ task_id: id, progress_entries: progress, latest, count: progress.length }, 200, port);
|
|
2801
|
+
}
|
|
2738
2802
|
const taskMatch = path.match(/^\/api\/tasks\/([^/]+)$/);
|
|
2739
2803
|
if (taskMatch) {
|
|
2740
2804
|
const id = taskMatch[1];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/server/serve.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/server/serve.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiHH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0uB1G"}
|