Commit Graph
235 Commits
Author SHA1 Message Date
Will PflegerandGitHub b0503d80c2 feat(desktop): add custom harness inline from agent dialogs (#3252)
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>
2026-07-28 16:01:41 -04:00
a35771fc44 feat(desktop): refine agent catalog sharing (#2439)
## Summary

- add custom-agent catalog sharing and hide built-ins from discovery
- let owners publish later catalog updates from Share or while saving
edits — the save always persists locally, and the publish reports
`published` or `queued` (flushed automatically once the relay is
reachable again)
- preserve agent type, model, and runtime across snapshot import/export
- simplify agent and team entry points and tighten catalog layout
- migrate the legacy global retention queue into the owner's active
scope so pending catalog publishes survive the upgrade
- keep the agent list and edits usable in recovery mode by degrading to
unshared projections when scope resolution or the retention DB fails
- track catalog provenance on copied personas, so adding an
already-added foreign agent resolves to the existing copy instead of
creating a duplicate
- scope inbound persona events to the community relay they arrived on
- page the catalog read past the relay's 1,000-row query clamp
- unify the share dialog's memory-level choice into a single "What's
included" selector that drives both DM-send and copy-link delivery (all
six combinations preserved), group the delivery rows above the option
rows, and label the catalog toggle "Not shared" / "Shared"
- keep emoji avatars on catalog entries — they persist as inline
percent-encoded SVG, which the catalog projection's http(s)-only URL
guard used to drop, so a shared agent showed initials instead of its
avatar
- drop the "Active in communities" card from Agents settings, superseded
by the per-channel runtime controls in the members sidebar

## Screenshots

### Agent actions

![Agent
actions](https://raw.githubusercontent.com/block/buzz/4643581cd0882d8b101b04e3d8be290ea7e39f08/pr-2439--01-agent-menu.png)

### Team avatar stack

![Team avatar
stack](https://raw.githubusercontent.com/block/buzz/4643581cd0882d8b101b04e3d8be290ea7e39f08/pr-2439--02-team-menu.png)

### Catalog sharing

![Catalog
sharing](https://raw.githubusercontent.com/block/buzz/648d6eaf6df7d4daa5b7375948ed221f723793d6/pr-2439--03-share-to-catalog.png)

### Publish while editing

![Publish while
editing](https://raw.githubusercontent.com/block/buzz/bd4eb473ff456f6e665173054dc5a0f764594d1e/pr-2439--01-edit-agent-publish-updates.png)

### Publish from Share

![Publish from
Share](https://raw.githubusercontent.com/block/buzz/648d6eaf6df7d4daa5b7375948ed221f723793d6/pr-2439--02-share-dialog-publish-updates.png)

### Catalog details

![Catalog
details](https://raw.githubusercontent.com/block/buzz/4643581cd0882d8b101b04e3d8be290ea7e39f08/pr-2439--04-agent-catalog.png)

---------

Signed-off-by: kenny lopez <klopez4212@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
2026-07-28 15:01:03 -04:00
Will PflegerandGitHub 4e3998f36e fix(desktop): gate codex-acp on a minimum supported version (#3254)
The codex adapter version gate accepted any `major >= 1`, so a 1.x
`codex-acp` older than the version that fixes outbound relay access for
`buzz` CLI subprocesses classified as `Available` and was never offered
a reinstall. Only the 0.16.x `@zed-industries/codex-acp` adapter — which
fails `--version` outright — was caught.

`probe_codex_acp_version` now returns the full `(major, minor, patch)`
triple and `codex_adapter_availability` compares it against a new
`MIN_CODEX_ACP_VERSION` floor of `1.1.7`, the current npm latest. An
adapter below the floor classifies as `AdapterOutdated`, which routes it
through the existing uninstall-then-install reinstall plan.

The parse requires exactly three numeric dot-separated components.
Partial versions (`1.2`) and prerelease tags (`1.2.0-rc1`) return `None`
and therefore classify as `AdapterOutdated` — a version Buzz cannot
compare against the floor fails closed, offering a reinstall rather than
running an adapter of unknown vintage. Both the floor's bump policy and
the strict-parse behavior are stated in doc comments rather than left
implicit.

Supersedes [#3097](https://github.com/block/buzz/pull/3097) by
@Bharathchinneni, whose semver floor and behavior tests this carries.
That PR could not land as written: the two
`probe_codex_acp_major_version` compatibility wrappers it kept had no
non-test callers, which is a hard `clippy -D warnings` failure. The
wrappers are deleted here and their call sites collapsed onto
`probe_codex_acp_version`.

Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
2026-07-28 13:56:59 -04:00
Will PflegerandGitHub be13b4bb9c fix(desktop): probe legacy Goose install dir on Windows (#3248)
Goose's pre-[#2680](https://github.com/block/buzz/pull/2680) Windows
installer unpacked the CLI to `%USERPROFILE%\goose\goose.exe`. That
directory is on no standard `PATH`, and `common_binary_paths()` never
probed it, so users who installed Goose with the legacy installer stayed
permanently undiscovered — the residual half of #2239.

`resolve_command_uncached` finds binaries outside `PATH` only by
scanning `common_binary_paths()`, so adding the directory there is the
whole fix: Windows basename expansion already supplies
`goose.exe`/`.cmd`/`.bat`, and discovery, readiness probes, and spawn
all route through the same shared resolver. No Goose-specific resolution
path is introduced. The entry sits beside the existing Codex
`%LOCALAPPDATA%\Programs\OpenAI\Codex\bin` probe in the same
`#[cfg(windows)]` block.

The regression test is `#[cfg(windows)]` and is CI-reachable, not dead
code — the `desktop-build-windows` job runs `cargo test --manifest-path
desktop/src-tauri/Cargo.toml --target $env:TARGET` on `windows-latest`.
It asserts the probe list rather than planting a binary:
`common_binary_paths` is a process-lifetime `OnceLock`, so a test cannot
deterministically re-seed `USERPROFILE`, and planting an executable
under the real user profile is not an acceptable side effect. Verified
locally by widening the `cfg` to build on macOS — the test passes with
the probe and fails without it.

The `check-file-sizes.mjs` override for `managed_agents/discovery.rs`
moves 1835 → 1841, the exact post-`cargo fmt` gate count. Verified both
directions: 1841 passes, 1840 fails.

Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
2026-07-27 21:30:21 -04:00
Will PflegerandGitHub 94675e0d25 refactor(desktop): extract install command execution into install_exec (#3251)
`commands/agent_discovery.rs` was pinned at its 2167-line file-size
ceiling with zero headroom, blocking the install-supervision and
install-log work queued behind it. Install command *execution* is a
clean seam and moves into `commands/agent_discovery/install_exec.rs`
together with its tests, matching the existing `managed_node.rs` /
`post_install_verification.rs` split under the same module.

Moved: `INSTALL_MAX_ATTEMPTS`, `run_install_command_with_retry`,
`run_install_with_retry`, `install_failure_is_retryable`,
`install_retry_backoff`, `annotate_retry_attempts`,
`run_install_command`, `truncate_output`, `floor_char_boundary`, and the
install-retry test block. Command *construction*
(`install_shell_command`, `install_powershell_command`,
`build_install_command`) stays in the parent — the new module owns only
what happens once a `Command` exists. Public surface is exactly one
`pub(super) fn run_install_command_with_retry`.

The extraction is behavior-preserving, verified by diffing the moved
text against the original line ranges: the parent is original-minus-cuts
plus the intended edits, and the moved code is byte-identical except for
the `pub(super)` marker, the `build_install_command` →
`prepare_install_command` call site, and the new function described
below. Two parent imports (`std::io::Read`, `InstallStepResult`) became
unused and were dropped.

### Install working directory (#2245)

Absorbed from #3090. A packaged desktop launch inherits `/` as its
working directory, so installers that write relative to the CWD fail on
a read-only root. The new `prepare_install_command` builds the command
and applies `default_agent_workdir()`, and it is the only builder
`run_install_command` calls — so no spawn path can bypass the workdir.

This differs from #3090 in the test: that version spawned `pwd` through
the real install shell and deleted
`test_install_shell_command_returns_ok_on_unix` to make room. Here the
prepared `Command` is asserted directly via `get_current_dir()` —
hermetic, no shell spawn — and the existing test is kept.

### Tests

Four new, on top of the moved retry block:

- `test_prepared_install_command_uses_default_workdir` — every install
child carries `default_agent_workdir()`.
- `test_truncate_output_leaves_short_output_untouched` — under the cap,
byte-for-byte passthrough.
- `test_truncate_output_keeps_head_and_tail_with_marker` — over the cap,
both ends survive and the marker names the omitted byte count.
- `test_truncate_output_does_not_split_multibyte_characters` — the
boundary floor prevents a mid-codepoint cut.

`truncate_output` had no coverage anywhere before this.

### File-size gate

`check-file-sizes.mjs` override for `agent_discovery.rs` moves 2167 →
1808, the exact post-`cargo fmt` gate count — verified both directions
(1808 passes, 1807 fails). `install_exec.rs` is 458 lines and needs no
override; the default 1000-line limit covers it.

Related: #3090, #2245

Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
2026-07-27 21:29:44 -04:00
d98da7389e feat(desktop): redesign agent runtime settings (#3093)
**Category:** improvement
**User Impact:** Users can understand, install, authenticate, and manage
agent runtimes from one progressively disclosed Agents settings
experience.

**Problem:** Runtime health and custom harness management were split
across overlapping settings surfaces, exposing low-level configuration
too early while leaving setup and authentication states hard to
understand. **Solution:** Consolidate those operations into one stable
runtime list and an Add runtimes catalog, with task-oriented state
labels, direct setup actions, and custom configuration contained in a
dedicated form.

<details>
<summary>File changes</summary>

**desktop/playwright.config.ts**
Registers the visual coverage needed for the redesigned runtime catalog.

**desktop/public/harness-logos/CREDITS.md**
Documents bundled runtime-mark provenance and the decision not to ship
the withdrawn OpenAI mark.

**desktop/public/runtime-icons/codex.png**
Removes the obsolete Codex bitmap in favor of the neutral fallback.

**desktop/public/runtime-icons/goose.svg**
Removes the old Goose asset now replaced by the theme-adaptive mark.

**desktop/src-tauri/src/managed_agents/discovery.rs**
Aligns runtime discovery guidance with the new task-oriented setup
language.

**desktop/src-tauri/src/managed_agents/discovery/runtime_metadata.rs**
Updates runtime metadata used by the redesigned settings states.

**desktop/src/features/agents/ui/runtimeAvailabilityWarning.test.mjs**
Updates availability-warning expectations for the revised runtime
guidance.

**desktop/src/features/onboarding/assets/harness-logos/chatgpt.png**
Removes the redundant bitmap from the unified runtime icon pipeline.

**desktop/src/features/onboarding/assets/harness-logos/goose.png**
Removes the redundant Goose bitmap.

**desktop/src/features/onboarding/ui/HarnessMarks.tsx**
Adds theme-adaptive bundled runtime marks with safe fallbacks.

**desktop/src/features/onboarding/ui/RuntimeIcon.tsx**
Centralizes runtime logo rendering so settings and catalog rows cannot
drift.

**desktop/src/features/onboarding/ui/SetupStep.tsx**
Aligns onboarding runtime setup copy with the settings terminology.

**desktop/src/features/onboarding/ui/presetLogos.test.mjs**
Guards bundled-logo behavior and prevents the withdrawn Codex mark from
returning.

**desktop/src/features/settings/ui/CustomHarnessForm.tsx**
Reworks custom runtime creation and editing into a clear, dedicated
catalog form.

**desktop/src/features/settings/ui/HarnessCatalogDialog.tsx**
Introduces the Add runtimes master-detail catalog, grouped setup states,
loading treatment, and pinned actions.

**desktop/src/features/settings/ui/HarnessManagementCard.tsx**
Removes the superseded standalone custom-harness management surface.

**desktop/src/features/settings/ui/HarnessRow.tsx**
Provides stable operational runtime rows with install, update,
authentication, edit, and delete behavior.

**desktop/src/features/settings/ui/HarnessesSettingsPanel.tsx**
Consolidates runtime health and custom management into one Agents
settings panel.

**desktop/src/features/settings/ui/SettingsPanels.tsx**
Wires the consolidated panel into Agents settings.

**desktop/src/features/settings/ui/harnessCatalogCopy.ts**
Adds restrained, source-annotated runtime descriptions and setup
guidance.

**desktop/src/features/settings/ui/harnessCatalogLogic.test.mjs**
Covers grouping, state labels, stable row order, actions, and adapter
warnings.

**desktop/src/features/settings/ui/harnessCatalogLogic.ts**
Centralizes catalog grouping, actions, status labels, and runtime-safe
warning copy.

**desktop/src/features/settings/ui/harnessGalleryLogic.test.mjs**
Removes obsolete gallery-only tests after consolidation.

**desktop/src/features/settings/ui/harnessGalleryLogic.ts**
Retains only the shared custom-runtime safety logic needed by the new
surface.

**desktop/src/shared/ui/config-nudge-attachment.tsx**
Points configuration nudges to Agent runtimes with matching terminology.

**desktop/src/testing/e2eBridge.ts**
Adds deterministic runtime states for authentication and catalog E2E
coverage.

**desktop/tests/e2e/doctor-states.spec.ts**
Verifies ready, setup-required, node-gated, authentication, loading, and
error contracts.

**desktop/tests/e2e/harness-catalog-screenshots.spec.ts**
Captures whole-pane visual states for the runtime catalog experience.

**desktop/tests/e2e/harness-management.spec.ts**
Exercises catalog actions and custom runtime create, edit,
authentication, and deletion flows.

**desktop/tests/e2e/onboarding-agent-defaults.spec.ts**
Updates default-runtime expectations for the consolidated experience.

**desktop/tests/e2e/profile.spec.ts**
Aligns profile navigation assertions with the new settings surface.

</details>

## Reproduction steps

1. Open Settings → Agents and inspect Agent runtimes; ready, signed-out,
installable, and setup-required runtimes should have stable rows and
explicit actions.
2. Open Add runtimes and browse the Setup and Installed groups; select
entries to see sourced guidance and a pinned Install or Setup guide
action.
3. Select Custom harness, create a runtime, then edit and delete it;
verify required-field gating and the blast-radius confirmation.
4. Exercise a signed-out runtime and connect it; the row should move
from Sign-in needed to Ready without reordering.
5. Resize the window and switch themes to verify responsive layout and
adaptive bundled marks.

## Screenshots

| Mixed runtime states | Goose not installed | Sign-in needed |
|---|---|---|
| <img width="980" height="1000" alt="image"
src="https://github.com/user-attachments/assets/28705b39-1d91-440a-a954-fb2d7d8ee759"
/> | <img width="980" height="1000" alt="image"
src="https://github.com/user-attachments/assets/e65ce8e1-8c85-4272-afb5-e6001b94d560"
/> | <img width="980" height="1000" alt="image"
src="https://github.com/user-attachments/assets/3987f355-960d-4744-8c26-b3746944a33c"
/> |

| Add runtimes catalog | Custom runtime | Setup guide |
|---|---|---|
| <img width="896" height="672" alt="image"
src="https://github.com/user-attachments/assets/a2f32c8a-4dff-4929-af96-b07346933335"
/> | <img width="896" height="672" alt="image"
src="https://github.com/user-attachments/assets/b2e85a0c-3940-4875-a138-4035423c9de7"
/> | <img width="896" height="672" alt="image"
src="https://github.com/user-attachments/assets/5a690c1c-368e-4ee3-98b9-ffefdc3cf804"
/> |

Full 13-state screenshot matrix and review evidence:
https://buzz.block.builderlab.xyz/channels/c5af9e3e-4317-4853-b3e3-ed9c15bc511d?event=ec88f6e472f2b08d6318ae76fd754fd4f218385f67cfe59b73034c4bc34c9252

---------

Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@buzz.block.builderlab.xyz>
Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@buzz.block.builderlab.xyz>
2026-07-27 11:01:42 -07:00
8995316844 fix(desktop): use forward slashes for git credential.helper on Windows (#3023)
## Problem

On Windows, Projects **Remote** view shows an empty file tree and
Sync/Clone fails with a mangled credential-helper path, for example:

```
C:\Users\<user>\AppData\Local\Buzz\git-credential-nostr.exe get: line 1:
C:Users<user>AppDataLocalBuzzgit-credential-nostr.exe: command not found
fatal: could not read Username for 'https://<relay>/git/...': terminal prompts disabled
```

Buzz injects an absolute path into `credential.helper` via
`Path::display()`. On Windows that yields backslashes. Git for Windows
runs credential helpers through MinGW bash, which treats `\` as escapes
and destroys the path, so NIP-98 auth never runs and the blobless temp
clone behind Remote view fails.

macOS/Linux are unaffected (paths already use `/`).

This is unrelated to shipping a stub helper - the bundled
`git-credential-nostr.exe` is a real binary. User `~/.gitconfig`
workarounds also cannot help here because Projects git sets
`GIT_CONFIG_GLOBAL=/dev/null` and injects its own helper.

Closes #3025

## Fix

Normalize the helper path to forward slashes before writing
`GIT_CONFIG_VALUE_*`:

- `desktop/src-tauri/src/commands/project_git_exec.rs` (Projects Remote
/ Sync)
- `desktop/src-tauri/src/managed_agents/runtime.rs` (agent spawn git
auth)

Forward slashes are accepted by Git on every platform; on macOS/Linux
the replace is a no-op. No `cfg(windows)`, packaging, or libgit2
changes.

## How to reproduce (before)

1. Install Buzz on Windows with Git for Windows
2. Connect to a relay that has a repository with at least one pushed
branch
3. Open **Projects** -> select the repo -> **Remote**
4. Observe empty tree; Sync/Clone shows the mangled-path / `command not
found` error above

## Test plan

- [x] Unit: `cargo test --manifest-path desktop/src-tauri/Cargo.toml
credential_helper_config_value` (formatter covered on all platforms;
no-op for Unix-style paths)
- [x] Local Windows NSIS build + install of this branch
- [x] Projects -> Remote / Sync against a Buzz relay repo succeeds on
Windows after the fix

---------

Signed-off-by: Bjorn de Jong <bcrdejong@users.noreply.github.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: Bjorn de Jong <bcrdejong@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
2026-07-27 13:56:34 -04:00
Will PflegerandGitHub b92a1f4bf4 chore(desktop): add AgentCreationPreview file-size override to unblock main CI (#3154)
`Desktop Core` is currently red on `main`, and every open PR that picks
up current main inherits the failure.

[#2630](https://github.com/block/buzz/pull/2630) added a shadow-root
search-input autofocus effect to `AgentCreationPreview.tsx`, taking the
file from 999 to 1026 lines. It sat one line under the 1000-line default
beforehand, so that PR's own CI was green while the merged file crossed
the cap with no override entry in
`desktop/scripts/check-file-sizes.mjs`.

This adds the missing entry at 1026, following the pattern the rest of
the overrides list uses. The split stays queued along with the others.

```
- src/features/agents/ui/AgentCreationPreview.tsx: 1026 lines (limit 1000)
```

The override is tight in both directions: at `1026` the gate passes, and
at `1025` it reproduces the failure above.

Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
2026-07-27 13:18:44 -04:00
Will PflegerandGitHub f2fe3b63c2 feat(acp): title agent sessions from the agent and channel name (#3028)
ACP harnesses that name a session from the first text they receive all
land in the same place: every managed Buzz agent opens with the
identical `[Base] You are operating inside the Buzz platform…` framing,
so the harness session list shows a wall of indistinguishable rows.
Because sessions are keyed per channel, one agent active in several
channels produces several of them.

This sends the name out of band instead. `session/new` carries
`_meta.sessionTitle` with `Agent · #channel`, composed from the agent's
`display_name` (or its unique `name` handle) and the channel it is
serving. The prompt is untouched — no tokens spent, no perturbation of
the prompt contract, and nothing new for the desktop observer's section
parsing to handle.

The mechanism is harness-agnostic: Buzz sends the field on every ACP
`session/new` regardless of which harness is behind it, and adapters
that don't read it ignore it per spec.

## Inert until a consuming adapter ships

ACP adapters ignore `_meta` members they do not recognize, so against an
adapter with no reader a Buzz session gets no title and nothing else
changes. Three adapter halves consume it — Codex, Goose, and Claude Code
(linked below); this half and each reader are only useful together, and
each reader lands independently.

No version floor is added. `codex_adapter_is_outdated_with_path` already
gates codex-acp on major version `>= 1`
(`desktop/src-tauri/src/managed_agents/discovery.rs:1276-1284`) and this
feature needs nothing above that — an older adapter is not broken by the
extra member, it simply ignores it.

## What changes

**`crates/buzz-acp`** owns sanitization and composition.
`sanitize_session_title` collapses whitespace, drops control characters,
and caps at `SESSION_TITLE_MAX_CHARS` (80) by character, not byte, so a
multi-byte character cannot be split. `compose_session_title` truncates
only the channel part against that cap, so the agent name always
survives; when the agent name alone fills the cap the channel is dropped
rather than the name. `session_new_full` sets `_meta.sessionTitle` when
a title exists and omits `_meta` entirely when it does not, since an
adapter may distinguish an absent member from a null one.

**`desktop/src-tauri`** only resolves and exports.
`resolve_session_title` picks `display_name` or falls back to `name`,
and `spawn_agent_child` writes it to `BUZZ_ACP_SESSION_TITLE` — or
removes the variable when neither candidate yields anything printable.

DMs, unresolved channels, and heartbeat sessions get the bare agent name
with no channel suffix.

## Four properties that are easy to remove by accident

**Control characters are stripped at the desktop boundary, not in the
harness.** An interior NUL cannot cross the environment boundary at all
— `Command::env` fails the entire spawn rather than passing it through.
Deferring the strip to `buzz-acp` would let a corrupted display name
turn display chrome into a spawn failure. A display name that is *only*
control characters falls back to `name`.

**The title is hashed into `spawn_config_hash`.** Without it, renaming
an agent left the running process with a stale title and no restart
badge. The hash runs the same `resolve_session_title` the spawn writes,
and skips it when a user env override shadows `BUZZ_ACP_SESSION_TITLE` —
spawn writes the title *before* the layered user env, so the override is
what actually runs, and it already reaches the hash through
`descriptor.env`. Hashing the record-derived value under an override
would badge a rename that changes nothing.

**One channel resolve serves both consumers.**
`resolve_new_session_channel_context` returns `(is_dm, title_channel)`
from a single metadata lookup, feeding both the canvas block's DM check
and the title. `ChannelInfoResolver` caches only `Some`, so two
independent calls against an unresolvable channel pay the full
`fetch_channel_info` retry sequence twice — two timeouts plus a retry
delay each — directly in front of `session/new`, precisely when the
relay is already degraded.

**The `"unknown"` channel name is treated as absent.**
`fetch_channel_info` substitutes the literal `"unknown"` for a metadata
event with no `name` tag. Composing that sentinel would title every
unnamed channel `Agent · #unknown`, reintroducing the exact collision
the suffix exists to remove while naming a channel something it isn't.
The startup cache already refuses `channel_type == "unknown"` for the
same reason.

Closes #2334

Related — the adapter halves that consume `_meta.sessionTitle`:

-
[codex-acp#338](https://github.com/agentclientprotocol/codex-acp/pull/338)
— Codex
-
[aaif-goose/goose#10712](https://github.com/aaif-goose/goose/pull/10712)
— Goose
-
[claude-agent-acp#920](https://github.com/agentclientprotocol/claude-agent-acp/pull/920)
— Claude Code

---------

Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
2026-07-27 12:46:43 -04:00
654f384906 fix(desktop): read the newest pair-scoped harness log (#3134)
Harnesses became per (agent, relay) pair in #2122 and now write
`agents/logs/{pubkey}__{sha256(relay_url)}.log` via
`managed_agent_runtime_log_path`. `get_managed_agent_log` was never
updated and still read the legacy `agents/logs/{pubkey}.log`, so agent
profile → Runtime → Harness Log froze at each agent's last
single-runtime line while live output accumulated in files the reader
never opened.

The reader now resolves the log through `latest_managed_agent_log_path`,
which picks the most recently modified file belonging to the agent —
pair-scoped `{pubkey}__*.log` or legacy `{pubkey}.log` — and falls back
to the legacy path when the agent has no log on disk at all. Agents that
have not restarted since the update keep working, and the panel follows
whichever harness is currently writing. The response already carried
`log_path`, so the panel header names the file being shown.

Selection is deterministic: equal mtimes break toward the higher
filename, and files belonging to other agents or without a `.log`
extension are never candidates.

`storage.rs`'s inline test module moves to a `#[path]`-included sibling
`storage_tests.rs`, matching the existing pattern in `teams.rs` and
`archive/mod.rs`. This drops both halves under the desktop file-size
limit (1383 → 826 / 701), so the ratchet entries tighten instead of
growing.

Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
2026-07-27 11:45:03 -04:00
95fdf97880 feat(acp): bring your own harness (BYOH) — generic ACP runtime seam + settings gallery (#2773)
## What

Implements a "bring your own harness" (BYOH) generic ACP mechanism —
replacing per-harness backend code with a data-driven 3-tier system:

- **Tier 1 (compiled-in builtins):** goose, claude, codex, buzz-agent —
unchanged behavior
- **Tier 2 (bundled presets):** cursor, omp, grok, opencode, kimi, amp,
hermes, openclaw, and any future additions — defined in
`PRESET_HARNESSES`, no code duplication, icons stay
TerminalSquare/bundled-asset-only
- **Tier 3 (user-defined custom):** JSON definitions saved to
`custom_harnesses/` under app data; managed via Settings → Agents UI

## Changes

### Core data model
- `HarnessDefinition` — id, label, command, args, env, install URL/hint
- `PRESET_HARNESSES` static table — single source of truth for all
presets; `preset_harness_ids()` derives reserved IDs (D-11: no
hand-maintained copy)
- `source: "builtin" | "preset" | "custom"` tagging on every catalog
entry

### Persistence (B-4, B-6)
- `save_custom_harness_to_dir(dir, definition, rename_old_id)` —
backup-swap atomic write (backs up target → .bak, commits temp → target,
restores .bak on failure, removes .bak on success); safe on Windows
where `fs::rename` over an existing file is "access denied"
- `save_and_warm` / `delete_and_warm` — hold `PERSIST_MUTEX` for the
write + registry-warm pair, eliminating the lost-update race (B-6) where
two concurrent saves could interleave their warm calls and leave a stale
registry snapshot
- Validate-before-mutate: both IDs and env validated before any
filesystem mutation

### Env validation boundary (B-3)
- `validate_harness_definition_pub` calls `validate_user_env_keys` on
definition env at save AND load
- Rejects malformed keys (BUZZ_AUTH_TAG=x forgery shape), reserved keys
(BUZZ_MANAGED_AGENT etc.), NUL bytes, oversized values

### TypeScript boundary (B-2 / Thufir CRITICAL)
- `RawAcpRuntimeCatalogEntry` now declares `definition_env?:
Record<string,string>` and `source: "builtin" | "preset" | "custom"`
- `fromRawAcpRuntimeCatalogEntry` maps `definition_env → definitionEnv`
(camelCase); absent field defaults to `{}`
- Edit form reads `entry.definitionEnv` — env no longer erased on
save-then-edit cycle

### Unified descriptor (Phase A / Thufir F4)
- `EffectiveHarnessDescriptor { command, args, env }` in `readiness.rs`
- `resolve_effective_harness_descriptor()` — single resolver used by
spawn, spawn_hash, summary, get_agent_models (both saved and unsaved),
and readiness
- No competing arg-resolution forms

### Other fixes
- B-5: stop freezing `runtime.defaultArgs` into `record.agent_args` on
normal create paths
- B-7: readiness exec-check — `MissingBinary` variant for custom
commands not found on PATH
- B-8: onboarding transition — `setTimeout(0)` removed, parent-owned
route intent via `navigateAfterComplete` prop
- C-9: collector-discriminating sweep tests with injectable filters
- C-10: `HarnessManagementCard` uses `harnessGalleryLogic` helpers
(killed duplicate filter/sort)
- D-11: `BUILTIN_IDS` derived from `PRESET_HARNESSES` (no
hand-maintained copy)
- D-12: `mobile/pubspec.lock` churn reverted
- D-13: false ownership fast-path comment fixed
- D-14: URL scheme validation for `installInstructionsUrl`
- D-15: OpenClaw Gateway env-locus README line

### Tests added
**B-4 persistence (6 tests):**
`save_to_dir_create_writes_file_and_loads_back`,
`save_to_dir_same_id_edit_replaces_content`,
`save_to_dir_backup_is_cleaned_up_after_same_id_edit`,
`save_to_dir_rename_removes_old_file_and_creates_new`,
`save_to_dir_rename_nonexistent_old_id_is_non_fatal`,
`save_to_dir_roundtrip_with_env_preserves_values`

**B-3 env validation (6 tests):**
`validate_rejects_malformed_key_with_equals_sign`,
`validate_rejects_reserved_key_buzz_managed_agent`,
`validate_rejects_reserved_key_case_insensitive`,
`validate_rejects_nul_byte_in_value`,
`validate_rejects_value_over_per_value_size_limit`,
`validate_accepts_well_formed_env`

**B-2 API boundary (4 TS tests in tauri.test.mjs):**
`fromRawAcpRuntimeCatalogEntry maps definition_env to definitionEnv`,
`defaults definitionEnv to {} when absent`, `preserves source preset`,
`env round-trips through edit payload shape`

## Preset catalog

| ID | Label | Command |
|----|-------|---------|
| `cursor` | Cursor | `cursor-agent acp` |
| `omp` | Oh My Pi | `omp acp` |
| `grok` | Grok Build | `grok agent --always-approve stdio` |
| `opencode` | OpenCode | `opencode acp` |
| `kimi` | Kimi Code | `kimi acp` |
| `amp` | Amp | `amp-acp` |
| `hermes` | Hermes Agent | `hermes-acp` |
| `openclaw` | OpenClaw | `openclaw acp` |

## Review-fix pass (2026-07-26, Eva)

Fixes from the three-way review (Wren / Dawn / Eva) in the
buzz-generic-acp-harnesses thread, pushed as new commits (no rewrite):

1. **installHint edit round-trip** — form seeding extracted to
`formValuesFromCatalogEntry` (single source of truth), input rendered,
full-definition lossless round-trip regression.
2. **Dangling-delete coherence** — delete allowed; confirm counts
referencing agents (direct pin + persona-inherited); summary rows render
`harness (deleted): <id>`; spawn errors become actionable sentences
(`user_facing_harness_error`); composed delete→summary→start test.
3. **Comma-in-args** — rejected at `validate_harness_definition` (shared
by save AND disk load), mirrored inline in the form.
4. **Registry publish race** — collision/dup filtering moved into
`load_custom_harnesses` (both loaders inherit shadowing rules);
discovery publishes by re-reading the dir under `persist_mutex` (lock
scoped to publish only); deterministic interleaving regressions for
save-during-discovery and delete-during-discovery.
5. **Mechanical** — discarded `belongs_to_us` sweep arg deleted,
`load_global_agent_config` hoisted out of the per-record summary loop,
duplicated doc paragraph + stray SAFETY comment removed.
6. **PGID test de-flaked** — leader kept alive through the assertion.

Known follow-up (filed in review, not blocking): file-size split-outs
queued in `check-file-sizes.mjs` entries.

## Gate table — head `bf53f1d60`

| Gate | Result |
|------|--------|
| `cargo test --lib` (desktop/src-tauri) | **1701 passed**, 0 failed, 14
ignored |
| desktop JS suite (`pnpm test`) | **3605 passed**, 0 failed |
| `tsc --noEmit` | clean |
| `biome check` + file-size/px/pubkey checks | clean |
| `cargo clippy --lib -- -D warnings` | clean |
| `cargo fmt --check` | clean |

PR head: `bf53f1d60e3cbd07392e1287b83bb37ba90d0d33` — includes merge of
origin/main (`c2a4ee711`, conflicts in agent_models composed with
#2890's live Databricks discovery)

---------

Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
Co-authored-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
Co-authored-by: Dawn (sprout agent) <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Co-authored-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz>
2026-07-26 20:06:20 -04:00
Taksh KothariandGitHub a31fc4d2f3 fix(desktop): remove bundled libsystemd from AppImage (#2353)
## Summary
- AppImage bundles an older `libsystemd.so.0` that shadows the system
copy after `libmount` is already removed
- on systemd ≥ 251 (Arch, Fedora 41+, etc.) launch fails with
`LIBSYSTEMD_251` not found
- add `libsystemd.so*` to the existing removal list in `fix-appimage.sh`

Closes #2335

## Test plan
- [ ] rebuild / repack an AppImage with the updated script
- [ ] launch on a distro with systemd ≥ 251 without `LD_PRELOAD`
workaround


Made with [Cursor](https://cursor.com)

Signed-off-by: Taksh <takshkothari09@gmail.com>
2026-07-26 13:54:59 -04:00
8c0e8cb165 fix(desktop): make agent definition authoritative for model/provider/prompt (#1968)
## Summary

Introduces a single effective-config resolver that makes agent
definitions authoritative for model, provider, system prompt, and
relay-mesh routing on linked instances. Stale materialized record bytes
are never consulted at spawn, deploy, readiness, hash, card summary, or
mesh preflight.

**Resolution semantics (field-specific):**
- **model/provider (linked):** definition → global. `None` = inherit
global default. Record value never consulted.
- **model/provider (definition-less):** instance → global.
- **system_prompt (linked):** strictly from definition; blank = no
prompt. No global tier for prompt.
- **system_prompt (definition-less):** from the instance.
- **relay-mesh preflight (both):** driven by the same
`resolve_effective_config` resolution spawn's mesh env consults. For a
linked instance the record's own `provider`/`model`/`relay_mesh` bytes
are never consulted; for a definition-less instance with no provider of
its own, the legacy marker and env preset are the last fallback (see
below).
- **Orphaned (linked record, definition missing):** spawn, deploy, and
mesh preflight blocked with actionable user-facing error.

**Changes:**
- New `effective_config` resolver module with `ConfigSource` metadata
(`definition`, `global`, `instance_legacy`)
- All consumers routed through the single resolver: local spawn, deploy,
readiness, spawn hash, card summary, relay-mesh preflight (interactive
start and restore-on-launch)
- `apply_persona_snapshot` no longer preserves stale record
model/provider when definition is blank
- Backend `update_managed_agent` blocks model/provider/prompt writes for
linked records
- Frontend omits model/provider/systemPrompt submission for linked
instances; system prompt override hidden
- `model_source` field added to `ManagedAgentSummary` so card labels
distinguish inherited (`Default model (X)`) from explicit
- Spawn hash now digests resolved model/provider (not raw record fields)
so global default changes trip the restart badge even for runtimes
without `model_env_var`
- Orphan spawn/deploy/mesh-preflight blocked with jargon-free error
("This agent's configuration is missing — it may still be syncing or was
deleted on another device")
- `EffectiveAgentConfig::relay_mesh_model_id()` and
`resolve_effective_relay_mesh_model_id()` added; both mesh preflights
(`start_local_agent_with_preflight`, `restore_managed_agents_on_launch`)
call this instead of the deleted
`relay_mesh_config`/`relay_mesh_model_id` record-byte sniffs
- Legacy relay-mesh records keep their mesh routing. Two shipped
generations predate `provider: "relay-mesh"` and are never rewritten on
load: the typed `relay_mesh` marker (added when `ManagedAgentRecord` had
no `provider` field), and before it the mesh preset written directly
into `env_vars`. `resolve_definition_less` falls back to the marker,
then to the env preset, so these records still resolve to mesh instead
of silently misrouting to an unrelated provider while their stale env
bytes reach the child. The fallback is skipped when the record carries
an explicit `provider` — that states current intent, including a switch
away from mesh — and `resolve_linked` has no legacy fallback at all
- The env discriminator accepts both spellings of the two sentinels
renamed in the Jun-11 window without a record migration: the provider
env key (`BUZZ_AGENT_PROVIDER`, previously `SPROUT_AGENT_PROVIDER`) and
the api-key value (`buzz-mesh-local`, previously `sprout-mesh-local`).
Each is independent, since a record can straddle the window; the current
provider-key spelling wins when both are present
- Dead `persona_field_with_record_fallback` and wrapper
`persona_snapshot_with_agent_config_fallback` deleted; callers use
`persona_snapshot` directly
- New resolver/deploy/hash/write-guard/mesh-preflight tests, including
switch-away and global-inheritance regressions for both mesh preflight
call sites, per-class legacy-mesh resolution (typed marker and env
preset, in every rename-window spelling combination), and the paired
assertions that a linked instance's legacy mesh bytes stay inert

---------

Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
2026-07-26 12:30:33 -04:00
Will PflegerandGitHub 8e67cf399d chore(desktop): delete dead persona catalog UI cluster (#2886)
## Summary

- Deletes 6 orphaned files in `desktop/src/features/agents/ui/` (556
lines) that formed a closed cluster with zero imports from the reachable
module graph — orphaned by the 1B dialog consolidation
(`PersonaCatalogSurface`, `PersonaCatalogSection`,
`PersonaCatalogDetailsSheet`, `PersonaCatalogSelectionBadge`,
`PersonaIdentity`, `PersonaLibraryEntryPoints`).
- Removes a stale `check-file-sizes.mjs` override entry for the
no-longer-existent `PersonaDialog.tsx`.

Verified dead two ways: import-graph reachability walk from all entry
points puts all six outside the reachable set, and `tsc --noEmit` passes
clean after deletion. Their `data-testid`s have zero references outside
the cluster. `PersonaCatalogDialog.tsx` is alive (`AgentsView` imports
it) and stays.

Independent of #1968 — pure dead code removal, no behavioral change.
2026-07-26 12:30:13 -04:00
166c6655e8 fix(desktop): surface install failures hidden by curl-pipe exit codes (#2892)
Ubuntu Doctor reports `Install failed at verify: The installer finished,
but Buzz still could not use claude-code (observed: CLI missing)` while
the `cli` step shows success. The `cli` step is lying.

## The masking

Every CLI install command is a pipe — `curl -fsSL
https://claude.ai/install.sh | bash`
(`managed_agents/discovery.rs:109`), `… | sh` for Codex (`:141`), `… |
CONFIGURE=false bash` for Goose (`:75`). `install_shell_command` ran
them through `bash -l -c` with no `pipefail`, so the pipeline's exit
status was the **right-hand** side's. A `curl` that fails — or that
isn't on the child's PATH at all — feeds `bash` an empty stdin, and
`bash` with nothing to run exits 0:

```
$ /bin/bash -l -c 'curl -fsSL https://nonexistent.invalid/x.sh | bash'; echo $?
curl: (6) Could not resolve host: nonexistent.invalid
0
$ PATH=/tmp/empty /bin/bash -l -c 'curl -fsSL https://claude.ai/install.sh | bash'; echo $?
bash: line 1: curl: command not found
0
```

`run_install_command` records exit 0 as `success: true`, the adapter
step then installs fine (it uses Buzz's own bundled Node, no system PATH
needed), and `post_install_verification` correctly reports the CLI is
absent. The user is handed a `verify` riddle instead of curl's error,
which is why diagnosing this required three rounds of guessing.

Install commands now run under `set -o pipefail`, so the left-hand
side's failure is the step's failure and `InstallStepResult.stderr`
carries the vendor's own message. `SHELLOPTS` is not exported by either
shell, so the piped-to vendor script still runs with its default
options. The Windows PowerShell install path
(`install_powershell_command`) bypasses this shell and is untouched.

## The PATH collapse it was hiding

`install_shell_command` composes the child's PATH and calls
`cmd.env("PATH", …)`, which **replaces** rather than extends.
`should_use_inherited` was `is_windows && !had_shell_path &&
has_local_context`, so on Unix the inherited process PATH was never
appended. When `login_shell_path()` returns `None` — a login shell that
exits non-zero or prints nothing, which a GUI-launched process can
easily hit via `~/.profile` — the child's entire PATH becomes Buzz's two
managed Node dirs. There is no `curl`, `sh`, `sha256sum`, or `tar` in
either, so every curl-pipe install fails, and before this PR it failed
invisibly.

The `is_windows` requirement is dropped: the inherited PATH is the floor
whenever no login-shell PATH was obtained, on every OS. Both existing
suppressions are kept — a login-shell PATH present still suppresses it
(no doubling), and no home/exe context still suppresses it (never
manufacture a PATH from ambient state alone). Inherited entries stay
**last**, so managed dirs keep precedence.

The other caller, `build_augmented_path` (`runtime/path.rs:148`, feeding
agent spawns and CLI probes), reads correctly under the new rule for the
same reason: it only gains the inherited PATH in the case where it would
otherwise hand a child a PATH with no native entries. When a login-shell
PATH exists — the normal case on macOS and Linux — its output is
unchanged, which `unix_shell_path_suppresses_inherited_fallback` pins.

## Scope

This fixes the reporting defect and the PATH floor. The specific
environment failure on the affected Ubuntu box is still being diagnosed
and is deliberately not addressed here; the point of this change is that
the next attempt produces the real error instead of a `verify` riddle.

One interaction worth noting: `install_failure_is_retryable` retries any
failure that carries an exit code, so a pipefail-surfaced curl failure
now gets 3 attempts with backoff — correct for transient network blips,
and harmless for hard failures.

`desktop/scripts/check-file-sizes.mjs` ratchets the `agent_discovery.rs`
ceiling 1836 → 1895 for the added tests.

---------

Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
2026-07-26 12:28:30 -04:00
74b63e1846 Refactor managed-agent runtime into cohesive modules (#2974)
## Summary

- split the managed-agent runtime warehouse into cohesive modules for
process ownership/termination, orphan sweeping, dead-instance reaping,
lifecycle synchronization, and runtime metadata
- preserve the existing `runtime` API through narrow re-exports; helper
bodies and platform `cfg` branches are unchanged apart from
module-qualified visibility
- reduce `runtime.rs` from 2,220 lines on `main` to 908 lines and remove
its temporary file-size override, restoring the standard 1,000-line
ceiling

## Why

`main` failed after stale successful PR checks allowed independent
growth to combine above `runtime.rs`'s 2,216-line override. The earlier
fix in #2974 extracted only 55 lines and left the monolith on a special
ratchet. This replacement includes that extraction but establishes
responsibility boundaries and removes the exception entirely.

## Module boundaries

- `process.rs` — process identity, ownership markers, receipt
validation, and termination primitives
- `orphan_sweep.rs` — same-instance orphan discovery and cleanup
- `instance_reaper.rs` — foreign/dead desktop instance detection and
agent reaping
- `lifecycle.rs` — tracked runtime synchronization and stale record
cleanup
- `metadata.rs` — model/provider metadata resolution
- `runtime.rs` — summary/config/spawn orchestration and composition

## Validation

At `a824fda31eff6ecc0d39ca1b8ea5602a108897e6`:

- pre-push `desktop-check`
- pre-push `desktop-test`
- pre-push full `desktop-tauri-test`: 1,637 passed, 0 failed, 14
ignored; integration + doc tests passed
- `cargo check --manifest-path desktop/src-tauri/Cargo.toml --lib`
- `cargo fmt --manifest-path desktop/src-tauri/Cargo.toml --all --
--check`
- `node desktop/scripts/check-file-sizes.mjs`

Supersedes #2974 and #2930.

Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Princess Donut <68157ebd23b3897c1991015c3038658ea916200c67d3a54620b0754d1b92f6e0@buzz.block.builderlab.xyz>
2026-07-26 15:34:00 +00:00
Daniel CadenasandGitHub cc6c4d3471 fix(desktop): make Linux AppImage GStreamer work on non-Debian distros (#2176) 2026-07-25 19:49:30 -07:00
aa51dab9da fix(desktop): supervise and re-arm relay-mesh runtime (#2823)
Refs #2062

This carries forward the relay-mesh recovery work from #2304 by @Bartok9
(cherry-picked with original authorship/sign-offs) and adds the
startup/readiness supervision and packaging fixes found while validating
it against a real two-machine Buzz setup.

## From #2304

- Watch the local OpenAI ingress (`:9337`) after launch and re-arm a
stale relay-mesh runtime.
- Require consecutive failed probes before eviction so a transient
inference stall does not cause a cold restart.
- Bound stale-runtime shutdown, preserve runtime identity across the
asynchronous probe, and never evict a concurrent replacement.
- Re-arm only for agents that are actually running; deliberately stopped
agents stay stopped.
- Persist an actionable sentinel error under the managed-agent store
lock and clear only that error after recovery.
- Treat serve-to-client fallback as an intentional fail-safe; configured
serve restoration remains on its existing path.

## Added here

- Use the inference ingress (`:9337`), rather than management port
`:3131`, as Buzz's client-readiness boundary. A usable client no longer
fails or holds agent-save open merely because management startup is
still pending.
- Supervise the embedded SDK startup asynchronously, publish a pending
status while management is unavailable, and keep its mesh identity
alive.
- Avoid racing a replacement while SDK startup still owns the embedded
runtime. If that pending startup later loses ingress while a running
agent still needs it, request a controlled Buzz restart to reclaim the
otherwise-unreachable SDK thread.
- Defer roster-driven replacement while client management startup is
pending.
- Keep post-launch recovery in a dedicated module so the mesh entry
point remains within the desktop file-size gate.
- Explicitly mark generated Unix sidecars executable. On macOS, copying
over an existing non-executable destination preserved its old mode,
causing packaged `buzz-acp`, `buzz-agent`, and tool sidecars to be
reported as missing.

## Validation

Automated:

- `just ci` — passed, including formatting, Clippy with warnings denied,
desktop/web/mobile checks and tests, and builds.
- Full Tauri mesh-feature suite — 1,702 passed, 0 failed, 15 ignored.
- Mesh-feature Clippy with `-D warnings` — passed.
- Release macOS app bundle with `mesh-llm` — built successfully; every
bundled sidecar passed executable-mode and deep code-signature
verification.

Live two-machine E2E:

- M5: released Buzz serving `unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q4_K_M`.
- Mac mini: this branch's packaged Buzz running a saved
`buzz-agent`/relay-mesh agent.
- Confirmed `:9337` accepted inference and the saved ACP harness started
with no error while `:3131` was still unavailable.
- Exact inference succeeded before restart (`CORRECTED-MINI-E2E-OK`).
- Bespoke Buzz shut down cleanly in 2.3s, then restored ingress and the
saved harness in 18.8s while `:3131` was still unavailable.
- Exact inference succeeded after restart (`AFTER-RESTART-E2E-OK`).
- A real Buzz `@C55` message traversed desktop → `buzz-acp` →
`buzz-agent` → mini `:9337` → M5 compute and published the requested
reply successfully.

---------

Signed-off-by: Bartok9 <danielrpike9@gmail.com>
Signed-off-by: Michael Neale <michael.neale@gmail.com>
Co-authored-by: Bartok9 <danielrpike9@gmail.com>
Co-authored-by: Michael Neale <michael.neale@gmail.com>
2026-07-25 22:13:51 -04:00
6ab3835f3f fix(discovery): inject PATH into Codex adapter planning (#2767)
## Why
The Codex adapter install-plan test depended on the process-global
login-shell PATH cache, making it flaky under concurrent or loaded CI
runs.

## What
- Thread an explicit probe PATH through adapter install planning
- Use a controlled PATH in Codex install-plan tests
- Update the existing desktop file-size allowance for the focused seam

## Risk Assessment
Low — production behavior keeps using the same augmented PATH; only
dependency injection and deterministic tests change.

## References
- Failure:
https://github.com/block/buzz/actions/runs/30110680608/job/89539202266
- Validation: `just desktop-tauri-test`; `cd desktop && pnpm check`;
full pre-push hooks

Generated with Codex

---------

Signed-off-by: npub1x4hk035p3p9q39a3fcrd2fe30lpkrhr5dwe0cqzzjphxyyh8m0gsq4vqap <356f67c681884a0897b14e06d527317fc361dc746bb2fc0042906e6212e7dbd1@buzz.block.builderlab.xyz>
Co-authored-by: npub1x4hk035p3p9q39a3fcrd2fe30lpkrhr5dwe0cqzzjphxyyh8m0gsq4vqap <356f67c681884a0897b14e06d527317fc361dc746bb2fc0042906e6212e7dbd1@buzz.block.builderlab.xyz>
Co-authored-by: Codex <noreply@openai.com>
2026-07-25 08:07:04 -06:00
b8510ede1b fix(desktop): clarify CLI runtime setup (#2680)
## 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>
2026-07-24 20:21:25 -04:00
f3981dbfef fix(discovery): spawn PowerShell install commands natively on Windows (#2750)
## Problem

On Windows, `install_shell_command` wraps every install command in Git
Bash `-l -c`, including the Windows-specific `powershell.exe … irm
https://chatgpt.com/codex/install.ps1 | iex` command. A Git Bash login
shell prepends its POSIX dirs (`C:\Program Files\Git\usr\bin`) to PATH,
so when Codex's `install.ps1` shells out to bare `tar -xzf C:\…`, it
resolves Git's GNU tar (`/usr/bin/tar`) instead of Windows bundled
bsdtar. GNU tar parses `C:` as a remote host:

```
tar (child): Cannot connect to C: resolve failed
gzip: stdin: unexpected end of file
/usr/bin/tar: Child returned status 128
/usr/bin/tar: Error is not recoverable: exiting now
Downloaded Codex package archive did not contain the expected package layout.
```

Claude's installer doesn't hit the same failure because it doesn't shell
out to `tar`.

## Solution

On Windows, detect `powershell.exe` install commands and spawn them
natively (`Command::new("powershell.exe")`) instead of routing them
through Git Bash. The discriminator is a case-insensitive prefix check
on the first whitespace-delimited token — minimal and precise.

The native spawn preserves everything `install_shell_command` provides
that applies:
- `NPM_CONFIG_*` / `COREPACK` env strip + managed npm prefix env
- PATH composed from managed Buzz dirs + inherited process PATH (no
POSIX login-shell dirs)
- `CREATE_NO_WINDOW` so no console flash
- stdin null, piped-drain in `run_install_command`
- The retry/backoff/annotate logic is fully shared

The `-Command` body is split correctly at the boundary
(case-insensitive) and passed as a single argument to preserve pipes and
spaces inside the installer script call.

Non-PowerShell commands (e.g. `npm install -g …` adapter steps) continue
through the existing Git Bash path unchanged.

## Tests

6 unit tests:
1. `is_powershell_command` detection (positive + negative)
2. Routing: PowerShell → native spawn on Windows, non-PowerShell → Git
Bash
3. Unix: non-Windows path returns the shell command unchanged
(compile-time cfg)
4. `-Command` body preservation (no bash args in native spawn; body is
single arg)

Full `just desktop-tauri-test` suite: 1627/1627 passing. Windows CI will
validate end-to-end.

---------

Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
2026-07-24 17:19:31 -04:00
cca16635d6 fix(desktop): fix Windows PATH clobber and .cmd shim EINVAL (#2563)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
2026-07-23 18:27:20 -04:00
fd967c6ea4 feat(desktop): gate sign-out behind key backup + typed confirmation (#2424)
Signed-off-by: Wes <wesb@block.xyz>
Co-authored-by: npub1cl47vfhsqpqy9pwndphpm36vcp7vvz5h2js4qpqm5yewzj7nutkq7xyw8c <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
2026-07-22 15:38:52 -07:00
+2 61cc738ee8 feat(desktop+acp): spawn a harness per (agent, community) pair at GUI startup — warm sockets, lazy LLM pool (#2122)
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: npub12gtutshhh76rx0jx697f32f9tffd4hhp3hx58fp4x6u4uemkm7sqf8f757 <5217c5c2f7bfb4333e46d17c98a9255a52dadee18dcd43a43536b95e6776dfa0@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: Tyler <109685178+tlongwell-block@users.noreply.github.com>
Co-authored-by: npub1jh9wn95s0472h86ahapupaf7m6kx4v9sx2n0atj2hltcfer8k06s5n3pyf <95cae996907d7cab9f5dbf43c0f53edeac6ab0b032a6feae4abfd784e467b3f5@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Co-authored-by: npub12gtutshhh76rx0jx697f32f9tffd4hhp3hx58fp4x6u4uemkm7sqf8f757 <5217c5c2f7bfb4333e46d17c98a9255a52dadee18dcd43a43536b95e6776dfa0@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1t2tgm7d8f995uqvmnm8h88sg3wnpp9a5xysjf6dg3tjmgt3ltulqdp8ehr <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Dawn <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Matt Toohey <contact@matttoohey.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: npub1hwqy0rnujtl25dzmlhn8qwux4kr8sjhas3ugltx9j5dm5dwkp2dsqjhytw <bb80478e7c92feaa345bfde6703b86ad86784afd84788facc5951bba35d60a9b@buzz.block.builderlab.xyz>
2026-07-22 13:24:46 -07:00
Will PflegerandGitHub fd55ab6624 fix(desktop): keep machine onboarding for unrecognized identities after reset (#2244) 2026-07-21 15:24:35 -04:00
258cc92064 fix(desktop): survive degraded networks with rate-limit-aware relay client (#2197)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1fgdl5qqnh3k3f2xkqrvt7cujalhm623x4s7fdjdj5yrtp5fzjl9qrjpucw <4a1bfa0013bc6d14a8d600d8bf6392efefbd2a26ac3c96c9b2a106b0d12297ca@sprout-oss.stage.blox.sqprod.co>
2026-07-21 12:18:20 -04:00
8908bd6b71 Add native Builderlab auth and community client (#2099)
Signed-off-by: npub1rf6fvdj6ut0c4kcmjv4p5mmgh89nj58n69uu3fz3cvk3jn500hqs7emz79 <1a7496365ae2df8adb1b932a1a6f68b9cb3950f3d179c8a451c32d194e8f7dc1@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: Bradley Axen <baxen@squareup.com>
Co-authored-by: npub1rf6fvdj6ut0c4kcmjv4p5mmgh89nj58n69uu3fz3cvk3jn500hqs7emz79 <1a7496365ae2df8adb1b932a1a6f68b9cb3950f3d179c8a451c32d194e8f7dc1@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 22:34:41 -07:00
morgmartandGitHub 7873135a0b Polish private key onboarding texture (#2051) 2026-07-18 00:21:15 +00:00
084e442d2d Bug-bash: mention/code-span, feed titles, autocomplete, edit-mentions, draft routing, and right-click media Download (#2027)
Signed-off-by: npub1jh9wn95s0472h86ahapupaf7m6kx4v9sx2n0atj2hltcfer8k06s5n3pyf <95cae996907d7cab9f5dbf43c0f53edeac6ab0b032a6feae4abfd784e467b3f5@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: npub17jjz49l9jjmhhk7cac63j8yt9z555n9cw8vk7v5jz4vzw4ppld5qgj57cc <f4a42a97e594b77bdbd8ee35191c8b28a94a4cb871d96f32921558275421fb68@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler <109685178+tlongwell-block@users.noreply.github.com>
Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
Signed-off-by: npub1t2tgm7d8f995uqvmnm8h88sg3wnpp9a5xysjf6dg3tjmgt3ltulqdp8ehr <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1jh9wn95s0472h86ahapupaf7m6kx4v9sx2n0atj2hltcfer8k06s5n3pyf <95cae996907d7cab9f5dbf43c0f53edeac6ab0b032a6feae4abfd784e467b3f5@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub17jjz49l9jjmhhk7cac63j8yt9z555n9cw8vk7v5jz4vzw4ppld5qgj57cc <f4a42a97e594b77bdbd8ee35191c8b28a94a4cb871d96f32921558275421fb68@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Co-authored-by: Dawn (sprout agent) <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1t2tgm7d8f995uqvmnm8h88sg3wnpp9a5xysjf6dg3tjmgt3ltulqdp8ehr <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@sprout-oss.stage.blox.sqprod.co>
2026-07-17 10:27:41 -04:00
klopez4212andGitHub 2121fd0452 Polish Buzz theme and sidebar (#1971) 2026-07-17 11:40:05 +00:00
Will PflegerandGitHub db57bc8a2c chore(desktop): add AppShell.tsx file-size override to unblock main CI (#1992)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
2026-07-16 17:12:06 -04:00
19dc33bda6 Persist agent audiences with native inline mentions (#1949)
Signed-off-by: npub1n4y9luxx9y27pz5qz93vr9w8auyk7mmpgwf9gpe9tn4zv4kyhzjqtcntu7 <9d485ff0c62915e08a801162c195c7ef096f6f6143925407255cea2656c4b8a4@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: npub1d6t84ajeg9skp2609l2k6axgcme8x7g7u7luj352r03hcwreg7lqnxcsex <6e967af659416160ab4f2fd56d74c8c6f273791ee7bfc9468a1be37c387947be@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1n4y9luxx9y27pz5qz93vr9w8auyk7mmpgwf9gpe9tn4zv4kyhzjqtcntu7 <9d485ff0c62915e08a801162c195c7ef096f6f6143925407255cea2656c4b8a4@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1d6t84ajeg9skp2609l2k6axgcme8x7g7u7luj352r03hcwreg7lqnxcsex <6e967af659416160ab4f2fd56d74c8c6f273791ee7bfc9468a1be37c387947be@sprout-oss.stage.blox.sqprod.co>
2026-07-16 10:25:44 -07:00
0722346b1f Add Buzz-managed Node runtime for agent installs (#1930)
Signed-off-by: npub1t2tgm7d8f995uqvmnm8h88sg3wnpp9a5xysjf6dg3tjmgt3ltulqdp8ehr <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1t2tgm7d8f995uqvmnm8h88sg3wnpp9a5xysjf6dg3tjmgt3ltulqdp8ehr <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@sprout-oss.stage.blox.sqprod.co>
2026-07-15 23:11:44 -04:00
Michael NealeandGitHub 32957692eb fix(desktop): load downloaded mesh runtime on signed macOS builds (#1932) 2026-07-15 21:28:17 -04:00
3e8dae7ff3 fix(desktop): simplify sign out settings row (#1903)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
2026-07-15 15:26:01 +00:00
Will PflegerandGitHub 1742dce7b2 feat(desktop): add API key field, global default indicators, and collapsed advanced (#1875) 2026-07-14 20:10:39 -04:00
448baeef77 feat(teams): unify team model, snapshot sharing, and PNG memory parity (#1846)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-07-14 17:10:51 -04:00
cf97237965 feat(desktop): add Sign Out to Settings to reset and relaunch (#1842)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-07-14 16:52:57 -04:00
Will PflegerandGitHub 1aec7ea7a7 fix(desktop): resolve Doctor install shell and command detection on Windows (#1854)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
2026-07-14 13:05:25 -04:00
a653406309 ci(desktop): surface flaky E2E tests instead of retry-masking them (#1838)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-07-13 22:14:40 -04:00
020ac7f405 fix(desktop): resolve Git Bash for Windows shell tool via PATH/git/registry fallback (#1821)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-07-13 16:53:02 -04:00
51ee1c473d feat(desktop): show read-only MCP server config (#1780)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-07-13 16:29:21 -04:00
095f3c7280 fix(desktop): centralize known-agent trust set in useKnownAgentPubkeys (#1703)
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: npub12gtutshhh76rx0jx697f32f9tffd4hhp3hx58fp4x6u4uemkm7sqf8f757 <5217c5c2f7bfb4333e46d17c98a9255a52dadee18dcd43a43536b95e6776dfa0@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: npub12gtutshhh76rx0jx697f32f9tffd4hhp3hx58fp4x6u4uemkm7sqf8f757 <5217c5c2f7bfb4333e46d17c98a9255a52dadee18dcd43a43536b95e6776dfa0@sprout-oss.stage.blox.sqprod.co>
2026-07-13 11:01:46 -04:00
11a286b9a4 feat(desktop): auto-restart setup-mode agents after adapter install, badge drift fallback (#1786)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-07-12 22:27:51 -04:00
1fa91f5691 refactor(desktop): remove legacy persona-card flows (#1781)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-07-12 21:05:03 -04:00
1580046b3c feat(desktop): add buzz-agent-snapshot v1 export, import, sender-native send, and recipient card/import (#1753)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-07-12 19:30:21 -04:00
Will PflegerandGitHub d2e87e1ca7 feat(desktop): add key backup and agent defaults to onboarding, make avatar optional (#1767) 2026-07-12 18:46:02 -04:00
Will PflegerandGitHub f3319dd111 fix(desktop): correct provider and model handling in agent config dialogs (#1764) 2026-07-12 18:23:27 -04:00
Will PflegerandGitHub 7c346d7f85 fix(desktop): cascade persona deletes and restart agents on global config save (#1766) 2026-07-12 18:03:36 -04:00
Will PflegerandGitHub 25bb714752 fix(desktop): make doctor installs retryable with per-runtime progress and auth status (#1765) 2026-07-12 17:42:35 -04:00