@db-lyon/flowkit 0.11.1 → 0.11.2
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 +1 -1
- package/docs/ai-agents.md +368 -0
- package/docs/api-reference.md +430 -0
- package/docs/configuration.md +343 -0
- package/docs/custom-tasks.md +203 -0
- package/docs/getting-started.md +172 -0
- package/package.json +3 -2
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
# API reference
|
|
2
|
+
|
|
3
|
+
Complete reference for all public exports from `@db-lyon/flowkit`.
|
|
4
|
+
|
|
5
|
+
## Config
|
|
6
|
+
|
|
7
|
+
*Import from `@db-lyon/flowkit` or `@db-lyon/flowkit/config`*
|
|
8
|
+
|
|
9
|
+
### `loadConfig(options)`
|
|
10
|
+
|
|
11
|
+
Load, layer, and validate YAML configuration files.
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
function loadConfig<T extends z.ZodType>(
|
|
15
|
+
options: LoadConfigOptions<T>,
|
|
16
|
+
): LoadedConfig<z.infer<T>>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**`LoadConfigOptions<T>`**
|
|
20
|
+
|
|
21
|
+
| Field | Type | Required | Description |
|
|
22
|
+
|-------|------|----------|-------------|
|
|
23
|
+
| `filename` | `string` | yes | Primary config filename (e.g., `'app.yml'`) |
|
|
24
|
+
| `schema` | `z.ZodType` | yes | Zod schema applied after merging all layers |
|
|
25
|
+
| `defaults` | `unknown` | no | Built-in defaults merged under the project file |
|
|
26
|
+
| `env` | `string` | no | Environment name — loads `{base}.{env}.{ext}` overlay |
|
|
27
|
+
| `envVar` | `string` | no | Env var to read environment name from when `env` is not passed |
|
|
28
|
+
| `configDir` | `string` | no | Directory to search (default: `process.cwd()`) |
|
|
29
|
+
|
|
30
|
+
**`LoadedConfig<T>`**
|
|
31
|
+
|
|
32
|
+
| Field | Type | Description |
|
|
33
|
+
|-------|------|-------------|
|
|
34
|
+
| `config` | `T` | The validated, merged configuration object |
|
|
35
|
+
| `configDir` | `string` | The directory the config was loaded from |
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
### `findConfigFile(filename, startDir?)`
|
|
40
|
+
|
|
41
|
+
Walk up parent directories looking for a file by name.
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
function findConfigFile(filename: string, startDir?: string): string
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Returns the absolute path. Throws if not found.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
### `loadRawYaml(filePath)`
|
|
52
|
+
|
|
53
|
+
Parse a YAML file and return the raw result (no schema validation).
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
function loadRawYaml(filePath: string): unknown
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
### `deepMerge(base, override)`
|
|
62
|
+
|
|
63
|
+
Recursively merge two values. Objects merge key-by-key, arrays replace (unless `__merge: 'append'`), scalars override, `null` nullifies, `undefined` is a no-op.
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
function deepMerge(base: unknown, override: unknown): unknown
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
### Zod schemas
|
|
72
|
+
|
|
73
|
+
| Schema | Validates |
|
|
74
|
+
|--------|-----------|
|
|
75
|
+
| `TaskOptionsSchema` | `Record<string, unknown>` |
|
|
76
|
+
| `TaskDefinitionSchema` | Task definition object |
|
|
77
|
+
| `FlowStepSchema` | Single flow step (task xor flow) |
|
|
78
|
+
| `FlowDefinitionSchema` | Flow with description and steps |
|
|
79
|
+
| `EngineConfigSchema` | Top-level config with `tasks` and `flows` |
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
### Config types
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
type TaskOptions = Record<string, unknown>;
|
|
87
|
+
|
|
88
|
+
type TaskDefinition = {
|
|
89
|
+
class_path: string;
|
|
90
|
+
description?: string;
|
|
91
|
+
group?: string;
|
|
92
|
+
options: TaskOptions; // defaults to {}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
type FlowStep = {
|
|
96
|
+
task?: string;
|
|
97
|
+
flow?: string;
|
|
98
|
+
options?: TaskOptions;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
type FlowDefinition = {
|
|
102
|
+
description: string;
|
|
103
|
+
steps: Record<string, FlowStep>;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
type EngineConfig = {
|
|
107
|
+
tasks: Record<string, TaskDefinition>;
|
|
108
|
+
flows: Record<string, FlowDefinition>;
|
|
109
|
+
};
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Task
|
|
115
|
+
|
|
116
|
+
*Import from `@db-lyon/flowkit` or `@db-lyon/flowkit/task`*
|
|
117
|
+
|
|
118
|
+
### `BaseTask<TOpts>`
|
|
119
|
+
|
|
120
|
+
Abstract base class for all tasks.
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
abstract class BaseTask<TOpts = Record<string, unknown>> {
|
|
124
|
+
protected ctx: TaskContext;
|
|
125
|
+
protected options: TOpts;
|
|
126
|
+
protected logger: Logger;
|
|
127
|
+
|
|
128
|
+
constructor(ctx: TaskContext, options: TOpts);
|
|
129
|
+
|
|
130
|
+
abstract get taskName(): string;
|
|
131
|
+
abstract execute(): Promise<TaskResult>;
|
|
132
|
+
protected validate(): void;
|
|
133
|
+
async run(): Promise<TaskResult>;
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
| Method | Description |
|
|
138
|
+
|--------|-------------|
|
|
139
|
+
| `taskName` | (getter) Human-readable name for logging |
|
|
140
|
+
| `execute()` | Perform the task's work. Return a `TaskResult`. |
|
|
141
|
+
| `validate()` | Optional. Called before `execute()`. Throw to abort. |
|
|
142
|
+
| `run()` | Lifecycle wrapper: validate → execute → catch errors → add duration. Called by the flow runner. |
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### `TaskContext`
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
interface TaskContext {
|
|
150
|
+
logger?: Logger;
|
|
151
|
+
[key: string]: unknown;
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Shared context passed to every task. Add any properties you need (database connections, API clients, etc.).
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
### `TaskResult`
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
interface TaskResult {
|
|
163
|
+
success: boolean;
|
|
164
|
+
data?: Record<string, unknown>;
|
|
165
|
+
error?: Error;
|
|
166
|
+
duration?: number; // milliseconds, set by run()
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
### `ShellTask`
|
|
173
|
+
|
|
174
|
+
Built-in task that executes shell commands via `execSync`.
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
class ShellTask extends BaseTask<ShellTaskOptions> {
|
|
178
|
+
get taskName(): string; // "shell:{command}"
|
|
179
|
+
protected validate(): void; // requires command
|
|
180
|
+
async execute(): Promise<TaskResult>;
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**`ShellTaskOptions`**
|
|
185
|
+
|
|
186
|
+
| Field | Type | Default | Description |
|
|
187
|
+
|-------|------|---------|-------------|
|
|
188
|
+
| `command` | `string` | (required) | Shell command to execute |
|
|
189
|
+
| `cwd` | `string` | `undefined` | Working directory |
|
|
190
|
+
| `timeout` | `number` | `300000` | Timeout in milliseconds (5 min) |
|
|
191
|
+
|
|
192
|
+
**Success result:** `data.output` contains trimmed stdout.
|
|
193
|
+
|
|
194
|
+
**Failure result:** `data.exitCode`, `data.stderr`, `data.stdout`.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
### `TaskRegistry`
|
|
199
|
+
|
|
200
|
+
Registry that maps names and class paths to task constructors.
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
class TaskRegistry {
|
|
204
|
+
register(name: string, ctor: TaskConstructor): this;
|
|
205
|
+
registerClassPath(classPath: string, ctor: TaskConstructor): this;
|
|
206
|
+
registerAll(entries: Record<string, TaskConstructor>): this;
|
|
207
|
+
registerClassPaths(entries: Record<string, TaskConstructor>): this;
|
|
208
|
+
async resolve(classPathOrName: string): Promise<TaskConstructor>;
|
|
209
|
+
async create(
|
|
210
|
+
classPathOrName: string,
|
|
211
|
+
ctx: TaskContext,
|
|
212
|
+
options: Record<string, unknown>,
|
|
213
|
+
): Promise<BaseTask>;
|
|
214
|
+
listRegistered(): string[];
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
| Method | Description |
|
|
219
|
+
|--------|-------------|
|
|
220
|
+
| `register(name, ctor)` | Register by short name |
|
|
221
|
+
| `registerClassPath(path, ctor)` | Register by dotted class path |
|
|
222
|
+
| `registerAll(entries)` | Bulk register by short name |
|
|
223
|
+
| `registerClassPaths(entries)` | Bulk register by class path |
|
|
224
|
+
| `resolve(nameOrPath)` | Look up a constructor. Falls back to dynamic filesystem import. |
|
|
225
|
+
| `create(nameOrPath, ctx, opts)` | Resolve + instantiate in one call |
|
|
226
|
+
| `listRegistered()` | Return all registered names and class paths |
|
|
227
|
+
|
|
228
|
+
**`TaskConstructor`**
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
type TaskConstructor = new (
|
|
232
|
+
ctx: TaskContext,
|
|
233
|
+
options: Record<string, unknown>,
|
|
234
|
+
) => BaseTask;
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Flow
|
|
240
|
+
|
|
241
|
+
*Import from `@db-lyon/flowkit` or `@db-lyon/flowkit/flow`*
|
|
242
|
+
|
|
243
|
+
### `FlowRunner`
|
|
244
|
+
|
|
245
|
+
Orchestration engine that executes flows.
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
class FlowRunner {
|
|
249
|
+
constructor(config: FlowRunnerConfig);
|
|
250
|
+
async run(options: FlowRunOptions): Promise<FlowRunResult>;
|
|
251
|
+
resolveExecutionPlan(
|
|
252
|
+
flow: FlowDefinition,
|
|
253
|
+
skipSet: Set<string>,
|
|
254
|
+
): PlanStep[];
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
### `FlowRunnerConfig`
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
interface FlowRunnerConfig {
|
|
264
|
+
tasks: Record<string, TaskDefinition>;
|
|
265
|
+
flows: Record<string, FlowDefinition>;
|
|
266
|
+
registry: TaskRegistry;
|
|
267
|
+
context: TaskContext;
|
|
268
|
+
hooks?: FlowRunnerHooks;
|
|
269
|
+
logger?: Logger;
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
### `FlowRunOptions`
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
interface FlowRunOptions {
|
|
279
|
+
flowName: string; // name of the flow to execute
|
|
280
|
+
skip?: string[]; // task names or step numbers to skip
|
|
281
|
+
plan?: boolean; // return plan without executing
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
### `FlowRunResult`
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
interface FlowRunResult {
|
|
291
|
+
success: boolean;
|
|
292
|
+
steps: FlowStepResult[];
|
|
293
|
+
duration: number; // total milliseconds
|
|
294
|
+
error?: Error; // first error that caused failure
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
### `FlowStepResult`
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
interface FlowStepResult {
|
|
304
|
+
stepNumber: number;
|
|
305
|
+
type: 'task' | 'flow';
|
|
306
|
+
name: string;
|
|
307
|
+
result?: TaskResult;
|
|
308
|
+
skipped: boolean;
|
|
309
|
+
duration: number; // milliseconds
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
### `PlanStep`
|
|
316
|
+
|
|
317
|
+
Represents a step in the execution plan (returned by plan mode or passed to hooks).
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
interface PlanStep {
|
|
321
|
+
stepNumber: number;
|
|
322
|
+
type: 'task' | 'flow';
|
|
323
|
+
name: string;
|
|
324
|
+
skipped: boolean;
|
|
325
|
+
options?: Record<string, unknown>;
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
### `FlowRunnerHooks`
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
interface FlowRunnerHooks {
|
|
335
|
+
beforeRun?(flowName: string, plan: PlanStep[]): Promise<void>;
|
|
336
|
+
afterRun?(result: FlowRunResult): Promise<void>;
|
|
337
|
+
beforeStep?(step: PlanStep): Promise<void>;
|
|
338
|
+
afterStep?(step: PlanStep, result: FlowStepResult): Promise<void>;
|
|
339
|
+
onStepError?(
|
|
340
|
+
step: PlanStep,
|
|
341
|
+
error: Error,
|
|
342
|
+
completed: FlowStepResult[],
|
|
343
|
+
): Promise<void>;
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
| Hook | Fires | Scope |
|
|
348
|
+
|------|-------|-------|
|
|
349
|
+
| `beforeRun` | Once before execution starts | Top-level flow only |
|
|
350
|
+
| `afterRun` | Once after execution completes | Top-level flow only |
|
|
351
|
+
| `beforeStep` | Before each step executes | All steps (including nested) |
|
|
352
|
+
| `afterStep` | After each step completes | All steps (including nested) |
|
|
353
|
+
| `onStepError` | When a step fails | All steps (including nested) |
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## DAG
|
|
358
|
+
|
|
359
|
+
*Import from `@db-lyon/flowkit` or `@db-lyon/flowkit/dag`*
|
|
360
|
+
|
|
361
|
+
### `topologicalSort(nodes)`
|
|
362
|
+
|
|
363
|
+
Sort a directed acyclic graph in dependency order (dependencies first).
|
|
364
|
+
|
|
365
|
+
```typescript
|
|
366
|
+
function topologicalSort<T>(nodes: DagNode<T>[]): DagNode<T>[]
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
Throws `CircularDependencyError` if the graph has cycles. Throws `MissingDependencyError` if a node references a dependency that doesn't exist.
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
### `DagNode<T>`
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
interface DagNode<T = unknown> {
|
|
377
|
+
id: string;
|
|
378
|
+
dependencies: string[];
|
|
379
|
+
data: T;
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
### `CircularDependencyError`
|
|
386
|
+
|
|
387
|
+
```typescript
|
|
388
|
+
class CircularDependencyError extends Error {
|
|
389
|
+
cycle: string[]; // e.g., ['a', 'b', 'c', 'a']
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
### `MissingDependencyError`
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
class MissingDependencyError extends Error {
|
|
399
|
+
nodeId: string; // the node that has the bad dependency
|
|
400
|
+
missingDep: string; // the dependency that doesn't exist
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## Logger
|
|
407
|
+
|
|
408
|
+
*Import from `@db-lyon/flowkit`*
|
|
409
|
+
|
|
410
|
+
### `Logger` interface
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
interface Logger {
|
|
414
|
+
debug(...args: unknown[]): void;
|
|
415
|
+
info(...args: unknown[]): void;
|
|
416
|
+
warn(...args: unknown[]): void;
|
|
417
|
+
error(...args: unknown[]): void;
|
|
418
|
+
child(bindings: Record<string, unknown>): Logger;
|
|
419
|
+
}
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
Compatible with pino, winston, and similar structured loggers.
|
|
423
|
+
|
|
424
|
+
### `noopLogger`
|
|
425
|
+
|
|
426
|
+
A silent logger that discards all output. Used as the default when no logger is provided.
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
const noopLogger: Logger;
|
|
430
|
+
```
|