# Workflow Editor — Integration Guide > **Canonical source**: `vl-workflow-engine/ui/workflow-editor.html` > **Version**: 2.1 (Spec 3.16) > **Replaces**: project-local copies in VL-Code, VLCode-Lite --- ## What Changed ### v2.1 — Checkpoint, Pause, Re-run, Node Editor | Feature | Description | |---------|-------------| | **Checkpoint persistence** | DAG state (node statuses) is saved to `localStorage` after each step. On page refresh, the DAG re-renders with previous execution state intact. Checkpoints expire after 24h. | | **Pause execution** | New amber "Pause" button in toolbar. Sends `POST /api/workflow/:runID/pause` (fallback to `/cancel`). Workflow stops cleanly, checkpoint is saved, user can resume from any node. | | **Re-run from node** | Right-click any node → "Re-run from here". Calls `POST /api/workflow/rerun` with the last checkpoint + target stepID. Downstream nodes are cleared; upstream statuses preserved. | | **Edit inputs & re-run** | Right-click → "Edit inputs & re-run" opens a modal editor. Type-specific fields (LLM: model/tokens/messages, Service: input params, Set/Write: target/value, Loop: source/while, Download: source/target). Plus a generic "Variable Overrides" JSON field for `$vars`. | | **Context menu** | Right-click on any node shows: Re-run from here, Edit inputs & re-run, View details, Copy node ID. | | **New PostMessage APIs** | `setCheckpoint`, `rerunFromStep`, `editNode` — parent can programmatically trigger checkpoint storage, re-runs, and the edit modal. | | **New outgoing message** | `nodeEdited` — sent to parent when user edits a node's inputs, with the modified `nodeData` and `overrides`. | ### v2.0 — Spec 3.16 Bug Fixes | # | Issue | Impact | |---|-------|--------| | 1 | **`BREAK` phantom connections** | `next: "BREAK"` no longer creates a connection to a non-existent node. Both `RETURN` and `BREAK` are now excluded from connection generation. This was the likely cause of DAG rendering failures. | | 2 | **Loop `while` mode not rendered** | `renderLoopBody()` now detects `while` vs `source` mode and renders the correct fields (`while` expression, `maxIterations`). | | 3 | **Missing Download/Unzip node types** | `Download_*` and `Unzip_*` are now recognized with dedicated icons (DL/UZ), colors, accent bars, and body renderers. | | 4 | **`computeIO` ignored `while` expression** | Variable references in `while` expressions now appear in I/O audit badges. | ### Visual Parity All existing visuals are preserved: - Same CSS variables, dark theme, font stack - Same 11 original node type colors + accent bars + 2 new (Download, Unzip) - Same connection styles (serial/parallel/branch-case) - Same minimap, legend, toast, toolbar layout - Same drag, selection, scroll, resize behavior - Same PNG/JSON export/import - Same SSE-based execution with live status updates --- ## How to Integrate ### Option A: Direct Copy (simplest) ```bash # VL-Code cp vl-workflow-engine/ui/workflow-editor.html vl-code/src/web/public/workflow-editor.html # VLCode-Lite cp vl-workflow-engine/ui/workflow-editor.html VLCode-Lite/public/workflow-editor.html ``` No other changes needed — the PostMessage API is fully backward compatible. ### Option B: Symlink (keeps in sync) ```bash # VL-Code ln -sf ../../../../VL-Workflow-Engine/ui/workflow-editor.html vl-code/src/web/public/workflow-editor.html # VLCode-Lite ln -sf ../VL-Workflow-Engine/ui/workflow-editor.html VLCode-Lite/public/workflow-editor.html ``` ### Option C: npm dependency (for VLClaw and future consumers) ```javascript const path = require('path'); const editorPath = path.join(require.resolve('vl-workflow-engine'), '..', 'ui', 'workflow-editor.html'); // Serve this file via your static file handler or express.static ``` --- ## API Endpoints Required The editor calls these endpoints directly (same-origin). Consumers must ensure these routes exist: | Method | Path | Purpose | Required? | |--------|------|---------|-----------| | `POST` | `/api/workflow/execute` | Start a workflow (SSE response) | Yes (existing) | | `POST` | `/api/workflow/rerun` | Re-run from step with checkpoint + overrides (SSE response) | **New** (for re-run feature) | | `POST` | `/api/workflow/:runID/pause` | Pause a running workflow | **New** (for pause feature) | | `POST` | `/api/workflow/:runID/abort` | Abort a running workflow | Recommended | | `GET` | `/api/workflow/:runID/checkpoint` | Fetch latest checkpoint | Recommended (fallback: localStorage) | **If `/api/workflow/rerun` is not implemented**, the editor falls back to `/api/workflow/execute` with `{ fromStep, checkpoint, overrides }` params. See the engine's `executeFrom()` API for implementation details in [API.md](../API.md). --- ## PostMessage API (Extended) ### Parent → iframe | Message | Payload | Since | Description | |---------|---------|-------|-------------| | `loadWorkflow` | `{ type: 'loadWorkflow', data: workflowJSON }` | v1.0 | Parse and render a workflow | | `updateNodeStatus` | `{ type: 'updateNodeStatus', nodeId, status }` | v1.0 | Update node status | | `highlightNode` | `{ type: 'highlightNode', nodeId }` | v1.0 | Select and scroll to a node | | `clearStatus` | `{ type: 'clearStatus' }` | v1.0 | Clear all node statuses | | **`setCheckpoint`** | `{ type: 'setCheckpoint', checkpoint, runID }` | **v2.1** | Store a checkpoint (persists to localStorage) | | **`rerunFromStep`** | `{ type: 'rerunFromStep', nodeId, overrides? }` | **v2.1** | Programmatically trigger re-run from a step | | **`editNode`** | `{ type: 'editNode', nodeId }` | **v2.1** | Open the edit modal for a node | ### iframe → Parent | Message | Payload | Since | Description | |---------|---------|-------|-------------| | `ready` | `{ type: 'ready' }` | v1.0 | iframe is ready | | `nodeClick` | `{ type: 'nodeClick', nodeId, nodeType, nodeData }` | v1.0 | User clicked a node | | `workflowImported` | `{ type: 'workflowImported', workflow }` | v1.0 | User imported JSON | | **`nodeEdited`** | `{ type: 'nodeEdited', nodeId, nodeData, overrides }` | **v2.1** | User edited node inputs and triggered re-run | --- ## Supported Node Types (13 total) | Type | Icon | Color | Since | |------|------|-------|-------| | LLM | AI | Indigo-purple | v1.0 | | Service | SV | Green | v1.0 | | API | AP | Cyan | v1.0 | | Component | CP | Teal | v1.0 | | Set | = | Blue | v1.0 | | Write | WR | Orange | v1.0 | | Branch | BR | Purple | v1.0 | | Loop | LP | Pink | v1.0 | | Stop | ST | Red | v1.0 | | Pause | ⏸ | Violet | v1.0 | | Fork | FK | Emerald | v1.0 | | **Download** | **DL** | **Sky blue** | **v2.0** | | **Unzip** | **UZ** | **Yellow** | **v2.0** | --- ## User Workflows ### Breakpoint Resume (page refresh) 1. User runs workflow → nodes light up green/orange/red 2. Page refreshes / closes 3. User reopens → DAG renders with last-known node statuses (from localStorage) 4. User right-clicks a failed/incomplete node → "Re-run from here" 5. Engine resumes from that step using saved checkpoint ### Edit & Re-run (fix bad input) 1. Workflow finishes but LLM output was wrong 2. User right-clicks the LLM node → "Edit inputs & re-run" 3. Modal shows: model, max_tokens, messages (editable JSON) 4. User fixes the prompt, adds variable overrides if needed 5. Clicks "Re-run from here" → engine resumes from that node with new inputs 6. Downstream nodes re-execute; upstream results are preserved ### Pause & Inspect 1. User clicks "Pause" during execution 2. Workflow pauses cleanly; checkpoint saved 3. User inspects node statuses, variables 4. User can resume from any node or edit inputs first --- ## Testing After integration, verify: 1. **Spec 3.16**: Loop `while` mode, `BREAK` badge, Download/Unzip nodes 2. **Context menu**: Right-click a node → menu appears with 4 options 3. **Re-run**: Right-click → "Re-run from here" → workflow resumes from that step 4. **Edit modal**: Right-click → "Edit inputs" → modal shows type-specific fields 5. **Checkpoint persistence**: Run workflow, refresh page → node statuses restored 6. **Pause**: Click pause during execution → workflow stops, checkpoint saved