@ripline/core
v0.1.0
Published
Repeatable AI agent workflows with multi-agent review built in
Maintainers
Readme
Ripline
Repeatable AI agent workflows with multi-agent review built in.
What Ripline is
Ripline is a pipeline engine for building repeatable, auditable multi-agent workflows. You describe the flow as a YAML DAG, Ripline executes it reliably, and every run is traceable and resumable.
Key capabilities:
- Declarative DAG pipelines in YAML — Each step (inputs, agent calls, transforms, approvals) is explicit with typed contracts between phases.
- Native multi-agent review phases — Built-in
plan,review, andreview_onlyphase kinds fan out to multiple AI CLIs in parallel, evaluate quorum, and retry on disagreement. No custom orchestration code required. - Voice/lineage system — Route phases to specific AI CLIs (Claude, Codex, Gemini, Kimi, OpenCode) by lineage rather than hardcoded runner names. The registry detects installed CLIs automatically.
- Input/output contracts — JSON Schema validation between steps catches mismatches before they propagate.
- Resumable runs, loop nodes, sub-pipelines — Long-running workflows survive interruptions; loops and fan-out are first-class constructs.
- CLI + HTTP API — Run locally, trigger from CI, or expose an HTTP surface for dashboards and external integrations.
Quick-start example: architecture review pipeline
The following pipeline defines an architecture review workflow. Claude writes a draft design, then two reviewers (Gemini and Codex) critique it in parallel. If either reviewer requests changes, the doer gets the feedback and tries again, up to three rounds.
id: arch_review
name: Architecture review
version: 1
description: Draft an architecture, then fan out to two reviewers for quorum approval.
entry: [plan_arch]
phases:
- id: plan_arch
kind: plan
title: Draft architecture
description: |
You are a senior software architect. The user has requested:
{{ inputs.request }}
Write a concise architecture document covering: system components, data flow,
key technology choices, and risks. Use markdown headings.
doer:
lineage: anthropic
iterate:
maxRounds: 3
onDisagreement: continue
- id: review_arch
kind: review
title: Architecture review
description: |
Review the architecture document produced by the previous phase.
Focus on soundness, scalability, and risk coverage.
doer:
lineage: anthropic
reviewer:
require: 2
crossLineage: true
candidates:
- lineage: google
- lineage: openai
iterate:
maxRounds: 3
onDisagreement: continue
inputs:
include: [plan_arch]Run it:
ripline run --pipeline pipelines/arch-review.yaml \
--input '{"request": "Design a URL shortening service that handles 10k req/s"}'See docs/review-pipelines.md for the full guide, including the programmatic API (parseChorusTemplate / loadChorusTemplate) and ship config for auto-PR after approval.
Why Ripline exists
Coordinating multiple agents, tools, and humans through ad-hoc scripts doesn't scale. Ripline gives you a typed pipeline engine so every step is explicit:
- Each node has a schema and output contract.
- Runs are traceable and resumable, so you can splice new work in midstream.
- Pipelines live as code/YAML, so you can version them, review them, and hand them to other teams.
Principles
- Visible flow. Every run has a traceable line — nodes, payloads, durations, and retries.
- Multi-agent by default. Review phases distribute work to multiple AI CLIs in parallel and evaluate quorum before proceeding.
- Hot reload. Pipelines are plain YAML/JSON. Edit, reroute, and relaunch without restarting the engine.
- Open surface. CLI + HTTP API + optional dashboards. Use whichever view fits the work.
Feature highlights
- Graph DSL with loops, inline fragments, and reusable sub-pipelines
- Built-in
plan,review, andreview_onlyphase kinds with quorum and retry logic - Voice/lineage registry routing phases to Claude, Codex, Gemini, Kimi, or OpenCode
- Type-checked registry that watches
pipelines/and validates on save - In-memory run store with resumable IDs and JSON payload snapshots
- CLI runner for local testing
- HTTP surface (default
/pipelines) for boards, metrics, and visualizations - Per-node agent runners: optional
runner: claude-codewith plan (read-only) or execute mode and configurablecwd; see Using Claude Code as a runner
Hello World example
A minimal pipeline has three steps: input (consume JSON), transform (compute with a small expression), output (write an artifact).
Pipeline (pipelines/examples/hello-world.yaml):
id: hello_world
name: Hello World Pipeline
entry:
- intake
nodes:
- id: intake
type: input
description: Provide `person` and optional `goal` fields
- id: enrich
type: transform
expression: "({ greeting: `Hello, ${inputs.person}!`, goal: inputs.goal ?? 'explore Ripline' })"
- id: finalize
type: output
path: hello.result
source: enrich
edges:
- from: { node: intake }
to: { node: enrich }
- from: { node: enrich }
to: { node: finalize }Run it:
npm run build
ripline run --pipeline pipelines/examples/hello-world.yaml --input samples/hello-world-inputs.jsonOr run by pipeline ID from your pipeline directory with a profile for default inputs (see Pipelines and profiles):
ripline run hello_world --profile myapp --input '{"task": "add login"}'Outputs are written to .ripline/runs/<runId>/run.json and, if you pass -o <path>, to that file.
Logging
When using the Claude Code runner (runner: claude-code), the runner logs to stderr (and to <runsDir>/<runId>/log.txt when running a stored run):
- Stream messages — Each Claude Agent SDK message is logged with
typeandsubtypeso you can see turns in real time. - Result dump — On
type=result, the full message is logged (truncated to 2000 chars). - Failure detail — On non-success (e.g.
error_max_turns), the runner logssubtype,errors, and a result snippet before throwing. - Config at startup — Set
RIPLINE_LOG_CONFIG=1to logmaxTurns,timeoutMs,mode, andcwdonce per invocation.
Viewing logs:
- CLI:
ripline logs <runId>prints the run's log file;ripline logs <runId> --followpolls and streams new lines until the run completes. Use--api-url http://localhost:4001to fetch from the HTTP server instead of the local runs dir. - HTTP API:
GET /runs/:runId/logsreturns log content (plain text or?format=json);GET /runs/:runId/logs/streamstreams new lines via SSE. See HTTP API.
Run-scoped logs are written to <runsDir>/<runId>/log.txt whenever a run is executed with a file-based run store (e.g. scheduler, server, or CLI with default runs dir).
Quickstart
Clone and install
git clone https://github.com/craigjmidwinter/ripline cd ripline npm installBuild
npm run buildRun the Hello World pipeline
node dist/cli/run.js -p pipelines/examples/hello-world.yaml -i samples/hello-world-inputs.jsonOr run the built-in demo (same pipeline with stub agent, writes to
dist/demo-artifact.json):npm run demoOptional: HTTP server
node dist/cli/run.js serve # default port 4001See docs/http-api.md for available endpoints.
Automation (cron, CI, npx)
Run Ripline from cron, CI, or any automation without cloning the repo.
npx
npx ripline run -p pipelines/examples/hello-world.yaml -i samples/hello-world-inputs.jsonIf the package is installed globally or as a dependency, the ripline bin is available:
ripline run -p <path> [-i <inputs>] [-o <out>]Advanced: area-owner and cron
For the optional area-owner workflow and backlog summary:
npx ripline run -p pipelines/templates/ripline-area-owner.yaml -i samples/ripline-area-owner-inputs.jsonDaily cron example (area-owner, email summary):
0 13 * * * cd /path/to/ripline && npm run build && node bin/ripline.js run -p pipelines/templates/ripline-area-owner.yaml -i samples/ripline-area-owner-inputs.json -o dist/backlog-cron.json 2>&1 | mail -s "Ripline backlog" [email protected]Or use the helper script:
npm run cron:area-ownerSee docs/automation-cron.md for env vars (RIPLINE_INPUTS, RIPLINE_OUT).
GitHub Action
The repo includes .github/workflows/ripline-demo.yml: on push/PR it runs npm run demo and uploads dist/demo-artifact.json as an artifact.
Failure handling
- Exit codes: CLI exits
0on success, non-zero on failure. Use in cron or scripts for alerts or retries. - Resume:
ripline run --resume <runId>to continue a paused or failed run. - Logs: Run state in
.ripline/runs/<runId>/run.json; use--verbosefor per-node logs. - runsDir: Set plugin config
runsDir, CLI--runs-dir, or envRIPLINE_RUNS_DIR. Plan for cleanup; runs are not auto-deleted. - Queue:
ripline run --enqueueadds a run to the queue for later processing (e.g. via worker or HTTP API).
Anatomy of a pipeline
- Node types:
input,transform,agent,http,loop,fork,output, and inline sub-pipelines. - Phase kinds:
plan,review,review_onlyfor multi-agent review workflows (see docs/review-pipelines.md). - Edges: Always explicit. Ripline refuses implicit fall-through so reroutes stay intentional.
- Expressions: JS/TS snippets in a sandbox with
inputs,context, andenv.
Advanced example: product-engineering loop
Ripline can coordinate a multi-stage product flow: area-owner signals → breakdown → design spec → engineering plan → implementation queue. Each agent sees only the slice relevant to its step. See the YAML in pipelines/examples/ripline-area-owner.yaml and docs/templates/ripline-area-owner.md. For simpler copy-paste examples (Implement Story, Spec→Build→Queue, Write Tech Script), see pipelines/examples/ and docs/pipelines/example-pipelines.md.
Documentation
| Guide | Contents | | --- | --- | | Getting started | Installation and first pipeline | | Pipeline reference | All node types, fields, edges, contracts, and template syntax | | Review pipelines | Multi-agent review phases: plan/review/review_only, quorum, retry loop | | CLI reference | All commands, flags, and environment variables | | Configuration reference | All config files, env vars, plugin config, and precedence rules | | HTTP API | REST endpoints for triggering and inspecting runs | | Pipelines and profiles | Pipeline directory, profile system, and user config | | Agent integration | Runner configuration: Claude Code, Codex, Gemini, Kimi, OpenCode | | Automation and cron | Cron jobs, CI, and messaging integrations |
Developing pipelines
| Workflow | What to do |
| --- | --- |
| Reusable nodes | Put fragments in pipelines/lib/*.yaml, reference with type: pipeline |
| Input validation | Use inputs schema blocks in the pipeline definition |
| Debug | Use --verbose for per-node logs |
| Resume | ripline run --resume <runId> restarts from the failed node |
Observability
- run-store: Pluggable provider (memory, SQLite, Dynamo). Defaults to memory.
- events: JSON events (
pipeline.run.started,node.completed,node.errored) for dashboards and 3rd-party sinks. - metrics: Prometheus-style helpers under
/pipelines/metrics.
Multi-agent async orchestration
Ripline is designed for workflows where multiple specialized agents must coordinate without blocking each other. The core pattern: each agent node runs as a fully isolated subprocess, so slow or long-running agents never starve fast ones.
How it works
Pipeline YAML → Ripline scheduler → AI CLI subprocess → JSON artifact
(4 concurrent (isolated session,
workers) fresh context)- Declare the flow as a graph of
agentnodes (or reviewphases) in YAML. Edges express data dependencies, not timing. - Ripline queues runs and dispatches up to
maxConcurrencynodes simultaneously. - Artifacts propagate through the graph: the JSON output of each node becomes available to downstream nodes as template variables (
{{nodeid.text}}or{{variableName}}).
Example: parallel breakdown + spec pipeline
id: product_spec
name: Parallel product spec
entry: [intake]
nodes:
- id: intake
type: input
- id: break-down
type: agent
agentId: vector
prompt: "Break {{task}} into engineering features."
- id: design-spec
type: agent
agentId: nova
prompt: "Write a design spec for these features: {{break-down.text}}"
- id: eng-plan
type: agent
agentId: vector
prompt: "Estimate effort for: {{design-spec.text}}"
- id: result
type: output
source: eng-plan
edges:
- { from: { node: intake }, to: { node: break-down } }
- { from: { node: break-down }, to: { node: design-spec } }
- { from: { node: design-spec }, to: { node: eng-plan } }
- { from: { node: eng-plan }, to: { node: result } }Each agent sees only the slice of context relevant to its step.
Fire-and-forget spawning
Trigger a pipeline run asynchronously via HTTP and poll for completion:
# Enqueue a run (returns immediately with a runId)
run_id=$(curl -s -X POST http://localhost:4001/pipelines/product_spec/runs \
-H "Content-Type: application/json" \
-d '{"task":"OAuth login flow"}' | jq -r '.runId')
# Poll until done
while true; do
status=$(curl -s http://localhost:4001/runs/$run_id | jq -r '.status')
[[ "$status" == "completed" || "$status" == "failed" || "$status" == "errored" ]] && break
sleep 2
done
# Fetch artifacts
curl -s http://localhost:4001/runs/$run_id | jq '.artifacts'Session isolation
By default every agent node gets a fresh session (UUID). This means:
- No history bleeds between pipeline runs or between nodes in the same run.
- You can run the same pipeline concurrently without agents seeing each other's context.
To keep continuity across nodes (e.g. a multi-turn conversation flow), set resetSession: false on downstream nodes and pass a shared sessionId in the run context.
Scaling
| Setting | Effect |
|---|---|
| maxConcurrency: 4 (default) | Up to 4 agent nodes run in parallel across all active pipeline runs |
| timeoutSeconds per node | Per-node deadline; the scheduler kills the subprocess and marks the node errored |
| runsDir | Persist run state across restarts; resume with ripline run --resume <runId> |
Roadmap
- [ ] Type-safe config schemas per node type
- [ ] Browser-side graph editor backed by the HTTP API
- [ ] Agent-to-agent triggers and human approval nodes
- [ ] Terraform-style plan/apply mode for destructive nodes
OpenClaw integration
Ripline can be loaded as an OpenClaw plugin. When running inside an OpenClaw host, the host provides the agent runner and Ripline's pipeline graph executes within the platform's sandbox.
Plugin config example:
{
"id": "ripline",
"from": "./path/to/ripline/openclaw.plugin.json",
"config": {
"pipelinesDir": "./pipelines",
"runsDir": ".ripline/runs",
"maxConcurrency": 4,
"httpPath": "/pipelines",
"httpPort": 4001,
"authToken": "optional-bearer-token"
}
}See docs/agent-integration.md for runner selection rules when inside vs. outside an OpenClaw host.
Contributing
- Fork and clone the repo
npm installthennpm run check && npm test- Open a PR with scenario, steps, and screenshots/logs where relevant
License
MIT © Craig Midwinter
