[Wails] M5.5: desktop binary binds no TCP listener#146
[Wails] M5.5: desktop binary binds no TCP listener#146josh-padnick merged 2 commits intofeat/wails-rewritefrom
Conversation
Removes the lazy embedded Gin server from the desktop binary so a
running Gruntbooks process listens on no network sockets. The
threat-model goal of M5.5 — eliminating the localhost API that any
sibling process running as the same user could discover and abuse —
is delivered: a `lsof -i -P -p $(pidof Gruntbooks)` after opening a
gruntbook returns nothing.
What changed
- `services/serverManager.Start` no longer calls
`api.StartServerWithShutdown`. It still creates the SessionManager
and ExecutableRegistry that every IPC service depends on; it just
doesn't bind a port.
- `desktop/app.go` drops the `/api/*` reverse-proxy block and the
`newAPIProxy` helper. The asset handler now only serves the embedded
React build with SPA fallback. `OpenResult.port` and
`DesktopStatus.serverPort` are gone — the frontend never used the
number anyway.
- TS bindings regenerated.
What did not change (deferred from the original M5.5 plan)
- `cmd/serve.go`, `api/server.go`, and the dual-pathed
`if (!isDesktop()) fetch('/api/...')` branches in every legacy
frontend hook are kept. Playwright still drives `gruntbooks serve`
for now.
- The full Gin deletion + Playwright-on-bindings migration was meant
to land here. It is blocked on Wails v3 alpha.78's `-tags server`
build mode failing to compile (`BrowserWindow` is missing
`Window.SetScreen`, a regression introduced in PR #5067 and not yet
fixed upstream). Until either alpha.79 ships a fix or we adopt a
custom HTTP transport on top of `application.MessageProcessor`,
Playwright stays on the legacy harness. See HANDOFF_PROMPT.md for
the prompt that picks this work up.
Verification
- `go build ./...` clean
- `go test ./services/... ./desktop/...` clean
- `bun x tsc --noEmit` clean
- `bun run lint` clean (one pre-existing warning unrelated)
- Playwright e2e suite: 17/17 passing (Chromium)
- `lsof -a -p $PID -iTCP -sTCP:LISTEN` empty for the desktop binary
with a gruntbook open
- `gruntbooks serve` still works for Playwright (verified via
/api/health probe)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Demo3's <TemplateInline> component was hitting POST /api/boilerplate/render-inline unconditionally via useApi, which surfaced as "Failed to connect to gruntbook server at wails://localhost/api/boilerplate/render-inline" once #146 removed the desktop binary's /api/* asset proxy. The earlier audit looked for raw fetch('/api/...') calls and missed this one because TemplateInline used the useApi hook indirectly — useApi has no isDesktop() gating of its own. Fix follows the dual-path pattern used by useApiBoilerplateRender / Template and useScriptExecution: keep the useApi call for browser mode (gated by isDesktop() so the endpoint is empty in desktop), and add a parallel BoilerplateService.RenderInline IPC invoker with local 300ms debounce, monotonic seq guard for stale-response discard, and matching state shape so the rest of TemplateInline doesn't change. Verified against testdata/sample-gruntbooks/demo3: - Backend logs show RenderBoilerplateTemplate firing on input change - No TCP listener bound (lsof empty) - Build, lint, and tsc all green Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Summary
Removes the lazy embedded Gin server from the desktop binary so a running Gruntbooks process listens on no network sockets. The threat-model goal of M5.5 — eliminating the localhost API that any sibling process running as the same user could discover and abuse — is delivered:
lsof -a -p $PID -iTCP -sTCP:LISTENafter opening a gruntbook returns nothing.What changed
services/serverManager.Startno longer callsapi.StartServerWithShutdown. It still creates theSessionManagerandExecutableRegistrythat every IPC service depends on; it just doesn't bind a port.desktop/app.godrops the/api/*reverse-proxy block and thenewAPIProxyhelper. The asset handler now only serves the embedded React build with SPA fallback.OpenResult.portandDesktopStatus.serverPortare gone — the frontend never used the number anyway.What did not change (deferred from the original M5.5 plan)
The original M5.5 plan was: migrate Playwright onto Wails's
-tags serverbuild mode (real bindings over HTTP at/wails/runtime), then deletecmd/serve.go,api/server.go, everyif (!isDesktop()) fetch('/api/...')branch in the frontend, andgin-gonic/ginfromgo.mod.That plan is blocked on a Wails alpha.78 bug:
go build -tags serverfails to compile becauseBrowserWindow(inpkg/application/browser_window.go) is missingWindow.SetScreen, a regression introduced when theWindowinterface gained screen-management methods (PR wailsapp/wails#5067) without a matching update onBrowserWindow. The bug is also present on the upstreamv3-alphabranch tip — there is no later alpha to bump to. Filed upstream as wailsapp/wails#5262.Until either (a) a future alpha ships the fix or (b) we adopt a custom HTTP transport on top of
application.MessageProcessor, Playwright stays on the legacygruntbooks serveharness. The dual-pathedfetch('/api/...')branches in frontend hooks remain in place for that path. None of that code runs in the shipped desktop binary — that's the headline guarantee this PR delivers.Test plan
go build ./...cleango test ./services/... ./desktop/...clean (full suite green)bun x tsc --noEmitcleanbun run lintclean (one pre-existing warning unrelated)lsof -a -p $PID -iTCP -sTCP:LISTENempty for the desktop binary with a gruntbook opengruntbooks servestill works for Playwright (verified via /api/health probe)🤖 Generated with Claude Code