Repository navigation
fix(builderlab): clarify remote-agent account availability - #2764
Conversation
Replace the rollout promise with quiet account-specific status in Harness defaults. Keep account management in Builderlab Settings and preserve contextual sign-in and recovery. Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@feedback.communities.buzz.xyz> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
🤖 Review round 1Posted by Princess Donut, an AI review agent, through Taylor's GitHub account. Reviewed exact head Verdict: changes requested. There is one Medium issue; everything else in scope holds. Medium: keyboard focus is lost when sign-in from the Harness defaults row ends in no accessBuilderlab has no direct attention action, so a signed-out user who activates Log in to Builderlab opens the provider dialog and signs in there. If the account has no remote-agent access, the row switches to status-only while the dialog is still open, and the dialog's return-focus target, the row button, is removed. When the user closes the dialog, focus falls to the document body instead of returning to the row. On main the button stays (relabelled "Coming soon"), so focus comes back to it. This is the main route a no-access user takes to reach this state, so it is a real keyboard and screen-reader regression. I reproduced it with a throwaway jsdom test (not committed) using the real Harness defaults row and dialog. A row starts with a labelled attention action, the dialog opens from it, the snapshot changes in place, then Escape. With a string label, focus returns to the row button. With Suggested fix: keep a stable return-focus target when the trigger disappears, such as a programmatically focusable status element (the row's status text) that the dialog falls back to. Add a regression test for this in-dialog transition. The current tests only cover rows that render directly in the status-only state, and this PR removed the only dialog assertion for the no-access state without replacing it. That leaves the dialog's "unavailable for this account" status line untested. Low: the help text names the Builderlab account location looselyThe help text says "Manage its account in Builderlab Settings." Nearby help entries use bold navigation paths, and the account lives at Settings → Builderlab (the Builderlab card under Plugins). Matching that convention would make it easier for users, and for agents answering from the help file, to find. Nit: the README now under-describes where the status appearsThe README says Harness defaults "shows only 'Unavailable for this account'", but the Builderlab Settings remote-agents section and the provider dialog show the same status too. Consider "Harness defaults and Builderlab Settings show…" so the doc matches the code. Checked and clean
|
Keep the provider dialog return target on the status text when sign-in replaces its button. Cover Escape and Close, and assert Builderlab account denial inside the sign-in dialog. Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@feedback.communities.buzz.xyz> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@feedback.communities.buzz.xyz> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@feedback.communities.buzz.xyz> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
|
🤖 Fixed all three findings in The dialog now returns focus to the non-tabbable status text when sign-in removes its button. Escape and Close regressions fail at the reviewed head and pass with the fix; the Builderlab integration test again asserts the no-access dialog message. The help uses Settings → Builderlab, and the README describes all three status locations. Validation: 21 affected-file tests, real built-app focus/sign-in checks in Chromium and WebKit with mocked account data, and all required push gates pass. The earlier native/design-viewer validation limits remain documented. The PR stays draft for CI and recheck. |
🤖 Review round 2Posted by Princess Donut, an AI review agent, through Taylor's GitHub account. Reviewed exact head Verdict: clean. All three round-1 findings are fixed, and I found no new defects in the fixes. Medium (focus lost after in-dialog sign-in without access): fixed
Low (help text location): fixedThe help text now uses the bold Settings → Builderlab path, matching the surrounding entries. Nit (README wording): fixedThe README now says the status appears in both Harness defaults and Builderlab Settings, that the dialog explains the restriction, and that the row has no action. That matches the code. Commit attribution checked: Taylor is the author, Carl is credited as co-author, and each commit carries Taylor's sign-off. Hosted CI remains the broad gate. |
kalvinnchau
left a comment
There was a problem hiding this comment.
🤖 Approved at d41a400. No actionable findings.
The provider status/action contract and its callers remain consistent: Builderlab accounts without capability receive status-only feedback, other providers retain their actions, and sign-out restores the sign-in action. Focus restoration handles the original button being replaced while the dialog is open. Capability checks still deny remote calls before transport or replay-state creation; account fencing and provider error isolation remain intact.
Validation covered:
- 118 passing tests across the three affected test files. Removing either the status span focus-ref assignment or tabindex caused both Escape/Close regression tests to fail, supporting the usefulness of those assertions.
- Actual compiled application with the production broker in Chromium and WebKit: sign-in without access, Escape/Close focus return, Tab continuation, reload retention, Settings status, sign-out, and login failure/retry plus capability transitions. Denied journeys sent no Beekeeper requests. Account and relay upstreams were modeled with isolated identities and storage.
- CI run 42180304554 verified at this head, including all six Vitest shards, browser journeys, Rust/native fixture and the required gate. Windows native was skipped.
Remaining limits: real Builderlab accounts and relay, successful identity binding, native credentials/storage/IPC, and theme/width/enlarged-text acceptance were not validated. Design-fixture collection independently failed while parsing claude.png as JavaScript; this was not established as a regression introduced here. The author-reported native SIGSEGV was not independently verified.
…leanup * origin/main: feat(agents): let app-hosted agents read their owner's channels and members (#2745) NEXUS-4271: Expose installed plugin status (#2754) fix(menu): stop clipping lifecycle actions behind a hidden scrollbar (#2716) feat(agents): give approved external apps the selected agent's full Buzz tools (#2707) AIDA-2549: Keep Claude settings drafts in sync (#2841) fix(channels): keep a channel's side panels open when returning to it (#2838) fix(builderlab): clarify remote-agent account availability (#2764) fix(sidebar): rename Remove from Team to Close conversation (#2845) perf(channels): cut header and name-matching work in large channels (#2726) fix(browser): silence a browser page once its tab goes away (#2721) Community Mesh: shared compute plugin (including agent type) (#941) perf(relay): cut main-thread work from profile updates (#2730) fix(composer): lead the channel placeholder with its sidebar icon (#2829) test(activity): scope preview assertions to the request row (#2843) perf(search): fold people names once across palette keystrokes (#2570) fix(github): keep PR watches running when localStorage is full (#2699) Make drafts and sent part of Messages (#2728) fix(canvas): render every Canvas within the save limit (#2839) # Conflicts: # .github/workflows/release.yml
…ime-hint * upstream/main: ci: give the native job room for a cold Rust cache (block#2867) fix(pairing): refuse unknown communities natively and name the requesting process (block#2835) Add per-interest Attention pause and management controls (block#2847) feat(drafts): show where unsent drafts wait (block#2853) feat(agents): let app-hosted agents read their owner's channels and members (block#2745) NEXUS-4271: Expose installed plugin status (block#2754) fix(menu): stop clipping lifecycle actions behind a hidden scrollbar (block#2716) feat(agents): give approved external apps the selected agent's full Buzz tools (block#2707) AIDA-2549: Keep Claude settings drafts in sync (block#2841) fix(channels): keep a channel's side panels open when returning to it (block#2838) fix(builderlab): clarify remote-agent account availability (block#2764) fix(sidebar): rename Remove from Team to Close conversation (block#2845) perf(channels): cut header and name-matching work in large channels (block#2726) fix(browser): silence a browser page once its tab goes away (block#2721) Community Mesh: shared compute plugin (including agent type) (block#941) perf(relay): cut main-thread work from profile updates (block#2730) fix(composer): lead the channel placeholder with its sidebar icon (block#2829) test(activity): scope preview assertions to the request row (block#2843) perf(search): fold people names once across palette keystrokes (block#2570) fix(github): keep PR watches running when localStorage is full (block#2699) Signed-off-by: Cheng Peng <cheng@block.xyz> Co-authored-by: Cursor <cursoragent@cursor.com>
…ions-literal-markdown * upstream/main: (38 commits) fix(composer): let Option+Up/Down switch conversations from an empty composer (block#2832) fix(reactions): Scope timed reactions to the selected video (block#2796) fix(communities): name what the Join dialog is doing instead of "Working…" (block#2822) docs(agents): explain the per-conversation MCP cost of Claude agents (block#2683) fix(avatars): keep unsaved avatar drafts and focus, and validate the URL late (block#2714) fix(agents): offer stream and forum connection setup only to channel members (block#2749) Describe Attention as what the agent does, not its tools (block#2865) Let a local Codex agent join its owner's huddle by voice (block#2321) ci: give the native job room for a cold Rust cache (block#2867) fix(pairing): refuse unknown communities natively and name the requesting process (block#2835) Add per-interest Attention pause and management controls (block#2847) feat(drafts): show where unsent drafts wait (block#2853) feat(agents): let app-hosted agents read their owner's channels and members (block#2745) NEXUS-4271: Expose installed plugin status (block#2754) fix(menu): stop clipping lifecycle actions behind a hidden scrollbar (block#2716) feat(agents): give approved external apps the selected agent's full Buzz tools (block#2707) AIDA-2549: Keep Claude settings drafts in sync (block#2841) fix(channels): keep a channel's side panels open when returning to it (block#2838) fix(builderlab): clarify remote-agent account availability (block#2764) fix(sidebar): rename Remove from Team to Close conversation (block#2845) ... Signed-off-by: Cheng Peng <cheng@block.xyz> Co-authored-by: Cursor <cursoragent@cursor.com>
Overview
Category: fix
User Impact: People whose Builderlab account lacks remote-agent access see a clear availability status without a misleading button.
Problem: Harness defaults shows a “Coming soon” button for signed-in accounts without remote-agent access, implying a scheduled rollout. Clicking it only opens account information.
Solution: Show quiet “Unavailable for this account” text without an action. Keep account management in Settings → Builderlab and preserve signed-out sign-in and recovery actions. Closing the sign-in dialog returns focus to the quiet status when its button disappears.
Changes
File changes
src/features/agents/service.ts
Allow a provider to supply supporting status text and explicitly omit its Harness defaults action.
src/bundled/agents/AgentDefaults.tsx
Render that status through the shared PreferenceRow while preserving existing setup controls for actionable states. The status can receive programmatic return focus without adding a Tab stop or action.
src/bundled/agents/AgentDefaults.test.tsx
Cover the status-only row, restoration of the default setup action, and focus return after in-dialog sign-in with Escape and Close.
src/bundled/agents/ProviderDialog.tsx
Allow the existing return-focus ref to point to status text as well as a button.
src/bundled/builderlab/index.tsx
Declare the signed-in no-access state as status-only and remove the rollout promise from dialog copy.
src/bundled/builderlab/index.test.tsx
Check the no-access row across missing/false capabilities, the in-dialog denial message and focus return, while retaining sign-in/capability-transition coverage.
src/bundled/builderlab/agents/RemoteAgents.tsx
Use the same quiet availability wording in Builderlab Settings.
src/bundled/builderlab/agents/client.ts
Use accurate account-availability copy when refusing remote-agent calls.
src/bundled/builderlab/agents/client.test.ts
Retain coverage that denial sends no remote requests and retains no replay state.
src/bundled/builderlab/README.md
Document the status and account-management location.
docs/agents.md
Document the provider status/action contract.
docs/buzz-help.md
Explain the account-specific unavailable state.
Reproduction steps
Validation
Current head:
d41a400aeeee39339238e4580cbd028df40da045.26d944dwith focus on the document body, then pass with the fix.The full validation run at initial head
26d944d1596f13e6d8ccd0804311fa4c9e50c060remains useful context:pnpm check,pnpm build,pnpm design:build, Rust formatting and workspace Clippy passed.window_state::tests::onboarding_snapshot_is_kept_until_next_launch_restoretest. This branch changes no Rust sources.claude.pngas source; the same failure reproduced on untouched mainf9ce9dfc4.Native no-access account acceptance, human acceptance and independent review remain pending; this PR stays draft.
No permanent browser tests were added or removed. The existing capability and access-gating tests were updated, and a colocated host test covers the status-only contract. Temporary browser checks exercise real layout, in-dialog sign-in and keyboard focus recovery in Chromium and WebKit.
Screenshots
Mock account/relay data; real compiled app UI in headless Chromium. The no-access account responses are mocked; native FI no-access acceptance remains unverified. Before uses main
f9ce9dfc4; after uses26d944d(the row appearance is unchanged by the focus fix). The channel list and sign-in screens are excluded.