mirror of
https://github.com/mikeyobrien/ralph-orchestrator.git
synced 2026-04-25 07:05:57 +03:00
[PR #200] [MERGED] feat(rpc): subprocess TUI via JSON-RPC stdin/stdout protocol #195
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/ralph-orchestrator#195
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/mikeyobrien/ralph-orchestrator/pull/200
Author: @mikeyobrien
Created: 2/26/2026
Status: ✅ Merged
Merged: 2/26/2026
Merged by: @mikeyobrien
Base:
main← Head:fix/rpc-review-sweep📝 Commits (7)
8e193f7feat(proto): add JSON-RPC protocol types for stdin/stdout communicationf94b51efeat(adapters): add JsonRpcStreamHandler for JSON-lines output1ed626afeat(cli): add RPC stdin command reader and dispatcherc212d4ffeat(cli): wire JSON-RPC mode into orchestration loop4209377feat(tui): convert TUI to JSON-RPC client mode376ee87feat(cli): make subprocess TUI the default mode5593036fix(rpc): harden JSON-RPC protocol layer📊 Changes
22 files changed (+4933 additions, -96 deletions)
View changed files
📝
Cargo.lock(+21 -0)📝
Cargo.toml(+2 -0)➕
crates/ralph-adapters/src/json_rpc_handler.rs(+348 -0)📝
crates/ralph-adapters/src/lib.rs(+2 -0)📝
crates/ralph-adapters/src/pi_stream.rs(+20 -4)📝
crates/ralph-adapters/src/pty_executor.rs(+120 -4)📝
crates/ralph-adapters/src/stream_handler.rs(+15 -1)📝
crates/ralph-api/src/runtime/dispatch.rs(+27 -0)📝
crates/ralph-cli/src/loop_runner.rs(+353 -48)📝
crates/ralph-cli/src/main.rs(+370 -22)➕
crates/ralph-cli/src/rpc_stdin.rs(+536 -0)➕
crates/ralph-proto/src/json_rpc.rs(+1036 -0)📝
crates/ralph-proto/src/lib.rs(+5 -0)📝
crates/ralph-tui/Cargo.toml(+7 -0)📝
crates/ralph-tui/src/app.rs(+55 -6)📝
crates/ralph-tui/src/lib.rs(+217 -11)➕
crates/ralph-tui/src/rpc_bridge.rs(+506 -0)➕
crates/ralph-tui/src/rpc_client.rs(+327 -0)➕
crates/ralph-tui/src/rpc_source.rs(+499 -0)➕
crates/ralph-tui/src/rpc_writer.rs(+199 -0)...and 2 more files
📄 Description
Summary
Decouples the TUI from the orchestration process by introducing a JSON-RPC protocol over stdin/stdout. The TUI now runs as a subprocess that observes and controls the loop through typed JSON messages instead of sharing memory with it.
Motivation
The in-process TUI couples the display layer to the orchestration loop — a panic in rendering code kills the running agent, the TUI can't attach to an already-running loop, and non-terminal frontends (IDE plugins, web dashboards, scripts) have no way to observe or steer execution.
This PR introduces a JSON-lines IPC protocol that makes the TUI a regular client:
ralph-apiserver over HTTP/WebSocket for remote attachWhat's new
Protocol (
ralph-proto)json_rpc.rs— Wire format for the IPC layer:Prompt,Guidance,Steer,FollowUp,Abort,GetState,GetIterations,SetHat,ExtensionUiResponseLoopStarted,IterationStart/End,TextDelta,ToolCallStart/End,Error,HatChanged,TaskStatusChanged,TaskCountsUpdated,GuidanceAck,LoopTerminated,Response,OrchestrationEventEvent producer (
ralph-adapters)JsonRpcStreamHandler— ImplementsStreamHandlerto emitRpcEventJSON lines on stdout. Tracks tool call durations, iteration context, and token/cost metrics fromSessionResult.Command consumer (
ralph-cli)rpc_stdin.rs—RpcDispatcherreads commands from stdin, routes them to the appropriate channels (interrupt, guidance, state queries), and emits correlated responses. Runs as a background tokio task alongside the loop.loop_runner.rs— Wired with--rpcflag support. Spawns stdin reader + stdout emitter tasks, adds anEventBusobserver that maps internal events toRpcEvent::OrchestrationEvent, and maintains shared state (atomics + mutexes) for liveGetStateresponses including hat, completion status, and accumulated cost.TUI as subprocess client (
ralph-tui)rpc_source.rs— Reads JSON-line events from subprocess stdout, translates them intoTuiStatemutations (iteration buffers, tool call rendering, task counts, completion)rpc_writer.rs— Writes typedRpcCommandmessages to subprocess stdin (guidance, steer, abort, state queries)rpc_bridge.rs— Alternative path: connects toralph-apiover HTTP/WebSocket for remote TUI attachrpc_client.rs— HTTP + WebSocket client for theralph-apiRPC v1 protocoltext_renderer.rs— Extracted shared text→Lines rendering (markdown via termimad, ANSI preservation, control character sanitization)state_mutations.rs— Shared TuiState mutation helpers used by both subprocess and remote modesCLI (
ralph-cli/main.rs)ralph runspawns itself as a child with--rpcand wraps it in the TUI--legacy-tuiescape hatch for in-process mode during migration--rpcflag for headless JSON-lines mode (IDE integrations)ralph tuisubcommand for remote attach to a runningralph-apiserver-c,-H) forwarded to the subprocessTest plan
cargo check --all— zero warnings from project crates🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.