docs(cli-skill): update skill file to match CLI parity changes

Brings the agent skill file to parity with all 62 CLI subcommands
across 13 command groups after PR #612's output normalization and bug
fixes. Adds 5 missing command groups (social, repos, upload, mem,
pack), 5 missing subcommands in existing groups (channels update/
add-member/remove-member, workflows update/delete), missing flags
(--file, --mention, --kinds, --depth-limit, --limit), fixes output
contract inaccuracies (channels get pubkey field, workflows list
pubkey, exit code 5, feed description), and restructures the Quick
Reference table by output pattern for scannability.
This commit is contained in:
Will Pfleger
2026-05-21 12:12:34 -04:00
parent 3474e1e5f0
commit bcb8279f34

View File

@@ -2,12 +2,12 @@
name: sprout-cli
description: >
Use the Sprout CLI (`sprout` command) to interact with a Sprout relay: send
and read messages in channels, post threaded replies, manage channels
(create, list, join, leave, archive), set canvas documents, add reactions,
open direct messages, query user profiles and presence, trigger and approve
workflows, search messages, post code diffs, and manage repositories.
Activate when the task involves messaging, channels, feeds, DMs, reactions,
workflows, or any Sprout relay operation via the `sprout` command.
and read messages, manage channels, set canvas documents, add reactions,
open DMs, query user profiles, trigger workflows, search messages, post code
diffs, manage repositories, publish social notes, upload files, and manage
persistent agent memory. Activate when the task involves messaging, channels,
feeds, DMs, reactions, workflows, social notes, repos, uploads, agent memory,
or any Sprout relay operation via the `sprout` command.
version: 1
---
@@ -19,9 +19,9 @@ version: 1
`SPROUT_RELAY_URL` defaults to `http://localhost:3000`. Override only if explicitly instructed.
All output is JSON on stdout. Commands that return lists return JSON arrays; commands that return a single resource return a JSON object.
All output is JSON on stdout unless noted otherwise. Commands that return lists return JSON arrays; commands that return a single resource return a JSON object. Exceptions: `canvas get` returns a raw markdown string (not JSON); `mem get`/`mem hash` write raw values to stdout; `pack inspect` outputs human-readable text; `social` and `repos` commands return raw Nostr event JSON (includes `sig` and relay-specific fields — not the normalized format used by `messages`, `channels`, etc.).
Errors go to stderr as `{"error": "<category>", "message": "<detail>"}`. Category values: `user_error` (exit 1), `relay_error` / `network_error` (exit 2), `auth_error` / `key_error` (exit 3), `error` (exit 4). On non-zero exit, parse stderr for the error message before retrying or escalating.
Errors go to stderr as `{"error": "<category>", "message": "<detail>"}`. Category values: `user_error` (exit 1), `relay_error` / `network_error` (exit 2), `auth_error` / `key_error` (exit 3), `error` (exit 4), `conflict` (exit 5 — write conflict, relay rejected as superseded). On non-zero exit, parse stderr for the error message before retrying or escalating.
## Parameter Conventions
@@ -46,24 +46,50 @@ Send a threaded reply:
sprout messages send --channel <UUID> --content "reply text" --reply-to <event-id>
```
Read recent messages (returns array, newest messages at the end when no `--since`):
Send a forum post (kind 45001) or forum comment (kind 45003):
```bash
sprout messages send --channel <UUID> --content "post title" --kind 45001
sprout messages send --channel <UUID> --content "comment" --kind 45003 --reply-to <event-id>
```
`--kind` routing: omitted or `9` sends a stream message; `45001` sends a forum post; `45003` sends a forum comment (requires `--reply-to`). Other kinds are rejected.
Attach files (uploads to Blossom, includes as imeta tags):
```bash
sprout messages send --channel <UUID> --content "see attached" --file /path/to/image.png
```
Explicitly mention users by pubkey (in addition to @name auto-resolution from message body):
```bash
sprout messages send --channel <UUID> --content "cc @alice" --mention <hex-pubkey>
```
`--file` and `--mention` are repeatable.
Read recent messages (default kinds: `[9, 40002, 40008, 45001, 45003]`):
```bash
sprout messages get --channel <UUID> --limit 20
sprout messages get --channel <UUID> --limit 50 --since 1716000000
sprout messages get --channel <UUID> --limit 50 --before 1716050000
sprout messages get --channel <UUID> --kinds "1,1984" # override default kinds
```
Get a thread rooted at a specific event:
```bash
sprout messages thread --channel <UUID> --event <event-id>
sprout messages thread --channel <UUID> --event <event-id> --limit 100 --depth-limit 5
```
Full-text search across all channels you can access:
```bash
sprout messages search --query "architecture decision"
sprout messages search --query "deploy" --limit 50
```
Send a code diff with repository metadata (pipe the diff via stdin):
@@ -112,6 +138,7 @@ Create a channel:
```bash
sprout channels create --name "eng-backend" --type stream --visibility open
sprout channels create --name "rfcs" --type forum --visibility open --description "Architecture RFCs"
```
Returns `{event_id, channel_id, accepted, message}`. Use `channel_id` for subsequent operations.
@@ -122,6 +149,14 @@ Get channel details:
sprout channels get --channel <UUID>
```
Returns `{channel_id, name, description, created_at, pubkey}`, or `null` if not found.
Update channel metadata:
```bash
sprout channels update --channel <UUID> --name "new-name" --description "new description"
```
Join or leave:
```bash
@@ -142,7 +177,16 @@ List members:
sprout channels members --channel <UUID>
```
Returns `[{pubkey, role}]`.
Returns `[{pubkey, role}]`. Roles: `owner`, `admin`, `member`, `guest`, `bot`.
Manage members:
```bash
sprout channels add-member --channel <UUID> --pubkey <hex> --role member
sprout channels remove-member --channel <UUID> --pubkey <hex>
```
`--role` is optional (defaults to `member`). Valid roles: `owner`, `admin`, `member`, `guest`, `bot`.
Admin operations (require `admin:channels` scope):
@@ -154,7 +198,7 @@ sprout channels delete --channel <UUID>
## Canvas
Get the canvas document for a channel (returns the markdown content string directly, or `null` if no canvas is set):
Get the canvas document for a channel (returns the markdown content string directly, or `null` if no canvas is set — this is NOT a JSON envelope):
```bash
sprout canvas get --channel <UUID>
@@ -195,6 +239,7 @@ List existing DM conversations:
```bash
sprout dms list
sprout dms list --limit 10
```
Returns `[{dm_id, participants, created_at}]`.
@@ -203,6 +248,7 @@ Open a new DM (creates a group DM conversation):
```bash
sprout dms open --pubkey <hex-pubkey>
sprout dms open --pubkey <hex1> --pubkey <hex2> # group DM (up to 8)
```
Returns `{event_id, dm_id, accepted, message}`. Use `dm_id` as the `--channel` value for subsequent `messages` commands.
@@ -273,7 +319,7 @@ List workflows for a channel:
sprout workflows list --channel <UUID>
```
Returns `[{workflow_id, content, created_at}]`.
Returns `[{workflow_id, content, created_at, pubkey}]`.
Get a specific workflow definition:
@@ -292,6 +338,18 @@ cat workflow.yaml | sprout workflows create --channel <UUID> --yaml -
Returns `{event_id, workflow_id, accepted, message}`.
Update a workflow (requires both `--channel` and `--workflow`):
```bash
sprout workflows update --channel <UUID> --workflow <UUID> --yaml "name: updated\nsteps: ..."
```
Delete a workflow:
```bash
sprout workflows delete --workflow <UUID>
```
Trigger a workflow:
```bash
@@ -309,19 +367,20 @@ Get run history for a workflow:
```bash
sprout workflows runs --workflow <UUID>
sprout workflows runs --workflow <UUID> --limit 10
```
Returns `[{event_id, kind, content, created_at, tags}]`. Note: currently returns empty results because run history is stored in the database rather than as Nostr events.
## Feed
Get your activity feed (mentions, needs-action items, recent channel activity):
Get your activity feed (mentions of your pubkey):
```bash
sprout feed get --limit 20
```
Returns events sorted newest-first.
Returns events sorted newest-first (descending `created_at`). This is the only list command that sorts newest-first; all others sort oldest-first.
Poll for recent activity since a timestamp:
@@ -329,6 +388,149 @@ Poll for recent activity since a timestamp:
sprout feed get --since 1716000000 --limit 50
```
## Social
Nostr social protocol commands (NIP-01, NIP-02, NIP-51/NIP-65). These commands return **raw Nostr event JSON** including `sig` and all relay fields — not the normalized format used by `messages`, `channels`, etc.
Publish a text note (kind:1):
```bash
sprout social publish --content "Hello world"
sprout social publish --content "reply text" --reply-to <event-id>
```
Set your contact list (kind:3):
```bash
sprout social set-contacts --contacts '[{"pubkey":"<hex>","relay_url":"","petname":"alice"}]'
```
Get a single event by ID:
```bash
sprout social event --event <hex-event-id>
```
Get a user's recent notes:
```bash
sprout social notes --pubkey <hex> --limit 20
sprout social notes --pubkey <hex> --limit 20 --before 1716050000
```
Get a user's contact list:
```bash
sprout social contacts --pubkey <hex>
```
Publish a NIP-51/NIP-65 social list (supported kinds: 10000, 10001, 10002, 10003, 30000, 30003):
```bash
sprout social set-list --kind 10002 --tags '[["r","wss://relay.example.com"]]'
```
Read a user's social lists by kind:
```bash
sprout social list --pubkey <hex> --kind 10002
sprout social list --pubkey <hex> --kind 30000 --d-tag "friends"
```
## Repos
Git repository announcements (NIP-34 kind:30617). Returns raw Nostr event JSON.
Create a repository announcement:
```bash
sprout repos create --id "my-repo" --name "My Repo" --description "A project" --clone https://github.com/org/repo.git
```
`--clone`, `--web`, and `--nostr-relay` flags are optional; `--clone` is repeatable.
Get a repository:
```bash
sprout repos get --id "my-repo"
sprout repos get --id "my-repo" --owner <hex-pubkey>
```
List repositories:
```bash
sprout repos list
sprout repos list --owner <hex-pubkey> --limit 10
```
## Upload
Upload a file to the relay's Blossom store:
```bash
sprout upload file --file /path/to/image.png
```
Returns a pretty-printed (multi-line) JSON `BlobDescriptor`: `{url, sha256, size, type, uploaded}`. Optional fields: `dim`, `blurhash`, `thumb`, `duration`.
## Mem (Agent Memory)
Persistent agent memory (NIP-AE engrams). Progress messages go to stderr; data goes to stdout. Exit code 5 on write conflicts.
List memory entries:
```bash
sprout mem ls # tab-delimited: slug, created_at, event_id
sprout mem ls --json # JSON array: [{slug, event_id, created_at}]
```
Read a memory value (raw bytes to stdout, no trailing newline):
```bash
sprout mem get <slug>
```
Get the SHA-256 hash of a value (use as `--base-hash` for safe patching):
```bash
sprout mem hash <slug>
```
Set a memory value:
```bash
sprout mem set <slug> "value"
echo "value" | sprout mem set <slug> - # read from stdin
sprout mem set <slug> - --allow-empty # allow empty stdin
```
Patch a memory value with a unified diff (safer than `set` for concurrent access):
```bash
sprout mem hash <slug> # get base hash first
diff -u old.txt new.txt | sprout mem patch <slug> --base-hash <hex>
sprout mem patch <slug> --patch-file changes.patch --base-hash <hex>
sprout mem patch <slug> --no-base-hash # skip hash check (unsafe)
sprout mem patch <slug> --base-hash <hex> --dry-run # preview without writing
```
Delete (tombstone) a memory entry:
```bash
sprout mem rm <slug>
```
The `core` slug cannot be deleted.
## Pack (Local-Only)
Persona pack operations. No relay connection or `--private-key` needed.
```bash
sprout pack validate /path/to/pack # validate pack directory structure
sprout pack inspect /path/to/pack # show pack metadata (human-readable text, not JSON)
```
## Polling Pattern
The Sprout relay has no push or webhook support. Poll with `--since` and sleep between iterations.
@@ -346,23 +548,76 @@ Use shorter intervals (10s) when latency matters; longer intervals (30s) for bac
## Quick Reference
Most write commands return `{event_id, accepted, message}`. Exceptions noted below.
**Read commands:**
| Command | Required Flags | Returns |
|---------|---------------|---------|
| `messages send` | `--channel`, `--content` | `{event_id, ...}` |
| `messages get` | `--channel` | array of message objects |
| `messages thread` | `--channel`, `--event` | array of thread events |
| `messages search` | `--query` | array of matching messages |
| `messages send-diff` | `--channel`, `--diff`, `--repo`, `--commit` | `{event_id, ...}` |
| `messages get` | `--channel` | `[{id, pubkey, kind, content, created_at, tags}]` |
| `messages thread` | `--channel`, `--event` | `[{id, pubkey, kind, content, created_at, tags}]` |
| `messages search` | `--query` | `[{id, pubkey, kind, content, created_at, tags}]` |
| `channels list` | — | `[{channel_id, name, description, created_at}]` |
| `channels create` | `--name`, `--type`, `--visibility` | `{event_id, channel_id, accepted, message}` |
| `channels join` | `--channel` | `{event_id, accepted, message}` |
| `channels get` | `--channel` | `{channel_id, name, description, created_at, pubkey}` or `null` |
| `channels members` | `--channel` | `[{pubkey, role}]` |
| `canvas get` | `--channel` | markdown string or `null` |
| `canvas set` | `--channel`, `--content` | `{event_id, accepted, message}` |
| `reactions add` | `--event`, `--emoji` | `{event_id, accepted, message}` |
| `reactions get` | `--event` | `{"reactions": [{emoji, count, pubkeys}]}` |
| `dms list` | — | `[{dm_id, participants, created_at}]` |
| `dms open` | `--pubkey` | `{event_id, dm_id, accepted, message}` |
| `users get` | — | `[{display_name, about, picture, pubkey, ...}]` |
| `workflows list` | `--channel` | `[{workflow_id, content, created_at}]` |
| `feed get` | — | array of feed events, newest-first |
| `users presence` | `--pubkeys` | `[{pubkey, status, updated_at}]` |
| `workflows list` | `--channel` | `[{workflow_id, content, created_at, pubkey}]` |
| `workflows get` | `--workflow` | `{workflow_id, content, created_at, pubkey}` or `null` |
| `workflows runs` | `--workflow` | `[{event_id, kind, content, created_at, tags}]` |
| `feed get` | — | event array, newest-first |
**Write commands** (all return `{event_id, accepted, message}` unless noted):
| Command | Required Flags | Notes |
|---------|---------------|-------|
| `messages send` | `--channel`, `--content` | |
| `messages send-diff` | `--channel`, `--diff`, `--repo`, `--commit` | |
| `messages edit` | `--event`, `--content` | |
| `messages delete` | `--event` | |
| `messages vote` | `--event`, `--direction` | |
| `channels create` | `--name`, `--type`, `--visibility` | adds `channel_id` |
| `channels update/join/leave/topic/purpose` | `--channel` (+ value flag) | |
| `channels add-member/remove-member` | `--channel`, `--pubkey` | |
| `channels archive/unarchive/delete` | `--channel` | |
| `canvas set` | `--channel`, `--content` | |
| `reactions add/remove` | `--event`, `--emoji` | |
| `dms open` | `--pubkey` | adds `dm_id` |
| `dms add-member` | `--channel`, `--pubkey` | |
| `users set-profile` | one of `--name`/`--avatar`/`--about`/`--nip05` | |
| `workflows create` | `--channel`, `--yaml` | adds `workflow_id` |
| `workflows update` | `--channel`, `--workflow`, `--yaml` | |
| `workflows delete/trigger` | `--workflow` | |
| `workflows approve` | `--token` | |
| `social publish` | `--content` | |
| `social set-contacts` | `--contacts` | |
**Raw output commands** (return unprocessed Nostr event JSON including `sig`):
| Command | Required Flags |
|---------|---------------|
| `social event` | `--event` |
| `social notes` | `--pubkey` |
| `social contacts` | `--pubkey` |
| `social set-list` | `--kind`, `--tags` |
| `social list` | `--pubkey`, `--kind` |
| `repos create` | `--id` |
| `repos get` | `--id` |
| `repos list` | — |
**Other output formats:**
| Command | Required Flags | Returns |
|---------|---------------|---------|
| `upload file` | `--file` | `{url, sha256, size, type, uploaded}` (pretty-printed) |
| `mem ls` | — | tab-delimited lines or `--json` array |
| `mem get` | `<slug>` | raw value (stdout, no newline) |
| `mem hash` | `<slug>` | SHA-256 hex string |
| `mem set` | `<slug>`, `<value>` | stderr progress only |
| `mem patch` | `<slug>`, `--base-hash` or `--no-base-hash` | stderr progress only |
| `mem rm` | `<slug>` | stderr progress only |
| `pack validate` | `<path>` | "Valid." or errors |
| `pack inspect` | `<path>` | human-readable text |