diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-03-05 14:19:49 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-03-05 14:23:07 +0000 |
| commit | 37244449d6d0d58bb639f181bd15092de1acaaee (patch) | |
| tree | 7de03867a1a9578e32fdbdbb2be63e863cea57a4 /src/lib/client.rs | |
| parent | 609f3c3db02d437222e2c8e171189179d06c3e9c (diff) | |
feat(cover-note): add kind-1624 cover notes for PRs, patches, and issues
Implements experimental kind-1624 cover note events:
- KIND_COVER_NOTE constant and process_cover_note() in git_events.rs;
replaceable semantics (latest created_at, hex-id tiebreak), author or
maintainer only
- kind-1624 events fetched alongside labels in the fetch pipeline;
cover_notes count added to FetchReport display
- ngit pr/issue view: cover note displayed in place of description with
a clear 'Cover Note:' header; maintainer-authored notes identify the
author; original description shown only with --comments; cover_note
object included in --json output
- ngit pr set-cover-note / ngit issue set-cover-note: publish a
kind-1624 event; nostr: mentions in --body converted to q/p tags via
tags_from_content (same rules as issue --body)
- Fix pre-existing clippy::too_many_lines on repo/mod.rs show_info
Diffstat (limited to 'src/lib/client.rs')
| -rw-r--r-- | src/lib/client.rs | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/src/lib/client.rs b/src/lib/client.rs index 94a173f..d5597fa 100644 --- a/src/lib/client.rs +++ b/src/lib/client.rs | |||
| @@ -56,7 +56,7 @@ use crate::{ | |||
| 56 | get_dirs, | 56 | get_dirs, |
| 57 | git::{Repo, RepoActions, get_git_config_item}, | 57 | git::{Repo, RepoActions, get_git_config_item}, |
| 58 | git_events::{ | 58 | git_events::{ |
| 59 | KIND_COMMENT, KIND_LABEL, KIND_PULL_REQUEST, KIND_PULL_REQUEST_UPDATE, | 59 | KIND_COMMENT, KIND_COVER_NOTE, KIND_LABEL, KIND_PULL_REQUEST, KIND_PULL_REQUEST_UPDATE, |
| 60 | KIND_USER_GRASP_LIST, event_is_cover_letter, event_is_patch_set_root, | 60 | KIND_USER_GRASP_LIST, event_is_cover_letter, event_is_patch_set_root, |
| 61 | event_is_revision_root, event_is_valid_pr_or_pr_update, status_kinds, | 61 | event_is_revision_root, event_is_valid_pr_or_pr_update, status_kinds, |
| 62 | }, | 62 | }, |
| @@ -2000,6 +2000,8 @@ async fn process_fetched_events( | |||
| 2000 | report.comments.insert(event.id); | 2000 | report.comments.insert(event.id); |
| 2001 | } else if event.kind.eq(&KIND_LABEL) { | 2001 | } else if event.kind.eq(&KIND_LABEL) { |
| 2002 | report.labels.insert(event.id); | 2002 | report.labels.insert(event.id); |
| 2003 | } else if event.kind.eq(&KIND_COVER_NOTE) { | ||
| 2004 | report.cover_notes.insert(event.id); | ||
| 2003 | } else if [Kind::RelayList, Kind::Metadata, KIND_USER_GRASP_LIST].contains(&event.kind) | 2005 | } else if [Kind::RelayList, Kind::Metadata, KIND_USER_GRASP_LIST].contains(&event.kind) |
| 2004 | { | 2006 | { |
| 2005 | if request.missing_contributor_profiles.contains(&event.pubkey) { | 2007 | if request.missing_contributor_profiles.contains(&event.pubkey) { |
| @@ -2126,6 +2128,9 @@ pub fn consolidate_fetch_reports(reports: Vec<Result<FetchReport>>) -> FetchRepo | |||
| 2126 | for c in relay_report.labels { | 2128 | for c in relay_report.labels { |
| 2127 | report.labels.insert(c); | 2129 | report.labels.insert(c); |
| 2128 | } | 2130 | } |
| 2131 | for c in relay_report.cover_notes { | ||
| 2132 | report.cover_notes.insert(c); | ||
| 2133 | } | ||
| 2129 | report.deletions += relay_report.deletions; | 2134 | report.deletions += relay_report.deletions; |
| 2130 | for c in relay_report.contributor_profiles { | 2135 | for c in relay_report.contributor_profiles { |
| 2131 | report.contributor_profiles.insert(c); | 2136 | report.contributor_profiles.insert(c); |
| @@ -2268,6 +2273,24 @@ pub fn get_fetch_filters( | |||
| 2268 | ] | 2273 | ] |
| 2269 | } | 2274 | } |
| 2270 | }, | 2275 | }, |
| 2276 | // Fetch kind-1624 cover note events for issues and proposals. | ||
| 2277 | // Cover notes reference the target via a lowercase `e` tag. | ||
| 2278 | { | ||
| 2279 | let all_root_ids: HashSet<EventId> = issue_ids | ||
| 2280 | .iter() | ||
| 2281 | .chain(proposal_ids.iter()) | ||
| 2282 | .copied() | ||
| 2283 | .collect(); | ||
| 2284 | if all_root_ids.is_empty() { | ||
| 2285 | vec![] | ||
| 2286 | } else { | ||
| 2287 | vec![ | ||
| 2288 | nostr::Filter::default() | ||
| 2289 | .events(all_root_ids) | ||
| 2290 | .kind(KIND_COVER_NOTE), | ||
| 2291 | ] | ||
| 2292 | } | ||
| 2293 | }, | ||
| 2271 | // Request kind-5 deletions for state events and repo announcements by | 2294 | // Request kind-5 deletions for state events and repo announcements by |
| 2272 | // their event ID (#e tag), as per NIP-09. The #a-tagged filter above | 2295 | // their event ID (#e tag), as per NIP-09. The #a-tagged filter above |
| 2273 | // covers addressable-event deletions; this covers the specific event IDs | 2296 | // covers addressable-event deletions; this covers the specific event IDs |
| @@ -2358,6 +2381,8 @@ pub struct FetchReport { | |||
| 2358 | comments: HashSet<EventId>, | 2381 | comments: HashSet<EventId>, |
| 2359 | /// NIP-32 kind-1985 label events for issues and proposals. | 2382 | /// NIP-32 kind-1985 label events for issues and proposals. |
| 2360 | labels: HashSet<EventId>, | 2383 | labels: HashSet<EventId>, |
| 2384 | /// Kind-1624 cover note events for issues, patches, and PRs. | ||
| 2385 | cover_notes: HashSet<EventId>, | ||
| 2361 | /// Count of kind-5 deletion events received (for display purposes). | 2386 | /// Count of kind-5 deletion events received (for display purposes). |
| 2362 | deletions: u32, | 2387 | deletions: u32, |
| 2363 | contributor_profiles: HashSet<PublicKey>, | 2388 | contributor_profiles: HashSet<PublicKey>, |
| @@ -2453,6 +2478,13 @@ impl Display for FetchReport { | |||
| 2453 | if self.labels.len() > 1 { "s" } else { "" }, | 2478 | if self.labels.len() > 1 { "s" } else { "" }, |
| 2454 | )); | 2479 | )); |
| 2455 | } | 2480 | } |
| 2481 | if !self.cover_notes.is_empty() { | ||
| 2482 | display_items.push(format!( | ||
| 2483 | "{} cover note{}", | ||
| 2484 | self.cover_notes.len(), | ||
| 2485 | if self.cover_notes.len() > 1 { "s" } else { "" }, | ||
| 2486 | )); | ||
| 2487 | } | ||
| 2456 | if self.deletions > 0 { | 2488 | if self.deletions > 0 { |
| 2457 | display_items.push(format!( | 2489 | display_items.push(format!( |
| 2458 | "{} deletion{}", | 2490 | "{} deletion{}", |