digital-tasks 2.1.1 → 2.3.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +560 -0
  3. package/package.json +20 -5
  4. package/src/client.ts +268 -0
  5. package/src/index.ts +12 -10
  6. package/src/markdown.ts +63 -48
  7. package/src/project.ts +57 -42
  8. package/src/queue.ts +76 -37
  9. package/src/task.ts +132 -75
  10. package/src/types.ts +177 -40
  11. package/src/worker.ts +959 -0
  12. package/test/project.test.ts +28 -84
  13. package/test/queue.test.ts +51 -24
  14. package/test/task.test.ts +80 -27
  15. package/test/worker.test.ts +1158 -0
  16. package/tsconfig.json +2 -13
  17. package/vitest.config.ts +48 -0
  18. package/wrangler.jsonc +44 -0
  19. package/.turbo/turbo-build.log +0 -5
  20. package/dist/function-task.d.ts +0 -319
  21. package/dist/function-task.d.ts.map +0 -1
  22. package/dist/function-task.js +0 -286
  23. package/dist/function-task.js.map +0 -1
  24. package/dist/index.d.ts +0 -72
  25. package/dist/index.d.ts.map +0 -1
  26. package/dist/index.js +0 -74
  27. package/dist/index.js.map +0 -1
  28. package/dist/markdown.d.ts +0 -112
  29. package/dist/markdown.d.ts.map +0 -1
  30. package/dist/markdown.js +0 -510
  31. package/dist/markdown.js.map +0 -1
  32. package/dist/project.d.ts +0 -259
  33. package/dist/project.d.ts.map +0 -1
  34. package/dist/project.js +0 -397
  35. package/dist/project.js.map +0 -1
  36. package/dist/queue.d.ts +0 -17
  37. package/dist/queue.d.ts.map +0 -1
  38. package/dist/queue.js +0 -347
  39. package/dist/queue.js.map +0 -1
  40. package/dist/task.d.ts +0 -69
  41. package/dist/task.d.ts.map +0 -1
  42. package/dist/task.js +0 -321
  43. package/dist/task.js.map +0 -1
  44. package/dist/types.d.ts +0 -292
  45. package/dist/types.d.ts.map +0 -1
  46. package/dist/types.js +0 -15
  47. package/dist/types.js.map +0 -1
  48. package/src/index.js +0 -73
  49. package/src/markdown.js +0 -509
  50. package/src/project.js +0 -396
  51. package/src/queue.js +0 -346
  52. package/src/task.js +0 -320
  53. package/src/types.js +0 -14
