npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ralphctl

v0.26.0

Published

A ralph harness for long-running AI coding tasks — a generator-evaluator loop that drives Claude Code, GitHub Copilot CLI, OpenAI Codex CLI, OpenCode or Grok Build CLI across one or more repositories

Readme

npm version npm downloads CI License: MIT TypeScript Node.js PRs Welcome Claude Code GitHub Copilot CLI OpenAI Codex CLI OpenCode Grok Build CLI Built with Donuts

ralphctl

A ralph harness for long-running AI coding tasks — a hardened ralph loop that drives your coding agent of choice (Claude Code, GitHub Copilot CLI, OpenAI Codex CLI, OpenCode, or Grok Build CLI) across one or more repositories.

"I'm helping!" — Ralph Wiggum

[!NOTE] Active development. New features and polish ship regularly. Upgrades are best-effort: install the latest version, redo your config, proceed. See Upgrading and CHANGELOG.


What is a ralph harness?

The "Ralph" technique comes from Geoffrey Huntley's Ralph Wiggum as a software engineer: point a coding agent at a task and run it in a loop until the work is done. The bare version (while :; do cat PROMPT.md | claude; done) loops blindly — it re-runs the same prompt and hopes each pass lands. ralphctl is a ralph harness around that idea: instead of blind repetition it runs a generator-evaluator loop, where one pass writes the change and a second independent pass reviews it against the task spec before the loop advances. Same loop, with a verification gate on every step. For the wider picture — what an agent harness is, and how the plan → generate → evaluate → verify loop turns one-shot prompting into a repeatable workflow — see AI Agent Harnesses: A Field Guide.


What is ralphctl?

AI coding agents are powerful but lose context on long tasks, need babysitting when things break, and have no way to coordinate changes across multiple repositories. ralphctl wraps your chosen AI CLI — Claude Code, GitHub Copilot CLI, OpenAI Codex CLI, OpenCode, or Grok Build CLI — in a structured harness that decomposes your work into dependency-ordered tasks, drives each one through a generator-evaluator loop that catches issues before moving on, and persists context across sessions so nothing gets lost.

You describe what to build. ralphctl handles the rest — or works alongside you, whichever you prefer.


Quick Start

npm install -g ralphctl

Needs Node.js ≥ 24 — mise use node@24 or nvm install 24.

Want to poke around before setting up a provider CLI? ralphctl demo seeds a throwaway sandbox project (three sprints, one per pre-flow state) and launches straight into it — zero setup:

ralphctl demo

Otherwise, install one of the supported CLIs and authenticate it:

| CLI | Install | Auth | | ---------------------------------------------------------------------------------- | ------------------------------------ | -------------------------- | | Claude Code | npm i -g @anthropic-ai/claude-code | Anthropic account | | GitHub Copilot CLI | npm i -g @github/copilot | GitHub Copilot seat | | OpenAI Codex CLI | npm i -g @openai/codex | ChatGPT / OpenAI | | OpenCode | npm i -g opencode-ai | your own key, or none | | Grok Build CLI | npm i -g @xai-official/grok | xAI account (grok login) |

Then confirm ralphctl can see it:

ralphctl doctor    # checks your provider CLI is on PATH — and reports auth for the CLIs that can answer — the #1 first-run failure

doctor's auth check is only as honest as each CLI lets it be: Claude Code and OpenAI Codex answer locally via their own auth status / login status verbs, OpenCode reports whether it has a saved credential (its free tier works with zero), and GitHub Copilot and Grok expose no non-interactive auth-status command at all — those rows always report unknown, not a guess. Sign in to Grok with grok login.

When doctor is green, launch:

ralphctl

That's it. The TUI launches, walks you through registering a project, refining your first ticket, generating a task plan, and kicking off implementation. Press + from the home screen to create a new sprint, press n to start a flow (refine / plan / implement / readiness / …), or open the Sprints submenu and follow its on-screen hint to pick or create a sprint. No commands to memorize.

Requirements: Node.js ≥ 24, Git, and one supported AI CLI in PATH and authenticated (OpenCode takes your own keys, or runs on its free tier with none).

Interactive flows (refine / plan / ideate / implement / readiness / create sprint) are TUI-only. The CLI covers inspection and one-shot operations:

