@polpo-ai/core 0.1.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 (122) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapter.d.ts +61 -0
  3. package/dist/adapter.d.ts.map +1 -0
  4. package/dist/adapter.js +9 -0
  5. package/dist/adapter.js.map +1 -0
  6. package/dist/agent-manager.d.ts +36 -0
  7. package/dist/agent-manager.d.ts.map +1 -0
  8. package/dist/agent-manager.js +176 -0
  9. package/dist/agent-manager.js.map +1 -0
  10. package/dist/approval-manager.d.ts +49 -0
  11. package/dist/approval-manager.d.ts.map +1 -0
  12. package/dist/approval-manager.js +325 -0
  13. package/dist/approval-manager.js.map +1 -0
  14. package/dist/approval-store.d.ts +19 -0
  15. package/dist/approval-store.d.ts.map +1 -0
  16. package/dist/approval-store.js +2 -0
  17. package/dist/approval-store.js.map +1 -0
  18. package/dist/checkpoint-store.d.ts +20 -0
  19. package/dist/checkpoint-store.d.ts.map +1 -0
  20. package/dist/checkpoint-store.js +2 -0
  21. package/dist/checkpoint-store.js.map +1 -0
  22. package/dist/config-store.d.ts +13 -0
  23. package/dist/config-store.d.ts.map +1 -0
  24. package/dist/config-store.js +2 -0
  25. package/dist/config-store.js.map +1 -0
  26. package/dist/cron.d.ts +29 -0
  27. package/dist/cron.d.ts.map +1 -0
  28. package/dist/cron.js +105 -0
  29. package/dist/cron.js.map +1 -0
  30. package/dist/delay-store.d.ts +21 -0
  31. package/dist/delay-store.d.ts.map +1 -0
  32. package/dist/delay-store.js +2 -0
  33. package/dist/delay-store.js.map +1 -0
  34. package/dist/escalation-manager.d.ts +31 -0
  35. package/dist/escalation-manager.d.ts.map +1 -0
  36. package/dist/escalation-manager.js +281 -0
  37. package/dist/escalation-manager.js.map +1 -0
  38. package/dist/event-bus.d.ts +18 -0
  39. package/dist/event-bus.d.ts.map +1 -0
  40. package/dist/event-bus.js +2 -0
  41. package/dist/event-bus.js.map +1 -0
  42. package/dist/events.d.ts +377 -0
  43. package/dist/events.d.ts.map +1 -0
  44. package/dist/events.js +9 -0
  45. package/dist/events.js.map +1 -0
  46. package/dist/hooks.d.ts +185 -0
  47. package/dist/hooks.d.ts.map +1 -0
  48. package/dist/hooks.js +152 -0
  49. package/dist/hooks.js.map +1 -0
  50. package/dist/index.d.ts +31 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +22 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/log-store.d.ts +31 -0
  55. package/dist/log-store.d.ts.map +1 -0
  56. package/dist/log-store.js +6 -0
  57. package/dist/log-store.js.map +1 -0
  58. package/dist/memory-store.d.ts +17 -0
  59. package/dist/memory-store.d.ts.map +1 -0
  60. package/dist/memory-store.js +2 -0
  61. package/dist/memory-store.js.map +1 -0
  62. package/dist/notification-router-port.d.ts +11 -0
  63. package/dist/notification-router-port.d.ts.map +1 -0
  64. package/dist/notification-router-port.js +2 -0
  65. package/dist/notification-router-port.js.map +1 -0
  66. package/dist/notification-store.d.ts +58 -0
  67. package/dist/notification-store.d.ts.map +1 -0
  68. package/dist/notification-store.js +9 -0
  69. package/dist/notification-store.js.map +1 -0
  70. package/dist/orchestrator-context.d.ts +87 -0
  71. package/dist/orchestrator-context.d.ts.map +1 -0
  72. package/dist/orchestrator-context.js +2 -0
  73. package/dist/orchestrator-context.js.map +1 -0
  74. package/dist/peer-store.d.ts +29 -0
  75. package/dist/peer-store.d.ts.map +1 -0
  76. package/dist/peer-store.js +6 -0
  77. package/dist/peer-store.js.map +1 -0
  78. package/dist/quality-controller.d.ts +46 -0
  79. package/dist/quality-controller.d.ts.map +1 -0
  80. package/dist/quality-controller.js +373 -0
  81. package/dist/quality-controller.js.map +1 -0
  82. package/dist/run-store.d.ts +31 -0
  83. package/dist/run-store.d.ts.map +1 -0
  84. package/dist/run-store.js +2 -0
  85. package/dist/run-store.js.map +1 -0
  86. package/dist/scheduler.d.ts +35 -0
  87. package/dist/scheduler.d.ts.map +1 -0
  88. package/dist/scheduler.js +195 -0
  89. package/dist/scheduler.js.map +1 -0
  90. package/dist/schemas.d.ts +104 -0
  91. package/dist/schemas.d.ts.map +1 -0
  92. package/dist/schemas.js +200 -0
  93. package/dist/schemas.js.map +1 -0
  94. package/dist/session-store.d.ts +50 -0
  95. package/dist/session-store.d.ts.map +1 -0
  96. package/dist/session-store.js +6 -0
  97. package/dist/session-store.js.map +1 -0
  98. package/dist/sla-monitor.d.ts +30 -0
  99. package/dist/sla-monitor.d.ts.map +1 -0
  100. package/dist/sla-monitor.js +156 -0
  101. package/dist/sla-monitor.js.map +1 -0
  102. package/dist/state-machine.d.ts +8 -0
  103. package/dist/state-machine.d.ts.map +1 -0
  104. package/dist/state-machine.js +23 -0
  105. package/dist/state-machine.js.map +1 -0
  106. package/dist/task-manager.d.ts +38 -0
  107. package/dist/task-manager.d.ts.map +1 -0
  108. package/dist/task-manager.js +308 -0
  109. package/dist/task-manager.js.map +1 -0
  110. package/dist/task-store.d.ts +33 -0
  111. package/dist/task-store.d.ts.map +1 -0
  112. package/dist/task-store.js +2 -0
  113. package/dist/task-store.js.map +1 -0
  114. package/dist/task-watcher.d.ts +38 -0
  115. package/dist/task-watcher.d.ts.map +1 -0
  116. package/dist/task-watcher.js +103 -0
  117. package/dist/task-watcher.js.map +1 -0
  118. package/dist/types.d.ts +1073 -0
  119. package/dist/types.d.ts.map +1 -0
  120. package/dist/types.js +35 -0
  121. package/dist/types.js.map +1 -0
  122. package/package.json +170 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-machine.js","sourceRoot":"","sources":["../src/state-machine.ts"],"names":[],"mappings":"AAEA,0DAA0D;AAC1D,MAAM,CAAC,MAAM,iBAAiB,GAAwD;IACpF,KAAK,EAAE,CAAC,SAAS,CAAC;IAClB,OAAO,EAAE,CAAC,UAAU,EAAE,mBAAmB,CAAC;IAC1C,iBAAiB,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC;IAC5D,QAAQ,EAAE,CAAC,aAAa,EAAE,mBAAmB,CAAC;IAC9C,WAAW,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,mBAAmB,CAAC;IACtD,MAAM,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,mBAAmB,CAAC;IAC/C,IAAI,EAAE,EAAE;IACR,MAAM,EAAE,CAAC,SAAS,CAAC;CACX,CAAC;AAEX,sEAAsE;AACtE,MAAM,UAAU,iBAAiB,CAAC,IAAgB,EAAE,EAAc;IAChE,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,qBAAqB,CAAC,IAAgB,EAAE,EAAc;IACpE,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,uBAAuB,IAAI,MAAM,EAAE,cAAc,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,GAAG,CACjF,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { OrchestratorContext } from "./orchestrator-context.js";
2
+ import type { Task, TaskExpectation, ExpectedOutcome, RetryPolicy, ScopedNotificationRules } from "./types.js";
3
+ /**
4
+ * Task CRUD: add, update, retry, reassess, kill, abort, clear.
5
+ */
6
+ export declare class TaskManager {
7
+ private ctx;
8
+ private idMap;
9
+ constructor(ctx: OrchestratorContext);
10
+ addTask(opts: {
11
+ title: string;
12
+ description: string;
13
+ assignTo: string;
14
+ expectations?: TaskExpectation[];
15
+ expectedOutcomes?: ExpectedOutcome[];
16
+ dependsOn?: string[];
17
+ group?: string;
18
+ missionId?: string;
19
+ maxDuration?: number;
20
+ retryPolicy?: RetryPolicy;
21
+ notifications?: ScopedNotificationRules;
22
+ sideEffects?: boolean;
23
+ draft?: boolean;
24
+ }): Promise<Task>;
25
+ updateTaskDescription(taskId: string, description: string): Promise<void>;
26
+ updateTaskAssignment(taskId: string, agentName: string): Promise<void>;
27
+ updateTaskExpectations(taskId: string, expectations: TaskExpectation[]): Promise<void>;
28
+ retryTask(taskId: string): Promise<void>;
29
+ reassessTask(taskId: string): Promise<void>;
30
+ killTask(taskId: string): Promise<boolean>;
31
+ abortGroup(group: string): Promise<number>;
32
+ clearTasks(filter: (task: Task) => boolean): Promise<number>;
33
+ /** Load initial tasks from config (non-interactive mode). */
34
+ seedTasks(): Promise<void>;
35
+ /** Force a task through the state machine to failed (used by deadlock resolver). */
36
+ forceFailTask(taskId: string): Promise<void>;
37
+ }
38
+ //# sourceMappingURL=task-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-manager.d.ts","sourceRoot":"","sources":["../src/task-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,eAAe,EAAE,WAAW,EAAiB,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAI9H;;GAEG;AACH,qBAAa,WAAW;IAGV,OAAO,CAAC,GAAG;IAFvB,OAAO,CAAC,KAAK,CAA6B;gBAEtB,GAAG,EAAE,mBAAmB;IAEtC,OAAO,CAAC,IAAI,EAAE;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;QACjC,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;QACrC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,WAAW,CAAC;QAC1B,aAAa,CAAC,EAAE,uBAAuB,CAAC;QACxC,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,GAAG,OAAO,CAAC,IAAI,CAAC;IAwEX,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzE,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItE,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAatF,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOxC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyF3C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAqB1C,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoB1C,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAalE,6DAA6D;IACvD,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAuChC,oFAAoF;IAC9E,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWnD"}
@@ -0,0 +1,308 @@
1
+ import { setAssessment } from "./types.js";
2
+ import { sanitizeExpectations } from "./schemas.js";
3
+ /**
4
+ * Task CRUD: add, update, retry, reassess, kill, abort, clear.
5
+ */
6
+ export class TaskManager {
7
+ ctx;
8
+ idMap = new Map();
9
+ constructor(ctx) {
10
+ this.ctx = ctx;
11
+ }
12
+ async addTask(opts) {
13
+ if (!this.ctx.registry)
14
+ throw new Error("Orchestrator not initialized");
15
+ // Run before:task:create hook (sync — addTask is synchronous)
16
+ const hookResult = this.ctx.hooks.runBeforeSync("task:create", {
17
+ title: opts.title,
18
+ description: opts.description,
19
+ assignTo: opts.assignTo,
20
+ expectations: opts.expectations,
21
+ expectedOutcomes: opts.expectedOutcomes,
22
+ dependsOn: opts.dependsOn,
23
+ group: opts.group,
24
+ missionId: opts.missionId,
25
+ maxDuration: opts.maxDuration,
26
+ retryPolicy: opts.retryPolicy,
27
+ notifications: opts.notifications,
28
+ sideEffects: opts.sideEffects,
29
+ draft: opts.draft,
30
+ });
31
+ if (hookResult.cancelled) {
32
+ throw new Error(`Task creation blocked by hook: ${hookResult.cancelReason ?? "no reason"}`);
33
+ }
34
+ // Apply any modifications from hooks
35
+ const hookData = hookResult.data;
36
+ // Enforce unique title among active (non-terminal) tasks
37
+ const existingTasks = await this.ctx.registry.getAllTasks();
38
+ const duplicate = existingTasks.find(t => t.title === hookData.title && t.status !== "done" && t.status !== "failed");
39
+ if (duplicate) {
40
+ throw new Error(`A task with title "${hookData.title}" already exists (id: ${duplicate.id}, status: ${duplicate.status}). ` +
41
+ `Task titles must be unique among active tasks.`);
42
+ }
43
+ const rawExps = hookData.expectations ?? [];
44
+ const { valid: expectations, warnings } = sanitizeExpectations(rawExps);
45
+ for (const w of warnings)
46
+ this.ctx.emitter.emit("log", { level: "warn", message: `[addTask "${hookData.title}"] ${w}` });
47
+ const task = await this.ctx.registry.addTask({
48
+ title: hookData.title,
49
+ description: hookData.description,
50
+ assignTo: hookData.assignTo,
51
+ group: hookData.group,
52
+ missionId: hookData.missionId ?? opts.missionId,
53
+ dependsOn: hookData.dependsOn ?? [],
54
+ expectations,
55
+ expectedOutcomes: hookData.expectedOutcomes,
56
+ metrics: [],
57
+ maxRetries: this.ctx.config.settings.maxRetries,
58
+ maxDuration: hookData.maxDuration,
59
+ retryPolicy: hookData.retryPolicy,
60
+ notifications: hookData.notifications,
61
+ sideEffects: hookData.sideEffects,
62
+ status: hookData.draft ? "draft" : undefined,
63
+ });
64
+ this.ctx.emitter.emit("task:created", { task });
65
+ // Fire after:task:create hook (async, fire-and-forget)
66
+ this.ctx.hooks.runAfter("task:create", {
67
+ title: task.title,
68
+ description: task.description,
69
+ assignTo: task.assignTo,
70
+ expectations: task.expectations,
71
+ dependsOn: task.dependsOn,
72
+ group: task.group,
73
+ }).catch(() => { });
74
+ return task;
75
+ }
76
+ async updateTaskDescription(taskId, description) {
77
+ await this.ctx.registry.updateTask(taskId, { description });
78
+ }
79
+ async updateTaskAssignment(taskId, agentName) {
80
+ await this.ctx.registry.updateTask(taskId, { assignTo: agentName });
81
+ }
82
+ async updateTaskExpectations(taskId, expectations) {
83
+ const task = await this.ctx.registry.getTask(taskId);
84
+ if (!task)
85
+ throw new Error("Task not found");
86
+ const editable = ["pending", "failed", "done"];
87
+ if (!editable.includes(task.status)) {
88
+ throw new Error(`Cannot edit expectations of task in "${task.status}" state`);
89
+ }
90
+ const { valid, warnings } = sanitizeExpectations(expectations);
91
+ for (const w of warnings)
92
+ this.ctx.emitter.emit("log", { level: "warn", message: `[updateExpectations "${taskId}"] ${w}` });
93
+ await this.ctx.registry.updateTask(taskId, { expectations: valid });
94
+ this.ctx.emitter.emit("task:updated", { task: (await this.ctx.registry.getTask(taskId)) });
95
+ }
96
+ async retryTask(taskId) {
97
+ const task = await this.ctx.registry.getTask(taskId);
98
+ if (!task)
99
+ throw new Error("Task not found");
100
+ if (task.status !== "failed")
101
+ throw new Error(`Cannot retry task in "${task.status}" state`);
102
+ await this.ctx.registry.transition(taskId, "pending");
103
+ }
104
+ async reassessTask(taskId) {
105
+ const task = await this.ctx.registry.getTask(taskId);
106
+ if (!task)
107
+ throw new Error("Task not found");
108
+ if (task.status !== "done" && task.status !== "failed") {
109
+ throw new Error(`Cannot reassess task in "${task.status}" state`);
110
+ }
111
+ if (task.expectations.length === 0 && task.metrics.length === 0) {
112
+ throw new Error("Task has no expectations or metrics to assess");
113
+ }
114
+ this.ctx.emitter.emit("assessment:started", { taskId });
115
+ const result = task.result ?? { exitCode: 0, stdout: "", stderr: "", duration: 0 };
116
+ const onProgress = (msg) => this.ctx.emitter.emit("assessment:progress", { taskId, message: msg });
117
+ // Build rich ReviewContext from RunStore, JSONL transcript, and outcomes
118
+ const run = await this.ctx.runStore.getRunByTaskId(taskId);
119
+ const activity = run?.activity;
120
+ const outcomes = run?.outcomes ?? task.outcomes;
121
+ let executionSummary;
122
+ let toolsSummary;
123
+ try {
124
+ if (this.ctx.findLogForTask && this.ctx.buildExecutionSummary) {
125
+ const logPath = this.ctx.findLogForTask(this.ctx.polpoDir, taskId, run?.id);
126
+ if (logPath) {
127
+ const summaryResult = this.ctx.buildExecutionSummary(logPath);
128
+ executionSummary = summaryResult.summary;
129
+ toolsSummary = summaryResult.toolsSummary;
130
+ }
131
+ }
132
+ }
133
+ catch { /* best effort */ }
134
+ const reviewContext = {
135
+ taskTitle: task.title,
136
+ taskDescription: task.originalDescription ?? task.description,
137
+ agentOutput: result.stdout || undefined,
138
+ agentStderr: result.stderr || undefined,
139
+ exitCode: result.exitCode,
140
+ duration: result.duration,
141
+ filesCreated: activity?.filesCreated,
142
+ filesEdited: activity?.filesEdited,
143
+ toolCalls: activity?.toolCalls,
144
+ toolsSummary: toolsSummary || undefined,
145
+ executionSummary,
146
+ outcomes: outcomes?.length ? outcomes : undefined,
147
+ };
148
+ try {
149
+ const assessment = await this.ctx.assessFn(task, this.ctx.agentWorkDir, onProgress, reviewContext, this.ctx.config.settings.reasoning);
150
+ setAssessment(result, assessment, "reassess");
151
+ await this.ctx.registry.updateTask(taskId, { result });
152
+ if (assessment.passed) {
153
+ this.ctx.emitter.emit("assessment:complete", {
154
+ taskId,
155
+ passed: true,
156
+ scores: assessment.scores,
157
+ globalScore: assessment.globalScore,
158
+ message: `Reassessment PASSED`,
159
+ });
160
+ if (task.status === "failed") {
161
+ await this.ctx.registry.transition(taskId, "pending");
162
+ await this.ctx.registry.transition(taskId, "assigned");
163
+ await this.ctx.registry.transition(taskId, "in_progress");
164
+ await this.ctx.registry.transition(taskId, "review");
165
+ await this.ctx.registry.transition(taskId, "done");
166
+ }
167
+ }
168
+ else {
169
+ const reasons = [
170
+ ...assessment.checks.filter(c => !c.passed).map(c => `${c.type}: ${c.message}`),
171
+ ...assessment.metrics.filter(m => !m.passed).map(m => `${m.name}: ${m.value} < ${m.threshold}`),
172
+ ];
173
+ this.ctx.emitter.emit("assessment:complete", {
174
+ taskId,
175
+ passed: false,
176
+ scores: assessment.scores,
177
+ globalScore: assessment.globalScore,
178
+ message: `Reassessment FAILED — ${reasons.join(", ")}`,
179
+ });
180
+ if (task.status === "done") {
181
+ await this.ctx.registry.unsafeSetStatus(taskId, "failed", "reassessment invalidated done task");
182
+ }
183
+ }
184
+ }
185
+ catch (err) {
186
+ const message = err instanceof Error ? err.message : String(err);
187
+ this.ctx.emitter.emit("log", { level: "error", message: `[${taskId}] Reassessment error: ${message}` });
188
+ }
189
+ }
190
+ async killTask(taskId) {
191
+ const run = await this.ctx.runStore.getRunByTaskId(taskId);
192
+ if (run && run.status === "running" && run.pid > 0) {
193
+ if (this.ctx.killProcess) {
194
+ try {
195
+ this.ctx.killProcess(run.pid, "SIGTERM");
196
+ }
197
+ catch { /* already dead */ }
198
+ }
199
+ }
200
+ const task = await this.ctx.registry.getTask(taskId);
201
+ if (!task)
202
+ return false;
203
+ if (task.status !== "done" && task.status !== "failed") {
204
+ try {
205
+ if (task.status === "pending")
206
+ await this.ctx.registry.transition(taskId, "assigned");
207
+ if (task.status === "assigned")
208
+ await this.ctx.registry.transition(taskId, "in_progress");
209
+ await this.ctx.registry.transition(taskId, "failed");
210
+ }
211
+ catch { /* transition race — force status */
212
+ await this.ctx.registry.unsafeSetStatus(taskId, "failed", "killTask transition race fallback");
213
+ }
214
+ }
215
+ return true;
216
+ }
217
+ async abortGroup(group) {
218
+ const tasks = await this.ctx.registry.getAllTasks();
219
+ const groupTasks = tasks.filter(t => t.group === group);
220
+ let count = 0;
221
+ for (const task of groupTasks) {
222
+ if (task.status === "done" || task.status === "failed")
223
+ continue;
224
+ await this.killTask(task.id);
225
+ count++;
226
+ }
227
+ // Resolve mission via task.missionId (direct FK) first, fallback to group name
228
+ const mid = groupTasks.find(t => t.missionId)?.missionId;
229
+ const mission = mid
230
+ ? await this.ctx.registry.getMission?.(mid)
231
+ : await this.ctx.registry.getMissionByName?.(group);
232
+ if (mission && mission.status === "active") {
233
+ await this.ctx.registry.updateMission?.(mission.id, { status: "cancelled" });
234
+ }
235
+ return count;
236
+ }
237
+ async clearTasks(filter) {
238
+ const tasks = (await this.ctx.registry.getAllTasks()).filter(filter);
239
+ for (const task of tasks) {
240
+ const run = await this.ctx.runStore.getRunByTaskId(task.id);
241
+ if (run && run.status === "running" && run.pid > 0) {
242
+ if (this.ctx.killProcess) {
243
+ try {
244
+ this.ctx.killProcess(run.pid, "SIGTERM");
245
+ }
246
+ catch { /* already dead */ }
247
+ }
248
+ }
249
+ }
250
+ return await this.ctx.registry.removeTasks(filter);
251
+ }
252
+ /** Load initial tasks from config (non-interactive mode). */
253
+ async seedTasks() {
254
+ if (!this.ctx.config.tasks.length)
255
+ return;
256
+ for (const ct of this.ctx.config.tasks) {
257
+ const rawExps = ct.expectations ?? [];
258
+ const { valid: expectations, warnings } = sanitizeExpectations(rawExps);
259
+ for (const w of warnings)
260
+ this.ctx.emitter.emit("log", { level: "warn", message: `[seed "${ct.title}"] ${w}` });
261
+ const task = await this.ctx.registry.addTask({
262
+ title: ct.title,
263
+ description: ct.description,
264
+ assignTo: ct.assignTo,
265
+ dependsOn: [],
266
+ expectations,
267
+ metrics: [],
268
+ maxRetries: this.ctx.config.settings.maxRetries,
269
+ maxDuration: ct.maxDuration,
270
+ retryPolicy: ct.retryPolicy,
271
+ });
272
+ this.idMap.set(ct.title, task.id);
273
+ this.idMap.set(task.id, task.id);
274
+ this.ctx.emitter.emit("task:created", { task });
275
+ }
276
+ // Resolve dependencies by title → id
277
+ for (const ct of this.ctx.config.tasks) {
278
+ if (!ct.dependsOn?.length)
279
+ continue;
280
+ const taskId = this.idMap.get(ct.title);
281
+ if (!taskId)
282
+ continue;
283
+ const resolved = ct.dependsOn
284
+ .map(dep => this.idMap.get(dep))
285
+ .filter((id) => !!id);
286
+ if (resolved.length > 0) {
287
+ await this.ctx.registry.updateTask(taskId, { dependsOn: resolved });
288
+ }
289
+ }
290
+ }
291
+ /** Force a task through the state machine to failed (used by deadlock resolver). */
292
+ async forceFailTask(taskId) {
293
+ const task = await this.ctx.registry.getTask(taskId);
294
+ if (!task || task.status === "done" || task.status === "failed")
295
+ return;
296
+ try {
297
+ if (task.status === "pending")
298
+ await this.ctx.registry.transition(taskId, "assigned");
299
+ if (task.status === "assigned")
300
+ await this.ctx.registry.transition(taskId, "in_progress");
301
+ await this.ctx.registry.transition(taskId, "failed");
302
+ }
303
+ catch { /* transition race — force status */
304
+ await this.ctx.registry.unsafeSetStatus(taskId, "failed", "forceFailTask transition race fallback");
305
+ }
306
+ }
307
+ }
308
+ //# sourceMappingURL=task-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-manager.js","sourceRoot":"","sources":["../src/task-manager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD;;GAEG;AACH,MAAM,OAAO,WAAW;IAGF;IAFZ,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE1C,YAAoB,GAAwB;QAAxB,QAAG,GAAH,GAAG,CAAqB;IAAG,CAAC;IAEhD,KAAK,CAAC,OAAO,CAAC,IAcb;QACC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAExE,8DAA8D;QAC9D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,aAAa,EAAE;YAC7D,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;QACH,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,kCAAkC,UAAU,CAAC,YAAY,IAAI,WAAW,EAAE,CAAC,CAAC;QAC9F,CAAC;QACD,qCAAqC;QACrC,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC;QAEjC,yDAAyD;QACzD,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC5D,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAClC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,CAChF,CAAC;QACF,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CACb,sBAAsB,QAAQ,CAAC,KAAK,yBAAyB,SAAS,CAAC,EAAE,aAAa,SAAS,CAAC,MAAM,KAAK;gBAC3G,gDAAgD,CACjD,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,QAAQ,CAAC,YAAY,IAAI,EAAE,CAAC;QAC5C,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACxE,KAAK,MAAM,CAAC,IAAI,QAAQ;YAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,QAAQ,CAAC,KAAK,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QACzH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC3C,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS;YAC/C,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,EAAE;YACnC,YAAY;YACZ,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB;YAC3C,OAAO,EAAE,EAAE;YACX,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU;YAC/C,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,aAAa,EAAE,QAAQ,CAAC,aAAa;YACrC,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;SAC7C,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAEhD,uDAAuD;QACvD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,EAAE;YACrC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAA2C,CAAC,CAAC,CAAC;QAE5D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,MAAc,EAAE,WAAmB;QAC7D,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,MAAc,EAAE,SAAiB;QAC1D,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,MAAc,EAAE,YAA+B;QAC1E,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC/C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,wCAAwC,IAAI,CAAC,MAAM,SAAS,CAAC,CAAC;QAChF,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC;QAC/D,KAAK,MAAM,CAAC,IAAI,QAAQ;YAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,wBAAwB,MAAM,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5H,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;QACpE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAE,EAAE,CAAC,CAAC;IAC9F,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,MAAc;QAC5B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC7C,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,MAAM,SAAS,CAAC,CAAC;QAC7F,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,MAAc;QAC/B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC7C,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,CAAC,MAAM,SAAS,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;QACnF,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;QAE3G,yEAAyE;QACzE,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,GAAG,EAAE,QAAQ,CAAC;QAC/B,MAAM,QAAQ,GAAG,GAAG,EAAE,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;QAEhD,IAAI,gBAAoC,CAAC;QACzC,IAAI,YAAgC,CAAC;QACrC,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC;gBAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;gBAC5E,IAAI,OAAO,EAAE,CAAC;oBACZ,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;oBAC9D,gBAAgB,GAAG,aAAa,CAAC,OAAO,CAAC;oBACzC,YAAY,GAAG,aAAa,CAAC,YAAY,CAAC;gBAC5C,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAE7B,MAAM,aAAa,GAAkB;YACnC,SAAS,EAAE,IAAI,CAAC,KAAK;YACrB,eAAe,EAAE,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,WAAW;YAC7D,WAAW,EAAE,MAAM,CAAC,MAAM,IAAI,SAAS;YACvC,WAAW,EAAE,MAAM,CAAC,MAAM,IAAI,SAAS;YACvC,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,YAAY,EAAE,QAAQ,EAAE,YAAY;YACpC,WAAW,EAAE,QAAQ,EAAE,WAAW;YAClC,SAAS,EAAE,QAAQ,EAAE,SAAS;YAC9B,YAAY,EAAE,YAAY,IAAI,SAAS;YACvC,gBAAgB;YAChB,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;SAClD,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACvI,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;YAC9C,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YAEvD,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;gBACtB,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE;oBAC3C,MAAM;oBACN,MAAM,EAAE,IAAI;oBACZ,MAAM,EAAE,UAAU,CAAC,MAAM;oBACzB,WAAW,EAAE,UAAU,CAAC,WAAW;oBACnC,OAAO,EAAE,qBAAqB;iBAC/B,CAAC,CAAC;gBACH,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC7B,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;oBACtD,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;oBACvD,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;oBAC1D,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;oBACrD,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBACrD,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,OAAO,GAAG;oBACd,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;oBAC/E,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC;iBAChG,CAAC;gBACF,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE;oBAC3C,MAAM;oBACN,MAAM,EAAE,KAAK;oBACb,MAAM,EAAE,UAAU,CAAC,MAAM;oBACzB,WAAW,EAAE,UAAU,CAAC,WAAW;oBACnC,OAAO,EAAE,yBAAyB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;iBACvD,CAAC,CAAC;gBACH,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;oBAC3B,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,oCAAoC,CAAC,CAAC;gBAClG,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,MAAM,yBAAyB,OAAO,EAAE,EAAE,CAAC,CAAC;QAC1G,CAAC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAc;QAC3B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAC3D,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;YACnD,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;gBACzB,IAAI,CAAC;oBAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;YAChF,CAAC;QACH,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACvD,IAAI,CAAC;gBACH,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;oBAAE,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;gBACtF,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU;oBAAE,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;gBAC1F,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YACvD,CAAC;YAAC,MAAM,CAAC,CAAC,oCAAoC;gBAC5C,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,mCAAmC,CAAC,CAAC;YACjG,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAa;QAC5B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QACpD,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;QACxD,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ;gBAAE,SAAS;YACjE,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC7B,KAAK,EAAE,CAAC;QACV,CAAC;QACD,+EAA+E;QAC/E,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;QACzD,MAAM,OAAO,GAAG,GAAG;YACjB,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC;YAC3C,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC,KAAK,CAAC,CAAC;QACtD,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC3C,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;QAC/E,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAA+B;QAC9C,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACrE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5D,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;gBACnD,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;oBACzB,IAAI,CAAC;wBAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;oBAAC,CAAC;oBAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;gBAChF,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACrD,CAAC;IAED,6DAA6D;IAC7D,KAAK,CAAC,SAAS;QACb,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO;QAE1C,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,IAAI,EAAE,CAAC;YACtC,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;YACxE,KAAK,MAAM,CAAC,IAAI,QAAQ;gBAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,KAAK,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;YAEhH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAC3C,KAAK,EAAE,EAAE,CAAC,KAAK;gBACf,WAAW,EAAE,EAAE,CAAC,WAAW;gBAC3B,QAAQ,EAAE,EAAE,CAAC,QAAQ;gBACrB,SAAS,EAAE,EAAE;gBACb,YAAY;gBACZ,OAAO,EAAE,EAAE;gBACX,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU;gBAC/C,WAAW,EAAE,EAAE,CAAC,WAAW;gBAC3B,WAAW,EAAE,EAAE,CAAC,WAAW;aAC5B,CAAC,CAAC;YAEH,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YAClC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YACjC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,CAAC;QAED,qCAAqC;QACrC,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACvC,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM;gBAAE,SAAS;YACpC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;YACxC,IAAI,CAAC,MAAM;gBAAE,SAAS;YACtB,MAAM,QAAQ,GAAG,EAAE,CAAC,SAAS;iBAC1B,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;iBAC/B,MAAM,CAAC,CAAC,EAAE,EAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACtC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;IACH,CAAC;IAED,oFAAoF;IACpF,KAAK,CAAC,aAAa,CAAC,MAAc;QAChC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ;YAAE,OAAO;QACxE,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;gBAAE,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YACtF,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU;gBAAE,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;YAC1F,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC,CAAC,oCAAoC;YAC5C,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,wCAAwC,CAAC,CAAC;QACtG,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,33 @@
1
+ import type { Task, TaskStatus, PolpoState, Mission } from "./types.js";
2
+ /**
3
+ * Abstract interface for task persistence.
4
+ * Implementations can be JSON file, SQLite, PostgreSQL, or in-memory (for tests).
5
+ *
6
+ * All methods return Promise to support async backends (PostgreSQL, cloud DBs).
7
+ * Synchronous implementations (SQLite, file) can simply use `async` keyword.
8
+ */
9
+ export interface TaskStore {
10
+ getState(): Promise<PolpoState>;
11
+ setState(partial: Partial<PolpoState>): Promise<void>;
12
+ addTask(task: Omit<Task, "id" | "status" | "retries" | "createdAt" | "updatedAt"> & {
13
+ status?: TaskStatus;
14
+ }): Promise<Task>;
15
+ getTask(taskId: string): Promise<Task | undefined>;
16
+ getAllTasks(): Promise<Task[]>;
17
+ updateTask(taskId: string, updates: Partial<Omit<Task, "id" | "status">>): Promise<Task>;
18
+ removeTask(taskId: string): Promise<boolean>;
19
+ removeTasks(filter: (task: Task) => boolean): Promise<number>;
20
+ transition(taskId: string, newStatus: TaskStatus): Promise<Task>;
21
+ /** Bypass state machine — sets status directly with mandatory reason logging.
22
+ * Use ONLY for recovery, race-condition fallbacks, and fix/Q&A re-runs. */
23
+ unsafeSetStatus(taskId: string, newStatus: TaskStatus, reason: string): Promise<Task>;
24
+ close?(): Promise<void> | void;
25
+ saveMission?(mission: Omit<Mission, "id" | "createdAt" | "updatedAt">): Promise<Mission>;
26
+ getMission?(missionId: string): Promise<Mission | undefined>;
27
+ getMissionByName?(name: string): Promise<Mission | undefined>;
28
+ getAllMissions?(): Promise<Mission[]>;
29
+ updateMission?(missionId: string, updates: Partial<Omit<Mission, "id">>): Promise<Mission>;
30
+ deleteMission?(missionId: string): Promise<boolean>;
31
+ nextMissionName?(): Promise<string>;
32
+ }
33
+ //# sourceMappingURL=task-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-store.d.ts","sourceRoot":"","sources":["../src/task-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAExE;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IAExB,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAGtD,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,CAAC,GAAG;QAAE,MAAM,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5H,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC;IACnD,WAAW,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/B,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzF,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,WAAW,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAG9D,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE;gFAC4E;IAC5E,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAGtF,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAG/B,WAAW,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzF,UAAU,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IAC7D,gBAAgB,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IAC9D,cAAc,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACtC,aAAa,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3F,aAAa,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD,eAAe,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CACrC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=task-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-store.js","sourceRoot":"","sources":["../src/task-store.ts"],"names":[],"mappings":""}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * TaskWatcherManager — event-driven task watchers.
3
+ *
4
+ * Watchers listen for task:transition events and fire a configured action
5
+ * when a target task reaches a specific status. Each watcher fires at most once.
6
+ *
7
+ * This is the mechanism for "when task X finishes, do Y" without polling.
8
+ */
9
+ import type { EventBus } from "./event-bus.js";
10
+ import type { TaskWatcher, TaskStatus, NotificationAction } from "./types.js";
11
+ export declare class TaskWatcherManager {
12
+ private emitter;
13
+ private watchers;
14
+ private listener?;
15
+ private actionExecutor?;
16
+ constructor(emitter: EventBus);
17
+ /** Set the action executor callback — injected by the orchestrator. */
18
+ setActionExecutor(executor: (action: NotificationAction) => Promise<string>): void;
19
+ /** Start listening for task:transition events. */
20
+ start(): void;
21
+ /** Create a new task watcher. */
22
+ create(opts: {
23
+ taskId: string;
24
+ targetStatus: TaskStatus;
25
+ action: NotificationAction;
26
+ }): TaskWatcher;
27
+ /** Remove a watcher by ID. */
28
+ remove(watcherId: string): boolean;
29
+ /** Get a watcher by ID. */
30
+ get(watcherId: string): TaskWatcher | undefined;
31
+ /** List all watchers. */
32
+ getAll(): TaskWatcher[];
33
+ /** List active (unfired) watchers. */
34
+ getActive(): TaskWatcher[];
35
+ /** Cleanup: remove all watchers and stop listening. */
36
+ dispose(): void;
37
+ }
38
+ //# sourceMappingURL=task-watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-watcher.d.ts","sourceRoot":"","sources":["../src/task-watcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE9E,qBAAa,kBAAkB;IAKjB,OAAO,CAAC,OAAO;IAJ3B,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,QAAQ,CAAC,CAAwD;IACzE,OAAO,CAAC,cAAc,CAAC,CAAkD;gBAErD,OAAO,EAAE,QAAQ;IAErC,uEAAuE;IACvE,iBAAiB,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI;IAIlF,kDAAkD;IAClD,KAAK,IAAI,IAAI;IAmCb,iCAAiC;IACjC,MAAM,CAAC,IAAI,EAAE;QACX,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,UAAU,CAAC;QACzB,MAAM,EAAE,kBAAkB,CAAC;KAC5B,GAAG,WAAW;IAqBf,8BAA8B;IAC9B,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAQlC,2BAA2B;IAC3B,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAI/C,yBAAyB;IACzB,MAAM,IAAI,WAAW,EAAE;IAIvB,sCAAsC;IACtC,SAAS,IAAI,WAAW,EAAE;IAI1B,uDAAuD;IACvD,OAAO,IAAI,IAAI;CAOhB"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * TaskWatcherManager — event-driven task watchers.
3
+ *
4
+ * Watchers listen for task:transition events and fire a configured action
5
+ * when a target task reaches a specific status. Each watcher fires at most once.
6
+ *
7
+ * This is the mechanism for "when task X finishes, do Y" without polling.
8
+ */
9
+ import { nanoid } from "nanoid";
10
+ export class TaskWatcherManager {
11
+ emitter;
12
+ watchers = new Map();
13
+ listener;
14
+ actionExecutor;
15
+ constructor(emitter) {
16
+ this.emitter = emitter;
17
+ }
18
+ /** Set the action executor callback — injected by the orchestrator. */
19
+ setActionExecutor(executor) {
20
+ this.actionExecutor = executor;
21
+ }
22
+ /** Start listening for task:transition events. */
23
+ start() {
24
+ if (this.listener)
25
+ return; // already started
26
+ this.listener = (payload) => {
27
+ for (const [id, watcher] of this.watchers) {
28
+ if (watcher.fired)
29
+ continue;
30
+ if (watcher.taskId !== payload.taskId)
31
+ continue;
32
+ if (watcher.targetStatus !== payload.to)
33
+ continue;
34
+ // Match! Fire the watcher
35
+ watcher.fired = true;
36
+ watcher.firedAt = new Date().toISOString();
37
+ this.emitter.emit("watcher:fired", {
38
+ watcherId: id,
39
+ taskId: watcher.taskId,
40
+ targetStatus: watcher.targetStatus,
41
+ actionType: watcher.action.type,
42
+ });
43
+ if (this.actionExecutor) {
44
+ this.actionExecutor(watcher.action).catch((err) => {
45
+ const msg = err instanceof Error ? err.message : String(err);
46
+ this.emitter.emit("log", {
47
+ level: "error",
48
+ message: `[watcher] Action failed for watcher ${id}: ${msg}`,
49
+ });
50
+ });
51
+ }
52
+ }
53
+ };
54
+ this.emitter.on("task:transition", this.listener);
55
+ }
56
+ /** Create a new task watcher. */
57
+ create(opts) {
58
+ const watcher = {
59
+ id: `watch-${nanoid(10)}`,
60
+ taskId: opts.taskId,
61
+ targetStatus: opts.targetStatus,
62
+ action: opts.action,
63
+ fired: false,
64
+ createdAt: new Date().toISOString(),
65
+ };
66
+ this.watchers.set(watcher.id, watcher);
67
+ this.emitter.emit("watcher:created", {
68
+ watcherId: watcher.id,
69
+ taskId: watcher.taskId,
70
+ targetStatus: watcher.targetStatus,
71
+ });
72
+ return watcher;
73
+ }
74
+ /** Remove a watcher by ID. */
75
+ remove(watcherId) {
76
+ const deleted = this.watchers.delete(watcherId);
77
+ if (deleted) {
78
+ this.emitter.emit("watcher:removed", { watcherId });
79
+ }
80
+ return deleted;
81
+ }
82
+ /** Get a watcher by ID. */
83
+ get(watcherId) {
84
+ return this.watchers.get(watcherId);
85
+ }
86
+ /** List all watchers. */
87
+ getAll() {
88
+ return [...this.watchers.values()];
89
+ }
90
+ /** List active (unfired) watchers. */
91
+ getActive() {
92
+ return [...this.watchers.values()].filter(w => !w.fired);
93
+ }
94
+ /** Cleanup: remove all watchers and stop listening. */
95
+ dispose() {
96
+ if (this.listener) {
97
+ this.emitter.off("task:transition", this.listener);
98
+ this.listener = undefined;
99
+ }
100
+ this.watchers.clear();
101
+ }
102
+ }
103
+ //# sourceMappingURL=task-watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-watcher.js","sourceRoot":"","sources":["../src/task-watcher.ts"],"names":[],"mappings":"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"}