feat(workflows): add workflow editor - #6248
Conversation
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>
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>
7183d58 to
76a8c2a
Compare
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>
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>
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>
Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
jedwards27
left a comment
There was a problem hiding this comment.
:bot: Jude’s code review agent
Requesting changes at exact head b59375b5d71da234b26727baa9223456cf6351e3.
[P1] The editor teaches a trigger condition that cannot execute
desktop/src/features/workflows/ui/WorkflowFormBuilder.tsx:58-72 suggests contains(text, "deploy"), but the executor registers str_contains(...) and exposes message content as trigger_text (crates/buzz-workflow/src/executor.rs:203-223,232-242,289-300). The working syntax is already used in WorkflowStepCard.tsx:378 and desktop/tests/e2e/workflows.spec.ts:260: str_contains(trigger_text, "deploy").
The editor serializes this field unchanged, and evaluation errors are only logged before the workflow is skipped (crates/buzz-workflow/src/lib.rs:904-927). A user following the product's own example can therefore save a workflow that silently never fires. Please correct the example and add a regression assertion for the visible trigger-condition guidance.
[P1] The PR's changed Desktop smoke test is deterministically failing
desktop/tests/e2e/navigation.spec.ts:139-142 scopes the trigger assertion under getByRole("dialog", { name: workflowName }), but the dialog's accessible name is Edit workflow; the workflow name is separate content. The trigger node is rendered, yet the locator cannot reach it. CI run 32201513980, job 95916252006, failed the test on the initial attempt and both retries, leaving the aggregate Desktop gate red. Independent exact-head reproduction after pnpm build:e2e failed at the same line with the same accessibility snapshot.
Please scope the locator by the stable dialog title and assert the workflow name separately, following desktop/tests/e2e/workflows.spec.ts:812-815, then rerun the required smoke gate.
Validation at this exact head and clean worktree:
cargo test -p buzz-workflow— 156 passed, 2 ignoredjust desktop-test— 5045 passedjust desktop-typecheck— passed- targeted changed smoke test — failed reproducibly as described above
The reaction-trigger schema/runtime expansion was traced through crates/buzz-workflow/src/schema.rs:45-52 and crates/buzz-workflow/src/lib.rs:878-1001; no additional material relay, identity, persistence, or release-boundary issue was found in the 27-file base-to-head diff.
Co-authored-by: Codex <noreply@openai.com> Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
dd89361 to
967283c
Compare
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>
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>
Channel Settings routed to /workflows before showing workflow detail or creation, which swapped the channel out from behind the modal. Extract the editor dialog wiring into a shared host and mount it once more in an app-shell overlay provider so the ingress can portal the same editor above the active channel: the settings sheet closes, the route stays on the channel, and closing returns to it. Workflow routes keep their URL-addressable host, so canonical deep links, pane state, dirty-exit guards, unavailable/loading handling, and webhook handoff are unchanged. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Deleting from the Workflows route editor cleared only the confirmation and the list caches, leaving the editor mounted on a workflow that no longer exists. Close the editor when the deleted workflow is the one it is pointed at, matching the channel overlay, and cover it in the workflow E2E suite. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
…oundation * origin/main: fix(desktop): hide archived channels from #/Tab autocomplete (#6156) Unify mobile channel details (#6113) Revert "fix(acp): gate relay-signed workflow messages on their attributed author" (#6311) fix(desktop): morph the drawer panel icon instead of sliding it (#6306) feat(desktop): refine repository-aware project workspaces (#6003) Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com> # Conflicts: # desktop/src/app/AppShell.tsx
The dialog header derived the workflow name by running the working YAML
through yamlToFormState — full definition validation. A step added from
the builder starts as `{id, action: send_message}` with no text, which
send_message requires, so the whole definition stops validating the
moment the first step is created. The name then fell through to the
saved workflow's name: blank in create mode ("Untitled workflow"), and
the un-suffixed original in duplicate mode (dropping "(copy)"). The same
gate drove the name editor's disabled state, so the title could not be
typed back either.
Read the header's fields — name, enabled, and whether they can be
written — from the YAML document instead, so a definition that is merely
incomplete still presents its name. yamlWithWorkflowName and
yamlWithWorkflowEnabled move alongside them, since the header now reads
and writes through the same document layer in a single parse per render.
Making the header writable in that state exposed a second half of the
same split: the form builder only re-synced from YAML when the whole
definition validated, so a header rename or disable applied while a step
was incomplete was dropped, and the next form edit re-serialized the
values the builder still held. It now adopts the header's fields from
the document when full validation fails.
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>
…oundation * origin/main: Add appearance preference previews (#6193) fix(desktop): restore emoji recents (#6263) chore: serialize mobile pre-push checks (#6322) fix(buzz-acp): loosen workspace-scan guardrail to allow named paths (#6261) fix(buzz-dev-mcp): expand leading ~ in read_file/str_replace paths (#6271) perf(desktop): move five hot renderer paths from JS into Rust (#6024) fix(media): accept portrait video resolutions (#6058) Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
|
Addressed the requested review changes:
Validation:
Updated by Carl, an AI agent 🤖 |
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>
|
Implemented the two adversarial-review blockers:
Validation at
AI-generated implementation and summary by Carl. |
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.
File changes
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 a Canvas-style Workflows ingress below Canvas, including channel-scoped loading, error, empty, and list states plus open/create actions.
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 Workflows placement beneath Canvas, channel workflow listing and opening, and channel-preselected workflow creation.
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.
Reproduction steps
Open Workflows and confirm the responsive card library, create tile, card action menu, and card-to-detail/run-history modal navigation.
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.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.
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.
Enter unsupported YAML and confirm Form mode gives an actionable fallback without rewriting the definition; verify reaction triggers preserve and execute their filter.
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, and New workflow preselects that channel.
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
str_contains(trigger_text, "deploy")syntax and added a visible Playwright regression assertion.Edit workflowdialog name, asserted the workflow title separately, and retained the trigger-node assertion.Verification
Verified at exact pushed head
3760c3d657a525f5af98e8d0f98bdd03999d8e61:origin/main: destination-org policy, branch-skew, differential file-size, Desktop checks, TypeScript typecheck, Desktop tests, and Tauri checkschannel settings opens and creates channel workflows over the channel;rejected deletion keeps the confirmation, editor, and draft)direct workflow detail links close back to workflows;shows executable guidance for diff trigger conditions)workflows.spec.tsandchannels.spec.tsat prior product headc5c3abc91a71fe511d43e6cc9168b1626d0c217cc5c3abc91a71fe511d43e6cc9168b1626d0c217cRelated issue
None found. Closest prior work: #231.