Skip to content

feat: add openmax-bridge, a JSON-RPC over stdio front end#48

Merged
Max17190 merged 2 commits into
mainfrom
feat/stdio-jsonrpc-bridge
Jul 18, 2026
Merged

feat: add openmax-bridge, a JSON-RPC over stdio front end#48
Max17190 merged 2 commits into
mainfrom
feat/stdio-jsonrpc-bridge

Conversation

@Max17190

Copy link
Copy Markdown
Owner

Why

--stdio (versioned and pinned in #46) is the contract external hosts build against, but every host still has to learn openmax's native JSONL envelope to use it. A host that already speaks JSON-RPC 2.0, the common line protocol for editor and tool integration, had no path in. This adds that path as a thin, separate front end so integration does not require touching the harness core.

Summary

  • New crate crates/bridge (open-max-bridge, binary openmax-bridge). It exposes a running session over line-delimited JSON-RPC 2.0 on stdio and is a client of the openmax-stdio/1 contract: it spawns openmax --stdio (or $OPENMAX_BIN) and translates both directions. The core is unchanged and gains no dependency.
  • Methods. initialize (answered from the child hello: server, protocol_version, version, session_id), prompt { text } (streams update notifications, resolves with { stop_reason } at the turn's done), cancel, approve { approval_id, approved }, shutdown. A request carries id; a notification omits it. A second prompt while one is in flight is a JSON-RPC error.
  • Approvals and streaming. Every child event is forwarded as one update notification, approval requests included; the host answers with approve. Closing stdin drains the in-flight turn, mirroring the underlying protocol.
  • Structure. translate.rs is a pure mapping layer with no I/O (parsing, request-to-command mapping, child-line classification, JSON-RPC builders), unit-tested exhaustively. main.rs is thin subprocess plumbing: two reader threads feeding one channel, hello read synchronously so initialize never races the child's first write.
  • README documents the bridge methods and the update stream.

Test Plan

  • cargo test --workspace (6 bridge + 145 core + 59 tui)
  • cargo clippy --all-targets --locked -- -D warnings
  • Unit coverage: every method parse and its error cases, request-to-command mapping, child-line classification (hello, done, update, protocol_error, non-JSON, no-type), initialize extraction, and JSON-RPC builder shape
  • Manual end-to-end against a real openmax --stdio: initialize resolves with protocol_version and session_id; a prompt streams update notifications and its request resolves at done with the turn's stop_reason; stdin close drains and exits cleanly

A separate binary that exposes a running session over line-delimited
JSON-RPC 2.0 on stdio, so any host that speaks JSON-RPC can drive openmax
without handling its native JSONL envelope. It is a client of the pinned
openmax-stdio contract, not a change to the harness core.

- New crate crates/bridge (open-max-bridge, binary openmax-bridge). It
  spawns openmax --stdio (or $OPENMAX_BIN) and translates both directions.
- Methods: initialize (answered from the child hello), prompt (streams
  update notifications and resolves with stop_reason at turn end), cancel,
  approve, shutdown. A prompt request stays open until the turn's done.
- translate.rs is a pure mapping layer with no I/O, unit-tested across
  every method, child-line class, and JSON-RPC builder; main.rs is thin
  subprocess plumbing over two reader threads and one channel.
- README documents the bridge methods and update stream.
@greptile-apps

greptile-apps Bot commented Jul 18, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds a JSON-RPC 2.0 bridge for driving an Open Max stdio session. The main changes are:

  • A new openmax-bridge workspace binary.
  • JSON-RPC methods for initialization, prompts, cancellation, approvals, and shutdown.
  • Streaming child events through update notifications.
  • Translation tests and bridge usage documentation.

Confidence Score: 5/5

The latest fixes appear safe to merge.

  • Prompt notifications now participate in turn tracking.
  • Child exits and failed writes now resolve pending requests with errors.
  • Initialization and protocol-version handling now reject the previously broken cases.
  • No additional distinct blocking issue qualifies for this follow-up.

Important Files Changed

Filename Overview
crates/bridge/src/main.rs Adds subprocess management, request dispatch, prompt lifecycle tracking, and stdio event forwarding.
crates/bridge/src/translate.rs Adds JSON-RPC parsing, child command translation, event classification, response builders, and unit tests.
crates/bridge/Cargo.toml Defines the new bridge binary and its serde_json dependency.

Reviews (2): Last reviewed commit: "fix: harden bridge request lifecycle and..." | Re-trigger Greptile

Comment thread crates/bridge/src/main.rs Outdated
Comment thread crates/bridge/src/main.rs
Comment thread crates/bridge/src/main.rs Outdated
Comment thread crates/bridge/src/main.rs Outdated
Comment thread crates/bridge/src/main.rs
Comment thread crates/bridge/src/main.rs Outdated
Address review findings on the JSON-RPC front end:

- Track turn activity separately from the response id, so a notification
  prompt (no id) still blocks a concurrent prompt and cannot let one
  turn's done resolve another request.
- Reject a malformed or non-2.0 envelope with -32600 before any method
  runs, so an unversioned or 1.0 message cannot reach prompt or shutdown.
- Do not answer an initialize notification (no id); notifications get no
  response.
- Fail initialize with -32002 when the child never handshook, instead of
  reporting a partial success without protocol_version or session_id.
- forward now returns its write result; a failed prompt write is reported
  and the turn is not armed, and a child exit fails any pending request
  with -32001 rather than closing the transport on an unresolved call.
- Unit-test envelope version validation.
@Max17190
Max17190 merged commit 40e1edf into main Jul 18, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant