@mclean-capital/neura 3.4.0 → 3.5.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/README.md +8 -0
- package/core/server.bundled.mjs +2582 -1145
- package/core/server.bundled.mjs.map +4 -4
- package/core/version.txt +1 -1
- package/dist/commands/install.js +2 -2
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/skill.d.ts +26 -0
- package/dist/commands/skill.d.ts.map +1 -0
- package/dist/commands/skill.js +111 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/stores/index.js +171 -11
- package/stores/index.js.map +2 -2
- package/stores/mappers.d.ts +27 -3
- package/stores/mappers.d.ts.map +1 -1
- package/stores/mappers.js +23 -0
- package/stores/mappers.js.map +1 -1
- package/stores/migrations.d.ts.map +1 -1
- package/stores/migrations.js +106 -1
- package/stores/migrations.js.map +1 -1
- package/stores/migrations.test.d.ts +14 -0
- package/stores/migrations.test.d.ts.map +1 -0
- package/stores/migrations.test.js +164 -0
- package/stores/migrations.test.js.map +1 -0
- package/stores/pglite-store.d.ts +5 -7
- package/stores/pglite-store.d.ts.map +1 -1
- package/stores/pglite-store.js +2 -2
- package/stores/pglite-store.js.map +1 -1
- package/stores/pglite-store.test.js +110 -0
- package/stores/pglite-store.test.js.map +1 -1
- package/stores/task-comment-queries.d.ts +55 -0
- package/stores/task-comment-queries.d.ts.map +1 -0
- package/stores/task-comment-queries.js +98 -0
- package/stores/task-comment-queries.js.map +1 -0
- package/stores/task-comment-queries.test.d.ts +8 -0
- package/stores/task-comment-queries.test.d.ts.map +1 -0
- package/stores/task-comment-queries.test.js +321 -0
- package/stores/task-comment-queries.test.js.map +1 -0
- package/stores/work-item-queries.d.ts +47 -2
- package/stores/work-item-queries.d.ts.map +1 -1
- package/stores/work-item-queries.js +79 -6
- package/stores/work-item-queries.js.map +1 -1
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for task-comment-queries.ts — the Phase 6b comments CRUD.
|
|
3
|
+
*
|
|
4
|
+
* Uses an in-memory PGlite via the PgliteStore facade. Comments are tied to
|
|
5
|
+
* a work_item (FK CASCADE), so every test creates a parent task first.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
8
|
+
import { PGlite } from '@electric-sql/pglite';
|
|
9
|
+
import { vector } from '@electric-sql/pglite/vector';
|
|
10
|
+
import crypto from 'crypto';
|
|
11
|
+
import { runMigrations } from './migrations.js';
|
|
12
|
+
import { insertComment, listComments, pruneHeartbeats, countOpenRequests, TASK_COMMENT_CONTENT_MAX_BYTES, } from './task-comment-queries.js';
|
|
13
|
+
describe('task-comment-queries', () => {
|
|
14
|
+
let db;
|
|
15
|
+
let taskId;
|
|
16
|
+
beforeEach(async () => {
|
|
17
|
+
db = await PGlite.create({ extensions: { vector } });
|
|
18
|
+
await runMigrations(db);
|
|
19
|
+
// Seed a work_item to anchor comments to.
|
|
20
|
+
taskId = crypto.randomUUID();
|
|
21
|
+
await db.query(`INSERT INTO work_items (id, title, priority) VALUES ($1, $2, $3)`, [
|
|
22
|
+
taskId,
|
|
23
|
+
'Test task',
|
|
24
|
+
'medium',
|
|
25
|
+
]);
|
|
26
|
+
});
|
|
27
|
+
afterEach(async () => {
|
|
28
|
+
await db.close();
|
|
29
|
+
});
|
|
30
|
+
describe('insertComment', () => {
|
|
31
|
+
it('inserts a progress comment and returns the entry', async () => {
|
|
32
|
+
const comment = await insertComment(db, {
|
|
33
|
+
taskId,
|
|
34
|
+
type: 'progress',
|
|
35
|
+
author: 'worker:abc-123',
|
|
36
|
+
content: 'Halfway done',
|
|
37
|
+
});
|
|
38
|
+
expect(comment.taskId).toBe(taskId);
|
|
39
|
+
expect(comment.type).toBe('progress');
|
|
40
|
+
expect(comment.author).toBe('worker:abc-123');
|
|
41
|
+
expect(comment.content).toBe('Halfway done');
|
|
42
|
+
expect(comment.urgency).toBeNull();
|
|
43
|
+
expect(comment.metadata).toBeNull();
|
|
44
|
+
expect(comment.attachmentPath).toBeNull();
|
|
45
|
+
expect(comment.createdAt).toBeTruthy();
|
|
46
|
+
});
|
|
47
|
+
it('inserts a clarification_request with urgency + metadata', async () => {
|
|
48
|
+
const comment = await insertComment(db, {
|
|
49
|
+
taskId,
|
|
50
|
+
type: 'clarification_request',
|
|
51
|
+
author: 'worker:abc-123',
|
|
52
|
+
content: 'Which branch should I push to?',
|
|
53
|
+
urgency: 'high',
|
|
54
|
+
metadata: { topic: 'git-branch-selection' },
|
|
55
|
+
});
|
|
56
|
+
expect(comment.type).toBe('clarification_request');
|
|
57
|
+
expect(comment.urgency).toBe('high');
|
|
58
|
+
expect(comment.metadata).toEqual({ topic: 'git-branch-selection' });
|
|
59
|
+
});
|
|
60
|
+
it('supports attachment_path for overflow content', async () => {
|
|
61
|
+
const comment = await insertComment(db, {
|
|
62
|
+
taskId,
|
|
63
|
+
type: 'error',
|
|
64
|
+
author: 'worker:abc-123',
|
|
65
|
+
content: 'Traceback summary (first 10 lines)…',
|
|
66
|
+
attachmentPath: '/tmp/worker/abc-123/_attachments/traceback-1.txt',
|
|
67
|
+
});
|
|
68
|
+
expect(comment.attachmentPath).toBe('/tmp/worker/abc-123/_attachments/traceback-1.txt');
|
|
69
|
+
});
|
|
70
|
+
it('rejects content exceeding the 32 KB cap', async () => {
|
|
71
|
+
const big = 'a'.repeat(TASK_COMMENT_CONTENT_MAX_BYTES + 1);
|
|
72
|
+
await expect(insertComment(db, { taskId, type: 'progress', author: 'worker:1', content: big })).rejects.toThrow(/exceeds/);
|
|
73
|
+
});
|
|
74
|
+
it('accepts content exactly at the 32 KB cap', async () => {
|
|
75
|
+
const exact = 'a'.repeat(TASK_COMMENT_CONTENT_MAX_BYTES);
|
|
76
|
+
const comment = await insertComment(db, {
|
|
77
|
+
taskId,
|
|
78
|
+
type: 'progress',
|
|
79
|
+
author: 'worker:1',
|
|
80
|
+
content: exact,
|
|
81
|
+
});
|
|
82
|
+
expect(Buffer.byteLength(comment.content)).toBe(TASK_COMMENT_CONTENT_MAX_BYTES);
|
|
83
|
+
});
|
|
84
|
+
it('rejects insertion for an unknown task_id (FK enforced)', async () => {
|
|
85
|
+
await expect(insertComment(db, {
|
|
86
|
+
taskId: 'does-not-exist',
|
|
87
|
+
type: 'progress',
|
|
88
|
+
author: 'worker:1',
|
|
89
|
+
content: 'orphan',
|
|
90
|
+
})).rejects.toThrow();
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
describe('listComments', () => {
|
|
94
|
+
it('returns comments in chronological order', async () => {
|
|
95
|
+
await insertComment(db, {
|
|
96
|
+
taskId,
|
|
97
|
+
type: 'progress',
|
|
98
|
+
author: 'worker:1',
|
|
99
|
+
content: 'first',
|
|
100
|
+
});
|
|
101
|
+
// Small delay so timestamps differ enough for ordering
|
|
102
|
+
await new Promise((r) => setTimeout(r, 5));
|
|
103
|
+
await insertComment(db, {
|
|
104
|
+
taskId,
|
|
105
|
+
type: 'progress',
|
|
106
|
+
author: 'worker:1',
|
|
107
|
+
content: 'second',
|
|
108
|
+
});
|
|
109
|
+
await new Promise((r) => setTimeout(r, 5));
|
|
110
|
+
await insertComment(db, {
|
|
111
|
+
taskId,
|
|
112
|
+
type: 'progress',
|
|
113
|
+
author: 'worker:1',
|
|
114
|
+
content: 'third',
|
|
115
|
+
});
|
|
116
|
+
const comments = await listComments(db, { taskId });
|
|
117
|
+
expect(comments).toHaveLength(3);
|
|
118
|
+
expect(comments[0].content).toBe('first');
|
|
119
|
+
expect(comments[1].content).toBe('second');
|
|
120
|
+
expect(comments[2].content).toBe('third');
|
|
121
|
+
});
|
|
122
|
+
it('filters by single comment type', async () => {
|
|
123
|
+
await insertComment(db, {
|
|
124
|
+
taskId,
|
|
125
|
+
type: 'progress',
|
|
126
|
+
author: 'worker:1',
|
|
127
|
+
content: 'p',
|
|
128
|
+
});
|
|
129
|
+
await insertComment(db, {
|
|
130
|
+
taskId,
|
|
131
|
+
type: 'clarification_request',
|
|
132
|
+
author: 'worker:1',
|
|
133
|
+
content: 'q',
|
|
134
|
+
});
|
|
135
|
+
await insertComment(db, {
|
|
136
|
+
taskId,
|
|
137
|
+
type: 'result',
|
|
138
|
+
author: 'worker:1',
|
|
139
|
+
content: 'done',
|
|
140
|
+
});
|
|
141
|
+
const requests = await listComments(db, { taskId, type: 'clarification_request' });
|
|
142
|
+
expect(requests).toHaveLength(1);
|
|
143
|
+
expect(requests[0].content).toBe('q');
|
|
144
|
+
});
|
|
145
|
+
it('filters by multiple comment types', async () => {
|
|
146
|
+
await insertComment(db, {
|
|
147
|
+
taskId,
|
|
148
|
+
type: 'progress',
|
|
149
|
+
author: 'worker:1',
|
|
150
|
+
content: 'p',
|
|
151
|
+
});
|
|
152
|
+
await insertComment(db, {
|
|
153
|
+
taskId,
|
|
154
|
+
type: 'clarification_request',
|
|
155
|
+
author: 'worker:1',
|
|
156
|
+
content: 'q',
|
|
157
|
+
});
|
|
158
|
+
await insertComment(db, {
|
|
159
|
+
taskId,
|
|
160
|
+
type: 'approval_request',
|
|
161
|
+
author: 'worker:1',
|
|
162
|
+
content: 'a',
|
|
163
|
+
});
|
|
164
|
+
const requests = await listComments(db, {
|
|
165
|
+
taskId,
|
|
166
|
+
type: ['clarification_request', 'approval_request'],
|
|
167
|
+
});
|
|
168
|
+
expect(requests).toHaveLength(2);
|
|
169
|
+
});
|
|
170
|
+
it('respects limit', async () => {
|
|
171
|
+
for (let i = 0; i < 5; i++) {
|
|
172
|
+
await insertComment(db, {
|
|
173
|
+
taskId,
|
|
174
|
+
type: 'progress',
|
|
175
|
+
author: 'worker:1',
|
|
176
|
+
content: `msg ${i}`,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
const limited = await listComments(db, { taskId, limit: 3 });
|
|
180
|
+
expect(limited).toHaveLength(3);
|
|
181
|
+
});
|
|
182
|
+
it('cascades delete when parent task is deleted', async () => {
|
|
183
|
+
await insertComment(db, {
|
|
184
|
+
taskId,
|
|
185
|
+
type: 'progress',
|
|
186
|
+
author: 'worker:1',
|
|
187
|
+
content: 'orphan-to-be',
|
|
188
|
+
});
|
|
189
|
+
await db.query('DELETE FROM work_items WHERE id = $1', [taskId]);
|
|
190
|
+
const comments = await listComments(db, { taskId });
|
|
191
|
+
expect(comments).toHaveLength(0);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
describe('pruneHeartbeats', () => {
|
|
195
|
+
it('deletes only heartbeat comments from the named author', async () => {
|
|
196
|
+
await insertComment(db, {
|
|
197
|
+
taskId,
|
|
198
|
+
type: 'heartbeat',
|
|
199
|
+
author: 'worker:alpha',
|
|
200
|
+
content: 'alive',
|
|
201
|
+
});
|
|
202
|
+
await insertComment(db, {
|
|
203
|
+
taskId,
|
|
204
|
+
type: 'heartbeat',
|
|
205
|
+
author: 'worker:alpha',
|
|
206
|
+
content: 'still alive',
|
|
207
|
+
});
|
|
208
|
+
await insertComment(db, {
|
|
209
|
+
taskId,
|
|
210
|
+
type: 'heartbeat',
|
|
211
|
+
author: 'worker:beta',
|
|
212
|
+
content: 'unrelated',
|
|
213
|
+
});
|
|
214
|
+
await insertComment(db, {
|
|
215
|
+
taskId,
|
|
216
|
+
type: 'progress',
|
|
217
|
+
author: 'worker:alpha',
|
|
218
|
+
content: 'keep-me',
|
|
219
|
+
});
|
|
220
|
+
const pruned = await pruneHeartbeats(db, taskId, 'worker:alpha');
|
|
221
|
+
expect(pruned).toBe(2);
|
|
222
|
+
const remaining = await listComments(db, { taskId });
|
|
223
|
+
expect(remaining).toHaveLength(2);
|
|
224
|
+
expect(remaining.some((c) => c.author === 'worker:beta' && c.type === 'heartbeat')).toBe(true);
|
|
225
|
+
expect(remaining.some((c) => c.author === 'worker:alpha' && c.type === 'progress')).toBe(true);
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
describe('countOpenRequests', () => {
|
|
229
|
+
it('counts unresolved clarification_request + approval_request comments', async () => {
|
|
230
|
+
await insertComment(db, {
|
|
231
|
+
taskId,
|
|
232
|
+
type: 'clarification_request',
|
|
233
|
+
author: 'worker:1',
|
|
234
|
+
content: 'q1',
|
|
235
|
+
});
|
|
236
|
+
await insertComment(db, {
|
|
237
|
+
taskId,
|
|
238
|
+
type: 'approval_request',
|
|
239
|
+
author: 'worker:1',
|
|
240
|
+
content: 'approve?',
|
|
241
|
+
});
|
|
242
|
+
expect(await countOpenRequests(db, taskId)).toBe(2);
|
|
243
|
+
});
|
|
244
|
+
it('excludes requests with a matching response comment', async () => {
|
|
245
|
+
const clarifyReq = await insertComment(db, {
|
|
246
|
+
taskId,
|
|
247
|
+
type: 'clarification_request',
|
|
248
|
+
author: 'worker:1',
|
|
249
|
+
content: 'q1',
|
|
250
|
+
});
|
|
251
|
+
await insertComment(db, {
|
|
252
|
+
taskId,
|
|
253
|
+
type: 'clarification_response',
|
|
254
|
+
author: 'orchestrator',
|
|
255
|
+
content: 'use main',
|
|
256
|
+
metadata: { resolves_comment_id: clarifyReq.id },
|
|
257
|
+
});
|
|
258
|
+
expect(await countOpenRequests(db, taskId)).toBe(0);
|
|
259
|
+
});
|
|
260
|
+
it('returns 0 on a task with no comments at all', async () => {
|
|
261
|
+
expect(await countOpenRequests(db, taskId)).toBe(0);
|
|
262
|
+
});
|
|
263
|
+
it('ignores orchestrator responses that point at a nonexistent request id', async () => {
|
|
264
|
+
await insertComment(db, {
|
|
265
|
+
taskId,
|
|
266
|
+
type: 'clarification_request',
|
|
267
|
+
author: 'worker:1',
|
|
268
|
+
content: 'real question',
|
|
269
|
+
});
|
|
270
|
+
// A malformed response that points at an id that doesn't exist on
|
|
271
|
+
// this task (e.g. from a prior session or a bug). Must not
|
|
272
|
+
// accidentally "resolve" the unrelated real request.
|
|
273
|
+
await insertComment(db, {
|
|
274
|
+
taskId,
|
|
275
|
+
type: 'clarification_response',
|
|
276
|
+
author: 'orchestrator',
|
|
277
|
+
content: 'dangling answer',
|
|
278
|
+
metadata: { resolves_comment_id: crypto.randomUUID() },
|
|
279
|
+
});
|
|
280
|
+
expect(await countOpenRequests(db, taskId)).toBe(1);
|
|
281
|
+
});
|
|
282
|
+
it('scopes resolution lookup to the current task — cross-task response ids do not resolve', async () => {
|
|
283
|
+
// Create a second task with its own request + response.
|
|
284
|
+
const otherTaskId = crypto.randomUUID();
|
|
285
|
+
await db.query(`INSERT INTO work_items (id, title, priority) VALUES ($1, $2, $3)`, [
|
|
286
|
+
otherTaskId,
|
|
287
|
+
'Other task',
|
|
288
|
+
'medium',
|
|
289
|
+
]);
|
|
290
|
+
const otherReq = await insertComment(db, {
|
|
291
|
+
taskId: otherTaskId,
|
|
292
|
+
type: 'clarification_request',
|
|
293
|
+
author: 'worker:other',
|
|
294
|
+
content: 'other question',
|
|
295
|
+
});
|
|
296
|
+
// On our original task, have a request and then a malformed response
|
|
297
|
+
// that references the OTHER task's request id.
|
|
298
|
+
await insertComment(db, {
|
|
299
|
+
taskId,
|
|
300
|
+
type: 'clarification_request',
|
|
301
|
+
author: 'worker:1',
|
|
302
|
+
content: 'q1',
|
|
303
|
+
});
|
|
304
|
+
await insertComment(db, {
|
|
305
|
+
taskId,
|
|
306
|
+
type: 'clarification_response',
|
|
307
|
+
author: 'orchestrator',
|
|
308
|
+
content: 'cross-task leak attempt',
|
|
309
|
+
metadata: { resolves_comment_id: otherReq.id },
|
|
310
|
+
});
|
|
311
|
+
// The original task's request should still count as open.
|
|
312
|
+
// (countOpenRequests's subquery scopes to task_id = $1, so the
|
|
313
|
+
// cross-task response is invisible.)
|
|
314
|
+
expect(await countOpenRequests(db, taskId)).toBe(1);
|
|
315
|
+
// The other task's request should also still be open — the only
|
|
316
|
+
// response in the system references it from the wrong task.
|
|
317
|
+
expect(await countOpenRequests(db, otherTaskId)).toBe(1);
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
//# sourceMappingURL=task-comment-queries.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-comment-queries.test.js","sourceRoot":"","sources":["../../src/stores/task-comment-queries.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACrD,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EACL,aAAa,EACb,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,8BAA8B,GAC/B,MAAM,2BAA2B,CAAC;AAEnC,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,IAAI,EAAU,CAAC;IACf,IAAI,MAAc,CAAC;IAEnB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;QACrD,MAAM,aAAa,CAAC,EAAE,CAAC,CAAC;QAExB,0CAA0C;QAC1C,MAAM,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAC7B,MAAM,EAAE,CAAC,KAAK,CAAC,kEAAkE,EAAE;YACjF,MAAM;YACN,WAAW;YACX,QAAQ;SACT,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAChE,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtC,MAAM;gBACN,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,gBAAgB;gBACxB,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACpC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACtC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC9C,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC7C,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;YACnC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;YACpC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC1C,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;YACvE,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtC,MAAM;gBACN,IAAI,EAAE,uBAAuB;gBAC7B,MAAM,EAAE,gBAAgB;gBACxB,OAAO,EAAE,gCAAgC;gBACzC,OAAO,EAAE,MAAM;gBACf,QAAQ,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE;aAC5C,CAAC,CAAC;YAEH,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;YACnD,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;YAC7D,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtC,MAAM;gBACN,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE,gBAAgB;gBACxB,OAAO,EAAE,qCAAqC;gBAC9C,cAAc,EAAE,kDAAkD;aACnE,CAAC,CAAC;YAEH,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;QAC1F,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACvD,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,8BAA8B,GAAG,CAAC,CAAC,CAAC;YAC3D,MAAM,MAAM,CACV,aAAa,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAClF,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,8BAA8B,CAAC,CAAC;YACzD,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtC,MAAM;gBACN,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,KAAK;aACf,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QAClF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;YACtE,MAAM,MAAM,CACV,aAAa,CAAC,EAAE,EAAE;gBAChB,MAAM,EAAE,gBAAgB;gBACxB,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,QAAQ;aAClB,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACvD,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,OAAO;aACjB,CAAC,CAAC;YACH,uDAAuD;YACvD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC3C,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,QAAQ;aAClB,CAAC,CAAC;YACH,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC3C,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,OAAO;aACjB,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YACpD,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC1C,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC3C,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;YAC9C,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,GAAG;aACb,CAAC,CAAC;YACH,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,uBAAuB;gBAC7B,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,GAAG;aACb,CAAC,CAAC;YACH,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,MAAM;aAChB,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC,CAAC;YACnF,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;YACjD,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,GAAG;aACb,CAAC,CAAC;YACH,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,uBAAuB;gBAC7B,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,GAAG;aACb,CAAC,CAAC;YACH,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,kBAAkB;gBACxB,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,GAAG;aACb,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,EAAE,EAAE;gBACtC,MAAM;gBACN,IAAI,EAAE,CAAC,uBAAuB,EAAE,kBAAkB,CAAC;aACpD,CAAC,CAAC;YACH,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;YAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,MAAM,aAAa,CAAC,EAAE,EAAE;oBACtB,MAAM;oBACN,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE,UAAU;oBAClB,OAAO,EAAE,OAAO,CAAC,EAAE;iBACpB,CAAC,CAAC;YACL,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;YAC7D,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC3D,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;YAEH,MAAM,EAAE,CAAC,KAAK,CAAC,sCAAsC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;YAEjE,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YACpD,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;YACrE,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,WAAW;gBACjB,MAAM,EAAE,cAAc;gBACtB,OAAO,EAAE,OAAO;aACjB,CAAC,CAAC;YACH,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,WAAW;gBACjB,MAAM,EAAE,cAAc;gBACtB,OAAO,EAAE,aAAa;aACvB,CAAC,CAAC;YACH,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,WAAW;gBACjB,MAAM,EAAE,aAAa;gBACrB,OAAO,EAAE,WAAW;aACrB,CAAC,CAAC;YACH,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,cAAc;gBACtB,OAAO,EAAE,SAAS;aACnB,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;YACjE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAEvB,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YACrD,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAClC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,CACtF,IAAI,CACL,CAAC;YACF,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,cAAc,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CACtF,IAAI,CACL,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;YACnF,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,uBAAuB;gBAC7B,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;YACH,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,kBAAkB;gBACxB,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,UAAU;aACpB,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,iBAAiB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;YAClE,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,EAAE,EAAE;gBACzC,MAAM;gBACN,IAAI,EAAE,uBAAuB;gBAC7B,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;YACH,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,wBAAwB;gBAC9B,MAAM,EAAE,cAAc;gBACtB,OAAO,EAAE,UAAU;gBACnB,QAAQ,EAAE,EAAE,mBAAmB,EAAE,UAAU,CAAC,EAAE,EAAE;aACjD,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,iBAAiB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC3D,MAAM,CAAC,MAAM,iBAAiB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;YACrF,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,uBAAuB;gBAC7B,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,eAAe;aACzB,CAAC,CAAC;YACH,kEAAkE;YAClE,2DAA2D;YAC3D,qDAAqD;YACrD,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,wBAAwB;gBAC9B,MAAM,EAAE,cAAc;gBACtB,OAAO,EAAE,iBAAiB;gBAC1B,QAAQ,EAAE,EAAE,mBAAmB,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE;aACvD,CAAC,CAAC;YAEH,MAAM,CAAC,MAAM,iBAAiB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uFAAuF,EAAE,KAAK,IAAI,EAAE;YACrG,wDAAwD;YACxD,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,EAAE,CAAC,KAAK,CAAC,kEAAkE,EAAE;gBACjF,WAAW;gBACX,YAAY;gBACZ,QAAQ;aACT,CAAC,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,EAAE,EAAE;gBACvC,MAAM,EAAE,WAAW;gBACnB,IAAI,EAAE,uBAAuB;gBAC7B,MAAM,EAAE,cAAc;gBACtB,OAAO,EAAE,gBAAgB;aAC1B,CAAC,CAAC;YAEH,qEAAqE;YACrE,+CAA+C;YAC/C,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,uBAAuB;gBAC7B,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;YACH,MAAM,aAAa,CAAC,EAAE,EAAE;gBACtB,MAAM;gBACN,IAAI,EAAE,wBAAwB;gBAC9B,MAAM,EAAE,cAAc;gBACtB,OAAO,EAAE,yBAAyB;gBAClC,QAAQ,EAAE,EAAE,mBAAmB,EAAE,QAAQ,CAAC,EAAE,EAAE;aAC/C,CAAC,CAAC;YAEH,0DAA0D;YAC1D,+DAA+D;YAC/D,qCAAqC;YACrC,MAAM,CAAC,MAAM,iBAAiB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAEpD,gEAAgE;YAChE,4DAA4D;YAC5D,MAAM,CAAC,MAAM,iBAAiB,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PGlite } from '@electric-sql/pglite';
|
|
2
|
-
import type { WorkItemEntry, WorkItemPriority } from '@neura/types';
|
|
2
|
+
import type { TaskContext, TaskSource, WorkItemEntry, WorkItemPriority, WorkItemStatus } from '@neura/types';
|
|
3
3
|
export declare function getOpenWorkItems(db: PGlite, limit?: number): Promise<WorkItemEntry[]>;
|
|
4
4
|
export declare function getWorkItems(db: PGlite, options?: {
|
|
5
5
|
status?: string;
|
|
@@ -11,7 +11,52 @@ export declare function createWorkItem(db: PGlite, title: string, priority: Work
|
|
|
11
11
|
dueAt?: string;
|
|
12
12
|
parentId?: string;
|
|
13
13
|
sourceSessionId?: string;
|
|
14
|
+
goal?: string;
|
|
15
|
+
context?: TaskContext;
|
|
16
|
+
relatedSkills?: string[];
|
|
17
|
+
repoPath?: string;
|
|
18
|
+
baseBranch?: string;
|
|
19
|
+
source?: TaskSource;
|
|
14
20
|
}): Promise<string>;
|
|
15
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Fields the caller may update via {@link updateWorkItem}. Excludes
|
|
23
|
+
* system-managed columns (version, lease_expires_at, completed_at,
|
|
24
|
+
* updated_at — those are maintained by the DB layer).
|
|
25
|
+
*/
|
|
26
|
+
export interface UpdateWorkItemFields {
|
|
27
|
+
status?: WorkItemStatus;
|
|
28
|
+
priority?: WorkItemPriority;
|
|
29
|
+
title?: string;
|
|
30
|
+
description?: string | null;
|
|
31
|
+
dueAt?: string | null;
|
|
32
|
+
goal?: string | null;
|
|
33
|
+
context?: TaskContext | null;
|
|
34
|
+
relatedSkills?: string[];
|
|
35
|
+
repoPath?: string | null;
|
|
36
|
+
baseBranch?: string | null;
|
|
37
|
+
workerId?: string | null;
|
|
38
|
+
leaseExpiresAt?: string | null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Error thrown when an optimistic-lock version check fails. Caller should
|
|
42
|
+
* re-read the task and decide whether to retry or abort.
|
|
43
|
+
*/
|
|
44
|
+
export declare class VersionConflictError extends Error {
|
|
45
|
+
readonly id: string;
|
|
46
|
+
readonly expectedVersion: number;
|
|
47
|
+
constructor(id: string, expectedVersion: number);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Update a work item. Increments `version` on every call. Pass
|
|
51
|
+
* `expectVersion` to enforce optimistic locking — the caller should have
|
|
52
|
+
* read the current version first and pass it here to prevent races
|
|
53
|
+
* between concurrent `update_task` calls (worker + orchestrator).
|
|
54
|
+
*
|
|
55
|
+
* Returns the new version on success. Throws {@link VersionConflictError}
|
|
56
|
+
* if `expectVersion` was supplied and the row's version has moved.
|
|
57
|
+
*/
|
|
58
|
+
export declare function updateWorkItem(db: PGlite, id: string, updates: UpdateWorkItemFields, opts?: {
|
|
59
|
+
expectVersion?: number;
|
|
60
|
+
}): Promise<number>;
|
|
16
61
|
export declare function deleteWorkItem(db: PGlite, id: string): Promise<void>;
|
|
17
62
|
//# sourceMappingURL=work-item-queries.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"work-item-queries.d.ts","sourceRoot":"","sources":["../../src/stores/work-item-queries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"work-item-queries.d.ts","sourceRoot":"","sources":["../../src/stores/work-item-queries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,cAAc,EACf,MAAM,cAAc,CAAC;AAKtB,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAYvF;AAED,wBAAsB,YAAY,CAChC,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C,OAAO,CAAC,aAAa,EAAE,CAAC,CAmB1B;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAGvF;AAED,wBAAsB,cAAc,CAClC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,CAAC,EAAE;IACR,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB,GACA,OAAO,CAAC,MAAM,CAAC,CAyBjB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;aAE3B,EAAE,EAAE,MAAM;aACV,eAAe,EAAE,MAAM;gBADvB,EAAE,EAAE,MAAM,EACV,eAAe,EAAE,MAAM;CAK1C;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,oBAAoB,EAC7B,IAAI,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAChC,OAAO,CAAC,MAAM,CAAC,CAkFjB;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1E"}
|
|
@@ -3,7 +3,7 @@ import { mapWorkItem } from './mappers.js';
|
|
|
3
3
|
// --- Work items ---
|
|
4
4
|
export async function getOpenWorkItems(db, limit = 50) {
|
|
5
5
|
const result = await db.query(`SELECT * FROM work_items
|
|
6
|
-
WHERE status IN ('pending', 'in_progress')
|
|
6
|
+
WHERE status IN ('pending', 'awaiting_dispatch', 'in_progress', 'awaiting_clarification', 'awaiting_approval', 'paused')
|
|
7
7
|
ORDER BY
|
|
8
8
|
CASE priority WHEN 'high' THEN 0 WHEN 'medium' THEN 1 WHEN 'low' THEN 2 END,
|
|
9
9
|
due_at ASC NULLS LAST,
|
|
@@ -35,8 +35,11 @@ export async function getWorkItem(db, id) {
|
|
|
35
35
|
}
|
|
36
36
|
export async function createWorkItem(db, title, priority, options) {
|
|
37
37
|
const id = crypto.randomUUID();
|
|
38
|
-
await db.query(`INSERT INTO work_items (
|
|
39
|
-
|
|
38
|
+
await db.query(`INSERT INTO work_items (
|
|
39
|
+
id, title, priority, description, due_at, parent_id, source_session_id,
|
|
40
|
+
goal, context, related_skills, repo_path, base_branch, source
|
|
41
|
+
)
|
|
42
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`, [
|
|
40
43
|
id,
|
|
41
44
|
title,
|
|
42
45
|
priority,
|
|
@@ -44,11 +47,40 @@ export async function createWorkItem(db, title, priority, options) {
|
|
|
44
47
|
options?.dueAt ?? null,
|
|
45
48
|
options?.parentId ?? null,
|
|
46
49
|
options?.sourceSessionId ?? null,
|
|
50
|
+
options?.goal ?? null,
|
|
51
|
+
options?.context ? JSON.stringify(options.context) : null,
|
|
52
|
+
JSON.stringify(options?.relatedSkills ?? []),
|
|
53
|
+
options?.repoPath ?? null,
|
|
54
|
+
options?.baseBranch ?? null,
|
|
55
|
+
options?.source ?? 'user',
|
|
47
56
|
]);
|
|
48
57
|
return id;
|
|
49
58
|
}
|
|
50
|
-
|
|
51
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Error thrown when an optimistic-lock version check fails. Caller should
|
|
61
|
+
* re-read the task and decide whether to retry or abort.
|
|
62
|
+
*/
|
|
63
|
+
export class VersionConflictError extends Error {
|
|
64
|
+
id;
|
|
65
|
+
expectedVersion;
|
|
66
|
+
constructor(id, expectedVersion) {
|
|
67
|
+
super(`version conflict on work_item ${id} (expected ${expectedVersion})`);
|
|
68
|
+
this.id = id;
|
|
69
|
+
this.expectedVersion = expectedVersion;
|
|
70
|
+
this.name = 'VersionConflictError';
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Update a work item. Increments `version` on every call. Pass
|
|
75
|
+
* `expectVersion` to enforce optimistic locking — the caller should have
|
|
76
|
+
* read the current version first and pass it here to prevent races
|
|
77
|
+
* between concurrent `update_task` calls (worker + orchestrator).
|
|
78
|
+
*
|
|
79
|
+
* Returns the new version on success. Throws {@link VersionConflictError}
|
|
80
|
+
* if `expectVersion` was supplied and the row's version has moved.
|
|
81
|
+
*/
|
|
82
|
+
export async function updateWorkItem(db, id, updates, opts) {
|
|
83
|
+
const sets = ['updated_at = NOW()', 'version = version + 1'];
|
|
52
84
|
const values = [];
|
|
53
85
|
let paramIdx = 1;
|
|
54
86
|
if (updates.title !== undefined) {
|
|
@@ -76,8 +108,49 @@ export async function updateWorkItem(db, id, updates) {
|
|
|
76
108
|
sets.push(`due_at = $${paramIdx++}`);
|
|
77
109
|
values.push(updates.dueAt);
|
|
78
110
|
}
|
|
111
|
+
if (updates.goal !== undefined) {
|
|
112
|
+
sets.push(`goal = $${paramIdx++}`);
|
|
113
|
+
values.push(updates.goal);
|
|
114
|
+
}
|
|
115
|
+
if (updates.context !== undefined) {
|
|
116
|
+
sets.push(`context = $${paramIdx++}`);
|
|
117
|
+
values.push(updates.context === null ? null : JSON.stringify(updates.context));
|
|
118
|
+
}
|
|
119
|
+
if (updates.relatedSkills !== undefined) {
|
|
120
|
+
sets.push(`related_skills = $${paramIdx++}`);
|
|
121
|
+
values.push(JSON.stringify(updates.relatedSkills));
|
|
122
|
+
}
|
|
123
|
+
if (updates.repoPath !== undefined) {
|
|
124
|
+
sets.push(`repo_path = $${paramIdx++}`);
|
|
125
|
+
values.push(updates.repoPath);
|
|
126
|
+
}
|
|
127
|
+
if (updates.baseBranch !== undefined) {
|
|
128
|
+
sets.push(`base_branch = $${paramIdx++}`);
|
|
129
|
+
values.push(updates.baseBranch);
|
|
130
|
+
}
|
|
131
|
+
if (updates.workerId !== undefined) {
|
|
132
|
+
sets.push(`worker_id = $${paramIdx++}`);
|
|
133
|
+
values.push(updates.workerId);
|
|
134
|
+
}
|
|
135
|
+
if (updates.leaseExpiresAt !== undefined) {
|
|
136
|
+
sets.push(`lease_expires_at = $${paramIdx++}`);
|
|
137
|
+
values.push(updates.leaseExpiresAt);
|
|
138
|
+
}
|
|
139
|
+
// Build the WHERE clause — include version guard if provided.
|
|
140
|
+
let whereClause = `WHERE id = $${paramIdx++}`;
|
|
79
141
|
values.push(id);
|
|
80
|
-
|
|
142
|
+
if (opts?.expectVersion !== undefined) {
|
|
143
|
+
whereClause += ` AND version = $${paramIdx}`;
|
|
144
|
+
values.push(opts.expectVersion);
|
|
145
|
+
}
|
|
146
|
+
const result = await db.query(`UPDATE work_items SET ${sets.join(', ')} ${whereClause} RETURNING version`, values);
|
|
147
|
+
if (result.rows.length === 0) {
|
|
148
|
+
if (opts?.expectVersion !== undefined) {
|
|
149
|
+
throw new VersionConflictError(id, opts.expectVersion);
|
|
150
|
+
}
|
|
151
|
+
throw new Error(`work_item ${id} not found`);
|
|
152
|
+
}
|
|
153
|
+
return result.rows[0].version;
|
|
81
154
|
}
|
|
82
155
|
export async function deleteWorkItem(db, id) {
|
|
83
156
|
await db.query('DELETE FROM work_items WHERE id = $1', [id]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"work-item-queries.js","sourceRoot":"","sources":["../../src/stores/work-item-queries.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"work-item-queries.js","sourceRoot":"","sources":["../../src/stores/work-item-queries.ts"],"names":[],"mappings":"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"}
|