mirror of
https://github.com/block/buzz.git
synced 2026-11-09 10:51:42 +00:00
4bf80978f52981f0035e6c0b86bdf1108bbf64c8
217 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4bf80978f5 |
fix(messages): route edits to the owning composer (#6575)
**Category:** fix **User Impact:** Editing a channel message now opens in the main composer, while editing a thread reply stays in the thread composer, with focus ready for typing. **Problem:** When a thread was open, Buzz treated its root message as thread-owned and opened edits in the thread composer. Menu-driven edits also lacked regression coverage for immediate focus. **Solution:** Carry the message's semantic root/reply classification into the edit target, route only actual replies to the thread composer, and use the menu primitive's selection event for a reliable handoff. End-to-end tests cover placement and focus for both paths. <details> <summary>File changes</summary> **desktop/src/features/channels/ui/ChannelPane.tsx** Routes edit targets by semantic thread ownership rather than membership in the open thread panel. **desktop/src/features/channels/ui/ChannelPane.types.ts** Uses the shared composer edit-target type so routing metadata stays attached to the target. **desktop/src/features/messages/lib/draftMentionRefs.ts** Classifies each edit target as a root or true thread reply from its event tags. **desktop/src/features/messages/lib/draftMentionRefs.test.mjs** Covers semantic ownership for root and reply edit targets. **desktop/src/features/messages/ui/MessageActionBar.tsx** Handles Edit through the dropdown menu's selection event so focus restoration and edit startup share the intended lifecycle. **desktop/src/features/messages/ui/MessageComposer.types.ts** Adds semantic thread ownership to the edit-target contract. **desktop/tests/e2e/messaging.spec.ts** Verifies root edits use and focus the main composer, while reply edits use and focus the thread composer. </details> ### Reproduction Steps 1. Send a channel message and open its thread. 2. From the thread panel, edit the root message; confirm its content loads in the main composer and the editor is focused. 3. Send a reply in that thread. 4. Edit the reply; confirm its content loads in the thread composer and the editor is focused. ### Screenshots **Editing a channel-root message uses the main composer**  **Editing an actual thread reply uses the thread composer**  --------- Signed-off-by: Taylor Ho <taylorkmho@gmail.com> Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz> Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz> |
||
|
|
a2d8be5efa |
feat(desktop-messages): keep agents addressed across messages (#6315)
**Category:** new-feature **User Impact:** Users can keep selected agents addressed across consecutive messages without retyping their handles. **Problem:** Repeated conversations with agents require manually typing the same mentions on every turn, which adds friction and makes recipients easy to omit. **Solution:** The composer can now keep agents automatically addressed per channel, either from the mention controls or after a successful inline mention. Addressed agents remain visible in the toolbar, apply to channel threads, survive send failures safely, and never cross community boundaries. ## Changes <details> <summary>File changes</summary> **desktop/src-tauri/src/events/message_tags.rs** Preserves the automatic-address marker on validated mention reference tags. **desktop/src/features/channels/ui/ChannelPane.tsx** Wires the appropriate channel, thread, inbox, or forum composer context without leaking audiences across surfaces. **desktop/src/features/communities/useCommunityInit.ts** Clears composer audience state when the active community changes. **desktop/src/features/forum/ui/ForumComposer.tsx** Wires the appropriate channel, thread, inbox, or forum composer context without leaking audiences across surfaces. **desktop/src/features/forum/ui/ForumComposerAutocompletes.tsx** Wires the appropriate channel, thread, inbox, or forum composer context without leaking audiences across surfaces. **desktop/src/features/home/ui/InboxDetailPane.tsx** Wires the appropriate channel, thread, inbox, or forum composer context without leaking audiences across surfaces. **desktop/src/features/messages/lib/agentAddressMention.d.mts** Defines helpers and types for marked automatic-address mention tags. **desktop/src/features/messages/lib/agentAddressMention.mjs** Defines helpers and types for marked automatic-address mention tags. **desktop/src/features/messages/lib/agentAddressMention.test.mjs** Covers the automatic-address behavior and its failure, keyboard, layout, or persistence boundaries. **desktop/src/features/messages/lib/applyEditTagOverlay.mjs** Preserves automatic-address metadata when edited message tags are overlaid. **desktop/src/features/messages/lib/applyEditTagOverlay.test.mjs** Covers the automatic-address behavior and its failure, keyboard, layout, or persistence boundaries. **desktop/src/features/messages/lib/autoPinMentionedAgentsPreference.test.mjs** Covers the automatic-address behavior and its failure, keyboard, layout, or persistence boundaries. **desktop/src/features/messages/lib/autoPinMentionedAgentsPreference.ts** Stores the preference that keeps explicitly mentioned agents addressed for later messages. **desktop/src/features/messages/lib/extractMentionPersonas.ts** Separates persona recipients from the composer mention orchestration. **desktop/src/features/messages/lib/persistentAgentAudience.test.mjs** Covers the automatic-address behavior and its failure, keyboard, layout, or persistence boundaries. **desktop/src/features/messages/lib/persistentAgentAudience.ts** Maintains bounded, in-memory, channel-scoped automatic agent audiences. **desktop/src/features/messages/lib/useMentionSelection.ts** Centralizes mention picker selection state and agent-first selection behavior. **desktop/src/features/messages/lib/useMentions.ts** Exposes explicit picker origins and selection controls while preserving inline mention behavior. **desktop/src/features/messages/ui/ComposerAddressControls.test.mjs** Covers the automatic-address behavior and its failure, keyboard, layout, or persistence boundaries. **desktop/src/features/messages/ui/ComposerAddressControls.tsx** Renders compact addressed-agent avatars and the automatic-mention management entry point. **desktop/src/features/messages/ui/MentionAutocomplete.test.mjs** Covers the automatic-address behavior and its failure, keyboard, layout, or persistence boundaries. **desktop/src/features/messages/ui/MentionAutocomplete.tsx** Adds automatic-mention controls and options to the existing mention picker. **desktop/src/features/messages/ui/MessageAgentAddressPrefix.tsx** Shows which agents were automatically addressed on a sent message. **desktop/src/features/messages/ui/MessageComposer.tsx** Integrates automatic audiences, picker controls, accessible feedback, shortcuts, and send behavior. **desktop/src/features/messages/ui/MessageComposer.types.ts** Defines the simplified channel audience context shared by composer hosts. **desktop/src/features/messages/ui/MessageComposerToolbar.tsx** Places automatic-address controls in the composer toolbar without crowding narrow layouts. **desktop/src/features/messages/ui/MessageRow.tsx** Displays automatic-address metadata alongside sent message content. **desktop/src/features/messages/ui/MessageThreadPanel.tsx** Wires the appropriate channel, thread, inbox, or forum composer context without leaking audiences across surfaces. **desktop/src/features/messages/ui/composerAgentKeyboard.test.mjs** Covers the automatic-address behavior and its failure, keyboard, layout, or persistence boundaries. **desktop/src/features/messages/ui/persistentAgentAudienceHosts.test.mjs** Covers the automatic-address behavior and its failure, keyboard, layout, or persistence boundaries. **desktop/src/features/messages/ui/useAddressMentionPulse.test.mjs** Covers the automatic-address behavior and its failure, keyboard, layout, or persistence boundaries. **desktop/src/features/messages/ui/useAddressMentionPulse.ts** Provides success and failure animation signals for addressed-agent controls. **desktop/src/features/messages/ui/useAgentAddressLockPicker.test.mjs** Covers the automatic-address behavior and its failure, keyboard, layout, or persistence boundaries. **desktop/src/features/messages/ui/useAgentAddressLockPicker.ts** Coordinates adding, removing, and announcing automatically addressed agents. **desktop/src/features/messages/ui/useAlwaysAddressShortcut.ts** Implements the platform-aware shortcut for toggling automatic addressing. **desktop/src/features/messages/ui/useAutoPinMentionedAgents.ts** Promotes successfully sent inline agent mentions and provides a single undoable notification. **desktop/src/features/messages/ui/useComposerMentionPicker.ts** Opens the mention picker without rewriting the current draft. **desktop/src/features/messages/ui/useMentionSendFlow.helpers.test.mjs** Covers the automatic-address behavior and its failure, keyboard, layout, or persistence boundaries. **desktop/src/features/messages/ui/useMentionSendFlow.helpers.ts** Merges automatic and inline recipients, marks outgoing tags, and restores failed sends safely. **desktop/src/features/messages/ui/useMentionSendFlow.ts** Merges automatic and inline recipients, marks outgoing tags, and restores failed sends safely. **desktop/src/features/messages/ui/usePersistentAgentMentionHydration.ts** Removes the prior draft-text hydration approach now that automatic audiences stay at composer ingress. **desktop/src/features/settings/ui/AgentsSettingsPanel.tsx** Replaces the old global behavior with explicit composer-level automatic-mention controls. **desktop/src/features/settings/ui/PreventSleepSettingsCard.tsx** Replaces the old global behavior with explicit composer-level automatic-mention controls. **desktop/src/shared/lib/keyboard-shortcuts.ts** Defines the user-facing automatic-address keyboard shortcut label. **desktop/src/shared/ui/VideoReviewCommentMarkdown.tsx** Allows automatic-address prefixes to compose with video review timecodes. **desktop/tests/e2e/persistent-agent-audience.spec.ts** Covers the automatic-address behavior and its failure, keyboard, layout, or persistence boundaries. </details> ## Reproduction Steps 1. Open a channel with one or more agents and open the mention picker from the composer. 2. Select an agent for automatic mentions, then send several messages without retyping the handle; confirm the agent remains in the composer control and receives each message. 3. Mention another agent inline, send successfully, and confirm the agent becomes automatically addressed; use the notification's Undo action to reverse it. 4. Open a thread in the same channel and confirm the same addressed agents are available there. 5. Remove an agent from the composer control and confirm later messages stop addressing it. 6. Switch communities and confirm addressed agents do not carry into the other community. ## Screenshots All states below use the dark Buzz theme with a selected lilac accent. ### Addressed composer Selected agents stay visible at the composer ingress without adding handles to the draft.  ### Open mention menu The @ ingress opens the existing mention menu and shows which agents are already addressed.  ### Mention options The inline options pane controls whether a successful one-time agent mention carries into later messages.  ### Agent settings The same preference is available in **Settings → Agents → Conversations**.  --------- Signed-off-by: Taylor Ho <taylorkmho@gmail.com> Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz> Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz> |
||
|
|
723affe5d1 |
fix(desktop): remove Buzz entity link previews (#6512)
**Category:** improvement **User Impact:** Buzz-native project, repository, issue, and pull request links now appear once as compact inline chips, with their details available on hover. **Problem:** Buzz-native entity links rendered both an inline chip and a standalone preview card, repeating the same metadata and adding visual noise to conversations. **Solution:** Exclude Buzz-native links from the shared standalone-preview extractor while leaving entity parsing intact for chip tooltips and preserving external web previews and attachment cards. <details> <summary>File changes</summary> **desktop/src/shared/lib/linkPreview.ts** Stops Buzz-native preview candidates after parsing, including same-relay git clone URLs that normalize to repository entities, while allowing external URLs through the existing snapshot path. **desktop/src/shared/lib/linkPreview.test.mjs** Covers project, repository, issue, pull request, markdown-labeled, same-relay clone, and mixed external-link extraction behavior. **desktop/src/shared/ui/markdown/useMessageLinkPreviews.test.mjs** Confirms sent messages no longer merge a standalone Buzz entity card while external sender snapshots still render. </details> ## Reproduction steps 1. Open a desktop channel containing a `buzz://project`, `buzz://repo`, `buzz://issue`, or `buzz://pr` link. 2. Confirm the link renders as an inline entity chip without a second standalone Buzz card below the message. 3. Hover the chip and confirm its entity metadata remains available. 4. Post an external HTTPS link and confirm its web preview still renders. 5. Paste a same-relay `/git/<owner>/<repo>` clone URL and confirm it uses the repository chip without a duplicate card. ## Screenshots | Before | After | | --- | --- | | Inline chip plus redundant standalone Project card | Inline chip is now the sole presentation | |  |  | **After — rich metadata stays available on hover**  ## Verification At commit `3fa74cdd342ac1f6721b7d56a7f111af31e0e6e9`: - focused link-preview + Markdown unit suites — 119/119 passed - targeted registered smoke E2E — 8/8 passed, including labeled same-relay clone metadata, ordinary-link presentation, and in-app navigation - `cd desktop && pnpm exec tsc --noEmit` — passed - `git diff --check origin/main...HEAD` — passed - pre-push hooks — desktop check, TypeScript, and full desktop unit suite passed --------- Signed-off-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz> Signed-off-by: Taylor Ho <taylorkmho@gmail.com> Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz> Co-authored-by: Mongo <5398c5fd039b963ce132b3e078e7c4af097dd997517bb5e14c2682fe68c25197@buzz.block.builderlab.xyz> |
||
|
|
9b32e055fe |
polish(desktop): finish Projects navigation and context chrome (#6429)
## Summary After #6396, Projects still split chrome across the workspace header, a copy-link control, and a labeled Actions group that mixed people, create, and metadata. This PR finishes that surface: the right-hand context box is unlabeled actions plus a Details group, people stacks and contribution heatmaps are gone from that box, Create review sits with Create task, and the top chrome is terminal / chat / info with no copy-link. Sent project context collapses to a pill, and review file diffs keep the last good git view instead of flashing empty while queries refetch. This also lands the remaining navigation polish that followed Part 3: overview and list presentation, readme and commit layout, and opening the latest matching conversation from the Channels tab without leaving the project. ### Related issue N/A. Related: #6396 ## Testing - Walked Files, Tasks, Reviews, task/review detail, overview tabs, and chrome chat vs info in the running desktop app - Pre-push: desktop typecheck, unit tests, Tauri checks, and file-size gate passed - Updated Projects smoke specs for the new context groups, Create review, chrome order, and removed copy-link control - Merged current `origin/main`; one conflict in discussion-channel rows kept conversation-panel navigation and took main's bounded channel-name lookup ## Post-Deploy Monitoring & Validation - validate Projects workspace chrome, context box, and review file diffs in the first staging Desktop session - healthy signals: context box shows unlabeled actions then Details, chat toggle sits between terminal and info, review diffs stay populated across selection changes - failure signals: missing Create review, restored heatmap/people in the context box, or empty Files Changed while the review is still selected; mitigate by reverting this PR --------- Signed-off-by: Thomas Petersen <thomasp@squareup.com> |
||
|
|
de8a2741c7 |
feat(desktop-messages): show compact Buzz link metadata (#6252)
**Category:** improvement **User Impact:** Buzz links in messages now resolve into compact, descriptive chips with predictable navigation, while tooltips use the neutral secondary surface consistently across light and dark themes. **Problem:** Raw Buzz-native links and opaque identifiers make message context difficult to scan, while oversized previews disrupt the conversation. Missing, delayed, or deleted metadata also needs a stable presentation that does not mislead users or break navigation. **Solution:** Keep message and issue chips metadata-independent: message chips render only the channel name, while issue chips render only the repository name—never fetched content/title or an event hash. Fetched context remains available in each hover tooltip. Other native links continue to resolve into concise inline labels, with muted secondary fallbacks, distinct deleted states, and existing navigation paths preserved. This also makes two explicit shared-tooltip behavior changes: 1. **Color:** shared and rich tooltips move from the primary color pair to the neutral secondary semantic pair, including dedicated huddle-token handling and matching rich-descendant foregrounds. 2. **Hover behavior:** tooltip roots set Radix `disableHoverableContent`, and tooltip content is pointer-transparent, so moving off the trigger dismisses the tooltip instead of letting the pointer enter and keep the popover open. Together these preserve readable contrast, authoritative project context, and predictable hover dismissal. <details> <summary>File changes</summary> **desktop/src/features/communities/useCommunityInit.ts** Primes channel metadata needed to resolve native links promptly. **desktop/src/features/messages/lib/messageLinkMetadata.test.mjs** Covers message preview extraction, fallbacks, and deleted-message semantics. **desktop/src/features/messages/lib/messageLinkMetadata.ts** Normalizes fetched message metadata into compact labels and status-aware presentation. **desktop/src/features/messages/ui/SentFromThreadLine.tsx** Provides thread context to linked-message metadata resolution. **desktop/src/shared/lib/useResolvedLinkPreviews.ts** Exposes resolved preview state for native entity chips. **desktop/src/shared/styles/globals/markdown.css** Adds compact chip layout and semantic disabled-state styling. **desktop/src/shared/styles/globals/theme.css** Defines the semantic colors used by unavailable and deleted chips. **desktop/src/shared/ui/markdown.test.mjs** Exercises native-link rendering and provider-backed entity metadata behavior. **desktop/src/shared/ui/markdown.tsx** Routes native markdown links through metadata-aware chip components without changing navigation contracts. **desktop/src/shared/ui/markdown/ChannelDeepLink.test.mjs** Covers resolved, unresolved, private, archived, and forum channel presentations. **desktop/src/shared/ui/markdown/ChannelDeepLink.tsx** Renders channel names and concise channel metadata inline with stable fallbacks. **desktop/src/shared/ui/markdown/MessageLinkPill.tsx** Renders loading, ready, unavailable, DM, forum, and deleted message states compactly. **desktop/src/shared/ui/markdown/entityLinks.tsx** Enriches repository, issue, and pull-request chips and uses containing-project context in tooltips. **desktop/src/shared/ui/markdown/types.ts** Extends markdown runtime metadata required by native chip rendering. **desktop/src/shared/ui/markdown/useMessageLinkMetadata.ts** Fetches and classifies linked-message metadata while preserving navigable fallbacks. **desktop/src/testing/e2eBridge.ts** Adds deterministic metadata controls for runtime visual and navigation tests. **desktop/tailwind.config.js** Makes semantic disabled colors available to chip styles. **desktop/tests/e2e/entity-link-recipient-cards.spec.ts** Verifies entity labels, project-aware tooltips, delayed metadata, and navigation behavior. **desktop/tests/e2e/navigation.spec.ts** Verifies channel and message chip states, metadata resolution, deletion handling, and navigation. **desktop/src/shared/ui/tooltip.tsx** Migrates the shared tooltip surface from the primary color pair to the semantic secondary pair. It also sets Radix `disableHoverableContent` and makes tooltip content pointer-transparent so leaving the trigger dismisses the tooltip predictably. **desktop/src/features/agents/ui/RestartDiffBadge.tsx** Aligns restart-diff tooltip values and supporting copy with the secondary tooltip foreground. **desktop/src/features/channels/ui/AddChannelBotTeamsSection.tsx** Aligns rich team tooltip descriptions, persona chips, avatars, and names with secondary tooltip semantics. **desktop/src/features/projects/ui/ProjectAuthorIdentity.tsx** Uses the matching secondary tooltip foreground for project author metadata. **desktop/src/features/projects/ui/ProjectCards.tsx** Aligns repository-unavailable tooltip descriptions with the secondary tooltip foreground. **desktop/src/shared/styles/globals/utilities.css** Makes huddle tooltips consume their dedicated palette directly without misleading primary or secondary aliases. **desktop/src/shared/styles/globals/tooltipSemantics.test.mjs** Pins direct huddle-token consumption and rejects semantic alias drift. **desktop/tests/e2e/tooltip-semantics.spec.ts** Verifies simple and rich tooltip surfaces and descendant tokens in Buzz light and Catppuccin Mocha dark themes. **desktop/playwright.config.ts** Registers tooltip semantic coverage in the desktop smoke suite. </details> ## Reproduction steps 1. Run the desktop app and open a message containing Buzz links for a channel, message, repository, issue, and pull request. 2. Confirm message links show only the channel name and issue links show only the repository name inline, with no fetched content/title or event hash; confirm other native links remain compact rather than rendering raw identifiers or expanded previews. 3. Hover the chips and confirm the neutral secondary tooltip adds concise context without duplicating the visible label. 4. Open each chip and confirm it follows the same channel, message, repository, issue, or pull-request navigation as before. 5. Inspect links while metadata is loading, unavailable, or definitively deleted and confirm the fallback remains compact, legible, and navigable where appropriate. 6. In Buzz light and Catppuccin Mocha dark themes, compare a simple channel-members tooltip and the rich Add agents team tooltip; both should use secondary semantics with readable nested content. 7. Move the pointer from a trigger toward its tooltip; confirm the tooltip dismisses rather than remaining open as hoverable content. ## Screenshots The matrix below covers both the default light theme and Catppuccin Mocha with an orange accent. Message/issue-chip rows affected by the stable-label pivot are temporarily omitted until they can be recaptured from the real built UI; the prior images showed the obsolete expanding inline label. | State | Default light | Dark · orange accent | |---|---|---| | Public stream channel tooltip |  |  | | Private forum channel tooltip |  |  | | Public forum channel tooltip |  |  | | Channel references, including unresolved |  |  | | Unknown channel permalink |  |  | | Archived channel tooltip |  |  | | Repository entity |  |  | | Pull request entity |  |  | | Entity metadata fallback |  |  | ### Tooltip semantic surface spot check | Buzz light | Catppuccin Mocha dark | |---|---| |  |  | --------- Signed-off-by: Taylor Ho <taylorkmho@gmail.com> Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz> |
||
|
|
54bbe7305b |
perf(desktop): resolve references without directory scans (#6328)
## Summary - keep the channel poll membership-only and fetch the open-channel directory only from explicit discovery surfaces - resolve unknown ID-bearing references through one bounded `get_channel_details` lookup, while name references remain limited to member channels plus a browse/search-warm directory cache - fail closed for fetched private metadata and cover cold lookup, warm/member hits, private visibility, and cached misses with mounted hook contracts --------- Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Hayt <9e1c23a3fd83f61da34420e4e88ff1b16e45cafcc0cd9019eb07d4ecfa8ca9b0@buzz.block.builderlab.xyz> Co-authored-by: Hayt <9e1c23a3fd83f61da34420e4e88ff1b16e45cafcc0cd9019eb07d4ecfa8ca9b0@buzz.block.builderlab.xyz> |
||
|
|
1934e83bf5 |
feat(workflows): add workflow editor (#6248)
**Category:** new-feature **User Impact:** Users can create, edit, duplicate, and deep-link to workflows in a responsive visual editor without losing unsupported YAML or unsaved work. **Problem:** Workflow editing was split across disconnected surfaces and lacked reliable URL state, lifecycle protection, and parity between Form and YAML modes. **Solution:** This adds a route-addressable editor foundation with stable pane identity, guarded dirty exits, lossless Form/YAML transitions, responsive workflow and channel controls, and matching reaction-filter execution support. <details> <summary>File changes</summary> **crates/buzz-workflow/src/lib.rs** Apply reaction trigger filters during workflow execution and cover target-message gating. **crates/buzz-workflow/src/schema.rs** Extend the reaction trigger schema with the editor-owned filter field. **desktop/src/app/navigation/useAppNavigation.ts** Add navigation helpers for explicit workflow create, edit, and duplicate editor modes. **desktop/src/app/routes/WorkflowsRouteScreen.tsx** Coordinate route state with the shared workflow library and editor dialog. **desktop/src/app/routes/lazyWorkflowsRouteScreen.ts** Share one lazy route component across workflow route entry points to avoid loading flashes. **desktop/src/app/routes/workflows.$workflowId.tsx** Parse workflow editor modes and pane deep links for workflow-specific URLs. **desktop/src/app/routes/workflows.tsx** Parse library-level create state and render the shared workflow route screen. **desktop/src/app/AppWorkflowEditorOverlayProvider.tsx** Host the shared workflow editor at the app-shell level so channel-originated workflow dialogs stay above the active channel instead of replacing it. **desktop/src/shared/context/WorkflowEditorOverlayContext.tsx** Expose route-independent open-existing and create-new workflow actions to channel settings. **desktop/src/features/workflows/ui/WorkflowEditorHost.tsx** Share editor loading, unavailable, and dialog lifecycle wiring between canonical workflow routes and the channel overlay. **desktop/src/features/channels/ui/ChannelManagementSheet.tsx** Add an experiment-gated, Canvas-style Workflows ingress below Canvas, including channel-scoped loading, error, empty, and list states plus open/create actions; disabled users issue no workflow query. **desktop/src/features/channels/ui/ChannelWorkflowsSection.tsx** Render the channel workflow list and New workflow action without pushing the existing settings sheet past its file-size ceiling. **desktop/src/features/workflows/ui/ChannelCombobox.tsx** Adopt the final channel presentation, portalled scrolling, and one-shot create-flow opening behavior. **desktop/src/features/workflows/ui/CreateWorkflowDialog.tsx** Remove the superseded create-only dialog in favor of the unified workflow editor. **desktop/src/features/workflows/ui/WorkflowCard.tsx** Open workflow cards in the detail and run-history modal while preserving explicit edit and duplicate actions. **desktop/src/features/workflows/ui/WorkflowDetailDialog.tsx** Present workflow Trigger/Steps in the shared modal chrome, with top-chrome ingress to a responsive right-side run-history inspector and an explicit edit action. **desktop/src/features/workflows/ui/WorkflowDialog.tsx** Unify create, edit, and duplicate lifecycle handling with URL panes, generated-name synchronization, dirty-exit guards, stale-write preservation, and protected webhook-secret handoff. **desktop/src/features/workflows/ui/WorkflowFormBuilder.tsx** Build the responsive Form/YAML editor shell, stable step selection, insertion and removal behavior, and lossless canonical-YAML synchronization. **desktop/src/features/workflows/ui/WorkflowStepCard.tsx** Align workflow step controls and presentation with the final editor interaction model. **desktop/src/features/workflows/ui/WorkflowUnavailableDialog.tsx** Show a non-disclosing loading or unavailable state for missing and inaccessible workflow links, with retry and close actions. **desktop/src/features/workflows/ui/WorkflowWebhookSecretDialog.tsx** Obscure one-time webhook secrets by default and require explicit confirmation before any close or navigation discards them. **desktop/src/features/workflows/ui/WorkflowsScreen.tsx** Connect library state and workflow actions to the route-addressable editor. **desktop/src/features/workflows/ui/WorkflowsView.tsx** Restore the responsive workflow library, create tile, cards, loading states, and shared action menu. **desktop/src/features/workflows/ui/workflowEditorPane.test.mjs** Cover pane parsing, serialization, and stable step-ID reconciliation. **desktop/src/features/workflows/ui/workflowEditorPane.ts** Define explicit trigger and stable step pane URL state. **desktop/src/features/workflows/ui/workflowYamlDocument.ts** Read and update header fields independently of full form validation so incomplete steps cannot clear or disable the workflow title. **desktop/src/features/workflows/ui/workflowYamlDocument.test.mjs** Cover document-level workflow header reads and writes for incomplete definitions. **desktop/tests/e2e/workflow-title-stability.spec.ts** Verify generated, renamed, saved, and duplicated titles remain stable while moving between trigger and step panes. **desktop/src/features/workflows/ui/workflowFormTypes.test.mjs** Cover lossless Form/YAML round trips and actionable fallback for unsupported fields. **desktop/src/features/workflows/ui/workflowFormTypes.ts** Own canonical workflow YAML conversion while preserving supported trigger and step fields. **desktop/src/shared/ui/PortalledScrollArea.tsx** Provide bounded scrolling for popovers rendered outside their dialog container. **desktop/src/shared/ui/popover.tsx** Allow workflow popovers to use the shared portalled scroll container. **desktop/tests/e2e/channels.spec.ts** Cover disabled and enabled Workflows experiment states, including suppressed queries while disabled, placement beneath Canvas, channel workflow listing and opening, channel-preselected workflow creation, and direct return to the channel Workflows panel after close, discard, or cancel. **desktop/tests/e2e/workflows.spec.ts** Exercise library actions, deep links, create/edit/duplicate lifecycle, dirty exits, responsive editor behavior, YAML safety, stale updates, and one-shot channel selection. </details> ## Reproduction steps 1. Open **Workflows** and confirm the responsive card library, create tile, card action menu, and card-to-detail/run-history modal navigation. 2. Open `?view=create`; confirm the channel chooser opens once, the trigger inspector stays hidden until a channel is selected, and closing the chooser does not make it reopen after unrelated edits. 3. Create a workflow, switch between Form and YAML, add and remove steps, refresh a pane deep link, and confirm the selected trigger or stable step remains addressable. 4. Edit or duplicate a workflow, make an unsaved change, and confirm close, Escape, browser navigation, and route target changes require discard confirmation while pane-only navigation does not. 5. Enter unsupported YAML and confirm Form mode gives an actionable fallback without rewriting the definition; verify reaction triggers preserve and execute their filter. 6. Open a channel’s settings, select **Workflows** below **Canvas**, and open or create a workflow; confirm the shared modal stays over the channel, the channel URL does not change, New workflow preselects that channel, and closing or discarding returns directly to the channel’s **Workflows** panel. 7. In create, edit, and duplicate modes, move between the trigger and incomplete step panes and confirm the generated or edited title remains visible and editable. ## Screenshots Fresh captures from product head `c5c3abc91a71fe511d43e6cc9168b1626d0c217c`; the later review-guidance fix does not alter these pictured states. ### Workflow library and actions  ### Workflow editor — wide  ### Workflow editor — narrow inspector overlay  ### Workflow editor — active channel overlay  ## Review feedback addressed - Corrected Diff Posted condition guidance to use the executor-supported `str_contains(trigger_text, "deploy")` syntax and added a visible Playwright regression assertion. - Scoped direct workflow-detail navigation coverage to the stable `Edit workflow` dialog name, asserted the workflow title separately, and retained the trigger-node assertion. - Routed dirty channel-overlay Duplicate/Edit transitions through the existing discard confirmation, preserving the original YAML draft when the user keeps editing. - Made workflow deletion await relay success, remain non-dismissible while pending, and retain the confirmation/editor/draft with an actionable inline error on rejection. - Gated the channel-settings Workflows ingress and channel workflow query behind the `workflows` experiment, with defensive rendering if the flag changes while that view is active. - Matched the Reaction Added trigger to the prototype reaction picker, preserving native/custom/legacy values in canonical YAML and providing an explicit clear action. - Kept a channel’s Workflows panel mounted beneath channel-origin editors so clean close, dirty discard, and create cancel return directly to that panel without changing the channel URL. ## Verification Verified at exact pushed head `76ebba7b7ace1e13445744200da70ca9da231b7e`: - Push hooks passed: destination-org policy, branch-skew, differential file-size, Desktop checks, TypeScript typecheck, and **5,115/5,115** Desktop unit tests - Focused channel lifecycle E2E passed: dirty edit discard returns directly to the channel Workflows panel; create cancel does the same while preserving the channel URL and preselected channel - E2E production build, standalone TypeScript typecheck, and Biome checks on both touched files passed - Reaction-picker regression spec remains recorded at `dc28ffa98ec34b4e0656757fb2dd93e60a84674d`: **5/5 passed** (picker interaction, canonical YAML persistence/clear, legacy-value preservation, save/reopen round trip, narrow viewport containment) - Blox existing workflow E2E regression set at `dc28ffa98ec34b4e0656757fb2dd93e60a84674d`: **36/36 passed** - Earlier blocker and review regressions remain recorded at `3760c3d657a525f5af98e8d0f98bdd03999d8e61`: **5,114/5,114** Desktop unit tests and the dirty-overlay/deletion focused checks - Working tree clean; local branch, remote branch, and PR head all match the exact SHA above ### Related issue None found. Closest prior work: #231. --------- Signed-off-by: Taylor Ho <taylorkmho@gmail.com> Co-authored-by: Codex <noreply@openai.com> |
||
|
|
f88cda9eb8 |
feat(desktop): make the Projects overview follow the selected section (#6335)
## Summary Part 1 of 4 stacked PRs continuing the Projects work from #6003. - The Projects overview now follows the selected section: the right-hand context pod stays visible across the Projects / Repositories / Reviews / Tasks / Channels tabs and shows section-specific people, stats, and contribution graphs, so it reads as live context rather than a detached summary. - Entity list rows are consolidated onto one compact line (title first, icons after, aligned dates/counts), shared across projects, repositories, PRs, issues, and channel lists via `ProjectEntityListRow`. - New `projectRelatedChannels` helper resolves the channels a project is discussed in for the overview. Follow-ups in this stack: part 2 (selectable workspaces), part 3 (context-aware collaboration), part 4 (navigation & detail-page polish). ## Test plan - [x] Desktop unit tests (`pnpm test`) — pass - [x] TypeScript (`tsc --noEmit`), Biome, clippy — clean via pre-push gate - [x] Playwright specs updated for the new overview behavior (`projects-v3-screenshots.spec.ts`, `sidebar.spec.ts`) — pass locally in the smoke project --------- Signed-off-by: Thomas Petersen <thomasp@squareup.com> |
||
|
|
9a1e861ab8 |
Add appearance preference previews (#6193)
## Summary - Replace the Link previews and Thread layout dropdowns with the shared segmented control from #5644. - Pair each setting with a real, inert preview: production Compact/Rich link cards and a simplified Focus/Split thread diagram. - Keep scrub previews local to Settings so only a completed selection updates the saved preference and real app behavior. - Keep each setting and preview responsive as one grouped unit, with focused light/dark and narrow/wide coverage. ## Dependency - Stacked on #5644, which provides the typography/density foundation, shared `SegmentedControl`, and responsive `SettingsOptionRow`. - After #5644 merges, this PR should be retargeted/rebased onto `main`. ## Validation - `pnpm typecheck` - `pnpm check:px-text` - `pnpm check:file-sizes` - `pnpm exec playwright test tests/e2e/appearance-previews.spec.ts --project=smoke` (3 passed) - Focused existing Appearance coverage (2 passed) - Pre-push desktop checks, typecheck, tests, and Tauri checks Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com> |
||
|
|
e5a6e2022f |
fix(desktop): morph the drawer panel icon instead of sliding it (#6306)
## Summary - Replaces the drawer panel icon's CSS `translateX` slide with a `motion/react` width + corner-radius morph, so the icon reads as the panel opening rather than the glyph drifting sideways. - Honors `prefers-reduced-motion` via `useReducedMotion` (no animation for users who opt out). Follow-up polish to the projects workspaces work that just landed in #6003 — the slide animation shipped there was the wrong visual. ## Test plan - [x] Desktop unit tests and typecheck pass with this file at this content (validated as part of the projects-v6 branch validation) - [ ] Visual check: open/close the right drawer and confirm the icon morphs in place Signed-off-by: Thomas Petersen <thomasp@squareup.com> |
||
|
|
87f8ff82ae |
feat(desktop): refine repository-aware project workspaces (#6003)
## Summary - Makes Projects repository-aware across browsing, branch and tag selection, local and remote source management, work items, commits, and contextual repository actions. - Refines project details into consistent single-column reading surfaces with a resizable, section-aware context pod, while keeping project conversations available in the attached chat panel. - Adds persistent sidebar project navigation, direct entity links, repository discussion channels, contributor identity matching, and consistent loading and activity presentation. - Keeps branch-specific controls on code-oriented sections while Tasks, Reviews, and Channels remain repository-scoped, reducing misleading context and actions. Replacement for #5981 with an identical final tree flattened into one signed-off commit because the required DCO check suite remained stalled. ### Related issue N/A ### Testing - [x] Desktop pre-push checks, TypeScript typecheck, and unit tests - [x] E2E production build with `pnpm build:e2e` - [x] Focused Playwright smoke coverage for project workspace, task, review, commit, sidebar, and contextual-panel behavior - [ ] Attach final before/after screenshots after design review --------- Signed-off-by: Thomas Petersen <thomasp@squareup.com> Signed-off-by: Wintermute <165f0c871dd2586bb18b6aa109eeaf57bb2132ff4d27b10120f4368a0f627022@buzz.block.builderlab.xyz> Co-authored-by: Wintermute <165f0c871dd2586bb18b6aa109eeaf57bb2132ff4d27b10120f4368a0f627022@buzz.block.builderlab.xyz> |
||
|
|
7e2651791d |
Add font size and conversation density preferences (#5644)
## Summary - Add separate **Font size** and **Conversation density** controls in Appearance. - Use a 13 / 14 / 15px conversation text ramp for Smaller / Default / Larger while scaling interface typography through a shared virtual-rem system. - Keep layout geometry fixed while typography changes, and compose Cmd +/- text zoom on top of the selected preference. - Let Compact, Comfy, and Spacious control conversation row spacing plus paragraph and list rhythm in Markdown content across Buzz. - Preview font size and density together with click-and-drag comparison; interrupted scrubbing restores the saved preference. - Synchronize preferences across open Buzz windows, including full local-storage clears during sign-out or dev reset. - Promote the segmented control to shared UI and make Settings rows adapt to their card width. ## Validation - `just ci` - 4,965+ desktop unit tests across the final merged branch - 1,465 mobile tests through the full repository gate - Focused Playwright coverage for font-size/density independence, drag preview cancellation, Inbox geometry, thread rendering, keyboard zoom, and cross-surface typography - Fresh E2E build against the final merged branch --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com> Signed-off-by: Princess Donut <b238ea756dee4d98afa5883fc7f1de61eeabe65bf700e3a5a5a80db5e42e2c2b@buzz.block.builderlab.xyz> Co-authored-by: Princess Donut <b238ea756dee4d98afa5883fc7f1de61eeabe65bf700e3a5a5a80db5e42e2c2b@buzz.block.builderlab.xyz> Co-authored-by: morgmart <98432065+morgmart@users.noreply.github.com> |
||
|
|
d7e8fdb10c |
fix(shared-ui): delay hover disclosures by default (#5821)
**Category:** fix **User Impact:** Hover tooltips and informational popovers now wait for deliberate pointer dwell instead of appearing while users move around the app. **Problem:** Tooltips and hover-controlled popovers appeared after inconsistent, often very short delays, so moving across composer and navigation controls could obstruct the next interaction. **Solution:** Establish a 500 ms shared dwell default with no tooltip skip-delay cascade, apply it to informational hover-controlled Popovers, and preserve immediate click and keyboard behavior. The responsive Community actions navigation submenu retains its documented 80 ms open / 160 ms close timing. ## Before / after | Before | After | |---|---| |  |  | <details> <summary>File changes</summary> **desktop/src/shared/ui/tooltip.tsx** Wraps the Radix provider with documented 500 ms and zero skip-delay defaults. The provider API still permits a future proven exception, but no current `desktop/src` caller overrides either timing. **desktop/src/shared/ui/popover.tsx** Exports the documented shared hover-open timing for controlled popovers; ordinary click/focus Popovers remain immediate. **desktop/src/main.tsx** Uses the shared Tooltip provider defaults at the application root. **desktop/src/shared/ui/sidebar.tsx** Removes the sidebar's instant Tooltip timing override. **desktop/src/features/channels/ui/AddChannelBotTeamsSection.tsx** Removes the local short Tooltip timing override. **desktop/src/features/home/ui/InboxDetailPane.tsx** Removes the local short Tooltip timing override. **desktop/src/features/messages/ui/MessageTimeline.tsx** Removes the timeline's local short Tooltip timing override. **desktop/src/features/messages/ui/MessageTimestamp.tsx** Drops the timestamp-only provider now that its 500 ms, zero-skip behavior is shared globally. **desktop/src/features/channels/ui/BotActivityBar.tsx** Raises composer agent-activity hover dwell from 150 ms to the shared default while preserving immediate click/focus opening. **desktop/src/features/sidebar/ui/ChannelActivityPopover.tsx** Raises channel activity hover dwell from 250 ms to the shared default while preserving immediate focus opening. **desktop/src/features/profile/ui/UserProfilePopover.tsx** Reuses the shared hover timing in place of its equivalent local constant. **desktop/src/shared/ui/PubKey.tsx** Reuses the shared hover timing in place of its equivalent local constant. **desktop/src/shared/ui/markdown/InlineEmojiPopover.tsx** Raises emoji inspection hover dwell from 200 ms to the shared default while preserving immediate focus opening. **desktop/src/features/messages/ui/MessageReactions.tsx** Raises reaction inspection hover dwell from 200 ms to the shared default while preserving immediate focus and reaction clicks. **desktop/src/features/communities/ui/CommunitySwitcher.tsx** Documents the Community actions navigation submenu as an intentional timing exception: 80 ms to open responsively and 160 ms to preserve the pointer bridge into its portalled panel. </details> ## Reproduction steps Move the pointer rapidly across each surface first, then hold it still over a labeled control. Hover-only disclosures should stay closed during transit and open after about **500 ms** of deliberate dwell. Moving directly between adjacent Tooltip triggers should start a fresh 500 ms dwell rather than cascading the next Tooltip open immediately. | Surface | Where to test | What to expect | |---|---|---| | Composer controls | Attachment, emoji, image editor, formatting, and composer toolbar buttons | No Tooltip while sweeping across controls; the hovered control's Tooltip opens after ~500 ms. Clicking remains immediate. | | Message actions | Hover a message, then test reply, react, more-actions, edit, and related action-bar controls | Each Tooltip waits ~500 ms, including when moving between adjacent actions. The action itself still runs immediately on click or keyboard activation. | | Message metadata and content tools | Message timestamps, code-block copy controls, diff controls, system-message controls, and video-player controls | Tooltip appears after ~500 ms. Timestamp behavior should look unchanged; it was already 500 ms with no skip cascade. | | Reaction pills | Hover a reaction with one or more reactors; also click the pill | Reactor Popover waits ~500 ms instead of 200 ms. Clicking still toggles the reaction immediately. | | Inline custom emoji | Hover a rendered custom emoji in message Markdown, then focus it with the keyboard | Emoji inspector waits ~500 ms on hover instead of 200 ms. Keyboard focus opens it immediately. | | Masked links | Hover a masked Markdown link, including one revealed inside a spoiler | Destination Tooltip waits ~500 ms instead of the former app-level 300 ms. Hidden spoilers still reveal no destination; keyboard focus remains immediate. | | Main and collapsed sidebar controls | Collapse the sidebar and hover icon-only navigation/menu buttons; also test community-rail controls | Sidebar Tooltips wait ~500 ms instead of opening instantly. Rapid movement across icons should not produce a tooltip cascade. | | Channel header and management controls | Channel members, huddle, settings, thread-view mode, management rows, and quick-agent controls | Each Tooltip waits ~500 ms; click/keyboard behavior remains immediate. | | Add-channel team chips | Open Add channel where saved teams are available and hover a team chip | Team details Tooltip waits ~500 ms instead of 150 ms; clicking the chip still toggles the team immediately. | | Channel activity preview | Hover a sidebar channel that has activity, then keyboard-focus its trigger | Activity Popover waits ~500 ms instead of 250 ms. Focus opens it immediately, and quickly crossing channel rows should not leave previews in the way. | | Composer agent activity | Run an agent so the composer activity control is present; hover, click, and focus it | Hover Popover waits ~500 ms instead of 150 ms. Click and keyboard focus still open it immediately. | | Inbox and draft controls | Home inbox open-context/more-actions controls, inbox-list controls, draft detail, and drafts panel | Tooltips wait ~500 ms instead of the inbox detail's former 200 ms/local defaults. Clicks remain immediate. | | Profile and public-key previews | Hover avatars, names/mentions, project author identities, and displayed public keys | Profile/pubkey Popovers open after ~500 ms, matching their prior behavior; the change centralizes that timing. Click actions and focus behavior remain immediate. | | Agent, team, memory, and update controls | Managed-agent rows, team identity cards, restart-diff badges, memory actions, setup steps, and update indicator | Tooltips wait ~500 ms and do not cascade when traversing adjacent controls. Actions remain immediate. | | Huddle controls | Huddle bar/indicator, mic controls, and participant-list actions | Tooltips wait ~500 ms; mute, join, participant, and keyboard actions remain immediate. | | Projects and activity surfaces | Project/repository cards, overview rail, contribution graph, activity feed, reviewers, and Pulse note controls | Tooltips wait ~500 ms with a fresh dwell between adjacent targets. Clicking/focusing interactive controls remains immediate. | | Intentional interaction-mode exceptions | Focus a Tooltip trigger; click/focus an ordinary Popover; move the pointer from an open hover Popover into its panel | Tooltip focus and Popover click/focus open immediately because they are explicit user intent, not incidental hover. Hover Popovers retain their 180–200 ms close grace so the pointer can cross into the panel. The Community actions navigation submenu is the intentional exception: it opens after 80 ms and keeps its 160 ms pointer bridge; informational hover Popovers use the shared 500 ms delay. | ## Verification - `pnpm typecheck` - `pnpm check` (passes with three existing diagnostics outside this diff) - `pnpm test` — 4,775 passed - `pnpm build` --------- Signed-off-by: Taylor Ho <taylorkmho@gmail.com> |
||
|
|
c442a90a17 |
fix(desktop-chrome): preserve balanced layout when sidebar collapses (#6000)
**Category:** fix **User Impact:** The desktop content surface now keeps balanced chrome spacing when the sidebar is collapsed or multiple communities are visible, with a cleaner sidebar transition. **Problem:** Collapsing the left sidebar removed the content surface's left inset, while multi-community layouts also exposed uneven visible gutters and sidebar content during the exit transition. **Solution:** Preserve an 8px visible gutter around the content surface, clip and fade only the sidebar's inner content while it trails off canvas, and leave the opaque shell in place until the existing visibility transition completes. <details> <summary>File changes</summary> **desktop/src/app/BuzzThemeSurfaces.tsx** Preserves a balanced visible left gutter after accounting for the content-edge shadow. **desktop/src/shared/ui/sidebar.tsx** Clips the collapsing sidebar, disables interaction off canvas, and fades/translates its inner content without exposing a different background. **desktop/tests/e2e/community-rail.spec.ts** Adds gutter assertions for single-community collapsed-sidebar and multi-community layouts. **desktop/tests/e2e/sidebar.spec.ts** Covers the collapse opacity, translation, clipping, pointer-event behavior, and restoration on reopen. </details> ## Reproduction steps 1. Launch the desktop app with the Buzz theme and at least two communities. 2. Collapse the channel sidebar. 3. Confirm the main content surface keeps equal visible left and right gutters and does not overlap the community rail. 4. Reopen and collapse the sidebar again; confirm its contents fade and trail right while the chrome background stays opaque, then restore fully when reopened. ## Screenshots | Single community | Multiple communities | | --- | --- | |  |  | ## Validation - `pnpm build:e2e` - focused sidebar integration tests: 2 passed - collapsed multi-community smoke regression: 1 passed - Biome check on all four changed files - pre-push desktop check, typecheck, and test hooks - `git diff --check` Related issue/PR: none found. --------- Signed-off-by: Taylor Ho <taylorkmho@gmail.com> |
||
|
|
f0234f1449 |
fix(desktop): eliminate mounted-view CPU burn — compositor-safe shimmer, observer append fast path, poll-tick disk reads (#6198)
## Summary Live 0.5.16 review (Royal Court thread) traced the sustained 20–25% WebContent CPU burn in any large mounted channel with a working agent to three defects, in descending impact: 1. **Shimmer animation forces per-frame style + compositing walks.** `.buzz-shimmer` animated `background-position` under `-webkit-background-clip: text`, which WebKit cannot run on the compositor: every frame did a full document style resolve plus a recursive compositing-hierarchy update over the timeline's layer tree. The highlight now lives on an `aria-hidden` overlay child duplicating the label text and animates **opacity only** (compositor-accelerated); a real element is used instead of `::after` generated content so screen readers never see the duplicate text. Visual: the moving sweep becomes a gentle pulse. `prefers-reduced-motion` removes the overlay entirely — static muted label, exactly as before. 2. **Observer journal whole-journal dedup + re-sort per append.** Every one-per-second observer frame rebuilt a dedup Set over up to 3000 retained events and re-sorted the whole journal with a `Date.parse`-per-comparison comparator. In-order batches (the ordinary live path, same condition as the existing incremental transcript fold) now dedup within the batch and concat; out-of-order/replayed arrivals keep the full path. 3. **Redundant disk reads in the 5s agent-list poll.** `build_managed_agent_summary` re-read the global config from disk per call despite receiving it as a parameter, and re-read the teams store per tracked pair — 2N redundant reads per poll tick for N agents. Both are now caller-supplied; one-shot command paths use a `summarize_from_disk` helper. Same stores, same `unwrap_or_default` failure posture, read once. ## Evidence (mechanism attribution, live 0.5.16-block, mounted ~1500-event channel) - True-idle mounted view (working-state UI live): **25.08% mean / 24.15% median** WebContent CPU; post working-state decay: **6.33% / 3.50%**. - Reduce Motion A/B during a live agent turn (isolates the shimmer, working UI still mounted): **19.50% mean → 5.39% mean** (72% collapse). Native 10s samples: `Document::resolveStyle` 379 samples → 1; `updateCompositingLayersAfterStyleChange` 378 → 0; recursive `updateBackingAndHierarchy` 363 → 6. - The shimmer mechanism predates 0.5.16 (CSS unchanged since #3151); current multi-agent workloads exposed and amplified it. The mention regression itself was fixed separately in #6182. ## Testing - `desktop` observer store suites: 55/55 pass, including 5 new tests pinning the fast-path invariants (equal-timestamp seq ordering, duplicate-batch redelivery, intra-batch duplicates, overlapping late arrival takes the slow path, transcript-equals-replay on both paths). - `cargo test --lib managed_agents` (1016 passed) and `--lib commands` (727 passed); `cargo clippy` clean; `pnpm typecheck` + biome clean. - Release gate for the patched build (per Mongo): active-turn mounted CPU must collapse from the ~21–25% baseline with no per-frame style/compositing walk in a native sample — measured on Wes's workspace once a build with this branch is running. Findings and raw samples: `RESEARCH/LIVE_0_5_16_WEBKIT_ATTRIBUTION_2026_08_18.md`, `RESEARCH/RENDERER_STEADY_STATE_LOOP_AUDIT_2026_08_18.md`, `.scratch/live-app-review/` (Carl/Donut/Mongo/Brain, Royal Court thread 01a7fe75). --- *Opened by Brain (agent) via @wesbillman's account on his behalf — coordinated in Buzz channel agent-mention-policy-royal-court, thread 01a7fe75.* --------- Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Brain <21994759fc7a6fa6b965551d35cfd7897d262f2495467f2d78694ddcfa6a5c7e@buzz.block.builderlab.xyz> |
||
|
|
78cbffeb64 |
fix(desktop): hide the offcanvas-collapsed sidebar so it stops painting over the community rail (#5947)
## Summary Collapsing the sidebar left a phantom copy of it painted over the community/relay rail — opaquely on flat themes (vesper et al., which made the rail look *removed*), and as ghost fragments (muted search-box fill, truncated channel-name tails) on the Buzz themes whose chrome is intentionally transparent for the gradient. **Cause:** #4281 made the app-sidebar layer `overflow-visible` (the huddle drawer needs to escape it). That removed the ancestor clipping the offcanvas collapse relied on: the sidebar slides to `left: -sidebar-width` but kept painting, exactly over the `z-0` rail (`z-10` sidebar layer). **Fix:** the offcanvas-collapsed sidebar container is now `invisible` + `pointer-events-none`, with `visibility` added to the transition list so the 200 ms slide-out still animates and the flip happens only at the transition's end. Theme-independent; no per-theme CSS touched; the huddle drawer's `overflow-visible` is preserved. ## Before / after Left 420px of the app with the sidebar collapsed. Before = unpatched `origin/main` @ 69107dc3b; after = this branch. Same seeded state, same build pipeline (`build:e2e` between checkouts). | theme | before (ghost sidebar over the rail) | after (rail clean: A / B / + visible) | |---|---|---| | vesper |  |  | | buzz |  |  | | buzz-dark |  |  | Before shots: ghost `⌘K` search chip + blue active-item pill painted over the rail column; on vesper the opaque panel hides the rail buttons entirely. After: the rail's community buttons (A, B) and `+` are visible and clickable in all three themes. Reported by Thomas P in #buzz-bugs: buzz://message?channel=e62570dd-33ad-42c5-b92b-75f2689f9694&id=9ea401ca1d009f555ca4324e136f8d8d8156db2f8afa3ff89fd038d2c16260f7 cc @klopez4212 — this touches the layout your #4281/#5478 work shaped; please confirm it doesn't defeat the huddle drawer or glass intentions. The change deliberately hides only the *offcanvas-collapsed* container, nothing in the expanded path. ## Test plan - [x] New Playwright regression spec `sidebar-offcanvas-rail.spec.ts` (buzz / buzz-dark / vesper): collapsed sidebar must be `visibility: hidden` + `pointer-events: none`, community rail stays visible and interactive. **Fails on unpatched build** (verified), passes with the fix. - [x] Full desktop unit suite: 4,954 pass / 0 fail - [x] `pnpm typecheck`, `pnpm check` (biome + file-size ratchet + px-text + pubkey-truncation) green - [x] Before/after screenshots above captured via the e2e harness on both builds Signed-off-by: Thomas Petersen <thomasp@squareup.com> Co-authored-by: Wintermute <165f0c871dd2586bb18b6aa109eeaf57bb2132ff4d27b10120f4368a0f627022@buzz.block.builderlab.xyz> |
||
|
|
122a8b8988 |
Projects v3: unify sharing, discussions, and issue ownership (#5792)
## Summary Projects v3 makes repository work shareable, discussion-aware, and easier to scan in one coherent workspace. People can copy canonical links, reopen the exact workspace tab, understand issue and pull-request context at a glance, find related channel conversations, and assign or unassign issues across Desktop and CLI. - **Unified workspace** — top-level sections sit above repository controls in one rounded workspace, with navigation positioned close to the page heading. README and Files retain branch selection; every section has a labeled icon header, and Issues and Pull Requests expose creation from a consistent right-aligned action. - **Repository management** — the repository selector is always available, including single-repository projects. Its integrated add flow lets project owners create a repository manually or select an existing repository without a separate toolbar button. - **Readable work-item lists** — issue and pull-request rows use plain-language context instead of opaque metadata. Files, commits, issues, pull requests, channels, and contributors share consistent row density and right-aligned timestamps, while deterministic fallback-avatar colors keep participants distinct on light backgrounds. Inbox pull-request metadata wraps between complete phrases and truncates long channel names instead of compressing copy into narrow columns. - **Reliable entity links** — projects, repositories, issues, pull requests, and commits have canonical `buzz://` links, preview cards, OS deep-link routing, and tab-aware navigation. Reopening the same link re-applies its destination instead of leaving the user on a locally selected tab. - **Related conversations** — repository and work-item views surface channels discussing the current entity, including participants, channel navigation, message context, and an explicit notice when discovery reaches its 500-result cap. - **Reversible issue ownership** — trusted assignment and unassignment events work across Desktop, Tauri, `buzz-sdk`, and `buzz issues`. Assignees appear in project views and the assigned inbox, while authorized users can remove assignments directly from the assignee row. Assignment state is derived chronologically from labeled Nostr notes. Issue authors and repository owners may change any assignee; other users may only assign or unassign themselves. Shared golden fixtures keep entity-link grammar and validation aligned across TypeScript and Rust. The branch also updates `webbrowser` to the patched release for RUSTSEC-2026-0257. ### Related issue N/A. ### Testing - [x] `just ci` — formatting, lint, typechecking, unit tests, and builds passed - [x] Full pre-push suite — organization, branch-skew, Desktop checks, typechecking, and tests passed on the latest push - [x] `cargo test -p buzz-cli` and focused `buzz-sdk` assignment tests passed - [x] Focused Tauri recipient-note and 500-result search-limit tests passed - [x] Desktop entity-link and issue-assignment unit tests passed - [x] Playwright smoke coverage passed for assignment, repeated entity-link navigation, repository create/select flows, section headers and actions, timestamp alignment, timeline icons, sentence-style issue/PR metadata, header spacing, avatar contrast, and Inbox metadata at stacked and side-rail breakpoints - [ ] Manual staging pass: link round-trips, Channels tab, assignment flows, and inbox routing ### Screenshots Pull requests explain who opened the request, where it lives, and which branch it comes from; fallback avatars remain visually distinct.  Issues use the same sentence-style hierarchy while keeping status and recency easy to scan.  The wide Inbox detail keeps author, timestamp, and origin context readable beside its metadata rail.  [View the complete six-state Projects v3 screenshot set](https://github.com/block/buzz/pull/5624#issuecomment-5268039672) and [the compact/wide Inbox comparison](https://github.com/block/buzz/pull/5624#issuecomment-5268614585). --- > Supersedes #5624, whose head commit accumulated permanently-queued required check suites (block-dco-check et al.) that GitHub never dispatched. History flattened into a single signed-off commit on latest main; tree verified byte-identical (`git merge-tree`) to merging the original branch into main. --------- Signed-off-by: Thomas Petersen <thomasp@squareup.com> Co-authored-by: Wintermute <3f1797424fd9ad6653a83665c660517777cd7f8c228c0d5907f49e01537f3ca5@buzz.block.builderlab.xyz> |
||
|
|
207154706c |
fix(desktop): support channel message path links (#5889)
## Summary - accept `buzz://channel/<uuid>/<64-hex-event-id>` as a compatibility message deep link - activate the desktop window and route path-form message links through the existing durable message-navigation queue - support the same path form when rendered or pasted inside Buzz, while canonicalizing composer output to `buzz://message?...` - retain the existing one-segment channel-link behavior and reject malformed event IDs or extra segments ## Context Buzz Desktop 0.5.11 has no native `channel` route. The recently merged channel-link handling on main recognizes `buzz://channel/<uuid>`, but rejects the externally shared `<channel>/<event-id>` form before window activation. On macOS that presents as Buzz taking the menu bar while its window neither foregrounds nor navigates. ## Test plan - `cargo test --manifest-path desktop/src-tauri/Cargo.toml parse_channel_deep_link` - focused channel-link, composer-link, and markdown unit tests - `pnpm typecheck` - mandatory pre-push hook: desktop checks, full desktop unit tests, and Tauri/Rust checks Installed-app external-open behavior requires a build containing this change; 0.5.11 cannot exercise it because that release predates native channel-link handling. --------- Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz> |
||
|
|
5acb930821 |
feat(desktop-messages): render compact Buzz permalink chips (#5638)
**Category:** improvement **User Impact:** Buzz channel, message, repository, pull request, and issue links now open reliably and display recognizable context in the desktop app. **Problem:** Buzz links could appear as raw or ambiguous URLs, and navigation links received during startup or community transitions could be dropped before the UI was ready. Repository and issue shares in particular required hover context to understand at a glance. **Solution:** Queue desktop channel/message navigation until the UI is ready, then render bare Buzz permalinks as icon-prefixed chips with concise entity context while preserving user-authored Markdown labels as ordinary links. <details> <summary>File changes</summary> **desktop/src-tauri/src/deep_link.rs** Adds validated channel-link parsing and a deduplicated, acknowledged queue so navigation survives frontend startup. **desktop/src-tauri/src/lib.rs** Registers the pending-navigation state and commands with the desktop application. **desktop/src/features/communities/useCommunityInit.ts** Resets queued navigation safely across community boundaries without leaking stale destinations. **desktop/src/features/messages/lib/channelLink.test.mjs** Covers valid, malformed, and canonical channel permalink forms. **desktop/src/features/messages/lib/channelLink.ts** Defines strict parsing and detection for `buzz://channel/<uuid>` links. **desktop/src/features/messages/lib/composerMessageLinkNode.test.mjs** Extends composer-node coverage for normalized Buzz link content. **desktop/src/features/messages/lib/composerMessageLinkNode.ts** Keeps composer link-node handling aligned with the expanded Buzz link surface. **desktop/src/features/messages/lib/remarkChannelDeepLinks.test.mjs** Verifies bare channel URLs become renderable deep-link nodes without touching code. **desktop/src/features/messages/lib/remarkChannelDeepLinks.ts** Transforms eligible bare channel links into dedicated Markdown nodes. **desktop/src/features/messages/lib/remarkEntityLinks.test.mjs** Covers bare repository, pull-request, and issue detection and code-span exclusions. **desktop/src/features/messages/lib/remarkEntityLinks.ts** Adds dedicated Markdown nodes for bare Buzz project entities. **desktop/src/shared/deep-link.test.mjs** Exercises queued navigation, acknowledgement, serialization, and community-switch behavior. **desktop/src/shared/deep-link.ts** Serializes pending deep-link drains and acknowledges destinations only after successful navigation. **desktop/src/shared/styles/globals/markdown.css** Aligns permalink icon geometry and spacing with agent mention chips. **desktop/src/shared/ui/markdown.test.mjs** Adds integration coverage for every permalink chip, authored labels, fallbacks, icons, and static rendering. **desktop/src/shared/ui/markdown.tsx** Routes channel and entity nodes through the shared presentation path while preserving authored link text. **desktop/src/shared/ui/markdown/BuzzLinkChip.tsx** Introduces the shared interactive/static permalink chip and authored-label inline-link components. **desktop/src/shared/ui/markdown/ChannelDeepLink.tsx** Renders channel shares and references with Hash icons, names, and shortened-ID fallbacks. **desktop/src/shared/ui/markdown/MessageLinkPill.tsx** Renders ordinary message shares with message icons and channel/message context while retaining sent-from-thread behavior. **desktop/src/shared/ui/markdown/entityLinks.tsx** Maps repositories, pull requests, and issues to Projects-aligned icons and contextual labels. **desktop/src/shared/ui/markdown/nodeCache.ts** Includes entity-link rendering in cached Markdown node handling. **desktop/src/shared/ui/markdown/utils.ts** Allows validated channel links through the Buzz URL transform. **desktop/src/shared/useMessageDeepLinks.ts** Drains queued navigation links safely and clears them during teardown. **desktop/src/testing/e2eBridge.ts** Extends the mock bridge with pending-navigation command behavior. **desktop/tests/e2e/community-rail.spec.ts** Verifies queued links do not cross community boundaries. **desktop/tests/e2e/navigation.spec.ts** Covers channel/message deep-link navigation during startup and active sessions. **desktop/tests/helpers/bridge.ts** Adds reusable deep-link mock state and acknowledgement helpers. </details> ## Reproduction steps 1. Run the desktop app and open a channel containing bare `buzz://channel`, `buzz://message`, `buzz://repo`, `buzz://pr`, and `buzz://issue` URLs. 2. Confirm each bare URL renders as one cohesive chip with a type icon, a useful name or shortened identifier, and no duplicated channel `#` character. 3. Add an authored Markdown link such as `[design discussion](buzz://issue?...)` and confirm the supplied label remains an ordinary link rather than becoming a chip. 4. Select channel and message links and confirm they navigate correctly in warm and cold-start states. ## Screenshots / demos Houston dark theme with custom purple accent (`#a855f7`), captured from rebased visual implementation `ad411cc06`; current head `0aafa144f` only adjusts E2E expectations for the visible mention-label behavior shown here. **Composer — channel, message, repository, pull request, and issue pills**  **Message list — channel, message, repository, pull request, and issue pills**  --------- Signed-off-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz> Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz> |
||
|
|
17d2147eca |
Fix video comment effect wrapping (#5748)
## What changed - render video-review timecode chips inside the first Markdown paragraph so comment text wraps naturally around them - reuse the canonical video-review chip treatment across the timeline, Inbox previews, and Inbox detail - preserve video-review context in Inbox so timestamp chips remain interactive ## Why Video comments now support Markdown-like effects, but non-player surfaces rendered the timestamp beside a separate text layout. That kept the chip and comment from sharing the same inline flow and made Inbox behavior inconsistent with the player. ## Validation - `pnpm --dir desktop check` - 100 focused Markdown, timecode, video-review, and Inbox unit tests - `pnpm --dir desktop build:e2e` - focused `video-attachment.spec.ts` Playwright scenario - pre-push desktop typecheck and 4,761-test desktop suite - native Builderlab staging with the configured profile Focused timeline and Inbox snapshots will be attached in a PR comment. --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Signed-off-by: Fast Fizz <2df81cb51f05a9d5387ef24d7b9ecb8fcdfcd1c70ffabc67061c9596e1b5b1c4@buzz.block.builderlab.xyz> Co-authored-by: Fast Fizz <2df81cb51f05a9d5387ef24d7b9ecb8fcdfcd1c70ffabc67061c9596e1b5b1c4@buzz.block.builderlab.xyz> |
||
|
|
eedcd886a0 |
fix(desktop): match compact link preview thumbnail corners to card shell (#5711)
## Problem In compact link preview cards with an image, the thumbnail's corners looked inconsistent — the flush left side and the interior right side read as different shapes. ## Cause The `Attachment` shell rounds its corners with a **smooth-corner (squircle) clip path** via `useSmoothCorners`, not a plain `border-radius`. In compact image mode the shell has `p-0`, so the thumbnail sits flush against its left, top, and bottom edges. That means: - **Left corners** are carved by the shell's smoothed clip path. - **Right corners** are drawn by the thumbnail's own plain `border-radius`. A circular arc and a smoothed corner of the *same* radius are different shapes (at 16px the smoothed curve starts 25.6px along the edge instead of 16px). So the two sides could never match by picking a radius value — the thumbnail's class has no effect on its left corners at all. ## Fix Give the thumbnail the same `useSmoothCorners` treatment as the shell, so both sides share one curve. - Radius token unchanged: `rounded-2xl` (16px). - The shell and the shared `Attachment` component are untouched, so no other `Attachment` consumer changes. Verified on a rendered card — thumbnail vs shell now agree on all three: arc radius (16), smoothing (0.6), and curve start (25.6px). ## Hardening The underlying issue is an invariant that lived nowhere: **a child flush against a smooth-cornered parent must share its corner treatment.** This is why the bug was easy to introduce and hard to diagnose. - Documented the invariant in `smoothCorners.ts`, where anyone reaching for the hook will see it. - Added an `expectSmoothCorners()` guard to the existing compact-preview e2e test. Confirmed it **fails** when the fix is reverted, so it genuinely bites. Note: this cannot be a lint rule — "flush" is a runtime layout fact, not visible in the source. ## Known follow-up (not in this PR) The composer link preview (`useComposerLinkPreviews.tsx`) has the same latent issue: a flush thumbnail with a hand-copied `rounded-l-2xl` that happens to match the shell's current 16px. It is correct today only by coincidence of two literals agreeing. Left for a separate PR rather than expanding scope here. ## Screenshots The same compact card and content before and after the change. | Before | After | | --- | --- | | Original `rounded-xl` (12px) thumbnail: left corners are clipped by the card’s 16px smooth silhouette while the right corners keep the thumbnail’s smaller plain radius | `rounded-2xl` (16px) thumbnail with the same smooth-corner treatment as the card | |  |  | ## Verification - `pnpm exec biome check` on all three touched files - `pnpm exec tsc --noEmit` - `node --test src/shared/ui/smoothCorners.test.mjs` — 3 passed - All 18 link-preview e2e tests pass - Guard verified to fail without the fix, then pass with it Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com> |
||
|
|
45f4b91a36 |
fix(desktop): more compact "compact" link previews (#5629)
**Category:** improvement **User Impact:** Compact link previews now use a single-line title and smaller thumbnail, making conversations easier to scan. **Problem:** Compact previews gave long titles and oversized thumbnails too much visual weight in the message timeline. **Solution:** Keep titles to one ellipsized line and reduce image thumbnails to a 104×64 treatment while preserving the existing wide aspect ratio; Rich previews remain unchanged. <details> <summary>File changes</summary> **desktop/src/shared/ui/compact-link-preview-attachment.tsx** Tightens the Compact presentation with a single-line title and smaller wide thumbnail, leaving Rich previews untouched. **desktop/tests/e2e/messaging.spec.ts** Adds focused coverage for title overflow, exact 64px card and 104×64 thumbnail geometry, and successful decoded-image rendering using a realistic fixture, plus an optional visual capture. **desktop/tests/fixtures/github-pr-5629-og.png** Provides realistic visible image bytes for the compact-preview image-rendering E2E path. </details> ## Reproduction steps 1. Launch the desktop app with link preview style set to Compact. 2. Send a link whose preview has an image and a long title. 3. Confirm the thumbnail renders at the smaller wide size and the title truncates to one line with an ellipsis. 4. Switch link preview style to Rich and confirm its presentation is unchanged. ## Screenshot  --------- Signed-off-by: Taylor Ho <taylorkmho@gmail.com> Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz> |
||
|
|
884ed8a5d3 |
fix(link-previews): proxy sent preview media (#5627)
## Overview **Category:** fix **User Impact:** Sent link previews now reliably display their thumbnail and favicon when the media is hosted on the relay. **Problem:** Sent preview cards loaded relay-hosted snapshot media directly, so authenticated relay requests could fail even though the snapshot itself was valid. **Solution:** Rewrite snapshot media at the shared card render boundary through Buzz's authenticated local media proxy, preserving the original display domain and rerendering when the proxy becomes ready. ## Changes <details> <summary>File changes</summary> **desktop/src/shared/ui/link-preview-attachment.tsx** Routes sent preview thumbnails and favicons through authenticated relay media handling above the Compact/Rich fork while preserving original metadata. **desktop/src/testing/e2eBridge.ts** Adds an opt-in proxy-readiness seam that deterministically re-arms the production media lookup when released. **desktop/tests/e2e/messaging.spec.ts** Covers the real send, snapshot, recipient, and card-render path for Compact and Rich previews, including fallback URLs, proxied URLs, and decoded image content. **desktop/tests/helpers/bridge.ts** Exposes the opt-in media-proxy startup state to E2E tests. </details> ## Reproduction Steps 1. Send a link whose preview snapshot includes a relay-hosted thumbnail and favicon. 2. Inspect the sent message card in Compact mode and confirm both images render after the local media proxy becomes ready. 3. Switch link previews to Rich mode and confirm the thumbnail and favicon continue to render. 4. Run the focused Playwright regression: `pnpm exec playwright test tests/e2e/messaging.spec.ts --project=smoke --grep "sent link preview media uses the authenticated proxy"` ## Before / After | Before | After | | --- | --- | | Relay-hosted preview media fails to load. | The sent preview thumbnail and favicon render through the authenticated media proxy. | |  |  | Signed-off-by: Taylor Ho <taylorkmho@gmail.com> |
||
|
|
63f961c7e4 |
Refine channel settings and profile panels (#5574)
## Summary - simplify channel settings into concise detail, member, canvas, and action sections - align human and agent profiles around shared rows, segmented tabs, and top-level actions - add agent runtime presentation, sticky glass behavior, and scroll-linked action transitions ## Snapshots ### Channel settings  ### Agent info  ### Agent runtime  ## Validation - `pnpm -C desktop check` - `pnpm -C desktop test` (4,604 passed) - `pnpm -C desktop build:e2e` - focused channel settings and agent profile Playwright tests --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Co-authored-by: Mongo <9cfd347903944d5b85aa6c93d2ab67381b978a92a31914bca69998968752a1d7@buzz.block.builderlab.xyz> |
||
|
|
cd2aa5c12d |
Add glass appearance and cohesive settings (#5478)
## Summary - add an opt-in native glass sidebar with opacity controls and live theme previews - refine sidebar spacing and Buzz-only active rows while preserving production defaults - unify settings section cards, subtitles, and agent runtime rows ## Validation - repository format, lint, type, and file-size checks - 4,538 desktop tests and 2,270 native desktop tests - desktop and web production builds - 1,261 mobile tests in the completed full gate - focused Playwright appearance, sidebar, settings, pairing, and runtime coverage --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Signed-off-by: Kenny Lopez <klopez4212@gmail.com> Signed-off-by: Wes <wesbillman@users.noreply.github.com> Signed-off-by: Fast Fizz <2df81cb51f05a9d5387ef24d7b9ecb8fcdfcd1c70ffabc67061c9596e1b5b1c4@buzz.block.builderlab.xyz> Co-authored-by: Carl <3c4caeafb646d23867f1c4832e68211d77e2561946171625f75c3ce1a3f2670f@buzz.block.builderlab.xyz> Co-authored-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz> Co-authored-by: Fast Fizz <2df81cb51f05a9d5387ef24d7b9ecb8fcdfcd1c70ffabc67061c9596e1b5b1c4@buzz.block.builderlab.xyz> |
||
|
|
b0795a10ea |
Add Send to channel for thread messages (#5305)
## Summary - Share eligible self-authored or owned-agent thread messages into the parent channel as new top-level messages. - Link the shared message back to the exact root thread with a semantic channel label and excerpt. - Add a dedicated channel-arrow icon plus ownership and navigation coverage. ## Validation - Desktop lint, size, and text guards - Desktop TypeScript build and all 4,543 unit tests - Focused Playwright send-to-channel and thread-link navigation tests --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Signed-off-by: Kenny Lopez <klopez4212@gmail.com> Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <3c4caeafb646d23867f1c4832e68211d77e2561946171625f75c3ce1a3f2670f@buzz.block.builderlab.xyz> Co-authored-by: Princess Donut <b238ea756dee4d98afa5883fc7f1de61eeabe65bf700e3a5a5a80db5e42e2c2b@buzz.block.builderlab.xyz> Co-authored-by: Fast Fizz <2df81cb51f05a9d5387ef24d7b9ecb8fcdfcd1c70ffabc67061c9596e1b5b1c4@buzz.block.builderlab.xyz> Co-authored-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz> |
||
|
|
7e6e9c547f |
fix(link-preview): restore Buzz entity link cards (#5494)
**Category:** fix **User Impact:** Buzz pull request, issue, and repository links now show compact, useful metadata cards in received messages, including messages sent by agents and the CLI. **Problem:** Sender-authored snapshots protect recipients from external preview fetches, but that change also removed recipient-side cards for trusted Buzz entity links when the sender did not attach snapshots. **Solution:** Resolve recognized Buzz entities only against the active relay and show signed repository identity, title, and compact builder context with the current inline Buzz mark in the favicon slot, but without avatars, thumbnails, or external image fetches. Entity metadata wins over conflicting sender snapshots, while unsupported or unavailable metadata retains a safe text fallback. <details> <summary>File changes</summary> **desktop/playwright.config.ts** Adds the entity-link regression spec to the smoke test project. **desktop/src/features/messages/ui/useComposerLinkPreviews.tsx** Treats recognized Buzz entity cards as complete without generating snapshot tags and retains fallback cards when relay metadata is absent. **desktop/src/shared/lib/useResolvedLinkPreviews.test.mjs** Covers kind-scoped entity detection, trusted relay metadata, root-scoped lifecycle queries, exact single-repository root binding, image-less pending state, and fallback behavior. **desktop/src/shared/lib/useResolvedLinkPreviews.ts** Resolves signed repository, pull request, and issue metadata from the active relay. Entity roots fail closed unless they carry exactly one matching repository tag; lifecycle queries are root-scoped before limits; successful metadata remains stable until relay/community reset, and PR commit context uses the immutable root event rather than an unindexed update query. **desktop/src/shared/ui/compact-link-preview-attachment.tsx** Uses Buzz repository identity as the compact card provider and avoids reserving thumbnail space for image-less entity cards. **desktop/src/shared/ui/markdown.tsx** Routes message cards through the combined entity/snapshot preview hook. **desktop/src/shared/ui/markdown/useMessageLinkPreviews.test.mjs** Proves relay-authenticated entity metadata beats a forged sender snapshot while preserving mixed-link content order. **desktop/src/shared/ui/markdown/useMessageLinkPreviews.ts** Combines recipient-resolved Buzz entities with sender-authored external snapshots using explicit trust precedence and first-seen ordering. **desktop/tests/e2e/entity-link-recipient-cards.spec.ts** Exercises repository identity, PR workflow context, repository metadata, image-less rendering, and composer send behavior for agent/CLI-style entity links. </details> ## Reproduction steps 1. Open a channel containing a message sent without `link-preview` tags whose content includes valid `buzz://pr`, `buzz://issue`, or `buzz://repo` links. 2. Confirm each card shows its repository identity and signed title; PRs/issues also show compact lifecycle context, and repositories show description/status/default branch. 3. Confirm the cards use the Buzz mark in the favicon slot with no avatar, thumbnail, or reserved image area. 4. Compose and send a message containing a Buzz entity link; confirm sending is not blocked waiting for a snapshot. 5. Send a message containing both a Buzz entity link and a snapshot-backed HTTPS link; confirm cards follow content order and the HTTPS link remains sender-snapshot-only. ## Screenshots ### Recipient view — Buzz-branded metadata cards Repository identity, title, and compact builder context render with the current inline Buzz mark in the favicon slot and no avatar, thumbnail, or reserved image space.  ## Validation At commit `7bc70b0a9f70392bd062ed25b1d2362cc4021a40` with a clean working tree: - Pre-push hooks passed: branch skew, desktop check, desktop typecheck, and full desktop unit suite - Full desktop unit suite: 4,560 passed - Purpose-built Playwright regression after a fresh E2E build: 2 passed - Screenshot regenerated from the same commit and visually inspected Originating conversation: Buzz channel `c2859932-b679-4091-9c7e-f5a65deddd64`, thread `93c3e7be59a8d1ec10b4992efd783a2a79f253a10f10d39746c6ad41b0d5bb42`. --------- Signed-off-by: Taylor Ho <taylorkmho@gmail.com> |
||
|
|
1922d49cb2 |
feat(desktop): adding rich link previews to messages (#3818)
## Overview **Category:** improvement **User impact:** Link previews appear in the composer and travel as privacy-safe sender-authored snapshots, so recipients never contact the linked site merely by opening a conversation. **Problem:** Cold-cache link paste could freeze the composer before the URL painted; recipient-side unfurling leaked visits; invalid or unresolved preview work could interfere with sending or leave dead cards behind. **Solution:** Paint pasted links before starting cold resolver work, resolve only in the sender's composer, attach only complete validated snapshots at Send, and render authored snapshots without recipient fallback fetching. ## Behavior - **Cold paste stays responsive:** bare and angle-bracket URL paste paths commit the visible link before resolver work begins. - **Sender-only fetching:** metadata is resolved while composing; recipients render only the sender-authored snapshot. - **Send never waits:** pending, failed, invalid, and unsendable previews are omitted. They do not block or cancel the message. - **Terminal misses disappear:** failed, timed-out, or 404 resolver results remove the composer card while preserving visible link text. - **Display-text links work:** Markdown links such as `[review the pull request](…)` produce and send the same snapshots as bare URLs. - **Compact and Rich presentation:** Compact remains the default; Rich preserves source description line breaks and paragraphs. - **Immediate draft-wide dismissal:** clicking × immediately hides all previews for the draft, suppresses links pasted later, and emits only `["link-preview", "none"]`. No confirmation detour. Suppression resets after send or clearing the draft. - **Zero recipient fallback:** missing, stale, malformed, off-relay, unsupported, or suppressed snapshots remain ordinary visible links; recipients never regenerate them. ## Implementation - Resolve previews from deferred composer URL state so paste can paint first. - Upload finished preview media to the active community relay and snapshot only valid, sendable media references. - Atomically capture ready snapshots at submit time; never append a late preview after send. - Validate snapshot and suppression tags in desktop/native and relay ingestion, rejecting duplicate or mixed forms. - Render composer previews as stable 55px attachment cards at desktop and narrow widths. - Add deterministic E2E coverage for cold paste, ready/pending/failed/invalid previews, display-text links, multiline Rich descriptions, immediate dismissal, later-pasted links, and suppression reset. ## Validation Validated head: `9807ba8952f190e76153834abf8ab61dd40be5e2` - Push hooks passed: `check-push-org`, branch skew, desktop check, mobile tests, desktop tests, Rust tests, and desktop Tauri checks. - Focused screenshot E2E at the validated head: 5/5 passed across Compact/Rich composer and recipient states, 800px/420px geometry, display-text links, multiline descriptions, and immediate dismissal. - PR CI was triggered for this exact head and is currently running; completed checks are green at the time of this update. - Worktree is clean and both PR head and validated branch resolve to `9807ba895…`. ## Screenshots ### Compact composer | Loading | Ready | |---|---| |  |  | ### Rich composer | Loading | Ready | |---|---| |  |  | ### Responsive composer | 800px loading | 800px ready | |---|---| |  |  | | 420px loading | 420px ready | |---|---| |  |  | ### Recipient presentation | Compact | Rich | |---|---| |  |  | ### Display-text Markdown link | Composer | Recipient | |---|---| |  |  | ### Rich multiline description  ### Immediate dismissal | Before × | Immediately after × | |---|---| |  |  | --------- Signed-off-by: Taylor Ho <taylorkmho@gmail.com> |
||
|
|
cd2125c34b |
Improve video review readiness and controls (#5161)
   --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> |
||
|
|
a1d78f2959 |
feat: Buzz entity links — rich preview cards + in-app navigation for repos, PRs, and issues (#4695)
## 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>
|
||
|
|
ce3cf3cd25 |
Polish Huddle voice controls (#4694)
## Summary - add a visible Stop control for interrupting agent speech - make push-to-talk available by default while preserving manual mute controls - refine agent management, muted audio states, drawer layering, and return navigation - suppress duplicate notification sounds for Huddle messages ## Why Huddles could trap users behind long agent speech, hide useful agent controls, and leave temporary Huddle state visible after the call. The drawer also regressed when the terminal substrate began painting behind the rounded app surface. ## Validation - `just desktop-ci` - focused Huddle Playwright coverage for the drawer, speech interruption, agent picker, and leave navigation --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz> |
||
|
|
540b58920c |
Polish sidebar unread hierarchy (#4573)
## Summary - Keep selected sidebar rows regular by default; manually unread rows become bold immediately. - Apply a clearer dark-mode hierarchy: standard inactive rows at 75%, muted rows at 45%, and unread rows at full emphasis. - Keep hover text color stable while retaining the selected-row and unread cues. ## Validation - `pnpm typecheck` - `pnpm build:e2e` - Playwright: sidebar badge and channel-mute coverage ## Screenshots Posted in the PR comments. --------- Signed-off-by: kenny lopez <klopez4212@gmail.com> |
||
|
|
468647a51f |
feat(desktop): locally stored NIP-49 encrypted key backup (#2937)
## Summary
Adds a locally stored **NIP-49 encrypted key backup** (`ncryptsec`) to
the desktop app, per the plan reviewed in buzz-development (Rev 3,
approved 9/10 by Wren; implementation also reviewed and approved 9/10).
**Two-artifact design — canonical bytes originate entirely in Rust:**
- `create_ncryptsec_backup` runs under the `identity_mutation` lock:
encrypt → decrypt-verify against the live pubkey → atomic `0o600` write
to `{app_data_dir}/identity.ncryptsec` → reread/byte-compare → return
the exact persisted bytes. The frontend never re-derives or re-encrypts.
- `save_ncryptsec_copy` writes a portable copy via the save dialog
(parse-gated, secret-file semantics) and never mutates canonical state.
- `generate_backup_passphrase`: 6 words from the EFF short wordlist via
`OsRng` (custom passphrases min 12 chars).
- Import accepts `ncryptsec1` with optional password; the raw-`nsec`
path is untouched. Different-pubkey import and sign-out wipe the
app-managed backup (post-commit, best-effort — a failed import can never
destroy the still-live identity's backup; regression-tested).
**Never-relay guarantee (egress guard + tripwires):**
- `egress_guard.rs` fail-closed at all 8 `/events` submission boundaries
(relay submit funnel, 3× `relay.rs`, huddle STT, both engram submitters,
native WS choke point), rejecting `ncryptsec1`/`NCRYPTSEC1` in text and
binary frames. Scope is deliberately ncryptsec-only: pairing
intentionally carries raw nsec inside its encrypted session.
- Site-granular `/events` inventory tripwire: per-file (`/events` count,
guard-call count) pairs; unlisted files expect zero. Mutation-style
tests prove a ninth site in an existing file, a removed guard, and a new
unlisted file all fail the scan.
- ncryptsec source-allowlist scans in **both** trees (Rust + TS).
**Frontend:** onboarding `BackupStep` is encrypted-by-default — the
default path never invokes `get_nsec` (e2e asserts the command log).
Raw-nsec export stays behind an explicit click with prior semantics.
Shared `EncryptedBackupCreator` powers onboarding + a new settings row;
the import form auto-switches to encrypted mode on `ncryptsec1` paste
(case-insensitive HRP).
**Open product call for @tlongwell-block:** onboarding default is
*encrypted* in this PR; flipping to raw-default is a small change either
way (documented in the plan).
Review history: plan Rev 3 and the implementation were both iterated
with Wren to 9/10 (two blockers from round 1 — import ordering,
inventory granularity — plus an uppercase-bech32 hardening gap, all
fixed in `dde37183e`). Thread: buzz-development.
### Related issue
Follow-up to the direction explored in #385 (NIP-PB, closed) — this
ships local NIP-49 (the standard) instead of a new NIP. No open
duplicate found.
### Testing
All at exactly `dde37183e` (same shell, HEAD verified):
- `cargo test` — 1680 passed / 0 failed / 14 ignored (includes a
deliberate ~70s log_n-18 NIP-49 round trip, spec vector, wrong-password,
NFKC, uppercase-vector decrypt, injection test per egress boundary,
inventory mutation tests, import-ordering regression tests)
- `cargo clippy --all-targets -- -D warnings` — clean; `cargo fmt
--check` — clean
- `pnpm typecheck` — clean; JS unit suite 3529/3529; biome (repo-pinned
2.4.16) clean
- Playwright `onboarding-backup` / `onboarding` /
`onboarding-agent-defaults` / `profile-nsec-reveal` — 86 passed, 1 known
avatar-reservation flake (passed on rerun; untouched by this diff).
`passThroughBackupStep` now exercises the encrypted default, so every
downstream onboarding spec covers the new path.
- Note: browser e2e fakes the crypto via the mock bridge (fixed
spec-vector blob); decryption correctness is proven in the Rust tests.
## Latest onboarding integration
The current head adds an additive `IdentityInfo.storage` field
(`ephemeral`, `system-keyring`, `local-file`, or `environment`) so
onboarding can accurately explain where the active identity is
protected. It surfaces storage metadata only—never key material—and
leaves the existing lost/keyring-locked recovery behavior intact.
---------
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz>
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@buzz.block.builderlab.xyz>
|
||
|
|
d8f9d87c17 |
Polish composer activity layout and transitions (#3151)
## Summary - Replace the permanently reserved composer activity row with a conditional, content-driven accessory for channel and thread composers. - Keep the composer dock geometrically stable while activity appears, so the composer’s bottom edge resizes smoothly without shifting the conversation. - Preserve translucent backdrop blur during the resize with a stable dock-level blur layer, and keep thread overlay/focus-mode alignment consistent. - Keep bottom-pinned virtualized conversations fully visible as composer content, zoom, or viewport height changes without repinning readers who have scrolled into history. - Refine the activity lockup with aligned avatars/text and a subtle, reduced-motion-safe shimmer. - Centralize the dock’s quiet inset, activity rail, released space, and activity offset in one CSS-variable geometry contract. This takes a different, systemic route from the spacing reduction proposed in #2602 and supersedes that approach. ### Related issue Related PR: #2602 ### Testing - `./scripts/check-branch-skew.sh` - `just desktop-check` - `just desktop-test` — 3,638 passing - `useAnchoredScroll.test.mjs` — virtualized viewport resize follows the explicit bottom state - Focused desktop smoke E2E — 6 passing across stable dock geometry, multiline growth, viewport resize, reduced motion, blur ownership, and thread overlay alignment - Pre-push hooks passed for organization safety, branch skew, desktop checks/tests, Rust tests, workspace tests, and desktop Tauri tests - Mobile pre-push is independently red on latest `main`; the exact `activity_page_test.dart` compiler failure reproduces on untouched `origin/main` - Visually tested channel and thread composers across quiet/activity states, multiline composer growth, and thread overlay/focus mode https://github.com/user-attachments/assets/ed0b08d9-18e0-4061-b272-ab509dbcd8ee --------- Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com> |
||
|
|
d98da7389e |
feat(desktop): redesign agent runtime settings (#3093)
**Category:** improvement **User Impact:** Users can understand, install, authenticate, and manage agent runtimes from one progressively disclosed Agents settings experience. **Problem:** Runtime health and custom harness management were split across overlapping settings surfaces, exposing low-level configuration too early while leaving setup and authentication states hard to understand. **Solution:** Consolidate those operations into one stable runtime list and an Add runtimes catalog, with task-oriented state labels, direct setup actions, and custom configuration contained in a dedicated form. <details> <summary>File changes</summary> **desktop/playwright.config.ts** Registers the visual coverage needed for the redesigned runtime catalog. **desktop/public/harness-logos/CREDITS.md** Documents bundled runtime-mark provenance and the decision not to ship the withdrawn OpenAI mark. **desktop/public/runtime-icons/codex.png** Removes the obsolete Codex bitmap in favor of the neutral fallback. **desktop/public/runtime-icons/goose.svg** Removes the old Goose asset now replaced by the theme-adaptive mark. **desktop/src-tauri/src/managed_agents/discovery.rs** Aligns runtime discovery guidance with the new task-oriented setup language. **desktop/src-tauri/src/managed_agents/discovery/runtime_metadata.rs** Updates runtime metadata used by the redesigned settings states. **desktop/src/features/agents/ui/runtimeAvailabilityWarning.test.mjs** Updates availability-warning expectations for the revised runtime guidance. **desktop/src/features/onboarding/assets/harness-logos/chatgpt.png** Removes the redundant bitmap from the unified runtime icon pipeline. **desktop/src/features/onboarding/assets/harness-logos/goose.png** Removes the redundant Goose bitmap. **desktop/src/features/onboarding/ui/HarnessMarks.tsx** Adds theme-adaptive bundled runtime marks with safe fallbacks. **desktop/src/features/onboarding/ui/RuntimeIcon.tsx** Centralizes runtime logo rendering so settings and catalog rows cannot drift. **desktop/src/features/onboarding/ui/SetupStep.tsx** Aligns onboarding runtime setup copy with the settings terminology. **desktop/src/features/onboarding/ui/presetLogos.test.mjs** Guards bundled-logo behavior and prevents the withdrawn Codex mark from returning. **desktop/src/features/settings/ui/CustomHarnessForm.tsx** Reworks custom runtime creation and editing into a clear, dedicated catalog form. **desktop/src/features/settings/ui/HarnessCatalogDialog.tsx** Introduces the Add runtimes master-detail catalog, grouped setup states, loading treatment, and pinned actions. **desktop/src/features/settings/ui/HarnessManagementCard.tsx** Removes the superseded standalone custom-harness management surface. **desktop/src/features/settings/ui/HarnessRow.tsx** Provides stable operational runtime rows with install, update, authentication, edit, and delete behavior. **desktop/src/features/settings/ui/HarnessesSettingsPanel.tsx** Consolidates runtime health and custom management into one Agents settings panel. **desktop/src/features/settings/ui/SettingsPanels.tsx** Wires the consolidated panel into Agents settings. **desktop/src/features/settings/ui/harnessCatalogCopy.ts** Adds restrained, source-annotated runtime descriptions and setup guidance. **desktop/src/features/settings/ui/harnessCatalogLogic.test.mjs** Covers grouping, state labels, stable row order, actions, and adapter warnings. **desktop/src/features/settings/ui/harnessCatalogLogic.ts** Centralizes catalog grouping, actions, status labels, and runtime-safe warning copy. **desktop/src/features/settings/ui/harnessGalleryLogic.test.mjs** Removes obsolete gallery-only tests after consolidation. **desktop/src/features/settings/ui/harnessGalleryLogic.ts** Retains only the shared custom-runtime safety logic needed by the new surface. **desktop/src/shared/ui/config-nudge-attachment.tsx** Points configuration nudges to Agent runtimes with matching terminology. **desktop/src/testing/e2eBridge.ts** Adds deterministic runtime states for authentication and catalog E2E coverage. **desktop/tests/e2e/doctor-states.spec.ts** Verifies ready, setup-required, node-gated, authentication, loading, and error contracts. **desktop/tests/e2e/harness-catalog-screenshots.spec.ts** Captures whole-pane visual states for the runtime catalog experience. **desktop/tests/e2e/harness-management.spec.ts** Exercises catalog actions and custom runtime create, edit, authentication, and deletion flows. **desktop/tests/e2e/onboarding-agent-defaults.spec.ts** Updates default-runtime expectations for the consolidated experience. **desktop/tests/e2e/profile.spec.ts** Aligns profile navigation assertions with the new settings surface. </details> ## Reproduction steps 1. Open Settings → Agents and inspect Agent runtimes; ready, signed-out, installable, and setup-required runtimes should have stable rows and explicit actions. 2. Open Add runtimes and browse the Setup and Installed groups; select entries to see sourced guidance and a pinned Install or Setup guide action. 3. Select Custom harness, create a runtime, then edit and delete it; verify required-field gating and the blast-radius confirmation. 4. Exercise a signed-out runtime and connect it; the row should move from Sign-in needed to Ready without reordering. 5. Resize the window and switch themes to verify responsive layout and adaptive bundled marks. ## Screenshots | Mixed runtime states | Goose not installed | Sign-in needed | |---|---|---| | <img width="980" height="1000" alt="image" src="https://github.com/user-attachments/assets/28705b39-1d91-440a-a954-fb2d7d8ee759" /> | <img width="980" height="1000" alt="image" src="https://github.com/user-attachments/assets/e65ce8e1-8c85-4272-afb5-e6001b94d560" /> | <img width="980" height="1000" alt="image" src="https://github.com/user-attachments/assets/3987f355-960d-4744-8c26-b3746944a33c" /> | | Add runtimes catalog | Custom runtime | Setup guide | |---|---|---| | <img width="896" height="672" alt="image" src="https://github.com/user-attachments/assets/a2f32c8a-4dff-4929-af96-b07346933335" /> | <img width="896" height="672" alt="image" src="https://github.com/user-attachments/assets/b2e85a0c-3940-4875-a138-4035423c9de7" /> | <img width="896" height="672" alt="image" src="https://github.com/user-attachments/assets/5a690c1c-368e-4ee3-98b9-ffefdc3cf804" /> | Full 13-state screenshot matrix and review evidence: https://buzz.block.builderlab.xyz/channels/c5af9e3e-4317-4853-b3e3-ed9c15bc511d?event=ec88f6e472f2b08d6318ae76fd754fd4f218385f67cfe59b73034c4bc34c9252 --------- Signed-off-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@buzz.block.builderlab.xyz> Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@buzz.block.builderlab.xyz> |
||
|
|
afb272bb7b |
fix(desktop): render rich project work item content (#3100)
## Summary Project issues, pull requests, reviews, and commit details no longer flatten rich content into inert or plain text. They now share the message markdown and media pipeline, preserving NIP-92 `imeta` metadata so links, images, and videos render consistently. Commit bodies are fetched only when a single-commit detail view is opened, keeping list queries lightweight while exposing full context beside the diff. ### Related issue None found. ### Testing - Pre-push suite: `desktop-check`, `desktop-test`, `desktop-tauri-test`, `rust-tests`, and `mobile-test` - Project issue and pull request regression tests cover preserving attachment metadata on roots, updates, and comments - The project commit detail smoke scenario verifies linked text, images, and video in commit bodies Signed-off-by: Thomas Petersen <thomasp@squareup.com> |
||
|
|
95fdf97880 |
feat(acp): bring your own harness (BYOH) — generic ACP runtime seam + settings gallery (#2773)
## What
Implements a "bring your own harness" (BYOH) generic ACP mechanism —
replacing per-harness backend code with a data-driven 3-tier system:
- **Tier 1 (compiled-in builtins):** goose, claude, codex, buzz-agent —
unchanged behavior
- **Tier 2 (bundled presets):** cursor, omp, grok, opencode, kimi, amp,
hermes, openclaw, and any future additions — defined in
`PRESET_HARNESSES`, no code duplication, icons stay
TerminalSquare/bundled-asset-only
- **Tier 3 (user-defined custom):** JSON definitions saved to
`custom_harnesses/` under app data; managed via Settings → Agents UI
## Changes
### Core data model
- `HarnessDefinition` — id, label, command, args, env, install URL/hint
- `PRESET_HARNESSES` static table — single source of truth for all
presets; `preset_harness_ids()` derives reserved IDs (D-11: no
hand-maintained copy)
- `source: "builtin" | "preset" | "custom"` tagging on every catalog
entry
### Persistence (B-4, B-6)
- `save_custom_harness_to_dir(dir, definition, rename_old_id)` —
backup-swap atomic write (backs up target → .bak, commits temp → target,
restores .bak on failure, removes .bak on success); safe on Windows
where `fs::rename` over an existing file is "access denied"
- `save_and_warm` / `delete_and_warm` — hold `PERSIST_MUTEX` for the
write + registry-warm pair, eliminating the lost-update race (B-6) where
two concurrent saves could interleave their warm calls and leave a stale
registry snapshot
- Validate-before-mutate: both IDs and env validated before any
filesystem mutation
### Env validation boundary (B-3)
- `validate_harness_definition_pub` calls `validate_user_env_keys` on
definition env at save AND load
- Rejects malformed keys (BUZZ_AUTH_TAG=x forgery shape), reserved keys
(BUZZ_MANAGED_AGENT etc.), NUL bytes, oversized values
### TypeScript boundary (B-2 / Thufir CRITICAL)
- `RawAcpRuntimeCatalogEntry` now declares `definition_env?:
Record<string,string>` and `source: "builtin" | "preset" | "custom"`
- `fromRawAcpRuntimeCatalogEntry` maps `definition_env → definitionEnv`
(camelCase); absent field defaults to `{}`
- Edit form reads `entry.definitionEnv` — env no longer erased on
save-then-edit cycle
### Unified descriptor (Phase A / Thufir F4)
- `EffectiveHarnessDescriptor { command, args, env }` in `readiness.rs`
- `resolve_effective_harness_descriptor()` — single resolver used by
spawn, spawn_hash, summary, get_agent_models (both saved and unsaved),
and readiness
- No competing arg-resolution forms
### Other fixes
- B-5: stop freezing `runtime.defaultArgs` into `record.agent_args` on
normal create paths
- B-7: readiness exec-check — `MissingBinary` variant for custom
commands not found on PATH
- B-8: onboarding transition — `setTimeout(0)` removed, parent-owned
route intent via `navigateAfterComplete` prop
- C-9: collector-discriminating sweep tests with injectable filters
- C-10: `HarnessManagementCard` uses `harnessGalleryLogic` helpers
(killed duplicate filter/sort)
- D-11: `BUILTIN_IDS` derived from `PRESET_HARNESSES` (no
hand-maintained copy)
- D-12: `mobile/pubspec.lock` churn reverted
- D-13: false ownership fast-path comment fixed
- D-14: URL scheme validation for `installInstructionsUrl`
- D-15: OpenClaw Gateway env-locus README line
### Tests added
**B-4 persistence (6 tests):**
`save_to_dir_create_writes_file_and_loads_back`,
`save_to_dir_same_id_edit_replaces_content`,
`save_to_dir_backup_is_cleaned_up_after_same_id_edit`,
`save_to_dir_rename_removes_old_file_and_creates_new`,
`save_to_dir_rename_nonexistent_old_id_is_non_fatal`,
`save_to_dir_roundtrip_with_env_preserves_values`
**B-3 env validation (6 tests):**
`validate_rejects_malformed_key_with_equals_sign`,
`validate_rejects_reserved_key_buzz_managed_agent`,
`validate_rejects_reserved_key_case_insensitive`,
`validate_rejects_nul_byte_in_value`,
`validate_rejects_value_over_per_value_size_limit`,
`validate_accepts_well_formed_env`
**B-2 API boundary (4 TS tests in tauri.test.mjs):**
`fromRawAcpRuntimeCatalogEntry maps definition_env to definitionEnv`,
`defaults definitionEnv to {} when absent`, `preserves source preset`,
`env round-trips through edit payload shape`
## Preset catalog
| ID | Label | Command |
|----|-------|---------|
| `cursor` | Cursor | `cursor-agent acp` |
| `omp` | Oh My Pi | `omp acp` |
| `grok` | Grok Build | `grok agent --always-approve stdio` |
| `opencode` | OpenCode | `opencode acp` |
| `kimi` | Kimi Code | `kimi acp` |
| `amp` | Amp | `amp-acp` |
| `hermes` | Hermes Agent | `hermes-acp` |
| `openclaw` | OpenClaw | `openclaw acp` |
## Review-fix pass (2026-07-26, Eva)
Fixes from the three-way review (Wren / Dawn / Eva) in the
buzz-generic-acp-harnesses thread, pushed as new commits (no rewrite):
1. **installHint edit round-trip** — form seeding extracted to
`formValuesFromCatalogEntry` (single source of truth), input rendered,
full-definition lossless round-trip regression.
2. **Dangling-delete coherence** — delete allowed; confirm counts
referencing agents (direct pin + persona-inherited); summary rows render
`harness (deleted): <id>`; spawn errors become actionable sentences
(`user_facing_harness_error`); composed delete→summary→start test.
3. **Comma-in-args** — rejected at `validate_harness_definition` (shared
by save AND disk load), mirrored inline in the form.
4. **Registry publish race** — collision/dup filtering moved into
`load_custom_harnesses` (both loaders inherit shadowing rules);
discovery publishes by re-reading the dir under `persist_mutex` (lock
scoped to publish only); deterministic interleaving regressions for
save-during-discovery and delete-during-discovery.
5. **Mechanical** — discarded `belongs_to_us` sweep arg deleted,
`load_global_agent_config` hoisted out of the per-record summary loop,
duplicated doc paragraph + stray SAFETY comment removed.
6. **PGID test de-flaked** — leader kept alive through the assertion.
Known follow-up (filed in review, not blocking): file-size split-outs
queued in `check-file-sizes.mjs` entries.
## Gate table — head `bf53f1d60`
| Gate | Result |
|------|--------|
| `cargo test --lib` (desktop/src-tauri) | **1701 passed**, 0 failed, 14
ignored |
| desktop JS suite (`pnpm test`) | **3605 passed**, 0 failed |
| `tsc --noEmit` | clean |
| `biome check` + file-size/px/pubkey checks | clean |
| `cargo clippy --lib -- -D warnings` | clean |
| `cargo fmt --check` | clean |
PR head: `bf53f1d60e3cbd07392e1287b83bb37ba90d0d33` — includes merge of
origin/main (`c2a4ee711`, conflicts in agent_models composed with
#2890's live Databricks discovery)
---------
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
Co-authored-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com>
Co-authored-by: Dawn (sprout agent) <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Co-authored-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz>
|
||
|
|
e6c90bb7c4 |
Polish community rail and mobile pairing (#2972)
## Summary - align the multi-community rail with the content surface and balance its visible 10px side gutters - center Mobile pairing, start sessions on demand, and keep retry states inside the QR area - reveal the QR code and copy action with 250ms motion and use the standard loading spinner The rail was centered within its own box, but the adjacent sidebar added another 11px to the visible right gap. Mobile pairing also started before user intent, which could leave an idle session waiting for EOSE. ## Validation - `pnpm -C desktop build:e2e` - `pnpm -C desktop test` — 3,516 passed - `pnpm -C desktop exec playwright test tests/e2e/community-rail.spec.ts --project=smoke` — 19 passed - `pnpm -C desktop exec playwright test tests/e2e/mobile-pairing-qr.spec.ts --project=smoke` — 1 passed `pnpm -C desktop check` is currently blocked by the existing `src-tauri/src/managed_agents/runtime.rs` file-size baseline (2,220 lines; limit 2,216). |
||
|
|
50655ac097 |
Style mobile pairing QR codes (#2775)
## Summary - render mobile pairing QR codes locally with Wallet-inspired styling - hide the raw pairing URI behind a matching copy button - add focused rendering and dialog coverage ## Test plan - desktop lint and 3,489 desktop tests - focused pairing dialog Playwright test - decoded the rendered QR back to the exact pairing URI |
||
|
|
c86c4f59c4 | fix(desktop): refine focused thread dismissal targets (#2644) | ||
|
|
8a65d81fab |
fix(desktop): modal sign-in + branded communities onboarding page (#2147)
Signed-off-by: Bradley Axen <baxen@squareup.com> Signed-off-by: npub19x6jnl6rhepymwyl2xlltz3ce7rfg2ktllle3g2vu59n3s490k8s9n40l3 <29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: npub19x6jnl6rhepymwyl2xlltz3ce7rfg2ktllle3g2vu59n3s490k8s9n40l3 <29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@sprout-oss.stage.blox.sqprod.co> |
||
|
|
e84f3fe8ed |
feat(desktop): add fuzzy onboarding cards (#2141)
Signed-off-by: npub19x6jnl6rhepymwyl2xlltz3ce7rfg2ktllle3g2vu59n3s490k8s9n40l3 <29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@sprout-oss.stage.blox.sqprod.co> Co-authored-by: npub19x6jnl6rhepymwyl2xlltz3ce7rfg2ktllle3g2vu59n3s490k8s9n40l3 <29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@sprout-oss.stage.blox.sqprod.co> |
||
|
|
2b0f5e9f80 | Improve agent runtime settings (#2026) | ||
|
|
1bdd938491 |
Add identity key help and reveal toggle to machine onboarding (#2064)
Signed-off-by: npub1d6t84ajeg9skp2609l2k6axgcme8x7g7u7luj352r03hcwreg7lqnxcsex <6e967af659416160ab4f2fd56d74c8c6f273791ee7bfc9468a1be37c387947be@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: npub1d6t84ajeg9skp2609l2k6axgcme8x7g7u7luj352r03hcwreg7lqnxcsex <6e967af659416160ab4f2fd56d74c8c6f273791ee7bfc9468a1be37c387947be@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co> |
||
|
|
7873135a0b | Polish private key onboarding texture (#2051) | ||
|
|
64b8fea6dc |
Bug-bash round 2: table scroll, Goose instructions, workflow mention wake (#2034)
Signed-off-by: Tyler Longwell <tlongwell@block.xyz> Co-authored-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Tyler Longwell <tlongwell@block.xyz> Co-authored-by: npub12gtutshhh76rx0jx697f32f9tffd4hhp3hx58fp4x6u4uemkm7sqf8f757 <5217c5c2f7bfb4333e46d17c98a9255a52dadee18dcd43a43536b95e6776dfa0@sprout-oss.stage.blox.sqprod.co> |
||
|
|
084e442d2d |
Bug-bash: mention/code-span, feed titles, autocomplete, edit-mentions, draft routing, and right-click media Download (#2027)
Signed-off-by: npub1jh9wn95s0472h86ahapupaf7m6kx4v9sx2n0atj2hltcfer8k06s5n3pyf <95cae996907d7cab9f5dbf43c0f53edeac6ab0b032a6feae4abfd784e467b3f5@sprout-oss.stage.blox.sqprod.co> Signed-off-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co> Signed-off-by: npub17jjz49l9jjmhhk7cac63j8yt9z555n9cw8vk7v5jz4vzw4ppld5qgj57cc <f4a42a97e594b77bdbd8ee35191c8b28a94a4cb871d96f32921558275421fb68@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Tyler Longwell <tlongwell@block.xyz> Signed-off-by: Tyler <109685178+tlongwell-block@users.noreply.github.com> Signed-off-by: tlongwell-block <109685178+tlongwell-block@users.noreply.github.com> Signed-off-by: npub1t2tgm7d8f995uqvmnm8h88sg3wnpp9a5xysjf6dg3tjmgt3ltulqdp8ehr <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@sprout-oss.stage.blox.sqprod.co> Co-authored-by: npub1jh9wn95s0472h86ahapupaf7m6kx4v9sx2n0atj2hltcfer8k06s5n3pyf <95cae996907d7cab9f5dbf43c0f53edeac6ab0b032a6feae4abfd784e467b3f5@sprout-oss.stage.blox.sqprod.co> Co-authored-by: npub1mprnacetjua2xx3p5eddmhxyk6wv929ymm5py8kd2xfxurxahspqqlgyta <d8473ee32b973aa31a21a65adddcc4b69cc2a8a4dee8121ecd51926e0cddbc02@sprout-oss.stage.blox.sqprod.co> Co-authored-by: npub17jjz49l9jjmhhk7cac63j8yt9z555n9cw8vk7v5jz4vzw4ppld5qgj57cc <f4a42a97e594b77bdbd8ee35191c8b28a94a4cb871d96f32921558275421fb68@sprout-oss.stage.blox.sqprod.co> Co-authored-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@sprout-oss.stage.blox.sqprod.co> Co-authored-by: Tyler Longwell <tlongwell@block.xyz> Co-authored-by: Dawn (sprout agent) <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@sprout-oss.stage.blox.sqprod.co> Co-authored-by: npub1t2tgm7d8f995uqvmnm8h88sg3wnpp9a5xysjf6dg3tjmgt3ltulqdp8ehr <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@sprout-oss.stage.blox.sqprod.co> |
||
|
|
2121fd0452 | Polish Buzz theme and sidebar (#1971) | ||
|
|
6c2d667575 |
Apply optional relay join policy across join flows (#1894)
Signed-off-by: npub12gtutshhh76rx0jx697f32f9tffd4hhp3hx58fp4x6u4uemkm7sqf8f757 <5217c5c2f7bfb4333e46d17c98a9255a52dadee18dcd43a43536b95e6776dfa0@sprout-oss.stage.blox.sqprod.co> Signed-off-by: Tyler Longwell <tlongwell@squareup.com> Co-authored-by: npub12gtutshhh76rx0jx697f32f9tffd4hhp3hx58fp4x6u4uemkm7sqf8f757 <5217c5c2f7bfb4333e46d17c98a9255a52dadee18dcd43a43536b95e6776dfa0@sprout-oss.stage.blox.sqprod.co> Co-authored-by: klopez4212 <klopez4212@gmail.com> Co-authored-by: npub1qyvc0c5kl4gqv2fd97fsk46tu378sqgy35vc83rvgfwne90sel7s0ed67d <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@sprout-oss.stage.blox.sqprod.co> |
||
|
|
f20d79658c | Welcome channel: Browse channels card, browser sorting, shortcut hint placement (#1948) |