Commit Graph

159 Commits

Author SHA1 Message Date
tlongwell-block
c5ec624ebc mesh-llm: B6 kind:31990 publisher + settings-card publish-on-save
desktop/src-tauri/src/commands/mesh_llm.rs: new mesh_publish_offer
command. Reads persisted prefs and the local iroh endpoint id; on
enabled=true, builds a kind:31990 event with the JSON-serialised
MeshLlmOffer envelope and a 'd' tag matching prefs.d_tag, then signs
+ POSTs via the existing submit_event pipeline (NIP-98 to /events).

On enabled=false, publishes the *same address* with empty content —
NIP-33's 'delete by replace' idiom — so consumers know the offer has
been withdrawn. PublishOfferResult.published_offer reports which path
was taken.

desktop/src/features/settings/ui/MeshComputeSettingsCard.tsx: persist()
now follows save-prefs with a relay capability probe and (when the
relay advertises iroh_relay_url) a publish call. If the relay doesn't
support mesh-LLM, prefs are still saved locally and the UI surfaces a
specific 'this relay does not advertise iroh_relay_url' message rather
than a confusing 'publish failed'.

The user-facing flow is now: open settings -> Share compute -> toggle
on -> a kind:31990 event hits the relay, NIP-43-fanned-out to other
members. Toggling off publishes the empty-content replacement.

Tests: 208 sprout-relay, 174 sprout-core, 11 desktop mesh_llm — all
unchanged-and-pass. desktop typecheck + biome clean.

Signed-off-by: Tyler Longwell <109685178+tlongwell-block@users.noreply.github.com>
Co-authored-by: Dawn (sprout agent) <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
2026-05-19 17:06:52 -04:00
tlongwell-block
d8ca1a9c3e mesh-llm: B7 Tauri commands surface
desktop/src-tauri/src/commands/mesh_llm.rs (new):
- mesh_get_endpoint_id(app) -> { endpoint_id }: creates the persisted
  iroh keypair on first call; returns the canonical Display form of
  the public key so the UI can show 'this device' identity.
- mesh_get_sharing_prefs(app) -> ComputeSharingPrefs: reads the
  persisted prefs file (defaults applied when absent).
- mesh_set_sharing_prefs(app, prefs) -> (): atomic write-through.
- mesh_relay_iroh_url(state, relay_ws_url) -> Option<String>: probes
  the relay's NIP-11 doc for iroh_relay_url; returns None gracefully
  when the relay doesn't advertise mesh-LLM.

All four registered in lib.rs's tauri::generate_handler! block.
Frontend hooks land in C1 (avatar-menu MeshComputeSettingsCard).

Cleanup: drop wildcard re-exports from mesh_llm/mod.rs so unused
publisher/dialer helpers don't trip top-level dead-code lints before
B5/B6 are wired in.

cargo check passes; clippy + fmt clean (relay-side workspace).

Signed-off-by: Tyler Longwell <109685178+tlongwell-block@users.noreply.github.com>
Co-authored-by: Dawn (sprout agent) <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
2026-05-19 16:59:57 -04:00
tlongwell-block
000c78c203 mesh-llm: B1 NIP-11 fetcher for iroh_relay_url
desktop/src-tauri/src/mesh_llm/nip11.rs: fetch_iroh_relay_url(ws_url)
converts ws:// -> http://, GETs / with Accept: application/nostr+json,
extracts the iroh_relay_url field from the NIP-11 JSON. Returns
Ok(None) on unreachable relays / malformed responses / missing field
so mesh-LLM silently disables itself rather than producing a deploy
mystery; only returns Err for un-fixable caller mistakes (non-ws URL).

Mirrors the probe_relay_supports_nip43 helper already in
commands/pairing.rs; deliberately doesn't share code since this is a
different decode shape with different graceful-failure semantics.

desktop mesh_llm tests: 9 -> 11 (+2 nip11 helper).

Signed-off-by: Tyler Longwell <109685178+tlongwell-block@users.noreply.github.com>
Co-authored-by: Dawn (sprout agent) <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
2026-05-19 16:58:14 -04:00
tlongwell-block
1dbc89cc11 mesh-llm: offer envelope (sprout-core) + desktop building blocks
B0 — sprout-core/src/mesh_llm.rs (new): MeshLlmOffer envelope, the
content of a kind:31990 event. Schema versioned (v: u32), with
deny_unknown_fields at the top level and a freeform 'extra' Value
escape hatch. ResourceCaps + ModelOffer sub-structs. d_tag charset is
limited to [A-Za-z0-9_-] (NIP-33 stability). 9 unit tests covering
round-trip JSON, optional caps, unknown-field rejection, d_tag
validation, is_publishable rule set.

B2 — desktop/src-tauri/src/mesh_llm/endpoint.rs: persists the iroh
endpoint keypair to {app_data_dir}/mesh_iroh.key as 32 hex bytes.
Atomic write via tempfile.persist; corrupt files quarantined to
.bad.{epoch} (same pattern as identity.key). 2 unit tests.

  Design note in the module doc: we deliberately do NOT derive the
  iroh key from the Nostr key, because that would couple key rotation
  (rotating the Nostr key would silently break active offers) and
  invent a new key-custody convention. Separate file, same Tauri
  sandbox.

