@taskcast/core 0.2.0 → 0.3.1

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 (40) hide show
  1. package/dist/config.d.ts +13 -2
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js.map +1 -1
  4. package/dist/engine.d.ts +17 -1
  5. package/dist/engine.d.ts.map +1 -1
  6. package/dist/engine.js +93 -5
  7. package/dist/engine.js.map +1 -1
  8. package/dist/heartbeat-monitor.d.ts +40 -0
  9. package/dist/heartbeat-monitor.d.ts.map +1 -0
  10. package/dist/heartbeat-monitor.js +139 -0
  11. package/dist/heartbeat-monitor.js.map +1 -0
  12. package/dist/index.d.ts +4 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +4 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/memory-adapters.d.ts +15 -1
  17. package/dist/memory-adapters.d.ts.map +1 -1
  18. package/dist/memory-adapters.js +93 -0
  19. package/dist/memory-adapters.js.map +1 -1
  20. package/dist/scheduler.d.ts +24 -0
  21. package/dist/scheduler.d.ts.map +1 -0
  22. package/dist/scheduler.js +64 -0
  23. package/dist/scheduler.js.map +1 -0
  24. package/dist/series.d.ts.map +1 -1
  25. package/dist/series.js +3 -2
  26. package/dist/series.js.map +1 -1
  27. package/dist/state-machine.d.ts.map +1 -1
  28. package/dist/state-machine.js +4 -3
  29. package/dist/state-machine.js.map +1 -1
  30. package/dist/types.d.ts +87 -2
  31. package/dist/types.d.ts.map +1 -1
  32. package/dist/worker-manager.d.ts +68 -0
  33. package/dist/worker-manager.d.ts.map +1 -0
  34. package/dist/worker-manager.js +336 -0
  35. package/dist/worker-manager.js.map +1 -0
  36. package/dist/worker-matching.d.ts +23 -0
  37. package/dist/worker-matching.d.ts.map +1 -0
  38. package/dist/worker-matching.js +50 -0
  39. package/dist/worker-matching.js.map +1 -0
  40. package/package.json +1 -1
