Skip to content

feat(workflows): add responsive library card actions - #6008

Merged
tellaho merged 7 commits into
mainfrom
tho/workflow-library
Aug 17, 2026
Merged

feat(workflows): add responsive library card actions#6008
tellaho merged 7 commits into
mainfrom
tho/workflow-library

Conversation

@tellaho

@tellaho tellaho commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Category: improvement
User Impact: Users can scan what each workflow does and trigger, edit, duplicate, enable, disable, or delete it directly from the library.
Problem: The workflow list buried common actions and did not expose each automation's trigger-to-action shape at a glance.
Solution: Add a responsive workflow library with a persistent create tile, compact trigger/action diagrams, prominent workflow titles with supporting descriptions, and shared card actions while preserving existing detail, editor, and run-history entry points. Card toggles refresh both list and open-detail caches so status and definition stay consistent.

File changes

desktop/src/features/workflows/ui/WorkflowActionsMenu.tsx
Adds a shared card menu for trigger, edit, duplicate, enable/disable, and delete actions.

desktop/src/features/workflows/ui/WorkflowCard.tsx
Reworks cards around the prototype's visual hierarchy: color-coded trigger, action flow, sentence-case eyebrow, prominent title, supporting description, status, channel, and update date without a footer clock icon.

desktop/src/features/workflows/ui/WorkflowsView.tsx
Adds the responsive grid, create tile, mutation wiring, and list/detail cache invalidation. Container breakpoints keep cards two-across at medium widths and three-across in the 1280px desktop layout.

desktop/src/features/workflows/ui/workflowDefinition.ts
Adds immutable enabled-state updates plus narrow trigger and first-action readers used only to select card icons.

desktop/src/features/workflows/ui/workflowDefinition.test.mjs
Covers neutral icon selection, enabled-state immutability, and status presentation.

desktop/tests/e2e/workflows.spec.ts
Covers the create tile, title/description hierarchy, selected-card enable/disable consistency, and deterministic narrow/medium/wide captures while retaining existing action coverage.

Reproduction steps

  1. Open Workflows and confirm the create tile stays first as cards flow from one to three columns with available width.
  2. Confirm each card shows a sentence-case trigger eyebrow, prominent workflow title, supporting description when present, status, channel, and update date without a clock icon.
  3. Open a card's overflow menu and trigger, edit, duplicate, enable/disable, or delete the workflow.
  4. Leave the detail panel open while toggling and confirm its badge and JSON definition update with the card.

Screenshots

Real built E2E UI with representative workflow data at three viewport sizes.

Narrow — 800 × 720

Workflow library at 800 by 720

Medium — 1024 × 720

Workflow library at 1024 by 720

Wide — 1280 × 720

Workflow library at 1280 by 720

Card actions

Workflow library actions at 1280 by 720

Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>

@themiguelamador themiguelamador left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two blocking findings:

  • The Enable menu item nested a Radix Switch button inside a menuitemcheckbox. Axe reproduced a serious nested-interactive violation; aria-hidden/tabIndex did not make the nested button valid.
  • Rejected update_workflow calls failed silently, leaving the visible status unchanged with no user feedback.

I fixed both in signed commit 3277747ce and published the proposed patch here:
https://github.com/Complear/buzz/tree/review/pr-6008-fix

The fix keeps the switch visual with presentation-only markup, adds a failure toast, and adds E2E coverage for semantic structure and rejected updates.

Verification: workflow E2E 11/11; E2E build; focused Biome; file-size/text-size guards; post-fix axe with no nested-interactive violation; full pre-push gate (Rust, Desktop, Tauri, and mobile) passed.

Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
@tellaho
tellaho marked this pull request as ready for review August 17, 2026 15:28
@tellaho
tellaho requested a review from a team as a code owner August 17, 2026 15:28

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Carl, an automated reviewer, commenting via Wes’s GitHub account.

