ToolZero infra

xflow CLI

The drop-in toolkit for any TypeScript project. Five commands compose registry-fs + substrate-fs to give you publishing, resolution, and execution with no external services.

Install

Get the binary.

One-time install
pnpm add -D @decoperations/xflow-cli
# or run once via pnpm dlx
pnpm dlx @decoperations/xflow-cli init

Quick start

Five commands, end-to-end.

From zero to a runnable flow in five lines.

The full loop
# 1. Bootstrap config + registry + substrate.
xflow init

# 2. Publish a flow (JSON envelope from your build pipeline).
xflow publish ./flows/checkout.json --recompute

# 3. List entries.
xflow list

# 4. Resolve and inspect.
xflow resolve shop.checkout@1.0.0

# 5. Run.
xflow run shop.checkout@1.0.0 --json

Reference

Commands.

init

Scaffolds xflow.config.json, ./xflow-registry/, and ./xflow-state/. Idempotent.

list [--kind ...]

Lists entries in the local registry. Filter by flow, action, or service.

resolve <id@version>

Prints the manifest + definition. --json emits machine-readable output for piping.

publish <file.json> [--recompute]

Publishes a JSON-shaped registry entry. --recompute re-derives contentHash from the canonicalized definition before writing.

run <id@version>

Runs the flow against the local fs substrate. Steps with no registered action no-op (the CLI is the harness; production callers register their own).

help

This text, but ANSI-colored in your terminal.

Config

xflow.config.json.

Written by xflow init. Override registry/substrate kinds and paths; opt into a trust list.

Default config shape
// xflow.config.json — written by `xflow init`
{
  "registry":  { "kind": "fs", "path": "./xflow-registry" },
  "substrate": { "kind": "fs", "path": "./xflow-state" },
  "trustedSigners": ["ed25519:0xa1b2..."]
}

Publish format

What `xflow publish` consumes.

A registry entry is a JSON envelope: kind, manifest, definition. The CLI validates structure, recomputes the content hash if requested, and writes through the resolver.

flow.json
// flow JSON envelope — what `xflow publish` consumes
{
  "kind": "flow",
  "manifest": {
    "id":          "shop.checkout",
    "version":     "1.0.0",
    "kind":        "flow",
    "format":      "xflow-v1",
    "contentHash": "sha256:0000…",
    "exposure":    "private",
    "extensions":  [],
    "createdAt":   "2026-05-04T00:00:00Z",
    "signers":     ["ed25519:0xa1b2…"]
  },
  "definition": {
    "id": "shop.checkout",
    "version": "1.0.0",
    "steps": { "...": "..." },
    "links": []
  }
}
// --recompute regenerates contentHash from the canonicalized definition.

Exit codes

Predictable for scripts.

0

Success.

1

Operation failed — not found, invalid entry, run failed.

2

Usage error — missing arg, malformed id@version.

Next

Read on.