@@ -38,10 +38,7 @@ describe('Project DSL', () => {
38
38
 
39
39
  it('should create a task with subtasks', () => {
40
40
  const t = task('Parent task', {
41
- subtasks: [
42
- task('Subtask 1'),
43
- task('Subtask 2'),
44
- ],
41
+ subtasks: [task('Subtask 1'), task('Subtask 2')],
45
42
  })
46
43
 
47
44
  expect(t.subtasks).toHaveLength(2)
@@ -59,24 +56,14 @@ describe('Project DSL', () => {
59
56
 
60
57
  describe('parallel()', () => {
61
58
  it('should create a parallel group', () => {
62
- const group = parallel(
63
- task('Task A'),
64
- task('Task B'),
65
- task('Task C'),
66
- )
59
+ const group = parallel(task('Task A'), task('Task B'), task('Task C'))
67
60
 
68
61
  expect(group.__type).toBe('parallel')
69
62
  expect(group.tasks).toHaveLength(3)
70
63
  })
71
64
 
72
65
  it('should support nested groups', () => {
73
- const group = parallel(
74
- task('Task A'),
75
- sequential(
76
- task('Step 1'),
77
- task('Step 2'),
78
- ),
79
- )
66
+ const group = parallel(task('Task A'), sequential(task('Step 1'), task('Step 2')))
80
67
 
81
68
  expect(group.tasks).toHaveLength(2)
82
69
  expect((group.tasks[1] as SequentialGroup).__type).toBe('sequential')
@@ -85,11 +72,7 @@ describe('Project DSL', () => {
85
72
 
86
73
  describe('sequential()', () => {
87
74
  it('should create a sequential group', () => {
88
- const group = sequential(
89
- task('Step 1'),
90
- task('Step 2'),
91
- task('Step 3'),
92
- )
75
+ const group = sequential(task('Step 1'), task('Step 2'), task('Step 3'))
93
76
 
94
77
  expect(group.__type).toBe('sequential')
95
78
  expect(group.tasks).toHaveLength(3)
@@ -98,11 +81,8 @@ describe('Project DSL', () => {
98
81
  it('should support nested groups', () => {
99
82
  const group = sequential(
100
83
  task('Setup'),
101
- parallel(
102
- task('Build frontend'),
103
- task('Build backend'),
104
- ),
105
- task('Deploy'),
84
+ parallel(task('Build frontend'), task('Build backend')),
85
+ task('Deploy')
106
86
  )
107
87
 
108
88
  expect(group.tasks).toHaveLength(3)
@@ -129,15 +109,8 @@ describe('Project DSL', () => {
129
109
  const project = createProject({
130
110
  name: 'Feature Launch',
131
111
  tasks: [
132
- parallel(
133
- task('Design mockups'),
134
- task('Write technical spec'),
135
- ),
136
- sequential(
137
- task('Implement backend'),
138
- task('Implement frontend'),
139
- task('Write tests'),
140
- ),
112
+ parallel(task('Design mockups'), task('Write technical spec')),
113
+ sequential(task('Implement backend'), task('Implement frontend'), task('Write tests')),
141
114
  ],
142
115
  })
143
116
 
@@ -178,10 +151,7 @@ describe('Project DSL', () => {
178
151
 
179
152
  it('should build a project with fluent API', () => {
180
153
  const project = workflow('Feature Launch')
181
- .parallel(
182
- task('Design'),
183
- task('Spec'),
184
- )
154
+ .parallel(task('Design'), task('Spec'))
185
155
  .then(task('Implement'))
186
156
  .then(task('Test'))
187
157
  .build()
@@ -229,10 +199,7 @@ describe('Project DSL', () => {
229
199
  it('should convert project to actual Task objects', async () => {
230
200
  const project = createProject({
231
201
  name: 'Test Project',
232
- tasks: [
233
- task('Task 1'),
234
- task('Task 2'),
235
- ],
202
+ tasks: [task('Task 1'), task('Task 2')],
236
203
  })
237
204
 
238
205
  const { tasks } = await materializeProject(project)
@@ -245,13 +212,7 @@ describe('Project DSL', () => {
245
212
  it('should create dependencies for sequential tasks', async () => {
246
213
  const project = createProject({
247
214
  name: 'Sequential Project',
248
- tasks: [
249
- sequential(
250
- task('Step 1'),
251
- task('Step 2'),
252
- task('Step 3'),
253
- ),
254
- ],
215
+ tasks: [sequential(task('Step 1'), task('Step 2'), task('Step 3'))],
255
216
  })
256
217
 
257
218
  const { tasks } = await materializeProject(project)
@@ -268,20 +229,14 @@ describe('Project DSL', () => {
268
229
  it('should not create dependencies for parallel tasks', async () => {
269
230
  const project = createProject({
270
231
  name: 'Parallel Project',
271
- tasks: [
272
- parallel(
273
- task('Task A'),
274
- task('Task B'),
275
- task('Task C'),
276
- ),
277
- ],
232
+ tasks: [parallel(task('Task A'), task('Task B'), task('Task C'))],
278
233
  })
279
234
 
280
235
  const { tasks } = await materializeProject(project)
281
236
 
282
237
  expect(tasks).toHaveLength(3)
283
238
  // Parallel tasks should have no dependencies between them
284
- tasks.forEach(t => {
239
+ tasks.forEach((t) => {
285
240
  expect(t.dependencies).toBeUndefined()
286
241
  })
287
242
  })
@@ -289,15 +244,7 @@ describe('Project DSL', () => {
289
244
  it('should handle nested groups', async () => {
290
245
  const project = createProject({
291
246
  name: 'Nested Project',
292
- tasks: [
293
- sequential(
294
- parallel(
295
- task('A1'),
296
- task('A2'),
297
- ),
298
- task('B'),
299
- ),
300
- ],
247
+ tasks: [sequential(parallel(task('A1'), task('A2')), task('B'))],
301
248
  })
302
249
 
303
250
  const { tasks } = await materializeProject(project)
@@ -315,10 +262,7 @@ describe('Project DSL', () => {
315
262
  name: 'Subtask Project',
316
263
  tasks: [
317
264
  task('Parent', {
318
- subtasks: [
319
- task('Child 1'),
320
- task('Child 2'),
321
- ],
265
+ subtasks: [task('Child 1'), task('Child 2')],
322
266
  }),
323
267
  ],
324
268
  })
@@ -338,7 +282,7 @@ describe('Project DSL', () => {
338
282
  const createTestTasks = (): AnyTask[] => [
339
283
  {
340
284
  id: 'task_1',
341
- function: { type: 'generative', name: 'Task 1', args: {}, output: 'string' },
285
+ tool: { type: 'generative', name: 'Task 1', args: {}, output: 'string' },
342
286
  status: 'queued',
343
287
  priority: 'normal',
344
288
  createdAt: new Date(),
@@ -346,7 +290,7 @@ describe('Project DSL', () => {
346
290
  },
347
291
  {
348
292
  id: 'task_2',
349
- function: { type: 'generative', name: 'Task 2', args: {}, output: 'string' },
293
+ tool: { type: 'generative', name: 'Task 2', args: {}, output: 'string' },
350
294
  status: 'queued',
351
295
  priority: 'normal',
352
296
  dependencies: [{ type: 'blocked_by', taskId: 'task_1', satisfied: false }],
@@ -355,7 +299,7 @@ describe('Project DSL', () => {
355
299
  },
356
300
  {
357
301
  id: 'task_3',
358
- function: { type: 'generative', name: 'Task 3', args: {}, output: 'string' },
302
+ tool: { type: 'generative', name: 'Task 3', args: {}, output: 'string' },
359
303
  status: 'queued',
360
304
  priority: 'normal',
361
305
  dependencies: [{ type: 'blocked_by', taskId: 'task_2', satisfied: false }],
@@ -414,8 +358,8 @@ describe('Project DSL', () => {
414
358
  const ready = getReadyTasks(tasks)
415
359
 
416
360
  expect(ready).toHaveLength(2)
417
- expect(ready.map(t => t.id)).toContain('task_1')
418
- expect(ready.map(t => t.id)).toContain('task_2')
361
+ expect(ready.map((t) => t.id)).toContain('task_1')
362
+ expect(ready.map((t) => t.id)).toContain('task_2')
419
363
  })
420
364
 
421
365
  it('should exclude non-queued tasks', () => {
@@ -438,7 +382,7 @@ describe('Project DSL', () => {
438
382
  const tasks: AnyTask[] = [
439
383
  {
440
384
  id: 'cycle_1',
441
- function: { type: 'generative', name: 'Cycle 1', args: {}, output: 'string' },
385
+ tool: { type: 'generative', name: 'Cycle 1', args: {}, output: 'string' },
442
386
  status: 'queued',
443
387
  priority: 'normal',
444
388
  dependencies: [{ type: 'blocked_by', taskId: 'cycle_2', satisfied: false }],
@@ -447,7 +391,7 @@ describe('Project DSL', () => {
447
391
  },
448
392
  {
449
393
  id: 'cycle_2',
450
- function: { type: 'generative', name: 'Cycle 2', args: {}, output: 'string' },
394
+ tool: { type: 'generative', name: 'Cycle 2', args: {}, output: 'string' },
451
395
  status: 'queued',
452
396
  priority: 'normal',
453
397
  dependencies: [{ type: 'blocked_by', taskId: 'cycle_1', satisfied: false }],
@@ -479,7 +423,7 @@ describe('Project DSL', () => {
479
423
  const tasks: AnyTask[] = [
480
424
  {
481
425
  id: 'independent_1',
482
- function: { type: 'generative', name: 'Ind 1', args: {}, output: 'string' },
426
+ tool: { type: 'generative', name: 'Ind 1', args: {}, output: 'string' },
483
427
  status: 'queued',
484
428
  priority: 'normal',
485
429
  createdAt: new Date(),
@@ -487,7 +431,7 @@ describe('Project DSL', () => {
487
431
  },
488
432
  {
489
433
  id: 'independent_2',
490
- function: { type: 'generative', name: 'Ind 2', args: {}, output: 'string' },
434
+ tool: { type: 'generative', name: 'Ind 2', args: {}, output: 'string' },
491
435
  status: 'queued',
492
436
  priority: 'normal',
493
437
  createdAt: new Date(),
@@ -508,7 +452,7 @@ describe('Project DSL', () => {
508
452
  const tasks: AnyTask[] = [
509
453
  {
510
454
  id: 'A',
511
- function: { type: 'generative', name: 'A', args: {}, output: 'string' },
455
+ tool: { type: 'generative', name: 'A', args: {}, output: 'string' },
512
456
  status: 'queued',
513
457
  priority: 'normal',
514
458
  createdAt: new Date(),
@@ -516,7 +460,7 @@ describe('Project DSL', () => {
516
460
  },
517
461
  {
518
462
  id: 'B',
519
- function: { type: 'generative', name: 'B', args: {}, output: 'string' },
463
+ tool: { type: 'generative', name: 'B', args: {}, output: 'string' },
520
464
  status: 'queued',
521
465
  priority: 'normal',
522
466
  dependencies: [{ type: 'blocked_by', taskId: 'A', satisfied: false }],
@@ -525,7 +469,7 @@ describe('Project DSL', () => {
525
469
  },
526
470
  {
527
471
  id: 'C',
528
- function: { type: 'generative', name: 'C', args: {}, output: 'string' },
472
+ tool: { type: 'generative', name: 'C', args: {}, output: 'string' },
529
473
  status: 'queued',
530
474
  priority: 'normal',
531
475
  dependencies: [{ type: 'blocked_by', taskId: 'A', satisfied: false }],
@@ -534,7 +478,7 @@ describe('Project DSL', () => {
534
478
  },
535
479
  {
536
480
  id: 'D',
537
- function: { type: 'generative', name: 'D', args: {}, output: 'string' },
481
+ tool: { type: 'generative', name: 'D', args: {}, output: 'string' },
538
482
  status: 'queued',
539
483
  priority: 'normal',
540
484
  dependencies: [
@@ -20,7 +20,7 @@ describe('TaskQueue', () => {
20
20
  it('should add and retrieve a task', async () => {
21
21
  const task: AnyTask = {
22
22
  id: 'test_task_1',
23
- function: createTestFunc('test'),
23
+ tool: createTestFunc('test'),
24
24
  status: 'queued',
25
25
  priority: 'normal',
26
26
  createdAt: new Date(),
@@ -45,7 +45,7 @@ describe('TaskQueue', () => {
45
45
  it('should update task status', async () => {
46
46
  const task: AnyTask = {
47
47
  id: 'update_test',
48
- function: createTestFunc('update'),
48
+ tool: createTestFunc('update'),
49
49
  status: 'queued',
50
50
  priority: 'normal',
51
51
  createdAt: new Date(),
@@ -62,7 +62,7 @@ describe('TaskQueue', () => {
62
62
  it('should update task priority', async () => {
63
63
  const task: AnyTask = {
64
64
  id: 'priority_test',
65
- function: createTestFunc('priority'),
65
+ tool: createTestFunc('priority'),
66
66
  status: 'queued',
67
67
  priority: 'normal',
68
68
  createdAt: new Date(),
@@ -78,7 +78,7 @@ describe('TaskQueue', () => {
78
78
  it('should update task progress', async () => {
79
79
  const task: AnyTask = {
80
80
  id: 'progress_test',
81
- function: createTestFunc('progress'),
81
+ tool: createTestFunc('progress'),
82
82
  status: 'in_progress',
83
83
  priority: 'normal',
84
84
  createdAt: new Date(),
@@ -98,7 +98,7 @@ describe('TaskQueue', () => {
98
98
  it('should add events to task history', async () => {
99
99
  const task: AnyTask = {
100
100
  id: 'event_test',
101
- function: createTestFunc('event'),
101
+ tool: createTestFunc('event'),
102
102
  status: 'queued',
103
103
  priority: 'normal',
104
104
  createdAt: new Date(),
@@ -114,7 +114,7 @@ describe('TaskQueue', () => {
114
114
  })
115
115
 
116
116
  const updated = await queue.get('event_test')
117
- const commentEvent = updated!.events?.find(e => e.type === 'comment')
117
+ const commentEvent = updated!.events?.find((e) => e.type === 'comment')
118
118
  expect(commentEvent).toBeDefined()
119
119
  expect(commentEvent!.message).toBe('Test comment')
120
120
  })
@@ -129,7 +129,7 @@ describe('TaskQueue', () => {
129
129
  it('should remove a task', async () => {
130
130
  const task: AnyTask = {
131
131
  id: 'remove_test',
132
- function: createTestFunc('remove'),
132
+ tool: createTestFunc('remove'),
133
133
  status: 'queued',
134
134
  priority: 'normal',
135
135
  createdAt: new Date(),
@@ -156,7 +156,7 @@ describe('TaskQueue', () => {
156
156
  const tasks: AnyTask[] = [
157
157
  {
158
158
  id: 'query_1',
159
- function: createTestFunc('task1'),
159
+ tool: createTestFunc('task1'),
160
160
  status: 'queued',
161
161
  priority: 'high',
162
162
  tags: ['frontend'],
@@ -166,7 +166,7 @@ describe('TaskQueue', () => {
166
166
  },
167
167
  {
168
168
  id: 'query_2',
169
- function: createTestFunc('task2'),
169
+ tool: createTestFunc('task2'),
170
170
  status: 'in_progress',
171
171
  priority: 'normal',
172
172
  tags: ['backend'],
@@ -176,7 +176,7 @@ describe('TaskQueue', () => {
176
176
  },
177
177
  {
178
178
  id: 'query_3',
179
- function: createTestFunc('task3'),
179
+ tool: createTestFunc('task3'),
180
180
  status: 'completed',
181
181
  priority: 'low',
182
182
  tags: ['frontend', 'ui'],
@@ -250,7 +250,7 @@ describe('TaskQueue', () => {
250
250
  const tasks: AnyTask[] = [
251
251
  {
252
252
  id: 'next_1',
253
- function: createTestFunc('low'),
253
+ tool: createTestFunc('low'),
254
254
  status: 'queued',
255
255
  priority: 'low',
256
256
  createdAt: new Date(),
@@ -258,7 +258,7 @@ describe('TaskQueue', () => {
258
258
  },
259
259
  {
260
260
  id: 'next_2',
261
- function: createTestFunc('high'),
261
+ tool: createTestFunc('high'),
262
262
  status: 'queued',
263
263
  priority: 'high',
264
264
  createdAt: new Date(),
@@ -280,7 +280,13 @@ describe('TaskQueue', () => {
280
280
  it('should respect allowedWorkers', async () => {
281
281
  const task: AnyTask = {
282
282
  id: 'worker_type_test',
283
- function: { type: 'human', name: 'human-task', args: {}, output: 'object', instructions: 'Do something' },
283
+ tool: {
284
+ type: 'human',
285
+ name: 'human-task',
286
+ args: {},
287
+ output: 'object',
288
+ instructions: 'Do something',
289
+ },
284
290
  status: 'queued',
285
291
  priority: 'high',
286
292
  allowedWorkers: ['human'],
@@ -304,7 +310,7 @@ describe('TaskQueue', () => {
304
310
  const futureDate = new Date(Date.now() + 60000) // 1 minute in future
305
311
  const task: AnyTask = {
306
312
  id: 'scheduled_test',
307
- function: createTestFunc('scheduled'),
313
+ tool: createTestFunc('scheduled'),
308
314
  status: 'pending',
309
315
  priority: 'high',
310
316
  scheduledFor: futureDate,
@@ -322,7 +328,7 @@ describe('TaskQueue', () => {
322
328
  it('should skip blocked tasks', async () => {
323
329
  const task: AnyTask = {
324
330
  id: 'blocked_test',
325
- function: createTestFunc('blocked'),
331
+ tool: createTestFunc('blocked'),
326
332
  status: 'queued',
327
333
  priority: 'high',
328
334
  dependencies: [{ type: 'blocked_by', taskId: 'other_task', satisfied: false }],
@@ -342,7 +348,7 @@ describe('TaskQueue', () => {
342
348
  it('should claim a task and assign it to worker', async () => {
343
349
  const task: AnyTask = {
344
350
  id: 'claim_test',
345
- function: createTestFunc('claim'),
351
+ tool: createTestFunc('claim'),
346
352
  status: 'queued',
347
353
  priority: 'normal',
348
354
  createdAt: new Date(),
@@ -364,7 +370,7 @@ describe('TaskQueue', () => {
364
370
  it('should not claim already assigned task', async () => {
365
371
  const task: AnyTask = {
366
372
  id: 'claim_assigned',
367
- function: createTestFunc('claim'),
373
+ tool: createTestFunc('claim'),
368
374
  status: 'assigned',
369
375
  priority: 'normal',
370
376
  assignment: {
@@ -394,7 +400,7 @@ describe('TaskQueue', () => {
394
400
  it('should mark task as completed', async () => {
395
401
  const task: AnyTask = {
396
402
  id: 'complete_test',
397
- function: createTestFunc('complete'),
403
+ tool: createTestFunc('complete'),
398
404
  status: 'in_progress',
399
405
  priority: 'normal',
400
406
  createdAt: new Date(),
@@ -411,7 +417,7 @@ describe('TaskQueue', () => {
411
417
  it('should satisfy dependencies in other tasks', async () => {
412
418
  const task1: AnyTask = {
413
419
  id: 'dep_complete_1',
414
- function: createTestFunc('task1'),
420
+ tool: createTestFunc('task1'),
415
421
  status: 'in_progress',
416
422
  priority: 'normal',
417
423
  createdAt: new Date(),
@@ -420,7 +426,7 @@ describe('TaskQueue', () => {
420
426
 
421
427
  const task2: AnyTask = {
422
428
  id: 'dep_complete_2',
423
- function: createTestFunc('task2'),
429
+ tool: createTestFunc('task2'),
424
430
  status: 'blocked',
425
431
  priority: 'normal',
426
432
  dependencies: [{ type: 'blocked_by', taskId: 'dep_complete_1', satisfied: false }],
@@ -442,7 +448,7 @@ describe('TaskQueue', () => {
442
448
  it('should mark task as failed', async () => {
443
449
  const task: AnyTask = {
444
450
  id: 'fail_test',
445
- function: createTestFunc('fail'),
451
+ tool: createTestFunc('fail'),
446
452
  status: 'in_progress',
447
453
  priority: 'normal',
448
454
  createdAt: new Date(),
@@ -460,9 +466,30 @@ describe('TaskQueue', () => {
460
466
  describe('stats()', () => {
461
467
  it('should return queue statistics', async () => {
462
468
  const tasks: AnyTask[] = [
463
- { id: 's1', function: createTestFunc('t1'), status: 'queued', priority: 'high', createdAt: new Date(), events: [] },
464
- { id: 's2', function: createTestFunc('t2'), status: 'queued', priority: 'normal', createdAt: new Date(), events: [] },
465
- { id: 's3', function: createTestFunc('t3'), status: 'completed', priority: 'low', createdAt: new Date(), events: [] },
469
+ {
470
+ id: 's1',
471
+ tool: createTestFunc('t1'),
472
+ status: 'queued',
473
+ priority: 'high',
474
+ createdAt: new Date(),
475
+ events: [],
476
+ },
477
+ {
478
+ id: 's2',
479
+ tool: createTestFunc('t2'),
480
+ status: 'queued',
481
+ priority: 'normal',
482
+ createdAt: new Date(),
483
+ events: [],
484
+ },
485
+ {
486
+ id: 's3',
487
+ tool: createTestFunc('t3'),
488
+ status: 'completed',
489
+ priority: 'low',
490
+ createdAt: new Date(),
491
+ events: [],
492
+ },
466
493
  ]
467
494
 
468
495
  for (const task of tasks) {