SDK Reference
Install the SDK:
npm install @boboddy/sdk# orbun add @boboddy/sdkdefineStep(options)
Define a reusable, versioned step with typed input/output schemas.
import { defineStep } from '@boboddy/sdk';import { z } from 'zod';
const myStep = defineStep({ key: 'my-step', name: 'My Step', version: 1, description: 'Does something useful.', additionalInput: z.object({ text: z.string() }), result: z.object({ summary: z.string(), score: z.number() }), signals: [ { sourcePath: 'score', key: 'quality_score', type: 'number', required: true }, ], agentPrompt: 'Analyze the provided text and return a summary and quality score.', status: 'active',});StepDefinition options
| Field | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Unique step key within the project |
name | string | Yes | Display name |
version | number | No | Version (default: 1) |
description | string | No | Short description |
agentPrompt | string | Yes | AI instruction given to the executing agent |
additionalInput | ZodType | No | Additional input payload schema; fields are bound via the pipeline mapper |
result | ZodType | No | Output payload schema |
signals | Signal[] | No | Values to extract from the result |
mcpServers | OpenCodeMcpServers | No | MCP server configs for tool-using agents |
status | "draft" | "active" | No | Draft steps are skipped by workers |
Signal
type Signal = { sourcePath: string; // dot-notation path into result, e.g. "metrics.score" key?: string; // signal name used in advancement rules (defaults to sourcePath) type?: 'number' | 'string' | 'boolean' | 'object' | 'array'; required?: boolean; // fail execution if signal is missing};pipeline(meta)
Define an ordered sequence of steps using the fluent builder.
import { pipeline } from '@boboddy/sdk/definitions/pipelines';import { z } from 'zod';
const inputSchema = z.object({ text: z.string() });
const myPipeline = pipeline({ key: 'my-pipeline', name: 'My Pipeline', status: 'active', additionalPipelineInput: { schema: z.object({ text: z.string() }), bindings: ({ workItem }) => ({ text: workItem.field('Text') }), },}) .step(myStep, ({ input }) => ({ text: input.text })) .advance(() => ({ default: 'continue' })) .build();PipelineMeta options
| Field | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Unique pipeline key |
name | string | Yes | Display name |
version | number | No | Version (default: 1) |
description | string | No | Short description |
status | "draft" | "active" | No | Draft pipelines are not executed |
additionalPipelineInput | object | No | Custom input fields; requires both schema and bindings |
additionalStepInput | object | No | Default bindings applied to every step in the pipeline |
additionalPipelineInput.schema is a Zod object schema for extra pipeline input fields. additionalPipelineInput.bindings receives { workItem, literal } and returns their bindings.
additionalStepInput applies default bindings to every step in the pipeline. Its bindings function receives { workItemField, literal } and compiles into regular step input bindings. Explicit .step(..., mapper) bindings override pipeline-level defaults.
Builder methods
| Method | Description |
|---|---|
.step(step, mapper, configFn?) | Append a step. mapper receives { input, signal, output, literal } and returns a record of input bindings keyed by the step’s input fields. Optional configFn receives { timeout } — set cfg.timeout (seconds) to cap execution time. |
.advance(callback) | Attach an advancement policy to the most recently added step. callback receives { signal, stepSignals, all, any, route, avg, sum, min, max, count, weightedAvg, booleanAny, booleanAll } and returns { default, rules? }. Required before adding another step or calling .build(). |
.build() | Finalize and return a PipelineDefinitionSpec. |
Step input bindings
Inside the .step() mapper:
input.workItemTitle/input.workItemDescription— always available; bind to the work item title or description.input.<path>— custom fields fromadditionalPipelineInput.schema.input.codebinds to path"code";input.ticket.titlebinds to"ticket.title". The accessor is a proxy — do not spread or coerce it to a primitive.signal(step, signalKey)— bind to a prior step’s signal.signalKeyis typed againststep.__signalKeys.output(step)— bind to a prior step’s whole output object.literal(value)— a hardcoded constant.
Fluent advancement rules
Inside the .advance() callback:
signal(key)— returns a typedSignalReffor the current step’s signal. Chain a comparator (.eq,.gt,.gte,.lt,.lte,.ne,.in,.notIn,.contains,.doesNotContain) followed by.then(outcome).stepSignals.<key>— property-map shorthand equivalent tosignal(key). Both produce identical output.- Computed factories —
avg,weightedAvg,sum,min,max,count,booleanAny,booleanAll. Each takes 2+signal(key)orstepSignals.keyreferences and returns aSignalRef. Identical calls across rules are deduplicated at build time. all(...refs)/any(...refs)— groupSignalRefs and other groups; terminate with.then(outcome).route(pipelineKey, inputJson?)— produces a route outcome value for.then(...).
Legacy definePipeline(options)
The original object-based API. Still supported; produces identical wire output. New pipelines should prefer the pipeline() builder above.
import { definePipeline, fromPipelineInput } from '@boboddy/sdk';import { z } from 'zod';
const myPipeline = definePipeline({ key: 'my-pipeline', name: 'My Pipeline', status: 'active', steps: [ { step: myStep, input: { text: fromPipelineInput(z.string(), 'text'), }, }, ],});PipelineDefinition options
| Field | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Unique pipeline key |
name | string | Yes | Display name |
version | number | No | Version (default: 1) |
description | string | No | Short description |
status | "draft" | "active" | No | Draft pipelines are not executed |
steps | PipelineStep[] | Yes | Ordered step entries |
PipelineStep
| Field | Type | Description |
|---|---|---|
step | TypedStepDefinitionSpec | Step definition returned by defineStep |
input | InputBindingMap | Map of input field names to binding helpers |
timeout | number | Milliseconds before the step is marked timed out |
advancement | Rule<SignalKeys> | Boolean signal rule; pipeline halts if not satisfied |
Legacy input binding helpers
These remain exported for use with definePipeline. With the pipeline() builder, prefer the input / signal / output context helpers documented above.
fromPipelineInput(schema, path)
Bind a step input field to a top-level pipeline input parameter.
input: { code: fromPipelineInput(z.string(), 'code'),}fromSignal(step, signalKey)
Bind a step input field to a signal emitted by a prior step in the pipeline.
input: { previousScore: fromSignal(reviewStep, 'clarity_score'),}stepOutput(step)
Bind a step input field to the complete output object of a prior step.
input: { reviewResult: stepOutput(reviewStep),}API client
The SDK ships an auto-generated API client built from the OpenAPI spec.
import { createBoboddyClient } from '@boboddy/sdk';
const client = createBoboddyClient('https://app.boboddy.dev');Use createStepDefinitionsClient for CRUD operations on step definitions:
import { createStepDefinitionsClient } from '@boboddy/sdk';
const stepClient = createStepDefinitionsClient('https://app.boboddy.dev');Config helpers
JSONC parser
Parse .boboddy/boboddy.jsonc files (JSON with comments):
import { parseJsonc } from '@boboddy/sdk';
const config = parseJsonc(rawString);Project config
Read the Boboddy project config from disk:
import { readProjectConfig } from '@boboddy/sdk';
const { projectId } = await readProjectConfig();