CLI
Run, trace, diagram, and export stitches from the shell — no app boot.
Reach for the stitch CLI when you want to run a stitch and read its trace from
the shell — no app boot. stitch run <name> streams a named stitch's events to
stdout as JSONL, and stitch trace summarizes the run log those events leave
behind.
Example
Author your stitches in a module that exports each one by name; the CLI
discovers them there (default ./stitches.ts, or pass --module).
// stitches.ts
import { } from 'stitchapi';
export const = ({
: 'getUser',
: 'https://api.example.com',
: '/users/{id}',
});Run it by name. A bare --id routes to the {id} path param, and every event
is printed as one line of JSON, so the stream pipes straight into jq:
stitch run getUser --id 1Then summarize what those runs recorded:
stitch trace --since 1hOptions
stitch run <name> [--module <path>] [--trace[=console|<path>]] [--flags…]
resolves the stitch named <name> from the module and streams its event stream
to stdout as JSONL — one JSON object per line, exit code 1 if an error event
is seen. Flags map onto the stitch's single input object: a bare --<k> becomes
a path param when <k> is a {param} in the path and a query param otherwise,
while --params.<k>, --query.<k>, --headers.<k>, and --body '<json>' (or
--body.<k> <v>) target a bucket explicitly. --module, -m points at the
stitches module (default ./stitches.ts and friends). --trace records the run
(off by default): bare writes the default JSONL file for stitch trace,
--trace=console streams events to stderr, and --trace=<path> writes JSONL to
that path.
stitch trace [--file <path>] [--since 1h] [--name <x>] [--json] folds the
JSONL run log into per-stitch stats (runs, ok/failed, retries, drift, latency
percentiles). --file picks the log (default ~/.stitch/runs/proto.jsonl),
--since keeps only records inside a window like 1h/30m/45s/2d,
--name filters to one stitch, and --json emits the raw summary instead of
the aligned table.
Anti-pattern: don't lean on stitch trace and the default
~/.stitch/runs/proto.jsonl log as your production observability — that
file is process-local (the proto name is a clue: it's a prototyping
convenience), so its percentiles and ok/failed counts only ever cover the
runs from this one shell and never roll up across machines, CI jobs, or
workers. For durable, shared telemetry, fan the same event stream into the
observability stack you already run with OTLP export instead. See OTLP
export.
The CLI runs the very same stitch definition as the in-process
function — one source of truth, just a different
front door. Like the library, the CLI traces nothing by default; pass --trace
to stitch run to record the JSONL
trace sink at
~/.stitch/runs/proto.jsonl (or STITCH_TRACE_FILE) so stitch trace has a
log to read — --trace=console streams to stderr, --trace=<path> writes JSONL
there.
A .ts module loads only when the host has a TypeScript loader registered
(run under tsx); otherwise point --module at compiled JS.
Diagram
stitch diagram [--module <path>] [--name <name>] prints a
Mermaid flowchart of each stitch's configured pipeline
— throttle, request, retry, the request surface,
pagination, validation, transform, pick, and cache — read straight from the
definition, with no run. Pass --name to diagram a single stitch by export name
or configured name. Auth is redacted from a stitch's public config, so the
credential never appears in the diagram.
stitch diagram --name getUser # paste the Mermaid into any rendererExport
stitch export --openapi [--module <path>] [--title <t>] [--api-version <v>] [--schema-module <path>]
emits an OpenAPI 3.1 document (JSON) for
the whole module to stdout — the emit half of "reversible": a stitch declaration
becomes a spec.
stitch export --openapi --title 'My API' --api-version 1.0.0 > openapi.jsonIt is structural by default — paths, methods, operationIds, and the
path/query parameters parsed from each
URL template, plus the presence of a request
body and response. Three things make it richer:
- Body and per-parameter schemas. Pass
--schema-module <path>at a module that exports atoJsonSchema(source, info)converter (its default export or a namedtoJsonSchema). Core stays zero-dependency — you bring the converter (e.g. one wrappingzod-to-json-schema), the way an adapter brings youraxios. Without it, bodies and parameters stay{}. - Security schemes. Each stitch's
authcontributes acomponents.securitySchemesentry and a per-operationsecurityrequirement —bearer/basicbecome HTTP schemes,apiKeyits declared header,oauth2its token endpoint and scopes. Only the scheme is emitted; the credential is never read or written. - Warnings, not silent drops. A stitch whose endpoint is a thunk (resolved
at call time) can't be exported statically, so it is reported on stderr as a
warning:and skipped — never dropped silently.
toOpenApi is also exported from stitchapi/registry for in-process use — pass
your own toJsonSchema converter to fill body and parameter schemas:
import { } from 'stitchapi';
import { } from 'stitchapi/registry';
const = ({
: 'https://api.example.com',
: '/users/{id}',
});
const { , } = ({ });