B3 — desktop/src-tauri/src/mesh_llm/nip98.rs: build_nip98_bearer(keys,
iroh_relay_public_url) signs a kind:27235 event with the user's Nostr
key over the canonical relay URL (sprout_auth::nip98_canonical_url
with path '/relay'), base64-encodes the event JSON. This is the exact
token the relay's iroh_relay::verify_bearer decodes + verifies.
3 unit tests.

B-offer prefs — desktop/src-tauri/src/mesh_llm/offer.rs: persisted
ComputeSharingPrefs (the avatar-menu sliders). Default is disabled,
1 concurrent consumer cap. build_offer() returns None when disabled
so callers know to *delete* any prior offer rather than re-publish.
JSON round-trip + helper tests, 4 tests.

Workspace deps added:
- desktop pulls sprout-auth (for the canonical URL helper, nostr-free
  at the API surface so the 0.36/0.37 nostr split doesn't matter).
- desktop pulls iroh-base = =1.0.0-rc.0 with the 'key' feature for
  SecretKey/PublicKey/EndpointId.
- desktop pulls thiserror = '2'.

Tests: 9 desktop mesh_llm tests pass + 9 sprout-core mesh_llm tests
pass. Workspace clippy + fmt clean (relay side; desktop has expected
dead_code warnings until B4-B6 wire these in).

Note: desktop crate requires sidecar binary stubs in
desktop/src-tauri/binaries/ to typecheck; created via the existing
'just _ensure-sidecar-stubs' helper.

Signed-off-by: Tyler Longwell <109685178+tlongwell-block@users.noreply.github.com>
Co-authored-by: Dawn (sprout agent) <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
2026-05-19 16:55:45 -04:00
Will Pfleger
50b350dc58 fix(desktop): worktree support — workspace boundary + shared identity (#610) 2026-05-18 19:11:34 -04:00
tlongwell-block
6e1418e571 feat(huddle): fix concurrent-speaker mixing + jitter buffer + protocol v2 (up to 10 peers) (#609)
Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
2026-05-18 16:34:52 -04:00
tlongwell-block
c0eb5affcf refactor(huddle): switch local TTS to Pocket TTS (Kyutai/sherpa-onnx) (#607)
Signed-off-by: Tyler Longwell <tlongwell@squareup.com>
Signed-off-by: npub1cc3ha7z055mu0rwwu7806t2wt8mj3pvu0uv5mfp2c50dahaqhczshdalg6 <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1cc3ha7z055mu0rwwu7806t2wt8mj3pvu0uv5mfp2c50dahaqhczshdalg6 <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
2026-05-18 14:28:27 -04:00
tlongwell-block
3daf8d6ae1 feat(huddle): swap STT default to Parakeet TDT-CTC 110M (EN, int8) (#562)
Signed-off-by: Tyler Longwell <109685178+tlongwell-block@users.noreply.github.com>
Signed-off-by: Tyler Longwell <tlongwell@squareup.com>
2026-05-15 22:22:05 -04:00
tlongwell-block
d1097aa91f chore(desktop): upgrade Tauri to 2.11.x to fix blank window after sleep on macOS (#600)
Signed-off-by: Tyler Longwell <109685178+tlongwell-block@users.noreply.github.com>
2026-05-15 18:59:16 -04:00
tlongwell-block
7171d4954d fix(relay,desktop): only advertise NIP-43 when enforced; probe pairing by supported_nips (#601)
Signed-off-by: Tyler Longwell <tlongwell@squareup.com>
2026-05-15 15:11:37 -04:00
tlongwell-block
32347d117c feat(desktop): per-persona and per-agent env var overrides (#594) 2026-05-15 10:43:00 -04:00
tlongwell-block
13dc0df688 fix(desktop): stop pinning agents to deprecated SPROUT_ACP_TURN_TIMEOUT (#592)
Signed-off-by: Tyler Longwell <109685178+tlongwell-block@users.noreply.github.com>
2026-05-14 21:51:38 -04:00
tlongwell-block
5cdb3062ed fix(desktop): populate member_count in get_channels so channel browser shows real counts (#548)
Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
2026-05-14 20:38:01 -04:00
tlongwell-block
9a403d3e8a fix: channel member search via NIP-50 + Typesense indexer fix for kind:0 (#569)
Signed-off-by: Tyler Longwell <109685178+tlongwell-block@users.noreply.github.com>
2026-05-13 15:03:35 -04:00
Wes
8716aefa3c fix(desktop): use resolve_command for ffmpeg discovery in sandboxed app (#568)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-13 11:00:00 -07:00
tlongwell-block
9c258e4beb feat(desktop): GUI for agent respond-to gate (owner-only / anyone / allowlist) (#557) 2026-05-13 12:48:42 -04:00
tlongwell-block
61c30add40 feat(desktop): multi-select in the paperclip file picker (#551)
Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
2026-05-12 15:01:48 -04:00
tlongwell-block
effa24f06c fix(desktop): forward cache headers in media proxy (#549)
Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
2026-05-12 14:40:07 -04:00
Wes
11778f4250 feat(desktop): image download, drag-drop prevention, and drop zone indicator (#542)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 23:26:12 +00:00
Wes
1b9f6169ee feat(desktop): channel templates — reusable project settings (#538)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 12:31:25 -07:00
tlongwell-block
e2b6e8b25a Use dedicated sprout-agent avatar (#532) 2026-05-11 17:16:08 +00:00
tlongwell-block
22f1e0b724 Launch sprout-agent from the desktop GUI (#529) 2026-05-11 12:36:53 -04:00
tlongwell-block
9e8302c35f fix: send x-auth-tag header in agent profile sync (#522) 2026-05-10 20:43:00 -04:00
tlongwell-block
90b0af136d fix: resolve media proxy relay URL dynamically per-request (#518) 2026-05-09 02:58:58 +00:00
Wes
0f10861850 feat(desktop): expand default agent toolsets with canvas, forums, dms, and member list (#510)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-08 10:10:06 -07:00
Wes
ff0806523a prompts(kit, scout): add @-mention discipline section (#506)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 06:15:42 +00:00
Wes
27bcd45cc9 Refresh built-in personas: Solo, Kit, Scout + Kit & Scout team (#499)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:22:26 +00:00
Wes
3d585dc044 fix(desktop): prevent-sleep spawn convention + expiry badge (#487)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-05 14:44:12 -07:00
tlongwell-block
d90bd768c5 fix(desktop): fetch open channels for channel browser discovery (#488) 2026-05-05 21:11:13 +00:00
Wes
ec489c5b1a feat(desktop): add keep awake while agents are active setting (#484)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-05 13:14:00 -07:00
tlongwell-block
ea62664759 post-475 fixes (#481)
Co-authored-by: Wes <wesb@block.xyz>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:41:18 -04:00
tlongwell-block
454781caae Sprout speaks Nostr. Nothing else. (#475) 2026-05-05 12:03:06 -04:00
Wes
4d0cd58d35 feat: pnpm workspace, deep links, and web repos page (#476)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-04 17:09:25 -07:00
Bradley Axen
c1063a0c92 Update onboarding flow to support membership checks and BYOK (#457) 2026-05-04 19:48:14 +00:00
tlongwell-block
8916825c45 feat(pairing): auto-detect NIP-43 relay and route target to /pair sidecar (#470) 2026-05-03 22:12:14 -04:00
Wes
e105c9ea5e feat(desktop): add relay membership admin UI in settings (#454)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-02 16:56:41 +00:00
tlongwell-block
c9f287958d feat(desktop): wire git-credential-nostr into agent spawn path (#451) 2026-05-02 11:46:49 -04:00
tlongwell-block
f23560d3d4 feat: Image & video uploads for MCP and CLI (Blossom protocol) (#433)
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
2026-04-30 14:35:02 -04:00
Bradley Axen
fcec10547d Route ACP observer traffic over relay (#421)
Signed-off-by: Tyler Longwell <tlongwell@squareup.com>
Co-authored-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
Co-authored-by: Tyler Longwell <tlongwell@squareup.com>
2026-04-30 09:34:37 -04:00
Wes
ddb242749f Fix mobile unread badges and read state sync (#422) 2026-04-29 07:44:44 -07:00
Bradley Axen
7c2c556d72 feat: Add local ACP session observer (#412) 2026-04-29 04:21:58 +00:00
Wes
2a01ca590d Implement NIP-RS unread state sync (#420)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-28 20:54:09 -07:00
tlongwell-block
d1c84a621c feat(nip-oa): Owner Attestation — cryptographic proof of agent authorization (#406) 2026-04-28 09:29:15 -04:00
Wes
a9024c2c78 Add multi-workspace support to desktop app (#409)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-28 04:47:11 +00:00
Wes
5a93403858 feat(pulse): rich text editor with @mentions, media uploads, and formatting (#407)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-27 13:57:46 -07:00
Wes
8abeb3d3ca feat: always notify on DM messages like Slack/Discord (#405)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-27 13:10:11 -07:00
Wes
480d78cb91 feat: CMD+F find-in-channel search (#400)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-24 19:15:07 +00:00
luthen-seas
ee76396d00 Fix profile settings first launch parse failure (#383)
Signed-off-by: luthen-seas <229396760+luthen-seas@users.noreply.github.com>
Co-authored-by: luthen-seas <229396760+luthen-seas@users.noreply.github.com>
2026-04-24 10:35:19 -07:00
Wes
c1a33e3ff1 feat(desktop): restore Tauri auto-updater support (#393)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-23 11:55:35 -07:00
Wes
686db1294e feat(desktop): streaming video proxy + player UX improvements (#389)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-23 09:42:44 -07:00