Skip to content

feat(cli): scope buzz messages search by channel, kind, and upper time bound - #3561

Open
mvanhorn wants to merge 1 commit into
block:mainfrom
mvanhorn:fix/buzz-cli-messages-search-scoping
Open

feat(cli): scope buzz messages search by channel, kind, and upper time bound#3561
mvanhorn wants to merge 1 commit into
block:mainfrom
mvanhorn:fix/buzz-cli-messages-search-scoping

Conversation

@mvanhorn

@mvanhorn mvanhorn commented Jul 29, 2026

Copy link
Copy Markdown

Summary

buzz messages search scoped by channel, kind, and upper time bound

Simulated demo. Every terminal frame is verbatim captured output — the opening is this branch's parent commit rejecting --channel before the flags existed. No search results are shown; the filter shapes are the ones the new unit tests assert.

buzz messages search accepts --query, --author, --since, and --limit. It builds its relay filter with a hardcoded kinds array and no channel constraint, so an agent asking "what did we say about the checkout bug in #eng-relay last week" has to pull unscoped hits and filter client-side.

All three capabilities already exist on the other side of the wire:

  • SearchQuery in buzz-search declares both since and until ("NIP-01 until (Unix seconds). Inclusive upper bound on created_at"). --since was reachable; --until was not.
  • Every other channel-scoped read path in this crate already sends "#h"cmd_get_messages (messages.rs:277), cmd_thread (:321), plus channels.rs and workflows.rs. Search was the one read path that could not narrow to a room.
  • SearchQuery.kinds is Option<Vec<i32>>, but the CLI pinned four values.

This adds three optional flags that map onto NIP-01 filter fields the relay already honors on this exact code path:

flag filter field
--channel <UUID> "#h": [uuid]
--until <UNIX_SECONDS> "until": n
--kinds <N,N,...> replaces the default kinds array

--kinds is named to match AGENTS.md, which already instructs agents to "pass at least --kinds 9,45001,45003 to scope the query" to avoid the relay p-gate. That flag did not exist yet, so the documented invocation was not previously possible.

Two guards fire locally, before any network call, matching the existing "at least one of --query or --author is required" check:

  • --since later than --until returns CliError::Usage.
  • A malformed --channel goes through the crate's existing validate_uuid rather than becoming a silent zero-hit query.

The filter construction moves into build_search_filter so its shape is testable without a relay. cmd_search calls it; behavior is otherwise unchanged.

Related issue

None found. Searched open issues and PRs for messages search, search channel, and search until — no duplicates.

Closest prior art is #1665 (feat(cli): --author and --since filters on buzz messages search, merged), which widened this command's filter surface and stopped short of channel scope and the upper time bound. #712 (feat(cli): add channels search, merged) is the same shape of change one command group over.

Testing

cargo test -p buzz-cli — 258 passed, 0 failed. Six new unit tests in commands::messages::search_filter_tests cover the filter shape without needing a relay:

  • default kinds when --kinds is omitted → [9, 40002, 45001, 45003]
  • explicit kinds replace the defaults
  • --channelfilter["#h"] == [uuid]
  • --channel absent → no #h key at all (regression guard on the existing unscoped path)
  • --until present and absent
  • all three flags omitted → filter is byte-identical to what the command sent before, asserted against a literal

just fmt and cargo clippy -p buzz-cli --all-targets -- -D warnings are both clean.

Local verification against the built binary:

$ buzz messages search --help
      --query <QUERY>      Search query string (optional when --author is given)
      --author <AUTHOR>    Filter by author: 64-char hex pubkey, npub, or display name
      --since <SINCE>      Unix timestamp — return messages after this time
      --until <UNTIL>      Unix timestamp — return messages before this time
      --channel <CHANNEL>  Channel UUID — restrict results to one channel (from 'buzz channels list')
      --kinds <KINDS>      Nostr event kinds to search (comma-separated) — defaults to chat, channel, and forum kinds
      --limit <LIMIT>      Maximum number of results to return

$ buzz messages search --query x --since 200 --until 100
{"error":"user_error","message":"--since must not be later than --until","retryable":false}

$ buzz messages search --query x --channel not-a-uuid
{"error":"user_error","message":"invalid UUID: not-a-uuid","retryable":false}

Both guards return before any relay connection is attempted.

No UI change. crates/buzz-cli/README.md documents the three flags.


AI was used for assistance. I wrote, ran, and reviewed the final code and tests.

…e bound

buzz messages search accepted --query, --author, --since, and --limit, and
built its relay filter with a hardcoded kinds array and no channel constraint.
The relay-side SearchQuery already declares until and kinds, and every other
channel-scoped read path in the crate already sends #h, so the capability
existed server-side but was unreachable from the CLI.

Add three optional flags that map onto NIP-01 filter fields the relay already
honors on this code path:

  --channel <UUID>  -> filter["#h"] = [uuid]
  --until <UNIX>    -> filter["until"] = n
  --kinds <N,N>     -> replaces the default kinds array

AGENTS.md already tells agents to pass --kinds 9,45001,45003 to avoid the
relay p-gate; this makes that documented invocation real.

Omitting all three emits a filter byte-identical to the previous one, covered
by a regression test. --since later than --until and a malformed --channel
both fail locally with CliError::Usage before any network call.

The filter build moves into build_search_filter so the shape is testable
without a relay.

Signed-off-by: Matt Van Horn <mvanhorn@gmail.com>
@mvanhorn
mvanhorn requested a review from a team as a code owner July 29, 2026 15:12

@Chessing234 Chessing234 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Natural CLI extension — --channel, --kinds, and --until were already on the wire via SearchQuery, so exposing them on buzz messages search removes a whole class of client-side filter work for agents. README + clap wiring look consistent with the rest of the messages command family. LGTM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants