@kb-labs/workflow-engine 1.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.
- package/README.md +408 -0
- package/dist/index.d.ts +1057 -0
- package/dist/index.js +3077 -0
- package/dist/index.js.map +1 -0
- package/package.json +67 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1057 @@
|
|
|
1
|
+
import { WorkflowSpec, WorkflowRun, JobRun, StepRun, RunTrigger, IdempotencyKey, ConcurrencyGroup, RetryPolicy, ArtifactMergeConfig } from '@kb-labs/workflow-contracts';
|
|
2
|
+
import { ILogger, ICache, IEventBus, IAnalytics, Unsubscribe, ICronManager, IJobScheduler, JobDefinition, JobHandle, CronExpression, JobFilter } from '@kb-labs/core-platform';
|
|
3
|
+
import { JobPriority, WorkflowEventName } from '@kb-labs/workflow-constants';
|
|
4
|
+
import { ArtifactClient } from '@kb-labs/workflow-artifacts';
|
|
5
|
+
import { IEntityRegistry } from '@kb-labs/core-registry';
|
|
6
|
+
import { PlatformServices, JobHandlerDecl, PluginContextDescriptor } from '@kb-labs/plugin-contracts';
|
|
7
|
+
import { IExecutionBackend } from '@kb-labs/core-contracts';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated Use ILogger from @kb-labs/core-platform instead.
|
|
11
|
+
* This type alias is kept for backward compatibility.
|
|
12
|
+
*/
|
|
13
|
+
type EngineLogger = ILogger;
|
|
14
|
+
interface WorkflowLoaderResult {
|
|
15
|
+
spec: WorkflowSpec;
|
|
16
|
+
source: string;
|
|
17
|
+
}
|
|
18
|
+
interface RunContext {
|
|
19
|
+
run: WorkflowRun;
|
|
20
|
+
jobs: JobRun[];
|
|
21
|
+
steps: StepRun[];
|
|
22
|
+
}
|
|
23
|
+
interface CreateRunInput {
|
|
24
|
+
spec: WorkflowSpec;
|
|
25
|
+
trigger: RunTrigger;
|
|
26
|
+
idempotencyKey?: IdempotencyKey;
|
|
27
|
+
concurrencyGroup?: ConcurrencyGroup;
|
|
28
|
+
metadata?: Record<string, unknown>;
|
|
29
|
+
env?: Record<string, string>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface WorkflowLoaderOptions {
|
|
33
|
+
cwd?: string;
|
|
34
|
+
}
|
|
35
|
+
declare class WorkflowLoader {
|
|
36
|
+
private readonly logger;
|
|
37
|
+
constructor(logger: EngineLogger);
|
|
38
|
+
fromFile(filePath: string, options?: WorkflowLoaderOptions): Promise<WorkflowLoaderResult>;
|
|
39
|
+
fromInline(spec: unknown, source?: string): WorkflowLoaderResult;
|
|
40
|
+
private parse;
|
|
41
|
+
private validate;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
declare class StateStore {
|
|
45
|
+
private readonly logger;
|
|
46
|
+
private readonly cache;
|
|
47
|
+
constructor(cache: ICache, logger: EngineLogger);
|
|
48
|
+
saveRun(run: WorkflowRun): Promise<void>;
|
|
49
|
+
getRun(runId: string): Promise<WorkflowRun | null>;
|
|
50
|
+
deleteRun(runId: string): Promise<void>;
|
|
51
|
+
getAllRunIds(): Promise<string[]>;
|
|
52
|
+
updateRun(runId: string, mutator: (draft: WorkflowRun) => WorkflowRun | void): Promise<WorkflowRun | null>;
|
|
53
|
+
updateJob(runId: string, jobId: string, mutator: (job: JobRun) => JobRun | void): Promise<JobRun | null>;
|
|
54
|
+
updateStep(runId: string, jobId: string, stepId: string, mutator: (step: StepRun) => StepRun | void): Promise<StepRun | null>;
|
|
55
|
+
releaseBlockedJobs(runId: string, completedJobName: string): Promise<JobRun[]>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
interface AcquireOptions {
|
|
59
|
+
ttlMs?: number;
|
|
60
|
+
}
|
|
61
|
+
declare class ConcurrencyManager {
|
|
62
|
+
private readonly logger;
|
|
63
|
+
private readonly cache;
|
|
64
|
+
private readonly ttlMs;
|
|
65
|
+
constructor(cache: ICache, logger: EngineLogger, options?: AcquireOptions);
|
|
66
|
+
acquire(group: ConcurrencyGroup, runId: string, options?: AcquireOptions): Promise<boolean>;
|
|
67
|
+
release(group: ConcurrencyGroup, runId: string): Promise<void>;
|
|
68
|
+
getActiveRun(group: ConcurrencyGroup): Promise<string | null>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface RunCoordinatorOptions {
|
|
72
|
+
idempotencyTtlMs?: number;
|
|
73
|
+
}
|
|
74
|
+
declare class RunCoordinator {
|
|
75
|
+
private readonly stateStore;
|
|
76
|
+
private readonly concurrencyManager;
|
|
77
|
+
private readonly logger;
|
|
78
|
+
private readonly cache;
|
|
79
|
+
private readonly idempotencyTtlMs;
|
|
80
|
+
constructor(cache: ICache, stateStore: StateStore, concurrencyManager: ConcurrencyManager, logger: EngineLogger, options?: RunCoordinatorOptions);
|
|
81
|
+
ensureRun(input: CreateRunInput): Promise<WorkflowRun>;
|
|
82
|
+
private buildInitialRun;
|
|
83
|
+
private registerIdempotencyKey;
|
|
84
|
+
private loadByIdempotencyKey;
|
|
85
|
+
releaseConcurrency(run: WorkflowRun): Promise<void>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
interface JobQueueEntry {
|
|
89
|
+
id: string;
|
|
90
|
+
runId: string;
|
|
91
|
+
jobId: string;
|
|
92
|
+
priority: JobPriority;
|
|
93
|
+
enqueuedAt: string;
|
|
94
|
+
availableAt: number;
|
|
95
|
+
jobName: string;
|
|
96
|
+
}
|
|
97
|
+
interface SchedulerOptions {
|
|
98
|
+
defaultPriority?: JobPriority;
|
|
99
|
+
lookAheadMs?: number;
|
|
100
|
+
}
|
|
101
|
+
declare class Scheduler {
|
|
102
|
+
private readonly logger;
|
|
103
|
+
private readonly cache;
|
|
104
|
+
private readonly defaultPriority;
|
|
105
|
+
private readonly lookAheadMs;
|
|
106
|
+
private readonly priorityOrder;
|
|
107
|
+
constructor(cache: ICache, logger: EngineLogger, options?: SchedulerOptions);
|
|
108
|
+
scheduleRun(run: WorkflowRun): Promise<void>;
|
|
109
|
+
enqueueJob(runId: string, job: JobRun, priority?: JobPriority): Promise<void>;
|
|
110
|
+
dequeueJob(): Promise<JobQueueEntry | null>;
|
|
111
|
+
reschedule(entry: JobQueueEntry, delayMs: number): Promise<void>;
|
|
112
|
+
private dequeueFromPriority;
|
|
113
|
+
getDefaultPriority(): JobPriority;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
interface SecretProvider {
|
|
117
|
+
resolve(names: string[]): Promise<Record<string, string>>;
|
|
118
|
+
}
|
|
119
|
+
interface EnvSecretProviderOptions {
|
|
120
|
+
/**
|
|
121
|
+
* Prefix applied when looking up secrets in environment variables.
|
|
122
|
+
* Defaults to `KB_SECRET_`.
|
|
123
|
+
*/
|
|
124
|
+
prefix?: string;
|
|
125
|
+
/**
|
|
126
|
+
* When true (default), check both plain and prefixed environment variable names.
|
|
127
|
+
*/
|
|
128
|
+
allowPlain?: boolean;
|
|
129
|
+
}
|
|
130
|
+
declare class EnvSecretProvider implements SecretProvider {
|
|
131
|
+
private readonly prefix;
|
|
132
|
+
private readonly allowPlain;
|
|
133
|
+
constructor(options?: EnvSecretProviderOptions);
|
|
134
|
+
resolve(names: string[]): Promise<Record<string, string>>;
|
|
135
|
+
}
|
|
136
|
+
declare function createDefaultSecretProvider(): SecretProvider;
|
|
137
|
+
|
|
138
|
+
interface WorkflowEvent<TPayload = Record<string, unknown>> {
|
|
139
|
+
type: WorkflowEventName;
|
|
140
|
+
runId: string;
|
|
141
|
+
jobId?: string;
|
|
142
|
+
stepId?: string;
|
|
143
|
+
payload?: TPayload;
|
|
144
|
+
timestamp?: string;
|
|
145
|
+
}
|
|
146
|
+
declare class EventBusBridge {
|
|
147
|
+
private readonly logger;
|
|
148
|
+
private readonly events;
|
|
149
|
+
private readonly channel;
|
|
150
|
+
constructor(events: IEventBus, logger: EngineLogger);
|
|
151
|
+
publish<TPayload = Record<string, unknown>>(event: WorkflowEvent<TPayload>): Promise<void>;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
interface RetryDecision {
|
|
155
|
+
shouldRetry: boolean;
|
|
156
|
+
nextDelayMs?: number;
|
|
157
|
+
}
|
|
158
|
+
declare function calculateBackoff(attempt: number, policy?: RetryPolicy): number;
|
|
159
|
+
declare function shouldRetry(attempt: number, policy?: RetryPolicy): RetryDecision;
|
|
160
|
+
|
|
161
|
+
interface RunSnapshot {
|
|
162
|
+
runId: string;
|
|
163
|
+
run: WorkflowRun;
|
|
164
|
+
stepOutputs: Record<string, Record<string, unknown>>;
|
|
165
|
+
env: Record<string, string>;
|
|
166
|
+
refs?: {
|
|
167
|
+
workspaceSnapshotId?: string;
|
|
168
|
+
environmentSnapshotId?: string;
|
|
169
|
+
};
|
|
170
|
+
createdAt: string;
|
|
171
|
+
version: string;
|
|
172
|
+
}
|
|
173
|
+
declare class RunSnapshotStorage {
|
|
174
|
+
private readonly cache;
|
|
175
|
+
private readonly logger;
|
|
176
|
+
constructor(cache: ICache, logger: EngineLogger);
|
|
177
|
+
private getSnapshotKey;
|
|
178
|
+
createSnapshot(run: WorkflowRun, stepOutputs: Record<string, Record<string, unknown>>, env: Record<string, string>, refs?: RunSnapshot['refs']): Promise<RunSnapshot>;
|
|
179
|
+
getSnapshot(runId: string): Promise<RunSnapshot | null>;
|
|
180
|
+
deleteSnapshot(runId: string): Promise<void>;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
interface SnapshotManagerClient {
|
|
184
|
+
restoreSnapshot(request: {
|
|
185
|
+
snapshotId: string;
|
|
186
|
+
workspaceId?: string;
|
|
187
|
+
environmentId?: string;
|
|
188
|
+
targetPath?: string;
|
|
189
|
+
overwrite?: boolean;
|
|
190
|
+
metadata?: Record<string, unknown>;
|
|
191
|
+
}): Promise<unknown>;
|
|
192
|
+
}
|
|
193
|
+
interface WorkflowEngineOptions {
|
|
194
|
+
scheduler?: SchedulerOptions;
|
|
195
|
+
concurrency?: AcquireOptions;
|
|
196
|
+
runCoordinator?: RunCoordinatorOptions;
|
|
197
|
+
maxWorkflowDepth?: number;
|
|
198
|
+
/** Platform cache adapter (REQUIRED) */
|
|
199
|
+
cache: ICache;
|
|
200
|
+
/** Platform event bus adapter (REQUIRED) */
|
|
201
|
+
events: IEventBus;
|
|
202
|
+
/** Platform logger (REQUIRED) */
|
|
203
|
+
logger: ILogger;
|
|
204
|
+
/** Platform analytics adapter (OPTIONAL) */
|
|
205
|
+
analytics?: IAnalytics;
|
|
206
|
+
/** Platform snapshot manager (OPTIONAL - for infra snapshot restore in replay) */
|
|
207
|
+
snapshotManager?: SnapshotManagerClient;
|
|
208
|
+
/** Workspace root (monorepo root) - used for plugin execution context */
|
|
209
|
+
workspaceRoot?: string;
|
|
210
|
+
}
|
|
211
|
+
declare class WorkflowEngine {
|
|
212
|
+
private readonly options;
|
|
213
|
+
readonly loader: WorkflowLoader;
|
|
214
|
+
readonly maxWorkflowDepth: number;
|
|
215
|
+
private readonly logger;
|
|
216
|
+
private readonly analytics?;
|
|
217
|
+
private readonly stateStore;
|
|
218
|
+
private readonly concurrency;
|
|
219
|
+
private readonly runCoordinator;
|
|
220
|
+
private readonly scheduler;
|
|
221
|
+
private readonly events;
|
|
222
|
+
private readonly snapshotStorage;
|
|
223
|
+
constructor(options: WorkflowEngineOptions);
|
|
224
|
+
dispose(): Promise<void>;
|
|
225
|
+
/**
|
|
226
|
+
* Subscribe to real-time events for a specific workflow run.
|
|
227
|
+
* Events are filtered by runId from the shared event bus channel.
|
|
228
|
+
*/
|
|
229
|
+
subscribeToRunEvents(runId: string, handler: (event: WorkflowEvent) => void): Unsubscribe;
|
|
230
|
+
createRun(input: CreateRunInput): Promise<WorkflowRun>;
|
|
231
|
+
runFromSpec(spec: WorkflowSpec, input: Omit<CreateRunInput, 'spec'>): Promise<WorkflowRun>;
|
|
232
|
+
runFromFile(filePath: string, input: Omit<CreateRunInput, 'spec'>): Promise<WorkflowRun>;
|
|
233
|
+
runFromInline(spec: unknown, input: Omit<CreateRunInput, 'spec'>): Promise<WorkflowRun>;
|
|
234
|
+
getRun(runId: string): Promise<WorkflowRun | null>;
|
|
235
|
+
cancelRun(runId: string): Promise<void>;
|
|
236
|
+
/**
|
|
237
|
+
* Mark job as failed and optionally schedule retry.
|
|
238
|
+
* Implements exponential/linear backoff retry logic.
|
|
239
|
+
*/
|
|
240
|
+
markJobFailed(runId: string, jobId: string, error: Error, shouldRetry?: boolean): Promise<void>;
|
|
241
|
+
/**
|
|
242
|
+
* Mark job as interrupted (e.g., during graceful shutdown).
|
|
243
|
+
* Interrupted jobs will be retried on next daemon startup.
|
|
244
|
+
*/
|
|
245
|
+
markJobInterrupted(runId: string, jobId: string): Promise<void>;
|
|
246
|
+
/**
|
|
247
|
+
* Mark job as started (running).
|
|
248
|
+
*/
|
|
249
|
+
markJobStarted(runId: string, jobId: string): Promise<void>;
|
|
250
|
+
/**
|
|
251
|
+
* Mark job as completed successfully.
|
|
252
|
+
*/
|
|
253
|
+
markJobCompleted(runId: string, jobId: string): Promise<void>;
|
|
254
|
+
/**
|
|
255
|
+
* Check if all jobs in a run are completed and update run status accordingly.
|
|
256
|
+
*/
|
|
257
|
+
private checkRunCompletion;
|
|
258
|
+
/**
|
|
259
|
+
* Mark step as started (running).
|
|
260
|
+
*/
|
|
261
|
+
markStepStarted(runId: string, jobId: string, stepId: string): Promise<void>;
|
|
262
|
+
/**
|
|
263
|
+
* Mark step as completed successfully with output.
|
|
264
|
+
*/
|
|
265
|
+
markStepCompleted(runId: string, jobId: string, stepId: string, output?: unknown): Promise<void>;
|
|
266
|
+
/**
|
|
267
|
+
* Mark step as failed with error.
|
|
268
|
+
*/
|
|
269
|
+
markStepFailed(runId: string, jobId: string, stepId: string, error: Error, outputs?: Record<string, unknown>): Promise<void>;
|
|
270
|
+
/**
|
|
271
|
+
* Mark step as waiting for human approval.
|
|
272
|
+
*/
|
|
273
|
+
markStepWaitingApproval(runId: string, jobId: string, stepId: string): Promise<void>;
|
|
274
|
+
/**
|
|
275
|
+
* Resolve a pending approval — approve or reject.
|
|
276
|
+
* On approve: marks step as success with approval outputs.
|
|
277
|
+
* On reject: marks step as failed with rejection error.
|
|
278
|
+
*/
|
|
279
|
+
resolveApproval(runId: string, jobId: string, stepId: string, action: 'approve' | 'reject', data?: Record<string, unknown>, comment?: string): Promise<void>;
|
|
280
|
+
/**
|
|
281
|
+
* Get the state store for direct access (used by worker for gate restart-from).
|
|
282
|
+
*/
|
|
283
|
+
getStateStore(): StateStore;
|
|
284
|
+
/**
|
|
285
|
+
* Get the scheduler for direct access (used by worker for gate re-enqueue).
|
|
286
|
+
*/
|
|
287
|
+
getScheduler(): Scheduler;
|
|
288
|
+
/**
|
|
289
|
+
* Mark stale running/queued runs as failed on daemon startup.
|
|
290
|
+
* Runs that were in-flight when the daemon crashed are unrecoverable —
|
|
291
|
+
* their executor process is gone, so we mark them failed immediately.
|
|
292
|
+
*/
|
|
293
|
+
cleanupStaleRuns(): Promise<void>;
|
|
294
|
+
/**
|
|
295
|
+
* Resume interrupted jobs on daemon startup.
|
|
296
|
+
* Re-queues jobs that were interrupted during previous shutdown.
|
|
297
|
+
*/
|
|
298
|
+
resumeInterruptedJobs(): Promise<void>;
|
|
299
|
+
/**
|
|
300
|
+
* Determine if job should be retried based on retry policy.
|
|
301
|
+
*/
|
|
302
|
+
private shouldRetryJob;
|
|
303
|
+
/**
|
|
304
|
+
* Calculate backoff delay using exponential or linear strategy.
|
|
305
|
+
*/
|
|
306
|
+
private calculateBackoff;
|
|
307
|
+
/**
|
|
308
|
+
* Move permanently failed job to Dead Letter Queue.
|
|
309
|
+
*/
|
|
310
|
+
private moveToDLQ;
|
|
311
|
+
updateRun(runId: string, mutator: (run: WorkflowRun) => WorkflowRun | void): Promise<WorkflowRun | null>;
|
|
312
|
+
finalizeRun(runId: string, status: WorkflowRun['status'], context?: Partial<RunContext>): Promise<WorkflowRun | null>;
|
|
313
|
+
nextJob(): Promise<JobQueueEntry | null>;
|
|
314
|
+
rescheduleJob(entry: JobQueueEntry, delayMs: number): Promise<void>;
|
|
315
|
+
publishRunEvent(type: WorkflowEventName, run: WorkflowRun): Promise<void>;
|
|
316
|
+
/**
|
|
317
|
+
* Publish a log entry for real-time streaming to Studio UI.
|
|
318
|
+
*/
|
|
319
|
+
publishLog(runId: string, jobId: string, stepId: string, entry: {
|
|
320
|
+
level: string;
|
|
321
|
+
message: string;
|
|
322
|
+
stream: string;
|
|
323
|
+
lineNo: number;
|
|
324
|
+
timestamp: string;
|
|
325
|
+
meta?: Record<string, unknown>;
|
|
326
|
+
}): Promise<void>;
|
|
327
|
+
/**
|
|
328
|
+
* Create a snapshot of the current run state
|
|
329
|
+
*/
|
|
330
|
+
createSnapshot(runId: string, stepOutputs: Record<string, Record<string, unknown>>, env: Record<string, string>, refs?: RunSnapshot['refs']): Promise<RunSnapshot | null>;
|
|
331
|
+
/**
|
|
332
|
+
* Get a snapshot for a run
|
|
333
|
+
*/
|
|
334
|
+
getSnapshot(runId: string): Promise<RunSnapshot | null>;
|
|
335
|
+
/**
|
|
336
|
+
* Replay a run from a snapshot, optionally starting from a specific step
|
|
337
|
+
*/
|
|
338
|
+
replayRun(runId: string, options?: {
|
|
339
|
+
fromStepId?: string;
|
|
340
|
+
stepOutputs?: Record<string, Record<string, unknown>>;
|
|
341
|
+
env?: Record<string, string>;
|
|
342
|
+
}): Promise<WorkflowRun | null>;
|
|
343
|
+
/**
|
|
344
|
+
* Delete a snapshot
|
|
345
|
+
*/
|
|
346
|
+
deleteSnapshot(runId: string): Promise<void>;
|
|
347
|
+
/**
|
|
348
|
+
* Get all active workflow executions (running or queued).
|
|
349
|
+
* Returns array of WorkflowRun objects with status 'running' or 'queued'.
|
|
350
|
+
*/
|
|
351
|
+
getActiveExecutions(): Promise<WorkflowRun[]>;
|
|
352
|
+
/**
|
|
353
|
+
* Get all workflow runs (all statuses).
|
|
354
|
+
* Returns array of all WorkflowRun objects ordered by creation time.
|
|
355
|
+
*/
|
|
356
|
+
getAllRuns(): Promise<WorkflowRun[]>;
|
|
357
|
+
/**
|
|
358
|
+
* List all workflow runs.
|
|
359
|
+
* Returns array of all runs in the system.
|
|
360
|
+
* Alias for getAllRuns() - maintained for backward compatibility.
|
|
361
|
+
*/
|
|
362
|
+
listRuns(): Promise<WorkflowRun[]>;
|
|
363
|
+
/**
|
|
364
|
+
* Get workflow engine metrics.
|
|
365
|
+
* Returns statistics about runs, jobs, and system health.
|
|
366
|
+
*/
|
|
367
|
+
getMetrics(): Promise<{
|
|
368
|
+
runs: {
|
|
369
|
+
total: number;
|
|
370
|
+
queued: number;
|
|
371
|
+
running: number;
|
|
372
|
+
completed: number;
|
|
373
|
+
failed: number;
|
|
374
|
+
cancelled: number;
|
|
375
|
+
dlq: number;
|
|
376
|
+
};
|
|
377
|
+
jobs: {
|
|
378
|
+
total: number;
|
|
379
|
+
queued: number;
|
|
380
|
+
running: number;
|
|
381
|
+
completed: number;
|
|
382
|
+
failed: number;
|
|
383
|
+
};
|
|
384
|
+
}>;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
interface ArtifactMergerOptions {
|
|
388
|
+
stateStore: StateStore;
|
|
389
|
+
logger: EngineLogger;
|
|
390
|
+
artifactsRoot: string;
|
|
391
|
+
}
|
|
392
|
+
declare class ArtifactMerger {
|
|
393
|
+
private readonly options;
|
|
394
|
+
constructor(options: ArtifactMergerOptions);
|
|
395
|
+
mergeArtifacts(config: ArtifactMergeConfig, targetArtifacts: ArtifactClient, currentRunId: string): Promise<void>;
|
|
396
|
+
private loadArtifactsFromRun;
|
|
397
|
+
private loadArtifactContent;
|
|
398
|
+
private applyMergeStrategy;
|
|
399
|
+
private mergeAppend;
|
|
400
|
+
private mergeJson;
|
|
401
|
+
private deepMerge;
|
|
402
|
+
private saveMergedArtifact;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* @module @kb-labs/workflow-engine/manifest-scanner
|
|
407
|
+
*
|
|
408
|
+
* Scans plugin manifests for workflows and jobs, converting them to unified WorkflowRuntime format.
|
|
409
|
+
*
|
|
410
|
+
* ## Features
|
|
411
|
+
* - Discovers workflows from `manifest.workflows.handlers`
|
|
412
|
+
* - Discovers jobs from `manifest.jobs`
|
|
413
|
+
* - Converts to unified WorkflowRuntime representation
|
|
414
|
+
* - Caches results via Platform state for performance
|
|
415
|
+
*
|
|
416
|
+
* ## Usage
|
|
417
|
+
* ```typescript
|
|
418
|
+
* const scanner = new ManifestScanner({ cliApi, platform });
|
|
419
|
+
* const workflows = await scanner.scanPlugins();
|
|
420
|
+
* ```
|
|
421
|
+
*/
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Workflow trigger type
|
|
425
|
+
*/
|
|
426
|
+
type WorkflowTriggerType = 'manual' | 'webhook' | 'push' | 'schedule' | 'event';
|
|
427
|
+
/**
|
|
428
|
+
* Workflow trigger configuration
|
|
429
|
+
*/
|
|
430
|
+
interface WorkflowTrigger {
|
|
431
|
+
type: WorkflowTriggerType;
|
|
432
|
+
config?: Record<string, unknown>;
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Schedule configuration for workflows
|
|
436
|
+
*/
|
|
437
|
+
interface WorkflowSchedule {
|
|
438
|
+
/** Cron expression (e.g., "0 2 * * *") */
|
|
439
|
+
cron: string;
|
|
440
|
+
/** Whether schedule is enabled */
|
|
441
|
+
enabled: boolean;
|
|
442
|
+
/** Next run time (calculated) */
|
|
443
|
+
nextRun?: Date;
|
|
444
|
+
/** Last run time */
|
|
445
|
+
lastRun?: Date;
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Workflow runtime statistics
|
|
449
|
+
*/
|
|
450
|
+
interface WorkflowStats {
|
|
451
|
+
totalRuns: number;
|
|
452
|
+
successRuns: number;
|
|
453
|
+
failedRuns: number;
|
|
454
|
+
lastRunStatus?: 'success' | 'failed' | 'cancelled';
|
|
455
|
+
lastRunAt?: Date;
|
|
456
|
+
avgDurationMs?: number;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Unified workflow runtime representation.
|
|
460
|
+
*
|
|
461
|
+
* Used for both manifest-based and standalone workflows.
|
|
462
|
+
*/
|
|
463
|
+
interface WorkflowRuntime {
|
|
464
|
+
id: string;
|
|
465
|
+
source: 'manifest' | 'standalone';
|
|
466
|
+
pluginId?: string;
|
|
467
|
+
manifestPath?: string;
|
|
468
|
+
name: string;
|
|
469
|
+
description?: string;
|
|
470
|
+
tags?: string[];
|
|
471
|
+
triggers: WorkflowTrigger[];
|
|
472
|
+
handler?: string;
|
|
473
|
+
schedule?: WorkflowSchedule;
|
|
474
|
+
status: 'active' | 'paused' | 'disabled';
|
|
475
|
+
stats?: WorkflowStats;
|
|
476
|
+
permissions?: unknown;
|
|
477
|
+
input?: unknown;
|
|
478
|
+
output?: unknown;
|
|
479
|
+
inputSchema?: Record<string, {
|
|
480
|
+
type: 'string' | 'number' | 'boolean';
|
|
481
|
+
description?: string;
|
|
482
|
+
required?: boolean;
|
|
483
|
+
default?: unknown;
|
|
484
|
+
}>;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Options for ManifestScanner
|
|
488
|
+
*/
|
|
489
|
+
interface ManifestScannerOptions {
|
|
490
|
+
/** CLI API instance */
|
|
491
|
+
cliApi: IEntityRegistry;
|
|
492
|
+
/** Platform services (for state, logger, etc.) */
|
|
493
|
+
platform: PlatformServices;
|
|
494
|
+
/** Cache TTL in milliseconds (default: 60000 = 1 minute) */
|
|
495
|
+
cacheTtlMs?: number;
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Manifest Scanner Service
|
|
499
|
+
*
|
|
500
|
+
* Discovers workflows and jobs from installed plugin manifests.
|
|
501
|
+
*/
|
|
502
|
+
declare class ManifestScanner {
|
|
503
|
+
private readonly cliApi;
|
|
504
|
+
private readonly platform;
|
|
505
|
+
private readonly cacheTtlMs;
|
|
506
|
+
constructor(options: ManifestScannerOptions);
|
|
507
|
+
/**
|
|
508
|
+
* Scan all installed plugins for workflows and jobs.
|
|
509
|
+
*
|
|
510
|
+
* Returns unified WorkflowRuntime representations.
|
|
511
|
+
*/
|
|
512
|
+
scanPlugins(): Promise<WorkflowRuntime[]>;
|
|
513
|
+
/**
|
|
514
|
+
* Convert workflow handler declaration to WorkflowRuntime.
|
|
515
|
+
*/
|
|
516
|
+
private convertWorkflowHandler;
|
|
517
|
+
/**
|
|
518
|
+
* Convert job handler declaration to WorkflowRuntime.
|
|
519
|
+
*/
|
|
520
|
+
private convertJobHandler;
|
|
521
|
+
/**
|
|
522
|
+
* Convert cron schedule declaration to WorkflowRuntime.
|
|
523
|
+
*/
|
|
524
|
+
private convertCronSchedule;
|
|
525
|
+
/**
|
|
526
|
+
* Scan all installed plugins for job handlers only.
|
|
527
|
+
*
|
|
528
|
+
* Returns information needed to register handlers in JobManager.
|
|
529
|
+
*/
|
|
530
|
+
scanJobHandlers(): Promise<Array<{
|
|
531
|
+
pluginId: string;
|
|
532
|
+
pluginVersion: string;
|
|
533
|
+
pluginRoot: string;
|
|
534
|
+
handler: JobHandlerDecl;
|
|
535
|
+
}>>;
|
|
536
|
+
/**
|
|
537
|
+
* Clear cache (useful for testing or force refresh).
|
|
538
|
+
*/
|
|
539
|
+
clearCache(): Promise<void>;
|
|
540
|
+
/**
|
|
541
|
+
* Watch for plugin changes and invalidate cache.
|
|
542
|
+
*
|
|
543
|
+
* @param callback Optional callback when workflows change
|
|
544
|
+
* @returns Unsubscribe function
|
|
545
|
+
*/
|
|
546
|
+
watchPlugins(callback?: (workflows: WorkflowRuntime[]) => void): () => void;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* @module @kb-labs/workflow-engine/workflow-repository
|
|
551
|
+
*
|
|
552
|
+
* Repository for standalone workflow definitions.
|
|
553
|
+
*
|
|
554
|
+
* ## Features
|
|
555
|
+
* - CRUD operations for user-created workflows
|
|
556
|
+
* - File-based storage via platform.storage (`.kb/workflows/*.yaml`)
|
|
557
|
+
* - Validation using WorkflowSpecSchema
|
|
558
|
+
* - Conversion to unified WorkflowRuntime format
|
|
559
|
+
*
|
|
560
|
+
* ## Usage
|
|
561
|
+
* ```typescript
|
|
562
|
+
* const repo = new WorkflowRepository({ platform });
|
|
563
|
+
* const workflow = await repo.create(spec);
|
|
564
|
+
* ```
|
|
565
|
+
*/
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* List options for filtering workflows
|
|
569
|
+
*/
|
|
570
|
+
interface WorkflowListOptions {
|
|
571
|
+
status?: 'active' | 'paused' | 'disabled';
|
|
572
|
+
tags?: string[];
|
|
573
|
+
limit?: number;
|
|
574
|
+
offset?: number;
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Options for WorkflowRepository
|
|
578
|
+
*/
|
|
579
|
+
interface WorkflowRepositoryOptions {
|
|
580
|
+
/** Platform services (for storage, logger, etc.) */
|
|
581
|
+
platform: PlatformServices;
|
|
582
|
+
/** Storage directory for workflows (default: '.kb/workflows') */
|
|
583
|
+
storageDir?: string;
|
|
584
|
+
/** Workspace root directory (default: process.cwd()) */
|
|
585
|
+
workspaceRoot?: string;
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Workflow Repository
|
|
589
|
+
*
|
|
590
|
+
* Manages standalone workflow definitions (user-created via UI/API).
|
|
591
|
+
* Uses platform.storage for persistence.
|
|
592
|
+
*/
|
|
593
|
+
declare class WorkflowRepository {
|
|
594
|
+
private readonly platform;
|
|
595
|
+
private readonly storageDir;
|
|
596
|
+
private readonly workspaceRoot;
|
|
597
|
+
private readonly absoluteStorageDir;
|
|
598
|
+
constructor(options: WorkflowRepositoryOptions);
|
|
599
|
+
/**
|
|
600
|
+
* Create a new standalone workflow.
|
|
601
|
+
*/
|
|
602
|
+
create(spec: WorkflowSpec): Promise<WorkflowRuntime>;
|
|
603
|
+
/**
|
|
604
|
+
* Get workflow by ID.
|
|
605
|
+
*/
|
|
606
|
+
get(id: string): Promise<WorkflowRuntime | null>;
|
|
607
|
+
/**
|
|
608
|
+
* List all workflows with optional filtering.
|
|
609
|
+
*/
|
|
610
|
+
list(options?: WorkflowListOptions): Promise<WorkflowRuntime[]>;
|
|
611
|
+
/**
|
|
612
|
+
* Update existing workflow.
|
|
613
|
+
*/
|
|
614
|
+
update(id: string, spec: Partial<WorkflowSpec>): Promise<WorkflowRuntime>;
|
|
615
|
+
/**
|
|
616
|
+
* Delete workflow.
|
|
617
|
+
*/
|
|
618
|
+
delete(id: string): Promise<void>;
|
|
619
|
+
/**
|
|
620
|
+
* Enable workflow (set status to active).
|
|
621
|
+
*/
|
|
622
|
+
enable(id: string): Promise<void>;
|
|
623
|
+
/**
|
|
624
|
+
* Disable workflow.
|
|
625
|
+
*/
|
|
626
|
+
disable(id: string): Promise<void>;
|
|
627
|
+
/**
|
|
628
|
+
* Pause workflow.
|
|
629
|
+
*/
|
|
630
|
+
pause(id: string): Promise<void>;
|
|
631
|
+
/**
|
|
632
|
+
* Resume workflow (unpause).
|
|
633
|
+
*/
|
|
634
|
+
resume(id: string): Promise<void>;
|
|
635
|
+
/**
|
|
636
|
+
* Update workflow statistics.
|
|
637
|
+
*/
|
|
638
|
+
updateStats(id: string, stats: Partial<WorkflowStats>): Promise<void>;
|
|
639
|
+
private updateStatus;
|
|
640
|
+
private getWorkflowPath;
|
|
641
|
+
private saveWorkflow;
|
|
642
|
+
private loadWorkflow;
|
|
643
|
+
private listWorkflowFiles;
|
|
644
|
+
/**
|
|
645
|
+
* Convert stored workflow to WorkflowRuntime format.
|
|
646
|
+
*/
|
|
647
|
+
private toRuntime;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* @module @kb-labs/workflow-engine/workflow-service
|
|
652
|
+
*
|
|
653
|
+
* Unified service for managing all workflows (manifest-based + standalone).
|
|
654
|
+
*
|
|
655
|
+
* ## Features
|
|
656
|
+
* - Combines ManifestScanner and WorkflowRepository
|
|
657
|
+
* - Unified interface for listing/getting workflows from both sources
|
|
658
|
+
* - Provides available handlers for UI autocomplete
|
|
659
|
+
* - Validates workflow specs
|
|
660
|
+
*
|
|
661
|
+
* ## Usage
|
|
662
|
+
* ```typescript
|
|
663
|
+
* const service = new WorkflowService({ cliApi, platform });
|
|
664
|
+
* const allWorkflows = await service.listAll();
|
|
665
|
+
* const workflow = await service.get('release-manager/create-release');
|
|
666
|
+
* ```
|
|
667
|
+
*/
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* Handler information for UI autocomplete
|
|
671
|
+
*/
|
|
672
|
+
interface WorkflowHandlerInfo {
|
|
673
|
+
/** Handler ID (e.g., "release-manager/create-release") */
|
|
674
|
+
id: string;
|
|
675
|
+
/** Plugin ID */
|
|
676
|
+
pluginId: string;
|
|
677
|
+
/** Human-readable name */
|
|
678
|
+
name: string;
|
|
679
|
+
/** Description */
|
|
680
|
+
description?: string;
|
|
681
|
+
/** Input schema */
|
|
682
|
+
inputSchema?: unknown;
|
|
683
|
+
/** Output schema */
|
|
684
|
+
outputSchema?: unknown;
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Validation result
|
|
688
|
+
*/
|
|
689
|
+
interface ValidationResult {
|
|
690
|
+
valid: boolean;
|
|
691
|
+
errors?: Array<{
|
|
692
|
+
path: string;
|
|
693
|
+
message: string;
|
|
694
|
+
}>;
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
* List options for workflows
|
|
698
|
+
*/
|
|
699
|
+
interface WorkflowServiceListOptions extends WorkflowListOptions {
|
|
700
|
+
/** Filter by source type */
|
|
701
|
+
source?: 'manifest' | 'standalone';
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* Options for WorkflowService
|
|
705
|
+
*/
|
|
706
|
+
interface WorkflowServiceOptions {
|
|
707
|
+
/** CLI API for plugin manifest scanning */
|
|
708
|
+
cliApi: IEntityRegistry;
|
|
709
|
+
/** Platform services */
|
|
710
|
+
platform: PlatformServices;
|
|
711
|
+
/** Cache TTL for manifest scanner (ms) */
|
|
712
|
+
manifestCacheTtlMs?: number;
|
|
713
|
+
/** Storage directory for standalone workflows */
|
|
714
|
+
workflowStorageDir?: string;
|
|
715
|
+
/** Workspace root directory (default: process.cwd()) */
|
|
716
|
+
workspaceRoot?: string;
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Unified Workflow Service
|
|
720
|
+
*
|
|
721
|
+
* Combines manifest-based and standalone workflows into a single interface.
|
|
722
|
+
*/
|
|
723
|
+
declare class WorkflowService {
|
|
724
|
+
private readonly scanner;
|
|
725
|
+
private readonly repository;
|
|
726
|
+
private readonly platform;
|
|
727
|
+
constructor(options: WorkflowServiceOptions);
|
|
728
|
+
/**
|
|
729
|
+
* List all workflows (manifest + standalone).
|
|
730
|
+
*/
|
|
731
|
+
listAll(options?: WorkflowServiceListOptions): Promise<WorkflowRuntime[]>;
|
|
732
|
+
/**
|
|
733
|
+
* Get workflow by ID (from either source).
|
|
734
|
+
*/
|
|
735
|
+
get(id: string): Promise<WorkflowRuntime | null>;
|
|
736
|
+
/**
|
|
737
|
+
* Create standalone workflow.
|
|
738
|
+
*/
|
|
739
|
+
create(spec: WorkflowSpec): Promise<WorkflowRuntime>;
|
|
740
|
+
/**
|
|
741
|
+
* Update standalone workflow.
|
|
742
|
+
*/
|
|
743
|
+
update(id: string, spec: Partial<WorkflowSpec>): Promise<WorkflowRuntime>;
|
|
744
|
+
/**
|
|
745
|
+
* Delete standalone workflow.
|
|
746
|
+
*/
|
|
747
|
+
delete(id: string): Promise<void>;
|
|
748
|
+
/**
|
|
749
|
+
* Enable workflow (set status to active).
|
|
750
|
+
*/
|
|
751
|
+
enable(id: string): Promise<void>;
|
|
752
|
+
/**
|
|
753
|
+
* Disable workflow.
|
|
754
|
+
*/
|
|
755
|
+
disable(id: string): Promise<void>;
|
|
756
|
+
/**
|
|
757
|
+
* Pause workflow.
|
|
758
|
+
*/
|
|
759
|
+
pause(id: string): Promise<void>;
|
|
760
|
+
/**
|
|
761
|
+
* Resume workflow (unpause).
|
|
762
|
+
*/
|
|
763
|
+
resume(id: string): Promise<void>;
|
|
764
|
+
/**
|
|
765
|
+
* Get available workflow handlers (for UI autocomplete).
|
|
766
|
+
*
|
|
767
|
+
* Returns manifest-based handlers that can be used in standalone workflows
|
|
768
|
+
* (via `uses: "plugin:id/handler"`).
|
|
769
|
+
*/
|
|
770
|
+
getAvailableHandlers(): Promise<WorkflowHandlerInfo[]>;
|
|
771
|
+
/**
|
|
772
|
+
* Validate workflow spec.
|
|
773
|
+
*/
|
|
774
|
+
validate(spec: WorkflowSpec): ValidationResult;
|
|
775
|
+
/**
|
|
776
|
+
* Refresh manifest scanner cache (force re-scan).
|
|
777
|
+
*/
|
|
778
|
+
refreshManifests(): Promise<void>;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
/**
|
|
782
|
+
* @module @kb-labs/workflow-engine/workflow-schedule-manager
|
|
783
|
+
*
|
|
784
|
+
* Manages scheduled workflow execution via CronManager.
|
|
785
|
+
*
|
|
786
|
+
* ## Features
|
|
787
|
+
* - Registers scheduled workflows with CronManager
|
|
788
|
+
* - Executes workflows on cron triggers
|
|
789
|
+
* - Tracks next/last run times
|
|
790
|
+
* - Supports both manifest-based jobs and standalone workflows
|
|
791
|
+
*
|
|
792
|
+
* ## Usage
|
|
793
|
+
* ```typescript
|
|
794
|
+
* const scheduleManager = new WorkflowScheduleManager({
|
|
795
|
+
* cronManager,
|
|
796
|
+
* workflowService,
|
|
797
|
+
* executor,
|
|
798
|
+
* platform,
|
|
799
|
+
* });
|
|
800
|
+
*
|
|
801
|
+
* await scheduleManager.registerAll();
|
|
802
|
+
* ```
|
|
803
|
+
*/
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
* Workflow executor interface.
|
|
807
|
+
* Executes workflows (will be implemented by workflow engine).
|
|
808
|
+
*/
|
|
809
|
+
interface WorkflowExecutor {
|
|
810
|
+
/**
|
|
811
|
+
* Execute workflow by ID.
|
|
812
|
+
*/
|
|
813
|
+
execute(request: {
|
|
814
|
+
workflowId: string;
|
|
815
|
+
trigger: 'manual' | 'schedule' | 'webhook' | 'push';
|
|
816
|
+
input?: Record<string, unknown>;
|
|
817
|
+
}): Promise<{
|
|
818
|
+
runId: string;
|
|
819
|
+
}>;
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Options for WorkflowScheduleManager
|
|
823
|
+
*/
|
|
824
|
+
interface WorkflowScheduleManagerOptions {
|
|
825
|
+
/** CronManager instance */
|
|
826
|
+
cronManager: ICronManager;
|
|
827
|
+
/** WorkflowService for discovering workflows */
|
|
828
|
+
workflowService: WorkflowService;
|
|
829
|
+
/** Workflow executor */
|
|
830
|
+
executor: WorkflowExecutor;
|
|
831
|
+
/** Platform services */
|
|
832
|
+
platform: PlatformServices;
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* Workflow Schedule Manager
|
|
836
|
+
*
|
|
837
|
+
* Integrates workflows with CronManager for scheduled execution.
|
|
838
|
+
*/
|
|
839
|
+
declare class WorkflowScheduleManager {
|
|
840
|
+
private readonly cronManager;
|
|
841
|
+
private readonly workflowService;
|
|
842
|
+
private readonly executor;
|
|
843
|
+
private readonly platform;
|
|
844
|
+
constructor(options: WorkflowScheduleManagerOptions);
|
|
845
|
+
/**
|
|
846
|
+
* Register all scheduled workflows with CronManager.
|
|
847
|
+
*
|
|
848
|
+
* Scans both manifest-based jobs and standalone workflows with schedules.
|
|
849
|
+
*/
|
|
850
|
+
registerAll(): Promise<void>;
|
|
851
|
+
/**
|
|
852
|
+
* Register single workflow schedule.
|
|
853
|
+
*/
|
|
854
|
+
register(workflow: WorkflowRuntime): Promise<void>;
|
|
855
|
+
/**
|
|
856
|
+
* Unregister workflow schedule.
|
|
857
|
+
*/
|
|
858
|
+
unregister(workflowId: string): Promise<void>;
|
|
859
|
+
/**
|
|
860
|
+
* Re-register all schedules (refresh).
|
|
861
|
+
*
|
|
862
|
+
* Useful after workflow changes or service restart.
|
|
863
|
+
*/
|
|
864
|
+
refresh(): Promise<void>;
|
|
865
|
+
/**
|
|
866
|
+
* Get next run time for scheduled workflow.
|
|
867
|
+
*/
|
|
868
|
+
getNextRun(workflowId: string): Date | null;
|
|
869
|
+
/**
|
|
870
|
+
* Get last run time for scheduled workflow.
|
|
871
|
+
*/
|
|
872
|
+
getLastRun(workflowId: string): Date | null;
|
|
873
|
+
/**
|
|
874
|
+
* Pause scheduled workflow.
|
|
875
|
+
*/
|
|
876
|
+
pause(workflowId: string): void;
|
|
877
|
+
/**
|
|
878
|
+
* Resume paused workflow schedule.
|
|
879
|
+
*/
|
|
880
|
+
resume(workflowId: string): void;
|
|
881
|
+
/**
|
|
882
|
+
* List all scheduled workflows.
|
|
883
|
+
*/
|
|
884
|
+
listScheduled(): Array<{
|
|
885
|
+
workflowId: string;
|
|
886
|
+
schedule: string;
|
|
887
|
+
status: 'active' | 'paused';
|
|
888
|
+
lastRun?: Date;
|
|
889
|
+
nextRun?: Date;
|
|
890
|
+
runCount: number;
|
|
891
|
+
}>;
|
|
892
|
+
private getCronId;
|
|
893
|
+
private getWorkflowId;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
interface WorkflowRegistryEntry {
|
|
897
|
+
id: string;
|
|
898
|
+
name: string;
|
|
899
|
+
description?: string;
|
|
900
|
+
filePath: string;
|
|
901
|
+
spec: WorkflowSpec;
|
|
902
|
+
metadata?: Record<string, unknown>;
|
|
903
|
+
}
|
|
904
|
+
interface WorkflowRegistryOptions {
|
|
905
|
+
scanDirs: string[];
|
|
906
|
+
cwd?: string;
|
|
907
|
+
logger: ILogger;
|
|
908
|
+
}
|
|
909
|
+
/**
|
|
910
|
+
* WorkflowRegistry - Auto-discovery and indexing of workflow definitions
|
|
911
|
+
*
|
|
912
|
+
* Scans directories for .yml workflow files and indexes them by ID.
|
|
913
|
+
* Provides clean API for finding and running workflows.
|
|
914
|
+
*/
|
|
915
|
+
declare class WorkflowRegistry {
|
|
916
|
+
private readonly options;
|
|
917
|
+
private entries;
|
|
918
|
+
private loader;
|
|
919
|
+
constructor(options: WorkflowRegistryOptions);
|
|
920
|
+
/**
|
|
921
|
+
* Scan configured directories and index all workflow files
|
|
922
|
+
*/
|
|
923
|
+
scan(): Promise<void>;
|
|
924
|
+
/**
|
|
925
|
+
* Index a single workflow file
|
|
926
|
+
*/
|
|
927
|
+
private indexFile;
|
|
928
|
+
/**
|
|
929
|
+
* Parse workflow file (YAML format with additional fields)
|
|
930
|
+
*/
|
|
931
|
+
private parseWorkflowFile;
|
|
932
|
+
/**
|
|
933
|
+
* Get workflow by ID
|
|
934
|
+
*/
|
|
935
|
+
get(id: string): WorkflowRegistryEntry | undefined;
|
|
936
|
+
/**
|
|
937
|
+
* List all registered workflows
|
|
938
|
+
*/
|
|
939
|
+
list(): WorkflowRegistryEntry[];
|
|
940
|
+
/**
|
|
941
|
+
* Check if workflow exists
|
|
942
|
+
*/
|
|
943
|
+
has(id: string): boolean;
|
|
944
|
+
/**
|
|
945
|
+
* Get workflow spec by ID
|
|
946
|
+
*/
|
|
947
|
+
getSpec(id: string): WorkflowSpec | undefined;
|
|
948
|
+
/**
|
|
949
|
+
* Clear all indexed workflows
|
|
950
|
+
*/
|
|
951
|
+
clear(): void;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
/**
|
|
955
|
+
* @module @kb-labs/workflow-engine/job-manager
|
|
956
|
+
* Job manager for background task execution with sandboxed handlers.
|
|
957
|
+
*/
|
|
958
|
+
|
|
959
|
+
interface JobManagerConfig {
|
|
960
|
+
/** Execution backend for sandboxed handler execution */
|
|
961
|
+
executionBackend?: IExecutionBackend<PluginContextDescriptor>;
|
|
962
|
+
/** Default job timeout in ms (default: 300000 = 5 min) */
|
|
963
|
+
defaultTimeout?: number;
|
|
964
|
+
/** Default max retries (default: 3) */
|
|
965
|
+
defaultMaxRetries?: number;
|
|
966
|
+
/** Default priority (default: 50) */
|
|
967
|
+
defaultPriority?: number;
|
|
968
|
+
/** Workspace root (monorepo root) for plugin execution context */
|
|
969
|
+
workspaceRoot?: string;
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* Job manager - handles background job execution with sandboxed handlers.
|
|
973
|
+
*
|
|
974
|
+
* Features:
|
|
975
|
+
* - Declarative job handlers from plugin manifests
|
|
976
|
+
* - Priority-based queue (0-100, higher = more important)
|
|
977
|
+
* - Retry with exponential/linear backoff
|
|
978
|
+
* - Sandboxed subprocess execution via ExecutionBackend
|
|
979
|
+
* - Progress tracking and status updates
|
|
980
|
+
* - Idempotency support
|
|
981
|
+
*
|
|
982
|
+
* Architecture:
|
|
983
|
+
* 1. Plugin declares job handlers in manifest.json
|
|
984
|
+
* 2. Plugin runtime registers handlers via registerJobHandler()
|
|
985
|
+
* 3. Plugin submits jobs via ctx.api.jobs.submit()
|
|
986
|
+
* 4. JobManager enqueues job in priority queue (platform.cache sorted sets)
|
|
987
|
+
* 5. Worker dequeues job and executes via ExecutionBackend.execute()
|
|
988
|
+
* 6. Handler runs in subprocess with JobContext
|
|
989
|
+
* 7. Results stored in cache, events emitted
|
|
990
|
+
*/
|
|
991
|
+
declare class JobManager implements IJobScheduler {
|
|
992
|
+
private readonly cache;
|
|
993
|
+
private readonly events;
|
|
994
|
+
private readonly logger;
|
|
995
|
+
private readonly config;
|
|
996
|
+
private handlerRegistry;
|
|
997
|
+
private readonly defaultTimeout;
|
|
998
|
+
private readonly defaultMaxRetries;
|
|
999
|
+
private readonly defaultPriority;
|
|
1000
|
+
private readonly workspaceRoot;
|
|
1001
|
+
constructor(cache: ICache, events: IEventBus, logger: ILogger, config?: JobManagerConfig);
|
|
1002
|
+
/**
|
|
1003
|
+
* Register job handler from plugin manifest.
|
|
1004
|
+
*
|
|
1005
|
+
* Called by plugin-runtime during plugin initialization.
|
|
1006
|
+
*
|
|
1007
|
+
* @param pluginId - Plugin identifier
|
|
1008
|
+
* @param pluginVersion - Plugin version
|
|
1009
|
+
* @param pluginRoot - Plugin root directory
|
|
1010
|
+
* @param handlerDecl - Job handler declaration from manifest
|
|
1011
|
+
*/
|
|
1012
|
+
registerJobHandler(pluginId: string, pluginVersion: string, pluginRoot: string, handlerDecl: JobHandlerDecl): void;
|
|
1013
|
+
/**
|
|
1014
|
+
* Submit a job for immediate execution.
|
|
1015
|
+
*/
|
|
1016
|
+
submit(job: JobDefinition): Promise<JobHandle>;
|
|
1017
|
+
/**
|
|
1018
|
+
* Schedule a job for future/recurring execution.
|
|
1019
|
+
*/
|
|
1020
|
+
schedule(job: JobDefinition, schedule: CronExpression | Date): Promise<JobHandle>;
|
|
1021
|
+
/**
|
|
1022
|
+
* Cancel a pending/running job.
|
|
1023
|
+
*/
|
|
1024
|
+
cancel(jobId: string): Promise<boolean>;
|
|
1025
|
+
/**
|
|
1026
|
+
* Get job status.
|
|
1027
|
+
*/
|
|
1028
|
+
getStatus(jobId: string): Promise<JobHandle | null>;
|
|
1029
|
+
/**
|
|
1030
|
+
* List jobs.
|
|
1031
|
+
*/
|
|
1032
|
+
list(filter?: JobFilter): Promise<JobHandle[]>;
|
|
1033
|
+
/**
|
|
1034
|
+
* Execute a job (called by worker).
|
|
1035
|
+
*
|
|
1036
|
+
* @internal
|
|
1037
|
+
*/
|
|
1038
|
+
executeJob(jobId: string): Promise<void>;
|
|
1039
|
+
/**
|
|
1040
|
+
* Update job progress.
|
|
1041
|
+
*
|
|
1042
|
+
* Called by job handler via ctx.updateProgress()
|
|
1043
|
+
*/
|
|
1044
|
+
updateProgress(jobId: string, percent: number, message?: string): Promise<void>;
|
|
1045
|
+
private handleJobFailure;
|
|
1046
|
+
private markJobFailed;
|
|
1047
|
+
private calculateBackoff;
|
|
1048
|
+
private saveJobRecord;
|
|
1049
|
+
private getJobRecord;
|
|
1050
|
+
private enqueueJob;
|
|
1051
|
+
private removeFromQueue;
|
|
1052
|
+
private findByIdempotencyKey;
|
|
1053
|
+
private getAllJobKeys;
|
|
1054
|
+
private jobRecordToHandle;
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
export { type AcquireOptions, ArtifactMerger, type ArtifactMergerOptions, ConcurrencyManager, type CreateRunInput, type EngineLogger, EnvSecretProvider, type EnvSecretProviderOptions, EventBusBridge, JobManager, type JobManagerConfig, type JobQueueEntry, ManifestScanner, type ManifestScannerOptions, type RetryDecision, type RunContext, RunCoordinator, type RunCoordinatorOptions, type RunSnapshot, RunSnapshotStorage, Scheduler, type SchedulerOptions, type SecretProvider, StateStore, type ValidationResult, WorkflowEngine, type WorkflowEngineOptions, type WorkflowEvent, type WorkflowExecutor, type WorkflowHandlerInfo, type WorkflowListOptions, WorkflowLoader, type WorkflowLoaderOptions, type WorkflowLoaderResult, WorkflowRegistry, type WorkflowRegistryEntry, type WorkflowRegistryOptions, WorkflowRepository, type WorkflowRepositoryOptions, type WorkflowRuntime, type WorkflowSchedule, WorkflowScheduleManager, type WorkflowScheduleManagerOptions, WorkflowService, type WorkflowServiceListOptions, type WorkflowServiceOptions, type WorkflowStats, type WorkflowTrigger, type WorkflowTriggerType, calculateBackoff, createDefaultSecretProvider, shouldRetry };
|