feat(app): run the app in a browser and smooth streamed text - #214
Closed
Sma1lboy wants to merge 1 commit into
Closed
feat(app): run the app in a browser and smooth streamed text#214Sma1lboy wants to merge 1 commit into
Sma1lboy wants to merge 1 commit into
Conversation
Adds a loopback web bridge so the renderer can run in a plain browser tab
against the real local AI runtime, plus one command to start both halves:
pnpm dev:web
The bridge reuses the existing IPC handlers rather than duplicating them:
`create*API()` already took an ipcRenderer-shaped argument, so the browser
passes an HTTP/WebSocket shim instead. Only the local AI and MCP channels
are exposed; window control, clipboard and shortcuts have no browser
meaning. Access needs a per-run token, loopback binding and a loopback
Origin, and the whole thing is off unless CONVERA_WEB_BRIDGE=1.
Streaming: the CLI providers deliver ~100 chars every ~220ms, which reads
as paste events rather than typing. Text now drips out on animation
frames, draining faster as the backlog grows and flushing on finish, so
no character is dropped. Measured 5 -> 40 DOM updates for one reply.
Theme: replaces 54 hardcoded palette colors with tokens, and adds the
success/warning/info tokens whose absence caused them. Dialogs, sheets
and drawers now use the popover surface and a shared overlay scrim, so
they match the popovers and menus they sit beside in both themes.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
Author
|
Superseded: this work landed on main directly and has since evolved past this branch — the web bridge (da6b5e9) now runs tokenless with a loopback-origin check (81cb1d8), text-drip smoothing is identical, and the dev harness gained dotenv loading and the new local-ai IPC contract. Verified file-by-file: everything here is either byte-identical on main (text-drip) or strictly older (server.ts, local-ai-api.ts, web-bridge-dev.mts still carry the token flow that was removed by request). Nothing to salvage; closing. |
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.
Why
Three things, all in service of being able to develop and verify this app without an Electron window.
1. Web bridge —
pnpm dev:webOne command starts the renderer dev server and a loopback bridge, and prints one ready-to-open link. No configuration.
The bridge reuses the existing
ipcMainhandlers rather than duplicating them for HTTP.createLocalAIAPI()/createMcpAPI()already accepted anipcRenderer-shaped argument, so the browser just passes a fetch/WebSocket shim. No annotations, no codegen, one implementation.Security (this channel can run local CLI agents):
CONVERA_WEB_BRIDGE=1OriginrejectedVerified against the real CLIs: Claude Code 2.1.219 and codex-cli 0.146.0 detected, and a real chat streamed back through HTTP → WebSocket → browser.
2. Streaming smoothness
Measured first: a reply delivered 412 chars in 5 chunks of ~100, ~220ms apart. That's five paste events, not typing — no renderer tuning could fix it, because the problem is arrival rate.
Text now buffers and releases on animation frames, draining proportionally faster as the backlog grows so it never lags, and flushing on finish/abort so nothing is truncated.
3. Theme consistency
Replaced 54 hardcoded palette colors (
bg-blue-500,text-gray-600, …) with theme tokens. Most existed because the theme had nosuccess/warning/info— so those were added in the warm palette, with-subtlesurfaces and light + dark variants.Also fixed real inconsistencies found while verifying:
bg-backgroundwhile popovers/menus usedbg-popover— two surfaces for the same jobblack/30vsblack/50, blur on some) — now one--overlaytoken<textarea>s bypassed the themed component and showed the browser-default blue focus ring inside a warm dialogTesting
tscandeslintcleanNote
pnpm dev:webhas no MCP hub (it needs Electron'sapppaths) — builtin tools only. Run the Electron app for MCP servers.🤖 Generated with Claude Code