# Inspect projects + sprints
ralphctl project list
ralphctl sprint list
ralphctl sprint show <sprint-id>
ralphctl sprint progress <sprint-id>

# Add / inspect tickets
ralphctl ticket add --title "<title>"
ralphctl ticket list
ralphctl ticket publish <ticket-id>

# Manage sprint state
ralphctl sprint activate <sprint-id>
ralphctl sprint close <sprint-id> [-y]      # review → done (-y skips the blocked-task confirm)
ralphctl sprint reopen <sprint-id>          # done → review (makes blocked work reachable again)
ralphctl sprint remove <sprint-id>

# Open a PR for the sprint branch
ralphctl create-pr --sprint <sprint-id>

# Export sprint artifacts
ralphctl export-requirements --sprint <id> --output <path>
ralphctl export-context --sprint <id> --project <id> --output <path>

# Settings
ralphctl settings show
ralphctl settings apply-preset claude-only     # or mixed / copilot-only / codex-only / opencode-only / grok-only / *-economic / *-strong-gate / *-fast / *-frontier
ralphctl settings set ai.implement.generator.provider claude-code
ralphctl settings set ai.implement.generator.model    <model-id>
ralphctl settings set ai.implement.generator.effort   high
ralphctl settings set ai.implement.evaluator.provider openai-codex
ralphctl settings set ai.implement.evaluator.model    <model-id>

How It Works

flowchart LR
    A[Create sprint] --> B[Add tickets] --> C[Refine] --> D[Plan] --> E[Implement] --> F[Review] --> G[Done]

    classDef you fill:#eef2ff,stroke:#6366f1,color:#1e1b4b
    classDef ai fill:#ecfdf5,stroke:#10b981,color:#052e16
    classDef end_ fill:#f1f5f9,stroke:#94a3b8,color:#0f172a
    class A,B you
    class C,D,E,F ai
    class G end_

The first two steps are yours (blue); from Refine onward ralphctl drives (green), with approval gates where your judgement matters.

Refine is implementation-agnostic: the AI clarifies requirements with you, ticket by ticket, and flips each one from pending to approved. Plan requires every ticket approved — the AI explores the affected repos and generates a dependency-ordered task graph. Implement drives those tasks in dependency order through a generator-evaluator cycle: a second AI pass reviews each task against its spec before the harness marks it done and moves on. Independent tasks in the same dependency wave can run in parallel (opt-in) when you want a sprint to finish faster. Review closes the loop — once every task lands, the sprint enters review and you run human-steered feedback rounds: you flag what's off, the AI revises, and the sprint flips to done when you're satisfied. Opening a PR (ralphctl create-pr) is separate and optional.

The loop inside Implement is what separates a ralph harness from a bare while loop — every task passes an independent reviewer before the harness moves on:

flowchart LR
    T[Next task] --> G[Generator] --> E{Evaluator}
    E -->|pass| V{Verify}
    E -->|fail| R[Retry]
    V -->|green| D[Done]
    V -->|red| R
    R --> G
    R -.->|attempts exhausted| B[Blocked]

    classDef work fill:#ecfdf5,stroke:#10b981,color:#052e16
    classDef gate fill:#fefce8,stroke:#eab308,color:#422006
    classDef ok fill:#f1f5f9,stroke:#94a3b8,color:#0f172a
    classDef bad fill:#fef2f2,stroke:#ef4444,color:#450a0a
    class T,G,R work
    class E,V gate
    class D ok
    class B bad

Both gates send the task back, but they spend different budgets: a failed review re-runs the generator within the same attempt (up to harness.maxTurns turns), while a red verify fails the attempt outright and opens a fresh one (up to harness.maxAttempts, after which the task is flagged blocked).

Key properties:

  • Dependency-ordered execution — tasks run in topological order; no task starts until its blockers are done. Opt-in parallelism (concurrency.maxParallelTasks > 1) runs independent tasks within a dependency wave concurrently, each in its own git worktree folded onto one branch — default stays serial
  • Generator-evaluator cycle — an independent AI reviewer checks each task; if it fails, the generator gets the critique and iterates (up to harness.maxTurns turns per attempt, across at most harness.maxAttempts attempts before the task is flagged blocked)
  • Context persistence — sprint state, branch, progress history, and per-task context survive across sessions; interrupted runs resume automatically
  • Multi-repo support — one sprint can span several repositories with per-repo setup and verify scripts

