fix(client): tell the dashboard it is a client - #3169
Conversation
The machine listener served the GUI without the runtime-role meta tag, so a connected client rendered as a plain standalone install. The tag is not decoration. gui/src/api-targets.ts reads it in isConnectedRuntime(), and discoverApiTargets() returns standalone targets immediately when it is anything other than "client" -- deliberately, so a user who never enabled remote hub issues no request to a remote-hub endpoint. The consequence on a real client was that discovery never queried /api/machine/status: no hub usage scope on Usage, no "this machine" panel on Startup, no connected-client list on Integrations, and no pairing form. src/server/index.ts already passes config.runtimeRole on the same call. The listener only ever serves a connected client, so the role is a constant here rather than a config read. Verified by hand before and after: with the tag absent the served document has only the session meta and the dashboard shows the standalone layout; with it present the two-plane UI appears, including "Disconnect from hub" and the pairing form. The regression test asserts the call carries the role. It reads the source rather than the HTTP response because the listener falls through to a JSON payload when gui/dist is absent, which would make an HTTP-level assertion pass vacuously in a checkout with no GUI build. A second test covers the document itself through serveGuiFile with a temporary dist. Both were driven red against the unfixed call.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
✅ Deterministic PR hygiene checks passed. |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Team Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe client machine listener now passes the fixed ChangesClient GUI role tagging
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
리뷰 · 우선순위 60 / 80설명이 PR은 연결된 클라이언트(machine listener)가 대시보드 HTML을 줄 때 왜 중요한가. GUI는 고친 곳. 테스트. 현재 라인 128 - 상수 메인테이너의 판단이 필요한 지점
너의 추천 이 댓글은 grok-bot이 작성했습니다 |
Summary
opencodex-runtime-rolemeta tag, so a connected client rendered as a plain standalone install.gui/src/api-targets.tsreads it inisConnectedRuntime(), anddiscoverApiTargets()returns standalone targets immediately when it is anything other thanclient— deliberately, so a user who never enabled remote hub issues no request to a remote-hub endpoint. On a real client that shortcut fired every time: discovery never queried/api/machine/status, so there was no hub usage scope on Usage, no "this machine" panel on Startup, no connected-client list on Integrations, and no pairing form.src/server/index.ts:1963already passesconfig.runtimeRoleon the same call. This listener only ever serves a connected client, so the role is a constant here rather than a config read.Found while documenting what a connected client actually shows, which is how the gap surfaced: the documentation claimed a two-plane dashboard the running code could not produce.
Verification
Verified by hand on a live listener with a real
gui/dist, before and after:<meta name="opencodex-runtime-role" content="client">is present and the two-plane UI appears — "Disconnect from hub" in the sidebar and the "Connect this dashboard to the hub" pairing form.Tests:
bun test tests/client-machine-listener.test.ts— 6 pass, 0 fail.bun test tests/client-machine-listener.test.ts tests/core-lab-boundary.test.ts— 23 pass, 0 fail.bun x tsc --noEmit— clean.Both new tests were driven red against the unfixed call before the fix landed. The listener-level one reads the source rather than the HTTP response on purpose: the listener falls through to a JSON payload when
gui/distis absent, so an HTTP-level assertion would pass vacuously in a checkout with no GUI build. The document-level one coversserveGuiFiledirectly with a temporary dist.No full suite, per the no-local-suite policy.
Checklist
Summary by CodeRabbit