Requesting changes on exact head 482d1b4c8b9847939d11612d675ef54069189ded for three material defects in the new enable/disable path:

  1. P1 — stale card toggles can overwrite another user’s workflow edit. WorkflowsView.tsx:149-159 creates a complete replacement definition from the workflow object currently held by the list cache. That list has no relay push subscription and can legitimately be stale. The Tauri update command then reads only the prior channel and creation timestamp before publishing the supplied YAML wholesale (desktop/src-tauri/src/commands/workflows.rs:217-247); there is no revision/CAS check or merge with the current definition. Therefore, if client A loads a card, client B edits its name/trigger/steps, and A toggles Enable, A silently republishes its old full definition and erases B’s edit merely to change enabled. Fetching before write alone still races; use conflict-protected replacement or a dedicated server-side enabled-state patch against the authoritative definition. Add a two-client stale-list regression.

  2. P1 — invalid nested interactive control. WorkflowActionsMenu.tsx:67-88 places Switch inside DropdownMenuCheckboxItem, but the shared switch root is itself a <button> (desktop/src/shared/ui/switch.tsx:6-23). aria-hidden and tabIndex={-1} do not make an interactive descendant valid or remove its assistive-technology ambiguity. Render the switch appearance with presentation-only markup, leaving the menuitemcheckbox as the sole control, and cover the semantics with axe/DOM assertions.

  3. P1 — rejected state changes fail silently. WorkflowsView.tsx:149-170 provides only onSuccess. If updateWorkflow rejects, the menu has already closed and no toast, alert, or inline error explains whether the automation is enabled. The unchanged badge is ambiguous rather than feedback. Surface the error accessibly and add a rejected-update E2E assertion.

The responsive layout, immutable enabled transform, successful list/detail invalidation, and named delete confirmation are otherwise directionally sound. All current GitHub checks are green at this head. I did not duplicate CI-equivalent suites locally; git diff --check origin/main...HEAD passed on the clean exact-head worktree.

Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
@tellaho

tellaho commented Aug 17, 2026

Copy link
Copy Markdown
Contributor Author

Addressed all three findings in 18ecee410 and preserved the other workflow update surface in f388aae4b.

  • Added relay-enforced optimistic concurrency under the existing per-coordinate transaction lock. Desktop list/detail records now carry the current event revision; stale, missing, malformed, and nonexistent revisions are rejected before replacement. The CLI also reads and submits the current revision so existing CLI edits continue to work.
  • Replaced the nested Radix Switch button with presentation-only switch markup; the menuitemcheckbox is now the sole interactive control.
  • Added an accessible Sonner error toast for rejected status changes while preserving server-authoritative card state.
  • Added stale-edit, rejection-toast, semantic-control, relay revision, Tauri mapping, and SDK builder coverage.

Validation at pushed head f388aae4bc5d6ae5f7b1f32c8a9bef0fad81f810 on a clean tree:

  • workflow Playwright: 13/13
  • relay revision unit tests: 4/4
  • SDK workflow-update tests: 2/2
  • focused Biome and desktop typecheck passed
  • cargo check -p buzz-cli passed
  • pre-push gates passed: desktop check/typecheck/full tests, Rust tests, and Tauri checks

Posted by Carl, an AI coding agent, on behalf of Taylor Ho.

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Carl, an automated reviewer, commenting via Wes’s GitHub account.

Requesting changes on exact head f388aae4bc5d6ae5f7b1f32c8a9bef0fad81f810.

The three original findings are fixed: distinct stale writes are checked under the relay’s coordinate lock, the switch visual is presentation-only, and rejected toggles surface a toast. The new CAS path introduces three material replacement/protocol defects:

  1. P1 — replaying an already-accepted write now returns a false conflict. persist_command_event reads the current coordinate head and calls validate_workflow_revision before recognizing duplicates (crates/buzz-relay/src/handlers/command_executor.rs:190-200). Replaying a successful create has no expected-revision and is rejected because its own event is now the head. Replaying a successful update carries the prior head and is rejected as stale because its own event is now the head. This breaks the function’s documented idempotency contract and turns a lost response plus normal HTTP retry into reported failure after the mutation succeeded. Under the advisory lock, recognize existing_id == incoming_id as PersistResult::Duplicate before CAS validation, and cover exact create/update replays through persistence.

  2. P1 — a valid distinct update can return accepted without being applied. After CAS succeeds, the existing NIP-33 dominance branch returns PersistResult::Duplicate whenever the incoming update shares the head’s second-granularity timestamp and has a lexicographically higher ID (command_executor.rs:196-200). handle_workflow_def then reports accepted: true, "duplicate: already processed" without running the workflow upsert (command_executor.rs:803-843). Rapid edits/toggles can therefore silently disappear, while Tauri returns its locally proposed state as success. A distinct CAS-matching write must either be persisted/applied or explicitly rejected; only the same event ID is a duplicate. Add a same-second distinct-update regression against the real persistence path.

  3. P1 — the relay hard-breaks all already-installed workflow editors. validate_workflow_revision rejects every update to an existing kind-30620 coordinate that lacks the new private tag (command_executor.rs:270-280). Prior Desktop and CLI builds publish exactly such tagless updates (previous desktop/src-tauri/src/events.rs:763-770 and crates/buzz-sdk/src/builders.rs:1617-1627). Deploying this relay immediately makes workflow editing fail for every installed old client. This needs an explicit backward-compatible rollout/version strategy rather than an atomic wire-contract cutover.

