Repository navigation
Conversation
Proof-of-work snapshot: WorkOS browser sessions, DeviceRoom RPC, shared UI parity and friendly device names. Pins published GPUI runtime fixes. Excludes local credentials, generated artifacts and experimental apps. Locked WASM build and scoped tests passed; exact native build remains unverified after validation timeouts. Not PR-ready.
|
Pushed 08fcd03: production deployment preparation and multiuser authentication. Keeping this PR in draft. Known unresolved issue from manual phone testing: emojis do not render correctly in chat messages or when pasted into the input. This is a rendering failure, not a passed emoji check; root cause has not yet been investigated. Previously verified taps, scrolling, keyboard behavior and popovers remain recorded separately. |
Resolve UI integration conflicts, pin published browser runtime fixes, refresh web lockfiles, harden workerd test execution, and correct rollout documentation.
|
Updated to The emoji issue mentioned in my earlier comment is fixed in staging. I’ve also manually verified terminal input/focus, mobile drawers, reconnect behavior and the mobile tap-highlight fix. This update resolves the upstream conflicts and pins the published runtime fixes, so the web build no longer depends on local runtime overrides. Local validation passed: locked release WASM build, 21 lifecycle tests, 44 unit tests, 24 workerd tests and 39 production-routing checks. The workerd runner assertions were investigated and addressed; repeated runs are now clean. Desktop/mobile browser startup checks also passed. Please land zui #8 first; I’ll then repin to its upstream revision. Hosted CI still needs confirmation. Production has not been deployed, and the WorkOS/storage rollout checklist remains a pre-merge requirement. |
wingleeio
left a comment
There was a problem hiding this comment.
Thanks for the thorough work here — the design is sound and the security posture (PKCE + state/nonce, __Host- cookies, CSRF header + Origin checks, sealed provider tokens, owner-scoped sessions, browser forced to role=client, catalog-only preview relay) is careful. I audited the vendored crate, the forked git dependency, CI/deploy changes, the postinstall hook, and the edge auth code, and found nothing unsafe. Findings below, ordered by importance.
Blocking / should fix before merge
-
Pin mismatch between description, README, and manifest. The PR body says zui is pinned at
c1700b8d…,apps/web/README.mdanddocs/web-deployment-session-summary.mdsayaca6b042…, andapps/web/Cargo.toml/Cargo.lockactually pin8d78b9c2…. Per your own checklist, zui #8 should land first and this should be repinned to azeronsh/zuirev, with the[patch."https://github.com/zeronsh/zui"]block removed. As written,deploy.ymlbuilds productionweb.zeron.shassets from a personal fork. -
Per-frame authorization round-trip to a single global DO (
edge/src/device-room.tswebSocketMessage→browserSessionActive→validateBrowserSession). Every relayed frame in both directions for a browser client does a sub-request to the onebrowser-sessions-v1BrowserSessionStoreinstance, withrefresh: trueby default (so a frame path can trigger a WorkOS refresh). Terminal output is many frames/sec per client; this makes one DO a global throughput ceiling and adds latency to every frame. There's also a correctness concern:webSocketMessageis nowasyncand awaits a non-storage sub-request, so workerd can deliver the next message before the previous one finishes validating — frames on a stream could be relayed out of order. The alarm-based recheck (BROWSER_SESSION_RECHECK_MS) plus the/browser-revokepush already cover revocation; I'd drop the per-frame check or make it a local, time-bounded cache on the socket attachment. -
Contributor-specific infra committed to the repo.
edge/wrangler.staging.jsonchardcodes a personal Cloudflareaccount_id, thezeron-test.embedez.comcustom domain, and a separate WorkOS client id;docs/web-deployment-session-summary.mdis a session log of that staging deploy. Either template the staging config or drop it and the session summary. -
/auth/browser/*broker API is dead code for this PR.edge/src/browser-auth.tsexposes exchange/refresh/revoke returning raw provider access+refresh tokens to any holder ofBROWSER_BROKER_TOKEN. Nothing in the browser flow uses it,BROWSER_BROKER_TOKENisn't inEnvor wrangler config, and its only consumer is the "not implemented"SELF_HOSTING_ROADMAP.md. It's fail-closed (501) when unset, but it's a new credential-issuing surface plus a===timing-unsafe token compare. Suggest removing it (and the roadmap doc) from this PR and landing it with the self-hosting work.
Should fix
-
forward()inedge/src/index.tsdoesn't strip the new internal headers. It clearsROOM_KIND_HEADERfor exactly this reason but passes throughx-comet-browser-session-hash,x-comet-browser-room, andx-comet-browser-session-storefrom native bearer clients. DeviceRoom re-validates the hash and matches owner so I couldn't find an escalation, but the/browser-revokeroute's only gate is that store header. Add the three to the delete list for defense in depth. -
Host device name is now sent to and stored on the edge (
crates/engine/src/lib.rs.with_device_name(local_device_name(...))→&name=→browser_devices.name). That's the machine hostname by default. Worth a note in the description and probably an opt-out, since it's a new piece of PII in DO storage. -
postinstallpatchingnode_modules(edge/scripts/patch-vitest-pool.mjs) will breaknpm cion any@cloudflare/vitest-pool-workersbump. Preferpatch-package/ npmoverrides, or upstream the fix and drop the hook.
Scope
- This PR bundles at least six independently reviewable changes: the
RpcClientwriter/shutdown refactor (affects native too —ServerFramenow rejects envelopes without exactly one ofok/item/err/done; I checkedserver.rsand it's compatible), large UI module splits (composer/input.rs,*/presentation.rs— confirmed these are essentially moves), the alacritty vendoring (verified byte-identical to crates.io 0.26.0 apart from wasmcfggating), thezeron-rpc/zeron-syntaxfeature-gating, the web app, and the edge BFF + deploy changes. Splitting the native-affecting refactors out first would make the remaining browser work much easier to review and bisect.
Nits
dtolnay/rust-toolchain@masterin both workflows; the repo otherwise uses@stable.browser-sessions.tsswallowsALTER TABLEerrors with barecatch {}on every DO construction — a migration table would be clearer than try/catch schema evolution.web-validation.ymlanddeploy.ymlduplicate the ~40-line WASM build/check block; a composite action would keep them in sync.
|
Good morning — here is my attempt to un-slop this PR and address the review properly.
I also changed the Rust setup actions to use the stable action tag and replaced exception-driven SQL column migrations with explicit schema inspection. The final upstream zui repin remains required after zui #8 merges. The PR also currently conflicts with upstream |
8d78b9c2 was rewritten out of the zui#8 branch by a rebase, so it no longer sits on any ref and could be garbage-collected, breaking the locked web build. 93ab2ca is the current zui#8 head (rebased onto zeronsh/zui main, plus the browser paste and soft-keyboard fixes). Only the zui revision lines in Cargo.lock change. The final repin to a zeronsh/zui SHA still waits for zui#8 to merge.
Trunk content-hashes the bundle and the new initializer script, so mark them immutable in _headers. index.html keeps the default revalidation, so a deploy is still picked up right away. Add a first-open loader that shows WASM download progress through Trunk's data-initializer hook, then "Starting Zeron…" while the module compiles, and a visible failure state instead of a blank page. The edge worker only routes an allowlist of paths to assets, so allow the hashed initializer script and extend production-routing.mjs to cover it and assert the cache headers.
Attachment thumbnails in the transcript are read from the owning device over ReadAttachmentChunk. The device lookup, the load spawn and the loader itself were compiled out on wasm32, so the browser had no candidate devices and every history image fell through to the blank "unavailable" thumbnail, while freshly staged images still showed. The browser already has an AppState with a device-relay EngineHandle and the edge/engine forward ReadAttachmentChunk to remote clients, so drop the three wasm32 gates and let the browser use the same path as native.
- Resolve all 24 conflicted paths across proto, rpc, ui, and edge tests - Gate engine, harness, update, gpui_tokio and native rpc/syntax features to non-wasm targets; restore the wasm web dependency set - Gate zeron-rpc server/device-room modules behind `native` so the client-only web graph stays wasm-safe - Restore platform-specific Instant aliases for browser-reachable UI clocks - Repair the mobile right-sidebar drawer overlay: <768px transient drawers, 90%/380px cap, occluding scrim, tap-backdrop close, full-width chat - Port browser preview-frame handling onto the upstream bounded socket pump - Add scripts/test-browser-instant.mjs authenticated browser regression - Regenerate apps/web/Cargo.lock for the boundary changes
…very The web client now uses PR zeronsh#319's browser-session model end to end; the manual connect flow (engine address, dev user id, pasted AuthKit code) is gone. - engine-client: `device-frame.ts` (the DeviceRoom binary framing ported from crates/rpc/src/device_frame.rs plus `RelaySocket` — the browser transport with ping/pong/echo liveness and buffered-amount backpressure) and `edge.ts` (the /api/browser/* session, login, devices, and logout API). EngineClient skips the first-frame Auth envelope when the credential is empty: the relay authenticates the browser session cookie at the WebSocket upgrade. - app: `state/fleet.ts` is rewritten around the edge — boot checks /api/browser/session and redirects signed-out visitors straight to WorkOS (PKCE authorize URL from the edge, callback returns to the app root with the HttpOnly session cookie); signed in, the owner-scoped device list is polled and every device is supervised through the cookie-authenticated relay WebSocket. `/pair` is now an automatic connect gate, and the Devices settings page describes the zeron-login-driven flow instead of manual pairing. - dev serving: vite allows the dev.embedez.com tunnel host and proxies /api/browser (HTTP + WS) to the local staging edge (ZERON_DEV_EDGE, default http://127.0.0.1:27641). Verification: pnpm -r build green (engine-client + app typecheck, Vite bundle); app suite 1873/1873 (one session-provider expectation updated: registry restart re-pins identity to the device-id key).
Summary
Adds an authenticated browser build of the shared GPUI interface. The browser renders the shared Shell/application state and connects to a native Zeron device through the existing RPC protocol and DeviceRoom relay. Execution stays on the native host; the browser does not run an engine or use loopback IPC.
Included
Merge-readiness sweep
7655c662c2e0e1dea91a9c4d9929725e219abd82, resolved the root lock conflict and reviewed the preview/sidebar auto-merges.Gratenes/zui@c1700b8de27a07b5bc1a190440b64e7323c008f9, including the input/runtime fixes from Fix browser runtime wakes, fonts, touch and text input zui#8.Validation
trunk build --release --locked: passed, usingnightly-2026-09-08, Trunk 0.21.14 and the published runtime pin; no local Cargo source override.npm ciin the clean checkout (44 unit + 23 workerd).cargo check --locked -p zeron: passed after reconciliation, using locally supplied Linux development libraries.Commands/configuration:
apps/web/README.md.Hosted checks: Web validation workflow.
Manual coverage and limits
The author has verified phone taps, scrolling, keyboard behavior and popovers; phone copy/paste and emoji testing remains pending. Device/browser versions and the tested revision were not recorded.
Earlier development checks reported real WorkOS login, device selection, chat, terminal commands, file editing, Git diffs, queue operations, previews and theme persistence. Those reports are not a reproducible end-to-end suite for this final commit; this sweep does not claim to repeat those authenticated flows.
Remote project preview is HTTP-only: WebSocket upgrades and Vite HMR are not supported. Full desktop/browser parity, one-command deployment and direct/self-hosted transport are outside this change;
SELF_HOSTING_ROADMAP.mdremains a proposal.Before merge
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.