mirror of
https://github.com/block/buzz.git
synced 2026-11-05 00:41:28 +00:00
feat(desktop): add persistent Bestie experience (#7223)
## Summary - add a persistent, community-scoped Bestie designation for local managed agents - surface the designated agent in the sidebar, agent library, profile actions, message toolbar, and draggable floating shortcut - bloom the floating shortcut into a lightweight compact composer that reuses the normal DM timeline, reactions, presence, and send behavior - support message handoff with a bounded snapshot and a full Buzz thread link so the agent can retrieve the complete conversation ## UX details - the floating avatar and expanded panel stay above app chrome and drag as one aligned surface - closing the expanded panel returns it to its top-right anchor - each mini-composer opening starts visually fresh while messages sent during that opening remain conversational - the designated Bestie's duplicate DM entry is hidden from the regular DM list - Bestie actions are suppressed inside the mini timeline to avoid recursive handoff ## Reliability and maintainability - preserve existing retention database paths across upgrades - serialize assignment and deletion, clearing matching assignments across community scopes before an agent is removed - fence async conversation resolution against workspace and assignment changes - validate stale assignments against existing local agents before hiding DMs - share lightweight assignment state across agent cards and keep protected-feature behavior out of the shared timeline API ## Testing - `pnpm --dir desktop test` — 5,886 tests passed - `pnpm --dir desktop exec tsc --noEmit` - `pnpm --dir desktop exec biome check ...` - `cargo clippy --manifest-path desktop/src-tauri/Cargo.toml --all-targets -- -D warnings` - focused native retention and Bestie assignment/command tests — 34 passed - `VITE_BUZZ_BESTIE=1 pnpm --dir desktop build:e2e` - `VITE_BUZZ_BESTIE=1 pnpm --dir desktop exec playwright test --project=smoke tests/e2e/bestie.spec.ts` - pre-commit and differential pre-push hooks ## Rollout The UI remains gated by the `bestie` build feature. Screenshots covering setup, empty, assigned, floating, and message-handoff states are included in the PR discussion. --------- Signed-off-by: Arjun Mahanti <arjun@squareup.com> Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -2475,6 +2475,7 @@ function resetMockRelayAgents(config?: E2eConfig) {
|
||||
|
||||
function resetMockManagedAgents(config?: E2eConfig) {
|
||||
mockManagedAgents = [];
|
||||
mockBestieAssignment = null;
|
||||
mockManagedAgentRuntimes = (config?.mock?.managedAgentRuntimes ?? []).map(
|
||||
(seed) => ({
|
||||
pubkey: seed.pubkey,
|
||||
@@ -3225,6 +3226,9 @@ let mockClosedChannelLiveSubscription = false;
|
||||
const realSockets = new Map<number, WebSocket>();
|
||||
let mockManagedAgents: MockManagedAgent[] = [];
|
||||
let mockManagedAgentRuntimes: MockManagedAgentRuntimeRow[] = [];
|
||||
let mockBestieAssignment: {
|
||||
agent_pubkey: string;
|
||||
} | null = null;
|
||||
|
||||
// Mutable `save_subscriptions` table mirror — TEST-ONLY.
|
||||
//
|
||||
@@ -9694,6 +9698,9 @@ async function handleDeleteManagedAgent(args: {
|
||||
mockManagedAgents = mockManagedAgents.filter(
|
||||
(candidate) => candidate.pubkey !== args.pubkey,
|
||||
);
|
||||
if (mockBestieAssignment?.agent_pubkey === args.pubkey) {
|
||||
mockBestieAssignment = null;
|
||||
}
|
||||
syncMockRelayAgentsFromManagedAgents();
|
||||
}
|
||||
|
||||
@@ -13734,6 +13741,32 @@ export function maybeInstallE2eTauriMocks() {
|
||||
);
|
||||
case "list_managed_agent_runtimes":
|
||||
return mockManagedAgentRuntimes.map((row) => ({ ...row }));
|
||||
case "get_bestie_assignment":
|
||||
return mockBestieAssignment ? { ...mockBestieAssignment } : null;
|
||||
case "assign_bestie": {
|
||||
const agentPubkey = (payload as { agentPubkey: string }).agentPubkey;
|
||||
const agent = getMockManagedAgent(agentPubkey);
|
||||
if (agent.backend.type !== "local") {
|
||||
throw new Error("only a local managed agent can be your Bestie");
|
||||
}
|
||||
mockBestieAssignment = {
|
||||
agent_pubkey: agent.pubkey,
|
||||
};
|
||||
return { ...mockBestieAssignment };
|
||||
}
|
||||
case "clear_bestie_assignment":
|
||||
mockBestieAssignment = null;
|
||||
return undefined;
|
||||
case "resolve_bestie_conversation": {
|
||||
if (!mockBestieAssignment) {
|
||||
throw new Error("choose an agent before opening Bestie");
|
||||
}
|
||||
const channel = await handleOpenDm(
|
||||
{ pubkeys: [mockBestieAssignment.agent_pubkey] },
|
||||
activeConfig,
|
||||
);
|
||||
return channel;
|
||||
}
|
||||
case "start_managed_agent_runtime":
|
||||
return handleManagedAgentRuntimeAction(
|
||||
"start",
|
||||
|
||||
Reference in New Issue
Block a user