Files
amethyst/cli/ROADMAP.md
T
Claude 6ef0c372b1 docs(cli): make USAGE.md the README; move contract material to DEVELOPMENT
USAGE.md was the better README — entry-point users want examples and
quick start, not the public-API contract. Flip them and refresh the
amy-expert skill so it matches the post-refactor reality.

cli/README.md (was USAGE.md):
- Install, quick start, seven worked examples, full command reference,
  output modes, multi-account workflows, agent recipes, troubleshooting.
- Cross-refs point at DEVELOPMENT.md for the contract / architecture
  and ROADMAP.md for what's coming.

cli/DEVELOPMENT.md absorbs the old README's architecture sections:
- New "Public contract" section at the top — the stable promises
  (text-default + --json contract, stderr for humans, exit codes,
  ~/.amy/ as the world).
- "Local event store" deep-dive with the cache-helper API.
- "Relay routing" rules table.
- "Full on-disk layout" tree with annotations.

cli/ROADMAP.md, cli/USAGE.md:
- ROADMAP cross-refs collapsed (no more USAGE.md row).
- USAGE.md deleted — content lives in README now.

.claude/skills/amy-expert refreshed end-to-end:
- SKILL.md description + Rules 2 and 4 rewritten for the dual-output
  contract (text default, --json opt-in) and the ~/.amy/ layout.
- "Where things live" listing matches the current source tree
  (Output.kt, Aliases.kt, UseCommand.kt, secrets/, all the new
  command files).
- "Common mistakes" lists the new traps: don't read user.home
  directly, don't add a global flag that collides with subcommand
  --name, don't use Json.writeLine (it's gone).
- references/command-template.md uses Output.emit / Output.error
  (Json.writeLine / Json.error helpers no longer exist).
- references/output-conventions.md rewritten around the dual-mode
  contract — same JSON shape rules, but framed as "this is what
  --json emits" rather than "this is stdout."
2026-04-25 16:35:10 +00:00

117 lines
5.6 KiB
Markdown

