Commit Graph

2468 Commits

Author SHA1 Message Date
Taylor Ho
2e697be1b2 fix(desktop): show full pop-out prompts
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-24 05:01:16 -07:00
Taylor Ho
32227296bd fix(desktop): preserve pop-out code blocks
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-24 04:24:12 -07:00
Taylor Ho
dac834c905 fix(desktop): make pop-out timestamps inert
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-24 03:55:08 -07:00
Taylor Ho
675bed8545 fix(desktop): keep activity pop-outs display-only
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-24 03:14:51 -07:00
Taylor Ho
1502d6215e fix(desktop): keep activity companions pinned
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-24 02:23:08 -07:00
Taylor Ho
d9392d2573 fix(desktop): pin activity window navigation
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-24 01:43:46 -07:00
Taylor Ho
3739bd0136 fix(desktop): keep popped activity controls scoped
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-24 01:43:45 -07:00
Taylor Ho
bd4980a8da fix(desktop): keep popped activity channel-scoped
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-24 01:43:44 -07:00
Taylor Ho
dde8a9ea74 fix(desktop): preserve activity window navigation context
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-24 01:43:43 -07:00
Taylor Ho
9d3c54a78f fix(desktop): preserve huddle community bootstrap
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-23 22:07:16 -07:00
Taylor Ho
5f7f5031d1 fix(desktop): make activity windows passive
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-23 21:27:20 -07:00
Taylor Ho
f156835e83 fix(desktop): keep companion effects passive
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-23 21:27:19 -07:00
Taylor Ho
aa781c6d12 fix(desktop): show unavailable activity state
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-23 21:27:18 -07:00
Taylor Ho
bd49723afc fix(desktop): preserve read state in activity windows
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-23 21:27:17 -07:00
Taylor Ho
ad9da72423 fix(desktop): scope activity windows to communities
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-23 21:27:16 -07:00
Taylor Ho
4a50a5e088 fix(desktop): reserve deep links for main window
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-23 21:27:15 -07:00
Taylor Ho
fc4aec4f56 fix(desktop): keep archive sync in main window
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-23 21:27:13 -07:00
Taylor Ho
22caeb7405 refactor(desktop): extract agent activity opening actions
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-23 21:27:12 -07:00
Taylor Ho
42002efaa9 refactor(desktop): centralize companion window ownership
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-23 21:27:10 -07:00
Taylor Ho
47907293ba Keep default activity ingress in app
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-23 21:27:08 -07:00
Taylor Ho
fe121d7713 Rename agent activity pop-out action
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-23 21:27:07 -07:00
Taylor Ho
2ab62fd4e8 Make external agent activity window optional
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-23 21:27:06 -07:00
Taylor Ho
96bb026c64 Polish agent activity companion window
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-23 21:27:04 -07:00
Taylor Ho
32405545e5 Grant activity windows Tauri capabilities
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-23 21:27:04 -07:00
Taylor Ho
e315b0d02b Open agent activity in companion window
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-23 21:27:03 -07:00
klopez4212
0720f5380c Downgrade desktop Huddles to audio protocol v2 (#6610)
## Summary
- negotiate Huddle audio protocol v2 on desktop
- decode the released one-byte peer-index prefix
- retain roster-driven playout resets and document the missing v3 epoch
fence

## Testing
- `just desktop-tauri-fmt-check`
- `just desktop-tauri-clippy`
- `just desktop-tauri-test`

Signed-off-by: kenny lopez <klopez4212@gmail.com>
2026-08-23 16:24:51 +01:00
klopez4212
e236329413 Polish Huddle participant interactions (#6312)
## Summary
- arrange Huddle participants in a responsive, equal-weight cluster with
spring enter/exit motion and a `+N` overflow
- spotlight tapped participants over a blurred call surface, with a
roster for hidden participants and no self-avatar action
- add selection haptics across full-screen and drawer controls,
including both end-call buttons
<img width="1080" height="2424" alt="Screenshot_20260819-151448"
src="https://github.com/user-attachments/assets/00b7fdca-2304-4788-9952-e07224798513"
/>
<img width="1080" height="2424" alt="Screenshot_20260819-151422"
src="https://github.com/user-attachments/assets/a0cfc861-0519-44ff-bb56-4c983ed6344c"
/>

## Validation
- `just mobile-check`
- focused participant, drawer-control, and full-screen end-call widget
tests
- Huddle-focused widget suite (15 tests)
- full mobile Flutter suite (1,538 tests)

## Dependency
Built on #6056 and contains only the follow-up interaction work. Merge
after #6056 lands.

---------

Signed-off-by: kenny lopez <klopez4212@gmail.com>
Signed-off-by: Kenny Lopez <klopez4212@gmail.com>
Signed-off-by: Princess Donut <b238ea756dee4d98afa5883fc7f1de61eeabe65bf700e3a5a5a80db5e42e2c2b@buzz.block.builderlab.xyz>
Signed-off-by: Tom Brow <tomb@block.xyz>
Co-authored-by: Carl <3c4caeafb646d23867f1c4832e68211d77e2561946171625f75c3ce1a3f2670f@buzz.block.builderlab.xyz>
Co-authored-by: Princess Donut <b238ea756dee4d98afa5883fc7f1de61eeabe65bf700e3a5a5a80db5e42e2c2b@buzz.block.builderlab.xyz>
Co-authored-by: leader <71e9f2c44a6932b6772caaaccda1911d010463c3e2c6c40410b8329956046801@buzz.block.builderlab.xyz>
Co-authored-by: Tom Brow <tomb@block.xyz>
Co-authored-by: Mongo <9cfd347903944d5b85aa6c93d2ab67381b978a92a31914bca69998968752a1d7@buzz.block.builderlab.xyz>
2026-08-22 16:06:36 -07:00
klopez4212
4baccd5394 Downgrade mobile Huddles to audio protocol v2 (#6558)
## Summary

- downgrade Mobile Huddle authentication and native media configuration
from protocol v3 to the currently deployed relay's v2 contract
- restore the released one-byte relay peer prefix while retaining later
reconnect, roster, and playout-reset reliability fixes
- update Android, iOS, protocol documentation, and focused tests
together

Protocol v2 does not carry v3's occupancy epoch on audio frames, so it
cannot fence the narrow delayed-packet/peer-index-reuse race. This is an
intentional compatibility tradeoff until the relay v3 rollout is ready.

### Related issue

None found.

### Testing

- `just mobile-check`
- `just mobile-test` — 1,661 tests passed
- Android debug build installed and launched on Pixel 10 as
`xyz.block.buzz.mobile.sprout_mobile_profile_settings`; foreground
process verified
- signed iOS Release build installed and launched on iPhone as
`com.buzz.buzzMobile`; running process verified

A live two-device Huddle audio call remains a manual verification step.

Signed-off-by: kenny lopez <klopez4212@gmail.com>
mobile-v0.14.0-rc.2
2026-08-22 18:37:08 +01:00
Max Lampert
040b203f73 perf(desktop): make the Projects surface render-cheap (#6460)
Diagnostic profiling on a large community (101 issues, 258 PRs) showed
Projects tab switches taking 2.5–3.6s, dominated by single React commits
of 0.5–1.5s and per-render recomputation — fetch work was already off
the main thread; the cost was building the UI.

### Measured: tab click → painted, per tab

| tab | before | after |
|---|---|---:|
| projects | 3,608ms | 320–580ms |
| repositories | 3,126–3,534ms | 310–410ms |
| tasks | 395–1,101ms | ~115ms |
| reviews | 322–2,603ms | ~96ms |
| activity | 597–741ms | ~148ms |

Single-commit ceiling dropped from 1,541ms to ≤200ms (growth steps
25–40ms). Fixes in profiled-cost order:

- **Profile popover body mounts only while open.** `UserProfilePopover`
carried seven query subscriptions plus interaction hooks per instance
even when closed; grids mount hundreds (five per card in people stacks,
one per row author) — measured **~40ms per card**, the dominant share of
the 1.2s card-tab commits. The always-mounted shell is now just the
Radix root + trigger; trigger markup, hover timing, and keyboard
handling are unchanged, and hover/tooltip event continuity is preserved
because the trigger never remounts.
- **Incremental row mounting.** The first 12 cards / 30 rows render in
the first commit; the rest stream in 36–60-per-frame low-priority
transitions. Grouped lists trim across group boundaries via a pure,
tested slicer; the mounted count survives in-place refetches.
- **Activity feed**: was rebuilt unmemoized on every render,
markdown-flattening every issue/PR/comment body in the community just to
sort and keep 30 items (~360+ flattens per render on the measured
community). Now memoized, and bodies stay raw until after the sort+slice
— 30 flattens, once per data change.
- **Contribution graph** (always-visible rail, so every tab paid for
it): ~180 day cells each wrapped in a Radix tooltip with per-cell Intl
date formatting per render. Now memoized, cells precomputed once per
data change, native `title` tooltips. (The activity-bar segments keep
their styled Radix tooltips — pinned by an existing spec.)
- **Rows/cards memoized with identity-stable props**: per-row selection
arrays were rebuilt per row per render (O(n²) — 258 PRs × 258-item
arrays each render) and are now hoisted and shared; people arrays derive
inside the memoized cards; the rail's stat walk over every issue/PR is
memoized.
- **`content-visibility: auto`** on cards and rows so offscreen entries
skip layout and paint; **tab switches run in a React transition** so the
click stays responsive while the new tree mounts.

Remaining known cost (out of scope): cold-entry data readiness — the
work-item and activity queries ship thousands of events to compute
counts (2–4s on a large community; see the fan-lifecycle PR). The
structural fix is a relay-side aggregate; tracked as follow-up.

---------

Signed-off-by: Max Lampert <maxwell@squareup.com>
2026-08-22 08:42:55 -06:00
Salman Mohammed
f99532585a refactor(acp): clarify agent prompt sections (#6501)
## Why
The ACP prompt puts a machine-specific Workspace prefix before static
base guidance and labels the user-facing agent instruction layer as the
generic System section. Because the cwd varies by launch and worktree,
leading with it reduces reusable prompt-prefix stability.

`[Workspace]` was added in [PR
#1194](https://github.com/block/buzz/pull/1194) as a defensive fix after
a broken `~/.sprout` → `~/.buzz` migration caused agents to scan `$HOME`
and trigger macOS TCC prompts. This change retains that grounding while
shrinking it to the current working directory and moving dynamic
environment context after the static Base prompt.

## What
- Emit the prompt in Base → Workspace → Agent Instructions order
- Reduce Workspace to `Current working directory: <absolute path>`
- Resolve cwd as an absolute native-platform path and preserve Windows
drive/UNC paths instead of checking for a leading `/`
- Emit Agent Instructions for persona and standalone agent instructions
across modern and legacy ACP paths
- Preserve parsing for archived observer frames that used System or the
former Workspace-before-Base order, and align the persona catalog label

## Risk Assessment
Medium-low — this changes prompt framing for every newly created agent
session. Existing archived observer frames remain parseable, and
execution still uses the same ACP working directory. Cwd resolution now
fails clearly instead of substituting `/` when the process directory
cannot be resolved.

## References
- https://github.com/block/buzz/pull/1103
- https://github.com/block/buzz/pull/1194

Generated with Codex

---------

Signed-off-by: Salman Mohammed <smohammed@squareup.com>
2026-08-22 08:29:41 -06:00
klopez4212
8c0f42e187 Add mobile Huddles voice MVP (#6056)
## Summary
- add foreground mobile Huddles on Android and iOS with native Opus
capture/playback, mute, speaker routing, participants, lifecycle, and
minimized drawer UI
- keep mobile Huddle cards and roster state live, including ended rooms,
relay-resolved profiles, and agents
- broadcast desktop agent TTS through the existing Huddle audio protocol

## Scope
Foreground human-to-human voice MVP only. Agent setup/transcripts,
background calling, recording, and advanced device controls remain out
of scope.

## Validation
- `just mobile-check`
- `just mobile-test` — 1,500 passed
- `just desktop-check` and `just desktop-test` — 4,957 passed
- desktop typecheck, strict Clippy, and Tauri tests — 2,445 passed, 15
ignored
- mobile worktree identity contract checks
- physical Pixel/iPhone behavior reviewed during development

---------

Signed-off-by: kenny lopez <klopez4212@gmail.com>
Signed-off-by: Kenny Lopez <klopez4212@gmail.com>
Signed-off-by: Princess Donut <b238ea756dee4d98afa5883fc7f1de61eeabe65bf700e3a5a5a80db5e42e2c2b@buzz.block.builderlab.xyz>
Signed-off-by: Tom Brow <tomb@block.xyz>
Co-authored-by: Carl <3c4caeafb646d23867f1c4832e68211d77e2561946171625f75c3ce1a3f2670f@buzz.block.builderlab.xyz>
Co-authored-by: Princess Donut <b238ea756dee4d98afa5883fc7f1de61eeabe65bf700e3a5a5a80db5e42e2c2b@buzz.block.builderlab.xyz>
Co-authored-by: leader <71e9f2c44a6932b6772caaaccda1911d010463c3e2c6c40410b8329956046801@buzz.block.builderlab.xyz>
Co-authored-by: Tom Brow <tomb@block.xyz>
Co-authored-by: Mongo <9cfd347903944d5b85aa6c93d2ab67381b978a92a31914bca69998968752a1d7@buzz.block.builderlab.xyz>
mobile-v0.14.0-rc.1
2026-08-22 05:28:16 -07:00
Taylor Ho
a2d8be5efa feat(desktop-messages): keep agents addressed across messages (#6315)
**Category:** new-feature
**User Impact:** Users can keep selected agents addressed across
consecutive messages without retyping their handles.

**Problem:** Repeated conversations with agents require manually typing
the same mentions on every turn, which adds friction and makes
recipients easy to omit.

**Solution:** The composer can now keep agents automatically addressed
per channel, either from the mention controls or after a successful
inline mention. Addressed agents remain visible in the toolbar, apply to
channel threads, survive send failures safely, and never cross community
boundaries.

## Changes

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

**desktop/src-tauri/src/events/message_tags.rs**  
Preserves the automatic-address marker on validated mention reference
tags.

**desktop/src/features/channels/ui/ChannelPane.tsx**  
Wires the appropriate channel, thread, inbox, or forum composer context
without leaking audiences across surfaces.

**desktop/src/features/communities/useCommunityInit.ts**  
Clears composer audience state when the active community changes.

**desktop/src/features/forum/ui/ForumComposer.tsx**  
Wires the appropriate channel, thread, inbox, or forum composer context
without leaking audiences across surfaces.

**desktop/src/features/forum/ui/ForumComposerAutocompletes.tsx**  
Wires the appropriate channel, thread, inbox, or forum composer context
without leaking audiences across surfaces.

**desktop/src/features/home/ui/InboxDetailPane.tsx**  
Wires the appropriate channel, thread, inbox, or forum composer context
without leaking audiences across surfaces.

**desktop/src/features/messages/lib/agentAddressMention.d.mts**  
Defines helpers and types for marked automatic-address mention tags.

**desktop/src/features/messages/lib/agentAddressMention.mjs**  
Defines helpers and types for marked automatic-address mention tags.

**desktop/src/features/messages/lib/agentAddressMention.test.mjs**  
Covers the automatic-address behavior and its failure, keyboard, layout,
or persistence boundaries.

**desktop/src/features/messages/lib/applyEditTagOverlay.mjs**  
Preserves automatic-address metadata when edited message tags are
overlaid.

**desktop/src/features/messages/lib/applyEditTagOverlay.test.mjs**  
Covers the automatic-address behavior and its failure, keyboard, layout,
or persistence boundaries.


**desktop/src/features/messages/lib/autoPinMentionedAgentsPreference.test.mjs**
Covers the automatic-address behavior and its failure, keyboard, layout,
or persistence boundaries.


**desktop/src/features/messages/lib/autoPinMentionedAgentsPreference.ts**
Stores the preference that keeps explicitly mentioned agents addressed
for later messages.

**desktop/src/features/messages/lib/extractMentionPersonas.ts**  
Separates persona recipients from the composer mention orchestration.

**desktop/src/features/messages/lib/persistentAgentAudience.test.mjs**  
Covers the automatic-address behavior and its failure, keyboard, layout,
or persistence boundaries.

**desktop/src/features/messages/lib/persistentAgentAudience.ts**  
Maintains bounded, in-memory, channel-scoped automatic agent audiences.

**desktop/src/features/messages/lib/useMentionSelection.ts**  
Centralizes mention picker selection state and agent-first selection
behavior.

**desktop/src/features/messages/lib/useMentions.ts**  
Exposes explicit picker origins and selection controls while preserving
inline mention behavior.

**desktop/src/features/messages/ui/ComposerAddressControls.test.mjs**  
Covers the automatic-address behavior and its failure, keyboard, layout,
or persistence boundaries.

**desktop/src/features/messages/ui/ComposerAddressControls.tsx**  
Renders compact addressed-agent avatars and the automatic-mention
management entry point.

**desktop/src/features/messages/ui/MentionAutocomplete.test.mjs**  
Covers the automatic-address behavior and its failure, keyboard, layout,
or persistence boundaries.

**desktop/src/features/messages/ui/MentionAutocomplete.tsx**  
Adds automatic-mention controls and options to the existing mention
picker.

**desktop/src/features/messages/ui/MessageAgentAddressPrefix.tsx**  
Shows which agents were automatically addressed on a sent message.

**desktop/src/features/messages/ui/MessageComposer.tsx**  
Integrates automatic audiences, picker controls, accessible feedback,
shortcuts, and send behavior.

**desktop/src/features/messages/ui/MessageComposer.types.ts**  
Defines the simplified channel audience context shared by composer
hosts.

**desktop/src/features/messages/ui/MessageComposerToolbar.tsx**  
Places automatic-address controls in the composer toolbar without
crowding narrow layouts.

**desktop/src/features/messages/ui/MessageRow.tsx**  
Displays automatic-address metadata alongside sent message content.

**desktop/src/features/messages/ui/MessageThreadPanel.tsx**  
Wires the appropriate channel, thread, inbox, or forum composer context
without leaking audiences across surfaces.

**desktop/src/features/messages/ui/composerAgentKeyboard.test.mjs**  
Covers the automatic-address behavior and its failure, keyboard, layout,
or persistence boundaries.


**desktop/src/features/messages/ui/persistentAgentAudienceHosts.test.mjs**
Covers the automatic-address behavior and its failure, keyboard, layout,
or persistence boundaries.

**desktop/src/features/messages/ui/useAddressMentionPulse.test.mjs**  
Covers the automatic-address behavior and its failure, keyboard, layout,
or persistence boundaries.

**desktop/src/features/messages/ui/useAddressMentionPulse.ts**  
Provides success and failure animation signals for addressed-agent
controls.

**desktop/src/features/messages/ui/useAgentAddressLockPicker.test.mjs**
Covers the automatic-address behavior and its failure, keyboard, layout,
or persistence boundaries.

**desktop/src/features/messages/ui/useAgentAddressLockPicker.ts**  
Coordinates adding, removing, and announcing automatically addressed
agents.

**desktop/src/features/messages/ui/useAlwaysAddressShortcut.ts**  
Implements the platform-aware shortcut for toggling automatic
addressing.

**desktop/src/features/messages/ui/useAutoPinMentionedAgents.ts**  
Promotes successfully sent inline agent mentions and provides a single
undoable notification.

**desktop/src/features/messages/ui/useComposerMentionPicker.ts**  
Opens the mention picker without rewriting the current draft.


**desktop/src/features/messages/ui/useMentionSendFlow.helpers.test.mjs**
Covers the automatic-address behavior and its failure, keyboard, layout,
or persistence boundaries.

**desktop/src/features/messages/ui/useMentionSendFlow.helpers.ts**  
Merges automatic and inline recipients, marks outgoing tags, and
restores failed sends safely.

**desktop/src/features/messages/ui/useMentionSendFlow.ts**  
Merges automatic and inline recipients, marks outgoing tags, and
restores failed sends safely.


**desktop/src/features/messages/ui/usePersistentAgentMentionHydration.ts**
Removes the prior draft-text hydration approach now that automatic
audiences stay at composer ingress.

**desktop/src/features/settings/ui/AgentsSettingsPanel.tsx**  
Replaces the old global behavior with explicit composer-level
automatic-mention controls.

**desktop/src/features/settings/ui/PreventSleepSettingsCard.tsx**  
Replaces the old global behavior with explicit composer-level
automatic-mention controls.

**desktop/src/shared/lib/keyboard-shortcuts.ts**  
Defines the user-facing automatic-address keyboard shortcut label.

**desktop/src/shared/ui/VideoReviewCommentMarkdown.tsx**  
Allows automatic-address prefixes to compose with video review
timecodes.

**desktop/tests/e2e/persistent-agent-audience.spec.ts**  
Covers the automatic-address behavior and its failure, keyboard, layout,
or persistence boundaries.

</details>

## Reproduction Steps

1. Open a channel with one or more agents and open the mention picker
from the composer.
2. Select an agent for automatic mentions, then send several messages
without retyping the handle; confirm the agent remains in the composer
control and receives each message.
3. Mention another agent inline, send successfully, and confirm the
agent becomes automatically addressed; use the notification's Undo
action to reverse it.
4. Open a thread in the same channel and confirm the same addressed
agents are available there.
5. Remove an agent from the composer control and confirm later messages
stop addressing it.
6. Switch communities and confirm addressed agents do not carry into the
other community.

## Screenshots

All states below use the dark Buzz theme with a selected lilac accent.

### Addressed composer

Selected agents stay visible at the composer ingress without adding
handles to the draft.

![Two automatically addressed agents in the dark composer with a lilac
accent](https://raw.githubusercontent.com/block/buzz/74c2cbbd80ed630a0c6e00c420505a691bd4994a/pr-6315--01-addressed-composer.png)

### Open mention menu

The @ ingress opens the existing mention menu and shows which agents are
already addressed.

![Open mention menu with automatically addressed agents
highlighted](https://raw.githubusercontent.com/block/buzz/74c2cbbd80ed630a0c6e00c420505a691bd4994a/pr-6315--02-open-mention-menu.png)

### Mention options

The inline options pane controls whether a successful one-time agent
mention carries into later messages.

![Automatic mention options expanded above the mention
menu](https://raw.githubusercontent.com/block/buzz/74c2cbbd80ed630a0c6e00c420505a691bd4994a/pr-6315--03-mention-options.png)

### Agent settings

The same preference is available in **Settings → Agents →
Conversations**.

![Automatic agent mentions preference in the Agents settings
pane](https://raw.githubusercontent.com/block/buzz/74c2cbbd80ed630a0c6e00c420505a691bd4994a/pr-6315--04-agent-settings.png)

---------

Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
2026-08-21 22:04:53 -07:00
Taylor Ho
723affe5d1 fix(desktop): remove Buzz entity link previews (#6512)
**Category:** improvement
**User Impact:** Buzz-native project, repository, issue, and pull
request links now appear once as compact inline chips, with their
details available on hover.

**Problem:** Buzz-native entity links rendered both an inline chip and a
standalone preview card, repeating the same metadata and adding visual
noise to conversations. **Solution:** Exclude Buzz-native links from the
shared standalone-preview extractor while leaving entity parsing intact
for chip tooltips and preserving external web previews and attachment
cards.

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

**desktop/src/shared/lib/linkPreview.ts**
Stops Buzz-native preview candidates after parsing, including same-relay
git clone URLs that normalize to repository entities, while allowing
external URLs through the existing snapshot path.

**desktop/src/shared/lib/linkPreview.test.mjs**
Covers project, repository, issue, pull request, markdown-labeled,
same-relay clone, and mixed external-link extraction behavior.

**desktop/src/shared/ui/markdown/useMessageLinkPreviews.test.mjs**
Confirms sent messages no longer merge a standalone Buzz entity card
while external sender snapshots still render.

</details>

## Reproduction steps

1. Open a desktop channel containing a `buzz://project`, `buzz://repo`,
`buzz://issue`, or `buzz://pr` link.
2. Confirm the link renders as an inline entity chip without a second
standalone Buzz card below the message.
3. Hover the chip and confirm its entity metadata remains available.
4. Post an external HTTPS link and confirm its web preview still
renders.
5. Paste a same-relay `/git/<owner>/<repo>` clone URL and confirm it
uses the repository chip without a duplicate card.

## Screenshots

| Before | After |
| --- | --- |
| Inline chip plus redundant standalone Project card | Inline chip is
now the sole presentation |
| ![Before: project chip and duplicate standalone
card](https://raw.githubusercontent.com/block/buzz/7e1a0d6cfb52382ef636d7331cf30ea334429c4d/pr-6512--before.png)
| ![After: project chip without a standalone
card](https://raw.githubusercontent.com/block/buzz/7e1a0d6cfb52382ef636d7331cf30ea334429c4d/pr-6512--after.png)
|

**After — rich metadata stays available on hover**

![After: dark theme with pink accent and Project tooltip showing
description and repository
count](https://raw.githubusercontent.com/block/buzz/7e1a0d6cfb52382ef636d7331cf30ea334429c4d/pr-6512--after-tooltip-rich.png)

## Verification

At commit `3fa74cdd342ac1f6721b7d56a7f111af31e0e6e9`:

- focused link-preview + Markdown unit suites — 119/119 passed
- targeted registered smoke E2E — 8/8 passed, including labeled
same-relay clone metadata, ordinary-link presentation, and in-app
navigation
- `cd desktop && pnpm exec tsc --noEmit` — passed
- `git diff --check origin/main...HEAD` — passed
- pre-push hooks — desktop check, TypeScript, and full desktop unit
suite passed

---------

Signed-off-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Co-authored-by: Mongo <5398c5fd039b963ce132b3e078e7c4af097dd997517bb5e14c2682fe68c25197@buzz.block.builderlab.xyz>
2026-08-21 22:04:17 -07:00
Taylor Ho
074561233e fix(composer): preserve caret when inserting mentions mid-message (#6531)
**Category:** fix
**User Impact:** Users can insert mentions earlier in a draft and
continue typing without the caret corrupting the rest of the message.

**Problem:** Caret correction ran after every document change, so typing
a mention before existing text repeatedly advanced across the mention
separator and interleaved spaces into the draft. **Solution:** Limit
correction to the autocomplete settlement it was designed for, with
transaction-level and browser-level regression coverage for known and
unregistered mentions.

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

**desktop/src/features/messages/lib/mentionHighlightExtension.ts**
Restricts trailing-space caret advancement to an armed autocomplete
settlement instead of every document change.

**desktop/src/features/messages/lib/mentionHighlightExtension.test.mjs**
Exercises the real ProseMirror plugin state and verifies mid-draft
mention typing, unknown tokens, end-of-message typing, and
completed-mention separators.

**desktop/tests/e2e/mentions.spec.ts**
Reproduces the reported composer workflow in Chromium and covers the
same corruption path for an unregistered `@token`.

</details>

## Reproduction steps

1. Open a channel and enter `hello world` in the composer.
2. Move the caret between `hello` and ` world`.
3. Type ` @bo`, select `bob` from autocomplete, and continue typing
`abc`.
4. Confirm the composer reads `hello @bob abc world` with the caret
after `abc`.
5. Repeat with an unregistered token such as ` @zzq` and confirm the
existing text remains intact.

## Before / After

| Before | After |
| --- | --- |
| Typing after a mid-draft mention walks the caret through the existing
message. | Continued typing stays after the inserted mention. |
| ![Before: mention caret corrupts existing draft
text](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/6531/mention-caret-before.gif)
| ![After: caret remains after the inserted
mention](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/6531/mention-caret-after.gif)
|

---------

Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Mongo <5398c5fd039b963ce132b3e078e7c4af097dd997517bb5e14c2682fe68c25197@buzz.block.builderlab.xyz>
2026-08-21 18:48:21 -06:00
renovate[bot]
f794216737 chore(deps): update rust crate async-trait to v0.1.92 (#6094)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [async-trait](https://redirect.github.com/dtolnay/async-trait) |
dependencies | patch | `0.1.91` → `0.1.92` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/1) for more information.

---

### Release Notes

<details>
<summary>dtolnay/async-trait (async-trait)</summary>

###
[`v0.1.92`](https://redirect.github.com/dtolnay/async-trait/releases/tag/0.1.92)

[Compare
Source](https://redirect.github.com/dtolnay/async-trait/compare/0.1.91...0.1.92)

- Resolve double\_must\_use clippy lint in generated code
([#&#8203;303](https://redirect.github.com/dtolnay/async-trait/issues/303))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Between 12:00 AM and 03:59 AM, only on Monday (`* 0-3 * * 1`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/block/buzz).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4yOS41IiwidXBkYXRlZEluVmVyIjoiNDQuMzkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-21 18:29:04 -06:00
renovate[bot]
2d93ea0955 chore(deps): update dependency sonner to v2.0.8 (#6093)
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [sonner](https://sonner.emilkowal.ski/)
([source](https://redirect.github.com/emilkowalski/sonner)) | [`2.0.7` →
`2.0.8`](https://renovatebot.com/diffs/npm/sonner/2.0.7/2.0.8) |
![age](https://developer.mend.io/api/mc/badges/age/npm/sonner/2.0.8?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/sonner/2.0.7/2.0.8?slim=true)
|

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/1) for more information.

---

### Release Notes

<details>
<summary>emilkowalski/sonner (sonner)</summary>

###
[`v2.0.8`](https://redirect.github.com/emilkowalski/sonner/compare/v2.0.7...ecce1841c55e4a72dfe139a8992b56498660125e)

[Compare
Source](https://redirect.github.com/emilkowalski/sonner/compare/v2.0.7...v2.0.8)

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Between 12:00 AM and 03:59 AM, only on Monday (`* 0-3 * * 1`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/block/buzz).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4yOS41IiwidXBkYXRlZEluVmVyIjoiNDQuMzkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-21 18:28:51 -06:00
renovate[bot]
9390e11c9b chore(deps): update rust crate http-body-util to v0.1.4 (#5452)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [http-body-util](https://redirect.github.com/hyperium/http-body) |
dependencies | patch | `0.1.3` → `0.1.5` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/1) for more information.

---

### Release Notes

<details>
<summary>hyperium/http-body (http-body-util)</summary>

###
[`v0.1.5`](https://redirect.github.com/hyperium/http-body/compare/http-body-util-v0.1.4...http-body-util-v0.1.5)

[Compare
Source](https://redirect.github.com/hyperium/http-body/compare/http-body-util-v0.1.4...http-body-util-v0.1.5)

###
[`v0.1.4`](https://redirect.github.com/hyperium/http-body/releases/tag/http-body-util-v0.1.4)

[Compare
Source](https://redirect.github.com/hyperium/http-body/compare/http-body-util-v0.1.3...http-body-util-v0.1.4)

#### What's Changed

- Add `Fused` body combinator that always returns `None` once completed.
- Add `BodyExt::into_stream()` to convert a body into a `Stream`.
- Add `Full::into_inner()` to get the full `Buf`.
- Add `InspectFrame` and `InspectErr` combinators.

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Between 12:00 AM and 03:59 AM, only on Monday (`* 0-3 * * 1`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/block/buzz).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMzkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-21 18:28:38 -06:00
renovate[bot]
1a0a27d358 chore(deps): update rust crate http to v1.4.2 (#5451)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [http](https://redirect.github.com/hyperium/http) | dependencies |
patch | `1.4.0` → `1.4.2` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/1) for more information.

---

### Release Notes

<details>
<summary>hyperium/http (http)</summary>

###
[`v1.4.2`](https://redirect.github.com/hyperium/http/blob/HEAD/CHANGELOG.md#142-June-8-2026)

[Compare
Source](https://redirect.github.com/hyperium/http/compare/v1.4.1...v1.4.2)

- Fix `uri::Builder` to allow `"*"` as the path when scheme and
authority are also set, used in HTTP/2 requests.
- Fix `Uri` to properly reject `DEL` characters.

###
[`v1.4.1`](https://redirect.github.com/hyperium/http/blob/HEAD/CHANGELOG.md#141-May-25-2026)

[Compare
Source](https://redirect.github.com/hyperium/http/compare/v1.4.0...v1.4.1)

- Fix `PathAndQuery::from_static()` and `from_shared()` to reject inputs
that do not start with `/`.
- Fix `Extend` for `HeaderMap` to clamp max size hint and not overflow.
- Fix `header::IntoIter` that could use-after-free if the generic value
type could panic on drop.
- Fix `header::{IterMut, ValuesIterMut}` to not violate stacked borrows.

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Between 12:00 AM and 03:59 AM, only on Monday (`* 0-3 * * 1`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/block/buzz).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMzkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-21 18:28:22 -06:00
renovate[bot]
d874d67c11 chore(deps): update rust crate futures-util to v0.3.33 (#5448)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [futures-util](https://rust-lang.github.io/futures-rs)
([source](https://redirect.github.com/rust-lang/futures-rs)) |
dependencies | patch | `0.3.32` → `0.3.34` |
| [futures-util](https://rust-lang.github.io/futures-rs)
([source](https://redirect.github.com/rust-lang/futures-rs)) |
workspace.dependencies | patch | `0.3.32` → `0.3.34` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/1) for more information.

---

### Release Notes

<details>
<summary>rust-lang/futures-rs (futures-util)</summary>

###
[`v0.3.34`](https://redirect.github.com/rust-lang/futures-rs/blob/HEAD/CHANGELOG.md#0334---2026-08-11)

[Compare
Source](https://redirect.github.com/rust-lang/futures-rs/compare/0.3.33...0.3.34)

- Preserve cloned waker identity.
([#&#8203;3032](https://redirect.github.com/rust-lang/futures-rs/issues/3032))
- Updato `syn` to 3.
([#&#8203;3028](https://redirect.github.com/rust-lang/futures-rs/issues/3028))

###
[`v0.3.33`](https://redirect.github.com/rust-lang/futures-rs/blob/HEAD/CHANGELOG.md#0333---2026-07-18)

[Compare
Source](https://redirect.github.com/rust-lang/futures-rs/compare/0.3.32...0.3.33)

- Fix `ReadLine`'s soundness issue regarding to exception safety.
([#&#8203;3020](https://redirect.github.com/rust-lang/futures-rs/issues/3020))
- Fix unsound `Send` impl for `IterPinRef` and `Iter`.
([#&#8203;3003](https://redirect.github.com/rust-lang/futures-rs/issues/3003))
- Fix stacked borrows violation in `compat01as03` implementation.
([#&#8203;3012](https://redirect.github.com/rust-lang/futures-rs/issues/3012))
- Fix memory leak in `FuturesUnordered::IntoIter`.
([#&#8203;3005](https://redirect.github.com/rust-lang/futures-rs/issues/3005))
- Add `portable-atomic-alloc` feature and use it in `FuturesUnordered`.
([#&#8203;3007](https://redirect.github.com/rust-lang/futures-rs/issues/3007))
- Re-export `alloc::task::Wake`.
([#&#8203;3010](https://redirect.github.com/rust-lang/futures-rs/issues/3010))
- Update `spin` to 0.12.
([#&#8203;3014](https://redirect.github.com/rust-lang/futures-rs/issues/3014))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Between 12:00 AM and 03:59 AM, only on Monday (`* 0-3 * * 1`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/block/buzz).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMzkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-21 18:28:08 -06:00
renovate[bot]
2cef92df67 chore(deps): update rust crate futures to v0.3.33 (#5445)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [futures](https://rust-lang.github.io/futures-rs)
([source](https://redirect.github.com/rust-lang/futures-rs)) |
dev-dependencies | patch | `0.3.32` → `0.3.34` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/1) for more information.

---

### Release Notes

<details>
<summary>rust-lang/futures-rs (futures)</summary>

###
[`v0.3.34`](https://redirect.github.com/rust-lang/futures-rs/blob/HEAD/CHANGELOG.md#0334---2026-08-11)

[Compare
Source](https://redirect.github.com/rust-lang/futures-rs/compare/0.3.33...0.3.34)

- Preserve cloned waker identity.
([#&#8203;3032](https://redirect.github.com/rust-lang/futures-rs/issues/3032))
- Updato `syn` to 3.
([#&#8203;3028](https://redirect.github.com/rust-lang/futures-rs/issues/3028))

###
[`v0.3.33`](https://redirect.github.com/rust-lang/futures-rs/blob/HEAD/CHANGELOG.md#0333---2026-07-18)

[Compare
Source](https://redirect.github.com/rust-lang/futures-rs/compare/0.3.32...0.3.33)

- Fix `ReadLine`'s soundness issue regarding to exception safety.
([#&#8203;3020](https://redirect.github.com/rust-lang/futures-rs/issues/3020))
- Fix unsound `Send` impl for `IterPinRef` and `Iter`.
([#&#8203;3003](https://redirect.github.com/rust-lang/futures-rs/issues/3003))
- Fix stacked borrows violation in `compat01as03` implementation.
([#&#8203;3012](https://redirect.github.com/rust-lang/futures-rs/issues/3012))
- Fix memory leak in `FuturesUnordered::IntoIter`.
([#&#8203;3005](https://redirect.github.com/rust-lang/futures-rs/issues/3005))
- Add `portable-atomic-alloc` feature and use it in `FuturesUnordered`.
([#&#8203;3007](https://redirect.github.com/rust-lang/futures-rs/issues/3007))
- Re-export `alloc::task::Wake`.
([#&#8203;3010](https://redirect.github.com/rust-lang/futures-rs/issues/3010))
- Update `spin` to 0.12.
([#&#8203;3014](https://redirect.github.com/rust-lang/futures-rs/issues/3014))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Between 12:00 AM and 03:59 AM, only on Monday (`* 0-3 * * 1`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/block/buzz).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMjkuNSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-21 18:27:52 -06:00
renovate[bot]
f84511c169 chore(deps): update dependency @tauri-apps/api to v2.11.1 (#5444)
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@tauri-apps/api](https://redirect.github.com/tauri-apps/tauri) |
[`2.11.0` →
`2.11.1`](https://renovatebot.com/diffs/npm/@tauri-apps%2fapi/2.11.0/2.11.1)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@tauri-apps%2fapi/2.11.1?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@tauri-apps%2fapi/2.11.0/2.11.1?slim=true)
|

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/1) for more information.

---

### Release Notes

<details>
<summary>tauri-apps/tauri (@&#8203;tauri-apps/api)</summary>

###
[`v2.11.1`](https://redirect.github.com/tauri-apps/tauri/releases/tag/%40tauri-apps/api-v2.11.1):
@&#8203;tauri-apps/api v2.11.1

[Compare
Source](https://redirect.github.com/tauri-apps/tauri/compare/@tauri-apps/api-v2.11.0...@tauri-apps/api-v2.11.1)

<details>
<summary><em><h4>PNPM Audit</h4></em></summary>

```
No known vulnerabilities found
```

</details>

#### \[2.11.1]
##### Enhancements

-
[`916782601`](9167826011)
([#&#8203;15520](https://redirect.github.com/tauri-apps/tauri/pull/15520)
by [@&#8203;polw1](https://www.github.com/tauri-apps/tauri/../../polw1))
Document that `Monitor.size`, `Monitor.position` and `Monitor.workArea`
are in physical pixels, with examples showing how to convert them to the
logical pixels expected by window creation options via
`toLogical(monitor.scaleFactor)`.

<details>
<summary><em><h4>PNPM Publish</h4></em></summary>

```
> @tauri-apps/api@2.11.1 npm-publish /home/runner/work/tauri/tauri/packages/api
> pnpm build && cd ./dist && pnpm publish --access public --loglevel silly --no-git-checks

> @tauri-apps/api@2.11.1 build /home/runner/work/tauri/tauri/packages/api
> rollup -c --configPlugin typescript


./src/app.ts, ./src/core.ts, ./src/dpi.ts, ./src/event.ts, ./src/image.ts, ./src/index.ts, ./src/menu.ts, ./src/mocks.ts, ./src/path.ts, ./src/tray.ts, ./src/webview.ts, ./src/webviewWindow.ts, ./src/window.ts → ./dist, ./dist...
created ./dist, ./dist in 883ms

src/index.ts → ../../crates/tauri/scripts/bundle.global.js...
created ../../crates/tauri/scripts/bundle.global.js in 1.4s
npm verbose cli /opt/hostedtoolcache/node/24.16.0/x64/bin/node /opt/hostedtoolcache/node/24.16.0/x64/bin/npm
npm info using npm@11.13.0
npm info using node@v24.16.0
npm silly config load:file:/opt/hostedtoolcache/node/24.16.0/x64/lib/node_modules/npm/npmrc
npm silly config load:file:/tmp/286e8dee195254a4370e608b672019b0/.npmrc
npm silly config load:file:/home/runner/.npmrc
npm silly config load:file:/home/runner/.config/pnpm/rc
npm verbose title npm publish tauri-apps-api-2.11.1.tgz
npm verbose argv "publish" "--ignore-scripts" "tauri-apps-api-2.11.1.tgz" "--access" "public" "--loglevel" "silly"
npm verbose logfile logs-max:10 dir:/home/runner/.npm/_logs/2026-06-17T13_41_23_851Z-
npm verbose logfile /home/runner/.npm/_logs/2026-06-17T13_41_23_851Z-debug-0.log
npm warn Unknown env config "verify-deps-before-run". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
npm warn Unknown env config "npm-globalconfig". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
npm warn Unknown env config "overrides". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
npm warn Unknown env config "_jsr-registry". This will stop working in the next major version of npm. See `npm help npmrc` for supported config options.
npm silly logfile done cleaning log files
npm verbose publish [ 'tauri-apps-api-2.11.1.tgz' ]
npm http cache file:/tmp/286e8dee195254a4370e608b672019b0/tauri-apps-api-2.11.1.tgz 0ms (cache hit)
npm notice
npm notice 📦  @tauri-apps/api@2.11.1
npm notice Tarball Contents
npm notice 99.3kB CHANGELOG.md
npm notice 10.2kB LICENSE_APACHE-2.0
npm notice 1.1kB LICENSE_MIT
npm notice 3.5kB README.md
npm notice 5.9kB app.cjs
npm notice 5.4kB app.d.ts
npm notice 5.5kB app.js
npm notice 11.2kB core.cjs
npm notice 6.5kB core.d.ts
npm notice 10.7kB core.js
npm notice 11.0kB dpi.cjs
npm notice 8.8kB dpi.d.ts
npm notice 10.8kB dpi.js
npm notice 5.8kB event.cjs
npm notice 4.9kB event.d.ts
npm notice 5.7kB event.js
npm notice 2.2kB external/tslib/tslib.es6.cjs
npm notice 2.2kB external/tslib/tslib.es6.js
npm notice 3.0kB image.cjs
npm notice 2.4kB image.d.ts
npm notice 2.9kB image.js
npm notice 738B index.cjs
npm notice 1.2kB index.d.ts
npm notice 669B index.js
npm notice 1.1kB menu.cjs
npm notice 451B menu.d.ts
npm notice 717B menu.js
npm notice 3.6kB menu/base.cjs
npm notice 887B menu/base.d.ts
npm notice 3.6kB menu/base.js
npm notice 2.2kB menu/checkMenuItem.cjs
npm notice 1.5kB menu/checkMenuItem.d.ts
npm notice 2.2kB menu/checkMenuItem.js
npm notice 7.4kB menu/iconMenuItem.cjs
npm notice 6.1kB menu/iconMenuItem.d.ts
npm notice 7.4kB menu/iconMenuItem.js
npm notice 5.1kB menu/menu.cjs
npm notice 4.4kB menu/menu.d.ts
npm notice 5.0kB menu/menu.js
npm notice 1.7kB menu/menuItem.cjs
npm notice 1.3kB menu/menuItem.d.ts
npm notice 1.6kB menu/menuItem.js
npm notice 1.1kB menu/predefinedMenuItem.cjs
npm notice 2.6kB menu/predefinedMenuItem.d.ts
npm notice 1.1kB menu/predefinedMenuItem.js
npm notice 7.1kB menu/submenu.cjs
npm notice 4.8kB menu/submenu.d.ts
npm notice 6.9kB menu/submenu.js
npm notice 9.8kB mocks.cjs
npm notice 5.0kB mocks.d.ts
npm notice 9.7kB mocks.js
npm notice 1.8kB package.json
npm notice 22.7kB path.cjs
npm notice 17.7kB path.d.ts
npm notice 21.7kB path.js
npm notice 7.1kB tray.cjs
npm notice 8.5kB tray.d.ts
npm notice 7.0kB tray.js
npm notice 20.7kB webview.cjs
npm notice 23.8kB webview.d.ts
npm notice 20.5kB webview.js
npm notice 8.4kB webviewWindow.cjs
npm notice 4.9kB webviewWindow.d.ts
npm notice 8.3kB webviewWindow.js
npm notice 68.1kB window.cjs
npm notice 64.9kB window.d.ts
npm notice 67.2kB window.js
npm notice Tarball Details
npm notice name: @tauri-apps/api
npm notice version: 2.11.1
npm notice filename: tauri-apps-api-2.11.1.tgz
npm notice package size: 135.7 kB
npm notice unpacked size: 699.0 kB
npm notice shasum: cd6b13fc26403ca095a02e39ecdbec8048d2872d
npm notice integrity: sha512-M2FPuYND2m+wh[...]sUepJWugQCvAA==
npm notice total files: 67
npm notice
npm http fetch GET https://run-actions-1-azure-eastus.actions.githubusercontent.com/113//idtoken/***/***?api-version=2.0&audience=npm%3Aregistry.npmjs.org 200 76ms
npm http fetch POST 201 https://registry.npmjs.org/-/npm/v1/oidc/token/exchange/package/@tauri-apps%2fapi 674ms
npm verbose oidc Successfully retrieved and set token
npm http fetch GET 200 https://registry.npmjs.org/@tauri-apps%2fapi 54ms (cache miss)
npm notice Publishing to https://registry.npmjs.org/ with tag latest and public access
npm notice publish Signed provenance statement with source and build information from GitHub Actions
npm notice publish Provenance statement published to transparency log: https://search.sigstore.dev/?logIndex=1851797040
npm http fetch PUT 200 https://registry.npmjs.org/@tauri-apps%2fapi 2070ms
+ @tauri-apps/api@2.11.1
npm verbose cwd /tmp/286e8dee195254a4370e608b672019b0
npm verbose os Linux 6.17.0-1018-azure
npm verbose node v24.16.0
npm verbose npm  v11.13.0
npm verbose exit 0
npm info ok
```

</details>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Between 12:00 AM and 03:59 AM, only on Monday (`* 0-3 * * 1`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/block/buzz).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMzkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-21 18:27:38 -06:00
renovate[bot]
9008a4d172 chore(deps): update ubuntu:24.04 docker digest to 561618e (#5442)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [ubuntu](https://hub.docker.com/_/ubuntu)
([source](https://git.launchpad.net/cloud-images/+oci/ubuntu-base)) |
container | digest | `4fbb8e6` → `561618e` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/1) for more information.

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Between 12:00 AM and 03:59 AM, only on Monday (`* 0-3 * * 1`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/block/buzz).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMjkuNSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-21 18:27:17 -06:00
renovate[bot]
694d804b24 chore(deps): update swatinem/rust-cache digest to 6323deb (#5441)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [Swatinem/rust-cache](https://redirect.github.com/Swatinem/rust-cache)
([changelog](e18b497796..6323deb102))
| action | digest | `e18b497` → `6323deb` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the [Dependency
Dashboard](../issues/1) for more information.

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - Between 12:00 AM and 03:59 AM, only on Monday (`* 0-3 * * 1`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/block/buzz).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMzkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-08-21 18:26:43 -06:00
morgmart
97b1fee5c3 fix(desktop): restore true zoom by scaling the root rem (#6514)
## Summary

Follow-up to #5644. Cmd +/- had become a text-only zoom: type scaled
while rem-based padding, gaps, widths, avatars, and controls stayed
frozen, which produced cramped layouts (see [#buzz-frontend
thread](buzz://message?channel=a410ffde-c61f-416a-96e0-c296b5f5ecc9&id=1a758115cf07b00c097f6e988553908c045165325a57637519cfa7ed9c9accec)).

Root cause: #5644 introduced a virtual typography rem so the **Font
size** preference could change text without moving layout — a good
decoupling — but it also routed **Cmd +/- zoom** through that same
px-valued token and pinned the real root at 16px. One decision ("freeze
layout") was applied to two dials that shouldn't share it.

This PR gives each dial one owner and lets CSS compose them:

| Control | Changes | How |
|---|---|---|
| **Cmd +/- zoom** | Everything — true zoom | Scales the real `<html>`
font-size again (`useWebviewZoomShortcuts`) |
| **Font size preference** | Text only | Sets `data-font-size`;
`typography.css` maps it to a unitless `--buzz-type-scale`, mirroring
how density already works |

`--buzz-type-rem` becomes `calc(1rem * var(--buzz-type-scale))` —
rem-relative, so it rides on zoom automatically. Resulting text px = `16
× zoom × scale × token-ratio`. The 13 / 14 / 15px conversation contract
is unchanged at default zoom. Density and the type ramp from #5644 are
untouched.

The preference module no longer does px math or knows about zoom; the
zoom hook no longer imports the preference module. Net deletion in
production code.

## Validation

- `pnpm test` — 5,308 desktop unit tests
- `pnpm check:px-text`, `tsc --noEmit`, biome
- Playwright: `top-chrome-zoom-clearance.spec.ts` (native-chrome
clearance stays fixed under root zoom),
`inbox-refactor-screenshots.spec.ts` (zoomed row padding now asserts
`4.4px` instead of the frozen `4px`), and both `profile.spec.ts` zoom
tests (composed zoom × preference, cross-window storage reset)
- Before/after screenshots at 140% zoom in the comment below

---------

Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-08-21 17:21:36 -07:00
Max Lampert
eb484387d5 chore(desktop): drop unused ORIGINAL_CONTENT from empty-edit-delete spec (#6517)
`biome check` fails with `lint/correctness/noUnusedVariables` on
`ORIGINAL_CONTENT` in `desktop/tests/e2e/empty-edit-delete.spec.ts`,
which fails `pnpm check` (Desktop Core) for **every PR touching desktop
paths** — e.g. it currently blocks #6460. It presumably landed while
Desktop Core was path-skipped on the introducing PR.

One-line removal; the constant has no remaining references (the
assertions use `RENDERED_ORIGINAL_CONTENT`).

Signed-off-by: Max Lampert <maxwell@squareup.com>
2026-08-21 18:20:19 -06:00
Taylor Ho
0e48ff2691 feat(workflows): clarify workflow setup and activation (#6470)
**Category:** new-feature
**User Impact:** Workflow authors can build filtered, runtime-aware
automations, understand them at a glance, and get a clear warning before
turning on workflows likely to run often.
**Problem:** Workflow setup exposed raw configuration without enough
help composing message templates, filtering triggers, or understanding
saved behavior; activation could also make a broadly triggered workflow
live without explaining its likely frequency.
**Solution:** Batch 3 adds local, deterministic template variables,
trigger filters, and semantic summaries, then refines cards and
activation around configured behavior and a risk-aware warning boundary.
Scheduling remains the already-shipped implementation, advanced
expressions remain lossless, and network-backed identity/message
enrichment stays in Batch 4.

| Message inputs | Trigger filters |
| --- | --- |
| Caret-aware, keyboard-accessible suggestions expose trigger-local
values and safe prior-step outputs in `send_message.text`. | Structured
conditions and validated manual IDs block invalid submission while
preserving advanced expressions. |
| ![Message variable
autocomplete](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/6470/message-variables.png)
| ![Structured trigger
filters](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/6470/trigger-filters.png)
|

| Workflow cards | Risk-aware activation |
| --- | --- |
| Semantic labels, channel-first hierarchy, configured reaction/action
visuals, real step stacks, and compact status controls make behavior
scannable. | Broad message and frequent schedule triggers explain the
risk before **Turn on**; narrowly scoped triggers proceed without
unnecessary ceremony. |
| ![Semantic workflow
card](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/6470/workflow-card.png)
| ![Activation
confirmation](https://d24qwcpro867f5.cloudfront.net/repos/buzz/prs/6470/activation-choice-v2.png)
|

## Changes

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

**desktop/src/features/workflows/ui/WorkflowActionsMenu.tsx**  
Separates direct card status controls from secondary actions while
retaining modal status actions.

**desktop/src/features/workflows/ui/WorkflowCard.tsx**  
Adds semantic behavior, channel-first hierarchy, configured
reaction/action visuals, real subsequent-step stacks, status controls,
and reduced-motion-aware trigger feedback.

**desktop/src/features/workflows/ui/WorkflowDialog.tsx**  
Warns before activating broadly triggered workflows while allowing
narrowly scoped workflows to proceed directly.

**desktop/src/features/workflows/ui/WorkflowFormBuilder.tsx**  
Connects structured trigger filters and template-aware step inputs while
preserving schedules, trigger transitions, and selected YAML authority.

**desktop/src/features/workflows/ui/WorkflowStepCard.tsx**  
Replaces generic labels with deterministic configured-step descriptions.

**desktop/src/features/workflows/ui/WorkflowTemplateTextarea.tsx**  
Adds caret-aware variable suggestions with keyboard navigation and focus
restoration.

**desktop/src/features/workflows/ui/WorkflowTriggerConditions.tsx**  
Adds structured local filters, validated author/message IDs, and a
lossless advanced-expression fallback.

**desktop/src/features/workflows/ui/workflowActivationWarning.ts** and
**workflowActivationWarning.test.mjs**
Classify broad message and frequent schedule triggers for contextual
activation warnings.

**desktop/src/features/workflows/ui/workflowConditionExpression.ts** and
**workflowConditionExpression.test.mjs**
Model and cover parsing, serialization, validation, and
advanced-expression preservation.

**desktop/src/features/workflows/ui/workflowDefinition.ts** and
**workflowDefinition.test.mjs**
Preserve trigger/step configuration and derive deterministic card
metadata across YAML round trips.

**desktop/src/features/workflows/ui/workflowStepDescription.ts** and
**workflowStepDescription.test.mjs**
Generate and cover local step summaries.

**desktop/src/features/workflows/ui/workflowTemplateVariables.ts** and
**workflowTemplateVariables.test.mjs**
Define and cover trigger-specific, order-bounded variables and caret
insertion.

**desktop/src/features/workflows/ui/workflowTriggerDescription.ts** and
**workflowTriggerDescription.test.mjs**
Generate and cover semantic trigger summaries without network lookups.

**desktop/tests/e2e/workflow-local-controls.spec.ts** and snapshot  
Cover filters, IDs, advanced expressions, autocomplete, activation
choices, summaries, and YAML authority.

**desktop/tests/e2e/workflow-reaction-picker.spec.ts**  
Covers configured reaction emoji in workflow nodes and summaries.

**desktop/tests/e2e/workflows.spec.ts**  
Covers risk-aware activation warnings, direct safe creation,
duplication, and card status controls.

</details>

## Reproduction steps

1. Create a message-posted workflow in **Workflows**, add a Send message
step, and type `{{trig`; verify keyboard-selectable variables insert at
the caret.
2. Configure message-text and manual ID filters; verify malformed IDs
block submission and advanced expressions survive Form/YAML transitions.
3. Create a broad message workflow; verify **Back** persists nothing,
**Keep off** saves it disabled, and **Turn on** enables it. Confirm a
narrowly triggered webhook skips the warning.
4. Inspect the saved card; verify its channel, semantic behavior,
configured actions/reaction, real step stack, and status are
understandable without opening YAML.

## Validation

Validated at exact clean head `f99503819889b95ee3c61657c5c3850aae35481e`
on base `24ec6a468ec9d0d425ee58fbfc4d416412c446ad`.

- Focused workflow regressions passed 59/60 locally; the only local miss
was a 438-pixel macOS snapshot drift, while the checked-in Linux
baseline comes from the failing CI artifact. Repository pre-push gates
and E2E build/typecheck passed.
- A broader 36-test smoke invocation had 31 passes and five unrelated
pre-existing expectation/snapshot failures, so it is not claimed as
fully green. Adversarial fixes are recorded in [round
one](https://github.com/block/buzz/pull/6470#issuecomment-5366366670)
and [round
two](https://github.com/block/buzz/pull/6470#issuecomment-5366407535).

---------

Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz>
Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Co-authored-by: Mongo <5398c5fd039b963ce132b3e078e7c4af097dd997517bb5e14c2682fe68c25197@buzz.block.builderlab.xyz>
2026-08-21 16:53:50 -07:00
Max Lampert
b85d680fb1 perf(desktop): stop the Projects fan refetching on re-entry and running after leave (#6458)
Entering Projects fires a large fan: an exhaustive paginated relay
enumeration (projects/repos/tombstones), five 2,000-event work-item
queries plus assignment-operation scans, per-repo activity summaries,
and a local-repository filesystem scan. Measured on a large community
(101 issues / 258 PRs):

| query | measured cost |
|---|---|
| work-items (5 × 2,000-event REQs + assignment scans) | 3.5–3.9s |
| activity summaries | 4.1s |
| repository activity | 1.0–2.2s |
| local repository scan | 1.7s |

Two lifecycle bugs made the fan far more expensive than it needs to be:

- **Freshness windows guaranteed a full refetch on nearly every
re-entry** (60s enumeration, 30s work-items/activity, 10s local scan) —
i.e., the costs above were re-paid on almost every visit. Every local
write path already invalidates its keys explicitly (issue/PR mutations,
project creation, repo sync), so the short windows only served
remote-actor freshness. Raised to 5m/2m/2m with a 30m enumeration cache:
re-entries now paint from cache, and the fan re-runs at most every 2–5
minutes.
- **Leaving Projects left the whole fan running**, competing with the
next surface's channel fetches on the same relay connection. AbortSignal
is now threaded through the enumeration and assignment pagination loops
(optional params — behavior identical without a signal), and leaving the
surface cancels the work-items query. Deliberately NOT cancelled: the
enumeration (the always-mounted sidebar projects section observes it and
its 30m cache is valuable), repo snapshots and local scans (native work
that can't abort — cancelling would discard the finished result and
force the same clones again), and activity summaries (a single bounded
request).

Abort behavior is covered by red-first unit tests on both pagination
loops. Remaining follow-up (out of scope): the queries themselves want a
relay-side aggregate instead of shipping thousands of events to compute
counts client-side.

---------

Signed-off-by: Max Lampert <maxwell@squareup.com>
2026-08-21 17:40:35 -06:00
Max Lampert
b0466ac465 perf(desktop): keep the member roster off the channel-switch path (#6456)
Switching channels triggered a full-roster fetch (kind:39002 plus a
kind:0 profile batch with every member pubkey as an author) in the
common case, and several render paths walked the full roster per render.
None of this scales past a few hundred members; the product target is
10k+.

- **Members query staleTime 30s → 5min.** Every membership change the
client can observe already invalidates the key explicitly: live
join/leave system messages for the active channel, member-added/removed
notifications for the current identity, and all membership mutations —
including previously-uncovered direct write paths (moderation kick,
agent-deletion cleanup), which now invalidate through a shared helper.
The 30s window bought correctness we already had and charged a roster
fetch per switch.
- **ChannelMembersBar no longer mounts the roster query for non-DM
channels** — the count renders from the channel summary, and the
private-channel huddle gate accepts `channel.isMember` (derived from the
same kind:39002 event as the roster's self entry).
- **Roster-derived lookups are cached on roster identity**
(`rosterDerivations.ts`): role map, agent-member subset, member/bot
pubkey sets. These were rebuilt O(members) on every live message /
profile re-key. React Query's structural sharing keeps the roster
identity stable, so each derivation computes once per distinct roster.
- **Backend: the kind:0 profile join in `get_channel_members` is capped
at the first 500 members** (roster order). Members past the cap keep
`display_name: None` (UI falls back to pubkey labels and profile
caches); `role=="bot"` agent flags are roster-derived and unaffected.
Full roster pagination is the structural follow-up.
- **Composer keystroke path**: `useCanAddChannelMembers` re-scanned
channels + roster per keystroke; now memoized on data identities,
sharing the cached pubkey set.

### Measured / estimated impact

| metric | before | after |
|---|---|---|
| roster fetches while switching (live trace) | nearly every switch | ≤1
per channel per 5 min |
| roster fetch cost on the wire (live, 51-member channel) | 273ms per
fetch | amortized away |
| kind:0 `authors` filter size at 10k members | ~670KB per request (~67
B/pubkey) | capped at 500 authors (~34KB) |
| warm-switch longtask at 10k members (mock harness, 4× throttle) |
364ms | 318ms |
| per-render roster walks (role map, agent sets) at 10k members |
O(members) per live message | once per distinct roster |

Deferred deliberately: protocol-level roster pagination and removing
`memberPubkeys` from channel summaries (needs relay support).

---------

Signed-off-by: Max Lampert <maxwell@squareup.com>
2026-08-21 17:40:20 -06:00
Brad Seiler
47526784d5 fix(deletion): allow IRSA S3 credentials (#6495)
## Why
`buzz-admin deletions` runs inside bb-public relay pods, where S3
credentials are provided by the pod credential chain rather than static
`BUZZ_S3_ACCESS_KEY` / `BUZZ_S3_SECRET_KEY` values. The deletion CLI was
requiring those two env vars to be non-empty before constructing the
shared media storage client, so it could not reach the existing default
AWS credential chain.

## What
- Treat missing/blank deletion S3 access key and secret key as an empty
credential pair so `MediaStorage::new` can use `Credentials::default()`.
- Keep the existing static-credential path unchanged when both values
are non-empty.
- Keep deletion unit tests deterministic by covering only deletion env
normalization for missing/blank pair, trimmed static pair, and
partial/whitespace-partial outputs; shared media tests continue to own
credential-pair enforcement.

## Risk Assessment
Low and scoped to the operator-only community deletion CLI startup path.
The shared media storage credential validation still owns
static-vs-default credential selection and still rejects mixed partial
credentials.

## Testing
At committed head `0a86c2914b1f97caf4788a771048aa8d9d9d88ac` with a
clean worktree before and after (`git rev-parse HEAD` before/after
matched):
- `just fmt-check` — passed.
- `cargo test -p buzz-deletion` — passed: 12 passed, 9 ignored.
- `cargo test -p buzz-media` — passed: 120 passed;
`static_creds_round_trip_against_minio` remained ignored because it
requires live MinIO.
- `cargo test -p buzz-admin` — passed: 1 passed.
- `cargo clippy -p buzz-deletion --all-targets -- -D warnings` — passed.
- Startup smoke at the same head: built `buzz-admin`, then ran
`target/debug/buzz-admin deletions drain` with `BUZZ_S3_ACCESS_KEY=` and
`BUZZ_S3_SECRET_KEY=' '` plus `AWS_ACCESS_KEY_ID` /
`AWS_SECRET_ACCESS_KEY` fallback credentials; command exited `0`,
proving startup transitions past deletion S3 key validation and
exercises the shared default credential-chain branch using AWS env
fallback credentials.
- `git push origin HEAD:seiler/deletion-irsa-credentials` — passed;
pre-push hooks passed.

Not run: the full `TESTING.md` live-local relay workflow. Docker Desktop
currently refuses CLI access on this machine with `Sign in to continue
using Docker Desktop. Membership in the [squareup] organization is
required.`

## References
- Buzz channel:
`buzz://message?channel=9e4aabc6-414c-4978-aba7-b9f5228776de&id=177c5b8ad9e78a647f438ec7040d25f0c20a7c2b8678dd0e34768effe053f7f4`

Generated with Codex

---------

Signed-off-by: coder 0 <d97ebdbb198c7237c94f84ea8bb8a73583ea067407eebd0062abbb3962527fb1@buzz.block.builderlab.xyz>
Co-authored-by: coder 0 <d97ebdbb198c7237c94f84ea8bb8a73583ea067407eebd0062abbb3962527fb1@buzz.block.builderlab.xyz>
2026-08-21 19:14:00 -04:00
Tyler
d97780b477 docs(nips): comprehensive NIP-FI — core + claimable profiles (EDGE/LIFECYCLE/DELEG/CONF) (#5946)
## What

Comprehensive NIP-FI against `main`: one normative core plus four
separately
claimable profiles, replacing the single-document structure of #3726
(which was
based on #1485's branch, not `main`). Six documents, 1,975 lines, docs
only.

- **`NIP-FI.md` (core, 632 lines)** — issuer-qualified identity `(iss,
sub)`,
independent Nostr proof, client-attached assertion, partial bijection
with
durable tombstones, atomic final admission, bounded leases, private
denials
  with a closed response vocabulary, retire/revoke/rotate, two contract
identities (`assertion_policy_id`, `transport_contract_id`), per-policy
  `skew` / `maximum_assertion_age` / `maximum_status_age` with missing
configuration denying, a closed token-class rule (`at+jwt`,
`nip-fi+jwt`,
  named compatibility; ID tokens always deny), declared freshness class
  (`offline-jwt` | `current-status`), server-declared body authorization
  relevance (NIP-98 payload-binding fix, including a `payload` tag on an
irrelevant-body operation), BCP 14, "equivalent" defined over identity /
bounds / provenance classes, a compact non-normative worked wire
example,
  and a non-normative comparison with DPoP, mTLS-bound tokens, and HTTP
  Message Signatures. FI-INV-01..16 are normative core text. The
behavioral-oracle table lists exactly 30 oracle IDs, one per row, with
no
  shorthand.
- **`NIP-FI-EDGE.md`** — trusted-edge surface: the
`trusted-proxy-hmac-v2`
envelope + canonicalization, or a private authenticated-edge adapter
under a
reviewed contract; `authorization_domain_id` derivation (exact 16 RFC
9562
UUID bytes); `proof_transport_code` registry (0x01 NIP-42, 0x02 NIP-98;
  0x03 Git smart-HTTP and 0x04 Blossom reserved pending their transport
contracts; 0x05–0x7f unassigned pending published stable specifications)
  + extension procedure; body-acquisition bounds; three normative test
vectors. An independent Nostr proof (the NIP-98 event in
`Authorization`,
  which reaches the verifier byte-identical, or the NIP-42 event after
connect) is the only decision input outside the MAC; absent or
incomplete
  provenance on an edge-required route is `missing_evidence`,
  present-but-failing provenance is `evidence_rejected`.
  Header-trust-without-provenance is nonconformant.
- **`NIP-FI-LIFECYCLE.md`** — provision / disable / re-enable /
administrative
expiry (`binding_not_after`) / pending-replacement lineage, one
conformance
trace per privileged transition; every binding-creating transition
declares
whether it continues or establishes a grant; a private-condition table
for
  CONF enumeration agreement.
- **`NIP-FI-DELEG.md`** — delegated agents; explicit temporal boundaries
matching core's inclusive-`nbf`/exclusive-`exp` idiom, with the
delegated
`skew` configured by this profile; lease deadline anchored to the lease
  issue instant; strict path separation — a delegated request carries no
assertion or provenance field, so it cannot traverse an edge-provenance
  route and uses ingress on which NIP-FI-EDGE is not required.
- **`NIP-FI-CONF.md`** — conformance evidence: an immutable claim tuple
  including the governing document revision and exit fixture digest; the
  complete 16-row denial-fixture enumeration with three mechanical
  enumeration-agreement checks; mutation adequacy with a countable
  denominator — one retained killed mutant per literal oracle-table row
(30 core + 6 EDGE + 11 LIFECYCLE + 7 DELEG + 4 CONF = 58), rows selected
structurally by their first cell, never by section title, with the
release
gate and CONF's own oracle rows stated in the same listed-oracle terms
and
  a mutant defined for CONF's own report- and suite-subject oracles; an
  interoperability exit test compared over signing inputs (per-transport
NIP-01 serialization for the NIP-98 and NIP-42 proofs; decoded protected
header and claims as JSON values for the assertion), with a shared exit
  fixture pinning complete pre-signature header/claim JSON and complete
unsigned event fields for both transports, and mandatory negative
controls.
  `FI-CONF-INTEROP-EXIT` is `deferred` with reason
`no-independent-implementation` until a second independent
implementation
  exists; the canonical fixture is editor-authored at
`docs/nips/fixtures/nip-fi-conf-exit.json` and is **not in this PR** —
until
it is published a claim records `pending-canonical-fixture`, valid only
  while the exit test is deferred. Explicit not-applicable dispositions,
including `offline-jwt` deployments for the two current-status oracles
and
  absence of a revocation-bounded external capability projection for
  `FI-TRACE-CAPABILITY-REVOCATION`.
- **`NIP-FI-MODEL.md`** — non-normative companion; defines no
requirement or
  conformance claim and is not claimable.

## Why

The prior draft rated 9 (soundness) / 6 (minimalness) / 7 (elegance) /
7 (correctness) in adversarial + comparative review. This restructure
keeps the
two-invariant spine untouched, makes everything else a claimable
profile, and
collapses five stacked versioning mechanisms into two contract
identities.

Mutation adequacy counts one mutant per literal oracle-table row — a set
two
implementers enumerate identically — instead of "each normative
requirement,"
which had four defensible readings.

Resolved product calls (owner-approved):
1. Enrollment/denial posture is private — boolean enrollment discovery,
TOFU
extension claim not self-advertised, `key_mismatch →
authorization_denied`
   joins the denial anonymity set, and replayed evidence is classed
   `authorization_denied` so resubmission reveals nothing about commit.
2. Revocation honesty — only `current-status` deployments may advertise
an
   unconditional residual-revocation bound; `offline-jwt` advertises
unbounded/unknown. Access tokens keep RFC 9068 `at+jwt`; `nip-fi+jwt` is
   reserved for a separately minted Buzz assertion.

## Acceptance bar

- Nothing in core is deletable without losing a stated core guarantee.
- From the core document plus the CONF exit fixture, a second
implementer can
produce a valid request equal over the request compared object (signing
  inputs), and a byte-exact public denial per class — no reference
  implementation.
- Every oracle-table row ships a retained killed mutant satisfying only
the
  entry it was selected for.
- Both deployment profiles (trusted proxy = EDGE, client-held OIDC =
core
  client-attached) pass the same lifecycle conformance suite.

## Status

Ready at head e720a5cda. Every revision below is on this branch: the
2026-08-17 and 2026-08-18 review laps (Wren, Dawn, Perci, Sami, Mari,
Quinn)
closed at 513e03b06, 17d455a9b, and 4f913a813; the 2026-08-20 external
line-by-line review (R1–R10, R12) closed across 56e74141e..772ba7a72;
the
2026-08-20/21 adversarial lap (#6437) squash-merged as b8db13d88; the
round-3
external review (R13, R14), the DELEG×EDGE composition note, and three
terminology nits closed at e720a5cda; R11 is this description. Oracle
census: 58 (30 core, 6 EDGE, 11 LIFECYCLE, 7 DELEG, 4 CONF).

Known follow-ups, filed after merge and out of scope here: adapter-only
edge
deployments and FI-EDGE claimability; an EDGE private-condition table
for
CONF's enumeration-agreement check; an enumerable definition of the
positive/negative oracle sets used by the global mutation controls;
NIP-OA's clock-free verification versus NIP-FI-DELEG's wall-clock
expiry.

Supersedes #3726 as the spec vehicle; #1485 remains the design-history
anchor.

---------

Signed-off-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz>
Signed-off-by: Max <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@buzz.block.builderlab.xyz>
Signed-off-by: Perci <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@buzz.block.builderlab.xyz>
Signed-off-by: Wren <5217c5c2f7bfb4333e46d17c98a9255a52dadee18dcd43a43536b95e6776dfa0@buzz.block.builderlab.xyz>
Signed-off-by: Dawn <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@buzz.block.builderlab.xyz>
Signed-off-by: Tyler Longwell <tlongwell@squareup.com>
Signed-off-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz>
Co-authored-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz>
Co-authored-by: Max <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@buzz.block.builderlab.xyz>
Co-authored-by: Perci <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@buzz.block.builderlab.xyz>
Co-authored-by: Wren <5217c5c2f7bfb4333e46d17c98a9255a52dadee18dcd43a43536b95e6776dfa0@buzz.block.builderlab.xyz>
Co-authored-by: Dawn <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@buzz.block.builderlab.xyz>
Co-authored-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz>
2026-08-21 17:18:24 -04:00