Commit Graph
1311 Commits
Author SHA1 Message Date
npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta 896685f9a3 T3 tune markdown reserve overshoot
Co-authored-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
2026-07-08 14:22:03 -04:00
npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta 870b02a29b T3 shrink timeline row height estimates
Co-authored-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
2026-07-08 14:08:56 -04:00
npub17jjz49l9jjmhhk7cac63j8yt9z555n9cw8vk7v5jz4vzw4ppld5qgj57ccandTyler Longwell 32e41e78e0 T1.1 upscroll-jitter gate: reframe to motion-consistency (comp-sensitive)
Dawn found the RED gate from 33e73511 was mathematically invariant to the
fix: its residual subtracted the REALIZED scrollTop delta, which includes
the fix-writer's compensating scrollBy, so the writer cancelled out and the
gate scored raw estimate error R (only T3 can move it), not motion
smoothness. Quinn and Eva re-derived and confirmed. Co-visible and any
row-vs-row differential share the disease: compensation is a uniform global
offset, so it cancels out of any quantity not referenced to the input.

Reframe (converged with Dawn/Quinn/Eva; ratified event 63f5e6e1):

- Metric is now per-notch MOTION CONSISTENCY: the reading row's viewport
  motion (rowMove = after.top - before.top; NO scrollTop reference) scored
  as deviation from the run median. This references the row's own motion
  ACROSS notches (temporal self-reference), never a neighbour (spatial) or
  scrollTop, so the writer's scrollBy survives into the metric and is SEEN.
- Actuation is a fixed synchronous step (scrollTop -= STEP) so the input
  delta is constant by construction, bypassing Blink's wheel-scaling (a
  wheel notch applies 218/220/222...; median-of-run would misread that
  per-notch scaling as jitter). Dawn independently confirmed even the
  actuated scrollTop delta is post-writer contaminated (48-75px spread
  under sync) — rowMove is the only clean measurable.
- Anti-cheat floor: mean rowMove must be > STEP*0.75 so a frozen or
  half-applying scroller (near-zero variance, would false-green) is caught.