For the full architectural picture see .claude/docs/ARCHITECTURE.md and .claude/docs/REQUIREMENTS.md.

GitHub and GitLab issues

ralphctl can create a GitHub or GitLab issue from a local ticket, and can post approved requirements as a comment on a linked issue. Both writes are opt-in. Neither rewrites the issue body.

Create on add. The TUI add-ticket wizard asks whether to create a tracker issue (default No) when the new ticket has no link and the project's first configured repository resolves to GitHub or GitLab. Yes creates the issue with that ticket's title and body and stores the returned URL as the ticket's link. ralphctl ticket add saves the ticket locally and does not ask.

Comment on approval. Refine can post approved requirements as a comment (default No, only when the ticket has a link). The approval menu default is Approve. Post as comment appears only for a linked ticket; choosing it posts the approved requirements as a new comment on that linked issue. Repeating the same approved text does not add another comment.

Retry with publish. ralphctl ticket publish <ticketId> and sprint-detail p run the same write with no second prompt: create when the ticket has no link, comment when it already has a link and approved requirements. Create uses the first configured repository origin. Comments use the ticket's existing link.


Providers

ralphctl drives five AI coding CLIs. All five run every flow and are supported first-class. Pick one per flow — or mix them, say plan with one and implement with another — through a preset or per-row settings.

| Provider | CLI | Install | Auth | Context file | | ----------------------------------------- | ---------- | ------------------------------------ | -------------------------- | --------------------------------- | | Claude Code (claude-code) | claude | npm i -g @anthropic-ai/claude-code | Anthropic account | CLAUDE.md | | GitHub Copilot CLI (github-copilot) | copilot | npm i -g @github/copilot | GitHub Copilot seat | .github/copilot-instructions.md | | OpenAI Codex CLI (openai-codex) | codex | npm i -g @openai/codex | ChatGPT / OpenAI | AGENTS.md | | OpenCode (opencode) | opencode | npm i -g opencode-ai | your own key, or none | AGENTS.md | | Grok Build CLI (xai-grok) | grok | npm i -g @xai-official/grok | xAI account (grok login) | AGENTS.md |

Codex, OpenCode, and Grok share one repo-root AGENTS.md. Readiness for more than one of them writes that file in sequence; each later pass keeps the previous body at AGENTS.md.bak.<timestamp>.

