Ralpher is a web dashboard and REST API for running, reviewing, and iterating on Ralph Loops with ACP-compatible agents such as Copilot and OpenCode. It keeps autonomous coding work manageable by starting each iteration with fresh context while persisting state in .ralph-planning/.
The repository is organized as a workspace-style monorepo:
apps/server- Bun server that embeds and serves the web app alongside the APIapps/web- browser bundle workspace for the shared web app assetsapps/cli- standalone API client CLIapps/tuiandapps/electron- reserved stubs for future client surfacespackages/shared,packages/contracts,packages/client-sdk- shared runtime-neutral types/helpers, API contracts, and client transport/auth utilities
The recommended workflow is to treat Ralpher as a controller for SSH-backed development environments, even when that SSH host is just your own machine.
- Register an
sshserver in Ralpher. Usinglocalhostis a great default if you want the SSH workflow without needing a separate remote machine. - Create an automatic workspace for each project you want to work on, and let that workspace use your devbox-managed environment so tools and dependencies are ready inside the project context.
- Once the workspace is ready, either open chats to work interactively with the coding agent in that workspace or create a new loop, write the task prompt, and let the agent work autonomously.
Dashboard overview with active loops, workspaces, and quick actions.
- Fresh context, persistent progress. Ralph Loops use
.ralph-planning/plan.mdand.ralph-planning/status.mdto keep long tasks moving across clean agent context windows. - Safer automation. Each loop works in its own branch/worktree, commits iteration-by-iteration, and can be merged or discarded deliberately.
- Operational visibility. The dashboard gives you logs, diffs, plan review, loop controls, and follow-up flows in one place.
- Local or remote execution. Workspaces can use local
stdiotransport or remotesshtransports, with optional SSH sessions and port forwarding.
More screenshots
Create a loop with prompt, model, and execution settings.
Track iteration status and loop progress in real time.
Review the accumulated changes before accepting or pushing them.
Open persistent SSH sessions alongside loop execution.
Install the latest Linux or macOS binary releases:
curl -fsSL https://raw.githubusercontent.com/pablozaiden/installer/main/install.sh | sh -s -- pablozaiden/ralpherThe shared installer downloads the latest release assets for Linux or macOS (x64 or arm64) and installs both ralpher and ralpher-cli in $HOME/.local/bin. If that directory is not on your PATH, the installer prints the shell profile line to add.
You can also download binaries directly from the Releases page.
Once installed from a release binary, you can update the installed release binaries in place:
ralpher-cli update --check
ralpher-cli update
ralpher-cli update --version v0.8.1ralpher-cli update is currently supported for the published Linux and macOS release binaries only. It updates ralpher-cli, also updates a sibling ralpher binary when one is installed beside it, verifies published checksums, and prints progress while release metadata and binary downloads are in flight. If you are running Ralpher from source with Bun, use the shared installer or download release binaries instead of self-updating.
- Git
- An ACP-capable CLI in your
PATH(opencodeand/orcopilot) - Optional SSH access to remote workspace hosts if you plan to use
sshtransport - Bun 1.3.5+ only if you want to run Ralpher from source
# Installed server binary (embedded API + web, same-origin)
ralpher
# Source development (combined API + web, same-origin)
bun dev
# Server process only
bun run dev:serverThe UI is available at http://localhost:3000 by default. Use RALPHER_PORT to change the port and RALPHER_HOST to change the bind address.
The normal development and published runtime is same-origin: the Bun server hosts the React app and the API together, and the frontend defaults to relative /api requests.
In development, bun dev watches the shared web bundle in apps/web/dist and serves that processed output from the server so Tailwind/CSS behaves the same way as the bundled app.
The separately installed ralpher-cli binary exposes the terminal client surface:
# Check which version is installed
ralpher-cli version
# Check whether a newer published binary is available
ralpher-cli update --check
# Update the installed release binaries in place
ralpher-cli update
# Install a specific published release
ralpher-cli update --version v0.8.1
# Start device authorization against a specific Ralpher server
ralpher-cli auth http://localhost:3000
# Check whether stored CLI credentials are still valid
ralpher-cli status
# List the discoverable REST endpoints
ralpher-cli api
# Invoke an authenticated API request (prints one JSON object)
ralpher-cli api loops/my-loop --method GET
# Inspect the expected schema for an endpoint
ralpher-cli schema auth/device
# Stream authenticated websocket events over stdio
ralpher-cli ws --loop-id my-loop- Open the dashboard and click New Loop.
- Pick or create a workspace that points at your repository.
- Choose the provider and transport for that workspace.
- Write the task prompt, select the model, and create the loop.
- Review plans, logs, diffs, and final changes from the loop details view.
A Ralph Loop is an external execution loop around an AI coding agent. Instead of keeping all history inside one growing chat, each iteration starts fresh and reads the project state from the filesystem.
| Principle | Description |
|---|---|
| Fresh context per iteration | Every iteration starts with a clean agent context window. |
| Filesystem state | Progress lives in .ralph-planning/plan.md and .ralph-planning/status.md. |
| Stop condition | The loop ends when the configured completion pattern is produced. |
| Git isolation | Changes stay isolated in a branch/worktree until you accept, push, or discard them. |
- Dashboard + API: manage loops from the browser or automate them through the REST API.
- Plan mode: review and refine a generated plan before code changes begin.
- Review cycles: continue from completed, pushed, or merged work with follow-up prompts and review comments.
- Live observability: stream logs, inspect diffs, and track loop state over WebSocket updates.
- Workspace flexibility: configure provider and transport per workspace, including remote SSH-backed execution.
- Testing support: use
RALPHER_MOCK_ACP=trueto replace local provider launches with the built-in mock ACP runtime.
| Variable | Description | Default |
|---|---|---|
RALPHER_HOST |
Host/interface passed to Bun.serve |
127.0.0.1 |
RALPHER_PORT |
HTTP port | 3000 |
RALPHER_DATA_DIR |
Data directory for SQLite persistence | ./data |
RALPHER_REMOTE_ONLY |
Disables local stdio transport |
unset |
RALPHER_MOCK_ACP |
Uses the built-in fake ACP runtime for local testing | unset |
RALPHER_DISABLE_PASSKEY |
Bypasses passkey enforcement when set to true, 1, or yes |
unset |
RALPHER_DISABLE_SAME_ORIGIN_CHECK |
Disables Origin/Referer validation for state-changing requests and WebSocket upgrades |
unset |
RALPHER_LOG_LEVEL |
Server log level override | info |
- Same-origin protection is enabled by default for mutating API requests and WebSocket upgrades by requiring
OriginorRefererto match the effective request origin. - Passkey authentication protects the browser session and device-approval flow.
- Bearer tokens are issued through the device authorization flow and work as an alternative to the browser passkey session for APIs, WebSocket upgrades, and forwarded-port proxy access.
ralpher-cli authstores bearer credentials in per-user CLI state under the home directory,ralpher-cli statusvalidates them throughGET /api/auth/status,ralpher-cli apisends authenticated REST calls with the stored tokens,ralpher-cli wsuses those same credentials for authenticated websocket upgrades to/api/ws, andralpher-cli schemaexposes endpoint discoverability data from the built-in API catalog.- Ralpher exposes
/.well-known/openid-configurationand/.well-known/jwks.jsonso external clients can verify access tokens. - Set
RALPHER_DISABLE_PASSKEY=true,1, oryesto bypass only the passkey requirement as an emergency override. - Set
RALPHER_DISABLE_SAME_ORIGIN_CHECK=true,1, oryesonly for development setups where the frontend intentionally runs on a different local origin than the backend. Leave it unset in normal and production deployments. - In production, Ralpher is typically deployed behind a reverse proxy that handles authentication and authorization.
services:
ralpher:
image: ghcr.io/pablozaiden/ralpher:latest
ports:
- "8080:8080"
volumes:
- ralpher-data:/app/data
environment:
RALPHER_DATA_DIR: /app/data
volumes:
ralpher-data:The container listens on port 8080 by default and starts the same embedded server product that the ralpher binary runs locally. Docker overrides the bind host to 0.0.0.0; local/native runs default to 127.0.0.1 unless you override RALPHER_HOST.
git clone https://github.com/pablozaiden/ralpher.git
cd ralpher
bun install
bun run build
bun run test
bun devbun run build creates a standalone executable in dist/ralpher.
It also builds apps/server/dist/ralpher and apps/cli/dist/ralpher-cli.
To repopulate local demo data for the UI, run:
bun tests/test-data-generation/generate-demo-ui-data.ts- Fork the repository.
- Create a feature branch.
- Make your changes with tests when appropriate.
- Run
bun run build && bun run test. - Open a pull request.




