Commit Graph
1037 Commits
Author SHA1 Message Date
npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67dandTyler Longwell 5dfeb7fbe0 test(e2e): use private channel for cross-author search isolation
The cross-author isolation test was vacuously failing on BOTH backends:
it created an `open` channel, which is searchable by anyone by design
(get_accessible_channel_ids unions member channels with ALL open
channels), so the outsider legitimately found the author's message.

Switch the test to create_private_test_channel. In a private channel the
creator is bootstrapped as a member (so the author still finds their own
post — the non-vacuous control), while the outsider is not a member and
gets zero hits. This makes the test a true visibility-widening guard,
backend-independent by construction.

Adds create_private_test_channel / create_channel_with_visibility helpers;
create_test_channel now delegates to the open variant (no behavior change
for existing callers).

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-06-24 19:27:35 -04:00
npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgytaandnpub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d 4a771fd08c Wire Postgres search backend through chart
Co-authored-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
Signed-off-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
(cherry picked from commit 86368981635df8b2f050069827b70c7ceea0e5fd)
Co-authored-by: Max <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-06-24 19:27:35 -04:00
npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67dandTyler Longwell 5304a9b242 test(e2e): make gift-wrap-not-searchable backend-agnostic; add cross-author search isolation
test_nip17_gift_wrap_not_searchable previously queried Typesense directly to
prove kind:1059 was never indexed — meaningless on the Postgres backend, where
every event lives in the events table and there is no separate index to skip.
Rewrite it to issue a NIP-50 search and assert the relay never surfaces the
gift wrap (kind:9 control IS returned, kind:1059 is NOT). That guarantee comes
from the relay's auth gates + filters_match post-filter, which are identical
across all three backends, so the test now guards typesense/postgres/disabled.

Add test_nip50_search_cross_author_isolation: an outsider who never joined an
author's channel gets zero hits when searching that channel's exact #h + token,
while the author finds their own message — proving the channel-scope clamp in
handle_search_req (gate #1, no visibility widening) holds. Also relay-side and
backend-independent.

Compiles clean (cargo test -p buzz-test-client --test e2e_nostr_interop
--no-run); the full matrix run lands after Max's backend-flag wiring is rebased
in.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-06-24 19:27:35 -04:00
npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67dandTyler Longwell bbf125dab2 pg-fts: swap generated content_tsv column for expression GIN index
Replace the GENERATED ALWAYS ... STORED tsvector column + column-backed
GIN index with a single expression index on to_tsvector('simple', content).

Why: the expression index is maintained by Postgres on every INSERT/UPDATE
exactly like a column index (no write-path work), but avoids the stored
column's ALTER TABLE row rewrite / ACCESS EXCLUSIVE backfill — so the
migration build is online-safe on a fresh/small relay and the same-named
index (idx_events_content_fts) is pre-buildable out of band on a large
populated relay (CREATE INDEX CONCURRENTLY + ATTACH per the live-relay
runbook). IF NOT EXISTS makes the migration idempotent against that path.

The query path renders the identical to_tsvector('simple', content)
expression so the planner uses the index. Rank SQL (ts_rank_cd) is
unchanged in behavior.

- migrations/0004_search_fts.sql: single CREATE INDEX IF NOT EXISTS expr index
- schema/schema.sql: drop generated column; expr index for fresh installs
- crates/buzz-search/src/postgres.rs: query refs -> to_tsvector(...) expr
- crates/buzz-db/src/migration.rs: assertions match new shape
- crates/buzz-search/src/lib.rs, crates/buzz-relay/src/main.rs: doc wording

Tests: cargo test -p buzz-db -p buzz-search (incl. ignored PG tests):
118 passed, 0 failed.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
2026-06-24 19:27:35 -04:00
a4943e53bc spike: ts_rank_cd ordering + non-vacuous relevance test
Implements Eva's blocker-2 fix: Postgres backend now orders search
results by relevance, and the e2e test that claims to verify this
actually discriminates rank from recency.

postgres.rs
- SELECT list now includes `ts_rank_cd(content_tsv,
  plainto_tsquery('simple', $q)) AS rank` when the query has
  searchable text. The same `$q` parameter slot is reused in WHERE.
- ORDER BY rank DESC, created_at DESC when has_text; empty/"*"
  queries skip the rank column and fall back to created_at DESC
  (no needless tsquery cost).
- SearchHit.score is populated from the rank column (f32 widened
  to f64). Empty/"*" queries leave score at 0.0.

e2e_nostr_interop::test_nip50_search_relevance_order
- Redesigned to discriminate rank from recency. Previous fixture
  used "alpha bravo charlie" with msg3="alpha bravo" — plainto_tsquery
  ANDs all terms, so msg3 never matched the WHERE clause and the
  test passed trivially with one candidate (Eva caught this).
- New fixture: query "{prefix} alpha bravo"; msg1 (oldest) has
  terms adjacent (high rank); msg2 (middle) doesn't match at all;
  msg3 (newest) has terms separated by filler (lower rank).
- Asserts both msg1 and msg3 are present, then asserts events[0].id
  == id1 with no `||content.contains(...)` escape hatch.
- Discriminator is term proximity, not term frequency: Typesense's
  default _text_match does NOT reward repeated query terms (verified
  empirically — identical tm scores for "alpha bravo" vs
  "alpha alpha bravo bravo"), but BOTH backends reward adjacency.
  Proximity is the property both backends agree on.
- New `send_rest_message_at` helper pins created_at via
  `custom_created_at`. Without explicit timestamps, three back-to-back
  sends share one wall-clock second; PG falls to heap-scan order and
  masquerades as rank ordering. Spreading by 30s each makes the
  recency-only ordering deterministically put msg3 first, so a
  passing test really means rank wins.

Validation
- buzz-search lib: 30/30. buzz-relay lib: 337/337.
- NIP-50 e2e on Postgres: 4/4 (incl. relevance_order) + isolation 1/1.
- NIP-50 e2e on Typesense: 4/4 + isolation 1/1.
- Proof of discrimination: with postgres.rs reverted to
  `ORDER BY created_at DESC`, the new test FAILS on PG (msg3 first,
  as predicted). Restored ts_rank_cd ordering after.

Pre-existing failure not introduced by this commit:
test_nip17_gift_wrap_not_searchable fails on both backends — it queries
Typesense directly at events-spike-{backend}; on the PG backend that
collection is never written to (structurally expected), and the
Typesense-backend failure is the same fixture coupling Eva already
acknowledged in the prior turn. No regression vs e5869ddd/4b7c8d12.

Co-authored-by: Tyler <109685178+tlongwell-block@users.noreply.github.com>
Signed-off-by: Tyler <109685178+tlongwell-block@users.noreply.github.com>
2026-06-24 19:27:35 -04:00
a3fbd0288f spike: enforce channel_scope by construction on SearchQuery
SearchQuery::new now requires non-empty channel_ids, returning
SearchError::EmptyChannelScope otherwise. Fields are pub(crate) so
struct-literal construction outside the crate is impossible; optional
facets use #[must_use] builder methods (with_kinds/authors/since/
until/page/per_page).