Which one?

  • Claude Code — read-only flows deny the edit, shell and network tools at the CLI level, the finest-grained gate of the five.
  • GitHub Copilot CLI — no extra billing relationship if you already have a seat. Read-only flows deny the shell tool; file writes stay open, bounded by path scope.
  • OpenAI Codex CLI — a natural fit inside the ChatGPT/OpenAI ecosystem. Its sandbox has two modes only, so path scope is the fine-grained safety envelope.
  • OpenCode — vendor-neutral: it fronts 75+ providers and local runtimes on a bring-your-own-key model, so you can run a specific model, a local model, or no account at all.
  • Grok Build CLI — xAI's coding CLI (grok-4.7 / grok-4.6). Read-only flows deny edit and shell by permission rule (--deny 'Edit(./**)', cwd-rooted, plus --deny 'Bash(*)' and both shell tool ids); Grok has no separate write tool, so creating signals.json outside the denied path stays possible. Both Grok surfaces pass --trust, since the AGENTS.md and .grok/skills it loads at startup are files ralphctl wrote itself. Extra roots are a named over-grant — Grok has no --add-dir and --sandbox off is forced.

On every backend the agent can always create the harness's signals.json — four keep the Write tool open, and Grok, which has no write tool, scopes its edit deny rule to --cwd instead — so path scope (cwd + mounted roots) is always part of the safety envelope. See the provider reference for the exact mapping.

Bundled skill injection and forensic capture work on all five; only the on-disk skills directory differs (.claude/ / .github/ / .agents/ / .opencode/ / .grok/). Parallel execution is provider-agnostic. Claude Code has the most real-world mileage simply because it came first — the others are equally supported, with correspondingly less of it.

📖 Full provider reference → — permission mapping per backend, per-provider setup, model ids, mixing backends, and known limitations.

Hit a rough edge with any provider? Please open an issue.

One-shot configuration: ralphctl settings apply-preset <name> where <name> is one of 26 presets — standard, economic, strong-gate, fast, and frontier families, each in mixed / claude-only / copilot-only / codex-only / grok-* variants, plus opencode-only in the standard family.


Features

  • Break big tickets into small tasks — dependency-ordered so they execute in the right sequence
  • Catch mistakes before they compound — independent AI review after each task, iterating until quality passes or budget is exhausted
  • Coordinate across repositories — one sprint can span multiple repos with automatic dependency tracking
  • Finish sprints faster (opt-in) — run independent tasks within a dependency wave in parallel, each in its own git worktree, folded back onto one sprint branch (still one PR); default stays serial, zero change
  • Branch per sprint — optional shared branch across every affected repo; ralphctl create-pr --sprint <id> opens a PR / MR via gh or glab when you're done
  • Recover from rate limits — exponential backoff and session resume keep the in-flight task's full context when the provider restarts
  • Separate the what from the how — AI clarifies requirements first (Refine), then generates the implementation plan (Plan), with human approval gates between
  • Pick up where you left off — full state persistence; interrupted Implement runs resume in-progress tasks first — the crashed attempt is settled as aborted (kept in history) and a fresh attempt opens automatically
  • Pair or let it run — work alongside your AI agent interactively, or let it execute unattended
  • Zero-memorization start — run ralphctl with no args for a guided menu
  • Bring your own model — five backends to choose from, one of which (OpenCode) is vendor-neutral, so the harness reaches hosted, aggregated, and local models alike

Configuration

Configure via the TUI Settings view or one-shot CLI commands.

Quickest path — apply a preset. Presets auto-seed from your detected CLIs on first run; override later with apply-preset.

# Standard — flagship model per flow
ralphctl settings apply-preset mixed               # best-fit provider per flow
ralphctl settings apply-preset claude-only         # every flow on Claude Code
ralphctl settings apply-preset copilot-only        # every flow on GitHub Copilot CLI
ralphctl settings apply-preset codex-only          # every flow on OpenAI Codex CLI
ralphctl settings apply-preset opencode-only       # every flow on OpenCode's free tier (no auth)
ralphctl settings apply-preset grok-only           # every flow on Grok Build CLI

# Economic — implement starts one tier below flagship; escalation ladder climbs only on plateau
ralphctl settings apply-preset mixed-economic
ralphctl settings apply-preset claude-economic
ralphctl settings apply-preset copilot-economic
ralphctl settings apply-preset codex-economic
ralphctl settings apply-preset grok-economic

# Strong-gate — cheap generator, permanently-flagship evaluator gate
ralphctl settings apply-preset mixed-strong-gate
ralphctl settings apply-preset claude-strong-gate
ralphctl settings apply-preset copilot-strong-gate
ralphctl settings apply-preset codex-strong-gate
ralphctl settings apply-preset grok-strong-gate

# Fast — cheapest viable tier at low effort; plateau settles rather than escalating (escalateOnPlateau=false)
ralphctl settings apply-preset mixed-fast
ralphctl settings apply-preset claude-fast
ralphctl settings apply-preset copilot-fast
ralphctl settings apply-preset codex-fast
ralphctl settings apply-preset grok-fast

# Frontier — the vendor's top model on plan/implement at max effort; light flows stay below max.
# Claude/Codex step up to Fable 5.1 / gpt-6-astra (Fable 5.1 needs a non-ZDR org);
# Copilot/Grok keep their flagship (Opus 4.8 / grok-4.7).
ralphctl settings apply-preset mixed-frontier
ralphctl settings apply-preset claude-frontier
ralphctl settings apply-preset copilot-frontier
ralphctl settings apply-preset codex-frontier
ralphctl settings apply-preset grok-frontier

Twenty-six presets ship, all equally first-class — none is marked default. opencode-only stays a single preset in the standard family: every free-tier model is at the same (zero) price point, so economic / frontier variants of it would differ in name only. Grok has a variant in every family (grok-4.5 / grok-4.6 / grok-4.7). Mixed presets stay a cross-provider split (Claude author, Codex critic) and were not rerouted onto Grok. Applying a preset stamps the entire ai section plus harness.escalateOnPlateau in one transaction (fast stamps it false so a plateau settles; all others stamp it true). On a fresh install the welcome view silently auto-seeds a preset based on which provider CLIs it detects on PATH.

Per-flow settings. Each flow carries its own {provider, model, effort?} row: refine, plan, readiness, ideate, and createPr. The implement flow instead splits into a nested generator / evaluator pair (ai.implement.generator.* and ai.implement.evaluator.*), each its own {provider, model, effort?} row. Edit individual keys with:

ralphctl settings set ai.implement.generator.provider claude-code
ralphctl settings set ai.implement.generator.model    <model-id>
ralphctl settings set ai.implement.generator.effort   high

ralphctl settings set ai.plan.provider      github-copilot
ralphctl settings set ai.plan.model         <model-id>

The selected provider's CLI must be in your PATH and authenticated. Every AI-spawning flow probes its row's CLI at launch and exits with a clear error if the binary is missing.

Tune the generator-evaluator loop (under harness):

ralphctl settings set harness.maxAttempts 2          # Cap fix attempts per task (1–10, default 3)
ralphctl settings set harness.maxTurns    8          # Generator-evaluator turns per attempt (1–10)
ralphctl settings set harness.rateLimitRetries 3     # Adapter-side 429 retries (0–10)

Run tasks in parallel (optional — default is serial):

ralphctl settings set concurrency.maxParallelTasks 3   # 1–5; 1 = serial (default), >1 = parallel git worktrees

When > 1, independent tasks within a dependency wave run concurrently — each in its own git worktree, with its own setupScript run, folded back onto the single sprint branch (still one PR per sprint). A task whose worktree setup fails is blocked on its own without stopping its siblings; if two same-wave tasks edit the same file, the second is blocked at fold time and a relaunch retries it. Dependencies are always respected — only independent tasks overlap.

Data directory

All state lives in ~/.ralphctl/ by default (settings under config/, sprints + projects under data/, advisory locks under state/). Override the root with:

export RALPHCTL_HOME="/path/to/custom/dir"

Environment variables

| Variable | Default | Purpose | | ---------------------------- | -------------- | ---------------------------------------------------- | | RALPHCTL_HOME | ~/.ralphctl/ | Override application root (data + config + state) | | RALPHCTL_SKIP_LEGACY_CHECK | unset | Bypass the v0.6.x legacy-layout detector at boot | | RALPHCTL_DEBUG_TRACE | unset | Write a <sprintDir>/events.ndjson debug trace | | RALPHCTL_NO_TUI | unset | Suppress implicit interactive prompts in implement | | NO_COLOR | unset | Suppress ANSI colors | | CI | auto-detected | Suppress implicit interactive prompts in implement |

Log verbosity is settings.logging.level (silent / debug / info / warn / error, default info), set via ralphctl settings set logging.level <level> or the TUI Settings view — not an environment variable.


Upgrading

Install the latest version, redo your config, proceed. Only the latest release is supported — there's no backporting, and upgrading is the answer to most "is this fixed?" questions.

npm install -g ralphctl@latest
ralphctl settings apply-preset <name>    # if your settings need a reset
ralphctl                                  # TUI prompts you to re-register projects if needed

If your ~/.ralphctl/ data from an older release doesn't load cleanly, back it up and start fresh:

mv ~/.ralphctl ~/.ralphctl.bak

The backup keeps your ticket bodies, plan output, and progress notes around for reference. See MIGRATION.md if you're crossing a major boundary (e.g. 0.6.x → 0.7.x) and want the longer story.


The CLI surface is deliberately smaller than v0.6.x — interactive flows (refine / plan / ideate / implement / readiness / create sprint) stay TUI-only by design. The CLI exposes inspection + one-shot operations.

Getting Started

| Command | Description | | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ralphctl | Interactive TUI (primary surface) | | ralphctl demo | Seed a throwaway sandbox project and launch straight into it — zero setup, no provider CLI required to look around (--no-launch to seed only, --home <dir> to relocate) | | ralphctl doctor | Check environment health | | ralphctl settings show | Print current settings | | ralphctl settings set <key> <value> | Set a single settings key | | ralphctl settings apply-preset <name> | Stamp the entire ai section — 26 presets: standard / economic / strong-gate / fast / frontier families, each in mixed / *-only variants (Grok included), plus opencode-only | | ralphctl completion <shell> | Print shell tab-completion script | | ralphctl agents list | List bundled + operator agent definitions and the implement role each is bound to | | ralphctl skills list | List bundled + manually-dropped skills — tier, enabled flows, provenance |

Project & Sprint Inspection

| Command | Description | | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | ralphctl project list | List registered projects | | ralphctl project show <id> | Show one project (incl. repositories) | | ralphctl project remove <id> | Delete a project registration | | ralphctl sprint list | List all sprints | | ralphctl sprint show <id> | Show one sprint (tickets, status, branch) | | ralphctl sprint progress <id> | Sprint progress with blocker diagnostics | | ralphctl sprint set-current <id> | Switch the current sprint pointer | | ralphctl ticket add --title <title> | Add a ticket to the current sprint (--sprint, --description, --link optional); does not ask to create a tracker issue | | ralphctl ticket list / show <id> | Inspect tickets | | ralphctl ticket publish <id> | Create a tracker issue or post the approved-requirements comment (--sprint optional); no second prompt | | ralphctl ticket remove <id> | Remove a ticket from a draft sprint | | ralphctl task list / show <id> | Inspect tasks (planning generates them) | | ralphctl task evaluation <id> | Print the latest evaluator verdict (evaluation.md) for the task's last attempt | | ralphctl task unblock <id> | Reset a blocked task to todo (--prior-work continue\|fresh picks what its rejected diff in git stash does next) |

Sprint Lifecycle

| Command | Description | | --------------------------------- | ----------------------------------------------------------------------------------------------------------- | | ralphctl sprint activate <id> | Flip a draft sprint to active | | ralphctl sprint close <id> [-y] | Transition review → done; confirms first when any task is still blocked (-y/--yes skips the prompt) | | ralphctl sprint reopen <id> | Reopen a closed sprint done → review so its blocked work is reachable again (idempotent) | | ralphctl sprint remove <id> | Delete a sprint permanently |

Export & PR

| Command | Description | | -------------------------------------------------------------------------- | -------------------------------------------------------------- | | ralphctl export-requirements [--sprint <id>] --output <path> | Render approved-ticket requirements to markdown | | ralphctl export-context [--sprint <id>] [--project <id>] --output <path> | Render harness context (sprint + project + tasks) to markdown | | ralphctl create-pr --sprint <id> [--base <branch>] [--draft] | Open a PR/MR via gh or glab, persist the URL on the sprint |

Maintenance

| Command | Description | | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | | ralphctl runs list [--flow <name>] | List per-run forensic artifacts grouped by flow | | ralphctl runs stats [--sprint <id>] [--project <id>] [--since <date>] [--json] | Harness outcome rollup — outcome mix, first-pass rate, plateaus, escalation efficacy | | ralphctl runs prune [--older-than 7d] [--keep-last <n>] [--flow <name>] [--dry-run] [-y] | Delete per-run forensic artifacts |

Run ralphctl <command> --help for flag-level detail.


Documentation

| Resource | Description | | ------------------------------------------------ | -------------------------------------------------------- | | Architecture | Data models, harness loop, file storage, error reference | | Providers | Per-backend setup, permission mapping, model ids, limits | | Adding a provider | Extension guide: wire a new AI CLI into the harness | | Requirements | Acceptance criteria and feature checklist | | Contributing | Dev setup, code style, PR process | | Migration | Per-version upgrade context for big version jumps | | Changelog | Version history |

From the author (Lukas Grigis): Building ralphctl (backstory) | From task CLI to ralph harness (evaluator deep-dive) | The harness era caught up (the field converges on the harness bet)

Further reading: AI Agent Harnesses: A Field Guide — Lukas Grigis | Harness Engineering for Coding Agent Users — Birgitta Böckeler, martinfowler.com (April 2026) | Harness Design for Long-Running Application Development — Anthropic Engineering


Development

git clone https://github.com/lukas-grigis/ralphctl.git
cd ralphctl
pnpm install
pnpm dev --help          # Run CLI in dev mode (tsx, no build needed)
pnpm build               # Compile for npm distribution (tsup)
pnpm typecheck           # Type check
pnpm test                # Run tests
pnpm lint                # Lint

Contributing

Contributions are welcome! Please open an issue first to discuss what you'd like to change.

See CONTRIBUTING.md for the full guide — dev setup, code style, PR process, and releasing.

This project follows the Contributor Covenant code of conduct.


Security

To report a vulnerability, use GitHub's private reporting. See SECURITY.md for details.


License

MIT — see LICENSE for details.