mirror of
https://github.com/block/buzz.git
synced 2026-11-04 00:12:02 +00:00
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:
@@ -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 |
|
||||
|
||||
Reference in New Issue
Block a user