@dexto/orchestration 1.5.8

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 (50) hide show
  1. package/LICENSE +44 -0
  2. package/dist/agent-controller.cjs +265 -0
  3. package/dist/agent-controller.d.cts +116 -0
  4. package/dist/agent-controller.d.ts +116 -0
  5. package/dist/agent-controller.js +241 -0
  6. package/dist/condition-engine.cjs +276 -0
  7. package/dist/condition-engine.d.cts +87 -0
  8. package/dist/condition-engine.d.ts +87 -0
  9. package/dist/condition-engine.js +252 -0
  10. package/dist/index.cjs +57 -0
  11. package/dist/index.d.cts +11 -0
  12. package/dist/index.d.ts +11 -0
  13. package/dist/index.js +32 -0
  14. package/dist/signal-bus.cjs +186 -0
  15. package/dist/signal-bus.d.cts +78 -0
  16. package/dist/signal-bus.d.ts +78 -0
  17. package/dist/signal-bus.js +162 -0
  18. package/dist/task-registry.cjs +345 -0
  19. package/dist/task-registry.d.cts +124 -0
  20. package/dist/task-registry.d.ts +124 -0
  21. package/dist/task-registry.js +321 -0
  22. package/dist/tools/check-task.cjs +65 -0
  23. package/dist/tools/check-task.d.cts +56 -0
  24. package/dist/tools/check-task.d.ts +56 -0
  25. package/dist/tools/check-task.js +40 -0
  26. package/dist/tools/index.cjs +51 -0
  27. package/dist/tools/index.d.cts +10 -0
  28. package/dist/tools/index.d.ts +10 -0
  29. package/dist/tools/index.js +19 -0
  30. package/dist/tools/list-tasks.cjs +80 -0
  31. package/dist/tools/list-tasks.d.cts +64 -0
  32. package/dist/tools/list-tasks.d.ts +64 -0
  33. package/dist/tools/list-tasks.js +55 -0
  34. package/dist/tools/start-task.cjs +149 -0
  35. package/dist/tools/start-task.d.cts +102 -0
  36. package/dist/tools/start-task.d.ts +102 -0
  37. package/dist/tools/start-task.js +123 -0
  38. package/dist/tools/types.cjs +16 -0
  39. package/dist/tools/types.d.cts +30 -0
  40. package/dist/tools/types.d.ts +30 -0
  41. package/dist/tools/types.js +0 -0
  42. package/dist/tools/wait-for.cjs +116 -0
  43. package/dist/tools/wait-for.d.cts +74 -0
  44. package/dist/tools/wait-for.d.ts +74 -0
  45. package/dist/tools/wait-for.js +91 -0
  46. package/dist/types.cjs +16 -0
  47. package/dist/types.d.cts +165 -0
  48. package/dist/types.d.ts +165 -0
  49. package/dist/types.js +0 -0
  50. package/package.json +38 -0
@@ -0,0 +1,78 @@
1
+ import { Signal, SignalType } from './types.js';
2
+
3
+ /**
4
+ * SignalBus
5
+ *
6
+ * Event emitter for routing orchestration signals.
7
+ * Supports typed subscriptions and promise-based waiting.
8
+ */
9
+
10
+ /**
11
+ * Handler function for signal subscriptions
12
+ */
13
+ type SignalHandler<T extends Signal = Signal> = (signal: T) => void;
14
+ /**
15
+ * Predicate function for filtering signals
16
+ */
17
+ type SignalPredicate = (signal: Signal) => boolean;
18
+ /**
19
+ * SignalBus - Routes signals between orchestration components
20
+ */
21
+ declare class SignalBus {
22
+ private emitter;
23
+ constructor();
24
+ /**
25
+ * Emit a signal to all subscribers
26
+ */
27
+ emit(signal: Signal): void;
28
+ /**
29
+ * Subscribe to signals of a specific type
30
+ * @returns Unsubscribe function
31
+ */
32
+ on<T extends SignalType>(type: T, handler: SignalHandler<Extract<Signal, {
33
+ type: T;
34
+ }>>): () => void;
35
+ /**
36
+ * Subscribe to all signals
37
+ * @returns Unsubscribe function
38
+ */
39
+ onAny(handler: SignalHandler): () => void;
40
+ /**
41
+ * Subscribe to a signal type once
42
+ */
43
+ once<T extends SignalType>(type: T, handler: SignalHandler<Extract<Signal, {
44
+ type: T;
45
+ }>>): void;
46
+ /**
47
+ * Remove a specific handler
48
+ */
49
+ off<T extends SignalType>(type: T, handler: SignalHandler<Extract<Signal, {
50
+ type: T;
51
+ }>>): void;
52
+ /**
53
+ * Wait for a signal matching the predicate
54
+ * @param predicate Function to test signals
55
+ * @param timeout Optional timeout in milliseconds
56
+ * @returns Promise that resolves with the matching signal
57
+ */
58
+ waitFor(predicate: SignalPredicate, timeout?: number): Promise<Signal>;
59
+ /**
60
+ * Wait for a signal for a specific task
61
+ */
62
+ waitForTask(taskId: string, timeout?: number): Promise<Signal>;
63
+ /**
64
+ * Wait for any of multiple tasks to complete
65
+ */
66
+ waitForAnyTask(taskIds: string[], timeout?: number): Promise<Signal>;
67
+ /**
68
+ * Wait for all tasks to complete
69
+ * @returns Promise that resolves with all signals
70
+ */
71
+ waitForAllTasks(taskIds: string[], timeout?: number, resolveInitial?: (taskId: string) => Signal | undefined): Promise<Signal[]>;
72
+ /**
73
+ * Remove all listeners
74
+ */
75
+ clear(): void;
76
+ }
77
+
78
+ export { SignalBus, type SignalHandler, type SignalPredicate };
@@ -0,0 +1,162 @@
1
+ import { EventEmitter } from "events";
2
+ class SignalBus {
3
+ emitter = new EventEmitter();
4
+ constructor() {
5
+ this.emitter.setMaxListeners(100);
6
+ }
7
+ /**
8
+ * Emit a signal to all subscribers
9
+ */
10
+ emit(signal) {
11
+ this.emitter.emit(signal.type, signal);
12
+ this.emitter.emit("*", signal);
13
+ }
14
+ /**
15
+ * Subscribe to signals of a specific type
16
+ * @returns Unsubscribe function
17
+ */
18
+ on(type, handler) {
19
+ this.emitter.on(type, handler);
20
+ return () => this.emitter.off(type, handler);
21
+ }
22
+ /**
23
+ * Subscribe to all signals
24
+ * @returns Unsubscribe function
25
+ */
26
+ onAny(handler) {
27
+ this.emitter.on("*", handler);
28
+ return () => this.emitter.off("*", handler);
29
+ }
30
+ /**
31
+ * Subscribe to a signal type once
32
+ */
33
+ once(type, handler) {
34
+ this.emitter.once(type, handler);
35
+ }
36
+ /**
37
+ * Remove a specific handler
38
+ */
39
+ off(type, handler) {
40
+ this.emitter.off(type, handler);
41
+ }
42
+ /**
43
+ * Wait for a signal matching the predicate
44
+ * @param predicate Function to test signals
45
+ * @param timeout Optional timeout in milliseconds
46
+ * @returns Promise that resolves with the matching signal
47
+ */
48
+ waitFor(predicate, timeout) {
49
+ return new Promise((resolve, reject) => {
50
+ let timeoutId;
51
+ let unsubscribe;
52
+ const cleanup = () => {
53
+ if (timeoutId) {
54
+ clearTimeout(timeoutId);
55
+ }
56
+ if (unsubscribe) {
57
+ unsubscribe();
58
+ }
59
+ };
60
+ const handler = (signal) => {
61
+ if (predicate(signal)) {
62
+ cleanup();
63
+ resolve(signal);
64
+ }
65
+ };
66
+ unsubscribe = this.onAny(handler);
67
+ if (timeout !== void 0 && timeout > 0) {
68
+ timeoutId = setTimeout(() => {
69
+ cleanup();
70
+ reject(new Error(`Signal wait timed out after ${timeout}ms`));
71
+ }, timeout);
72
+ }
73
+ });
74
+ }
75
+ /**
76
+ * Wait for a signal for a specific task
77
+ */
78
+ waitForTask(taskId, timeout) {
79
+ return this.waitFor(
80
+ (signal) => (signal.type === "task:completed" || signal.type === "task:failed" || signal.type === "task:cancelled") && signal.taskId === taskId,
81
+ timeout
82
+ );
83
+ }
84
+ /**
85
+ * Wait for any of multiple tasks to complete
86
+ */
87
+ waitForAnyTask(taskIds, timeout) {
88
+ if (taskIds.length === 0) {
89
+ return Promise.reject(new Error("taskIds must not be empty"));
90
+ }
91
+ const taskIdSet = new Set(taskIds);
92
+ return this.waitFor(
93
+ (signal) => (signal.type === "task:completed" || signal.type === "task:failed" || signal.type === "task:cancelled") && taskIdSet.has(signal.taskId),
94
+ timeout
95
+ );
96
+ }
97
+ /**
98
+ * Wait for all tasks to complete
99
+ * @returns Promise that resolves with all signals
100
+ */
101
+ async waitForAllTasks(taskIds, timeout, resolveInitial) {
102
+ if (taskIds.length === 0) {
103
+ return [];
104
+ }
105
+ const remaining = new Set(taskIds);
106
+ const signals = [];
107
+ if (resolveInitial) {
108
+ for (const taskId of taskIds) {
109
+ const signal = resolveInitial(taskId);
110
+ if (signal) {
111
+ remaining.delete(taskId);
112
+ signals.push(signal);
113
+ }
114
+ }
115
+ }
116
+ if (remaining.size === 0) {
117
+ return signals;
118
+ }
119
+ return new Promise((resolve, reject) => {
120
+ let timeoutId;
121
+ let unsubscribe;
122
+ const cleanup = () => {
123
+ if (timeoutId) {
124
+ clearTimeout(timeoutId);
125
+ }
126
+ if (unsubscribe) {
127
+ unsubscribe();
128
+ }
129
+ };
130
+ const handler = (signal) => {
131
+ if ((signal.type === "task:completed" || signal.type === "task:failed" || signal.type === "task:cancelled") && remaining.has(signal.taskId)) {
132
+ remaining.delete(signal.taskId);
133
+ signals.push(signal);
134
+ if (remaining.size === 0) {
135
+ cleanup();
136
+ resolve(signals);
137
+ }
138
+ }
139
+ };
140
+ unsubscribe = this.onAny(handler);
141
+ if (timeout !== void 0 && timeout > 0) {
142
+ timeoutId = setTimeout(() => {
143
+ cleanup();
144
+ reject(
145
+ new Error(
146
+ `Waiting for all tasks timed out after ${timeout}ms. Remaining tasks: ${Array.from(remaining).join(", ")}`
147
+ )
148
+ );
149
+ }, timeout);
150
+ }
151
+ });
152
+ }
153
+ /**
154
+ * Remove all listeners
155
+ */
156
+ clear() {
157
+ this.emitter.removeAllListeners();
158
+ }
159
+ }
160
+ export {
161
+ SignalBus
162
+ };
@@ -0,0 +1,345 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var task_registry_exports = {};
20
+ __export(task_registry_exports, {
21
+ TaskRegistry: () => TaskRegistry
22
+ });
23
+ module.exports = __toCommonJS(task_registry_exports);
24
+ class TaskRegistry {
25
+ tasks = /* @__PURE__ */ new Map();
26
+ signalBus;
27
+ config;
28
+ constructor(signalBus, config = {}) {
29
+ this.signalBus = signalBus;
30
+ this.config = {
31
+ maxTasks: config.maxTasks ?? 20,
32
+ resultTTL: config.resultTTL ?? 5 * 60 * 1e3
33
+ // 5 minutes
34
+ };
35
+ }
36
+ /**
37
+ * Generate a unique task ID
38
+ */
39
+ generateTaskId() {
40
+ return `task-${Math.random().toString(36).slice(2, 10)}`;
41
+ }
42
+ /**
43
+ * Get description from task for display
44
+ */
45
+ getTaskDescription(task) {
46
+ switch (task.type) {
47
+ case "agent":
48
+ return task.taskDescription;
49
+ case "process":
50
+ return task.command;
51
+ case "generic":
52
+ return task.description;
53
+ }
54
+ }
55
+ /**
56
+ * Register a new task and start tracking it
57
+ * @param task Task to register (must include promise)
58
+ * @param options Registration options
59
+ * @returns Task ID
60
+ */
61
+ register(task, options = {}) {
62
+ const runningCount = this.getRunningCount();
63
+ if (runningCount >= this.config.maxTasks) {
64
+ throw new Error(
65
+ `Maximum concurrent tasks (${this.config.maxTasks}) exceeded. ${runningCount} tasks currently running.`
66
+ );
67
+ }
68
+ const entry = {
69
+ task,
70
+ status: "running",
71
+ startedAt: /* @__PURE__ */ new Date(),
72
+ timeoutHandle: void 0,
73
+ ...options.notify !== void 0 && { notify: options.notify }
74
+ };
75
+ this.tasks.set(task.taskId, entry);
76
+ task.promise.then((result) => {
77
+ this.onTaskComplete(task.taskId, result);
78
+ }).catch((error) => {
79
+ const errorMessage = error instanceof Error ? error.message : String(error);
80
+ this.onTaskFailed(task.taskId, errorMessage);
81
+ });
82
+ if (options.timeout !== void 0 && options.timeout > 0) {
83
+ const timeoutHandle = setTimeout(() => {
84
+ const currentEntry = this.tasks.get(task.taskId);
85
+ if (currentEntry && currentEntry.status === "running") {
86
+ this.onTaskFailed(task.taskId, `Task timed out after ${options.timeout}ms`);
87
+ }
88
+ }, options.timeout);
89
+ entry.timeoutHandle = timeoutHandle;
90
+ }
91
+ return task.taskId;
92
+ }
93
+ /**
94
+ * Create and register an agent task
95
+ *
96
+ * Note: Uses agentId as the taskId so the caller can use the same ID
97
+ * for wait_for/check_task operations.
98
+ */
99
+ registerAgentTask(agentId, taskDescription, promise, options = {}) {
100
+ const taskId = agentId;
101
+ if (this.tasks.has(taskId)) {
102
+ throw new Error(`Task '${taskId}' already exists`);
103
+ }
104
+ const task = {
105
+ type: "agent",
106
+ taskId,
107
+ agentId,
108
+ taskDescription,
109
+ promise
110
+ };
111
+ return this.register(task, options);
112
+ }
113
+ /**
114
+ * Create and register a process task
115
+ */
116
+ registerProcessTask(processId, command, promise, options = {}) {
117
+ const taskId = this.generateTaskId();
118
+ const task = {
119
+ type: "process",
120
+ taskId,
121
+ processId,
122
+ command,
123
+ promise
124
+ };
125
+ return this.register(task, options);
126
+ }
127
+ /**
128
+ * Create and register a generic task
129
+ */
130
+ registerGenericTask(description, promise, options = {}) {
131
+ const taskId = this.generateTaskId();
132
+ const task = {
133
+ type: "generic",
134
+ taskId,
135
+ description,
136
+ promise
137
+ };
138
+ return this.register(task, options);
139
+ }
140
+ /**
141
+ * Called when a task completes successfully
142
+ */
143
+ onTaskComplete(taskId, result) {
144
+ const entry = this.tasks.get(taskId);
145
+ if (!entry || entry.status !== "running") {
146
+ return;
147
+ }
148
+ if (entry.timeoutHandle) {
149
+ clearTimeout(entry.timeoutHandle);
150
+ entry.timeoutHandle = void 0;
151
+ }
152
+ entry.status = "completed";
153
+ entry.completedAt = /* @__PURE__ */ new Date();
154
+ entry.result = result;
155
+ this.signalBus.emit({
156
+ type: "task:completed",
157
+ taskId,
158
+ result
159
+ });
160
+ }
161
+ /**
162
+ * Called when a task fails
163
+ */
164
+ onTaskFailed(taskId, error) {
165
+ const entry = this.tasks.get(taskId);
166
+ if (!entry || entry.status !== "running") {
167
+ return;
168
+ }
169
+ if (entry.timeoutHandle) {
170
+ clearTimeout(entry.timeoutHandle);
171
+ entry.timeoutHandle = void 0;
172
+ }
173
+ entry.status = "failed";
174
+ entry.completedAt = /* @__PURE__ */ new Date();
175
+ entry.error = error;
176
+ this.signalBus.emit({
177
+ type: "task:failed",
178
+ taskId,
179
+ error
180
+ });
181
+ }
182
+ /**
183
+ * Cancel a running task
184
+ */
185
+ cancel(taskId) {
186
+ const entry = this.tasks.get(taskId);
187
+ if (!entry) {
188
+ throw new Error(`Task '${taskId}' not found`);
189
+ }
190
+ if (entry.status !== "running") {
191
+ return;
192
+ }
193
+ if (entry.timeoutHandle) {
194
+ clearTimeout(entry.timeoutHandle);
195
+ entry.timeoutHandle = void 0;
196
+ }
197
+ entry.status = "cancelled";
198
+ entry.completedAt = /* @__PURE__ */ new Date();
199
+ entry.error = entry.error ?? "Cancelled";
200
+ this.signalBus.emit({
201
+ type: "task:cancelled",
202
+ taskId
203
+ });
204
+ }
205
+ /**
206
+ * Get task entry by ID
207
+ */
208
+ get(taskId) {
209
+ return this.tasks.get(taskId);
210
+ }
211
+ /**
212
+ * Get task status
213
+ */
214
+ getStatus(taskId) {
215
+ return this.tasks.get(taskId)?.status;
216
+ }
217
+ /**
218
+ * Get task result (if completed)
219
+ */
220
+ getResult(taskId) {
221
+ const entry = this.tasks.get(taskId);
222
+ if (!entry) {
223
+ return void 0;
224
+ }
225
+ return {
226
+ status: entry.status,
227
+ ...entry.result !== void 0 && { result: entry.result },
228
+ ...entry.error !== void 0 && { error: entry.error }
229
+ };
230
+ }
231
+ /**
232
+ * Get task info (safe for serialization - no promise)
233
+ */
234
+ getInfo(taskId) {
235
+ const entry = this.tasks.get(taskId);
236
+ if (!entry) {
237
+ return void 0;
238
+ }
239
+ const duration = entry.completedAt ? entry.completedAt.getTime() - entry.startedAt.getTime() : void 0;
240
+ return {
241
+ taskId: entry.task.taskId,
242
+ type: entry.task.type,
243
+ status: entry.status,
244
+ startedAt: entry.startedAt,
245
+ description: this.getTaskDescription(entry.task),
246
+ ...entry.completedAt !== void 0 && { completedAt: entry.completedAt },
247
+ ...duration !== void 0 && { duration },
248
+ ...entry.result !== void 0 && { result: entry.result },
249
+ ...entry.error !== void 0 && { error: entry.error },
250
+ ...entry.status === "cancelled" && entry.error !== void 0 && {
251
+ cancelReason: entry.error
252
+ }
253
+ };
254
+ }
255
+ /**
256
+ * List tasks matching filter
257
+ */
258
+ list(filter) {
259
+ const results = [];
260
+ for (const entry of this.tasks.values()) {
261
+ if (filter?.status) {
262
+ const statuses = Array.isArray(filter.status) ? filter.status : [filter.status];
263
+ if (!statuses.includes(entry.status)) {
264
+ continue;
265
+ }
266
+ }
267
+ if (filter?.type && entry.task.type !== filter.type) {
268
+ continue;
269
+ }
270
+ const info = this.getInfo(entry.task.taskId);
271
+ if (info) {
272
+ results.push(info);
273
+ }
274
+ }
275
+ return results.sort((a, b) => b.startedAt.getTime() - a.startedAt.getTime());
276
+ }
277
+ /**
278
+ * Get count of running tasks
279
+ */
280
+ getRunningCount() {
281
+ let count = 0;
282
+ for (const entry of this.tasks.values()) {
283
+ if (entry.status === "running") {
284
+ count++;
285
+ }
286
+ }
287
+ return count;
288
+ }
289
+ /**
290
+ * Get tasks that completed with notify=true and haven't been acknowledged
291
+ */
292
+ getNotifyPending() {
293
+ return this.list({ status: ["completed", "failed"] }).filter((info) => {
294
+ const entry = this.tasks.get(info.taskId);
295
+ return entry?.notify === true;
296
+ });
297
+ }
298
+ /**
299
+ * Mark notify tasks as acknowledged (clear notify flag)
300
+ */
301
+ acknowledgeNotify(taskIds) {
302
+ for (const taskId of taskIds) {
303
+ const entry = this.tasks.get(taskId);
304
+ if (entry) {
305
+ entry.notify = false;
306
+ }
307
+ }
308
+ }
309
+ /**
310
+ * Clean up old completed tasks
311
+ */
312
+ cleanup(olderThan) {
313
+ const cutoff = olderThan ?? new Date(Date.now() - this.config.resultTTL);
314
+ let cleaned = 0;
315
+ for (const [taskId, entry] of this.tasks.entries()) {
316
+ if (entry.status !== "running" && entry.completedAt && entry.completedAt < cutoff) {
317
+ this.tasks.delete(taskId);
318
+ cleaned++;
319
+ }
320
+ }
321
+ return cleaned;
322
+ }
323
+ /**
324
+ * Clear all tasks
325
+ */
326
+ clear() {
327
+ this.tasks.clear();
328
+ }
329
+ /**
330
+ * Check if a task exists
331
+ */
332
+ has(taskId) {
333
+ return this.tasks.has(taskId);
334
+ }
335
+ /**
336
+ * Get total task count
337
+ */
338
+ get size() {
339
+ return this.tasks.size;
340
+ }
341
+ }
342
+ // Annotate the CommonJS export names for ESM import in node:
343
+ 0 && (module.exports = {
344
+ TaskRegistry
345
+ });
@@ -0,0 +1,124 @@
1
+ import { Task, RegisterTaskOptions, TaskEntry, TaskStatus, TaskInfo, TaskFilter } from './types.cjs';
2
+ import { SignalBus } from './signal-bus.cjs';
3
+
4
+ /**
5
+ * TaskRegistry
6
+ *
7
+ * Tracks all background tasks and their results.
8
+ * Emits signals on task completion for the ConditionEngine.
9
+ */
10
+
11
+ /**
12
+ * Configuration for TaskRegistry
13
+ */
14
+ interface TaskRegistryConfig {
15
+ /** Maximum number of concurrent tasks (default: 20) */
16
+ maxTasks?: number;
17
+ /** TTL for completed task results in ms (default: 5 minutes) */
18
+ resultTTL?: number;
19
+ }
20
+ /**
21
+ * TaskRegistry - Manages background task lifecycle
22
+ */
23
+ declare class TaskRegistry {
24
+ private tasks;
25
+ private signalBus;
26
+ private config;
27
+ constructor(signalBus: SignalBus, config?: TaskRegistryConfig);
28
+ /**
29
+ * Generate a unique task ID
30
+ */
31
+ private generateTaskId;
32
+ /**
33
+ * Get description from task for display
34
+ */
35
+ private getTaskDescription;
36
+ /**
37
+ * Register a new task and start tracking it
38
+ * @param task Task to register (must include promise)
39
+ * @param options Registration options
40
+ * @returns Task ID
41
+ */
42
+ register(task: Task, options?: RegisterTaskOptions): string;
43
+ /**
44
+ * Create and register an agent task
45
+ *
46
+ * Note: Uses agentId as the taskId so the caller can use the same ID
47
+ * for wait_for/check_task operations.
48
+ */
49
+ registerAgentTask(agentId: string, taskDescription: string, promise: Promise<unknown>, options?: RegisterTaskOptions): string;
50
+ /**
51
+ * Create and register a process task
52
+ */
53
+ registerProcessTask(processId: string, command: string, promise: Promise<unknown>, options?: RegisterTaskOptions): string;
54
+ /**
55
+ * Create and register a generic task
56
+ */
57
+ registerGenericTask(description: string, promise: Promise<unknown>, options?: RegisterTaskOptions): string;
58
+ /**
59
+ * Called when a task completes successfully
60
+ */
61
+ private onTaskComplete;
62
+ /**
63
+ * Called when a task fails
64
+ */
65
+ private onTaskFailed;
66
+ /**
67
+ * Cancel a running task
68
+ */
69
+ cancel(taskId: string): void;
70
+ /**
71
+ * Get task entry by ID
72
+ */
73
+ get(taskId: string): TaskEntry | undefined;
74
+ /**
75
+ * Get task status
76
+ */
77
+ getStatus(taskId: string): TaskStatus | undefined;
78
+ /**
79
+ * Get task result (if completed)
80
+ */
81
+ getResult(taskId: string): {
82
+ status: TaskStatus;
83
+ result?: unknown;
84
+ error?: string;
85
+ } | undefined;
86
+ /**
87
+ * Get task info (safe for serialization - no promise)
88
+ */
89
+ getInfo(taskId: string): TaskInfo | undefined;
90
+ /**
91
+ * List tasks matching filter
92
+ */
93
+ list(filter?: TaskFilter): TaskInfo[];
94
+ /**
95
+ * Get count of running tasks
96
+ */
97
+ getRunningCount(): number;
98
+ /**
99
+ * Get tasks that completed with notify=true and haven't been acknowledged
100
+ */
101
+ getNotifyPending(): TaskInfo[];
102
+ /**
103
+ * Mark notify tasks as acknowledged (clear notify flag)
104
+ */
105
+ acknowledgeNotify(taskIds: string[]): void;
106
+ /**
107
+ * Clean up old completed tasks
108
+ */
109
+ cleanup(olderThan?: Date): number;
110
+ /**
111
+ * Clear all tasks
112
+ */
113
+ clear(): void;
114
+ /**
115
+ * Check if a task exists
116
+ */
117
+ has(taskId: string): boolean;
118
+ /**
119
+ * Get total task count
120
+ */
121
+ get size(): number;
122
+ }
123
+
124
+ export { TaskRegistry, type TaskRegistryConfig };