feat(cli): require --clear to empty a relay bucket

`relay set --type T` with no URLs is now rejected (bad_args, exit 2) instead
of silently wiping the list — a bare empty `set` is almost always a shell
variable that expanded to nothing. Emptying a bucket is explicit: pass
`--clear` (mutually exclusive with URLs).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EjHzNewJ2sfBGCcSwe35Mc
This commit is contained in:
Claude
2026-07-06 14:30:08 +00:00
parent 0319809b8c
commit c7bde868e1
3 changed files with 12 additions and 3 deletions
+2 -1
View File
@@ -462,7 +462,8 @@ event but do not broadcast — run `relay publish-lists` to push them.
|---|---|
| `amy relay add URL [--type T] [--marker read\|write\|both]` | Append URL to a bucket (default `all`). `--marker` sets the read/write role for `nip65` (default `both`). |
| `amy relay remove URL [--type T]` | Drop URL from a bucket (default `all`). |
| `amy relay set --type T [URL…] [--marker read\|write\|both]` | Replace a bucket's whole list. Passing no URLs clears it. |
| `amy relay set --type T URL… [--marker read\|write\|both]` | Replace a bucket's whole list. |
| `amy relay set --type T --clear` | Empty a bucket. Clearing is explicit — a bare `set` with no URLs is rejected (guards against a shell variable that expanded to nothing); `--clear` and URLs are mutually exclusive. |
| `amy relay list [--type T]` | Print the configured relays for every bucket, or just `T`. |
| `amy relay publish-lists` | Broadcast every configured relay list to the union of your relays. |
@@ -396,8 +396,8 @@ private fun printUsage() {
| [--marker read|write|both] T=nip65|inbox|key_package|search|private|blocked|
| trusted|proxy|indexer|broadcast|feeds|all
| relay remove URL [--type T] drop URL from a bucket (default all)
| relay set --type T [URL] replace a bucket's whole list (no URLs clears it)
| [--marker read|write|both]
| relay set --type T URL [--marker read|write|both] replace a bucket's whole list
| relay set --type T --clear empty a bucket (URLs and --clear are mutually exclusive)
| relay list [--type T] print configured relays (all buckets, or just T)
| relay publish-lists broadcast every configured relay list
| relay info URL fetch + print a relay's NIP-11 info document
@@ -323,6 +323,14 @@ object RelayCommands {
// dedupe, preserve order
val relays = normalized.distinctBy { it.url }
// Clearing a bucket is destructive, so it must be explicit: `--clear`
// with no URLs. A bare `set` with no URLs is almost always a shell
// variable that expanded to nothing — reject it rather than silently
// wiping the list. (require → IllegalArgumentException → bad_args/exit 2.)
val clear = args.bool("clear")
require(relays.isNotEmpty() || clear) { "set needs at least one URL, or --clear to empty the $type list" }
require(relays.isEmpty() || !clear) { "--clear cannot be combined with relay URLs" }
Context.open(dataDir).use { ctx ->
val signed: Event =
if (type == NIP65) {