feat(flows-yaml/ui): Monaco editor + autocomplete + validation + dry-run + replay (closes #1077) #1082
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!1082
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "flows-yaml/ui"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #1077. Builds on #1076 (defaults + REST CRUD + JSON Schema pipeline merged).
In-browser YAML editor for the Flows YAML system. Lives at
/flows-yamlalongside the legacy canvas at/flows; cutover (#1078) renames once the legacy node engine is removed.What landed
Routes
/flows-yaml) — searchable table with row actions (edit / dry-run / disable / delete or reset-to-default)/flows-yaml/new) — name validation + starter template picker (blank, pr-opened, issue-labeled, issue-assigned, breakdown-comment)/flows-yaml/:name) — split-pane Monaco editor + side panel; replay overlay via?run=<id>with gutter decorations + step-output tooltipsEditor
MonacoEditor.tsx— lazy-loadedmonaco-editor+monaco-yaml; loads/schemas/flows.schema.jsononce on mount; Tokyo Night theme via token CSS vars; debounced 50ms diagnosticsdiagnostics.ts— JSON Schema diagnostics (viamonaco-yaml) + custom semantic checks: duplicatestep.id, unknownuses:, unknown${{ steps.X.outputs.Y }}refs, expression parse for everyif:/ interpolation,concurrency.grouptemplateexpr-parser.ts— tiny mini-AST mirroring the server'sexpr/parsersurfaceschema-meta.ts— readsx-ops,x-trigger-kinds,x-outputsfrom the JSON Schema for autocomplete + Help renderingSide panel tabs
descriptionfields (top-level keys, triggers, ops, built-ins) with searchable filterPOST /api/flows-yaml/:name/dry-run→ per-step trace/api/flows-yaml/runs?flow=<name>; status pills, durations, replay linkAPI client
apps/web/src/lib/flows-yaml-api.ts— typed wrappers for every server endpoint (list / get / create / update / delete / disable / dry-run / reload / runs / run). Mtime-conflict 409 surfaced for the editor's merge dialog.SSE
Subscribes to
flow.changed. Silent refetch on the list view; banner on the open editor when local edits are unsaved.Bundle audit (vite build)
flows-yaml.indexflows-yaml.newflows-yaml.$nameMonacoEditorVerified via grep that monaco bundles only land in the editor chunk. 500 KB threshold cleared by an order of magnitude — Monaco kept; CodeMirror fallback not warranted.
Test plan
bun test apps/web/src/features/flows-yaml/editor/diagnostics.test.ts— 7 / 0 (pure logic)bun x tsc --noEmit(all packages) — cleanvite build— succeedscd apps/server && bun test) — 3692 / 0 (no server changes)New deps
monaco-yaml@^5.5.0(apps/web).monaco-editor+@monaco-editor/reactalready present.Out of scope (ships in #1078)
/flowscanvas removal (rename/flows-yaml→/flows, dropapps/web/src/features/flows/+apps/web/src/routes/flows.*.tsx)Validatebutton currently re-uses the save path (server is authoritative); a dedicatedPOST /api/flows-yaml/:name/validateendpoint would let operators check semantics without persisting🤖 Generated with Claude Code
CI green. Two AC violations:
behavior
apps/web/src/routes/flows-yaml.$name.tsx— Save button not disabled when client-side errors are present. Issue AC: "Save disabled while client-side schema errors present." Fix: add|| diagnostics.some(d => d.severity === "error")to thedisabledprop on both the Validate and Save buttons.behavior
apps/web/src/routes/flows-yaml.$name.tsx—onJumpcallback just callseditorControlsRef.current?.focus()and discardsline/column. Clicking a diagnostic in the Validation panel does not navigate the editor cursor. Issue AC: "click → jump-to-line." Fix: expose arevealLine(line, column)method viaEditorControlsand call it inonJump.Acknowledged-but-deferred (don't block merge once above fixed): web-worker isolation for diagnostics analyser; dedicated
POST /validateendpoint; diff-merge dialog on 409 (currently a toast+banner).