Runtime-owned AI workbench for local-first, cross-device session continuity.
Version: 1.0.0.
RAH 1.0.0 is the first milestone release for the provider-native runtime boundary. The product
boundary is intentionally narrow:
- Codex, Claude, and OpenCode are the first-class live provider CLIs.
- Codex and OpenCode default to provider
native_local_serverruntimes. RAH talks to the provider server for structured live events/control, and the local terminal uses the provider-native TUI attach client. - Claude defaults to the tmux/TUI mux fallback because it has no stable Codex/OpenCode-style local app-server path for RAH.
- Web New/Resume follows provider runtime capabilities: Codex/OpenCode use native local server; Claude uses the TUI mux fallback.
- structured Chat uses provider server events where available and provider-native history files/DBs for backfill/history. It is not ANSI screen scraping.
- Session sync has a fixed boundary: new live sessions do not show older-history loading; selecting an
existing live session silently syncs the latest tail; only read-only replay or upward scrolling loads
older history. See
docs/history-browsing.zh-CN.md. - Large history is transferred as bounded canonical turn summaries. Resume keeps the already rendered page in place and overlays the resident live projection instead of downloading the same history again.
- OpenCode live catch-up uses its official local-server message API with a bounded recent window; SQLite is reserved for stored-history discovery, paging, and audit rather than the live polling loop.
- tmux screen output is only the native TUI view/control surface for Claude and fallback paths.
- The Web/PWA
TUItab is the explicit handoff point for TUI surfaces. - provider adapters own launch specs, binding probes, mirror parsers, and optional capability catalogs.
- model/permission/plan/effort controls are optional provider enhancements, not the core contract.
The workbench is served through the daemon itself. The stable local entry is:
http://127.0.0.1:43111/
The daemon intentionally listens on 0.0.0.0 so phones/tablets on the LAN can reach the same
workbench when the host firewall/network allows it. Direct loopback access does not require pairing.
Browsers using LAN, Tailscale, or proxy URLs must be paired as trusted devices; reaching the port is
not sufficient to operate RAH remotely.
The Vite server remains a development-only entry:
http://127.0.0.1:43112/
Install dependencies once, or whenever package-lock.json changes:
npm installDaily source workflow:
node bin/rah.mjs restart --no-openThis is the normal command after code changes. It builds the web client, stops the current managed daemon, starts a new daemon from this checkout, and leaves the workbench at:
http://127.0.0.1:43111/
On the first visit from a LAN, Tailscale, or proxy URL, generate a one-time pairing code on the Mac:
node bin/rah.mjs pairEnter that code in the browser. Trusted browsers remain paired until revoked in Settings > Devices.
See docs/device-authentication.zh-CN.md.
If only backend code changed and the web bundle does not need rebuilding:
node bin/rah.mjs restart --no-build --no-openImportant behavior:
startdoes not replace a daemon that is already running.restartis the command that shuts down the old daemon and starts the updated code.restartinterrupts currently managed live provider runtimes because the old daemon is stopped.npm installis not needed for normal code changes.- daemon pid/log files live under
~/.rah/runtime-daemon. - Session creation, resume, Chat, and TUI access live in the Web/PWA workbench. The public CLI no longer starts provider sessions or hands them off to the current terminal.
- Provider runtime selection remains fixed by provider: Codex/OpenCode use native local-server; Claude uses the tmux/TUI fallback behind the Web TUI surface.
- Core live providers are
codex,claude, andopencode. Other model families are available through OpenCode + API providers rather than separate CLI adapters. Seedocs/provider-scope-codex-claude-opencode.zh-CN.md.
Optional: if you want the global rah command to point at this checkout, link it once:
npm link
rah restart --no-openIf the global rah may point at an older install, prefer node bin/rah.mjs ... from this repo.
For LAN access, use the Mac's LAN IP with port 43111.
Useful daemon commands:
node bin/rah.mjs status
node bin/rah.mjs pair
node bin/rah.mjs logs --follow
node bin/rah.mjs stopAdvanced development only:
npm run serve:workbench
npm run dev:daemon
npm run dev:webnpm run build:web
npm run serve:workbench
npm run typecheck
npm run test:protocol
npm run test:provider-contracts
npm run test:web
npm run test:runtime
npm run test:ci
npm run test:regression:e2e-browser
npm run test:native-tui
npm run test:tui-mux-auto
npm run test:tui-mux
npm run test:manual-qa-status
npm run test:smoke:native-codex-browser
npm run test:smoke:native-provider-browser
npm run test:smoke:native-browser
npm run test:smoke:native-browser-webkit
npm run test:smoke:history-resume
npm run test:smoke:tool-flow
npm run test:smoke:claude-flow
npm run test:smoke:claude-browser
npm run test:smoke:codex-browser
npm run test:smoke:opencode-browser
npm run test:smoke:browser-providers
npm run test:smoke:real-browser-providers
npm run test:smoke:provider-flowsRAH now uses four test tiers:
- default gate
npm run test:ci- runs typecheck, all protocol/Web/runtime test files, the production Web build, and
npm audit --omit=dev - Web/runtime tests are discovered recursively and each file runs in an isolated Node test process; adding a test file no longer requires editing a hand-maintained package-script list
- provider contracts
npm run test:provider-contracts- deterministic contract coverage for Codex, Claude, and OpenCode live paths
- protects queued input, no duplicate live/history merge, Stop state convergence, model/mode/permission propagation, and Markdown/timeline rendering contracts on the core live path
- native TUI gate
npm run test:native-tui- exercises the TUI surface lifecycle, fake native provider TUIs, browser replay/reconnect, WebKit browser smoke, mobile input bridge contracts, mirror diagnostics, and native-TUI-specific regression cases
- includes
test:manual-qa-statusso the human QA evidence verifier cannot silently weaken - core live provider expectations are Codex, Claude, and OpenCode
- provider smoke
native-browsernative-codex-browsernative-provider-browsernative-browser-webkithistory-resumetool-flowcodex-browserclaude-flowclaude-browseropencode-browserbrowser-providersreal-browser-providersprovider-flows
- release/CI gate
npm run test:regression:e2e-browser- runs real Codex, Claude, and OpenCode browser smoke against the current local machine
- requires matching provider CLIs, account login, quota, and network to be healthy
Detailed provider regression coverage is tracked in docs/provider-regression-testing.zh-CN.md.
For the current main branch, the preferred smoke coverage is split by runtime:
test:smoke:native-local-server verifies Codex/OpenCode provider-server capabilities, while
test:smoke:native-browser runs deterministic browser/UI smoke coverage for Codex, Claude, and
OpenCode with fake provider backends. native-browser-webkit and native-browser-firefox run the
same browser smoke in alternate engines. The smoke records screenshots for Chat mirror, Web TUI,
reload replay, and Web resume history, and asserts message ordering, duplicate prevention, Stop
state convergence, dirty-prompt blocking, and absence of unexpected provider-event/loading-history
noise on new live sessions.
The formal real-browser regression gate is npm run test:regression:e2e-browser. It runs the real provider browser
smokes for Codex, Claude, and OpenCode and hard-fails on the regressions that have historically hurt
human testing: duplicate bubbles, wrong message order, Stop not disappearing, repeated Stop exiting a
TUI, interrupt notices duplicating/drifting, history replay noise, claim/resume duplication, and
follow-up Web chat turns not reaching the provider.
Manual QA evidence for this branch is checked by:
npm run test:smoke:native-manual-qa-statusGenerate the current-code template with:
RAH_NATIVE_MANUAL_QA_TEMPLATE_OUTPUT=test-results/native-manual-qa.json npm run test:smoke:native-manual-qa-status -- --print-templateThe verifier records a worktreeFingerprint, so pass results are tied to the exact dirty worktree
snapshot being tested, not just the last commit.
Provider smoke is intentionally tied to this local workstation. Installed CLI binaries do not prove authentication, quota, or account access.
npm run test:smoke:browser-providers is the deterministic fake browser gate and currently aliases
test:smoke:native-browser. npm run test:regression:e2e-browser and
npm run test:smoke:real-browser-providers require a known-good local machine with the matching core
provider CLIs authenticated. Different machines may have:
- only some provider CLIs installed
- valid binaries but missing login/auth
- valid auth for one provider but not another
For that reason, provider smoke can still be run explicitly per provider. The old wrapper-control smoke path has been removed; current deterministic coverage lives in the native TUI, native local-server, and browser regression gates.
packages/
runtime-protocol/ Canonical types, event families, contract validation
runtime-daemon/ Runtime engine, event bus, PTY hub, provider adapters
client-web/ Workbench UI consuming the canonical protocol
RuntimeEngineowns the shared session store, event bus, and PTY hub.MuxRuntime/TmuxMuxBackendowns tmux session/pane create, attach, dump, subscribe, raw input, interrupt, close, kill, diagnostics, and recovery.RuntimeTerminalCoordinatoris the single live TUI lifecycle coordinator for native and tmux backed sessions.ProviderAdapteris the seam where concrete providers plug into the runtime.ProviderActivityis the adapter-facing normalization layer.- Codex, Claude, and OpenCode are the core live providers.
- Lower-frequency model families are accessed through OpenCode/API-provider configuration instead of separate RAH CLI adapters.
DebugAdapterremains useful for structured scenario replay and non-provider UI exercise.client-webconsumes the canonical API/events boundary and should not depend on provider-native event names.client-webstore ownership is documented indocs/client-web-store-ownership.zh-CN.md.
The daemon now exposes lightweight provider diagnostics at:
GET /api/providers
Diagnostics intentionally report only:
- launch command
- version probe
- basic runtime status
- Codex
doctor --jsonsummary when available
Provider diagnostics are scoped to the core live providers: Codex, Claude, and OpenCode.
They intentionally do not claim that provider authentication is valid. Codex diagnostics may show
whether Codex reports configured ChatGPT/API-key credentials, app-server status, and reachability via
codex doctor --json, but auth, quota, account entitlement, and token refresh remain managed by the
provider CLI itself.
Current statuses are:
readymissing_binarylaunch_error
RAH keeps the live runtime boundary explicit:
- transcript, tool calls, permissions, usage, attention, and session state are core workbench data.
- Codex/OpenCode live Chat/control uses provider-native local server APIs when available.
- provider-native history files/DBs remain the semantic source for history/backfill.
- tmux/PTY output is a TUI control and viewing surface, not the semantic transcript source.
- only explicit Web/PWA
TUIview claims a TUI display surface. - provider-specific maintenance signals should remain adapter-owned or inspector-only.
1.0.0 is the milestone release for the current runtime scope:
- Codex native local-server WebSocket runtime is wired, and Codex 0.130.0 remote TUI cross-client
sync has passed
scripts/native_local_server_probe.ts. Codex>=0.132.0is now recommended for RAH because it includes stronger MCP replay/elicitation routing, faster TUI startup, and machine-readablecodex doctor --jsondiagnostics. - OpenCode native local-server attach/cross-client sync has passed
scripts/native_local_server_probe.ts. - Claude tmux/TUI mux fallback remains the production continuity path for Claude.
- Chat timeline uses canonical identity/reconciliation to avoid live/history duplicates.
- provider runtime/capability metadata is protocolized so UI controls do not claim unsupported abilities.
- TUI mux diagnostics remain for Claude/fallback paths.
Known RC boundaries:
- Codex/OpenCode real model turn interrupt/archive behavior still requires provider-version QA after CLI upgrades.
- tmux is the only supported mux backend for Claude and future TUI-only fallback providers.
- real provider auth, quota, trust-folder prompts, and slash-command behavior remain owned by the provider TUI.
- iOS/PWA terminal keyboard behavior is still a product QA area, not a protocol guarantee.
- Kimi CLI will not return as a first-class provider unless there is a new product decision; use OpenCode/API-provider configuration instead.
Start here:
Core design and freeze documents: