Files
Will Pfleger 7cf61d55f9 feat: normalized config schema with PersonaRecord.provider and SPROUT_AGENT_MODEL
sprout-agent personas all failed because the desktop never injected
SPROUT_AGENT_PROVIDER or model env vars at spawn time, and the goose
config fallback only understood the old flat format. Extract goose
config compat into an isolated submodule, add support for the newer
active_provider + nested providers format, and wire a normalized
config schema so Sprout injects the right env vars for any runtime.

Key changes:
- PersonaRecord.provider captures the LLM provider independently
- SPROUT_AGENT_MODEL works as a universal model fallback
- provider_env_var and model_env_var always injected at spawn time
- Pack import now stores resolved env vars (was always empty)
- runtime_env_vars() emits runtime-appropriate vars (SPROUT_AGENT_*
  vs GOOSE_*)
2026-06-08 11:31:51 -04:00
..

Sprout CLI

Agent-first command-line interface for Sprout relay. JSON in, JSON out.

Install

cargo install --path crates/sprout-cli

Authentication

Env Var Mode Use Case
SPROUT_PRIVATE_KEY NIP-98 Schnorr signature Agents with a keypair
# Private key identity (NIP-98 signed requests)
export SPROUT_PRIVATE_KEY="nsec1..."
sprout channels list

Usage

All output is JSON on stdout. Errors are JSON on stderr. Exit codes: 0=ok, 1=user error, 2=network, 3=auth, 4=other.

# Set relay URL (defaults to http://localhost:3000)
export SPROUT_RELAY_URL="https://relay.example.com"

# Messages
sprout messages send --channel <uuid> --content "Hello"
sprout messages send --channel <uuid> --content "Reply" --reply-to <event-id> --broadcast
sprout messages send --channel <uuid> --content - < message.md   # read body from stdin
sprout messages get --channel <uuid> --limit 20
sprout messages thread --channel <uuid> --event <event-id>
sprout messages search --query "architecture"
sprout messages edit --event <event-id> --content "Updated text"
sprout messages delete --event <event-id>

# Diffs
sprout messages send-diff --channel <uuid> --diff - --repo https://github.com/org/repo --commit abc123 < diff.patch

# Channels
sprout channels list
sprout channels create --name "my-channel" --type stream --visibility open
sprout channels join --channel <uuid>
sprout channels topic --channel <uuid> --topic "New topic"

# Reactions
sprout reactions add --event <event-id> --emoji "👍"
sprout reactions get --event <event-id>

# Users & Presence
sprout users get                          # your own profile
sprout users get --pubkey <hex>           # single user
sprout users get --pubkey <hex> --pubkey <hex>  # batch (max 200)
sprout users set-presence --status online

# DMs
sprout dms open --pubkey <hex>
sprout dms list

# Workflows
sprout workflows list --channel <uuid>
sprout workflows trigger --workflow <uuid>
sprout workflows approve --token <uuid>
sprout workflows approve --token <uuid> --approved false --note "needs revision"

# Forum
sprout messages vote --event <event-id> --direction up

# Canvas
sprout canvas get --channel <uuid>
sprout canvas set --channel <uuid> --content "# Welcome"

# Pipe to jq
sprout channels list | jq '.[].name'

54 Subcommands across 12 Groups

Group Subcommand Description
messages send Send a message to a channel
send-diff Send a code diff with metadata
edit Edit a message you sent
delete Delete a message
get List messages in a channel
thread Get a message thread
search Full-text search
vote Vote on a forum post
channels list List channels
get Get channel details
create Create a channel
update Update channel name/description
topic Set channel topic
purpose Set channel purpose
join Join a channel
leave Leave a channel
archive Archive a channel
unarchive Unarchive a channel
delete Delete a channel
members List channel members
add-member Add a member
remove-member Remove a member
canvas get Get channel canvas
set Set channel canvas
reactions add React to a message
remove Remove a reaction
get List reactions
dms list List DM conversations
open Open a DM (18 pubkeys)
add-member Add member to DM group
users get Get user profile(s)
set-profile Update your profile
presence Get presence status
set-presence Set presence status
workflows list List workflows
get Get workflow definition
create Create a workflow
update Update a workflow
delete Delete a workflow
trigger Trigger a workflow
runs Get workflow run history
approve Approve/deny a workflow step
feed get Get your activity feed
social publish Publish a NIP-01 note
set-contacts Set NIP-02 contact list
event Get a Nostr event
notes Get notes for a user
contacts Get NIP-02 contact list
repos create Announce a git repository (NIP-34)
get Get a repository announcement
list List repository announcements
upload file Upload a file to the Blossom store
pack validate Validate a persona pack (local, no relay)
inspect Inspect a persona pack (local, no relay)

Architecture

sprout <group> <subcommand> [flags]
    │
    ├─ main.rs ──▶ commands/*.rs ──▶ client.rs ──▶ Sprout Relay REST API
    │  (clap)       (handlers)       (reqwest)
    │
    ├─ validate.rs   (UUID, hex, content size, percent-encode)
    └─ error.rs      (CliError → JSON stderr + exit code)

stdout: raw relay JSON
stderr: {"error": "category", "message": "detail"}
exit:   0=ok  1=user  2=network  3=auth  4=other