mirror of
https://github.com/block/buzz.git
synced 2026-10-30 05:51:46 +00:00
Add a dm.send command to the canvas widget SDK so a widget can deliver a
message to a user's DM as the viewing user, behind a new consent-gated
app.dm.send capability.
- Protocol: app.dm.send joins the capability schema and the consequential
(consent-required) set in projectCanvasProtocol.ts, mirrored in the Rust
manifest validator's ALLOWED_CAPABILITIES. The consent banner names it
"send direct messages as you" and now joins three-plus capability
phrases as a serial list instead of chaining " and ".
- Broker: dm.send takes strict {pubkey, message} params — 64-hex
recipient, message capped at 2,000 chars and rejected when blank after
trimming — and dispatches to a new sendDirectMessage delegate with the
recipient lowercased. Like the existing `user` open target, the
recipient is any valid pubkey rather than a host-source row, because
legitimate recipients come from people.lookup/people.search results,
which are not host sources; containment is the per-revision consent
gate, the 10-per-minute command budget, and a host toast on every send.
- Delegate: useProjectCanvasBroker captures tenant scope (normalized
relay URL + signer pubkey) before the first await so the backend fails
closed if the community or identity changes mid-send, opens the DM via
useOpenDmMutation (which also upserts the conversation into the
sidebar), and sends over the HTTP path because a freshly opened DM has
no live subscription yet. ProjectChannelHome feeds the community relay
URL through a new relayUrl parameter.
- Host: success toasts "Canvas sent a direct message"; failures title as
"Canvas direct message failed" instead of borrowing the task-update
title.
- Template: the support dashboard's bug reporter now delivers the report
as a DM to the project owner (resolved via project.metadata) when
app.dm.send and project.metadata.read are granted, showing "Report
sent"; without the capability it stages the report exactly as before.
The bundled manifest requests app.dm.send.
- Docs: base_prompt.md and nest_skill.md document dm.send, its params,
and the third consent capability; the buzz-acp doc-binding test now
asserts both `dm.send` and `app.dm.send` so the prompt cannot drift.
Tests: new broker coverage for the capability gate, param bounds, blank
and oversized messages, unknown keys, and recipient normalization; the
external-template harness drives the real bug reporter through the SDK
(metadata query -> dm.send command -> success copy) and pins the staged
fallback when the capability is missing; protocol tests cover the
granted/consent/effective sets with the new capability; the Rust
manifest test accepts the full eight-capability set.
Verified: desktop unit suite 5898 passing, Tauri lib suite 3077 passing,
buzz-acp prompt tests passing, canvas e2e spec 7 passing, and clippy -D
warnings, rustfmt, biome, tsc, and the file-size gate all clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>