# Amy Roadmap
The live checklist for growing `amy` from a Marmot test-bed into a
full command-line mirror of Amethyst.
**How to use this file:** update it in the same PR that ships a
feature. Move rows between tables, adjust ordering, add non-goals.
This is the single source of truth for "what's left".
- What amy is + how to use it: [README.md](./README.md)
- The public contract + how to extend amy: [DEVELOPMENT.md](./DEVELOPMENT.md)
- Ongoing design plans: [plans/](./plans/)
- Shared work consumed here: [../commons/plans/](../commons/plans/)
---
## North-star goal
> For every feature of the Amethyst Android app, there is a way to
> exercise it through `amy`, with byte-identical on-relay behaviour.
Why:
- Interop tests against the ~100 other Nostr clients need a
reproducible harness that does not require running Android.
- Agents and LLMs can script real Amethyst flows without a GUI.
- Regressions in shared logic (signing, encryption, filter building,
event parsing) become shell-scriptable.
- Power users get a command-line Amethyst for free.
**Non-goal:** Amy is not a second Nostr client implementation. It is
a thin assembly layer over `quartz` + `commons`. Protocol and business
logic in `cli/` are bugs.
---
## Parity matrix
Status legend: ✅ shipped · 📦 logic lives in `commons/`, needs a command ·
🆕 needs extraction from `amethyst/` first · ⚠️ blocked (see Notes).
| Area | Status | Notes |
|---|---|---|
| Identity create / import (`nsec`, `ncryptsec`, mnemonic, `npub`, `nprofile`, hex, NIP-05) | ✅ | `LoginCommand` + Quartz NIP-05 / NIP-06 / NIP-49 |
| Account bootstrap (nine events) | ✅ | `commons/account/AccountBootstrapEvents.kt` |
| Relay config + NIP-65 / NIP-10050 publish | ✅ | `RelayCommands` |
| MLS KeyPackage publish + fetch | ✅ | `commons/marmot/MarmotManager` |
| Marmot group create / add / rename / promote / demote / remove / leave | ✅ | `commons/marmot/` |
| Marmot message send / list | ✅ | `commons/marmot/` |
| `await` polling (KP / group / member / admin / message / rename / epoch) | ✅ | `AwaitCommands` |
| NIP-01 note publish (`amy notes post TEXT`) | ✅ | `PostCommand` — outbox via `RelayCommands` configured set. |
| NIP-01 feed read (`amy notes feed [--following \| --author NPUB]`) | ✅ | `FeedCommand`. Hashtag / community feeds still pending. |
| NIP-02 follow list add / remove / list | 🆕 | Logic in `amethyst/model/nip02FollowLists/`. |
| NIP-09 event deletion | 🆕 | Builder exists in quartz. |
| NIP-17 DMs send / list / await | ✅ | `DmCommands` — reuses Quartz `NIP17Factory` + `RecipientRelayFetcher`; filter extracted to `commons/relayClient/nip17Dm/`. Plan: [`cli/plans/2026-04-23-nip17-dm.md`](./plans/2026-04-23-nip17-dm.md). |
| NIP-18 reposts / quotes | 🆕 | |
| NIP-25 reactions | ✅ in groups · 🆕 elsewhere | `marmot message react` covers MLS group reactions; outer-event reactions still pending. |
| NIP-51 lists (bookmarks, mute, follow sets) | 🆕 | `amethyst/model/nip51Lists/` |
| NIP-57 zaps (send + verify) | 🆕 | Needs LN-URL plumbing; `amethyst/service/lnurl/`. |
| NIP-65 outbox model queries | 🆕 | |
| NIP-72 communities | 🆕 | |
| NIP-78 app-specific data (settings sync) | 🆕 | |
| Long-form (NIP-23) publish / read | 🆕 | |
| Live activities / chess (NIP-53 / NIP-64) | 🆕 | |
| Blossom uploads (NIP-B7) | 🆕 | |
| NIP-47 Wallet Connect | 🆕 | |
| NIP-46 bunker signer | 🆕 | Needs a signers abstraction in Amy. |
| Profile view (`amy profile show NPUB`) + edit | ✅ | `ProfileCommands`. Cache-first; `--refresh` forces a relay drain. |
| Thread view (`amy thread show EVENT_ID`) | ⚠️ | Same. |
| Notifications feed | 🆕 | |
| Search (NIP-50) | 🆕 | |
---
## Order of operations
Proposed sequencing. Each step is one PR. Each step should extract
at least one file from `amethyst/` into `commons/`; if it doesn't
move anything, re-audit — you're probably duplicating logic.
1. **Event rendering core** in `commons/commonMain/.../rendering/`
with renderers for kinds 0 / 1 / 3 / 6 / 7 / 10002 / 10050.
Unblocks all the 🆕 and ⚠️ read-path rows below.
Design: `commons/plans/2026-04-21-event-renderer.md`.
2. **`amy notes post` / `amy notes show` / `amy notes react`** —
smallest end-to-end write+read loop outside Marmot. Post + feed
✅ shipped; `notes show` and outer-event `react` still pending.
3. **`amy notes feed home|profile|hashtag|thread`** reading through the
renderer. `--following` and `--author NPUB` ✅; hashtag/thread
variants still pending.
4. **`amy follow add|remove|list`** (NIP-02) — proves extraction of
list-building logic from `amethyst/model/`.
5. **`amy dm send|list`** (NIP-17) — ✅ shipped. Reuses the gift-wrap
path also exercised by Marmot.
6. **`amy list bookmarks|mute|pin …`** (NIP-51).
7. **`amy zap send|verify`** (NIP-57).
8. **Distribution** — Homebrew + Scoop + `.deb` in the same release
pipeline as desktop. Plan: `cli/plans/2026-04-21-cli-distribution.md`.
9. **Test suite** — end-to-end against a local relay. Marmot interop is
covered by `cli/tests/marmot/marmot-interop-headless.sh`; NIP-17 DM
interop between two `amy` clients is covered by
`cli/tests/dm/dm-interop-headless.sh` (text + file + strict 10050 +
fallback + cursor-advance). Neither runs in CI yet (both need Rust +
~3 min cold relay build).
10. **Everything else in the matrix.**
---
## Non-goals
- Interactive TUI or REPL.
- Native image (GraalVM) until Quartz has a pure-Kotlin signer
fallback — `secp256k1-kmp-jni-*` needs JNI today.
- A Gradle dependency on `:amethyst` or `:desktopApp`. Ever.
- Re-implementing any Nostr protocol piece that's already in
`quartz/` or in another client's library.