Preset rows in Settings → Agent runtimes fell back to initials because
DoctorSettingsPanel's RuntimeLogo only knew the builtin logo map, while
presets deliberately emit an empty avatar_url (no remote or user-supplied
icon URLs). Route preset ids through RuntimeIcon — the same component the
preset gallery uses — so both surfaces share PRESET_LOGOS and the per-logo
contrast treatments. Builtins keep the ProfileAvatar path; customs keep
the terminal glyph by design.
Playwright regression in harness-management.spec.ts asserts the doctor
rows render the bundled hermes/openclaw files, not initials.
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
## Summary
- retire Virtua prepend reconciliation on every ordinary reader wheel
event, including events suppressed from its separate wheel-timing
heuristic
- keep Ctrl+wheel browser zoom excluded from reader ownership
- arm the Ctrl+wheel prepend probe before pagination begins so it cannot
miss the commit
- preserve ESM/CJS patch parity and update the patch lock hash
## Why main was red
PR #2855 added the reader-wheel retirement action after Virtua's
existing suppression guard. Once the first event set that guard, later
events in the same wheel burst returned before retiring prepend mode. A
late ResizeObserver correction could then pull the viewport backward by
20–40px. The same test had failed twice on #2855 but passed its final
retry, so the PR job appeared green; the merge commit lost all three
retries.
The separate Ctrl+wheel failure was a test race: its MutationObserver
was registered after the request had already been triggered and could
miss the prepend commit.
## Validation
- desktop full unit suite: 3,515 passed
- pre-push desktop check: passed
- `git diff --check`: passed
- CI is the E2E verification; no local E2E was run
Fixes the main-branch failure in CI run 30180099007.
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
## Summary
- make Virtua the sole prepend geometry/correction owner by accumulating
active prepend ResizeObserver corrections from the live DOM offset
- retire prepend reconciliation on ordinary reader wheel input, while
preserving it for Ctrl+wheel browser zoom
- remove Buzz's competing three-second semantic-anchor watcher and
corrective `scrollBy` loop
- keep ESM/CJS Virtua patch behavior equivalent and update the patch
lock hash
## Why
Buzz admitted prepended rows using seeded estimates, then Virtua
received multiple measurement corrections for the same transaction. Each
correction was based on the same stale model offset, so a later write
replaced an earlier correction instead of accumulating it. In the
reproduced first page, that resurrected 452px of anchor drift; the
app-level watcher merely corrected the lost virtualizer write afterward.
This fixes the correction inside Virtua and deletes the competing app
writer, following the single-owner geometry invariant used by Berd
rather than copying its spacer implementation.
## Validation
- watcher-off desktop virtualization matrix: 11/11 passed, including 15
cascading prepends, continued wheel input, detached rich-row growth,
channel switching, bottom follow, and buffered live arrivals
- focused cascading prepend/Ctrl+wheel regression passed
- desktop typecheck passed
- desktop unit suite passed: 3,495 tests
- Biome passed on changed desktop files
- `git diff --check` clean
## Manual behavior
Load older history repeatedly while scrolling upward, then wheel
downward during/after a prepend. The visible anchor should stay within
the existing 5px contract during reconciliation, and deliberate reader
movement should not be pulled back. Ctrl+wheel during the prepend commit
must not cancel reconciliation.
---------
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
The C-10 harness-management spec was 5 passed / 5 failed and had never run in
CI — it was added without an entry in either playwright.config.ts project's
testMatch, so no gate covered it. Three test-side defects, no product defects.
1. Ambiguous "Save" selector. getByRole("button", {name: "Save"}) substring-
matches "Save defaults" from AgentDefaultsEditor, a sibling card in the
same Settings -> Agents panel. Scoped to the form, exact match.
2. The mock catalog ignored its own mutation store. handleDiscoverAcpRuntimes
returned a test-supplied acpRuntimesCatalog early, never merging
mockCustomHarnesses — so save/delete mutated a store the seeded specs
never read back, and add/edit/rename/delete all silently no-oped.
Fixed with one mergeMockCustomHarnesses used by both catalog paths. A
deleted *seeded* row has no store entry to remove, so removal needs a
tombstone set rather than just the map; the same mechanism covers the id
vacated by a rename.
3. The onboarding-nav test was unsatisfiable as written. It needs machine
onboarding to run (community must not vouch for the active identity) and
needsSetup to be false afterwards (or App.tsx renders WelcomeSetup instead
of the router). skipCommunitySeed leaves zero communities and fails the
second; the default seed stamps the active pubkey and fails the first.
Seeding a community under a foreign pubkey satisfies both.
Instrumenting this showed the navigation itself always worked — the hash
became #/settings?section=agents on click, with WelcomeSetup painted over
it because the router never mounted. The route intent is correct.
Adds unit coverage for the merge/tombstone logic; reverting the tombstone
filter fails exactly the delete and rename cases.
Verified at 91080e0a9: harness-management 10/10, unit suite 3560/3561 (the
one failure is the pre-existing styled-qr-code / missing qrcode package
fault, identical on a pristine tree), tsc clean, biome clean 1641 files,
check-file-sizes clean.
Co-authored-by: Dawn (sprout agent) <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
C-10 (full form — Playwright spec):
Add desktop/tests/e2e/harness-management.spec.ts with 10 tests covering:
- Preset gallery: detected badge present for available preset
- Preset gallery: install link shown, no badge for not-installed preset
- Add custom harness: form save → row appears in list
- Edit preserves env vars: definitionEnv round-trip via edit form
- Same-ID edit replaces row without duplication
- Rename: old row gone, new row present
- Delete success: row disappears
- Delete failure: inline error shown, row kept (error-injection knob)
- PATH badge on custom row: Detected badge when availability === 'available'
- F8 onboarding navigate: setup-page More-harnesses click →
completes onboarding → Settings → Agents (settings-harness-management)
This exercises the real App.tsx effect that gates router.navigate()
on machine.stage === 'ready', which postOnboardingNav.test.mjs cannot
cover (it simulates the predicate, not the render path).
Delete-error injection knob:
- Add deleteCustomHarnessError?: string to MockBridgeOptions in bridge.ts
- Add same field to MockE2eConfig in e2eBridge.ts
- Thread config through to handleDeleteCustomHarness so the e2e bridge
throws when the knob is set (mirrors acpAuthMethodsError pattern)
- Add unit test: throws when knob set + entry survives in store
D-15 (README execution-locus sentence, full placement):
The install_hint placement (already in discovery.rs) is correct and stays.
Add the missing sentence to the README blockquote at line 265 per the brief:
Desktop-injected BUZZ_* env vars do NOT reach the execution locus unless
set on the Gateway's own environment.
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
## Summary
- render mobile pairing QR codes locally with Wallet-inspired styling
- hide the raw pairing URI behind a matching copy button
- add focused rendering and dialog coverage
## Test plan
- desktop lint and 3,489 desktop tests
- focused pairing dialog Playwright test
- decoded the rendered QR back to the exact pairing URI
## Summary
- Replace all references to a specific corporate VPN product name with
generic "VPN" / "corporate VPN" / "VPN tunnel" / "VPN CLI" language
across 15 files (21 lines)
- Comment-only and doc-only changes — zero functional impact
- Keeps the OSS repo free of vendor-specific assumptions
`rg -i warp` returns zero hits after this change (excluding
`node_modules`, lockfiles).
## Why
Installing the Codex, Claude, or Goose desktop app does not install the
command-line harness Buzz needs. The current UI makes that distinction
unclear, links some missing-CLI states to adapter documentation, and can
report a successful install from the installer exit code even when
runtime discovery still fails. On Windows, Buzz also invokes Goose's
Bash installer, which writes the executable somewhere Buzz does not
discover.
## What
- distinguish missing vendor CLIs from missing or outdated ACP adapters
in runtime metadata and UI guidance
- link Codex, Claude Code, and Goose missing-CLI states to their
official CLI installation documentation
- explain in Settings, onboarding, and agent configuration that the
desktop app alone is not sufficient
- use Goose's official PowerShell installer on Windows
- refresh PATH and rediscover the requested runtime after installation,
keeping the control retryable if the runtime is still unavailable
- add Rust and Playwright regression coverage for Windows installer
selection, CLI/adapter guidance, false-success prevention, verified
installs, and onboarding copy
## Risk Assessment
Medium. This changes desktop onboarding and runtime installation
behavior. Successful installs now require the runtime catalog to verify
availability; previously hidden discovery failures will surface as
actionable errors instead of a false success state.
## References
- [Codex CLI installation](https://developers.openai.com/codex/cli/)
- [Claude Code
installation](https://code.claude.com/docs/en/getting-started)
- [Goose
installation](https://goose-docs.ai/docs/getting-started/installation/)
- Follow-up to #2563 and #2587
## Validation
- `just desktop-typecheck`
- `just desktop-test` — 3,455 passed
- focused Rust post-install verification tests
- focused Playwright Doctor/onboarding coverage (in progress; CI and
local sequential rerun will provide final results)
Generated with Codex
---------
Signed-off-by: Atish Patel <atish@squareup.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Goose <opensource@block.xyz>
## Summary
- Preserve plain-string errors returned by Tauri and show an actionable
message when huddle audio is unavailable in the relay deployment.
- Use one error formatter across channel, timeline, wave, and profile
huddle actions while preserving other relay and device errors.
- Complete the huddle lifecycle when audio setup fails after publishing
a start event, preventing peers and reloaded clients from reconstructing
a phantom active huddle.
- Cover unavailable-audio formatting and START → rollback-END
reconstruction with regression tests.
## Behavior
The Tauri huddle commands reject with a plain string. Several desktop
toast call sites only preserved JavaScript `Error` objects, so the relay
message was discarded and replaced with “Failed to join huddle.”
The desktop now recognizes `huddle_audio_unavailable` and the current
relay message, then shows:
> Huddle audio isn’t available on this server. Ask an administrator to
turn it on.
Other relay and device messages remain intact, including microphone
errors.
`start_huddle` also publishes `KIND_HUDDLE_STARTED` before audio setup.
If setup fails, rollback now publishes `KIND_HUDDLE_ENDED` through the
normal end-and-archive path before resetting local state. This makes the
failed start observable to lifecycle reconstruction and prevents stale
join affordances.
## Checks
- `cd desktop && pnpm test` — 3,405 passed
- `cd desktop/src-tauri && cargo test` — 1,560 passed, 13 ignored; 3
diagnostic tests passed
- `cd desktop && pnpm exec playwright test tests/e2e/channels.spec.ts
--project=smoke --grep 'huddle rollback end event'` — passed
- `just desktop-tauri-check`
- `cd desktop && pnpm typecheck`
- `cd desktop && pnpm check`
- Pre-commit and pre-push hooks