@boboddy/sdk 0.4.3 → 0.5.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.
Files changed (32) hide show
  1. package/dist/client.js +0 -23
  2. package/dist/definitions/advancement-policies/define-advancement-policy.d.ts +30 -5
  3. package/dist/definitions/advancement-policies/index.js +11 -1
  4. package/dist/definitions/pipelines/bindings.d.ts +62 -0
  5. package/dist/definitions/pipelines/builder-helpers.d.ts +19 -106
  6. package/dist/definitions/pipelines/chain-graph.d.ts +15 -14
  7. package/dist/definitions/pipelines/compile-node-definitions.d.ts +27 -0
  8. package/dist/definitions/pipelines/define-pipeline.d.ts +101 -154
  9. package/dist/definitions/pipelines/index.d.ts +0 -2
  10. package/dist/definitions/pipelines/index.js +470 -615
  11. package/dist/definitions/pipelines/node-input-ctx.d.ts +31 -0
  12. package/dist/definitions/pipelines/pipeline-definitions-client.d.ts +18 -4
  13. package/dist/definitions/pipelines/pipeline-states.d.ts +104 -0
  14. package/dist/definitions/steps/define-code-step.d.ts +50 -0
  15. package/dist/definitions/steps/define-step.d.ts +22 -1
  16. package/dist/definitions/steps/index.d.ts +1 -0
  17. package/dist/definitions/steps/index.js +41 -24
  18. package/dist/definitions/steps/step-definitions-client.d.ts +29 -5
  19. package/dist/definitions/validation/index.js +15148 -94
  20. package/dist/definitions/validation/validate-definition-specs.d.ts +19 -1
  21. package/dist/generated/index.d.ts +1 -1
  22. package/dist/generated/sdk.gen.d.ts +1 -4
  23. package/dist/generated/types.gen.d.ts +296 -878
  24. package/dist/index.js +510 -615
  25. package/dist/push/collect-definitions.d.ts +40 -1
  26. package/dist/push/index.d.ts +2 -2
  27. package/dist/push/index.js +788 -738
  28. package/dist/step-execution-plane-client.d.ts +9 -4
  29. package/package.json +2 -2
  30. package/dist/definitions/pipelines/builder.d.ts +0 -80
  31. package/dist/definitions/pipelines/fan-out-builder.d.ts +0 -66
  32. 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 { PipelineDefinitionSpec } from "./define-pipeline";
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 `pipeline().build()`, along with the
135
+ * `PipelineDefinitionSpec` produced by `definePipeline()`, along with the
135
136
  * list of pushed step definitions (used to resolve `stepDefinitionId` for
136
- * each pipeline step).
137
+ * each node/branch referencing a step by key).
137
138
  *