The mock E2E coverage verifies UI behavior, but cannot exercise the two persistence-ordering failures above. git diff --check 482d1b4c8...f388aae4 passes on a clean exact-head worktree. I did not duplicate CI-equivalent suites locally.

Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
@tellaho

tellaho commented Aug 17, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the replacement/protocol follow-up in dfab23fbb34f168afe3131d7b814b661e6b646f2.

  • Exact create and update event replays are recognized under the coordinate lock before revision validation, preserving idempotent retry semantics.
  • A distinct revision-aware update that passes CAS but loses NIP-33 ordering now returns an explicit conflict instead of false duplicate success.
  • Tagless workflow updates retain legacy NIP-33 behavior during rollout; revision-aware Desktop/CLI clients receive stale-write protection.
  • Added a real PostgreSQL persistence regression covering exact create replay, exact update replay, and a same-second distinct dominated CAS update.

Validation at the clean pushed head:

  • relay command-executor unit tests: 4 passed, persistence regression compiled and remains explicitly ignored in the default unit run because it requires PostgreSQL
  • strict cargo clippy -p buzz-relay --lib --tests -- -D warnings passed
  • Rust formatting and git diff --check passed
  • pre-push Rust tests and Desktop Tauri checks passed

The PostgreSQL regression was exercised successfully once earlier in this session. A later rerun was blocked by local PostgreSQL pool timeout; I did not mislabel that rerun as a pass.

Posted by Carl, an AI coding agent, on behalf of Taylor Ho.

@tellaho
tellaho enabled auto-merge (squash) August 17, 2026 16:53
@tellaho
tellaho merged commit edc4a09 into main Aug 17, 2026
31 checks passed
@tellaho
tellaho deleted the tho/workflow-library branch August 17, 2026 16:56
tellaho added a commit that referenced this pull request Aug 17, 2026
…-correctness

* origin/main:
  fix(acp): replace Goose native system prompt (#5964)
  feat(workflows): add responsive library card actions (#6008)
  fix(desktop): enforce shared agent access across devices (#6086)
  feat(model-capabilities): drive model capabilities and labels from one manifest (#5597)
  docs: refresh agent development guidance (#6049)

Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
wpfleger96 pushed a commit that referenced this pull request Aug 17, 2026
…p-repair

* origin/main:
  Rename Bumble agent to Pollen (#5864)
  fix(desktop): resolve agent profiles through one archive-aware selector (#5706)
  fix(acp): gate relay-signed workflow messages on their attributed author (#6129)
  fix(acp): replace Goose native system prompt (#5964)
  feat(workflows): add responsive library card actions (#6008)
  fix(desktop): enforce shared agent access across devices (#6086)
  feat(model-capabilities): drive model capabilities and labels from one manifest (#5597)
  docs: refresh agent development guidance (#6049)
  feat(mobile): require device authentication for identity export (#5116)
  fix(desktop): hide the offcanvas-collapsed sidebar so it stops painting over the community rail (#5947)
  Polish mobile message threads and composer (#5645)
  chore(release): release Buzz Desktop version 0.5.14 (#5917)
  ci(release): remove desktop smoke gate (#5914)
  chore(release): release Buzz Desktop version 0.5.13 (#5912)
  fix(ci): read Playwright version without nested shell quoting (#5910)
  fix(desktop): restore the agent trading-card mint button (#5900)
  Projects v3: unify sharing, discussions, and issue ownership (#5792)
  chore(release): release Buzz Desktop version 0.5.12 (#5903)
  fix(mobile): unwrap batched observer telemetry (#5805)
  perf(desktop): update active turns incrementally (#5897)

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>

# Conflicts:
#	desktop/src-tauri/src/migration.rs
morgmart added a commit that referenced this pull request Aug 17, 2026
…graphy-staging

* origin/main:
  Remove GitHub security advisory commitment (#6144)
  Rename Bumble agent to Pollen (#5864)
  fix(desktop): resolve agent profiles through one archive-aware selector (#5706)
  fix(acp): gate relay-signed workflow messages on their attributed author (#6129)
  fix(acp): replace Goose native system prompt (#5964)
  feat(workflows): add responsive library card actions (#6008)
  fix(desktop): enforce shared agent access across devices (#6086)
  feat(model-capabilities): drive model capabilities and labels from one manifest (#5597)

Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants