Skip to content

SDK Reference

Install the SDK:

Terminal window
npm install @boboddy/sdk
# or
bun add @boboddy/sdk

defineStep(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

FieldTypeRequiredDescription
keystringYesUnique step key within the project
namestringYesDisplay name
versionnumberNoVersion (default: 1)
descriptionstringNoShort description
agentPromptstringYesAI instruction given to the executing agent
additionalInputZodTypeNoAdditional input payload schema; fields are bound via the pipeline mapper
resultZodTypeNoOutput payload schema
signalsSignal[]NoValues to extract from the result
mcpServersOpenCodeMcpServersNoMCP server configs for tool-using agents
status"draft" | "active"NoDraft 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

FieldTypeRequiredDescription
keystringYesUnique pipeline key
namestringYesDisplay name
versionnumberNoVersion (default: 1)
descriptionstringNoShort description
status"draft" | "active"NoDraft pipelines are not executed
additionalPipelineInputobjectNoCustom input fields; requires both schema and bindings
additionalStepInputobjectNoDefault 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

MethodDescription
.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 from additionalPipelineInput.schema. input.code binds to path "code"; input.ticket.title binds 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. signalKey is typed against step.__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 typed SignalRef for 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 to signal(key). Both produce identical output.
  • Computed factoriesavg, weightedAvg, sum, min, max, count, booleanAny, booleanAll. Each takes 2+ signal(key) or stepSignals.key references and returns a SignalRef. Identical calls across rules are deduplicated at build time.
  • all(...refs) / any(...refs) — group SignalRefs 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

FieldTypeRequiredDescription
keystringYesUnique pipeline key
namestringYesDisplay name
versionnumberNoVersion (default: 1)
descriptionstringNoShort description
status"draft" | "active"NoDraft pipelines are not executed
stepsPipelineStep[]YesOrdered step entries

PipelineStep

FieldTypeDescription
stepTypedStepDefinitionSpecStep definition returned by defineStep
inputInputBindingMapMap of input field names to binding helpers
timeoutnumberMilliseconds before the step is marked timed out
advancementRule<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();