English | 日本語
Roboppi (ろぼっぴ, pronounced "roh-boh-pee") is an execution-control runtime for agentic workers.
It does not try to be "the agent". It enforces safety invariants around external worker CLIs (OpenCode / Claude Code / Codex CLI / plain shell), so your automation stops when it should, stays within budgets, and leaves a trail you can audit.
Note: the primary CLI/binary name is roboppi.
- Env vars/state dirs: use
ROBOPPI_/.roboppi-loop/.
Execution control (Core runtime):
- Enforce hard budgets: timeouts, max attempts, concurrency, RPS, optional cost caps
- End-to-end cancellation: Job -> Permit -> Worker via AbortSignal (best-effort SIGTERM -> SIGKILL)
- Failure containment: circuit breakers + backpressure responses under overload
- Process isolation: delegate heavy work to separate worker processes (limit blast radius)
- Auditability: structured logs + artifacts (stdout/stderr summaries, diffs/patches, executed commands, timings)
Workflow orchestration (YAML):
- Run multi-step DAG workflows (
depends_on) with optional parallelism (concurrency) - Pass files between steps with declared
outputs/inputsvia acontext/directory - Automatic step retries and failure policy (
retry/continue/abort) - Loop until complete with
completion_check+max_iterations - Optional convergence guard for loops: stall detection + scope/diff budgets (
allowed_paths,max_changed_files)
Automation (Daemon mode):
- Run workflows on interval/cron/fswatch/webhook/command events
- Optional evaluate/analyze gates (run LLM work only when conditions are met)
- Supervised execution: Supervisor -> Core -> Worker process tree via IPC (socket-based transport available)
Repo safety (git workspaces):
- Deterministic base branch resolution (records base commit SHA)
- Branch Lock drift detection (fail-fast before a step runs)
- Protected-branch guard to avoid direct edits on
main(override must be explicit)
Extensibility:
- Add worker adapters behind a unified
WorkerAdapterinterface - Reusable agent profiles via agent catalogs (
agents.yaml) referenced bystep.agent
Scheduling (reference implementation):
- Prioritized job queue (interactive vs batch)
- Deduplication via idempotency keys (
coalesce/latest-wins/reject) - Retry policy (exponential backoff + jitter) + DLQ storage
- Supervisor that launches/monitors the Core process (crash/hang handling)
Roboppi is designed as a 3-layer system:
Supervisor / Runner (policy, parent process)
-> Core (mechanism, child process)
-> Worker processes (external CLIs)
- Core owns safety invariants (permits, budgets, cancellation, cutoffs).
- Policy (ordering, retries, dedup strategy) stays swappable at the supervisor/runner level.
- Core and supervisor communicate over JSON Lines IPC.
Design docs:
docs/design.mddocs/guide/architecture.md
Prerequisites:
- Bun (CI uses Bun 1.3.8)
Optional worker CLIs (depending on what you want to delegate to):
- OpenCode:
opencode - Claude Code:
claude - Codex CLI:
codex - Optional (PR creation in demos):
gh
Install dependencies:
bun installBuild the binary (optional):
make build
./roboppi --help
./roboppi workflow --help
./roboppi daemon --helpStart a JSON Lines IPC server (reads stdin, writes stdout; logs go to stderr):
./roboppiIf you are building your own Supervisor/Scheduler, this is the Core process you talk to.
roboppi run delegates a single task to a worker with a strict timeout/budget.
# One-shot: have OpenCode create files
./roboppi run --worker opencode --workspace /tmp/demo \
--capabilities READ,EDIT --timeout 60000 \
"Write a README for this repo"Workflows are executed by the workflow runner.
./roboppi workflow examples/hello-world.yaml --verbose
# (dev) bun run src/workflow/run.ts examples/hello-world.yaml --verboseBy default, workflows run in supervised mode (Supervisor -> Core -> Worker).
Use --direct to spawn workers directly from the runner (no Core IPC).
ROBOPPI_VERBOSE=1 bun run src/workflow/run.ts examples/agent-pr-loop.yaml \
--workspace /tmp/my-work --verboseDocs:
docs/guide/workflow.mddocs/workflow-design.md
./roboppi daemon examples/daemon/agent-pr-loop.yaml --verbose
# (dev) bun run src/daemon/cli.ts examples/daemon/agent-pr-loop.yaml --verboseDocs:
docs/guide/daemon.md
The demo creates a scratch git repo under /tmp/ and runs the full loop:
design -> todo -> (implement <-> review/fix)* -> (optional) create_pr
bash examples/agent-pr-loop-demo/run-in-tmp.shTo enable PR creation in the demo, create the marker file in the target repo:
touch "/path/to/target/.roboppi-loop/enable_pr"Run the PR loop against your own repo (recommended: run from this repo, target another workspace):
ROBOPPI_ROOT=/path/to/roboppi
TARGET=/path/to/your/repo
mkdir -p "$TARGET/.roboppi-loop"
$EDITOR "$TARGET/.roboppi-loop/request.md"
ROBOPPI_ROOT="$ROBOPPI_ROOT" bun run --cwd "$ROBOPPI_ROOT" src/workflow/run.ts \
"$ROBOPPI_ROOT/examples/agent-pr-loop.yaml" \
--workspace "$TARGET" --verboseNotes:
- The workflow writes state/artifacts under
.roboppi-loop/andcontext/inside the target workspace (typically gitignored). - PR creation is opt-in via
.roboppi-loop/enable_pr.
Minimal example:
name: build-test
version: "1"
timeout: "10m"
steps:
build:
worker: CUSTOM
instructions: "make build"
capabilities: [RUN_COMMANDS]
test:
depends_on: [build]
worker: CUSTOM
instructions: "make test"
capabilities: [RUN_TESTS]For loops:
- use
completion_check+max_iterations - prefer
decision_filefor deterministic COMPLETE/INCOMPLETE decisions
See docs/guide/workflow.md for the full schema.
If you repeat the same worker/model/capabilities/base-instructions across steps, define an agent catalog:
version: "1"
agents:
research:
worker: OPENCODE
model: openai/gpt-5.2
capabilities: [READ]
base_instructions: |
You are a research agent.
- Only read files. Do not edit.Then reference it from workflow steps:
steps:
investigate:
agent: research
instructions: "Investigate the codebase and write notes."Docs:
docs/guides/agents.mddocs/guides/agents.ja.md
For workflows that operate on git repos, Roboppi provides base-branch resolution, Branch Lock drift detection, and protected-branch guards.
Useful flags:
--base-branch <name>(overridesBASE_BRANCH)--protected-branches <csv>(default:main,master,release/*)--allow-protected-branch(dangerous; explicit override)
Docs:
docs/guides/branch.mddocs/guides/branch.ja.md
Workflows/daemon run supervised by default. In supervised mode, the runner starts a Core child process and delegates steps over IPC.
- Default: interactive runs typically use stdio; non-interactive runs default to a socket transport.
- Override transport:
ROBOPPI_SUPERVISED_IPC_TRANSPORT=stdio|socket|tcp - Debug IPC:
ROBOPPI_IPC_TRACE=1 - Tune request timeouts:
ROBOPPI_IPC_REQUEST_TIMEOUT=2m(orROBOPPI_IPC_REQUEST_TIMEOUT_MS=120000)
Disable supervised mode:
- Workflow runner:
--direct - Daemon CLI:
--direct
docs/guide/quickstart.mddocs/guide/workflow.mddocs/guide/daemon.mddocs/guide/architecture.mddocs/design.mddocs/guides/agents.mddocs/guides/branch.md
make typecheck
make test
make test-allThis project is still evolving and APIs/behavior may change. The design intent is stable (mechanism/policy separation + permits + process isolation); the surface area (CLI flags, YAML schema) may continue to iterate.
