Merge upstream/main into kannaka-buzz main (sync 2026-07-28 #2) - #4
Merged
Conversation
Search migrated to Postgres FTS (commit f8bbe6e). The Typesense container was removed from compose.yml and the Helm chart, but the cleanup missed two template/config files: - `deploy/compose/.env.example`: `TYPESENSE_API_KEY` and `TYPESENSE_PORT` are dead — no typesense service exists in compose.yml and the relay binary no longer reads `TYPESENSE_API_KEY`. The `CHANGE_ME_RANDOM_API_KEY` placeholder was never consumed, so removing it also unbreaks the sed loop in the blog draft (one fewer no-op secret to generate). - `benchmarks/harbor-buzz-orchestra/scripts/benchmark.py`: generates a typesense_api_key in state and writes `TYPESENSE_API_KEY` to the .env file it creates. - *Editing this file caused the https://github.com/block/buzz/blob/main/.github/workflows/benchmark-harbor.yml linter ci checks to run, which seemingly haven't run before, so I needed fix the lint issues to pass this.* --------- Signed-off-by: Kalvin Chau <kalvin@block.xyz> Co-authored-by: npub1c4alndp82zyt9veaklm5d965quss79vlhk9awv7qu5erwhmf42qqlvc25c <c57bf9b4275088b2b33db7f746975407210f159fbd8bd733c0e532375f69aa80@buzz.block.builderlab.xyz>
Registering a custom ACP harness works today, but only from Settings → Agents. Anyone whose first touchpoint is "New agent" has no way to discover the custom path — the dropdown just lists the baked-in presets plus whatever was registered earlier. This adds an inline "Add custom harness…" entry to the harness dropdown in all three agent surfaces: create, edit-definition (`AgentDefinitionDialog`), and instance edit (`AgentInstanceEditDialog`). The entry is a sentinel option (`ADD_CUSTOM_HARNESS_VALUE`, NUL-prefixed so it can never collide with a real harness id — backend ids match `[a-z0-9_][a-z0-9_-]*`), mirroring the `CUSTOM_ENTRY_ID` trick already used in `HarnessCatalogDialog`. Picking it never writes into form state; it opens `AddCustomHarnessDialog`, a thin modal wrapper hosting the existing `CustomHarnessForm` in `chromeless` mode. `CustomHarnessForm`'s `onSaved` now carries the saved `definition.id` (the form may rewrite it); the two existing call sites ignore the argument, so their behavior is unchanged. Selection after save is deferred rather than immediate. `usePendingHarnessSelection` holds the saved id until the runtime catalog actually publishes it via discovery, then selects it exactly once — so the dialog never selects an id it cannot render, and back-to-back registrations resolve correctly. The wait is scoped to the owning dialog's `open` state: both host dialogs stay mounted when closed, so an unpublished id is dropped on close rather than selecting into reset form state when discovery later catches up. Selection is routed through each dialog's normal dropdown change handler, so provider/model reset (and command pinning in the instance dialog) behave identically to a hand-picked harness. Dismissing the modal leaves the previous selection untouched. `AgentInstanceEditDialog`'s existing "Custom command" option is a different feature (ad-hoc command override vs. a registered reusable harness) and is untouched. Coverage is 16 unit tests in `addCustomHarness.test.mjs` (real React mount, following the existing `.test.mjs` pattern) plus 4 Playwright specs in `inline-custom-harness.spec.ts` covering all three surfaces end-to-end. Both suites were mutation-verified: treating the sentinel as a real selection, selecting before the catalog publishes, never clearing the pending id, ignoring the dialog's open state, and reversing latest-save-wins each turn the unit tests red; reverting the two dialog diffs turns all four e2e specs red. The `check-file-sizes.mjs` overrides for the two dialogs are ratcheted to their exact new counts (1048 and 1229) — verified tight in both directions, N passes and N−1 fails, so no headroom is introduced. --------- Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
…ck#3144) A Buzz install with a scheduled goose recipe fires each cron entry once per `goose acp` child instead of once, because every child unconditionally starts its own cron scheduler over the shared `~/.local/share/goose/schedule.json`. With a pool of N children per harness and multiple harnesses, one scheduled recipe fans out to N × harness_count executions — each running under the managed agent's identity rather than the operator's, and racing the operator's own standalone goose over the same schedule file. This injects `GOOSE_ACP_SCHEDULER_DISABLED=true` into every child spawned by `AcpClient::spawn`, so a managed agent never owns the operator's cron schedule. ## Placement The `cmd.env` call is set last — after the `extra_env` operator-wins loop and after the `CODEX_CONFIG` merge — deliberately with no escape hatch. Managed children not running the operator's schedule is a correctness invariant rather than an operator-tunable default, so the injection must beat both a conflicting persona `extra_env` entry and any value inherited from the parent process. It is injected for all agents, not just goose. Agent builds that don't recognize the variable ignore it. ## Sequencing The goose-side flag that reads this variable and skips scheduler startup lands separately (repo TBD). Until it does, this change is a forward-compatible no-op: it sets an environment variable nothing currently reads. Merging it first means no coordinated release is needed — the fix takes effect as soon as the goose side ships. Related: aaif-goose/goose#10738 Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
## Summary - paint the community rail across the full app height instead of exposing the parent background through external margins - preserve the existing community-button alignment and balanced horizontal gutters by moving vertical spacing inside the rail - update the rail geometry coverage to require full-height paint ownership ## Root cause PR block#2972 aligned the rail box with the inset content by adding top and bottom margins to the `bg-sidebar` element. Margins are outside the painted box, so flat light and dark themes exposed a differently colored app background above and below the rail. ## Validation - pre-push `desktop-check` - pre-push desktop unit suite: 3,751 passed - `git diff --check` Local Playwright/E2E was not run; CI owns the full browser matrix. Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
…res (block#3396) ## Problem The prerequisites table lists language toolchains (Rust, Node, pnpm, Flutter, Docker, `just`) but no system libraries. Hermit pins the former and not the latter, so following the setup section exactly on Linux still leaves `just ci` unable to run: it fails partway through its first dependency, `just check`, at `desktop-tauri-clippy`. ``` The system library `gdk-pixbuf-2.0` required by crate `gdk-pixbuf-sys` was not found. The file `gdk-pixbuf-2.0.pc` needs to be installed and the PKG_CONFIG_PATH environment variable must contain its parent directory. ``` The desktop crates link against GTK and WebKitGTK. CI installs those packages explicitly, so it never sees this — which is exactly why the gap is invisible from the maintainer side. Since `check` runs first in the `ci` chain, the failure also masks everything after it (`test-unit`, `desktop-test`, `web-build`, `mobile-test` never run), which makes it read as a broken repo rather than a missing dependency. ## Change Adds a `#### Linux: Tauri system libraries` subsection under Prerequisites with: - The apt list copied from `.github/workflows/ci.yml`, so a local run matches CI rather than drifting from it - A pointer to [Tauri's prerequisites](https://tauri.app/start/prerequisites/) for non-Debian distributions - A note that server-side contributors can skip it — `just fmt-check`, `just clippy`, `just test-unit`, and `just test` need no GTK Docs only. No TOC entry needed, since the TOC lists `##` headings and this is a `####` subsection. ## How I hit it Running `just ci` before pushing block#3372, on Ubuntu under WSL2 with the Hermit toolchain active and all Docker services healthy. Everything the guide asks for was in place. The four `check` steps before `desktop-tauri-clippy` (`fmt-check`, `clippy`, `desktop-check`, `desktop-tauri-fmt-check`) passed, which is what makes the failure point specific rather than a general build problem. ## Closest existing work None found. I searched open and closed issues and PRs for `gdk-pixbuf`, `libgtk`, `webkit2gtk`, `system dependencies`, `prerequisites`, `just ci`, and `linux setup`. The Linux/GTK issues that exist (block#2604, block#2643, block#2982, block#2811, block#2562) are all runtime bugs in shipped builds, not setup-path failures. ## Verification The package list is transcribed from `.github/workflows/ci.yml:152-163`; the same list appears in `release.yml` and `linux-canary.yml`. I have not installed the packages on my machine, so I can confirm the failure and the source of the fix but not that the list is exhaustive on a clean box — worth a second pair of eyes from anyone who has done a fresh Linux setup recently. Signed-off-by: Kyler Cao <kcao@gssmail.com>
…lock#2004) ## Summary Fixes 4 flaky DM expansion E2E tests in Desktop Smoke shard 1 that were failing non-deterministically on CI (also reproducing on `main` at run `29526844596`). **Failing tests:** - `channels.spec.ts:652` — creates the DM before preparing a persona mention - `channels.spec.ts:760` — routes an agent mention from an existing DM to the expanded conversation - `channels.spec.ts:815` — routes a relay-agent mention from an existing DM to the expanded conversation - `channels.spec.ts:940` — drops an expanded DM after the first message fails ## Root Cause Race condition: under fast CI execution, mock command completions (create_managed_agent, open_dm) can resolve in non-deterministic order, causing assertions to observe stale or mid-transition state. ## Fix - **:652** — Move the `new-message-recipient-popover` hidden assertion after `chat-title` settles (both names present), so it runs post-transition rather than mid-transition. - **:760, :940** — Add `createManagedAgentDelayMs: 100` to ensure persona provisioning doesn't collapse into the same tick as the expanded-DM open/start sequence. - **:815** — Add `openDmDelayMs: 100` so the two open_dm calls resolve in deterministic order. ## Validation All 4 tests pass with `--repeat-each=3` (12/12 green) locally. Biome lint clean. ## Scope Test-only change: 12 insertions, 1 deletion in `desktop/tests/e2e/channels.spec.ts`. --- Investigated by Ferret, reviewed by Grumplestiltzkin. Signed-off-by: Cameron Hotchkies <chotchkies@block.xyz> Co-authored-by: Goose <opensource@block.xyz>
…block#3271) On some Linux GPU/driver/compositor combinations, WebKitGTK's dmabuf renderer aborts the web process during startup, so Buzz comes up with no window at all and the user has no way to fix it. Setting `WEBKIT_DISABLE_DMABUF_RENDERER=1` avoids the abort by falling back to the shared-memory buffer path. WebKit reads each of its rendering variables exactly once per process, so the choice has to be made before anything initializes — there is no runtime toggle and no second chance later in the same process. This decides up front from two cheap preflight signals rather than reacting to a crash: - **NVIDIA GPU** — any DRM device under `/sys/class/drm` reporting PCI vendor `0x10de`, the driver family behind most upstream reports. - **AppImage** — the `APPIMAGE` environment variable. linuxdeploy's AppRun hook pins `GDK_BACKEND=x11`, and the dmabuf renderer buys nothing on that XWayland path. Either signal disables the dmabuf renderer. Neither signal leaves the environment untouched. ## Escape hatches `--safe-rendering` forces the safest configuration for one launch — `WEBKIT_DISABLE_DMABUF_RENDERER` plus `WEBKIT_DISABLE_COMPOSITING_MODE` — for a machine neither signal recognises. Any user assignment of a variable this module may set stands the heuristic down **wholesale**. Presence is the test, not truthiness, so `VAR=0` and `VAR=` both count: a user asking for the dmabuf renderer *on* gets it, even on a machine the heuristic would have opted out. `--safe-rendering` against such an assignment is refused with a diagnostic naming both the assignment and the key to unset, and exits non-zero — the flag and the environment are two incompatible answers to one question, and neither is guessed. ## Placement `webkit_rendering::apply()` runs at the top of `fn main()`, before `buzz_lib::run()`. That is the only point where the process is still single threaded with no GTK object alive, which is what makes `std::env::set_var` sound; the module doc and the call site both say so. The whole module is `#[cfg(target_os = "linux")]` — macOS and Windows compile none of it. The decision is a pure function of argv, an injected environment lookup, and an injected DRM root, so all of it is unit-testable without mutating the process environment. Closes block#2338. Upstream: [tauri#9394](tauri-apps/tauri#9394). Same approach and same variable as [clash-verge-rev](https://github.com/clash-verge-rev/clash-verge-rev/blob/main/src-tauri/src/utils/linux/workarounds.rs) `workarounds.rs` and [screenpipe](https://github.com/screenpipe/screenpipe/blob/main/apps/screenpipe-app-tauri/src-tauri/src/linux_webkit_env.rs) `linux_webkit_env.rs`. Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
…lock#3007) Mid-turn steering was reachable only through goose's `_goose/unstable/session/steer`, which requires an `expectedRunId` sourced from `_meta.goose.activeRunId`. claude-agent-acp and codex-acp never emit a run id, so every mid-turn mention to those harnesses bailed at the run-id guard before writing a byte and degraded to cancel + merge, destroying in-flight tool calls. Both adapters ship `_session/steering` (params `{sessionId, prompt}`, result `{outcome}`) and advertise it as `_meta.steering.supported` on the `initialize` response. This adds it as a second steer transport selected at write time, reusing the existing withhold/release, ack routing, and cancel+merge fallback machinery unchanged. ## Transport selection | `active_run_id` | `steering_supported` | Transport | |---|---|---| | `Some(run_id)` | any | `_goose/unstable/session/steer` + `expectedRunId` (unchanged) | | `None` | `true` | `_session/steering` with `{sessionId, prompt}` | | `None` | `false` | ack `ExpectedRunIdMissing`, write nothing (unchanged) | goose keeps priority when both are present — `expectedRunId` is strictly more precise about *which* run is being steered. ## Two load-bearing safety properties **The advertised capability is the only gate — never error-code probing.** codex-acp's `extMethod` answers unrecognized extension methods with a bare `{}`, which is a JSON-RPC *success* rather than `-32601`. Buzz maps a steer success to `queue.remove_event`, so probing an unknown method would silently delete the user's message with no error, no fallback, and no log line. **An `outcome` must be positively recognized.** Only `injected` and `startedNewTurn` count as delivery. Anything else — codex's `failed`, an unknown value, or a missing `outcome` entirely — is `SteerError::OutcomeRejected`, which releases the withheld event and fires the cancel+merge fallback. This makes the silent-loss path above unreachable even if an adapter mis-advertises. `startedNewTurn` acks `Success`, because the message really was delivered and must not be redelivered, but deliberately does **not** renew the read loop's hard deadline: the turn Buzz was awaiting had already settled, and renewing would extend the clock on a finished turn. ## Notes for reviewers - `SteerError::OutcomeRejected` needs no new arm in the `PoolEvent::SteerAck` match — the existing catch-all `Ok(SteerAck::Err(_)) => (true, false, true)` already gives release + fallback, and the two `AgentError` arms above it match that variant specifically, so they do not shadow it. - Comments that described the old goose-only "try-and-tolerate" `-32601` behavior are corrected; that assumption was never valid for codex-acp. - No CI job runs `buzz-acp` tests. The full package suite was run locally: **617 passing, 0 failing**. Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
## Why Publish chart 0.1.7 after the feature PR merged from a fork and therefore intentionally skipped the internal-branch auto-tag job. ## What - Trigger the `chart-release/0.1.7` release lane - Update the quickstart example to reference chart 0.1.7 ## Risk Assessment Low — the chart implementation is already merged and tested; this PR creates its immutable release tag and OCI artifact. ## References - Chart implementation: block#3322 - `helm unittest` 0.8.2: 43/43 tests passed - Local pre-push checks passed Generated with Amp Signed-off-by: David Grochowski <dgrochowski@squareup.com> Co-authored-by: Amp <amp@ampcode.com>
Three main-branch runs today had shards killed at exactly 20m17s
("exceeded the maximum execution time of 20m0s"); the killed shard was
actively passing tests seconds before the cap. Shard runtime has grown
to the limit. 30 matches the other desktop jobs in the same workflow.
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
flaukowski
added a commit
that referenced
this pull request
Jul 29, 2026
Merge upstream/main into kannaka-buzz main (sync 2026-07-28 #4)
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.
Summary
Second upstream sync today: merges 8 new block/buzz:main commits (ACP session steering, inline custom harness, Linux WebKit workarounds, goose cron fix in managed children, smoke-E2E timeout bump, chart 0.1.7, docs). Merge was conflict-free; the fork's mesh-llm cold-cache CI fallback survives intact in all three workflows.
Verified locally:
cargo check -p buzz-acp(the only Rust crate touched upstream) plus buzz-kannaka and buzz-workflow test suites all green.Note:
mainnow rejects direct pushes (repository rule), so this sync lands via PR — merge with a merge commit (no squash/rebase) to keep sync history convergent.City-Agent: claude-fable-5
🤖 Generated with Claude Code