Closes the type-system gap on Eva's gate-1 "no visibility widening"
invariant: the access boundary is now enforced at construction, not
just at the call sites. Both call sites (req.rs, bridge.rs) wrap
SearchQuery::new in a match — req.rs logs + breaks pagination on the
Err path, bridge.rs continues the filter loop. Upstream guards
(build_search_channel_scope_filter + the per-filter h_tag validity
check) keep the Err path unreachable in normal operation, but if a
future refactor lets an empty scope through, behavior is "no results"
not "widened search".

Also adds the missing `info!("Search backend: typesense", ...)` log
line for symmetry with the postgres/disabled branches — small
operational polish, no behavior change.

Tests: buzz-search 30/30 (+1 rejection test), buzz-relay lib 337/337,
NIP-50 e2e 5/5 on both Postgres and Typesense backends (4 NIP-50 +
test_ws_search_isolation_other_user_cannot_find_reminder).

Co-authored-by: Tyler <109685178+tlongwell-block@users.noreply.github.com>
Signed-off-by: Tyler <109685178+tlongwell-block@users.noreply.github.com>
2026-06-24 19:27:35 -04:00
npub17jjz49l9jjmhhk7cac63j8yt9z555n9cw8vk7v5jz4vzw4ppld5qgj57ccandnpub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d 4d8fe9a5e0 spike: postgres FTS backend behind BUZZ_SEARCH_BACKEND flag
Adds a Postgres full-text search backend as an alternative to Typesense for
NIP-50 search, gated behind BUZZ_SEARCH_BACKEND=typesense|postgres|disabled
(default typesense — no behavior change for existing deployments).

The replacement is structural: NIP-50 search is the only Typesense call site,
and the read path already refetches canonical events from Postgres by id, so
Typesense was just a lookup index in front of the DB that owns the data. A
generated stored tsvector column + GIN index gives the same shape with zero
write-path code change.

