diff --git a/crates/buzz-cli/src/lib.rs b/crates/buzz-cli/src/lib.rs index 61cdff22d..bf748d901 100644 --- a/crates/buzz-cli/src/lib.rs +++ b/crates/buzz-cli/src/lib.rs @@ -488,7 +488,7 @@ pub enum MessagesCmd { }, /// Get a message thread (replies to a root message) #[command( - after_help = "Pagination:\n Returns up to --limit replies (default 100, max 500) plus the root event.\n Replies without a cursor and without --depth-limit are NEWEST-first; either\n one selects the OLDEST-first walk, so the cursor picks which end you see.\n\n To page a thread larger than the cap, walk FORWARD from the oldest reply.\n Seed with --after 0, then pass the newest reply of each page back in:\n\n buzz messages thread --channel --event --limit 500 --after 0\n buzz messages thread --channel --event --limit 500 \\\n --after --after-id \n\n Always pass --after-id. The timestamp-only cursor is STRICTLY greater-than,\n so a page boundary landing inside a second shared by several replies skips\n the rest of that second silently (rc=0). --after-id carries the tiebreak, so\n no reply is skipped regardless of where the boundary lands.\n\nServer path and counts:\n The cursor is honoured only on the depth-limited server path; a filter\n without a depth bound routes to a generic query that has no cursor. So\n --depth-limit selects WHICH server code path serves the request, which\n its name does not suggest. Passing --after implies a depth bound meaning\n \"no effective limit\" so the cursor is always reached.\n\n The root event is fetched by a SECOND filter that carries no cursor, no\n depth bound and its own limit of 1. It therefore reappears on every page\n and does not consume a reply slot: expect --limit + 1 events per page,\n and dedupe the root when concatenating pages.\n\nKind scope:\n Replies are limited to kinds 9,40002,40003,40008,45003 (message, message\n v2, edit, diff, forum comment) and NOTHING ELSE. Notably EXCLUDED:\n reactions (7) and deletions (5) — on a busy thread these outnumber the\n replies, and no flag here surfaces them, so a reply count is not a thread\n event count. This list intentionally differs from `messages get`, which\n omits edits (40003) and includes forum posts (45001)." + after_help = "Pagination:\n Returns up to --limit replies (default 100, max 500) plus the root event.\n Replies without a cursor and without --depth-limit are NEWEST-first; either\n one selects the OLDEST-first walk, so the cursor picks which end you see.\n\n To page a thread larger than the cap, walk FORWARD from the oldest reply.\n Seed with --after 0, then pass the newest reply of each page back in:\n\n buzz messages thread --channel --event --limit 500 --after 0\n buzz messages thread --channel --event --limit 500 \\\n --after --after-id \n\n Always pass --after-id. The timestamp-only cursor is STRICTLY greater-than,\n so a page boundary landing inside a second shared by several replies skips\n the rest of that second silently (rc=0). --after-id carries the tiebreak, so\n no reply is skipped regardless of where the boundary lands.\n\nServer path and counts:\n The cursor is honoured only on the depth-limited server path; a filter\n without a depth bound routes to a generic query that has no cursor. So\n --depth-limit selects WHICH server code path serves the request, which\n its name does not suggest. Passing --after implies a depth bound meaning\n \"no effective limit\" so the cursor is always reached.\n\n Those two paths answer DIFFERENT QUESTIONS, not the same question at\n different speeds. The depth-limited path returns DESCENDANTS BY THREAD\n ANCESTRY, built from rows the relay writes at ingest only for events that\n carry a NIP-10 MARKED e tag (root/reply). The path without a depth bound\n returns every event that REFERENCES the id by any e tag. Two measured\n consequences: message edits (40003) carry a bare e tag, get no ancestry\n row, and are ABSENT from the depth-limited path; and a thread requested on\n a MID-THREAD event returns that event ALONE there, because no ancestry row\n names it as a root. Since --after implies a depth bound, a forward walk\n pays both. The ancestry path also ignores the filter kinds, so the two\n result sets are not nested in either direction by construction.\n\n The root event is fetched by a SECOND filter that carries no cursor, no\n depth bound and its own limit of 1. It therefore reappears on every page\n and does not consume a reply slot: expect --limit + 1 events per page,\n and dedupe the root when concatenating pages.\n\nKind scope:\n Replies are limited to kinds 9,40002,40003,40008,45003 (message, message\n v2, edit, diff, forum comment) and NOTHING ELSE. Notably EXCLUDED:\n reactions (7) and deletions (5) — on a busy thread these outnumber the\n replies, and no flag here surfaces them, so a reply count is not a thread\n event count. This list intentionally differs from `messages get`, which\n omits edits (40003) and includes forum posts (45001).\n This list is applied on the path WITHOUT a depth bound; the ancestry path\n ignores it, so --depth-limit and --after change the kind mix too." )] Thread { /// Channel UUID @@ -503,7 +503,8 @@ pub enum MessagesCmd { #[arg(long)] limit: Option, /// Maximum reply nesting depth to include. Also selects the - /// oldest-first reply ordering and the cursor-capable server path + /// oldest-first reply ordering, the cursor-capable server path, and a + /// result set defined by thread ancestry rather than e-tag reference /// (see Pagination below) #[arg(long)] depth_limit: Option,