mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
## Summary
Gives Buzz-hosted git entities the same "GitHub-style" chat experience
GitHub links already get: rich preview cards, real titles, and
click-through — except clicks navigate **in-app** to the Projects view
instead of a browser.
- **Spec**: `docs/buzz-entity-links.md` — link scheme, slices, and
deferred work (`buzz://project`, OS deep links, web routes).
- **Canonical `buzz://` deep links**: new
`desktop/src/shared/lib/entityLink.ts` with builders + strict parser for
`buzz://pr?id=…&owner=…&d=…`, `buzz://issue?…`, and
`buzz://repo?owner=…&d=…`, mirrored by a Rust module
(`crates/buzz-cli/src/links.rs`) with a shared golden-format test so the
two implementations can't drift.
- **Preview cards**: `linkPreview.ts` recognizes `buzz://` entity links
*and* HTTPS relay clone URLs (`{origin}/git/<pubkey>/<repo>`, the shape
agents paste today). Both normalize onto the canonical `buzz://` href,
so the two spellings of a repo dedupe to one `Buzz`-provider card
(`BuzzMark` logo) rendered by `link-preview-attachment.tsx`.
- **Title enrichment**: PR/issue cards fetch the real subject from the
relay event (`subject` tag or first content line) via
`useResolvedLinkPreviews.ts`; the cache is community-scoped and reset in
`resetCommunityState()`.
- **In-app navigation**: clicking a card or inline anchor (including
HTTPS relay clone URLs whose origin matches the active relay) routes to
the canonical `30617:<owner>:<d>` coordinate via `goProject()`
(`markdown/entityLinks.tsx`). **Merge dependency: #4671 must merge
first** — route resolution for `30617:` coordinates is implemented on
that branch (`feat/multi-repository-projects`). Entity-link and
external-anchor logic were extracted out of `markdown.tsx` to stay under
the file-size ratchet.
- **Agent side**: `buzz pr open`, `buzz issues create`, and `buzz repos
create` now return a ready-made `link` field (omitted when the relay
returns `accepted: false`), and `base_prompt.md` instructs agents to
paste it verbatim when announcing work.
## Test plan
- [x] Desktop unit tests: pass, including new `entityLink.test.mjs` and
`linkPreview.test.mjs` coverage (golden formats, malformed-link
rejection, clone-URL/`buzz://` dedupe, origin-gated anchor behavior,
label-must-win invariant, cache epoch)
- [x] Rust: `cargo test -p buzz-cli` golden-format test +
accepted/rejected link guard assertions, clippy + fmt clean
- [x] Biome + `tsc --noEmit` clean; pre-push hooks
(desktop-tauri-checks, rust-tests, desktop-test) pass
- [ ] Manual: paste a relay clone URL and a `buzz://pr` link in a
channel — verify one card each, real PR title, and in-app navigation to
the Projects view
Related: [#4671](https://github.com/block/buzz/pull/4671)
---------
Signed-off-by: Thomas Petersen <thomasp@squareup.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Co-authored-by: npub1g8493u0xfsjrvflg4n08ezd7vec99mnwzlv0qgwpr9d7gvjwhuzqx59rhw <41ea58f1e64c243627e8acde7c89be667052ee6e17d8f021c1195be4324ebf04@buzz.block.builderlab.xyz>
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
52 lines
2.0 KiB
Rust
52 lines
2.0 KiB
Rust
//! Canonical `buzz://` deep links for Buzz-hosted git entities.
|
|
//!
|
|
//! Buzz Desktop renders these links as rich preview cards in chat and
|
|
//! navigates in-app when they are clicked. The desktop parser lives in
|
|
//! `desktop/src/shared/lib/entityLink.ts` — the two implementations must
|
|
//! stay format-compatible (see `golden_format_matches_desktop` below and
|
|
//! the mirror test in `entityLink.test.mjs`).
|
|
//!
|
|
//! Callers are expected to validate inputs first (`validate_hex64`,
|
|
//! `validate_repo_id`); the identifier charsets need no URL encoding.
|
|
|
|
/// Build a `buzz://repo` link for a repository announcement (kind 30617).
|
|
pub fn repo_link(owner: &str, repo_id: &str) -> String {
|
|
format!("buzz://repo?owner={owner}&d={repo_id}")
|
|
}
|
|
|
|
/// Build a `buzz://pr` link for a pull request event (kind 1618).
|
|
pub fn pull_request_link(event_id: &str, owner: &str, repo_id: &str) -> String {
|
|
format!("buzz://pr?id={event_id}&owner={owner}&d={repo_id}")
|
|
}
|
|
|
|
/// Build a `buzz://issue` link for an issue event (kind 1621).
|
|
pub fn issue_link(event_id: &str, owner: &str, repo_id: &str) -> String {
|
|
format!("buzz://issue?id={event_id}&owner={owner}&d={repo_id}")
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
const OWNER: &str = "71d67180ba17e749ee825fc8819c9c6ee7003617e1c126504f9b658070ab9224";
|
|
const EVENT_ID: &str = "c3b589fa5713ba25bad6dc095e2de00a4ac8f50050fdea00fc6444e603be1dd1";
|
|
|
|
// Golden strings shared with desktop/src/shared/lib/entityLink.test.mjs
|
|
// ("builders emit the canonical cross-language link format").
|
|
#[test]
|
|
fn golden_format_matches_desktop() {
|
|
assert_eq!(
|
|
pull_request_link(EVENT_ID, OWNER, "buzz-world"),
|
|
format!("buzz://pr?id={EVENT_ID}&owner={OWNER}&d=buzz-world")
|
|
);
|
|
assert_eq!(
|
|
issue_link(EVENT_ID, OWNER, "buzz-world"),
|
|
format!("buzz://issue?id={EVENT_ID}&owner={OWNER}&d=buzz-world")
|
|
);
|
|
assert_eq!(
|
|
repo_link(OWNER, "buzz-world"),
|
|
format!("buzz://repo?owner={OWNER}&d=buzz-world")
|
|
);
|
|
}
|
|
}
|