A worker in Node
oren init worker my-task --template nodeimport { task } from '@oren-sh/sdk';
type Inputs = { defaultChange: 'major' | 'minor' | 'patch' | 'none' };type Outputs = { change: string; commitCount: number };
await task<Inputs, Outputs>(async ({ inputs, path, log }) => { const source = path('source'); log('analysing', source);
return { change: inputs.defaultChange, commitCount: 3 };});Whatever the function returns becomes the task’s output. Throwing aborts the step with exit code 1 — the CLI handles the rest.
The context
Section titled “The context”inputs |
inputs validated against the contract, with defaults applied |
execution |
pipeline, step, task, mounted dependencies |
path(name) |
the path where a dependency was mounted |
log(...) |
writes to stderr |
TaskError has its message shown without a stack trace — it is for whoever
wrote the pipeline, not for whoever wrote the worker.
import { task, TaskError } from '@oren-sh/sdk';
await task(async ({ path }) => { const source = path('source'); if (!existsSync(join(source, '.git'))) { throw new TaskError(`${source} does not contain a git repository`); } // ...});The cost
Section titled “The cost”A worker in shell lands at about 34 MB; the same one in Node, 283 MB — the runtime. In exchange you get types on inputs and outputs, structured errors and logic testable outside the container.
Both satisfy the same contract and ask for exactly the same dependencies, so the choice is about maintenance, not about privilege.
The SDK is optional
Section titled “The SDK is optional”The protocol is reading one file and writing another. A worker in Go, Python or Rust works the same, with nothing from Node involved. This package exists so you do not reimplement path lookup and error handling in every worker.