feat(#1137): rich unread summary in loose ends and wake signal

- hive-sh4re: UnreadMatrix gains summary: String field (per-room breakdown)
- hive-matrix-mcp/protocol: add RoomUnread struct + UnreadSummary request
- hive-matrix-mcp/handlers: collect_unread() fetches per-room data;
  single-unread rooms include truncated last-message body + sender;
  multi-unread rooms carry count only
- hive-matrix-mcp/wake: format_unread_summary() builds wake body from
  RoomUnread slice; terse one-liner for single-room/single-message,
  bulleted list for multi-room; always appends read-hint
- hive-matrix-mcp/timeline: wake body now covers all rooms with unread
  at fire time, not just the triggering event; falls back to per-event
  teaser if notification counts haven't updated yet
- hive-ag3nt/mcp: matrix_unread_summary() replaces matrix_unread_rooms();
  UnreadMatrix loose end carries per-room summary lines; render shows
  room breakdown with sender: body for single-unread rooms
This commit is contained in:
atlas 2026-06-03 12:52:24 +02:00
commit 68e30b857c
19 changed files with 421 additions and 108 deletions

View file

@ -1,7 +1,7 @@
//! `pr-reviews <number>` — list reviews, or submit one via `--approve` /
//! `--request-changes` / `--comment`.
use anyhow::{bail, Result};
use anyhow::{Result, bail};
use clap::Args as ClapArgs;
use serde_json::{Value, json};
@ -50,8 +50,10 @@ pub fn run(client: &Client, args: Args) -> Result<()> {
"event": ev,
"body": args.body.unwrap_or_default(),
});
let v = client
.post_json(&format!("/repos/{repo}/pulls/{}/reviews", args.number), &payload)?;
let v = client.post_json(
&format!("/repos/{repo}/pulls/{}/reviews", args.number),
&payload,
)?;
// Print a compact summary rather than the full review blob.
let summary = json!({
"id": v.get("id"),
@ -64,8 +66,7 @@ pub fn run(client: &Client, args: Args) -> Result<()> {
bail!("--body requires one of --approve / --request-changes / --comment");
}
// List mode (original behaviour).
let v =
client.get_json(&format!("/repos/{repo}/pulls/{}/reviews", args.number))?;
let v = client.get_json(&format!("/repos/{repo}/pulls/{}/reviews", args.number))?;
let trimmed: Vec<Value> = v
.as_array()
.map(|a| {