Files
buzz/desktop/src-tauri/Cargo.toml
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

81 lines
2.3 KiB
TOML

[workspace]
[package]
name = "sprout"
version = "0.1.0"
description = "Sprout desktop app"
authors = ["you"]
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
# The `_lib` suffix may seem redundant but it is necessary
# to make the lib name unique and wouldn't conflict with the bin name.
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
name = "sprout_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]
tauri-build = { version = "2", features = [] }
[target.'cfg(unix)'.dependencies]
libc = "0.2"
[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.61", features = ["Win32_Storage_FileSystem"] }
[dependencies]
atomic-write-file = "0.3"
dirs = "6"
tauri = { version = "2", features = [] }
tauri-plugin-deep-link = "2"
tauri-plugin-opener = "2"
tauri-plugin-single-instance = { version = "2", features = ["deep-link"] }
tauri-plugin-window-state = "2"
tauri-plugin-websocket = "2"
tauri-plugin-dialog = "2"
tauri-plugin-updater = "2"
tauri-plugin-process = "2"
infer = "0.19"
hex = "0.4"
tokio = { version = "1", features = ["fs", "sync", "rt", "macros", "time"] }
tokio-tungstenite = { version = "0.29", features = ["rustls-tls-webpki-roots"] }
tokio-util = { version = "0.7", features = ["rt"] }
futures-util = "0.3"
opus = "0.3"
neteq = { version = "0.8", default-features = false }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
nostr = { version = "0.37", features = ["nip44"] }
nostr-compat = { package = "nostr", version = "0.36" }
zeroize = "1"
reqwest = { version = "0.13", features = ["json", "query", "stream"] }
url = "2"
sprout-auth = { path = "../../crates/sprout-auth" }
sprout-core = { path = "../../crates/sprout-core" }
sprout-persona = { path = "../../crates/sprout-persona" }
sprout-sdk = { path = "../../crates/sprout-sdk" }
iroh-base = { version = "=1.0.0-rc.0", features = ["key"] }
base64 = "0.22"
sha2 = "0.11"
tar = "0.4"
bzip2 = "0.5"
chrono = { version = "0.4", features = ["serde"] }
tauri-plugin-global-shortcut = "2"
tauri-plugin-notification = "2.3.3"
uuid = { version = "1", features = ["v4"] }
png = "0.18"
zip = "2"
sherpa-onnx = "1.12"
regex = "1"
axum = "0.8"
rodio = "0.22"
earshot = "1.0"
rubato = "2.0"
audioadapter-buffers = "3.0"
tempfile = "3"
thiserror = "2"
[dev-dependencies]