@@ -0,0 +1,336 @@
1
+ import { ulid } from 'ulidx';
2
+ import { matchesWorkerRule } from './worker-matching.js';
3
+ // ─── WorkerManager ──────────────────────────────────────────────────────────
4
+ export class WorkerManager {
5
+ opts;
6
+ engine;
7
+ shortTermStore;
8
+ longTermStore;
9
+ hooks;
10
+ constructor(opts) {
11
+ this.opts = opts;
12
+ this.engine = opts.engine;
13
+ this.shortTermStore = opts.shortTermStore;
14
+ if (opts.longTermStore)
15
+ this.longTermStore = opts.longTermStore;
16
+ if (opts.hooks)
17
+ this.hooks = opts.hooks;
18
+ }
19
+ get heartbeatIntervalMs() {
20
+ return this.opts.defaults?.heartbeatIntervalMs ?? 30_000;
21
+ }
22
+ // ─── Audit Helpers ──────────────────────────────────────────────────────
23
+ async emitTaskAudit(taskId, action, extra) {
24
+ try {
25
+ await this.opts.engine.publishEvent(taskId, {
26
+ type: 'taskcast:audit',
27
+ level: 'info',
28
+ data: { action, ...extra },
29
+ });
30
+ }
31
+ catch {
32
+ // Task may be in terminal state or not found; audit is best-effort
33
+ }
34
+ }
35
+ emitWorkerAudit(action, workerId, data) {
36
+ if (!this.opts.longTermStore)
37
+ return;
38
+ const event = {
39
+ id: ulid(),
40
+ workerId,
41
+ timestamp: Date.now(),
42
+ action,
43
+ ...(data !== undefined && { data }),
44
+ };
45
+ this.opts.longTermStore.saveWorkerEvent(event).catch(() => { });
46
+ }
47
+ // ─── Worker Registration & Lifecycle ────────────────────────────────────
48
+ async registerWorker(config) {
49
+ const now = Date.now();
50
+ const worker = {
51
+ id: config.id ?? ulid(),
52
+ status: 'idle',
53
+ matchRule: config.matchRule,
54
+ capacity: config.capacity,
55
+ usedSlots: 0,
56
+ weight: config.weight ?? 50,
57
+ connectionMode: config.connectionMode,
58
+ connectedAt: now,
59
+ lastHeartbeatAt: now,
60
+ ...(config.metadata !== undefined && { metadata: config.metadata }),
61
+ };
62
+ await this.shortTermStore.saveWorker(worker);
63
+ this.emitWorkerAudit('connected', worker.id);
64
+ this.hooks?.onWorkerConnected?.(worker);
65
+ return worker;
66
+ }
67
+ async unregisterWorker(workerId) {
68
+ const worker = await this.shortTermStore.getWorker(workerId);
69
+ await this.shortTermStore.deleteWorker(workerId);
70
+ if (worker) {
71
+ this.emitWorkerAudit('disconnected', workerId, { reason: 'unregistered' });
72
+ this.hooks?.onWorkerDisconnected?.(worker, 'unregistered');
73
+ }
74
+ }
75
+ async updateWorker(workerId, update) {
76
+ const worker = await this.shortTermStore.getWorker(workerId);
77
+ if (!worker)
78
+ return null;
79
+ if (update.weight !== undefined)
80
+ worker.weight = update.weight;
81
+ if (update.capacity !== undefined)
82
+ worker.capacity = update.capacity;
83
+ if (update.matchRule !== undefined)
84
+ worker.matchRule = update.matchRule;
85
+ if (update.status !== undefined)
86
+ worker.status = update.status;
87
+ await this.shortTermStore.saveWorker(worker);
88
+ return worker;
89
+ }
90
+ async heartbeat(workerId) {
91
+ const worker = await this.shortTermStore.getWorker(workerId);
92
+ if (!worker)
93
+ return;
94
+ worker.lastHeartbeatAt = Date.now();
95
+ await this.shortTermStore.saveWorker(worker);
96
+ }
97
+ async getWorker(workerId) {
98
+ return this.shortTermStore.getWorker(workerId);
99
+ }
100
+ async listWorkers(filter) {
101
+ return this.shortTermStore.listWorkers(filter);
102
+ }
103
+ // ─── Task Dispatch ─────────────────────────────────────────────────────
104
+ async dispatchTask(taskId) {
105
+ const task = await this.engine.getTask(taskId);
106
+ if (!task || task.status !== 'pending') {
107
+ return { matched: false };
108
+ }
109
+ const blacklist = task.metadata?._blacklistedWorkers ?? [];
110
+ const workers = await this.shortTermStore.listWorkers({ status: ['idle', 'busy'] });
111
+ const taskCost = task.cost ?? 1;
112
+ const candidates = workers.filter((w) => {
113
+ if (blacklist.includes(w.id))
114
+ return false;
115
+ if (w.usedSlots + taskCost > w.capacity)
116
+ return false;
117
+ if (!matchesWorkerRule(task, w.matchRule))
118
+ return false;
119
+ return true;
120
+ });
121
+ if (candidates.length === 0) {
122
+ return { matched: false };
123
+ }
124
+ // Sort: weight desc → available slots desc → connectedAt asc
125
+ candidates.sort((a, b) => {
126
+ if (b.weight !== a.weight)
127
+ return b.weight - a.weight;
128
+ const aAvailable = a.capacity - a.usedSlots;
129
+ const bAvailable = b.capacity - b.usedSlots;
130
+ if (bAvailable !== aAvailable)
131
+ return bAvailable - aAvailable;
132
+ return a.connectedAt - b.connectedAt;
133
+ });
134
+ return { matched: true, workerId: candidates[0].id };
135
+ }
136
+ // ─── Task Claim ────────────────────────────────────────────────────────
137
+ async claimTask(taskId, workerId) {
138
+ const task = await this.engine.getTask(taskId);
139
+ if (!task) {
140
+ return { success: false, reason: 'Task not found' };
141
+ }
142
+ if (task.status !== 'pending') {
143
+ return { success: false, reason: `Task is not pending (status: ${task.status})` };
144
+ }
145
+ const cost = task.cost ?? 1;
146
+ const claimed = await this.shortTermStore.claimTask(taskId, workerId, cost);
147
+ if (!claimed) {
148
+ return { success: false, reason: 'Claim failed (concurrent modification)' };
149
+ }
150
+ // claimTask atomically sets status to 'assigned' and assignedWorker on the
151
+ // store. Re-read to get the authoritative state, then persist to longTermStore.
152
+ const updatedTask = (await this.shortTermStore.getTask(taskId));
153
+ if (this.longTermStore)
154
+ await this.longTermStore.saveTask(updatedTask);
155
+ // Emit audit events for the claim
156
+ this.emitWorkerAudit('task_assigned', workerId, { taskId });
157
+ await this.emitTaskAudit(taskId, 'assigned', { workerId });
158
+ // Create assignment record
159
+ const assignment = {
160
+ taskId,
161
+ workerId,
162
+ cost,
163
+ assignedAt: Date.now(),
164
+ status: 'assigned',
165
+ };
166
+ await this.shortTermStore.addAssignment(assignment);
167
+ // Update worker status (usedSlots already updated by claimTask)
168
+ const worker = await this.shortTermStore.getWorker(workerId);
169
+ if (worker) {
170
+ worker.status = worker.usedSlots >= worker.capacity ? 'busy' : 'idle';
171
+ await this.shortTermStore.saveWorker(worker);
172
+ this.hooks?.onTaskAssigned?.(updatedTask, worker);
173
+ }
174
+ return { success: true };
175
+ }
176
+ // ─── Task Decline ──────────────────────────────────────────────────────
177
+ async declineTask(taskId, workerId, opts) {
178
+ const assignment = await this.shortTermStore.getTaskAssignment(taskId);
179
+ if (!assignment || assignment.workerId !== workerId)
180
+ return;
181
+ // Remove assignment
182
+ await this.shortTermStore.removeAssignment(taskId);
183
+ // Restore worker capacity
184
+ const worker = await this.shortTermStore.getWorker(workerId);
185
+ if (worker) {
186
+ worker.usedSlots = Math.max(0, worker.usedSlots - assignment.cost);
187
+ worker.status = 'idle';
188
+ await this.shortTermStore.saveWorker(worker);
189
+ }
190
+ // Transition task back to pending
191
+ await this.engine.transitionTask(taskId, 'pending');
192
+ // Emit audit events for the decline
193
+ const blacklisted = opts?.blacklist ?? false;
194
+ this.emitWorkerAudit('task_declined', workerId, { taskId });
195
+ await this.emitTaskAudit(taskId, 'declined', { workerId, blacklisted });
196
+ // Clear assignedWorker
197
+ const task = await this.engine.getTask(taskId);
198
+ if (task) {
199
+ delete task.assignedWorker;
200
+ // Add to blacklist if requested
201
+ if (opts?.blacklist) {
202
+ const metadata = task.metadata ?? {};
203
+ const existing = metadata._blacklistedWorkers ?? [];
204
+ metadata._blacklistedWorkers = [...existing, workerId];
205
+ task.metadata = metadata;
206
+ }
207
+ await this.shortTermStore.saveTask(task);
208
+ if (this.longTermStore)
209
+ await this.longTermStore.saveTask(task);
210
+ if (worker) {
211
+ this.hooks?.onTaskDeclined?.(task, worker, blacklisted);
212
+ }
213
+ }
214
+ }
215
+ // ─── Worker Tasks ──────────────────────────────────────────────────────
216
+ async getWorkerTasks(workerId) {
217
+ return this.shortTermStore.getWorkerAssignments(workerId);
218
+ }
219
+ // ─── Task Release ───────────────────────────────────────────────────────
220
+ async releaseTask(taskId) {
221
+ const assignment = await this.shortTermStore.getTaskAssignment(taskId);
222
+ if (!assignment)
223
+ return;
224
+ // Remove the assignment record
225
+ await this.shortTermStore.removeAssignment(taskId);
226
+ // Restore worker capacity (but don't change status if offline/draining)
227
+ const worker = await this.shortTermStore.getWorker(assignment.workerId);
228
+ if (worker) {
229
+ worker.usedSlots = Math.max(0, worker.usedSlots - assignment.cost);
230
+ if (worker.status !== 'offline' && worker.status !== 'draining') {
231
+ worker.status = worker.usedSlots >= worker.capacity ? 'busy' : 'idle';
232
+ }
233
+ await this.shortTermStore.saveWorker(worker);
234
+ }
235
+ // Clear assignedWorker on the task
236
+ const task = await this.engine.getTask(taskId);
237
+ if (task) {
238
+ delete task.assignedWorker;
239
+ await this.shortTermStore.saveTask(task);
240
+ }
241
+ this.emitWorkerAudit('task_reclaimed', assignment.workerId, { taskId });
242
+ }
243
+ // ─── Pull Mode (Long-Poll) ─────────────────────────────────────────────
244
+ async waitForTask(workerId, signal) {
245
+ const worker = await this.shortTermStore.getWorker(workerId);
246
+ if (!worker)
247
+ throw new Error(`Worker not found: ${workerId}`);
248
+ // Check if already aborted
249
+ if (signal?.aborted) {
250
+ throw new Error('aborted');
251
+ }
252
+ // Check existing pending pull tasks
253
+ const pendingTasks = await this.shortTermStore.listTasks({ status: ['pending'], assignMode: ['pull'] });
254
+ const blacklist = new Set();
255
+ for (const task of pendingTasks) {
256
+ const taskBlacklist = task.metadata?._blacklistedWorkers ?? [];
257
+ if (taskBlacklist.includes(workerId))
258
+ continue;
259
+ if (!matchesWorkerRule(task, worker.matchRule))
260
+ continue;
261
+ const taskCost = task.cost ?? 1;
262
+ if (worker.usedSlots + taskCost > worker.capacity)
263
+ continue;
264
+ const result = await this.claimTask(task.id, workerId);
265
+ if (result.success) {
266
+ this.emitWorkerAudit('pull_request', workerId, { matched: true, taskId: task.id });
267
+ const claimed = await this.engine.getTask(task.id);
268
+ return claimed;
269
+ }
270
+ }
271
+ // Wait for a new task notification via broadcast
272
+ return new Promise((resolve, reject) => {
273
+ let unsubscribe;
274
+ const cleanup = () => {
275
+ unsubscribe?.();
276
+ signal?.removeEventListener('abort', onAbort);
277
+ };
278
+ const onAbort = () => {
279
+ cleanup();
280
+ this.emitWorkerAudit('pull_request', workerId, { matched: false });
281
+ reject(new Error('aborted'));
282
+ };
283
+ if (signal) {
284
+ signal.addEventListener('abort', onAbort);
285
+ }
286
+ unsubscribe = this.opts.broadcast.subscribe('taskcast:worker:new-task', async (event) => {
287
+ const taskId = event.data;
288
+ try {
289
+ // Re-fetch the worker to get current state
290
+ const currentWorker = await this.shortTermStore.getWorker(workerId);
291
+ if (!currentWorker) {
292
+ cleanup();
293
+ reject(new Error(`Worker not found: ${workerId}`));
294
+ return;
295
+ }
296
+ const task = await this.engine.getTask(taskId);
297
+ if (!task || task.status !== 'pending')
298
+ return;
299
+ if (task.assignMode !== 'pull')
300
+ return;
301
+ const taskBlacklist = task.metadata?._blacklistedWorkers ?? [];
302
+ if (taskBlacklist.includes(workerId))
303
+ return;
304
+ if (!matchesWorkerRule(task, currentWorker.matchRule))
305
+ return;
306
+ const taskCost = task.cost ?? 1;
307
+ if (currentWorker.usedSlots + taskCost > currentWorker.capacity)
308
+ return;
309
+ const result = await this.claimTask(taskId, workerId);
310
+ if (result.success) {
311
+ cleanup();
312
+ this.emitWorkerAudit('pull_request', workerId, { matched: true, taskId });
313
+ const claimed = await this.engine.getTask(taskId);
314
+ resolve(claimed);
315
+ }
316
+ }
317
+ catch {
318
+ // Ignore errors from individual task checks
319
+ }
320
+ });
321
+ });
322
+ }
323
+ async notifyNewTask(taskId) {
324
+ const event = {
325
+ id: ulid(),
326
+ taskId: 'system',
327
+ index: 0,
328
+ timestamp: Date.now(),
329
+ type: 'taskcast:worker:new-task',
330
+ level: 'info',
331
+ data: taskId,
332
+ };
333
+ await this.opts.broadcast.publish('taskcast:worker:new-task', event);
334
+ }
335
+ }
336
+ //# sourceMappingURL=worker-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-manager.js","sourceRoot":"","sources":["../src/worker-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { Task, TagMatcher, WorkerMatchRule } from './types.js';
2
+ /**
3
+ * Checks if a set of task tags matches a TagMatcher.
4
+ *
5
+ * - `all`: every tag in `all` must exist in taskTags
6
+ * - `any`: at least one tag in `any` must exist in taskTags
7
+ * - `none`: none of the tags in `none` may exist in taskTags
8
+ * - Empty/undefined matcher matches everything
9
+ * - Undefined taskTags treated as empty array
10
+ * - Empty arrays in matcher fields are vacuous true
11
+ */
12
+ export declare function matchesTag(taskTags: string[] | undefined, matcher: TagMatcher): boolean;
13
+ /**
14
+ * Checks if a task matches a WorkerMatchRule.
15
+ *
16
+ * - If rule has `taskTypes`: task.type must match using wildcard matching
17
+ * - If rule has `tags`: use matchesTag
18
+ * - Both conditions are AND'd
19
+ * - Empty/no rule matches everything
20
+ * - Task with no `type` does not match if rule has `taskTypes`
21
+ */
22
+ export declare function matchesWorkerRule(task: Task, rule: WorkerMatchRule): boolean;
23
+ //# sourceMappingURL=worker-matching.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-matching.d.ts","sourceRoot":"","sources":["../src/worker-matching.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAGnE;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAgBvF;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAW5E"}
@@ -0,0 +1,50 @@
1
+ import { matchesType } from './filter.js';
2
+ /**
3
+ * Checks if a set of task tags matches a TagMatcher.
4
+ *
5
+ * - `all`: every tag in `all` must exist in taskTags
6
+ * - `any`: at least one tag in `any` must exist in taskTags
7
+ * - `none`: none of the tags in `none` may exist in taskTags
8
+ * - Empty/undefined matcher matches everything
9
+ * - Undefined taskTags treated as empty array
10
+ * - Empty arrays in matcher fields are vacuous true
11
+ */
12
+ export function matchesTag(taskTags, matcher) {
13
+ const tags = taskTags ?? [];
14
+ if (matcher.all !== undefined && matcher.all.length > 0) {
15
+ if (!matcher.all.every((tag) => tags.includes(tag)))
16
+ return false;
17
+ }
18
+ if (matcher.any !== undefined && matcher.any.length > 0) {
19
+ if (!matcher.any.some((tag) => tags.includes(tag)))
20
+ return false;
21
+ }
22
+ if (matcher.none !== undefined && matcher.none.length > 0) {
23
+ if (matcher.none.some((tag) => tags.includes(tag)))
24
+ return false;
25
+ }
26
+ return true;
27
+ }
28
+ /**
29
+ * Checks if a task matches a WorkerMatchRule.
30
+ *
31
+ * - If rule has `taskTypes`: task.type must match using wildcard matching
32
+ * - If rule has `tags`: use matchesTag
33
+ * - Both conditions are AND'd
34
+ * - Empty/no rule matches everything
35
+ * - Task with no `type` does not match if rule has `taskTypes`
36
+ */
37
+ export function matchesWorkerRule(task, rule) {
38
+ if (rule.taskTypes !== undefined && rule.taskTypes.length > 0) {
39
+ if (task.type === undefined)
40
+ return false;
41
+ if (!matchesType(task.type, rule.taskTypes))
42
+ return false;
43
+ }
44
+ if (rule.tags !== undefined) {
45
+ if (!matchesTag(task.tags, rule.tags))
46
+ return false;
47
+ }
48
+ return true;
49
+ }
50
+ //# sourceMappingURL=worker-matching.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-matching.js","sourceRoot":"","sources":["../src/worker-matching.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CAAC,QAA8B,EAAE,OAAmB;IAC5E,MAAM,IAAI,GAAG,QAAQ,IAAI,EAAE,CAAA;IAE3B,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAA;IACnE,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAA;IAClE,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1D,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAA;IAClE,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAU,EAAE,IAAqB;IACjE,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9D,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,KAAK,CAAA;QACzC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YAAE,OAAO,KAAK,CAAA;IAC3D,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAA;IACrD,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taskcast/core",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Task engine, state machine, filtering, series merging. Zero HTTP deps.",
5
5
  "repository": {
6
6
  "type": "git",