138
- * Throws if any pipeline step references a step key/version that isn't
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<{
@@ -1,4 +1,5 @@
1
1
  export * from "./define-step";
2
+ export * from "./define-code-step";
2
3
  export * from "./prompt-template";
3
4
  export * from "./step-definitions-client";
4
5
  export * from "./step-features";
@@ -12080,6 +12080,32 @@ ${feature._promptAddition}` : feature._promptAddition;
12080
12080
  };
12081
12081
  return spec;
12082
12082
  }
12083
+ // src/definitions/steps/define-code-step.ts
12084
+ function codeStep(config2) {
12085
+ const spec = {
12086
+ key: config2.key,
12087
+ name: config2.name,
12088
+ description: config2.description ?? null,
12089
+ version: config2.version ?? 1,
12090
+ kind: "code",
12091
+ status: config2.status ?? "active",
12092
+ prompt: null,
12093
+ inputSchemaJson: config2.inputSchema ? toJSONSchema(config2.inputSchema) : null,
12094
+ resultSchemaJson: config2.resultSchema ? toJSONSchema(config2.resultSchema) : null,
12095
+ signalExtractorDefinitions: (config2.signals ?? []).map((signal) => ({
12096
+ key: signal.key ?? signal.sourcePath,
12097
+ sourcePath: signal.sourcePath,
12098
+ type: signal.type,
12099
+ required: signal.required ?? true,
12100
+ availableWhenResultStatusIn: signal.availableWhenResultStatusIn ?? null
12101
+ })),
12102
+ opencodeMcpJson: null,
12103
+ opencodePluginJson: null,
12104
+ healthChecksJson: null,
12105
+ entrypoint: { fn: config2.fn }
12106
+ };
12107
+ return spec;
12108
+ }
12083
12109
  // src/generated/core/bodySerializer.gen.ts
12084
12110
  var jsonBodySerializer = {
12085
12111
  bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value)
@@ -13159,29 +13185,6 @@ class PipelineDefinitions extends HeyApiClient {
13159
13185
  unarchivePipelineDefinition(options) {
13160
13186
  return (options.client ?? this.client).put({ url: "/api/pipeline-definitions/{pipelineDefinitionId}/unarchive", ...options });
13161
13187
  }
13162
- addPipelineStep(options) {
13163
- return (options.client ?? this.client).post({
13164
- url: "/api/pipeline-definitions/{pipelineDefinitionId}/steps",
13165
- ...options,
13166
- headers: {
13167
- "Content-Type": "application/json",
13168
- ...options.headers
13169
- }
13170
- });
13171
- }
13172
- removePipelineStep(options) {
13173
- return (options.client ?? this.client).delete({ url: "/api/pipeline-definitions/{pipelineDefinitionId}/steps/{pipelineStepDefinitionId}", ...options });
13174
- }
13175
- updatePipelineStep(options) {
13176
- return (options.client ?? this.client).put({
13177
- url: "/api/pipeline-definitions/{pipelineDefinitionId}/steps/{pipelineStepDefinitionId}",
13178
- ...options,
13179
- headers: {
13180
- "Content-Type": "application/json",
13181
- ...options.headers
13182
- }
13183
- });
13184
- }
13185
13188
  setPipelineStepAdvancementPolicy(options) {
13186
13189
  return (options.client ?? this.client).put({
13187
13190
  url: "/api/pipeline-definitions/{pipelineDefinitionId}/steps/{pipelineStepDefinitionId}/advancement-policy",
@@ -13710,8 +13713,21 @@ var buildStepDefinitionsClient = (stepDefinitions) => {
13710
13713
  },
13711
13714
  upsertFromSpec: async (projectId, spec, options) => {
13712
13715
  const body = {
13713
- ...spec,
13716
+ key: spec.key,
13717
+ name: spec.name,
13718
+ description: spec.description,
13714
13719
  prompt: spec.prompt ?? "",
13720
+ version: spec.version,
13721
+ kind: spec.kind,
13722
+ entrypointJson: spec.entrypointJson ?? null,
13723
+ executionMode: spec.executionMode,
13724
+ inputSchemaJson: spec.inputSchemaJson,
13725
+ resultSchemaJson: spec.resultSchemaJson,
13726
+ opencodeMcpJson: spec.opencodeMcpJson,
13727
+ opencodePluginJson: spec.opencodePluginJson,
13728
+ healthChecksJson: spec.healthChecksJson,
13729
+ status: spec.status,
13730
+ signalExtractorDefinitions: spec.signalExtractorDefinitions,
13715
13731
  projectId
13716
13732
  };
13717
13733
  const result = await stepDefinitions.upsertStepDefinition({
@@ -16136,5 +16152,6 @@ export {
16136
16152
  createStepDefinitionsClient,
16137
16153
  createPromptTemplateContext,
16138
16154
  createPromptInputProxy,
16155
+ codeStep,
16139
16156
  Features
16140
16157
  };
@@ -16,7 +16,11 @@ declare const buildStepDefinitionsClient: (stepDefinitions: StepDefinitions) =>
16
16
  description: string | unknown;
17
17
  prompt: string | unknown;
18
18
  version: number;
19
- kind: "built_in" | "user_defined";
19
+ kind: "built_in" | "user_defined" | "code";
20
+ entrypointJson: {
21
+ sourceFile: string;
22
+ exportName: string;
23
+ } | unknown;
20
24
  executionMode: "workspace" | "no_workspace";
21
25
  inputSchemaJson: {
22
26
  [key: string]: unknown;
@@ -84,7 +88,11 @@ declare const buildStepDefinitionsClient: (stepDefinitions: StepDefinitions) =>
84
88
  description: string | unknown;
85
89
  prompt: string | unknown;
86
90
  version: number;
87
- kind: "built_in" | "user_defined";
91
+ kind: "built_in" | "user_defined" | "code";
92
+ entrypointJson: {
93
+ sourceFile: string;
94
+ exportName: string;
95
+ } | unknown;
88
96
  executionMode: "workspace" | "no_workspace";
89
97
  inputSchemaJson: {
90
98
  [key: string]: unknown;
@@ -146,8 +154,20 @@ declare const buildStepDefinitionsClient: (stepDefinitions: StepDefinitions) =>
146
154
  }>;
147
155
  /**
148
156
  * Upserts a step definition keyed by (projectId, key, version). Accepts the
149
- * `StepDefinitionSpec` produced by `defineStep()` directly — no separate
150
- * fetch-existing/branch-on-id step needed.
157
+ * `StepDefinitionSpec` produced by `defineStep()`/`codeStep()` directly —
158
+ * no separate fetch-existing/branch-on-id step needed.
159
+ *
160
+ * `entrypointJson` (a `kind: "code"` step's resolved entrypoint — see
161
+ * `collect-definitions.ts`) and the widened `kind` union
162
+ * (`"user_defined" | "code"`) are not yet reflected in the
163
+ * OpenAPI-generated `UpsertStepDefinitionInput` type, so the request
164
+ * body is built explicitly and cast at the boundary rather than spread
165
+ * + `satisfies`-checked, mirroring the same pattern
166
+ * `pipeline-definitions-client.ts`'s `upsertFromSpec` already uses for
167
+ * its own wire-format-ahead-of-codegen gap. The spec's transient
168
+ * `entrypoint.fn` (a live, unserializable function reference —
169
+ * present only if a caller bypasses `collect-definitions.ts`'s own
170
+ * strip step) is never included here.
151
171
  */
152
172
  upsertFromSpec: (projectId: string, spec: StepDefinitionSpec, options?: RequestOptions) => Promise<{
153
173
  id: string;
@@ -157,7 +177,11 @@ declare const buildStepDefinitionsClient: (stepDefinitions: StepDefinitions) =>
157
177
  description: string | unknown;
158
178
  prompt: string | unknown;
159
179
  version: number;
160
- kind: "built_in" | "user_defined";
180
+ kind: "built_in" | "user_defined" | "code";
181
+ entrypointJson: {
182
+ sourceFile: string;
183
+ exportName: string;
184
+ } | unknown;
161
185
  executionMode: "workspace" | "no_workspace";
162
186
  inputSchemaJson: {
163
187
  [key: string]: unknown;