Motivation
An agent posts links into a channel on a self-hosted relay. The Buzz desktop client renders those links bare, while the same links posted by a human from the desktop app render as rich cards.
The card comes from a tag the sender embeds, not from anything the recipient does - desktop/src/shared/ui/markdown/useMessageLinkPreviews.ts states the privacy model explicitly ("recipients never contact external sites"), and desktop/src/shared/lib/linkPreviewSnapshot.ts parses it:
["link-preview", "snapshot", "1", <canonical url>, <title>, <site>, <description>,
<image url>, <image sha256>, <favicon url>, <favicon sha256>]
The desktop app writes it through desktop/src-tauri/src/link_preview_tags.rs, whose validation matches the reader's. An image must be relay-hosted at /media/<sha256>.<jpg|png|gif|webp> with a matching hash, which buzz upload file already produces - so the only missing piece is attaching the tag.
The gap: crates/buzz-cli/src/commands/messages.rs builds an event's tags entirely from SendMessageParams - channel, content, kind, reply-to, broadcast, files, mentions. There is no way to pass an arbitrary tag, so a CLI or SDK client cannot produce a card that the app produces routinely. Non-desktop senders (agents, bots, CI, mobile tooling) are second-class in the timeline as a result.
Proposed solution
--tag '["link-preview","snapshot","1",...]' (repeatable) on messages send, with the relay or CLI applying the same validation the desktop writer applies. This is the most generally useful and the smallest change: every other NIP this project adds later becomes reachable from the CLI at the same time.
Alternatives considered
- A purpose-built
--link-preview <json> flag, if arbitrary tags are considered too broad a surface to expose. More conservative, but each future tag kind then needs its own flag.
- Exposing
link_preview_tags::append-equivalent validation from the SDK so a client can build the tag and hand it to build_message.
- Workaround in use meanwhile:
messages send --file <thumbnail>, which uploads an image and appends  to the body. It shows a picture, but it edits the message body rather than annotating it, and it produces no title, site or description.
Additional context
Relay 0.2.1; CLI built from main as of 2026-08-12; checked again against main on 2026-08-23 (SendMessageParams unchanged).
Duplicates: none found (searched open issues and PRs for link-preview / tag / messages send).
Motivation
An agent posts links into a channel on a self-hosted relay. The Buzz desktop client renders those links bare, while the same links posted by a human from the desktop app render as rich cards.
The card comes from a tag the sender embeds, not from anything the recipient does -
desktop/src/shared/ui/markdown/useMessageLinkPreviews.tsstates the privacy model explicitly ("recipients never contact external sites"), anddesktop/src/shared/lib/linkPreviewSnapshot.tsparses it:The desktop app writes it through
desktop/src-tauri/src/link_preview_tags.rs, whose validation matches the reader's. An image must be relay-hosted at/media/<sha256>.<jpg|png|gif|webp>with a matching hash, whichbuzz upload filealready produces - so the only missing piece is attaching the tag.The gap:
crates/buzz-cli/src/commands/messages.rsbuilds an event's tags entirely fromSendMessageParams- channel, content, kind, reply-to, broadcast, files, mentions. There is no way to pass an arbitrary tag, so a CLI or SDK client cannot produce a card that the app produces routinely. Non-desktop senders (agents, bots, CI, mobile tooling) are second-class in the timeline as a result.Proposed solution
--tag '["link-preview","snapshot","1",...]'(repeatable) onmessages send, with the relay or CLI applying the same validation the desktop writer applies. This is the most generally useful and the smallest change: every other NIP this project adds later becomes reachable from the CLI at the same time.Alternatives considered
--link-preview <json>flag, if arbitrary tags are considered too broad a surface to expose. More conservative, but each future tag kind then needs its own flag.link_preview_tags::append-equivalent validation from the SDK so a client can build the tag and hand it tobuild_message.messages send --file <thumbnail>, which uploads an image and appendsto the body. It shows a picture, but it edits the message body rather than annotating it, and it produces no title, site or description.Additional context
Relay
0.2.1; CLI built frommainas of 2026-08-12; checked again againstmainon 2026-08-23 (SendMessageParamsunchanged).Duplicates: none found (searched open issues and PRs for link-preview / tag / messages send).