@boboddy/sdk 0.4.3 → 0.5.1
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/dist/boboddy-config-parser.js +2 -2
- package/dist/client.js +20 -43
- package/dist/contracts/artifacts.js +948 -948
- package/dist/defaults/index.js +11 -11
- package/dist/definitions/advancement-policies/define-advancement-policy.d.ts +30 -5
- package/dist/definitions/advancement-policies/index.js +21 -11
- package/dist/definitions/pipelines/bindings.d.ts +62 -0
- package/dist/definitions/pipelines/builder-helpers.d.ts +19 -106
- package/dist/definitions/pipelines/chain-graph.d.ts +15 -14
- package/dist/definitions/pipelines/compile-node-definitions.d.ts +27 -0
- package/dist/definitions/pipelines/define-pipeline.d.ts +101 -154
- package/dist/definitions/pipelines/index.d.ts +0 -2
- package/dist/definitions/pipelines/index.js +1457 -1602
- package/dist/definitions/pipelines/node-input-ctx.d.ts +31 -0
- package/dist/definitions/pipelines/pipeline-definitions-client.d.ts +18 -4
- package/dist/definitions/pipelines/pipeline-states.d.ts +104 -0
- package/dist/definitions/steps/define-code-step.d.ts +50 -0
- package/dist/definitions/steps/define-step.d.ts +22 -1
- package/dist/definitions/steps/index.d.ts +1 -0
- package/dist/definitions/steps/index.js +13782 -13765
- package/dist/definitions/steps/step-definitions-client.d.ts +29 -5
- package/dist/definitions/validation/index.js +15152 -98
- package/dist/definitions/validation/validate-definition-specs.d.ts +19 -1
- package/dist/generated/index.d.ts +1 -1
- package/dist/generated/sdk.gen.d.ts +1 -4
- package/dist/generated/types.gen.d.ts +296 -878
- package/dist/health-checks.js +950 -950
- package/dist/index.js +1624 -1729
- package/dist/jsonc.js +2 -2
- package/dist/opencode-mcp.js +946 -946
- package/dist/opencode-plugin.js +950 -950
- package/dist/push/collect-definitions.d.ts +40 -1
- package/dist/push/index.d.ts +2 -2
- package/dist/push/index.js +14595 -14545
- package/dist/step-execution-plane-client.d.ts +9 -4
- package/package.json +2 -2
- package/dist/definitions/pipelines/builder.d.ts +0 -80
- package/dist/definitions/pipelines/fan-out-builder.d.ts +0 -66
- package/dist/definitions/pipelines/input-accessor.d.ts +0 -25
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ZodType } from "zod";
|
|
2
|
+
import type { DotPaths } from "../steps/define-step";
|
|
3
|
+
import { type WorkItemAccessor } from "./builder-helpers";
|
|
4
|
+
import type { FanOutItemBinding, LiteralBinding, PipelineInputBinding, SignalsListBinding, StepOutputBinding, StepSignalBinding } from "./bindings";
|
|
5
|
+
/**
|
|
6
|
+
* The `input:` mapper ctx every `step`/`fanOut`/`loop`/parallel-branch
|
|
7
|
+
* state receives (see docs/research/flat-pipeline-sdk-and-visual-designer.md
|
|
8
|
+
* §4). Nodes are addressed by their plain string state key rather than a
|
|
9
|
+
* typed step reference — the flat, forward-only authoring model has no
|
|
10
|
+
* "tuple of prior steps" to statically check a binding's source/signal
|
|
11
|
+
* key against (cross-node static proof is explicitly out of scope; see
|
|
12
|
+
* that doc's §1).
|
|
13
|
+
*/
|
|
14
|
+
export type NodeInputCtx<TInput extends ZodType = ZodType> = {
|
|
15
|
+
/** Reads a value from the pipeline's own input, by dot-path. */
|
|
16
|
+
pipelineInput: (path: DotPaths<TInput["_output"]>) => PipelineInputBinding;
|
|
17
|
+
workItem: WorkItemAccessor;
|
|
18
|
+
/** Reads a signal declared by an earlier node, addressed by its state key. */
|
|
19
|
+
signal: (nodeKey: string, signalKey: string) => StepSignalBinding;
|
|
20
|
+
/** Reads an earlier node's whole result output, addressed by its state key. */
|
|
21
|
+
output: (nodeKey: string) => StepOutputBinding;
|
|
22
|
+
/** Reaches a fan-out's whole cohort (every terminal branch's signals + output). */
|
|
23
|
+
signalsList: (nodeKey: string) => SignalsListBinding;
|
|
24
|
+
literal: (value: unknown) => LiteralBinding;
|
|
25
|
+
};
|
|
26
|
+
/** `NodeInputCtx`, plus `item` — the current fan-out branch's own item. */
|
|
27
|
+
export type FanOutNodeInputCtx<TInput extends ZodType = ZodType> = NodeInputCtx<TInput> & {
|
|
28
|
+
item: FanOutItemBinding;
|
|
29
|
+
};
|
|
30
|
+
export declare function makeNodeInputCtx<TInput extends ZodType>(): NodeInputCtx<TInput>;
|
|
31
|
+
export declare function makeFanOutNodeInputCtx<TInput extends ZodType>(): FanOutNodeInputCtx<TInput>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PipelineDefinitions } from "../../generated/sdk.gen";
|
|
2
2
|
import type { PutApiPipelineDefinitionsData } from "../../generated/types.gen";
|
|
3
|
-
import type
|
|
3
|
+
import { type PipelineDefinitionSpec } from "./define-pipeline";
|
|
4
4
|
type RequestOptions = {
|
|
5
5
|
headers?: Record<string, unknown> | undefined;
|
|
6
6
|
};
|
|
@@ -26,6 +26,7 @@ declare const buildPipelineDefinitionsClient: (pipelineDefinitions: PipelineDefi
|
|
|
26
26
|
stepDefinitions: Array<{
|
|
27
27
|
id: string;
|
|
28
28
|
pipelineDefinitionId: string;
|
|
29
|
+
kind: "step" | "fanOut" | "cohortGate" | "choice" | "parallel" | "loop" | "succeed" | "fail";
|
|
29
30
|
stepDefinitionId: string;
|
|
30
31
|
stepDefinitionVersion: number;
|
|
31
32
|
key: string;
|
|
@@ -131,11 +132,23 @@ declare const buildPipelineDefinitionsClient: (pipelineDefinitions: PipelineDefi
|
|
|
131
132
|
}[]>;
|
|
132
133
|
/**
|
|
133
134
|
* Upserts a pipeline definition keyed by (projectId, key). Accepts the
|
|
134
|
-
* `PipelineDefinitionSpec` produced by `
|
|
135
|
+
* `PipelineDefinitionSpec` produced by `definePipeline()`, along with the
|
|
135
136
|
* list of pushed step definitions (used to resolve `stepDefinitionId` for
|
|
136
|
-
* each
|
|
137
|
+
* each node/branch referencing a step by key).
|
|
137
138
|
*
|
|
138
|
-
*
|
|
139
|
+
* Pushes via the richer `nodeDefinitions[]`/`dependencyEdges[]` graph
|
|
140
|
+
* shape (see `buildGraphNodeInput`) rather than the old flat,
|
|
141
|
+
* `position`-ordered `stepDefinitions[]` shape — every node kind
|
|
142
|
+
* `definePipeline()` can produce (`choice`/`fanOut`/`cohortGate`/
|
|
143
|
+
* `parallel`/`loop`/`succeed`/`fail`, not just `step`) is representable
|
|
144
|
+
* this way; the flat shape could only ever represent a `step`-only
|
|
145
|
+
* chain. The generated `UpsertPipelineDefinitionInput` type doesn't yet
|
|
146
|
+
* reflect this (it's OpenAPI-codegen'd from the pre-existing flat
|
|
147
|
+
* contract), so the body is cast at the boundary — the server's zod
|
|
148
|
+
* schema (`createPipelineDefinitionInputSchema`, extended to accept
|
|
149
|
+
* either shape) is the real, enforced contract.
|
|
150
|
+
*
|
|
151
|
+
* Throws if any node/branch references a step key/version that isn't
|
|
139
152
|
* present in `stepDefs`.
|
|
140
153
|
*/
|
|
141
154
|
upsertFromSpec: (projectId: string, spec: PipelineDefinitionSpec, stepDefs: ReadonlyArray<StepDefinitionRef>, options?: RequestOptions) => Promise<{
|
|
@@ -152,6 +165,7 @@ declare const buildPipelineDefinitionsClient: (pipelineDefinitions: PipelineDefi
|
|
|
152
165
|
stepDefinitions: Array<{
|
|
153
166
|
id: string;
|
|
154
167
|
pipelineDefinitionId: string;
|
|
168
|
+
kind: "step" | "fanOut" | "cohortGate" | "choice" | "parallel" | "loop" | "succeed" | "fail";
|
|
155
169
|
stepDefinitionId: string;
|
|
156
170
|
stepDefinitionVersion: number;
|
|
157
171
|
key: string;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { ZodType } from "zod";
|
|
2
|
+
import type { RuleCondition } from "../advancement-policies/define-advancement-policy";
|
|
3
|
+
import type { AdvanceAllCtx, AdvanceAllResult, AdvanceEachCtx, AdvanceEachResult } from "../advancement-policies/cohort-fluent-rules";
|
|
4
|
+
import type { AnyTypedStep } from "./builder-helpers";
|
|
5
|
+
import type { AnyBinding } from "./bindings";
|
|
6
|
+
import type { FanOutNodeInputCtx, NodeInputCtx } from "./node-input-ctx";
|
|
7
|
+
/**
|
|
8
|
+
* The 7 authoring state kinds (see
|
|
9
|
+
* docs/research/flat-pipeline-sdk-and-visual-designer.md §4/§5). Every
|
|
10
|
+
* kind besides `choice`/`succeed`/`fail` does its own work (a `step`) and
|
|
11
|
+
* therefore declares exactly one authored `input`/`timeout`; `choice` and
|
|
12
|
+
* `loop` are the only kinds with more than one possible exit.
|
|
13
|
+
*/
|
|
14
|
+
/** `next: "otherStateKey"`, or a special cross-pipeline route target. */
|
|
15
|
+
export type NextTarget = string | {
|
|
16
|
+
routeToPipeline: string;
|
|
17
|
+
input?: Record<string, unknown> | null;
|
|
18
|
+
};
|
|
19
|
+
export type StepState = {
|
|
20
|
+
kind: "step";
|
|
21
|
+
step: AnyTypedStep;
|
|
22
|
+
input?: (ctx: NodeInputCtx) => Partial<Record<string, AnyBinding>>;
|
|
23
|
+
timeout?: number | null;
|
|
24
|
+
/**
|
|
25
|
+
* A single-condition "pause for human review" gate — the narrow
|
|
26
|
+
* replacement for the old per-step rules-engine policy object (see §5's
|
|
27
|
+
* `complete`/`route`/`block` migration notes). When the condition
|
|
28
|
+
* matches, the node run blocks instead of advancing to `next`.
|
|
29
|
+
*/
|
|
30
|
+
blockWhen?: RuleCondition;
|
|
31
|
+
next: NextTarget;
|
|
32
|
+
};
|
|
33
|
+
export type ChoiceCase = {
|
|
34
|
+
when: RuleCondition;
|
|
35
|
+
next: string;
|
|
36
|
+
};
|
|
37
|
+
export type ChoiceState = {
|
|
38
|
+
kind: "choice";
|
|
39
|
+
/** At least one of `choices`/`default` is required — see `compileChoiceState`. */
|
|
40
|
+
choices?: ReadonlyArray<ChoiceCase>;
|
|
41
|
+
default?: string | null;
|
|
42
|
+
};
|
|
43
|
+
export type FanOutState = {
|
|
44
|
+
kind: "fanOut";
|
|
45
|
+
step: AnyTypedStep;
|
|
46
|
+
/**
|
|
47
|
+
* The signal to resolve branch cardinality (and, in array mode, each
|
|
48
|
+
* branch's own item) from. A bare signal key (`"changedFiles"`) or a
|
|
49
|
+
* `"stateKey.signalKey"` dotted convenience form — the dotted prefix is
|
|
50
|
+
* author-facing documentation only; the runtime resolves the signal by
|
|
51
|
+
* scanning every upstream node's own signals for a matching key (see
|
|
52
|
+
* `resolveFanOutCardinality`), not by an explicit node reference.
|
|
53
|
+
*/
|
|
54
|
+
over: string;
|
|
55
|
+
maxConcurrency?: number | null;
|
|
56
|
+
input?: (ctx: FanOutNodeInputCtx) => Partial<Record<string, AnyBinding>>;
|
|
57
|
+
timeout?: number | null;
|
|
58
|
+
advanceEach: (ctx: AdvanceEachCtx) => AdvanceEachResult;
|
|
59
|
+
advanceAll: (ctx: AdvanceAllCtx) => AdvanceAllResult;
|
|
60
|
+
next: string;
|
|
61
|
+
};
|
|
62
|
+
export type ParallelBranchConfig = {
|
|
63
|
+
step: AnyTypedStep;
|
|
64
|
+
input?: (ctx: NodeInputCtx) => Partial<Record<string, AnyBinding>>;
|
|
65
|
+
timeout?: number | null;
|
|
66
|
+
};
|
|
67
|
+
export type ParallelState = {
|
|
68
|
+
kind: "parallel";
|
|
69
|
+
/** Named branches (v1: single-step only — see decision 5). */
|
|
70
|
+
branches: Record<string, ParallelBranchConfig>;
|
|
71
|
+
/** Defaults to "continue iff every branch continued" when omitted. */
|
|
72
|
+
advanceAll?: (ctx: AdvanceAllCtx) => AdvanceAllResult;
|
|
73
|
+
next: string;
|
|
74
|
+
};
|
|
75
|
+
export type LoopState = {
|
|
76
|
+
kind: "loop";
|
|
77
|
+
step: AnyTypedStep;
|
|
78
|
+
maxIterations: number;
|
|
79
|
+
input?: (ctx: NodeInputCtx) => Partial<Record<string, AnyBinding>>;
|
|
80
|
+
timeout?: number | null;
|
|
81
|
+
until: RuleCondition;
|
|
82
|
+
next: string;
|
|
83
|
+
onExhausted: string;
|
|
84
|
+
};
|
|
85
|
+
export type SucceedState = {
|
|
86
|
+
kind: "succeed";
|
|
87
|
+
};
|
|
88
|
+
export type FailState = {
|
|
89
|
+
kind: "fail";
|
|
90
|
+
};
|
|
91
|
+
export type PipelineState = StepState | ChoiceState | FanOutState | ParallelState | LoopState | SucceedState | FailState;
|
|
92
|
+
export type DefinePipelineInput<TInput extends ZodType = ZodType> = {
|
|
93
|
+
key: string;
|
|
94
|
+
name?: string;
|
|
95
|
+
description?: string | null;
|
|
96
|
+
version?: number;
|
|
97
|
+
status?: "draft" | "active";
|
|
98
|
+
/** The pipeline's own input schema — drives `ctx.pipelineInput(path)`'s typing and `inputSchemaJson`. */
|
|
99
|
+
input?: TInput;
|
|
100
|
+
/** The entry state's key. Must not name a `choice`/`succeed`/`fail` state. */
|
|
101
|
+
startAt: string;
|
|
102
|
+
/** Every state in the pipeline, keyed by its unique node key. */
|
|
103
|
+
states: Record<string, PipelineState>;
|
|
104
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { ZodType } from "zod";
|
|
2
|
+
import type { SignalKeysOf, SignalTypeMapOf, TypedStepDefinitionSpec } from "./define-step";
|
|
3
|
+
/**
|
|
4
|
+
* `codeStep()`'s own signal spec shape — unlike `defineStep()`'s
|
|
5
|
+
* `SignalSpecInput`, `type` is required rather than inferred from the
|
|
6
|
+
* result schema at a dot-path (`resolveZodSchemaAtPath`/
|
|
7
|
+
* `zodTypeToSignalType` are `define-step.ts`-internal, and a code step's
|
|
8
|
+
* result shape is arbitrary application data, not necessarily reflecting
|
|
9
|
+
* one at all) — a small, deliberate simplification over `defineStep`'s own
|
|
10
|
+
* signal authoring surface.
|
|
11
|
+
*/
|
|
12
|
+
export type CodeStepSignalSpec = {
|
|
13
|
+
key?: string;
|
|
14
|
+
sourcePath: string;
|
|
15
|
+
type: "string" | "number" | "boolean" | "object" | "array";
|
|
16
|
+
required?: boolean;
|
|
17
|
+
availableWhenResultStatusIn?: string[] | null;
|
|
18
|
+
};
|
|
19
|
+
export type CodeStepFn<TInput, TResult> = (input: TInput) => TResult | Promise<TResult>;
|
|
20
|
+
export type DefineCodeStepInput<TInput extends ZodType = ZodType, TResult extends ZodType = ZodType> = {
|
|
21
|
+
key: string;
|
|
22
|
+
name: string;
|
|
23
|
+
description?: string | null;
|
|
24
|
+
version?: number;
|
|
25
|
+
/**
|
|
26
|
+
* The step's own implementation — resolved by `collect-definitions.ts`
|
|
27
|
+
* to a portable `{sourceFile, exportName}` pair (by identity-matching
|
|
28
|
+
* this reference against the declaring module's other exports) before
|
|
29
|
+
* the (unserializable) function reference is ever sent over the wire.
|
|
30
|
+
* Must be a plain named export of the same module `codeStep()` is
|
|
31
|
+
* called from (see docs/research/flat-pipeline-sdk-and-visual-designer.md
|
|
32
|
+
* §7.7/§8's "code-step entrypoints resolve against the target repo").
|
|
33
|
+
*/
|
|
34
|
+
fn: CodeStepFn<TInput["_output"], TResult["_output"]>;
|
|
35
|
+
inputSchema?: TInput;
|
|
36
|
+
resultSchema?: TResult;
|
|
37
|
+
signals?: readonly CodeStepSignalSpec[];
|
|
38
|
+
status?: "draft" | "active";
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Defines a `kind: "code"` step: a plain function instead of an LLM
|
|
42
|
+
* prompt. Produces the same phantom-typed `TypedStepDefinitionSpec` shape
|
|
43
|
+
* `defineStep()` does (so it plugs into `definePipeline()`'s
|
|
44
|
+
* `states[key].step` field unchanged), but with no `prompt` and a live
|
|
45
|
+
* `entrypoint.fn` reference attached instead — see `StepDefinitionSpec`'s
|
|
46
|
+
* own doc comment for what happens to it during collection.
|
|
47
|
+
*/
|
|
48
|
+
export declare function codeStep<TInput extends ZodType = ZodType, TResult extends ZodType = ZodType, const TSignals extends ReadonlyArray<CodeStepSignalSpec> = never[]>(config: DefineCodeStepInput<TInput, TResult> & {
|
|
49
|
+
signals?: TSignals;
|
|
50
|
+
}): TypedStepDefinitionSpec<TInput["_output"], TResult["_output"], SignalKeysOf<TSignals>, SignalTypeMapOf<TSignals, TResult["_output"]>>;
|
|
@@ -108,12 +108,21 @@ export type AdditionalStepInputLiteralBinding = LiteralBinding;
|
|
|
108
108
|
* coincidence, not by design.
|
|
109
109
|
*/
|
|
110
110
|
export type AdditionalStepInputBinding = WorkItemBinding | LiteralBinding;
|
|
111
|
+
/**
|
|
112
|
+
* A `kind: "code"` step's portable entrypoint, once resolved by
|
|
113
|
+
* `collect-definitions.ts`'s identity-capture pass — see
|
|
114
|
+
* docs/research/flat-pipeline-sdk-and-visual-designer.md §7.7/§8.
|
|
115
|
+
*/
|
|
116
|
+
export type StepDefinitionEntrypointJson = {
|
|
117
|
+
sourceFile: string;
|
|
118
|
+
exportName: string;
|
|
119
|
+
};
|
|
111
120
|
export type StepDefinitionSpec = {
|
|
112
121
|
key: string;
|
|
113
122
|
name: string;
|
|
114
123
|
description: string | null;
|
|
115
124
|
version: number;
|
|
116
|
-
kind: "user_defined";
|
|
125
|
+
kind: "user_defined" | "code";
|
|
117
126
|
status: "draft" | "active" | "archived";
|
|
118
127
|
executionMode?: "workspace" | "no_workspace";
|
|
119
128
|
prompt: string | null;
|
|
@@ -129,6 +138,18 @@ export type StepDefinitionSpec = {
|
|
|
129
138
|
opencodeMcpJson: OpenCodeMcpServers | null;
|
|
130
139
|
opencodePluginJson: OpenCodePlugins | null;
|
|
131
140
|
healthChecksJson: HealthChecks | null;
|
|
141
|
+
/**
|
|
142
|
+
* `kind === "code"` only, and only *before* collection —
|
|
143
|
+
* `collect-definitions.ts` resolves this live `fn` reference down to
|
|
144
|
+
* `entrypointJson` (by identity-matching against the declaring module's
|
|
145
|
+
* other exports) and strips this field before the spec is ever pushed;
|
|
146
|
+
* it can never be serialized into the push request.
|
|
147
|
+
*/
|
|
148
|
+
entrypoint?: {
|
|
149
|
+
fn: (input: unknown) => unknown;
|
|
150
|
+
};
|
|
151
|
+
/** `kind === "code"` only, present after `collect-definitions.ts` has run. */
|
|
152
|
+
entrypointJson?: StepDefinitionEntrypointJson | null;
|
|
132
153
|
};
|
|
133
154
|
export type SignalTypeStrToTs<T extends SignalTypeStr> = T extends "string" ? string : T extends "number" ? number : T extends "boolean" ? boolean : T extends "array" ? unknown[] : T extends "object" ? object : unknown;
|
|
134
155
|
export type SignalTypeMapOf<TSignals extends readonly unknown[], TResult> = Prettify<{
|