Changes
- migrations/0004_search_fts.sql: events.content_tsv GENERATED ALWAYS AS
  to_tsvector('simple', content) STORED, GIN index, cascades to partitions.
- crates/buzz-search: SearchBackend enum (Typesense | Postgres | Disabled),
  SearchService::with_postgres / ::disabled, postgres.rs backend impl,
  backend-neutral SearchQuery (structured kinds/authors/channel_ids/since/until;
  each backend renders its own filter).
- crates/buzz-relay/src/config.rs: BUZZ_SEARCH_BACKEND env wired with strict
  parsing (unknown value → ConfigError::InvalidValue, no silent fallback) +
  3 unit tests.
- crates/buzz-relay/src/main.rs: dispatch on backend; Postgres → with_postgres
  using db.pool(); Disabled → no-op; Typesense → existing path. ensure_collection
  only runs for the Typesense backend.
- crates/buzz-relay/src/{handlers/req.rs, api/bridge.rs}: swap to the new
  SearchService surface. Caller code shrinks — filter parts were already
  structured.
- crates/buzz-db/src/lib.rs: Db::pool() accessor for the PG backend.

Validation (against parent 2e426b2f, PG17 side-deployed):
- buzz-search lib: 29/29 pass.
- buzz-relay config tests: 11/11 (incl. 3 new).
- NIP-50 e2e on Typesense backend: 5/5 pass (regression baseline).
- NIP-50 e2e on Postgres backend: 5/5 pass — including
  test_nip50_search_relevance_order, confirming ts_rank_cd ranks correctly
  for the NIP-50 query shape and the 'simple' tokenizer config is acceptable.
- Wider e2e_nostr_interop sweep on Postgres: 19/23. The 4 failures reproduce
  identically on Typesense backend on this branch — pre-existing test-fixture
  coupling to a hard-coded 'events' collection name, not a regression.

This is additive: Typesense remains default; nothing in the existing path is
removed. Operators flip BUZZ_SEARCH_BACKEND per release to A/B/rollback.