- Old scrollTop-referenced residual kept as a printed NON-GATING diagnostic
  (= estimate error R = T3's estimator acceptance number).
- Second non-gating diagnostic: one wheel-actuated pass of the same metric
  (Tyler's real input is a wheel), on the record every run.
- RED-at-tip is a HARD gate with a VOID comment: median-of-run is only
  valid while the corpus produces varying realization, and the tip run
  being RED IS the proof of that dispersion.

RED at tip: peak-dev 41px / rms 24px (gate <=2 / <=0.6). GREEN target is
Dawn's real T2 writer: peak-dev 0.00 / rms 0.00, reproducible over 3 sync
runs. A synthetic per-notch-varying oracle drives 74/77 notches to exactly
STEP; the real writer re-pins in the same ResizeObserver cycle and closes
the synthetic-only outliers.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 14:04:08 -04:00
npub17jjz49l9jjmhhk7cac63j8yt9z555n9cw8vk7v5jz4vzw4ppld5qgj57ccandTyler Longwell 33e735117a L-E upscroll-jitter gate: RED metric isolating realization drift
Tyler's report: scrolling UP a fully-loaded channel is subtly jumpy;
DOWN is smooth. Root cause (Eva H1 + L-C): rows above the opening
viewport have never painted, so under content-visibility:auto they sit
at estimateRowHeight()'s contain-intrinsic-size reserve (60px,
utilities.css:17). Scrolling up, each realizes at its true height; the
reserve-vs-true delta shifts the reading position. Shipped WKWebView has
no overflow-anchor, so it corrects nothing — every delta lands raw.

This adds a deterministic gate that is RED at tip 77bd0e70 and that the
converged owned-compensation fix (overflow-anchor:none + same-frame
scrollBy(realized-reserved)) turns green:

- e2eBridge: a dedicated `jitter-corpus` mock channel (400 structurally
  heterogeneous rows — headings/lists/blockquotes/code fences/long prose
  whose true height estimateRowHeight is known to miss), its own channel
  so the uniform deep-history seed the load-older specs use is untouched.
- upscroll-jitter.perf.ts: forces overflow-anchor:none on the scroller
  (mirrors shipped WKWebView; logs CSS.supports per engine), then wheels
  up in notches tracking a row held INSIDE the viewport (SAFE_MARGIN band
  from both edges, re-picked each step, scored only if the same id stayed
  in-band before+after). Residual = row's visual delta-top minus the
  scroll delta: 0 == smooth. Gate is peak <=2px, rms <=0.6px.

Validity: within a single cold run the already-realized rows read
residual 0.0 exactly while realizing rows drift -27..-75px — an artifact
would drift on both. Negative sign shows the estimator over-reserves.
At tip: peak 75px, rms 40px over 23 steps → RED. A correct fill of
scrollTop absorbs the drift into the scroll delta, driving residual->0.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 13:09:31 -04:00
77bd0e700f perf(desktop): move blocking commands off the UI thread
Finding [L1] commands/** — several Tauri commands still performed filesystem, process discovery, sqlite/local-storage reads, zip/json parsing, managed-agent store work, and workspace symlink updates synchronously on the command thread. Convert the affected commands to async command handlers with explicit spawn_blocking around the blocking sections so the UI thread is not responsible for those operations.

Reacquire AppState from the owned AppHandle inside blocking closures instead of moving borrowed State<'_, AppState> or non-Send guards across await points. Keep existing store mutex serialization inside the blocking closures and preserve command-specific ordering: identity import persists before swapping in-memory keys, workspace apply validates before mutation and persists the effective repos dir before symlink updates, and repos-dir-error emissions still use the AppHandle.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:59:03 -04:00
4aac3916a2 perf(desktop): batch workflows overview into one relay query (#h fanout)
L6 finding: WorkflowsView's allWorkflowsQuery issued one get_channel_workflows
relay POST per member channel (Promise.all fanout) — N round-trips scaling with
channel count on the Workflows overview.

A nostr #h filter matches ANY listed value, so one query with all channel ids
returns the identical set. Added get_channels_workflows(channel_ids) which
queries once; each WorkflowWire already carries its own channel_id (from the
event h tag), so WorkflowsView groups results client-side via a channelId->name
map. Neither the per-channel nor the batched command sets a limit, so batching
does not change result completeness (review-bar #3: no shared-limit truncation).
e2eBridge gains a matching get_channels_workflows mock so overview e2e still
resolves. Single-channel get_channel_workflows stays for useChannelWorkflowsQuery.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:52:10 -04:00
f64dc32dd9 perf(desktop): drop redundant 30s polls on personas/teams/managed agents
L6 finding: usePersonasQuery, useTeamsQuery, and useManagedAgentsQuery's
idle branch each ran a 30s refetchInterval that duplicated an existing
event-driven refresh path. Inbound relay changes to PERSONA/TEAM/MANAGED_AGENT
records emit agents-data-changed (personas/mod.rs), which useAgentsDataRefresh
coalesces into a query invalidate (200ms window). The 30s poll was
belt-and-suspenders disk-read IPC on top of correct event invalidation.

Removed the interval from personas and teams entirely. For managed agents,
kept the 5s branch for locally-running agents (process state can change with
no relay event, so that poll is their only liveness signal) and dropped the
idle 30s fallback (control-plane changes have the event path; the 5s branch
already captures the running->stopped transition on its last poll, and user
actions invalidate directly).

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:52:10 -04:00
fc1d1aed91 perf(desktop): relax relay-agents poll 30s->5min, pause when backgrounded
L6 finding: useRelayAgentsQuery ran a 30s refetchInterval backed by an
unfiltered relay query for ALL kind:10100 agent profiles, mounted on ~13
always-live surfaces (channel screen, members bar, mentions, sidebar,
profile popovers). It re-pulled the full profile set app-wide every 30s.

Relay agent profiles are near-static; 30s is far too aggressive. This poll
is also the ONLY refresh path for kind:10100 (the agents-data-changed event
fires only for local PERSONA/TEAM/MANAGED_AGENT reconcile, never kind:10100),
so it cannot be dropped. Relaxing to 5min drops relay traffic ~10x, and
refetchIntervalInBackground:false (matches channels/hooks.ts house style)
pauses it while the window is unfocused. No semantics change: the set of
relay agents still refreshes, just less often.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:52:10 -04:00
53ba1f8269 perf(desktop): limit reconnect query invalidation to relay data
Finding L3-2: auto-heal and manual reconnect used broad queryClient.invalidateQueries(), refetching unrelated Tauri/disk/local queries after relay recovery.

Route both reconnect paths through a shared relay-dependent query predicate. The taxonomy includes relay-backed messages/channels/profiles/social/workflows/projects state and excludes local-only agent/runtime/workspace-icon/repo queries.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:51:02 -04:00
7f8746a618 perf(desktop): cap aux backfill request concurrency
Finding L3-3: fetchChunkedAuxEvents awaited each auxiliary-event chunk sequentially, delaying visible reaction/edit/deletion backfills on large history windows.

Run aux chunks through a small shared concurrency helper so relay history requests overlap without unbounded fanout. The helper preserves chunk result order and the existing fail-fast semantics.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:51:02 -04:00
e1edcfc46f perf(desktop): parallelize relay reconnect replay
Finding L3-1: reconnect replay previously awaited every live subscription REQ and paged history replay serially, making reconnect latency grow with active subscription count.

Start live REQs together, then replay paged channel catch-up with a bounded cap while preserving ordering inside each subscription's page loop.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:51:02 -04:00
ec8b041671 fix(desktop): offload huddle device and model setup
Finding: L2 huddle device enumeration used a sync command on provider mount/devicechange, and start/join performed sequential membership fetches plus synchronous STT/TTS ONNX construction on async workers.

Make audio output enumeration an async command backed by spawn_blocking, fetch bot/all memberships in parallel during post-connect setup, and construct STT/TTS pipelines on the blocking pool while preserving starting sentinels, stale-session checks, and final phase checks.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:45:39 -04:00
7d2cdba6f0 fix(desktop): defer event sync off setup path
Finding: L2 event_sync boot reconcile did best-effort JSON reads, SQLite retention checks/writes, and event signing synchronously during Tauri setup after identity resolution.

Snapshot the resolved owner keys, then spawn the reconcile after setup-critical boot work begins. The reconcile runs on spawn_blocking so no filesystem, SQLite, or signing work occupies the GUI setup path or an async worker. Secret-store identity resolution remains synchronous and out of scope by design.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:45:39 -04:00
13578737fe fix(desktop): offload archive sqlite work
Finding: L2 archive read/save-subscription/archive_events sqlite work could block the GUI IPC path or async workers under busy_timeout contention.

Move archive planning, commits, save-subscription merge/remove/list, and paginated reads through spawn_blocking with each rusqlite connection scoped inside the blocking closure. Relay query awaits remain between DB phases with no connection or transaction in scope.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:45:39 -04:00
a9a8d0a309 test(desktop): cover profileLookupsEqual + the messageProfiles stabiliser
Finding [L4] messageProfiles structural-share (Tier 1) — red/green evidence.
`profileLookupsEqual` cases: reference identity, distinct-but-value-equal,
key-count / key-set mismatch, each of the 5 summary fields breaking equality,
empty lookups. Plus a render-count-discipline pair that replays the exact
ChannelScreen ref idiom: value-equal re-derives hold the same reference (the
memo skips — no timeline re-render on typing churn) and a real profile change
swaps it (the memo fires), then re-stabilises around the new value.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:37:35 -04:00
17edcc2bc7 perf(desktop): memoise MessageActionBar, stabilise its onRemindLater callback
Finding [L4] MessageActionBar (Tier 3): the action bar re-rendered with every
row render even when its props were unchanged. Wrap it in `React.memo`. The
memo was dead on arrival, though — the row passed an inline `onRemindLater`
arrow, a fresh function identity every render that defeated the shallow prop
compare. Extract it to a `handleRemindLater` useCallback (deps
[channelId, openReminder]); all other props are already stable (openReminder
and handleReactionSelect are useCallbacks, setBadgeBurstEmoji is a state
setter), so the memo now actually skips.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:37:35 -04:00
b3c1cde788 perf(desktop): hoist non-DM channel-name filter into ChannelNavigation provider
Finding [L4] MessageRow channelNames (Tier 3): every row ran
`channels.filter(non-dm).map(name)` in its own useMemo, so the identical
derivation was recomputed once per mounted row and re-ran whenever the channel
list changed. Compute it once in `ChannelNavigationProvider` as
`nonDmChannelNames` (memoised on `[channels]`) and have rows read it directly.

Additive to the context value — `channels` is unchanged, so other consumers are
unaffected.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:37:34 -04:00
9628ce7662 perf(desktop): drop per-row agent-pubkey rescan, use the set passed from parent
Finding [L4] MessageRow resolvedAgentPubkeys (Tier 2): every mounted row
re-scanned the full `profiles` lookup to rebuild the agent-pubkey Set, so the
same O(profiles) work ran once per row and re-ran on every profile-lookup
change. ChannelScreen already computes this exact Set once (now from the
stabilised lookup) and passes it down as `agentPubkeys`, already normalised.

Consume the passed Set directly, falling back to a module-level stable empty
Set so rows without one keep a constant reference (a fresh `new Set()` per
render would defeat the row memo). Widen `getConfigNudgeAuthorPubkey`'s
parameter to `ReadonlySet<string>` — it only reads via `.has()`, and this
matches how the `agentPubkeys` prop is already typed upstream.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:37:34 -04:00
3bffd34e83 perf(desktop): stabilise messageProfiles reference to kill typing-storm re-renders
Finding [L4] ChannelScreen.tsx messageProfiles (Tier 1): the users-batch
query re-keys on the full sorted pubkey set, so typing churn (a transient
typing-only pubkey entering/leaving the set) produces a fresh lookup object
identity even when no profile value changed. That new reference fails
MessageRow's `prev.profiles === next.profiles` memo check and re-renders the
entire timeline on every keystroke-adjacent typing event.

Add `profileLookupsEqual(a, b)` — a by-value deep-equal over the 5 scalar
summary fields (displayName/avatarUrl/nip05Handle/ownerPubkey/isAgent) — and
use a useRef stabiliser at the ChannelScreen boundary to return the previous
reference when the re-derived lookup is value-equal. Consumers read profiles
by pubkey value only and never treat identity as a change signal, so returning
the stale-but-value-identical reference is safe (traced c6237ef8). The
stabilisation does O(profiles) equality work once at the boundary, replacing
O(rows x profiles) of downstream per-row re-render.

Also derive `agentPubkeys` from the stabilised lookup (was raw query data) so
that Set only churns on a real profile change, demoting the downstream row
scans that keyed off it.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:37:34 -04:00
73d2218336 perf(huddle): slow frontend fallback polls
Finding: L7 huddle frontend poll reductions.\n\nKeep event-driven huddle state updates and immediate initial checks, but slow the fallback timers that hit sync/lightweight IPC and duplicate membership refresh paths. This reduces steady-state huddle IPC/relay traffic without touching Rust huddle ownership.
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:34:53 -04:00
597c5d1eaa perf(pulse): pause interval refetches when hidden
Finding: L7 pulse fixed-interval refetches.\n\nGate Pulse timeline/reaction refetch intervals on document visibility so the visible tab stays fresh while hidden windows stop issuing periodic social API requests. Initial query enablement and invalidation behavior are unchanged.
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:34:52 -04:00
d49811f3df perf(search): lazy-load agent data for topbar search
Finding: L7 search dialog-open kind:10100 pull.\n\nKeep message/user search behavior the same, but defer managed-agent and relay-agent queries until the debounced query reaches the existing minimum search length. Opening and closing the dialog without typing no longer triggers agent discovery/network work.
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:34:52 -04:00
npub17jjz49l9jjmhhk7cac63j8yt9z555n9cw8vk7v5jz4vzw4ppld5qgj57ccandTyler Longwell a9f63b7699 perf(desktop): defer archive-seed hooks behind startupReady
Finding [L5] AppShell.tsx:161-164 — 4 archive/ingestion hooks mounted
unconditionally at first render competed with first paint. Gate the two
archive *seed* hooks (useObserverArchiveSeed, useAgentMetricArchiveSeed)
behind startupReady by passing deferredPubkey instead of the eager
identityQuery pubkey, matching the existing presence/user-status
deferral pattern.

useArchiveSync (the eager live-save path) stays unchanged — it owns live
event ingestion and must not be deferred. Only the one-shot first-run
seeds (mergeSaveSubscriptionKinds) move off the boot critical path.

The seeds' explicit-choice guard is untouched: each hook already
early-returns on `if (!pubkey) return`, so a deferred (undefined) pubkey
is a no-op until startup completes, then the seed fires exactly once with
identical semantics. Confirmed by useObserverArchiveSeed/
useAgentMetricArchiveSeed test suites (18/18), incl.
test_undefined_pubkey_does_nothing and
test_explicit_choice_set_does_not_reseed.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-07-08 10:15:49 -04:00
5dce80aff5 feat(desktop): unified AgentRecord groundwork — record-first resolution + runtime materialization (Phase 1A.1) (#1618)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co>
2026-07-07 20:24:35 -07:00
d1f3194e73 fix(desktop): backfill edits for thread replies so edited replies survive refetch (#1610)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co>
2026-07-07 19:38:21 -07:00
36fd41c5ce chore(desktop): clear desktop-tauri clippy backlog (#1612)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
2026-07-07 16:49:04 -07:00
Will PflegerandGitHub 2a870f5f1f docs(readme): add Getting started section routing install paths (#1606)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
2026-07-07 17:36:08 -04:00
Will PflegerandGitHub e5f831d2c2 fix(desktop): restrict shared-agent sync to dev data dirs (#1597) 2026-07-07 17:35:15 -04:00
cc42a49799 feat(desktop): restart-required badge from spawn-time config hash (#1602)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
2026-07-07 13:53:58 -07:00
c5a541ee2d feat(desktop): boot-time reconcile of managed agents to relay events (#1601)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
2026-07-07 13:53:41 -07:00
777babf393 feat(desktop): canonical <PubKey> component — hover to view/copy full keys, owner "you" labels (#1589)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co>
2026-07-07 13:35:15 -07:00
cdf982bdb3 fix(desktop): hydrate reactions for Inbox context messages (#1596)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@sprout-oss.stage.blox.sqprod.co>
2026-07-07 12:29:56 -07:00
Will PflegerandGitHub 7f1952d7de fix: cleanup old screenshots that my agents committed (#1598) 2026-07-07 15:08:41 -04:00
75079c87ff chore(release): release Buzz Desktop version 0.3.46 (#1585)
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
v0.3.46
2026-07-07 13:05:46 -04:00
Will PflegerandGitHub a3ee2c5693 fix(desktop): preserve agent model/provider when persona snapshot fields are blank (#1583) 2026-07-07 12:49:31 -04:00
Will PflegerandGitHub 3c6c0d4478 feat(acp,desktop): identify and reap stale agent harness processes (#1582) 2026-07-07 12:49:16 -04:00
b394e95ef0 feat(desktop): active-draft badge, send-from-drafts confirm dialog, thread-deleted state (#1581)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-07-07 12:48:57 -04:00
Will PflegerandGitHub b90e80443e fix(desktop): treat baked build env vars as satisfying required agent config (#1580) 2026-07-07 12:30:31 -04:00
Will PflegerandGitHub 683f7fec1c feat(desktop): add "Copy image" to image right-click context menu (#1579) 2026-07-07 10:27:47 -06:00
dcbb3ff789 fix(nest): use buzz-dev symlink name for dev builds (#1587)
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-07-07 12:17:53 -04:00
49391d8071 fix(composer): address image-editor follow-up nits on #1491 (#1565)
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@sprout-oss.stage.blox.sqprod.co>
2026-07-07 08:38:38 -07:00
10444d248e fix(desktop): render black static boot screen (#1570)
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@sprout-oss.stage.blox.sqprod.co>
2026-07-07 08:38:00 -07:00
426f044844 feat(agents): group activity tool bursts (#1571)
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub14vtk7pvazqrq9639qu7e560wnqtl0d53ca4gjuvq6jzf3k2el23qqlwa7f <ab176f059d100602ea25073d9a69ee9817f7b691c76a897180d48498d959faa2@sprout-oss.stage.blox.sqprod.co>
2026-07-07 09:34:21 -06:00
thomaspblockandGitHub c97263901f feat(desktop): aggregated overview rail, commit detail page, and full breadcrumbs (#1573) 2026-07-07 08:29:29 -07:00
62def1459c fix(desktop): fetch profiles for reaction actors and thread-reply authors (#1550)
Signed-off-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
2026-07-07 08:19:49 -07:00
c258ffc4a8 refactor(desktop): unify EditAgentDialog styling with PersonaDialog (#1540)
Signed-off-by: npub13fn4ahfnvaa2qwylvegdgeajqs0mph6v4qsw4jcqnw4mjh3hzh2quuucm5 <8a675edd33677aa0389f6650d467b2041fb0df4ca820eacb009babb95e3715d4@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub13fn4ahfnvaa2qwylvegdgeajqs0mph6v4qsw4jcqnw4mjh3hzh2quuucm5 <8a675edd33677aa0389f6650d467b2041fb0df4ca820eacb009babb95e3715d4@sprout-oss.stage.blox.sqprod.co>
2026-07-07 16:03:39 +01:00
564ead3856 feat(desktop): add 10-minute message grouping window (#1578)
Signed-off-by: npub13fn4ahfnvaa2qwylvegdgeajqs0mph6v4qsw4jcqnw4mjh3hzh2quuucm5 <8a675edd33677aa0389f6650d467b2041fb0df4ca820eacb009babb95e3715d4@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub13fn4ahfnvaa2qwylvegdgeajqs0mph6v4qsw4jcqnw4mjh3hzh2quuucm5 <8a675edd33677aa0389f6650d467b2041fb0df4ca820eacb009babb95e3715d4@sprout-oss.stage.blox.sqprod.co>
2026-07-07 07:42:51 -07:00
d94561795a feat(desktop): unify sidebar section actions into a per-section ⋮ menu (#1577)
Signed-off-by: npub13fn4ahfnvaa2qwylvegdgeajqs0mph6v4qsw4jcqnw4mjh3hzh2quuucm5 <8a675edd33677aa0389f6650d467b2041fb0df4ca820eacb009babb95e3715d4@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub13fn4ahfnvaa2qwylvegdgeajqs0mph6v4qsw4jcqnw4mjh3hzh2quuucm5 <8a675edd33677aa0389f6650d467b2041fb0df4ca820eacb009babb95e3715d4@sprout-oss.stage.blox.sqprod.co>
2026-07-07 07:29:02 -07:00
ed84a87358 feat(desktop): emoji avatar picker for agents + reliable picker scroll (#1576)
Signed-off-by: npub13fn4ahfnvaa2qwylvegdgeajqs0mph6v4qsw4jcqnw4mjh3hzh2quuucm5 <8a675edd33677aa0389f6650d467b2041fb0df4ca820eacb009babb95e3715d4@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1n6taw59js7ztz8pt9vma9uqx6g3gcvrwg37nmx9m8lq88yla0tjqfy2ncn <9e97d750b28784b11c2b2b37d2f006d2228c306e447d3d98bb3fc07393fd7ae4@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub13fn4ahfnvaa2qwylvegdgeajqs0mph6v4qsw4jcqnw4mjh3hzh2quuucm5 <8a675edd33677aa0389f6650d467b2041fb0df4ca820eacb009babb95e3715d4@sprout-oss.stage.blox.sqprod.co>
2026-07-07 07:16:31 -07:00
1f5ba5bb27 fix(desktop): sync derived active-turn liveness in channel activity path (#1492)
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@sprout-oss.stage.blox.sqprod.co>
2026-07-07 03:59:23 +00:00