Repository navigation
Serve the app's tools to Redrob Code through the app bridge - #78
Merged
Merged
Conversation
The egui shell now starts `redrob-app-bridge` on a thread once the egui context exists and registers as `app:query` with the shared daemon (optional: a daemon that cannot be reached is logged and the app runs without it). Tool handlers run on the bridge's threads and push requests onto a channel; `QueryApp::serve_bridge` drains it once per frame and runs each request against the real app state (ProfilesPanel, Workspace, tabs), polling the engine's `Pending` answers on the following frames so the UI thread never blocks. Tools: list_connections, connect, list_tables, describe_table, run_sql (TSV, 200 rows by default, summary line with count / time / truncation / rows affected), open_in_editor, export_result (csv | tsv of the last run_sql page, else the active tab's grid). app.rs only gains the bridge field, the start / serve / stop hooks and pub(crate) on the fields and helpers the bridge module shares. READMEs get a "Control from Redrob Code" section in both languages.
Lock redrob-app-bridge (redrob-code v0.7.0) and its dependencies into Cargo.lock, expose QueryApp.bridge to the crate so main.rs can stop it, name the metadata-step continuation type and use map_or_else, as clippy -D warnings asks.
Merged
its-janghoon
added a commit
that referenced
this pull request
Oct 17, 2026
Workspace version 0.4.0 -> 0.5.0; CHANGELOG 0.5.0 section for the Redrob Code app bridge (#78); CONTRIBUTING release example bumped.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What's done
apps/redrob-query/src/app_bridge.rs: the Redrob Code app bridge.redrob-app-bridgeis started on its own thread once the egui context exists and registers asapp:query; a daemon that cannot be reached is logged and the app runs without it. Handlers run on the bridge's threads and pushBridgeRequests onto a channel, ask for a repaint and block on the reply (30 s).QueryApp::serve_bridgedrains the queue once per frame (after the panels polled) and runs each request against the real app state through the sameProfilesPanel/Workspace/ tab functions the UI uses; enginePendinganswers are polled on the following frames and replied to the moment they land, so the UI thread never waits on a database.list_connections(id, name, driver, connected),connect {id}(id or name; answers once the profiles panel reports it up, so the schema tree and the query tab open as if clicked),list_tables {connection?, schema?},describe_table {connection?, table}(roots then columns,schema.tableaccepted, ambiguous names refused with candidates),run_sql {connection?, sql, max_rows?}(TSV header + rows, default 200, max 10 000, summary line with count / ms / "more rows exist" / rows affected; the status line notes the run),open_in_editor {sql, connection?}(new tab bound to the given or active connection, or an unbound tab),export_result {path, format: csv|tsv}(lastrun_sqlpage, else the active tab's grid).app.rs: thebridgefield,Bridge::startinnew,serve_bridge()afterpoll()inui(),bridge.stop()inon_exit, andpub(crate)on the fields and helpers (workspace,profiles,tabs,active,tab_counter,notify,active_profile,push_tab,open_tab_for) the bridge module shares.main.rs:mod app_bridge.Cargo.toml: the git dependency (branchfeat/channels-app-bridge, TODO pin to the release tag).What's not done
rustfmtwas run on the touched files only.run_sqldoes not run writes. The engine'sexecute_queryadmits exactly one read-only statement (is_single_read_only_statement) and theWorkspaceexposes no arbitrary-mutation path (prepare_mutation/apply_mutationare onDataService, which the shell cannot reach); the README's "No free-form write SQL" boundary stands. A write reaches the agent as the engine's ownReadOnlyViolationtext. Lifting that needs a core change outside this piece's file scope.Cargo.lockuntouched; the release build resolves the git dependency.What to review
app_bridge.rsbridge_advance: theconnectjob resolves fromProfilesPanel::is_connected/is_connectingrather than holding its ownPending, so the panel'sConnectedevent path (schema load, tab open) stays the single one.MetadataStepcontinuation (describe_tableis two loads in a row) and thatstep.thenis aFnOncewith explicit&Workspaceparameter types for the higher-ranked bound.page_as_delimitedescaping: TSV escapes tabs / newlines inside a field, CSV quotes per RFC 4180.Sender<BridgeRequest>and anegui::Contextonly.Intentions
Let the Redrob Code agent drive Redrob Query from any surface with the same bounds the UI has, without a mock or an unimplemented tool, and without putting the egui state behind a mutex.