{"owner":"block","repo":"buzz","hasSkills":true,"totalSkillsCount":5,"totalTokensCount":4382,"categories":["root-instruction","claude-rule","mcp-config","marketplace","plugin-manifest"],"hasMcp":true,"mcpConfig":{"mcpServers":{"buzz":{"command":"npx","args":["-y","@modelcontextprotocol/server-buzz"]}}},"found":["AGENTS.md","CLAUDE.md",".cursor/mcp.json",".claude-plugin/marketplace.json",".claude-plugin/plugin.json"],"skills":{"AGENTS.md":"# AGENTS.md — AI Agent Contributor Guide\n\nThis guide is for AI agents contributing to the Sprout codebase. It covers\nagent-specific context and conventions. For general contributor info (setup,\ncode style, PR process, architecture), see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n---\n\n## Repo Structure\n\n```\ncrates/\n  sprout-relay        # WebSocket relay server — main entry point\n  sprout-core         # Core types, event verification, filter matching\n  sprout-db           # Postgres event store and data access layer\n  sprout-auth         # Authentication and authorization\n  sprout-pubsub       # Redis pub/sub fan-out, presence, typing indicators\n  sprout-mcp          # MCP server providing AI agent tools\n  sprout-acp          # ACP harness bridging Sprout events to AI agents\n  sprout-workflow     # YAML-as-code workflow engine (evalexpr conditions)\n  sprout-search       # Typesense-backed full-text search\n  sprout-audit        # Hash-chain audit log\n  sprout-huddle       # LiveKit audio/video integration\n  sprout-proxy        # Nostr client compatibility proxy\n  sprout-admin        # Operator CLI for relay administration\n  sprout-test-client  # Integration test client and E2E test suite\n  sprout-sdk          # Typed Nostr event builders (used by sprout-mcp and sprout-cli)\n  sprout-media        # Blossom/S3 media storage\n  sprout-cli          # Agent-first CLI\n\ndesktop/              # Tauri 2 + React 19 desktop app\nmigrations/           # SQL migrations (auto-applied on relay startup)\nscripts/              # Dev tooling\n.env.example          # Config template — copy to .env before running\n```\n\n---\n\n## Getting Started\n\n```bash\n. ./bin/activate-hermit   # activate hermit toolchain (Rust, Node, etc.)\ncp .env.example .env      # configure local environment\njust setup                # install deps, run migrations\njust relay                # start relay at ws://localhost:3000\njust ci                   # run before any PR\n```\n\nSee CONTRIBUTING.md for full setup details and dependency requirements.\n\n---\n\n## Quality Gates\n\nRun `just ci` before every PR. It runs: Rust `fmt` + `clippy`, desktop lint\n(Biome), unit tests, desktop build, and Tauri check. All must pass.\n\nRun `just test` for integration tests if you touched `sprout-relay`,\n`sprout-db`, or `sprout-auth` — these require a running Postgres and Redis.\n\nAdditional rules:\n- No `unsafe` code\n- Do not introduce new `unwrap()` or `expect()` in production paths — use `?` and proper error types\n- New public API must have doc comments\n\n---\n\n## Key Patterns\n\n**Dual API surface**: Sprout exposes both a REST API and a NIP-29 WebSocket\nrelay. Both paths converge on shared DB functions in `sprout-db`. When adding\na feature, implement the shared DB logic first, then wire up both surfaces.\n\n**Event kinds**: All event kind integers are defined in\n`sprout-core/src/kind.rs`. New features get new kind integers — add them here\nfirst, then implement handling in the relay.\n\n**Channel scoping**: Channels use `h` tags (NIP-29 group tag), not `e` tags.\nFilters and queries must scope to `h` tags when operating within a channel.\n\n**MCP tools — dual transport**: The MCP server in `sprout-mcp` uses two\npatterns: write operations send signed Nostr events over WebSocket; read\noperations call REST endpoints (see `relay_client.rs` for the HTTP helpers).\nAdd the REST endpoint or event handler first, then add the MCP tool that calls\nit. Do not implement logic directly in MCP handlers.\n\n**Workflow conditions**: `sprout-workflow` uses\n[evalexpr](https://docs.rs/evalexpr) for condition evaluation. Keep expressions\nsimple and testable.\n\n**Thread counters**: `reply_count` and `descendant_count` are materialized on\nthread root events. Any code that inserts replies must update these counters —\ncheck existing reply handlers for the pattern.\n\n---\n\n## Testing\n\n```bash\njust test-unit    # unit tests, no infrastructure needed\njust test         # full integration suite (requires Postgres + Redis)\n```\n\nE2E tests live in `crates/sprout-test-client/tests/`:\n- `e2e_relay.rs` — WebSocket relay protocol\n- `e2e_rest_api.rs` — REST endpoint coverage\n- `e2e_mcp.rs` — MCP tool surface\n- `e2e_tokens.rs` — auth token flows\n- `e2e_workflows.rs` — workflow engine\n- `e2e_media.rs` — media upload/download (Blossom)\n- `e2e_media_extended.rs` — extended media scenarios\n- `e2e_nostr_interop.rs` — Nostr interop (NIP-50 search, NIP-10 threads, NIP-17 gift wraps)\n\nDesktop E2E: `cd desktop && pnpm exec playwright test`\n\nSee [TESTING.md](TESTING.md) for the full multi-agent E2E guide.\n\n---\n\n## Desktop App\n\nThe desktop app is Tauri 2 + React 19 + Vite + Tailwind CSS. Features are\norganized under `desktop/src/features/`. Biome handles linting and formatting.\n\n```bash\njust desktop-dev   # web-only dev server (faster iteration)\njust desktop-app   # full Tauri app with native shell\n```\n\n---\n\n## Mobile App (Flutter)\n\nThe mobile app lives in `mobile/` — a Flutter app using Riverpod + Hooks.\n\n### Architecture\n\n- **State management:** Riverpod + `flutter_hooks` (`HookConsumerWidget`)\n- **Theme:** Catppuccin Latte (light) / Macchiato (dark) — matches desktop\n- **Features:** Isolated under `lib/features/`, shared code in `lib/shared/`\n- **Nostr models:** `lib/shared/relay/nostr_models.dart` — event kinds must\n  stay in sync with `desktop/src/shared/constants/kinds.ts`\n\n### Rules\n\n- **NEVER use `StatefulWidget`** — always use `HookConsumerWidget` or\n  `ConsumerWidget` with `flutter_hooks` for local state.\n- **NEVER run `flutter run`, `flutter build`, `flutter clean`, or\n  `flutter upgrade`** — only `flutter test`, `flutter analyze`, and\n  `dart format` are safe for agents to run.\n- **Do NOT use `print()`** — use `debugPrint()` or structured logging.\n- Prefer `context.colors` and `context.textTheme` (via theme extensions)\n  over raw `Theme.of(context)` calls.\n- Keep widgets small and composable.\n- Feature modules must not import from other feature modules — only from\n  `shared/`.\n- Use `Grid` tokens for spacing, `Radii` for border radius.\n\n### Quality Checks\n\n```bash\ncd mobile\ndart format --output=none --set-exit-if-changed .\nflutter analyze\nflutter test\n```\n\nOr from repo root: `just mobile-check` and `just mobile-test`.\n\n### Testing Conventions\n\n- Prefer **widget tests** over unit tests for UI components — test the\n  whole widget tree, not individual methods.\n- Use `ProviderScope(overrides: [...])` to inject fake notifiers.\n- Fake notifiers should extend the real notifier class and override `build()`.\n- Use the `WidgetHelpers.testable()` wrapper for simple widget tests or\n  build a custom `ProviderScope` + `MaterialApp` when you need specific overrides.\n\n---\n\n## See Also\n\n- [CONTRIBUTING.md](CONTRIBUTING.md) — setup, code style, PR process, how to add event kinds / MCP tools / API endpoints\n- [TESTING.md](TESTING.md) — multi-agent E2E test guide\n- [ARCHITECTURE.md](ARCHITECTURE.md) — system design and component relationships\n- [README.md](README.md) — project overview and quick start\n","CLAUDE.md":"# AGENTS.md — AI Agent Contributor Guide\n\nThis guide is for AI agents contributing to the Sprout codebase. It covers\nagent-specific context and conventions. For general contributor info (setup,\ncode style, PR process, architecture), see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n---\n\n## Repo Structure\n\n```\ncrates/\n  sprout-relay        # WebSocket relay server — main entry point\n  sprout-core         # Core types, event verification, filter matching\n  sprout-db           # Postgres event store and data access layer\n  sprout-auth         # Authentication and authorization\n  sprout-pubsub       # Redis pub/sub fan-out, presence, typing indicators\n  sprout-mcp          # MCP server providing AI agent tools\n  sprout-acp          # ACP harness bridging Sprout events to AI agents\n  sprout-workflow     # YAML-as-code workflow engine (evalexpr conditions)\n  sprout-search       # Typesense-backed full-text search\n  sprout-audit        # Hash-chain audit log\n  sprout-huddle       # LiveKit audio/video integration\n  sprout-proxy        # Nostr client compatibility proxy\n  sprout-admin        # Operator CLI for relay administration\n  sprout-test-client  # Integration test client and E2E test suite\n  sprout-sdk          # Typed Nostr event builders (used by sprout-mcp and sprout-cli)\n  sprout-media        # Blossom/S3 media storage\n  sprout-cli          # Agent-first CLI\n\ndesktop/              # Tauri 2 + React 19 desktop app\nmigrations/           # SQL migrations (auto-applied on relay startup)\nscripts/              # Dev tooling\n.env.example          # Config template — copy to .env before running\n```\n\n---\n\n## Getting Started\n\n```bash\n. ./bin/activate-hermit   # activate hermit toolchain (Rust, Node, etc.)\ncp .env.example .env      # configure local environment\njust setup                # install deps, run migrations\njust relay                # start relay at ws://localhost:3000\njust ci                   # run before any PR\n```\n\nSee CONTRIBUTING.md for full setup details and dependency requirements.\n\n---\n\n## Quality Gates\n\nRun `just ci` before every PR. It runs: Rust `fmt` + `clippy`, desktop lint\n(Biome), unit tests, desktop build, and Tauri check. All must pass.\n\nRun `just test` for integration tests if you touched `sprout-relay`,\n`sprout-db`, or `sprout-auth` — these require a running Postgres and Redis.\n\nAdditional rules:\n- No `unsafe` code\n- Do not introduce new `unwrap()` or `expect()` in production paths — use `?` and proper error types\n- New public API must have doc comments\n\n---\n\n## Key Patterns\n\n**Dual API surface**: Sprout exposes both a REST API and a NIP-29 WebSocket\nrelay. Both paths converge on shared DB functions in `sprout-db`. When adding\na feature, implement the shared DB logic first, then wire up both surfaces.\n\n**Event kinds**: All event kind integers are defined in\n`sprout-core/src/kind.rs`. New features get new kind integers — add them here\nfirst, then implement handling in the relay.\n\n**Channel scoping**: Channels use `h` tags (NIP-29 group tag), not `e` tags.\nFilters and queries must scope to `h` tags when operating within a channel.\n\n**MCP tools — dual transport**: The MCP server in `sprout-mcp` uses two\npatterns: write operations send signed Nostr events over WebSocket; read\noperations call REST endpoints (see `relay_client.rs` for the HTTP helpers).\nAdd the REST endpoint or event handler first, then add the MCP tool that calls\nit. Do not implement logic directly in MCP handlers.\n\n**Workflow conditions**: `sprout-workflow` uses\n[evalexpr](https://docs.rs/evalexpr) for condition evaluation. Keep expressions\nsimple and testable.\n\n**Thread counters**: `reply_count` and `descendant_count` are materialized on\nthread root events. Any code that inserts replies must update these counters —\ncheck existing reply handlers for the pattern.\n\n---\n\n## Testing\n\n```bash\njust test-unit    # unit tests, no infrastructure needed\njust test         # full integration suite (requires Postgres + Redis)\n```\n\nE2E tests live in `crates/sprout-test-client/tests/`:\n- `e2e_relay.rs` — WebSocket relay protocol\n- `e2e_rest_api.rs` — REST endpoint coverage\n- `e2e_mcp.rs` — MCP tool surface\n- `e2e_tokens.rs` — auth token flows\n- `e2e_workflows.rs` — workflow engine\n- `e2e_media.rs` — media upload/download (Blossom)\n- `e2e_media_extended.rs` — extended media scenarios\n- `e2e_nostr_interop.rs` — Nostr interop (NIP-50 search, NIP-10 threads, NIP-17 gift wraps)\n\nDesktop E2E: `cd desktop && pnpm exec playwright test`\n\nSee [TESTING.md](TESTING.md) for the full multi-agent E2E guide.\n\n---\n\n## Desktop App\n\nThe desktop app is Tauri 2 + React 19 + Vite + Tailwind CSS. Features are\norganized under `desktop/src/features/`. Biome handles linting and formatting.\n\n```bash\njust desktop-dev   # web-only dev server (faster iteration)\njust desktop-app   # full Tauri app with native shell\n```\n\n---\n\n## Mobile App (Flutter)\n\nThe mobile app lives in `mobile/` — a Flutter app using Riverpod + Hooks.\n\n### Architecture\n\n- **State management:** Riverpod + `flutter_hooks` (`HookConsumerWidget`)\n- **Theme:** Catppuccin Latte (light) / Macchiato (dark) — matches desktop\n- **Features:** Isolated under `lib/features/`, shared code in `lib/shared/`\n- **Nostr models:** `lib/shared/relay/nostr_models.dart` — event kinds must\n  stay in sync with `desktop/src/shared/constants/kinds.ts`\n\n### Rules\n\n- **NEVER use `StatefulWidget`** — always use `HookConsumerWidget` or\n  `ConsumerWidget` with `flutter_hooks` for local state.\n- **NEVER run `flutter run`, `flutter build`, `flutter clean`, or\n  `flutter upgrade`** — only `flutter test`, `flutter analyze`, and\n  `dart format` are safe for agents to run.\n- **Do NOT use `print()`** — use `debugPrint()` or structured logging.\n- Prefer `context.colors` and `context.textTheme` (via theme extensions)\n  over raw `Theme.of(context)` calls.\n- Keep widgets small and composable.\n- Feature modules must not import from other feature modules — only from\n  `shared/`.\n- Use `Grid` tokens for spacing, `Radii` for border radius.\n\n### Quality Checks\n\n```bash\ncd mobile\ndart format --output=none --set-exit-if-changed .\nflutter analyze\nflutter test\n```\n\nOr from repo root: `just mobile-check` and `just mobile-test`.\n\n### Testing Conventions\n\n- Prefer **widget tests** over unit tests for UI components — test the\n  whole widget tree, not individual methods.\n- Use `ProviderScope(overrides: [...])` to inject fake notifiers.\n- Fake notifiers should extend the real notifier class and override `build()`.\n- Use the `WidgetHelpers.testable()` wrapper for simple widget tests or\n  build a custom `ProviderScope` + `MaterialApp` when you need specific overrides.\n\n---\n\n## See Also\n\n- [CONTRIBUTING.md](CONTRIBUTING.md) — setup, code style, PR process, how to add event kinds / MCP tools / API endpoints\n- [TESTING.md](TESTING.md) — multi-agent E2E test guide\n- [ARCHITECTURE.md](ARCHITECTURE.md) — system design and component relationships\n- [README.md](README.md) — project overview and quick start\n",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/block/buzz/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/block/buzz/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/block/buzz/HEAD/.claude-plugin/plugin.json)"},"files":{"AGENTS.md":"# AGENTS.md — AI Agent Contributor Guide\n\nThis guide is for AI agents contributing to the Sprout codebase. It covers\nagent-specific context and conventions. For general contributor info (setup,\ncode style, PR process, architecture), see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n---\n\n## Repo Structure\n\n```\ncrates/\n  sprout-relay        # WebSocket relay server — main entry point\n  sprout-core         # Core types, event verification, filter matching\n  sprout-db           # Postgres event store and data access layer\n  sprout-auth         # Authentication and authorization\n  sprout-pubsub       # Redis pub/sub fan-out, presence, typing indicators\n  sprout-mcp          # MCP server providing AI agent tools\n  sprout-acp          # ACP harness bridging Sprout events to AI agents\n  sprout-workflow     # YAML-as-code workflow engine (evalexpr conditions)\n  sprout-search       # Typesense-backed full-text search\n  sprout-audit        # Hash-chain audit log\n  sprout-huddle       # LiveKit audio/video integration\n  sprout-proxy        # Nostr client compatibility proxy\n  sprout-admin        # Operator CLI for relay administration\n  sprout-test-client  # Integration test client and E2E test suite\n  sprout-sdk          # Typed Nostr event builders (used by sprout-mcp and sprout-cli)\n  sprout-media        # Blossom/S3 media storage\n  sprout-cli          # Agent-first CLI\n\ndesktop/              # Tauri 2 + React 19 desktop app\nmigrations/           # SQL migrations (auto-applied on relay startup)\nscripts/              # Dev tooling\n.env.example          # Config template — copy to .env before running\n```\n\n---\n\n## Getting Started\n\n```bash\n. ./bin/activate-hermit   # activate hermit toolchain (Rust, Node, etc.)\ncp .env.example .env      # configure local environment\njust setup                # install deps, run migrations\njust relay                # start relay at ws://localhost:3000\njust ci                   # run before any PR\n```\n\nSee CONTRIBUTING.md for full setup details and dependency requirements.\n\n---\n\n## Quality Gates\n\nRun `just ci` before every PR. It runs: Rust `fmt` + `clippy`, desktop lint\n(Biome), unit tests, desktop build, and Tauri check. All must pass.\n\nRun `just test` for integration tests if you touched `sprout-relay`,\n`sprout-db`, or `sprout-auth` — these require a running Postgres and Redis.\n\nAdditional rules:\n- No `unsafe` code\n- Do not introduce new `unwrap()` or `expect()` in production paths — use `?` and proper error types\n- New public API must have doc comments\n\n---\n\n## Key Patterns\n\n**Dual API surface**: Sprout exposes both a REST API and a NIP-29 WebSocket\nrelay. Both paths converge on shared DB functions in `sprout-db`. When adding\na feature, implement the shared DB logic first, then wire up both surfaces.\n\n**Event kinds**: All event kind integers are defined in\n`sprout-core/src/kind.rs`. New features get new kind integers — add them here\nfirst, then implement handling in the relay.\n\n**Channel scoping**: Channels use `h` tags (NIP-29 group tag), not `e` tags.\nFilters and queries must scope to `h` tags when operating within a channel.\n\n**MCP tools — dual transport**: The MCP server in `sprout-mcp` uses two\npatterns: write operations send signed Nostr events over WebSocket; read\noperations call REST endpoints (see `relay_client.rs` for the HTTP helpers).\nAdd the REST endpoint or event handler first, then add the MCP tool that calls\nit. Do not implement logic directly in MCP handlers.\n\n**Workflow conditions**: `sprout-workflow` uses\n[evalexpr](https://docs.rs/evalexpr) for condition evaluation. Keep expressions\nsimple and testable.\n\n**Thread counters**: `reply_count` and `descendant_count` are materialized on\nthread root events. Any code that inserts replies must update these counters —\ncheck existing reply handlers for the pattern.\n\n---\n\n## Testing\n\n```bash\njust test-unit    # unit tests, no infrastructure needed\njust test         # full integration suite (requires Postgres + Redis)\n```\n\nE2E tests live in `crates/sprout-test-client/tests/`:\n- `e2e_relay.rs` — WebSocket relay protocol\n- `e2e_rest_api.rs` — REST endpoint coverage\n- `e2e_mcp.rs` — MCP tool surface\n- `e2e_tokens.rs` — auth token flows\n- `e2e_workflows.rs` — workflow engine\n- `e2e_media.rs` — media upload/download (Blossom)\n- `e2e_media_extended.rs` — extended media scenarios\n- `e2e_nostr_interop.rs` — Nostr interop (NIP-50 search, NIP-10 threads, NIP-17 gift wraps)\n\nDesktop E2E: `cd desktop && pnpm exec playwright test`\n\nSee [TESTING.md](TESTING.md) for the full multi-agent E2E guide.\n\n---\n\n## Desktop App\n\nThe desktop app is Tauri 2 + React 19 + Vite + Tailwind CSS. Features are\norganized under `desktop/src/features/`. Biome handles linting and formatting.\n\n```bash\njust desktop-dev   # web-only dev server (faster iteration)\njust desktop-app   # full Tauri app with native shell\n```\n\n---\n\n## Mobile App (Flutter)\n\nThe mobile app lives in `mobile/` — a Flutter app using Riverpod + Hooks.\n\n### Architecture\n\n- **State management:** Riverpod + `flutter_hooks` (`HookConsumerWidget`)\n- **Theme:** Catppuccin Latte (light) / Macchiato (dark) — matches desktop\n- **Features:** Isolated under `lib/features/`, shared code in `lib/shared/`\n- **Nostr models:** `lib/shared/relay/nostr_models.dart` — event kinds must\n  stay in sync with `desktop/src/shared/constants/kinds.ts`\n\n### Rules\n\n- **NEVER use `StatefulWidget`** — always use `HookConsumerWidget` or\n  `ConsumerWidget` with `flutter_hooks` for local state.\n- **NEVER run `flutter run`, `flutter build`, `flutter clean`, or\n  `flutter upgrade`** — only `flutter test`, `flutter analyze`, and\n  `dart format` are safe for agents to run.\n- **Do NOT use `print()`** — use `debugPrint()` or structured logging.\n- Prefer `context.colors` and `context.textTheme` (via theme extensions)\n  over raw `Theme.of(context)` calls.\n- Keep widgets small and composable.\n- Feature modules must not import from other feature modules — only from\n  `shared/`.\n- Use `Grid` tokens for spacing, `Radii` for border radius.\n\n### Quality Checks\n\n```bash\ncd mobile\ndart format --output=none --set-exit-if-changed .\nflutter analyze\nflutter test\n```\n\nOr from repo root: `just mobile-check` and `just mobile-test`.\n\n### Testing Conventions\n\n- Prefer **widget tests** over unit tests for UI components — test the\n  whole widget tree, not individual methods.\n- Use `ProviderScope(overrides: [...])` to inject fake notifiers.\n- Fake notifiers should extend the real notifier class and override `build()`.\n- Use the `WidgetHelpers.testable()` wrapper for simple widget tests or\n  build a custom `ProviderScope` + `MaterialApp` when you need specific overrides.\n\n---\n\n## See Also\n\n- [CONTRIBUTING.md](CONTRIBUTING.md) — setup, code style, PR process, how to add event kinds / MCP tools / API endpoints\n- [TESTING.md](TESTING.md) — multi-agent E2E test guide\n- [ARCHITECTURE.md](ARCHITECTURE.md) — system design and component relationships\n- [README.md](README.md) — project overview and quick start\n","CLAUDE.md":"# AGENTS.md — AI Agent Contributor Guide\n\nThis guide is for AI agents contributing to the Sprout codebase. It covers\nagent-specific context and conventions. For general contributor info (setup,\ncode style, PR process, architecture), see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n---\n\n## Repo Structure\n\n```\ncrates/\n  sprout-relay        # WebSocket relay server — main entry point\n  sprout-core         # Core types, event verification, filter matching\n  sprout-db           # Postgres event store and data access layer\n  sprout-auth         # Authentication and authorization\n  sprout-pubsub       # Redis pub/sub fan-out, presence, typing indicators\n  sprout-mcp          # MCP server providing AI agent tools\n  sprout-acp          # ACP harness bridging Sprout events to AI agents\n  sprout-workflow     # YAML-as-code workflow engine (evalexpr conditions)\n  sprout-search       # Typesense-backed full-text search\n  sprout-audit        # Hash-chain audit log\n  sprout-huddle       # LiveKit audio/video integration\n  sprout-proxy        # Nostr client compatibility proxy\n  sprout-admin        # Operator CLI for relay administration\n  sprout-test-client  # Integration test client and E2E test suite\n  sprout-sdk          # Typed Nostr event builders (used by sprout-mcp and sprout-cli)\n  sprout-media        # Blossom/S3 media storage\n  sprout-cli          # Agent-first CLI\n\ndesktop/              # Tauri 2 + React 19 desktop app\nmigrations/           # SQL migrations (auto-applied on relay startup)\nscripts/              # Dev tooling\n.env.example          # Config template — copy to .env before running\n```\n\n---\n\n## Getting Started\n\n```bash\n. ./bin/activate-hermit   # activate hermit toolchain (Rust, Node, etc.)\ncp .env.example .env      # configure local environment\njust setup                # install deps, run migrations\njust relay                # start relay at ws://localhost:3000\njust ci                   # run before any PR\n```\n\nSee CONTRIBUTING.md for full setup details and dependency requirements.\n\n---\n\n## Quality Gates\n\nRun `just ci` before every PR. It runs: Rust `fmt` + `clippy`, desktop lint\n(Biome), unit tests, desktop build, and Tauri check. All must pass.\n\nRun `just test` for integration tests if you touched `sprout-relay`,\n`sprout-db`, or `sprout-auth` — these require a running Postgres and Redis.\n\nAdditional rules:\n- No `unsafe` code\n- Do not introduce new `unwrap()` or `expect()` in production paths — use `?` and proper error types\n- New public API must have doc comments\n\n---\n\n## Key Patterns\n\n**Dual API surface**: Sprout exposes both a REST API and a NIP-29 WebSocket\nrelay. Both paths converge on shared DB functions in `sprout-db`. When adding\na feature, implement the shared DB logic first, then wire up both surfaces.\n\n**Event kinds**: All event kind integers are defined in\n`sprout-core/src/kind.rs`. New features get new kind integers — add them here\nfirst, then implement handling in the relay.\n\n**Channel scoping**: Channels use `h` tags (NIP-29 group tag), not `e` tags.\nFilters and queries must scope to `h` tags when operating within a channel.\n\n**MCP tools — dual transport**: The MCP server in `sprout-mcp` uses two\npatterns: write operations send signed Nostr events over WebSocket; read\noperations call REST endpoints (see `relay_client.rs` for the HTTP helpers).\nAdd the REST endpoint or event handler first, then add the MCP tool that calls\nit. Do not implement logic directly in MCP handlers.\n\n**Workflow conditions**: `sprout-workflow` uses\n[evalexpr](https://docs.rs/evalexpr) for condition evaluation. Keep expressions\nsimple and testable.\n\n**Thread counters**: `reply_count` and `descendant_count` are materialized on\nthread root events. Any code that inserts replies must update these counters —\ncheck existing reply handlers for the pattern.\n\n---\n\n## Testing\n\n```bash\njust test-unit    # unit tests, no infrastructure needed\njust test         # full integration suite (requires Postgres + Redis)\n```\n\nE2E tests live in `crates/sprout-test-client/tests/`:\n- `e2e_relay.rs` — WebSocket relay protocol\n- `e2e_rest_api.rs` — REST endpoint coverage\n- `e2e_mcp.rs` — MCP tool surface\n- `e2e_tokens.rs` — auth token flows\n- `e2e_workflows.rs` — workflow engine\n- `e2e_media.rs` — media upload/download (Blossom)\n- `e2e_media_extended.rs` — extended media scenarios\n- `e2e_nostr_interop.rs` — Nostr interop (NIP-50 search, NIP-10 threads, NIP-17 gift wraps)\n\nDesktop E2E: `cd desktop && pnpm exec playwright test`\n\nSee [TESTING.md](TESTING.md) for the full multi-agent E2E guide.\n\n---\n\n## Desktop App\n\nThe desktop app is Tauri 2 + React 19 + Vite + Tailwind CSS. Features are\norganized under `desktop/src/features/`. Biome handles linting and formatting.\n\n```bash\njust desktop-dev   # web-only dev server (faster iteration)\njust desktop-app   # full Tauri app with native shell\n```\n\n---\n\n## Mobile App (Flutter)\n\nThe mobile app lives in `mobile/` — a Flutter app using Riverpod + Hooks.\n\n### Architecture\n\n- **State management:** Riverpod + `flutter_hooks` (`HookConsumerWidget`)\n- **Theme:** Catppuccin Latte (light) / Macchiato (dark) — matches desktop\n- **Features:** Isolated under `lib/features/`, shared code in `lib/shared/`\n- **Nostr models:** `lib/shared/relay/nostr_models.dart` — event kinds must\n  stay in sync with `desktop/src/shared/constants/kinds.ts`\n\n### Rules\n\n- **NEVER use `StatefulWidget`** — always use `HookConsumerWidget` or\n  `ConsumerWidget` with `flutter_hooks` for local state.\n- **NEVER run `flutter run`, `flutter build`, `flutter clean`, or\n  `flutter upgrade`** — only `flutter test`, `flutter analyze`, and\n  `dart format` are safe for agents to run.\n- **Do NOT use `print()`** — use `debugPrint()` or structured logging.\n- Prefer `context.colors` and `context.textTheme` (via theme extensions)\n  over raw `Theme.of(context)` calls.\n- Keep widgets small and composable.\n- Feature modules must not import from other feature modules — only from\n  `shared/`.\n- Use `Grid` tokens for spacing, `Radii` for border radius.\n\n### Quality Checks\n\n```bash\ncd mobile\ndart format --output=none --set-exit-if-changed .\nflutter analyze\nflutter test\n```\n\nOr from repo root: `just mobile-check` and `just mobile-test`.\n\n### Testing Conventions\n\n- Prefer **widget tests** over unit tests for UI components — test the\n  whole widget tree, not individual methods.\n- Use `ProviderScope(overrides: [...])` to inject fake notifiers.\n- Fake notifiers should extend the real notifier class and override `build()`.\n- Use the `WidgetHelpers.testable()` wrapper for simple widget tests or\n  build a custom `ProviderScope` + `MaterialApp` when you need specific overrides.\n\n---\n\n## See Also\n\n- [CONTRIBUTING.md](CONTRIBUTING.md) — setup, code style, PR process, how to add event kinds / MCP tools / API endpoints\n- [TESTING.md](TESTING.md) — multi-agent E2E test guide\n- [ARCHITECTURE.md](ARCHITECTURE.md) — system design and component relationships\n- [README.md](README.md) — project overview and quick start\n",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/block/buzz/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/block/buzz/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/block/buzz/HEAD/.claude-plugin/plugin.json)"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/block/buzz/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AGENTS.md — AI Agent Contributor Guide\n\nThis guide is for AI agents contributing to the Sprout codebase. It covers\nagent-specific context and conventions. For general contributor info (setup,\ncode style, PR process, architecture), see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n---\n\n## Repo Structure\n\n```\ncrates/\n  sprout-relay        # WebSocket relay server — main entry point\n  sprout-core         # Core types, event verification, filter matching\n  sprout-db           # Postgres event store and data access layer\n  sprout-auth         # Authentication and authorization\n  sprout-pubsub       # Redis pub/sub fan-out, presence, typing indicators\n  sprout-mcp          # MCP server providing AI agent tools\n  sprout-acp          # ACP harness bridging Sprout events to AI agents\n  sprout-workflow     # YAML-as-code workflow engine (evalexpr conditions)\n  sprout-search       # Typesense-backed full-text search\n  sprout-audit        # Hash-chain audit log\n  sprout-huddle       # LiveKit audio/video integration\n  sprout-proxy        # Nostr client compatibility proxy\n  sprout-admin        # Operator CLI for relay administration\n  sprout-test-client  # Integration test client and E2E test suite\n  sprout-sdk          # Typed Nostr event builders (used by sprout-mcp and sprout-cli)\n  sprout-media        # Blossom/S3 media storage\n  sprout-cli          # Agent-first CLI\n\ndesktop/              # Tauri 2 + React 19 desktop app\nmigrations/           # SQL migrations (auto-applied on relay startup)\nscripts/              # Dev tooling\n.env.example          # Config template — copy to .env before running\n```\n\n---\n\n## Getting Started\n\n```bash\n. ./bin/activate-hermit   # activate hermit toolchain (Rust, Node, etc.)\ncp .env.example .env      # configure local environment\njust setup                # install deps, run migrations\njust relay                # start relay at ws://localhost:3000\njust ci                   # run before any PR\n```\n\nSee CONTRIBUTING.md for full setup details and dependency requirements.\n\n---\n\n## Quality Gates\n\nRun `just ci` before every PR. It runs: Rust `fmt` + `clippy`, desktop lint\n(Biome), unit tests, desktop build, and Tauri check. All must pass.\n\nRun `just test` for integration tests if you touched `sprout-relay`,\n`sprout-db`, or `sprout-auth` — these require a running Postgres and Redis.\n\nAdditional rules:\n- No `unsafe` code\n- Do not introduce new `unwrap()` or `expect()` in production paths — use `?` and proper error types\n- New public API must have doc comments\n\n---\n\n## Key Patterns\n\n**Dual API surface**: Sprout exposes both a REST API and a NIP-29 WebSocket\nrelay. Both paths converge on shared DB functions in `sprout-db`. When adding\na feature, implement the shared DB logic first, then wire up both surfaces.\n\n**Event kinds**: All event kind integers are defined in\n`sprout-core/src/kind.rs`. New features get new kind integers — add them here\nfirst, then implement handling in the relay.\n\n**Channel scoping**: Channels use `h` tags (NIP-29 group tag), not `e` tags.\nFilters and queries must scope to `h` tags when operating within a channel.\n\n**MCP tools — dual transport**: The MCP server in `sprout-mcp` uses two\npatterns: write operations send signed Nostr events over WebSocket; read\noperations call REST endpoints (see `relay_client.rs` for the HTTP helpers).\nAdd the REST endpoint or event handler first, then add the MCP tool that calls\nit. Do not implement logic directly in MCP handlers.\n\n**Workflow conditions**: `sprout-workflow` uses\n[evalexpr](https://docs.rs/evalexpr) for condition evaluation. Keep expressions\nsimple and testable.\n\n**Thread counters**: `reply_count` and `descendant_count` are materialized on\nthread root events. Any code that inserts replies must update these counters —\ncheck existing reply handlers for the pattern.\n\n---\n\n## Testing\n\n```bash\njust test-unit    # unit tests, no infrastructure needed\njust test         # full integration suite (requires Postgres + Redis)\n```\n\nE2E tests live in `crates/sprout-test-client/tests/`:\n- `e2e_relay.rs` — WebSocket relay protocol\n- `e2e_rest_api.rs` — REST endpoint coverage\n- `e2e_mcp.rs` — MCP tool surface\n- `e2e_tokens.rs` — auth token flows\n- `e2e_workflows.rs` — workflow engine\n- `e2e_media.rs` — media upload/download (Blossom)\n- `e2e_media_extended.rs` — extended media scenarios\n- `e2e_nostr_interop.rs` — Nostr interop (NIP-50 search, NIP-10 threads, NIP-17 gift wraps)\n\nDesktop E2E: `cd desktop && pnpm exec playwright test`\n\nSee [TESTING.md](TESTING.md) for the full multi-agent E2E guide.\n\n---\n\n## Desktop App\n\nThe desktop app is Tauri 2 + React 19 + Vite + Tailwind CSS. Features are\norganized under `desktop/src/features/`. Biome handles linting and formatting.\n\n```bash\njust desktop-dev   # web-only dev server (faster iteration)\njust desktop-app   # full Tauri app with native shell\n```\n\n---\n\n## Mobile App (Flutter)\n\nThe mobile app lives in `mobile/` — a Flutter app using Riverpod + Hooks.\n\n### Architecture\n\n- **State management:** Riverpod + `flutter_hooks` (`HookConsumerWidget`)\n- **Theme:** Catppuccin Latte (light) / Macchiato (dark) — matches desktop\n- **Features:** Isolated under `lib/features/`, shared code in `lib/shared/`\n- **Nostr models:** `lib/shared/relay/nostr_models.dart` — event kinds must\n  stay in sync with `desktop/src/shared/constants/kinds.ts`\n\n### Rules\n\n- **NEVER use `StatefulWidget`** — always use `HookConsumerWidget` or\n  `ConsumerWidget` with `flutter_hooks` for local state.\n- **NEVER run `flutter run`, `flutter build`, `flutter clean`, or\n  `flutter upgrade`** — only `flutter test`, `flutter analyze`, and\n  `dart format` are safe for agents to run.\n- **Do NOT use `print()`** — use `debugPrint()` or structured logging.\n- Prefer `context.colors` and `context.textTheme` (via theme extensions)\n  over raw `Theme.of(context)` calls.\n- Keep widgets small and composable.\n- Feature modules must not import from other feature modules — only from\n  `shared/`.\n- Use `Grid` tokens for spacing, `Radii` for border radius.\n\n### Quality Checks\n\n```bash\ncd mobile\ndart format --output=none --set-exit-if-changed .\nflutter analyze\nflutter test\n```\n\nOr from repo root: `just mobile-check` and `just mobile-test`.\n\n### Testing Conventions\n\n- Prefer **widget tests** over unit tests for UI components — test the\n  whole widget tree, not individual methods.\n- Use `ProviderScope(overrides: [...])` to inject fake notifiers.\n- Fake notifiers should extend the real notifier class and override `build()`.\n- Use the `WidgetHelpers.testable()` wrapper for simple widget tests or\n  build a custom `ProviderScope` + `MaterialApp` when you need specific overrides.\n\n---\n\n## See Also\n\n- [CONTRIBUTING.md](CONTRIBUTING.md) — setup, code style, PR process, how to add event kinds / MCP tools / API endpoints\n- [TESTING.md](TESTING.md) — multi-agent E2E test guide\n- [ARCHITECTURE.md](ARCHITECTURE.md) — system design and component relationships\n- [README.md](README.md) — project overview and quick start\n","isInternal":false,"tokens":1741,"sizeBytes":7029},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/block/buzz/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"# AGENTS.md — AI Agent Contributor Guide\n\nThis guide is for AI agents contributing to the Sprout codebase. It covers\nagent-specific context and conventions. For general contributor info (setup,\ncode style, PR process, architecture), see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n---\n\n## Repo Structure\n\n```\ncrates/\n  sprout-relay        # WebSocket relay server — main entry point\n  sprout-core         # Core types, event verification, filter matching\n  sprout-db           # Postgres event store and data access layer\n  sprout-auth         # Authentication and authorization\n  sprout-pubsub       # Redis pub/sub fan-out, presence, typing indicators\n  sprout-mcp          # MCP server providing AI agent tools\n  sprout-acp          # ACP harness bridging Sprout events to AI agents\n  sprout-workflow     # YAML-as-code workflow engine (evalexpr conditions)\n  sprout-search       # Typesense-backed full-text search\n  sprout-audit        # Hash-chain audit log\n  sprout-huddle       # LiveKit audio/video integration\n  sprout-proxy        # Nostr client compatibility proxy\n  sprout-admin        # Operator CLI for relay administration\n  sprout-test-client  # Integration test client and E2E test suite\n  sprout-sdk          # Typed Nostr event builders (used by sprout-mcp and sprout-cli)\n  sprout-media        # Blossom/S3 media storage\n  sprout-cli          # Agent-first CLI\n\ndesktop/              # Tauri 2 + React 19 desktop app\nmigrations/           # SQL migrations (auto-applied on relay startup)\nscripts/              # Dev tooling\n.env.example          # Config template — copy to .env before running\n```\n\n---\n\n## Getting Started\n\n```bash\n. ./bin/activate-hermit   # activate hermit toolchain (Rust, Node, etc.)\ncp .env.example .env      # configure local environment\njust setup                # install deps, run migrations\njust relay                # start relay at ws://localhost:3000\njust ci                   # run before any PR\n```\n\nSee CONTRIBUTING.md for full setup details and dependency requirements.\n\n---\n\n## Quality Gates\n\nRun `just ci` before every PR. It runs: Rust `fmt` + `clippy`, desktop lint\n(Biome), unit tests, desktop build, and Tauri check. All must pass.\n\nRun `just test` for integration tests if you touched `sprout-relay`,\n`sprout-db`, or `sprout-auth` — these require a running Postgres and Redis.\n\nAdditional rules:\n- No `unsafe` code\n- Do not introduce new `unwrap()` or `expect()` in production paths — use `?` and proper error types\n- New public API must have doc comments\n\n---\n\n## Key Patterns\n\n**Dual API surface**: Sprout exposes both a REST API and a NIP-29 WebSocket\nrelay. Both paths converge on shared DB functions in `sprout-db`. When adding\na feature, implement the shared DB logic first, then wire up both surfaces.\n\n**Event kinds**: All event kind integers are defined in\n`sprout-core/src/kind.rs`. New features get new kind integers — add them here\nfirst, then implement handling in the relay.\n\n**Channel scoping**: Channels use `h` tags (NIP-29 group tag), not `e` tags.\nFilters and queries must scope to `h` tags when operating within a channel.\n\n**MCP tools — dual transport**: The MCP server in `sprout-mcp` uses two\npatterns: write operations send signed Nostr events over WebSocket; read\noperations call REST endpoints (see `relay_client.rs` for the HTTP helpers).\nAdd the REST endpoint or event handler first, then add the MCP tool that calls\nit. Do not implement logic directly in MCP handlers.\n\n**Workflow conditions**: `sprout-workflow` uses\n[evalexpr](https://docs.rs/evalexpr) for condition evaluation. Keep expressions\nsimple and testable.\n\n**Thread counters**: `reply_count` and `descendant_count` are materialized on\nthread root events. Any code that inserts replies must update these counters —\ncheck existing reply handlers for the pattern.\n\n---\n\n## Testing\n\n```bash\njust test-unit    # unit tests, no infrastructure needed\njust test         # full integration suite (requires Postgres + Redis)\n```\n\nE2E tests live in `crates/sprout-test-client/tests/`:\n- `e2e_relay.rs` — WebSocket relay protocol\n- `e2e_rest_api.rs` — REST endpoint coverage\n- `e2e_mcp.rs` — MCP tool surface\n- `e2e_tokens.rs` — auth token flows\n- `e2e_workflows.rs` — workflow engine\n- `e2e_media.rs` — media upload/download (Blossom)\n- `e2e_media_extended.rs` — extended media scenarios\n- `e2e_nostr_interop.rs` — Nostr interop (NIP-50 search, NIP-10 threads, NIP-17 gift wraps)\n\nDesktop E2E: `cd desktop && pnpm exec playwright test`\n\nSee [TESTING.md](TESTING.md) for the full multi-agent E2E guide.\n\n---\n\n## Desktop App\n\nThe desktop app is Tauri 2 + React 19 + Vite + Tailwind CSS. Features are\norganized under `desktop/src/features/`. Biome handles linting and formatting.\n\n```bash\njust desktop-dev   # web-only dev server (faster iteration)\njust desktop-app   # full Tauri app with native shell\n```\n\n---\n\n## Mobile App (Flutter)\n\nThe mobile app lives in `mobile/` — a Flutter app using Riverpod + Hooks.\n\n### Architecture\n\n- **State management:** Riverpod + `flutter_hooks` (`HookConsumerWidget`)\n- **Theme:** Catppuccin Latte (light) / Macchiato (dark) — matches desktop\n- **Features:** Isolated under `lib/features/`, shared code in `lib/shared/`\n- **Nostr models:** `lib/shared/relay/nostr_models.dart` — event kinds must\n  stay in sync with `desktop/src/shared/constants/kinds.ts`\n\n### Rules\n\n- **NEVER use `StatefulWidget`** — always use `HookConsumerWidget` or\n  `ConsumerWidget` with `flutter_hooks` for local state.\n- **NEVER run `flutter run`, `flutter build`, `flutter clean`, or\n  `flutter upgrade`** — only `flutter test`, `flutter analyze`, and\n  `dart format` are safe for agents to run.\n- **Do NOT use `print()`** — use `debugPrint()` or structured logging.\n- Prefer `context.colors` and `context.textTheme` (via theme extensions)\n  over raw `Theme.of(context)` calls.\n- Keep widgets small and composable.\n- Feature modules must not import from other feature modules — only from\n  `shared/`.\n- Use `Grid` tokens for spacing, `Radii` for border radius.\n\n### Quality Checks\n\n```bash\ncd mobile\ndart format --output=none --set-exit-if-changed .\nflutter analyze\nflutter test\n```\n\nOr from repo root: `just mobile-check` and `just mobile-test`.\n\n### Testing Conventions\n\n- Prefer **widget tests** over unit tests for UI components — test the\n  whole widget tree, not individual methods.\n- Use `ProviderScope(overrides: [...])` to inject fake notifiers.\n- Fake notifiers should extend the real notifier class and override `build()`.\n- Use the `WidgetHelpers.testable()` wrapper for simple widget tests or\n  build a custom `ProviderScope` + `MaterialApp` when you need specific overrides.\n\n---\n\n## See Also\n\n- [CONTRIBUTING.md](CONTRIBUTING.md) — setup, code style, PR process, how to add event kinds / MCP tools / API endpoints\n- [TESTING.md](TESTING.md) — multi-agent E2E test guide\n- [ARCHITECTURE.md](ARCHITECTURE.md) — system design and component relationships\n- [README.md](README.md) — project overview and quick start\n","isInternal":false,"tokens":1741,"sizeBytes":7029},{"name":"marketplace.json","path":".claude-plugin/marketplace.json","rawUrl":"https://raw.githubusercontent.com/block/buzz/HEAD/.claude-plugin/marketplace.json","title":"Claude Plugin Marketplace Catalog","category":"marketplace","format":"json","content":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/block/buzz/HEAD/.claude-plugin/marketplace.json)","tokens":300,"sizeBytes":189},{"name":"plugin.json","path":".claude-plugin/plugin.json","rawUrl":"https://raw.githubusercontent.com/block/buzz/HEAD/.claude-plugin/plugin.json","title":"claude-plugin Plugin Manifest","category":"plugin-manifest","format":"json","content":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/block/buzz/HEAD/.claude-plugin/plugin.json)","tokens":300,"sizeBytes":175},{"name":"mcp.json","path":".cursor/mcp.json","rawUrl":"https://raw.githubusercontent.com/block/buzz/HEAD/.cursor/mcp.json","title":"Model Context Protocol (MCP) Configuration","category":"mcp-config","format":"json","content":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/block/buzz/HEAD/.cursor/mcp.json)","tokens":300,"sizeBytes":168}],"systemPromptSnippet":"<yakaai_skills repo=\"block/buzz\">\n<!-- File: AGENTS.md (Tokens: ~1741 | Category: root-instruction) -->\n# AGENTS.md — AI Agent Contributor Guide\n\nThis guide is for AI agents contributing to the Sprout codebase. It covers\nagent-specific context and conventions. For general contributor info (setup,\ncode style, PR process, architecture), see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n---\n\n## Repo Structure\n\n```\ncrates/\n  sprout-relay        # WebSocket relay server — main entry point\n  sprout-core         # Core types, event verification, filter matching\n  sprout-db           # Postgres event store and data access layer\n  sprout-auth         # Authentication and authorization\n  sprout-pubsub       # Redis pub/sub fan-out, presence, typing indicators\n  sprout-mcp          # MCP server providing AI agent tools\n  sprout-acp          # ACP harness bridging Sprout events to AI agents\n  sprout-workflow     # YAML-as-code workflow engine (evalexpr conditions)\n  sprout-search       # Typesense-backed full-text search\n  sprout-audit        # Hash-chain audit log\n  sprout-huddle       # LiveKit audio/video integration\n  sprout-proxy        # Nostr client compatibility proxy\n  sprout-admin        # Operator CLI for relay administration\n  sprout-test-client  # Integration test client and E2E test suite\n  sprout-sdk          # Typed Nostr event builders (used by sprout-mcp and sprout-cli)\n  sprout-media        # Blossom/S3 media storage\n  sprout-cli          # Agent-first CLI\n\ndesktop/              # Tauri 2 + React 19 desktop app\nmigrations/           # SQL migrations (auto-applied on relay startup)\nscripts/              # Dev tooling\n.env.example          # Config template — copy to .env before running\n```\n\n---\n\n## Getting Started\n\n```bash\n. ./bin/activate-hermit   # activate hermit toolchain (Rust, Node, etc.)\ncp .env.example .env      # configure local environment\njust setup                # install deps, run migrations\njust relay                # start relay at ws://localhost:3000\njust ci                   # run before any PR\n```\n\nSee CONTRIBUTING.md for full setup details and dependency requirements.\n\n---\n\n## Quality Gates\n\nRun `just ci` before every PR. It runs: Rust `fmt` + `clippy`, desktop lint\n(Biome), unit tests, desktop build, and Tauri check. All must pass.\n\nRun `just test` for integration tests if you touched `sprout-relay`,\n`sprout-db`, or `sprout-auth` — these require a running Postgres and Redis.\n\nAdditional rules:\n- No `unsafe` code\n- Do not introduce new `unwrap()` or `expect()` in production paths — use `?` and proper error types\n- New public API must have doc comments\n\n---\n\n## Key Patterns\n\n**Dual API surface**: Sprout exposes both a REST API and a NIP-29 WebSocket\nrelay. Both paths converge on shared DB functions in `sprout-db`. When adding\na feature, implement the shared DB logic first, then wire up both surfaces.\n\n**Event kinds**: All event kind integers are defined in\n`sprout-core/src/kind.rs`. New features get new kind integers — add them here\nfirst, then implement handling in the relay.\n\n**Channel scoping**: Channels use `h` tags (NIP-29 group tag), not `e` tags.\nFilters and queries must scope to `h` tags when operating within a channel.\n\n**MCP tools — dual transport**: The MCP server in `sprout-mcp` uses two\npatterns: write operations send signed Nostr events over WebSocket; read\noperations call REST endpoints (see `relay_client.rs` for the HTTP helpers).\nAdd the REST endpoint or event handler first, then add the MCP tool that calls\nit. Do not implement logic directly in MCP handlers.\n\n**Workflow conditions**: `sprout-workflow` uses\n[evalexpr](https://docs.rs/evalexpr) for condition evaluation. Keep expressions\nsimple and testable.\n\n**Thread counters**: `reply_count` and `descendant_count` are materialized on\nthread root events. Any code that inserts replies must update these counters —\ncheck existing reply handlers for the pattern.\n\n---\n\n## Testing\n\n```bash\njust test-unit    # unit tests, no infrastructure needed\njust test         # full integration suite (requires Postgres + Redis)\n```\n\nE2E tests live in `crates/sprout-test-client/tests/`:\n- `e2e_relay.rs` — WebSocket relay protocol\n- `e2e_rest_api.rs` — REST endpoint coverage\n- `e2e_mcp.rs` — MCP tool surface\n- `e2e_tokens.rs` — auth token flows\n- `e2e_workflows.rs` — workflow engine\n- `e2e_media.rs` — media upload/download (Blossom)\n- `e2e_media_extended.rs` — extended media scenarios\n- `e2e_nostr_interop.rs` — Nostr interop (NIP-50 search, NIP-10 threads, NIP-17 gift wraps)\n\nDesktop E2E: `cd desktop && pnpm exec playwright test`\n\nSee [TESTING.md](TESTING.md) for the full multi-agent E2E guide.\n\n---\n\n## Desktop App\n\nThe desktop app is Tauri 2 + React 19 + Vite + Tailwind CSS. Features are\norganized under `desktop/src/features/`. Biome handles linting and formatting.\n\n```bash\njust desktop-dev   # web-only dev server (faster iteration)\njust desktop-app   # full Tauri app with native shell\n```\n\n---\n\n## Mobile App (Flutter)\n\nThe mobile app lives in `mobile/` — a Flutter app using Riverpod + Hooks.\n\n### Architecture\n\n- **State management:** Riverpod + `flutter_hooks` (`HookConsumerWidget`)\n- **Theme:** Catppuccin Latte (light) / Macchiato (dark) — matches desktop\n- **Features:** Isolated under `lib/features/`, shared code in `lib/shared/`\n- **Nostr models:** `lib/shared/relay/nostr_models.dart` — event kinds must\n  stay in sync with `desktop/src/shared/constants/kinds.ts`\n\n### Rules\n\n- **NEVER use `StatefulWidget`** — always use `HookConsumerWidget` or\n  `ConsumerWidget` with `flutter_hooks` for local state.\n- **NEVER run `flutter run`, `flutter build`, `flutter clean`, or\n  `flutter upgrade`** — only `flutter test`, `flutter analyze`, and\n  `dart format` are safe for agents to run.\n- **Do NOT use `print()`** — use `debugPrint()` or structured logging.\n- Prefer `context.colors` and `context.textTheme` (via theme extensions)\n  over raw `Theme.of(context)` calls.\n- Keep widgets small and composable.\n- Feature modules must not import from other feature modules — only from\n  `shared/`.\n- Use `Grid` tokens for spacing, `Radii` for border radius.\n\n### Quality Checks\n\n```bash\ncd mobile\ndart format --output=none --set-exit-if-changed .\nflutter analyze\nflutter test\n```\n\nOr from repo root: `just mobile-check` and `just mobile-test`.\n\n### Testing Conventions\n\n- Prefer **widget tests** over unit tests for UI components — test the\n  whole widget tree, not individual methods.\n- Use `ProviderScope(overrides: [...])` to inject fake notifiers.\n- Fake notifiers should extend the real notifier class and override `build()`.\n- Use the `WidgetHelpers.testable()` wrapper for simple widget tests or\n  build a custom `ProviderScope` + `MaterialApp` when you need specific overrides.\n\n---\n\n## See Also\n\n- [CONTRIBUTING.md](CONTRIBUTING.md) — setup, code style, PR process, how to add event kinds / MCP tools / API endpoints\n- [TESTING.md](TESTING.md) — multi-agent E2E test guide\n- [ARCHITECTURE.md](ARCHITECTURE.md) — system design and component relationships\n- [README.md](README.md) — project overview and quick start\n\n<!-- File: CLAUDE.md (Tokens: ~1741 | Category: claude-rule) -->\n# AGENTS.md — AI Agent Contributor Guide\n\nThis guide is for AI agents contributing to the Sprout codebase. It covers\nagent-specific context and conventions. For general contributor info (setup,\ncode style, PR process, architecture), see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n---\n\n## Repo Structure\n\n```\ncrates/\n  sprout-relay        # WebSocket relay server — main entry point\n  sprout-core         # Core types, event verification, filter matching\n  sprout-db           # Postgres event store and data access layer\n  sprout-auth         # Authentication and authorization\n  sprout-pubsub       # Redis pub/sub fan-out, presence, typing indicators\n  sprout-mcp          # MCP server providing AI agent tools\n  sprout-acp          # ACP harness bridging Sprout events to AI agents\n  sprout-workflow     # YAML-as-code workflow engine (evalexpr conditions)\n  sprout-search       # Typesense-backed full-text search\n  sprout-audit        # Hash-chain audit log\n  sprout-huddle       # LiveKit audio/video integration\n  sprout-proxy        # Nostr client compatibility proxy\n  sprout-admin        # Operator CLI for relay administration\n  sprout-test-client  # Integration test client and E2E test suite\n  sprout-sdk          # Typed Nostr event builders (used by sprout-mcp and sprout-cli)\n  sprout-media        # Blossom/S3 media storage\n  sprout-cli          # Agent-first CLI\n\ndesktop/              # Tauri 2 + React 19 desktop app\nmigrations/           # SQL migrations (auto-applied on relay startup)\nscripts/              # Dev tooling\n.env.example          # Config template — copy to .env before running\n```\n\n---\n\n## Getting Started\n\n```bash\n. ./bin/activate-hermit   # activate hermit toolchain (Rust, Node, etc.)\ncp .env.example .env      # configure local environment\njust setup                # install deps, run migrations\njust relay                # start relay at ws://localhost:3000\njust ci                   # run before any PR\n```\n\nSee CONTRIBUTING.md for full setup details and dependency requirements.\n\n---\n\n## Quality Gates\n\nRun `just ci` before every PR. It runs: Rust `fmt` + `clippy`, desktop lint\n(Biome), unit tests, desktop build, and Tauri check. All must pass.\n\nRun `just test` for integration tests if you touched `sprout-relay`,\n`sprout-db`, or `sprout-auth` — these require a running Postgres and Redis.\n\nAdditional rules:\n- No `unsafe` code\n- Do not introduce new `unwrap()` or `expect()` in production paths — use `?` and proper error types\n- New public API must have doc comments\n\n---\n\n## Key Patterns\n\n**Dual API surface**: Sprout exposes both a REST API and a NIP-29 WebSocket\nrelay. Both paths converge on shared DB functions in `sprout-db`. When adding\na feature, implement the shared DB logic first, then wire up both surfaces.\n\n**Event kinds**: All event kind integers are defined in\n`sprout-core/src/kind.rs`. New features get new kind integers — add them here\nfirst, then implement handling in the relay.\n\n**Channel scoping**: Channels use `h` tags (NIP-29 group tag), not `e` tags.\nFilters and queries must scope to `h` tags when operating within a channel.\n\n**MCP tools — dual transport**: The MCP server in `sprout-mcp` uses two\npatterns: write operations send signed Nostr events over WebSocket; read\noperations call REST endpoints (see `relay_client.rs` for the HTTP helpers).\nAdd the REST endpoint or event handler first, then add the MCP tool that calls\nit. Do not implement logic directly in MCP handlers.\n\n**Workflow conditions**: `sprout-workflow` uses\n[evalexpr](https://docs.rs/evalexpr) for condition evaluation. Keep expressions\nsimple and testable.\n\n**Thread counters**: `reply_count` and `descendant_count` are materialized on\nthread root events. Any code that inserts replies must update these counters —\ncheck existing reply handlers for the pattern.\n\n---\n\n## Testing\n\n```bash\njust test-unit    # unit tests, no infrastructure needed\njust test         # full integration suite (requires Postgres + Redis)\n```\n\nE2E tests live in `crates/sprout-test-client/tests/`:\n- `e2e_relay.rs` — WebSocket relay protocol\n- `e2e_rest_api.rs` — REST endpoint coverage\n- `e2e_mcp.rs` — MCP tool surface\n- `e2e_tokens.rs` — auth token flows\n- `e2e_workflows.rs` — workflow engine\n- `e2e_media.rs` — media upload/download (Blossom)\n- `e2e_media_extended.rs` — extended media scenarios\n- `e2e_nostr_interop.rs` — Nostr interop (NIP-50 search, NIP-10 threads, NIP-17 gift wraps)\n\nDesktop E2E: `cd desktop && pnpm exec playwright test`\n\nSee [TESTING.md](TESTING.md) for the full multi-agent E2E guide.\n\n---\n\n## Desktop App\n\nThe desktop app is Tauri 2 + React 19 + Vite + Tailwind CSS. Features are\norganized under `desktop/src/features/`. Biome handles linting and formatting.\n\n```bash\njust desktop-dev   # web-only dev server (faster iteration)\njust desktop-app   # full Tauri app with native shell\n```\n\n---\n\n## Mobile App (Flutter)\n\nThe mobile app lives in `mobile/` — a Flutter app using Riverpod + Hooks.\n\n### Architecture\n\n- **State management:** Riverpod + `flutter_hooks` (`HookConsumerWidget`)\n- **Theme:** Catppuccin Latte (light) / Macchiato (dark) — matches desktop\n- **Features:** Isolated under `lib/features/`, shared code in `lib/shared/`\n- **Nostr models:** `lib/shared/relay/nostr_models.dart` — event kinds must\n  stay in sync with `desktop/src/shared/constants/kinds.ts`\n\n### Rules\n\n- **NEVER use `StatefulWidget`** — always use `HookConsumerWidget` or\n  `ConsumerWidget` with `flutter_hooks` for local state.\n- **NEVER run `flutter run`, `flutter build`, `flutter clean`, or\n  `flutter upgrade`** — only `flutter test`, `flutter analyze`, and\n  `dart format` are safe for agents to run.\n- **Do NOT use `print()`** — use `debugPrint()` or structured logging.\n- Prefer `context.colors` and `context.textTheme` (via theme extensions)\n  over raw `Theme.of(context)` calls.\n- Keep widgets small and composable.\n- Feature modules must not import from other feature modules — only from\n  `shared/`.\n- Use `Grid` tokens for spacing, `Radii` for border radius.\n\n### Quality Checks\n\n```bash\ncd mobile\ndart format --output=none --set-exit-if-changed .\nflutter analyze\nflutter test\n```\n\nOr from repo root: `just mobile-check` and `just mobile-test`.\n\n### Testing Conventions\n\n- Prefer **widget tests** over unit tests for UI components — test the\n  whole widget tree, not individual methods.\n- Use `ProviderScope(overrides: [...])` to inject fake notifiers.\n- Fake notifiers should extend the real notifier class and override `build()`.\n- Use the `WidgetHelpers.testable()` wrapper for simple widget tests or\n  build a custom `ProviderScope` + `MaterialApp` when you need specific overrides.\n\n---\n\n## See Also\n\n- [CONTRIBUTING.md](CONTRIBUTING.md) — setup, code style, PR process, how to add event kinds / MCP tools / API endpoints\n- [TESTING.md](TESTING.md) — multi-agent E2E test guide\n- [ARCHITECTURE.md](ARCHITECTURE.md) — system design and component relationships\n- [README.md](README.md) — project overview and quick start\n\n<!-- File: .claude-plugin/marketplace.json (Tokens: ~300 | Category: marketplace) -->\n# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/block/buzz/HEAD/.claude-plugin/marketplace.json)\n\n<!-- File: .claude-plugin/plugin.json (Tokens: ~300 | Category: plugin-manifest) -->\n# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/block/buzz/HEAD/.claude-plugin/plugin.json)\n\n<!-- File: .cursor/mcp.json (Tokens: ~300 | Category: mcp-config) -->\n# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/block/buzz/HEAD/.cursor/mcp.json)\n</yakaai_skills>"}