@db-lyon/flowkit 0.17.2 → 0.18.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 +53 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/config/index.d.ts +4 -2
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +2 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/loader.d.ts +11 -0
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +4 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/schema.d.ts +1486 -79
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +125 -8
- package/dist/config/schema.js.map +1 -1
- package/dist/config/strict.d.ts +40 -0
- package/dist/config/strict.d.ts.map +1 -0
- package/dist/config/strict.js +146 -0
- package/dist/config/strict.js.map +1 -0
- package/dist/flow/index.d.ts +2 -2
- package/dist/flow/index.d.ts.map +1 -1
- package/dist/flow/index.js +1 -1
- package/dist/flow/index.js.map +1 -1
- package/dist/flow/runner.d.ts +279 -6
- package/dist/flow/runner.d.ts.map +1 -1
- package/dist/flow/runner.js +845 -40
- package/dist/flow/runner.js.map +1 -1
- package/dist/index.d.ts +13 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/task/base-task.d.ts +55 -1
- package/dist/task/base-task.d.ts.map +1 -1
- package/dist/task/base-task.js +39 -0
- package/dist/task/base-task.js.map +1 -1
- package/dist/task/composite.d.ts +66 -0
- package/dist/task/composite.d.ts.map +1 -0
- package/dist/task/composite.js +21 -0
- package/dist/task/composite.js.map +1 -0
- package/dist/task/index.d.ts +7 -1
- package/dist/task/index.d.ts.map +1 -1
- package/dist/task/index.js +3 -0
- package/dist/task/index.js.map +1 -1
- package/dist/task/options-schema.d.ts +51 -0
- package/dist/task/options-schema.d.ts.map +1 -0
- package/dist/task/options-schema.js +102 -0
- package/dist/task/options-schema.js.map +1 -0
- package/dist/task/registry.d.ts +39 -1
- package/dist/task/registry.d.ts.map +1 -1
- package/dist/task/registry.js +44 -2
- package/dist/task/registry.js.map +1 -1
- package/dist/task/warnings.d.ts +25 -0
- package/dist/task/warnings.d.ts.map +1 -0
- package/dist/task/warnings.js +30 -0
- package/dist/task/warnings.js.map +1 -0
- package/docs/api-reference.md +273 -0
- package/docs/configuration.md +262 -1
- package/docs/custom-tasks.md +155 -0
- package/docs/releases.md +47 -0
- package/package.json +1 -1
package/docs/api-reference.md
CHANGED
|
@@ -26,6 +26,7 @@ function loadConfig<T extends z.ZodType>(
|
|
|
26
26
|
| `env` | `string` | no | Environment name — loads `{base}.{env}.{ext}` overlay |
|
|
27
27
|
| `envVar` | `string` | no | Env var to read environment name from when `env` is not passed |
|
|
28
28
|
| `configDir` | `string` | no | Directory to search (default: `process.cwd()`) |
|
|
29
|
+
| `strict` | `boolean \| { passthroughKeys?: string[] }` | no | Reject keys the schema does not declare, with an `UnknownConfigKeyError`. Off by default. See [Strict validation](configuration.md#strict-validation) |
|
|
29
30
|
|
|
30
31
|
**`LoadedConfig<T>`**
|
|
31
32
|
|
|
@@ -36,6 +37,31 @@ function loadConfig<T extends z.ZodType>(
|
|
|
36
37
|
|
|
37
38
|
---
|
|
38
39
|
|
|
40
|
+
### `findUnknownKeys(schema, value, options?)` / `assertKnownKeys(schema, value, options?)`
|
|
41
|
+
|
|
42
|
+
The check behind `loadConfig({ strict })`, for config that does not come
|
|
43
|
+
through the loader.
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
interface UnknownConfigKey {
|
|
47
|
+
path: string; // e.g. 'flows.ci.steps.2.retires', 'tasks["asset.list"].x'
|
|
48
|
+
key: string;
|
|
49
|
+
suggestion?: string; // nearest declared key, when close enough to be a typo
|
|
50
|
+
}
|
|
51
|
+
interface FindUnknownKeysOptions {
|
|
52
|
+
passthroughKeys?: readonly string[]; // top-level keys left unchecked
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function findUnknownKeys(schema: z.ZodTypeAny, value: unknown, options?: FindUnknownKeysOptions): UnknownConfigKey[];
|
|
56
|
+
function assertKnownKeys(schema: z.ZodTypeAny, value: unknown, options?: FindUnknownKeysOptions): void; // throws UnknownConfigKeyError
|
|
57
|
+
|
|
58
|
+
class UnknownConfigKeyError extends Error {
|
|
59
|
+
readonly keys: UnknownConfigKey[];
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
39
65
|
### `findConfigFile(filename, startDir?)`
|
|
40
66
|
|
|
41
67
|
Walk up parent directories looking for a file by name.
|
|
@@ -75,9 +101,23 @@ function deepMerge(base: unknown, override: unknown): unknown
|
|
|
75
101
|
| `TaskOptionsSchema` | `Record<string, unknown>` |
|
|
76
102
|
| `TaskDefinitionSchema` | Task definition object |
|
|
77
103
|
| `FlowStepSchema` | Single flow step (task xor flow) |
|
|
104
|
+
| `FlowStepObjectSchema` | The same step fields as an unrefined `z.object`, for hosts to `.extend()` |
|
|
105
|
+
| `FlowStepsSchema` | A `steps:` map keyed by step number |
|
|
78
106
|
| `FlowDefinitionSchema` | Flow with description and steps |
|
|
79
107
|
| `EngineConfigSchema` | Top-level config with `tasks` and `flows` |
|
|
80
108
|
|
|
109
|
+
`refineFlowStep(schema)` applies the step target rule (exactly one of `task`
|
|
110
|
+
or `flow`, or a `None` skip) to any step object schema, so a host manifest can
|
|
111
|
+
reuse every step field the runner understands and add its own:
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
import { FlowStepObjectSchema, refineFlowStep } from '@db-lyon/flowkit';
|
|
115
|
+
|
|
116
|
+
const ManifestStepSchema = refineFlowStep(
|
|
117
|
+
FlowStepObjectSchema.extend({ label: z.string().optional() }),
|
|
118
|
+
);
|
|
119
|
+
```
|
|
120
|
+
|
|
81
121
|
---
|
|
82
122
|
|
|
83
123
|
### Config types
|
|
@@ -131,9 +171,46 @@ abstract class BaseTask<TOpts = Record<string, unknown>> {
|
|
|
131
171
|
abstract execute(): Promise<TaskResult>;
|
|
132
172
|
protected validate(): void;
|
|
133
173
|
async run(): Promise<TaskResult>;
|
|
174
|
+
protected resolve<T extends BaseTask>(taskName: string, options?: Record<string, unknown>): Promise<T>;
|
|
175
|
+
protected call(taskName: string, options?: Record<string, unknown>): Promise<TaskResult>;
|
|
176
|
+
protected step(
|
|
177
|
+
target: ChildStepTarget,
|
|
178
|
+
options?: Record<string, unknown>,
|
|
179
|
+
spec?: ChildStepSpec,
|
|
180
|
+
): Promise<TaskResult>;
|
|
181
|
+
|
|
182
|
+
// Optional class-level declarations
|
|
183
|
+
static optionsSchema?: OptionSpecs;
|
|
184
|
+
static outputs?: OutputSpecs;
|
|
185
|
+
static description?: string;
|
|
186
|
+
static deprecated?: boolean | string;
|
|
187
|
+
static replacedBy?: string;
|
|
188
|
+
static expand?: ExpandFunction;
|
|
134
189
|
}
|
|
190
|
+
|
|
191
|
+
type ChildStepTarget = string | { task: string } | { flow: string };
|
|
192
|
+
interface ChildStepSpec { retries?: number; retryDelay?: number; retryOn?: string }
|
|
193
|
+
type ChildPlanEntry =
|
|
194
|
+
| { task: string; options?: Record<string, unknown> }
|
|
195
|
+
| { flow: string; options?: Record<string, unknown> };
|
|
196
|
+
interface ExpandContext {
|
|
197
|
+
taskName: string;
|
|
198
|
+
taskDefinitions: Record<string, TaskDefinition>;
|
|
199
|
+
flows: Record<string, FlowDefinition>;
|
|
200
|
+
references?: Record<string, unknown>;
|
|
201
|
+
}
|
|
202
|
+
type ExpandFunction = (
|
|
203
|
+
options: Record<string, unknown>,
|
|
204
|
+
ctx: ExpandContext,
|
|
205
|
+
) => ChildPlanEntry[] | null | Promise<ChildPlanEntry[] | null>;
|
|
206
|
+
|
|
207
|
+
// Every rollback record in a result tree, children first; invoke in reverse.
|
|
208
|
+
function collectRollbackRecords(result: TaskResult): RollbackRecord[];
|
|
135
209
|
```
|
|
136
210
|
|
|
211
|
+
`step()` runs a composite child through the runner (`ctx.step`); see
|
|
212
|
+
[Composite tasks](custom-tasks.md#composite-tasks).
|
|
213
|
+
|
|
137
214
|
| Method | Description |
|
|
138
215
|
|--------|-------------|
|
|
139
216
|
| `taskName` | (getter) Human-readable name for logging |
|
|
@@ -159,6 +236,8 @@ interface TaskContext {
|
|
|
159
236
|
logger?: Logger;
|
|
160
237
|
/** Cancels LLM work and retry backoff owned by this task invocation. */
|
|
161
238
|
readonly signal?: AbortSignal;
|
|
239
|
+
/** Run one composite child through the runner. Supplied by FlowRunner. */
|
|
240
|
+
step?: (target: ChildStepTarget, options?: Record<string, unknown>, spec?: ChildStepSpec) => Promise<TaskResult>;
|
|
162
241
|
[key: string]: unknown;
|
|
163
242
|
}
|
|
164
243
|
|
|
@@ -204,9 +283,25 @@ interface TaskResult {
|
|
|
204
283
|
data?: Record<string, unknown>;
|
|
205
284
|
error?: Error;
|
|
206
285
|
duration?: number; // milliseconds, set by run()
|
|
286
|
+
rollback?: RollbackRecord;
|
|
287
|
+
warnings?: RunWarning[]; // non-fatal notices; the runner appends deprecation warnings
|
|
288
|
+
children?: FlowStepResult[]; // composite child steps run through ctx.step, set by the runner
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
interface RunWarning {
|
|
292
|
+
code: 'deprecated' | 'check';
|
|
293
|
+
message: string;
|
|
294
|
+
name: string; // the task or flow it is about
|
|
295
|
+
kind?: 'task' | 'flow';
|
|
296
|
+
replacedBy?: string; // for 'deprecated'
|
|
297
|
+
stepNumber?: number; // for 'check'
|
|
207
298
|
}
|
|
208
299
|
```
|
|
209
300
|
|
|
301
|
+
`deprecationWarning(kind, name, deprecated, replacedBy)` builds the
|
|
302
|
+
`deprecated` warning (or returns `undefined`), and `mergeWarnings(...lists)`
|
|
303
|
+
concatenates lists without repeats, for a host that assembles its own.
|
|
304
|
+
|
|
210
305
|
---
|
|
211
306
|
|
|
212
307
|
### `ShellTask`
|
|
@@ -280,6 +375,10 @@ class TaskRegistry {
|
|
|
280
375
|
options: Record<string, unknown>,
|
|
281
376
|
): Promise<BaseTask>;
|
|
282
377
|
listRegistered(): string[];
|
|
378
|
+
async describe(
|
|
379
|
+
name: string,
|
|
380
|
+
taskDefinitions?: Record<string, TaskDefinition>,
|
|
381
|
+
): Promise<TaskDescription>;
|
|
283
382
|
}
|
|
284
383
|
```
|
|
285
384
|
|
|
@@ -292,6 +391,56 @@ class TaskRegistry {
|
|
|
292
391
|
| `resolve(nameOrPath)` | Look up a constructor. Falls back to dynamic filesystem import. |
|
|
293
392
|
| `create(nameOrPath, ctx, opts)` | Resolve + instantiate in one call; omitted phase defaults to `task` |
|
|
294
393
|
| `listRegistered()` | Return all registered names and class paths |
|
|
394
|
+
| `describe(name, defs?)` | Class metadata folded with the configured definition. See below |
|
|
395
|
+
|
|
396
|
+
**`TaskDescription`**
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
interface TaskDescription {
|
|
400
|
+
name: string;
|
|
401
|
+
class_path: string;
|
|
402
|
+
description?: string; // definition, else the class's static description
|
|
403
|
+
group?: string;
|
|
404
|
+
options: Record<string, unknown>; // schema defaults, then definition options (uninterpolated)
|
|
405
|
+
options_schema?: OptionSpecs; // class optionsSchema refined by definition options_schema
|
|
406
|
+
outputs?: OutputSpecs;
|
|
407
|
+
idempotent?: boolean;
|
|
408
|
+
reversible?: boolean;
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
**Option schemas**
|
|
413
|
+
|
|
414
|
+
```typescript
|
|
415
|
+
type OptionSpecs = Record<string, OptionSpec>;
|
|
416
|
+
interface OptionSpec {
|
|
417
|
+
type?: OptionType | OptionType[]; // 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array' | 'null'
|
|
418
|
+
description?: string;
|
|
419
|
+
required?: boolean;
|
|
420
|
+
default?: unknown;
|
|
421
|
+
enum?: unknown[];
|
|
422
|
+
const?: unknown;
|
|
423
|
+
minimum?: number; maximum?: number; exclusiveMinimum?: number; exclusiveMaximum?: number;
|
|
424
|
+
minLength?: number; maxLength?: number; pattern?: string;
|
|
425
|
+
minItems?: number; maxItems?: number; items?: Record<string, unknown>;
|
|
426
|
+
properties?: Record<string, unknown>; additionalProperties?: boolean | Record<string, unknown>;
|
|
427
|
+
nullable?: boolean;
|
|
428
|
+
}
|
|
429
|
+
type OutputSpecs = Record<string, { type?: OptionType | OptionType[]; description?: string; items?: object; properties?: object }>;
|
|
430
|
+
|
|
431
|
+
class TaskOptionsError extends Error {
|
|
432
|
+
readonly taskName: string;
|
|
433
|
+
readonly issues: { option: string; message: string }[];
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
function validateTaskOptions(specs: OptionSpecs | undefined, options: Record<string, unknown>): TaskOptionIssue[];
|
|
437
|
+
function assertTaskOptions(taskName: string, specs: OptionSpecs | undefined, options: Record<string, unknown>): Record<string, unknown>; // defaults applied; throws TaskOptionsError
|
|
438
|
+
function applyOptionDefaults(specs: OptionSpecs | undefined, options: Record<string, unknown>): Record<string, unknown>;
|
|
439
|
+
function mergeOptionSpecs(base?: OptionSpecs, override?: OptionSpecs): OptionSpecs | undefined;
|
|
440
|
+
function taskClassMetadata(ctor: unknown): TaskClassMetadata; // { description?, optionsSchema?, outputs? }
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
Zod: `OptionSpecSchema`, `OptionSpecsSchema`, `OutputSpecSchema`, `OutputSpecsSchema`.
|
|
295
444
|
|
|
296
445
|
**`TaskConstructor`**
|
|
297
446
|
|
|
@@ -321,6 +470,16 @@ Orchestration engine that executes flows.
|
|
|
321
470
|
class FlowRunner {
|
|
322
471
|
constructor(config: FlowRunnerConfig);
|
|
323
472
|
async run(options: FlowRunOptions): Promise<FlowRunResult>;
|
|
473
|
+
async runTask(taskName: string, options?: Record<string, unknown>): Promise<TaskResult>;
|
|
474
|
+
async describeTask(taskName: string): Promise<TaskDescription>;
|
|
475
|
+
describeFlow(flowName: string): FlowDescription;
|
|
476
|
+
checkStepReferences(flowName: string): StepReferenceIssue[];
|
|
477
|
+
async expandTask(taskName: string, options?: Record<string, unknown>): Promise<ChildPlanEntry[] | null>;
|
|
478
|
+
async preflight(
|
|
479
|
+
flowName: string,
|
|
480
|
+
params?: Record<string, unknown>,
|
|
481
|
+
options?: { skip?: string[] },
|
|
482
|
+
): Promise<PreflightResult>;
|
|
324
483
|
resolveExecutionPlan(
|
|
325
484
|
flow: FlowDefinition,
|
|
326
485
|
skipSet: Set<string>,
|
|
@@ -330,6 +489,92 @@ class FlowRunner {
|
|
|
330
489
|
|
|
331
490
|
---
|
|
332
491
|
|
|
492
|
+
**`StepReferenceIssue`**
|
|
493
|
+
|
|
494
|
+
```typescript
|
|
495
|
+
interface StepReferenceIssue {
|
|
496
|
+
flowName: string;
|
|
497
|
+
stepNumber: number;
|
|
498
|
+
phase?: HookPhase;
|
|
499
|
+
reference: string; // e.g. '${steps.deploy.url}'
|
|
500
|
+
kind: 'ambiguous' | 'unknown' | 'forward';
|
|
501
|
+
message: string;
|
|
502
|
+
}
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
**Checks and preflight**
|
|
506
|
+
|
|
507
|
+
```typescript
|
|
508
|
+
type StepCheck = { when: string | boolean; action: 'error' | 'warn' | 'skip'; message?: string };
|
|
509
|
+
|
|
510
|
+
interface CheckOutcome {
|
|
511
|
+
scope: 'flow' | 'step';
|
|
512
|
+
flowName: string;
|
|
513
|
+
stepNumber?: number;
|
|
514
|
+
name?: string;
|
|
515
|
+
path?: string;
|
|
516
|
+
when: string | boolean;
|
|
517
|
+
action: 'error' | 'warn' | 'skip';
|
|
518
|
+
message: string; // declared, or one naming the condition
|
|
519
|
+
triggered: boolean; // the condition was truthy
|
|
520
|
+
error?: Error; // the evaluator threw
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
class CheckFailedError extends Error {
|
|
524
|
+
readonly outcome: CheckOutcome;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
interface PreflightResult {
|
|
528
|
+
flowName: string;
|
|
529
|
+
ok: boolean; // no `error` check fired
|
|
530
|
+
checks: CheckOutcome[]; // the flow's own
|
|
531
|
+
steps: PreflightStep[];
|
|
532
|
+
warnings?: RunWarning[]; // fired `warn` checks, deprecations
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
interface PreflightStep {
|
|
536
|
+
stepNumber: number;
|
|
537
|
+
type: 'task' | 'flow';
|
|
538
|
+
name: string;
|
|
539
|
+
path: string; // '2/1', or '<phase>/<n>' for hooks
|
|
540
|
+
depth: number;
|
|
541
|
+
phase?: HookPhase;
|
|
542
|
+
status: 'run' | 'skip' | 'error' | 'unknown';
|
|
543
|
+
skipReason?: 'static' | 'check';
|
|
544
|
+
checks: CheckOutcome[];
|
|
545
|
+
deprecated?: boolean | string;
|
|
546
|
+
replaced_by?: string;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
interface ConditionContext {
|
|
550
|
+
steps: FlowStepResult[];
|
|
551
|
+
params?: Record<string, unknown>;
|
|
552
|
+
context: TaskContext;
|
|
553
|
+
error?: { message: string; name: string; stack?: string; step?: string };
|
|
554
|
+
references?: Record<string, unknown>; // FlowRunnerConfig.references
|
|
555
|
+
step?: PlanStep; // the step being gated
|
|
556
|
+
check?: StepCheck; // set when evaluating a check
|
|
557
|
+
flowName?: string;
|
|
558
|
+
}
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
**`FlowDescription`**
|
|
562
|
+
|
|
563
|
+
```typescript
|
|
564
|
+
interface FlowDescription {
|
|
565
|
+
name: string;
|
|
566
|
+
description?: string;
|
|
567
|
+
deprecated?: boolean | string;
|
|
568
|
+
replaced_by?: string;
|
|
569
|
+
rollback_on_failure?: boolean;
|
|
570
|
+
options_scope?: 'flat' | 'step';
|
|
571
|
+
checks?: StepCheck[];
|
|
572
|
+
steps: PlanStep[]; // main steps in run order
|
|
573
|
+
}
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
---
|
|
577
|
+
|
|
333
578
|
### `FlowRunnerConfig`
|
|
334
579
|
|
|
335
580
|
```typescript
|
|
@@ -344,6 +589,8 @@ interface FlowRunnerConfig {
|
|
|
344
589
|
references?: Record<string, unknown>;
|
|
345
590
|
agents?: Record<string, AgentDefinition>;
|
|
346
591
|
nestedAgentTaskFactory?: NestedAgentTaskFactory;
|
|
592
|
+
optionsScope?: 'flat' | 'step'; // default for how `params` reach steps; default 'flat'
|
|
593
|
+
strictStepReferences?: boolean; // refuse ambiguous/unknown/forward ${steps.x}; default false
|
|
347
594
|
}
|
|
348
595
|
```
|
|
349
596
|
|
|
@@ -380,6 +627,11 @@ interface FlowRunOptions {
|
|
|
380
627
|
flowName: string; // name of the flow to execute
|
|
381
628
|
skip?: string[]; // task names or step numbers to skip
|
|
382
629
|
plan?: boolean; // return plan without executing
|
|
630
|
+
params?: Record<string, unknown>; // runtime options, highest precedence
|
|
631
|
+
optionsScope?: 'flat' | 'step'; // how `params` are addressed; see configuration.md
|
|
632
|
+
rollback_on_failure?: boolean;
|
|
633
|
+
expandNestedFlows?: boolean; // plan mode: expand nested flows into child rows
|
|
634
|
+
expandComposites?: boolean; // plan mode: list composite children from static expand()
|
|
383
635
|
}
|
|
384
636
|
```
|
|
385
637
|
|
|
@@ -393,6 +645,10 @@ interface FlowRunResult {
|
|
|
393
645
|
steps: FlowStepResult[];
|
|
394
646
|
duration: number; // total milliseconds
|
|
395
647
|
error?: Error; // first error that caused failure
|
|
648
|
+
hookErrors?: HookError[];
|
|
649
|
+
rollback?: RollbackResult;
|
|
650
|
+
warnings?: RunWarning[]; // deprecations and fired `warn` checks, without repeats
|
|
651
|
+
checks?: CheckOutcome[]; // every check that fired, nested flows included
|
|
396
652
|
}
|
|
397
653
|
```
|
|
398
654
|
|
|
@@ -408,7 +664,12 @@ interface FlowStepResult {
|
|
|
408
664
|
result?: TaskResult;
|
|
409
665
|
skipped: boolean;
|
|
410
666
|
duration: number; // milliseconds
|
|
667
|
+
attempts?: number;
|
|
668
|
+
skipReason?: 'static' | 'when' | 'check';
|
|
669
|
+
ignoredFailure?: boolean;
|
|
670
|
+
checks?: CheckOutcome[]; // checks that fired for this step (and inside its flow)
|
|
411
671
|
nestedSteps?: FlowStepResult[]; // for a `flow` step: the child's own steps
|
|
672
|
+
path?: string; // for a composite child step: e.g. '2/1'
|
|
412
673
|
}
|
|
413
674
|
```
|
|
414
675
|
|
|
@@ -425,6 +686,18 @@ interface PlanStep {
|
|
|
425
686
|
name: string;
|
|
426
687
|
skipped: boolean;
|
|
427
688
|
options?: Record<string, unknown>;
|
|
689
|
+
retries?: number;
|
|
690
|
+
retryDelay?: number;
|
|
691
|
+
retryOn?: string;
|
|
692
|
+
when?: string | boolean;
|
|
693
|
+
ignore_failure?: boolean;
|
|
694
|
+
checks?: StepCheck[]; // declared, unevaluated
|
|
695
|
+
phase?: HookPhase; // hook steps only
|
|
696
|
+
path?: string; // expanded plans: hierarchical id, e.g. '2/1'
|
|
697
|
+
depth?: number;
|
|
698
|
+
deprecated?: boolean | string; // plan mode: the target is deprecated
|
|
699
|
+
replaced_by?: string;
|
|
700
|
+
composite?: 'expanded' | 'opaque'; // plan mode with expandComposites
|
|
428
701
|
}
|
|
429
702
|
```
|
|
430
703
|
|