Files

115 lines
4.9 KiB
Markdown

NIP-CD
======
Slash Commands
--------------
`draft` `optional`
A slash command is an interface published by a service, invoked as plain text in the content of any event. Invocations carry no tags and require no client support.
## Slash command definition
A kind `31992` event defines a slash command using the following tags:
- `command` - the trigger, without a leading slash. Required.
- `title` - short human-readable name. Required.
- `description` - usage, including any reply or context conventions. Required.
- `arg` - one argument. Ordered.
- `s` - a `scope` (defined below) indicating what events trigger this slash command.
An `arg` tag is `["arg", <name>, <type>, "required" | "optional", <label>, <choice>...]`. `<choice>` elements apply to type `enum` only.
Arguments are positional. Optional/text arguments MUST come after required arguments, and there can be at most one of either.
`scopes` are defined as follows:
- `kind:<kind>` - an invocation's `kind` must match `<kind>`.
- `relay:<url>` - the executor only listens on the given `<url>`.
- `author:<pubkey>` - an invocation must have an `author` matching `<pubkey>`.
- `tag:<tag>` - an invocation must include a non-empty `<tag>` tag.
- `tag:<tag>:<value>` - an invocation must have a `<tag>` tag matching `{value}`.
Scopes combine like a filter: those of the same type (grouped by tag name, for `tag` scopes) are alternatives, scopes of different types must all match, and an absent type is unrestricted.
```json
{
"kind": 31992,
"tags": [
["d", "8f2c1a"],
["command", "ban"],
["title", "Ban a user"],
["description", "Removes a user. Reply to a message to ban its author."],
["arg", "target", "pubkey", "required", "Who to ban"],
["arg", "reason", "text", "optional", "Why"],
["s", "kind:9"],
["s", "kind:11"],
["s", "tag:h:62af9b0"],
["s", "relay:wss://relay.example"]
]
}
```
## Invocation
```
/<command>[@nostr:<pubkey>] [<arg>...] [<text>]
```
Invocations appear in the `content` of any event and carry no tags.
- An invocation MUST begin at index `0` of `content`.
- `<pubkey>` is `npub1…`, and terminates at the end of the bech32 character set.
- Without `<pubkey>`, the invocation targets every slash command whose `command` tag matches and whose scope includes the event, which may result in multiple invocations across different executors.
- Arguments are separated by whitespace. A `text` argument consumes the remainder of `content` verbatim, including whitespace and newlines.
```
/ban@nostr:npub1qqqs... nostr:npub1abcd... repeatedly spamming links
```
## Argument types
- `pubkey` - hex, `nostr:npub1…`, `nostr:nprofile1…`
- `event` - hex, `nostr:note1…`, `nostr:nevent1…`
- `address` - `nostr:naddr1…`
- `relay` - websocket URL
- `number` - decimal digits
- `bool` - `true|false|yes|no|1|0|t|f|y|n`
- `enum` - one of the `<choice>` values on the `arg` tag
- `word` - any run of non-whitespace characters
- `text` - the remainder of `content`
## Executor behavior
An executor reads events within the scope it declares and matches invocations against its own definitions. It MUST ignore content not beginning at index `0`, and MUST accept both the bare and `nostr:`-prefixed forms of a qualifier and of any argument.
Executors may document additional trigger conditions, reply conventions, or ways to bring in additional context in the `description`. For example, a bot may take a `q` tagged event into consideration, or respond multiple times with emojis, zaps, comments, emails, etc.
## Client behavior
All client support is optional.
Clients MAY offer autocomplete for definitions in scope, insert arguments through a picker appropriate to each type, and render recognized invocations as a chip. A client SHOULD omit `@nostr:<pubkey>` and MAY insert it to target a single executor. Where a trigger resolves to more than one definition, a client SHOULD present all of them.
A client MUST NOT require its own support to send an invocation, and MUST send content that fails to parse as ordinary text.
## Installed slash commands
Users MAY keep a kind `10992` [NIP-51](51.md) list of `a` tags pointing to the definitions they want available. Clients SHOULD use it as the source for autocomplete and for rendering invocations as chips, and MAY offer to add or remove a definition from it wherever one is displayed.
```json
{
"kind": 10992,
"tags": [
["a", "31992:<executor-pubkey>:8f2c1a", "wss://relay.example"]
]
}
```
## Slash command discovery
Slash commands should be published to relays where they can be discovered by the relevant users:
- For slash commands related to relays-as-groups or nip29 groups, slash command definitions and invocations should be published to the group relay
- For slash commands related to broadcast social media use cases, slash command definitions should be published to executor outboxes and optionally slash-command-specific indexing relays, while slash command invocations should be published to executor inboxes.