feat(compass-app): Wails v3 desktop shell + compass_rpc IPC bridge - #191
Open
seal-agent wants to merge 2 commits into
Open
feat(compass-app): Wails v3 desktop shell + compass_rpc IPC bridge#191seal-agent wants to merge 2 commits into
seal-agent wants to merge 2 commits into
Conversation
seal-agent
added a commit
that referenced
this pull request
Aug 6, 2026
…ntity-guard cancel map Review round 1 on PR #191 (SEA-1684). Addresses the review findings: - HIGH: response head-frame headers marshalled as {name,value} objects but the frozen JS ResponseFrame contract (apps/ui/src/daemon-transport.ts) feeds frame.headers into new Headers(...), which requires [name,value] tuples and throws TypeError on objects — breaking every RPC's head frame in the webview. responseFrame.Headers is now [][2]string (marshals as tuples); headerObjects deleted; frameToResponse passes the pump's [][2]string through directly. The request direction stays object-shaped (rpcRequest.Headers, headerSlice) — the asymmetry is intentional: JS sends request headers as objects. - MEDIUM: finish() deleted the in-flight entry purely by key, so a re-registered requestId (same key, new call) had its live entry mis-deleted and cancelled by a prior call's deferred finish. In-flight map now stores *inflightCall and finish/CompassRPCCancel guard by pointer identity (cur == call), so a call only ever tears down its own entry. - MEDIUM: added TestResponseFrameWireContract — marshals each frame kind with encoding/json and asserts the exact wire shape (tuple headers, base64 chunk, camelCase), the missing test that let the header-shape defect ship green. - MEDIUM: added TestRPCRequestBodyDecodesNumberArray — locks the JS number[] -> Go []byte element-wise decode contract. - LOW: added TestCompassRPCConcurrentDistinctIDs (per-requestId event keying + call independence under cancel); softened the mid-stream-cancel comment to state the invariant the pump actually provides. Co-authored-by: Matt Wilkinson <matt@sealedsecurity.com>
Scaffold the Compass native desktop shell at go/cmd/compass-app: a Wails v3 application (v3.0.0-beta.0) that opens one window loading the prebuilt SolidJS UI and exposes the compass_rpc / compass_rpc_cancel IPC bridge, backed by the merged bridge pump (go/internal/bridge) over the daemon Unix socket. The bound service forwards each gRPC-Web call through the pump on its own goroutine and streams ordered response frames back as Wails runtime events keyed per requestId (compass_rpc:<id>), carrying the JS ResponseFrame shape (head|body|end|error). In-flight calls are tracked in a mutex-guarded map[string]context.CancelFunc so compass_rpc_cancel tears one down; a terminal frame drops the entry. The service emits through a small eventEmitter seam so the whole stream/cancel path is unit-tested against a real h2c stub daemon on a temp UDS with a fake emitter, no webview: unary, multi-frame stream, mid-stream cancel, and dial-error-before-head, all deterministic and event-gated. The dist is served at runtime via BundledAssetFileServer over os.DirFS (//go:embed cannot reach apps/ui/dist across the module boundary). main.go is gated unix && gtk3 (the only Linux Wails stack in the frozen toolchain is GTK3 + WebKit2GTK 4.1); a cgo-free !gtk3 entrypoint stub keeps the untagged go build ./... module lane green. This is T3 slice 2 (SEA-1684); stack supervision, host preflight, and mode selection are T4 (SEA-1685). The apps/ui daemon-transport.ts Wails binding is a separate cross-lane follow-up. Refs SEA-1684 Co-authored-by: Matt Wilkinson <matt@sealedsecurity.com>
…ntity-guard cancel map Review round 1 on PR #191 (SEA-1684). Addresses the review findings: - HIGH: response head-frame headers marshalled as {name,value} objects but the frozen JS ResponseFrame contract (apps/ui/src/daemon-transport.ts) feeds frame.headers into new Headers(...), which requires [name,value] tuples and throws TypeError on objects — breaking every RPC's head frame in the webview. responseFrame.Headers is now [][2]string (marshals as tuples); headerObjects deleted; frameToResponse passes the pump's [][2]string through directly. The request direction stays object-shaped (rpcRequest.Headers, headerSlice) — the asymmetry is intentional: JS sends request headers as objects. - MEDIUM: finish() deleted the in-flight entry purely by key, so a re-registered requestId (same key, new call) had its live entry mis-deleted and cancelled by a prior call's deferred finish. In-flight map now stores *inflightCall and finish/CompassRPCCancel guard by pointer identity (cur == call), so a call only ever tears down its own entry. - MEDIUM: added TestResponseFrameWireContract — marshals each frame kind with encoding/json and asserts the exact wire shape (tuple headers, base64 chunk, camelCase), the missing test that let the header-shape defect ship green. - MEDIUM: added TestRPCRequestBodyDecodesNumberArray — locks the JS number[] -> Go []byte element-wise decode contract. - LOW: added TestCompassRPCConcurrentDistinctIDs (per-requestId event keying + call independence under cancel); softened the mid-stream-cancel comment to state the invariant the pump actually provides. Co-authored-by: Matt Wilkinson <matt@sealedsecurity.com>
seal-agent
force-pushed
the
compass-native-1684-wails-shell-scaffold
branch
from
August 7, 2026 04:39
565d94a to
a92a399
Compare
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.
This PR is part of a stack containing 2 PRs:
mainScaffold the Compass native desktop shell at go/cmd/compass-app: a Wails v3
application (v3.0.0-beta.0) that opens one window loading the prebuilt SolidJS
UI and exposes the compass_rpc / compass_rpc_cancel IPC bridge, backed by the
merged bridge pump (go/internal/bridge) over the daemon Unix socket.
The bound service forwards each gRPC-Web call through the pump on its own
goroutine and streams ordered response frames back as Wails runtime events keyed
per requestId (compass_rpc:), carrying the JS ResponseFrame shape
(head|body|end|error). In-flight calls are tracked in a mutex-guarded
map[string]context.CancelFunc so compass_rpc_cancel tears one down; a terminal
frame drops the entry. The service emits through a small eventEmitter seam so the
whole stream/cancel path is unit-tested against a real h2c stub daemon on a temp
UDS with a fake emitter, no webview: unary, multi-frame stream, mid-stream
cancel, and dial-error-before-head, all deterministic and event-gated.
The dist is served at runtime via BundledAssetFileServer over os.DirFS
(//go:embed cannot reach apps/ui/dist across the module boundary). main.go is
gated unix && gtk3 (the only Linux Wails stack in the frozen toolchain is
GTK3 + WebKit2GTK 4.1); a cgo-free !gtk3 entrypoint stub keeps the untagged
go build ./... module lane green.
This is T3 slice 2 (SEA-1684); stack supervision, host preflight, and mode
selection are T4 (SEA-1685). The apps/ui daemon-transport.ts Wails binding is a
separate cross-lane follow-up.
Refs SEA-1684
Co-authored-by: Matt Wilkinson matt@sealedsecurity.com