Signed-off-by: Tyler <109685178+tlongwell-block@users.noreply.github.com>
Co-authored-by: Sami <f4a42a97e594b77bdbd8ee35191c8b28a94a4cb871d96f32921558275421fb68@sprout-oss.stage.blox.sqprod.co>
2026-06-24 19:27:35 -04:00
Will PflegerandGitHub 08d375aa2f chore(release): release Buzz Desktop version 0.3.32 (#1254) v0.3.32 2026-06-24 18:46:49 -04:00
9d3bfd38b0 fix(desktop): restore solid dot for top-level channel unreads (#1253)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-06-24 18:40:49 -04:00
ebd74d11b4 Allow explicit root posts from reply prompts (#1251)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
2026-06-24 22:38:38 +00:00
d256935c36 feat: publish personas, teams, and managed agents as relay events (#939)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
2026-06-24 22:28:25 +00:00
e993b9e741 fix(observability): gate agent observability on declared ownership, not key custody (#1229)
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@sprout-oss.stage.blox.sqprod.co>
2026-06-24 14:57:20 -07:00
a9ce477a04 fix(desktop): split AppShell notification effects (#1248)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
2026-06-24 14:51:05 -07:00
4be43d7086 feat(desktop): store nsec private keys in the OS keyring (#1172)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-06-24 17:07:34 -04:00
0482288891 fix: add evict-completed-work prompt rule and unblock desktop file-size gate (#1247)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-06-24 16:32:59 -04:00
a3e8fb6fd5 fix(desktop): scope mention/add autocomplete to reachable identities (#1243)
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-06-24 12:57:55 -07:00
09dbeb86fa test(e2e): raise scroll-history pagination test timeout to 90s (#1234)
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@sprout-oss.stage.blox.sqprod.co>
2026-06-24 12:56:22 -07:00
klopez4212andGitHub b264a32cfb Polish thread and media layout (#1239) 2026-06-24 12:55:25 -07:00
klopez4212andGitHub 092546495d Polish desktop navigation chrome (#1238) 2026-06-24 12:54:05 -07:00
2e426b2fdd fix: propagate persona harness edits to live agent instances (#1244)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-06-24 13:41:19 -04:00
45067ec135 fix(desktop): render autolinked message links as chips (#1241)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
2026-06-24 09:47:12 -07:00
733c766eba fix(desktop): clear unread projections from message read markers (#1242)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
2026-06-24 09:39:16 -07:00
86d7748ebd fix(desktop): resolve repos_dir symlink at boot before agent restore (#1231)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-06-24 11:58:48 -04:00
36d3d2ed1e Fix presence fan-out across relay pods (#1227)
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
Co-authored-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
2026-06-23 22:32:46 -04:00
Will PflegerandGitHub 142a5c9095 fix(relay): raise grace limit, add replay backpressure, and NOTICE on oversized frames (#1226) 2026-06-23 20:26:54 -04:00
WesandGitHub 38a9533439 [codex] Make relay frame limit configurable (#1225) 2026-06-23 17:18:55 -07:00
WesandGitHub 3e91ce274e chore(release): release Buzz Desktop version 0.3.31 (#1223) v0.3.31 2026-06-23 15:49:04 -07:00
549b7d2481 fix(release): publish versioned relay Docker tags via independent release lanes (#1173)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-06-23 18:35:30 -04:00
thomaspblockandGitHub 6ad68a6b09 fix(desktop): align settings section headers (#1165)
Signed-off-by: Thomas Petersen <thomasp@squareup.com>
2026-06-23 15:32:38 -07:00
1011cea268 fix(desktop): ground agent workspace, migrate legacy nest, configurable repos_dir (#1194)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-06-23 18:30:12 -04:00
fa1262a92c fix(desktop): enable mesh llm for release builds (#1221)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
2026-06-23 15:10:36 -07:00
Will PflegerandGitHub e35e84b08b fix(desktop): move crypto commands off the main thread (#1222) 2026-06-23 18:02:24 -04:00
c58e9880bf fix: tolerate missing private_key_nsec in agent store (#1220)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-06-23 17:55:13 -04:00
6b5cf325c2 Update navigation header height (#1212)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
2026-06-23 14:40:38 -07:00
klopez4212andGitHub 5130a6a0b6 Improve global search (#1195) 2026-06-23 14:31:06 -07:00
65ccb1262f Parse Typesense multi_search errors (#1208)
Signed-off-by: npub1t2tgm7d8f995uqvmnm8h88sg3wnpp9a5xysjf6dg3tjmgt3ltulqdp8ehr <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1t2tgm7d8f995uqvmnm8h88sg3wnpp9a5xysjf6dg3tjmgt3ltulqdp8ehr <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@sprout-oss.stage.blox.sqprod.co>
2026-06-23 14:16:15 -07:00
89ff950444 fix(desktop): keep settings shortcut from opening search (#1204)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
2026-06-23 14:15:44 -07:00
klopez4212andGitHub c0a872e898 Polish sidebar channel navigation (#1213) 2026-06-23 14:15:04 -07:00
89aaa26443 fix(desktop): restore channel unread badges (#1218)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
2026-06-23 13:59:21 -07:00
thomaspblockandGitHub b4e75a1e41 Fix collapsed home header chrome overlap (#1215)
Signed-off-by: Thomas Petersen <thomasp@squareup.com>
2026-06-23 13:45:57 -07:00
2a522826ed fix(desktop): dedupe welcome intro per channel (#1216)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
2026-06-23 12:47:11 -07:00
bee2d64cf7 fix(desktop): defer agent page secondary requests (#1217)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
2026-06-23 12:46:47 -07:00
3ef2a8e5c7 ci(release): enable Tauri auto-updater on Windows and Linux builds (#1206)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-06-23 15:34:11 -04:00
ed556f3deb Hydrate reactions for rendered messages (#1205)
Signed-off-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co>
2026-06-23 13:39:01 -04:00
40070a5855 fix(desktop): show NIP-OA owners in profile pane (#1198)
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
2026-06-23 09:07:50 -07:00
29978b6f93 fix(desktop): preserve login-shell PATH for managed agents (#1193)
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
Co-authored-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
2026-06-23 11:58:25 -04:00
b3b0704efb Fix nav chrome offset in fullscreen (#1192)
Signed-off-by: npub1t2tgm7d8f995uqvmnm8h88sg3wnpp9a5xysjf6dg3tjmgt3ltulqdp8ehr <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1t2tgm7d8f995uqvmnm8h88sg3wnpp9a5xysjf6dg3tjmgt3ltulqdp8ehr <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@sprout-oss.stage.blox.sqprod.co>
2026-06-23 10:58:02 -04:00
c0858dac12 fix(desktop): show due-reminder count in the Inbox nav badge (#1191)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-06-23 10:46:18 -04:00
Will PflegerandGitHub 45eae7c0ec chore(release): release version 0.3.30 (#1190) v0.3.30 2026-06-23 10:02:52 -04:00
ce994df74e fix(desktop): collapse mark-read/unread menu into one toggling item (#1188)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
2026-06-22 23:24:58 -04:00