> For the complete documentation index, see [llms.txt](https://developer.celigo.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.celigo.com/cli/vscode-extension.md).

# VS Code extension

The **Celigo** extension for VS Code and Cursor opens a flow, tool, or API from the tree `celigo pull` writes as the Flow Builder canvas — the **Flow Canvas**. It draws a `flow.json`, `tool.json`, or `api.json` with its step components, mappings, and scripts. It marks the steps with the tree's lint findings and status badges and, on request, the account's open errors — which you can open, retry, and resolve from the canvas. Edits go back to the account through `celigo push`. Other VS Code-based editors that install from Open VSX work the same way. This page describes extension 1.1.2. Version 1.1.1 was never published; its changes ship in 1.1.2.

The graph comes from the CLI's own engine, `celigo flows graph`, a port of Flow Builder's graph algorithm. The canvas shows what the product would show for the same document. See [The local tree](/cli/local-tree.md) for the tree the canvas opens and [flows graph](/cli/commands/flows.md#celigo-flows-graph) for the engine.

## Requirements

* **VS Code 1.104 or later, or Cursor.** Other editors built on VS Code install the extension from Open VSX.
* **The Celigo CLI 2026.9.1 or later** on your `PATH`, or at the path in `celigo.cliPath`. Lint findings, the live overlay, and push need it; rendering and editing work without it. When no `celigo` answers, the extension offers once per session to run the CLI through `npx`, pinned to the version it needs.
* **Node.js 22 or later** for the CLI. See [Install](/cli/getting-started/install.md).

## Install

Install from a terminal:

```bash
# VS Code
code --install-extension Celigo.celigo

# Cursor
cursor --install-extension Celigo.celigo
```

Or install from the Extensions view: search for **Celigo** by the publisher **Celigo** and click **Install**. VS Code installs from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=Celigo.celigo); Cursor and other editors install from [Open VSX](https://open-vsx.org/extension/Celigo/celigo). `ext install Celigo.celigo` in Quick Open does the same.

Or install a downloaded VSIX:

```bash
code --install-extension celigo.vsix      # VS Code
cursor --install-extension celigo.vsix    # Cursor
```

## Open the canvas

1. Pull a tree with the CLI.

   ```bash
   celigo pull                        # the whole account
   celigo pull --integration <id>     # one integration
   ```
2. Open a `flow.json`, `api.json`, or `tool.json` from the tree.
3. Press **Cmd/Ctrl+Shift+V** to open the canvas beside the editor.

The preview icon in the editor title opens the canvas beside the editor too. To open it in the current editor group, run `Celigo: Open Flow Canvas` from the Command Palette. The same command is on the editor's context menu and on the Explorer's context menu for `flow.json`, `tool.json`, and `api.json`.

A JSON document outside a tree whose shape is a flow, tool, or API renders too. Its references stay unresolved, and the features that need the tree — badges, lint findings, the live overlay, push — are off.

## Read the canvas

The canvas draws the document the way Flow Builder does: sources on the left, destinations and lookups to the right, branchings with their branch names, merge points, and terminals. Each step's step components — filters, transformation, mapping, hooks, results/response mapping, error handling — appear as chips in the positions Flow Builder shows them. Tools (`tool.json`) and API builders (`api.json`) render with their own shapes.

The canvas reads the tree, not only the open file. Every step resolves through the pulled tree's manifest: its name, its category, the application behind its connection, and its step components. Symlink and pointer trees work. In a `celigo pull --neutral` tree, the bindings resolve connection names. Since extension 1.1.2, when `.celigo/manifest.json` cannot be loaded — a merge conflict, say — the canvas still renders the document and shows the manifest's problem as a warning.

The canvas follows the editor:

* Unsaved edits re-render as you type.
* Saving a step's resource or script file in the tree re-renders the canvas and refreshes its badges and lint findings (since extension 1.1.2).
* Moving the caret in the JSON highlights the step it is in.
* Double-clicking a step, or *Go to step in flow\.json* in its `⋯` menu, jumps to the step's definition.
* *Open export file*, *Open import file*, *Open AI agent file*, and the other items named for the step's type open the document the step references.

Badges show the tree's state. `celigo status` badges (`modified`, `missing`, `untracked`, `moved`) sit on the flow and on each step's document. `celigo lint` findings sit on the steps they concern. Since extension 1.1.2 a document whose folder was renamed or moved in the explorer is badged *moved*, not *untracked*: the tree still tracks it, its *Pull latest* points at `celigo pull`, which puts the folder back where the resource's name places it, and a step whose resource folder was moved resolves where the folder now sits.

Flows drill down. Flows started by this one (`_runNextFlowIds`) and an instance's abstract flow open in their own canvas.

*Find node* in the toolbar (**Cmd/Ctrl+F** while the canvas is focused) matches step names, applications, resource types, resource and connection names, and branch names, word by word. Press Enter or Shift+Enter to walk the matches; each match is selected and centered at the current zoom. Press Esc to clear. Steps that do not match are dimmed so the matches stand out.

| Interaction                                                                                                         | What happens                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Click a step                                                                                                        | The details panel shows its facts, its *Live* section (live overlay on), its step components, its *Related* tree, and its JSON (*Step* and *Resource*), each section folding from its header. A collapsed panel stays collapsed — its rail's chevron shows a dot for the selection — and folded sections stay folded.                                                                                                                                                                                           |
| Double-click a step, or *Go to step in flow\.json* in its `⋯` menu                                                  | The editor jumps to the step's definition in the document (`api.json` or `tool.json` for those).                                                                                                                                                                                                                                                                                                                                                                                                                |
| *Open export file* in the `⋯` menu (*Open import file*, *Open lookup file*, *Open AI agent file* — the step's type) | The document the step references opens in its own editor.                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| Click a step component chip                                                                                         | Its configuration opens in the details panel, with its *Related* item selected (a folded *Related* tree or JSON section unfolds).                                                                                                                                                                                                                                                                                                                                                                               |
| Click a step's live error count (*3 errors*)                                                                        | The step is selected and its open errors are listed in the *Live errors* list of the details panel's *Live* section, which unfolds if folded (live overlay on; read through the CLI). See [Live errors](#live-errors).                                                                                                                                                                                                                                                                                          |
| Click the toolbar's *139 open errors* or *remote changed* badge                                                     | The details panel opens on the flow's *Live* section: every step with open errors as a link, and, when `celigo diff` confirmed the server copy changed since the pull, the *Pull latest* and *Compare* buttons, the `celigo diff` line, and the *Pull everything* link. See [Drift](#drift).                                                                                                                                                                                                                    |
| *Pull latest* in the *Live* section                                                                                 | Takes the server's copy of this document — `celigo pull --force <path>` through the CLI, only this file forced — and shows the CLI's summary line. A clean document is pulled at once; one with local edits asks first; an unsaved editor buffer asks what to do with the edits first. See [Pull latest](#pull-latest).                                                                                                                                                                                         |
| *Compare* / *Pull everything* in the *Live* section                                                                 | *Compare* runs the quoted `celigo diff` line in a terminal — nothing written. *Pull everything* runs the plain incremental `celigo pull` of the whole tree in a terminal: files the server changed are refreshed, local edits kept, deletions only reported.                                                                                                                                                                                                                                                    |
| *Live* (the dot · Live · ↻ button)                                                                                  | Re-reads the live overlay now; its tooltip says when it was last read and how often it refreshes on its own while the canvas is visible.                                                                                                                                                                                                                                                                                                                                                                        |
| *Open ›* on a listed error                                                                                          | The error's fields, its retry data (the record), and its request and response open in the section, read-only; *Copy JSON* and *Open in editor* give you the whole payload.                                                                                                                                                                                                                                                                                                                                      |
| *Retry* / *Resolve* on a listed error (or in the error view's title line)                                           | *Retry* sends the record through the step again — `celigo flows retry-errors` through the CLI, one record, no confirmation; disabled with the reason on an error without retry data. *Resolve* takes the error off the open list for good — `celigo flows resolve-errors` — after a modal. Both run under the tree's profile in its permission mode: a read-mode profile gets the CLI's refusal in the list, with the terminal line.                                                                            |
| *Retry all* / *Resolve all* above the list, or *Retry selected* / *Resolve selected* with rows checked              | Every open error on the step (the CLI pages them all — not only the 50 listed) or the checked ones, after a modal naming the count, the step, and the profile. A retry is queued as a job: the count drains as it completes.                                                                                                                                                                                                                                                                                    |
| Click a *Related* script or *Instructions* item                                                                     | The `script.js` or `instructions.md` loads in the details panel as its own tab.                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| **Cmd/Ctrl+F**                                                                                                      | *Find node* matches step, application, resource, connection, and branch names. Enter and Shift+Enter walk the matches.                                                                                                                                                                                                                                                                                                                                                                                          |
| **Cmd/Ctrl+\\**, the chevron in the details panel's header, or *View › Show details panel*                          | Collapses the details panel to a rail so the canvas takes the room, or opens it again at its previous width.                                                                                                                                                                                                                                                                                                                                                                                                    |
| A section's header (*Facts*, *Live*, *Step components*, *Related*, the JSON section's tabs row)                     | Folds or unfolds that section (Enter or Space on the focused header does the same). The sections above the editor scroll as one, so a folded section gives its room to the others.                                                                                                                                                                                                                                                                                                                              |
| The grip on the divider above the JSON section                                                                      | Drag to split the panel between the sections and the editor (ArrowUp / ArrowDown 16 px, Home / End to the floors); double-click for the default half.                                                                                                                                                                                                                                                                                                                                                           |
| *Edit*                                                                                                              | Turns on the Flow Builder affordances: `+` on edges, the add and remove items in the step and branching menus (a dashed placeholder step's `⋯` has *Remove step*), branch and merge operations (a branch end's menu removes an empty branch), the *Enabled* / *Disabled* switch, and an editable JSON panel. In view mode those menus say *Turn on Edit to…*. On a tool or an API, *Edit* turns on only the switch and the JSON panel, and the menus say *Edit this tool's structure in its JSON* (or *API's*). |
| *Push*                                                                                                              | Runs `celigo push --dry-run`, then `celigo push`, in a terminal for this flow and every referenced file with local changes. Push sends what is on disk: when the document or a related file it would send has unsaved edits, a modal names them and offers *Save all and continue*, or Cancel.                                                                                                                                                                                                                  |

## The details panel

Click a step to open the details panel. Since extension 1.1.0 it is a stack of sections, each folding from the chevron in its header (Enter or Space on the focused header does the same):

* **Facts** — the flow's kind, id, state, schedule, and step count; or the step's type, app, resource, document, pointer, branch, and routing rows, with the lint findings and, on a flow, *Move left* / *Move right* and the branching editor.
* **Live** — with the live overlay on: the flow's server state, drift, and `celigo diff` line and the steps with open errors; for a step, its *Open errors* count and the *Live errors* list or error view it opens. See [Live overlay](#live-overlay).
* **Step components** — the step's chips.
* **Related** — everything the step reaches in the tree, with its count badge. See [The Related tree](#the-related-tree).
* **JSON** — the editor, whose header keeps the *Step* / *Resource* / *Script* / *Instructions* tabs and *Open in editor* while its body is folded. Folding it gives the whole height to the sections above.

A fold hides a section in place: the editor keeps its unapplied draft and undo history, an error view its tab, the tree its selection. An action whose effect lands in a folded section unfolds it — a step component chip unfolds *Related* (and *JSON* once the item is in the editor), a live error count or a toolbar live badge unfolds *Live*, a *Related* item unfolds *JSON* — while selecting a step leaves your folds alone. The sections above the editor scroll as one, so a folded section hands its room to the others.

### Collapse and resize

* **Collapse.** The chevron in the panel's *Details* header (*Collapse panel*), *View › Show details panel* in the toolbar, or **Cmd/Ctrl+\\** while the canvas is the active editor folds the panel to a slim rail at the canvas's right edge; the canvas takes the room, and *Fit to screen* and the zoom floor follow. The rail's chevron (*Expand panel*) opens it again at the width it had. Selecting a step leaves a collapsed panel alone — the rail's chevron shows a dot while a step is selected — whereas clicking a step's live error count or a step component chip, whose whole effect is in the panel, opens it. Cmd/Ctrl+S with the panel collapsed applies nothing and says so beside the rail.
* **Resize.** Drag the grip on the panel's left edge (*Drag to resize · double-click to reset*): 240 px at the narrowest, up to what leaves the canvas 320 px in the window as it is now, so a narrowed window shrinks the panel and a widened one gives the chosen width back. Double-click the grip for the 380 px default. The handle takes the keyboard too — arrows in 16 px steps, Home / End for the narrowest and widest.
* **Split.** Drag the grip on the divider above the JSON section to split the panel between the sections and the editor. Neither side goes under 120 px; ArrowUp / ArrowDown move it 16 px, Home / End to the floors; double-click puts the default back — the JSON section at half the height. The splitter hides while the JSON section is folded. What is stored is the JSON section's *share* of the height, not a pixel height, so a dragged split looks the same in a maximized and a half-height editor group.

Width, collapse, the folded sections, and the split are remembered together across reloads.

### JSON tabs

*Step* shows the step's own object in the flow. *Resource* shows the export or import document it references from the tree. With nothing selected, the editor shows the whole document. In view mode the editor is read-only.

In *Edit* mode, changes stay local until you click *Apply* or press **Cmd/Ctrl+S**; Esc reverts them. The editor lints changes inline and runs them through the same guards as canvas edits: an instance flow is refused, and so are the `responseMapping` object wrapper and `fields: null`. An applied edit is written as canonical JSON over exactly the step's range in the document — or over the resource file's full text — and leaves the document dirty for you to save. When the document changes underneath unapplied edits, a banner offers *Reload* or *Keep mine*. Since extension 1.1.2 *Apply* and **Cmd/Ctrl+S** wait for that answer — *The text changed underneath your edits — choose Reload or Keep mine first.* — instead of writing the draft over the other change.

Since extension 1.1.2, **Cmd/Ctrl+Z** in the JSON panel undoes only what you typed there: moving to another step or tab, or an applied edit coming back from the extension, starts its history afresh, so an undo never brings another step's text in as an edit. An unapplied edit to a step follows the step when another edit moves it, and text typed while an apply is being written is kept as the draft.

### The Related tree

Above the JSON, the *Related* tree lists everything the selected step reaches in the tree, in Flow Builder order:

* The step's entry in the document.
* One item per step component. Hooks expand per stage, each with its script beneath.
* The export or import document, with its connection and every other reference.
* For an AI agent or guardrail step, its *Instructions*: the `instructions.md` the tree keeps the system prompt in.
* The flow-level links: `_runNextFlowIds` and an instance's abstract flow.

JSON items open in the editor as their own tab. They apply pointer-exact to whichever tree file they live in, under the same guards as a step edit. A script loads as a *Script* tab: its `script.js` with JavaScript highlighting, opened at the function the hook names. An AI agent's instructions load as an *Instructions* tab: its `instructions.md` with Markdown highlighting. Both are editable in *Edit* mode, and *Apply* writes the whole file back verbatim. The row's *open in editor* link opens the file in a full editor beside the canvas. A reference the tree cannot resolve shows its id, muted, with a *where it's written* link to the referencing field.

Clicking a step component chip on a card does the same as its tree item. Arrow keys move between items.

## Edit and push

*Edit* turns on the Flow Builder affordances:

* `+` on any edge adds a step or a branching.
* Step menus add, remove, and reorder steps and toggle error handling. The details panel's *Move left* / *Move right* reorder a step within its branch; since extension 1.1.0 they are offered only where the neighbour in that direction is a step, so a branch's last step moves left only, its first right only, and a lone step neither.
* A dashed *Add destination / lookup* placeholder — the unconfigured step that `+` › *Add destination / lookup* inserts (`{ "setupInProgress": true }`, the entry Flow Builder saves while a step is being set up) — and its *Add source* twin carry the card's `⋯` menu, cut to what a placeholder is: *Go to step in flow\.json* (double-click does the same) and, in *Edit* mode, *Remove step* / *Remove source* (since extension 1.1.0). The flow's only source keeps its slot, as Flow Builder always shows one.
* Branch ends merge into a merge point or another branch. Merge points unmerge. In *Edit* mode a branch end's menu also has *Go to branch in flow\.json* and, when the branch has no steps, *Remove branch ""* (since extension 1.1.0); a branching's last branch is refused — remove the router instead.
* Branchings gain branches and names.
* The *Enabled* / *Disabled* switch beside the flow's name toggles `disabled`. Outside *Edit* mode it is a read-only badge.

In view mode the step and branching menus say *Turn on Edit to…* where the structural items would be.

Since extension 1.1.2 the structural edits are offered on a flow only. A tool's or an API's structure is edited in its JSON — the JSON panel, or the file: the canvas offers no `+` on an edge, no add, move, or remove of a step, no branching or merge, no error-handling toggle, and no branching editor in the details panel, and the menus say *Edit this tool's structure in its JSON* (or *API's*). These edits speak the flow shape and would rebuild a tool or an API as a flow, so the CLI's own engine refuses them on those documents too. The *Enabled* / *Disabled* switch and the JSON panel stay.

Every edit is written to the open document as canonical JSON through the CLI's own mutation rules — the same JSON Flow Builder saves — and, since extension 1.1.2, in the document's own line endings, so a CRLF checkout stays CRLF. Undo works, and `celigo status` sees exactly the change. Canvas and JSON edits are ordinary unsaved edits to the document: **Cmd/Ctrl+Z** undoes them one at a time, *File: Revert File* drops them all, and *Pull latest* replaces the saved file with the server's copy. Nothing reaches the account until you push.

> ⚠️ **Push writes to the account.** *Push* runs `celigo push --dry-run`, then `celigo push`, in a terminal, with the profile the CLI resolves there (`CELIGO_PROFILE`, or the active profile). The push runs only when the dry run succeeds, so a refused plan stops before anything is sent — read the plan the dry run prints. `celigo push` needs a profile in full mode. It sends what is on disk: when the document or a related file it would send has unsaved edits, a modal names them — *flow\.json has unsaved edits. Push sends what is on disk.* — and offers **Save all and continue**, which saves the document and each named related buffer and goes on to the terminal, or Cancel, which leaves everything as it is. A save the editor could not make stops the push (*Push did not run: … could not be saved*). There is no Revert here; *File: Revert File* is a keystroke away.

*Push* covers this flow and its changed step documents and scripts: the flow's document first, then every file its steps reference that `celigo status` reports as `modified`, or as `untracked` when push can create it — an import edited in the *Resource* tab, a hook's `script.js`, an AI agent's `instructions.md`, a modified connection — each named on the terminal's line. Since extension 1.1.2 it also names a related draft an interrupted push created a resource from, so `celigo push` adopts and finishes it. `--prune` is never passed; a missing file is left to the plan's notes. The extension holds no token. Anything that needs credentials runs the installed `celigo` binary, and `celigo push` is the only writer. See [push](/cli/local-tree/push.md) for the plan, the check against the server copy, and `--prune`.

*Push*, *Compare*, and *Pull everything* type their command line into a terminal, quoted for the shell the terminal runs: a POSIX shell, fish, PowerShell, or cmd.exe. Windows PowerShell 5.1 has no `&&`, so in PowerShell *Push* chains the plan and the push as `… --dry-run; if ($?) { … }`, and since extension 1.1.2 a `celigo.cliPath` that is a path is called through PowerShell's call operator (`& 'C:\…\celigo.cmd' push …`), so the line runs instead of failing as an expression. A line holding a name a terminal would act on is never typed — see [Names and links from a cloned tree](#names-and-links-from-a-cloned-tree).

## Layout and export

The toolbar's *View* menu holds *Fit to screen*, which shows the whole graph however large it is, and *Horizontal layout* / *Vertical layout*, which flip one canvas without changing the setting. `celigo.canvas.direction` sets the default. The vertical layout is Flow Builder's layout transposed — the same rules and the same spacing, top to bottom — with the step component chips in columns above and below each card and the sources in a row centered over the trunk.

The toolbar's *Export* menu saves a PNG or SVG image of the whole canvas, or copies a Mermaid diagram that renders natively in a GitHub pull request description. The diagram follows the canvas's direction: `flowchart LR` for horizontal, `flowchart TD` for vertical. `Celigo: Copy Flow as Mermaid` in the Command Palette copies the same diagram; without an open canvas it follows the setting.

## Live overlay

The live overlay is off by default. With `celigo.canvas.liveOverlay` set to `true`, the canvas reads the account the tree is bound to, through the CLI in read mode — `celigo flows get` and `celigo flows error-summary`: open-error counts per step, whether the flow is enabled on the server and its last run, and whether the server copy changed since the pull. The overlay itself writes nothing; the only account writes the canvas runs are the *Live errors* list's explicit *Retry* / *Resolve* ([below](#live-errors)).

### Badges and the Live button

Since extension 1.1.0 the toolbar sums the overlay up beside the flow's name as quiet badges styled like the tree-state badges: a red *139 open errors* (hidden at zero) and an amber *remote changed* when the server copy changed since the pull, or one muted *live unavailable* carrying the CLI's own message when the read failed. Each opens the details panel's flow-level *Live* section — expanding a collapsed panel — which explains the drift in words, quotes the `celigo diff <path> --dir <root>` line to run, and lists the steps with open errors as links. The panel's *Live* section also reports *Enabled on the server* or *Disabled on the server*.

At the toolbar's right, the *Live* button carries a status dot — grey until the first read, green when clean, red for open errors, amber for a confirmed change, hollow when unavailable — and a refresh glyph that spins while a read is in flight. Click it to read now. Its tooltip says *Updated 40 s ago · refreshes every 60 s while visible*, then the flow's state on the server, its last run, the profile, and the drift. `Celigo: Refresh Live Overlay` in the Command Palette reads too.

### Timed refresh

While a canvas is visible and the window focused, the extension re-reads the overlay every `celigo.canvas.liveRefreshSeconds` (60 by default; values below 15 are raised to 15; `0` for on demand only) — the same two read-mode CLI calls as the *Live* button, never overlapping: a tick that falls due while a read is in flight is skipped, and a click, a save, or the palette command joins the read in progress rather than starting another. A hidden canvas or an unfocused window pauses the timer; coming back reads at once when the last read is older than the interval, else waits out the remainder. After a failed read the wait doubles, up to ten minutes, until a read succeeds. Restricted Mode and an overlay turned off run no timer. Nothing detects a push — save, click *Live*, or wait for the tick.

### Drift

*Remote changed* means a confirmed content difference. The server's `lastModified` against the token the tree pulled is only the first signal: the platform bumps that token for a flow run and for a debug toggle — fields `celigo pull` strips and `celigo diff` ignores — so a flow that had merely run since the pull used to wear the badge (extension 1.0.0). Since 1.1.0, when the two tokens differ the extension runs the CLI's own comparison — `celigo diff <path> --dir <root> [--profile <p>] --format json`, read mode, in the tree — and the drift is one of four:

| Drift                                                                                                                                                                             | Badge                                             | The *Drift* row                                                                                                                                                                                                                                                                                                   |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| *In sync* — the tokens agree; no diff runs.                                                                                                                                       | none                                              | *in sync*                                                                                                                                                                                                                                                                                                         |
| *Timestamp moved* — the diff finds the content identical.                                                                                                                         | none                                              | *timestamp moved — the server's timestamp moved since the pull (a run or a debug toggle); the content matches your file*, with *Pull latest* offered as a token refresh (the file is not rewritten) and *Compare* in the plain style.                                                                             |
| *Remote changed* — the diff reports differences.                                                                                                                                  | amber *remote changed* (the count in its tooltip) | *remote changed — 3 differences from your file* (on a document that also has local edits, some of the differences may be yours), with *Pull latest*, *Compare*, and *Pull everything*.                                                                                                                            |
| *Unfinished* — the diff reports the document left half-done by an interrupted `celigo pull` or push (since extension 1.1.2; `celigo diff` reports this state from CLI 2026.10.1). | none                                              | *unfinished —* and the CLI's note on what finishes it: *an interrupted `celigo pull` was renaming it — run `celigo pull` to finish*, or for a create whose write-back failed *… run `celigo push` to adopt it*. No *Pull latest* or *Compare*, since neither finishes it; the content is not compared until then. |

When the diff itself fails — a server error, a refusal — nothing is claimed: the row says the content *was not compared*, an error-toned line gives the CLI's reason (*could not compare: …*), the `celigo diff` line is quoted to run yourself, and the next refresh tries again. The comparison runs only while the tokens differ and once per state; its result is kept until the server's token, the pulled token, or the file on disk moves. The pulled token is re-read from the tree's manifest on every read, so a `celigo pull` you run in a terminal clears the drift on the next tick.

### Pull latest

Under the *Drift* row, **Pull latest** takes the server's copy of this document: `celigo pull --force <path> --dir <root> [--profile <p>]` through the CLI, in the extension host's own process (an argv, never a shell line), under a progress notification with ten minutes to finish. `--force` reaches only this document; the rest of the tree is pulled incrementally around it, never with `--prune` or `--allow-account-mismatch`. What happens is decided on the host before anything spawns:

| The document                                                                              | What *Pull latest* does                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Has an unsaved editor buffer                                                              | Asks first — *flow\.json has unsaved edits. Pull replaces the file on disk.* — with **Save and continue** (the edits stay in the file, and the pull then asks before discarding them, below), **Revert and continue** (the unsaved edits are dropped, as *File: Revert File* drops them, and the file as saved is pulled), or Cancel. A buffer still dirty afterwards, or a save the editor could not make, is a refusal that names what to do in the editor. |
| Is clean in `celigo status`                                                               | Pulled outright — nothing local is lost.                                                                                                                                                                                                                                                                                                                                                                                                                      |
| Has local edits since the last pull                                                       | Asks first — *Order Sync has local edits since the last pull. Take the server's copy and discard them?* — with *Take server copy*, *Compare first* (the diff in a terminal), or Cancel.                                                                                                                                                                                                                                                                       |
| Is missing, untracked, or moved, outside a tree, or in a tree whose status cannot be read | The button is disabled with the reason in its tooltip (Restricted Mode and a missing CLI disable it as they disable *Live*). For a moved document the tooltip points at `celigo pull`, which puts the folder back where the resource's name places it, after which *Pull latest* works again (since extension 1.1.2).                                                                                                                                         |

The CLI's summary line becomes the section's note — *Took the server copy of flows/Order Sync/flow\.json. Pulled 1, renamed 0, unchanged 245 (of 246).* — with the CLI's own notes beneath it, or *… already matched the server copy; its pulled token was refreshed* when only the token had moved. Since extension 1.1.2 a document the server renamed says so and where it lives now — *Took the server copy of flows/Order Sync/flow\.json: the server renamed it, so it now lives at flows/Order Sync v2/flow\.json.* — and a failure shows the CLI's error line, not the hint printed after it. The document is rewritten on disk, so the editor reloads its clean buffer, the canvas re-renders from the new text, the tree-state badge clears, and the overlay is re-read against the manifest's new token so *remote changed* goes.

Beside it, **Compare** runs the quoted `celigo diff` line in a terminal — your file against the server copy, nothing written — and, for a confirmed change, the **Pull everything** link runs the plain incremental `celigo pull` of the whole tree in a terminal: every file the server changed is refreshed, local edits are kept, deletions are only reported. See [pull](/cli/local-tree/pull.md) for `--force` and [status and diff](/cli/local-tree/status-and-diff.md) for the comparison.

### Live errors

Click a step's error count on its card (*3 errors*), or the *Open errors* row of the step's *Live* section, to list the step's open errors in a *Live errors* list under it, read through `celigo flows errors <flow> <step>` — a read-mode verb, against the tree's profile like the rest of the overlay. Each row shows the error's code, classification, whether it can be retried, when it occurred, its message (clamped; click to unfold), and the errorId and trace key a terminal continues with. The list shows the newest 50 and names the exact terminal line for the rest (*2 more — run `celigo flows errors … --profile …` in a terminal*), has *Refresh* and *Hide*, says *No open errors* when the step has none, and shows the CLI's own error line (a missing profile, a revoked token) when the listing fails. The flow-level *Live* section lists every step with open errors, most first, each a link that selects the step and opens its list. Where the CLI cannot run — Restricted Mode, no CLI installed — the count is a plain status whose tooltip says why.

**Open ›** on a row opens an error view — what Error Management shows when an error is clicked — read-only:

| Tab                    | Contents                                                                                                                                                                                                                      | Read through                                                  |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| *Error*                | The message unclamped and every field the record carries: occurred, code, classification, retryable, source, error ID, trace key, flow job, `oIndex`, purge time.                                                             | The listing.                                                  |
| *Record*               | The retry data — the record as the step saw it when it failed, in the envelope a retry re-feeds — as JSON in the panel's read-only editor, with the envelope's stage, source export, one-to-many path, and trace key as rows. | `celigo flows error <flow> <step> <errorId> --retry-data`     |
| *Request* / *Response* | The stored HTTP pair: method and URL, status and time received, headers, and the body as JSON when it parses, as text otherwise.                                                                                              | `celigo flows error <flow> <step> <errorId> --request-detail` |

Each payload is read on the first tab that needs it, under the same gates as the list. A tab the error has nothing for is disabled and its tooltip says so in the CLI's words — no retry data on a connection-class error, no stored request or response on a non-HTTP step. *Copy JSON* on every tab and *Open in editor* on the payload tabs read the whole payload on the host and open it as an untitled JSON document beside the canvas; nothing is written to disk, and the panel itself receives at most 512 KB per payload — past that it shows only the size. In the *Request* and *Response* tabs the host replaces every header and query-string value whose name reads as a credential (authorization, cookie, token, secret, password, api key) with `••••••`, on top of the platform's own `********`, and the tabs say so. Since extension 1.1.2 that covers more names — `passwd`, `credential`, `signature`, `session`, `subscription-key`, `X-Auth-Key`-style names, a bare `key` or `sig`, and a presigned URL's `X-Amz-Credential` and `X-Amz-Signature` — and the password in a `scheme://user:password@host` URL. Retry data and bodies never reach a log or an error message. *Back* returns to the list; a Refresh, another step, or *Hide* drops the view.

**Retry and resolve.** The list acts on what it lists (since extension 1.1.0):

| Control                                                          | What it does                                                                                                                                                                              | Asks first?                                                                                                                                                                                                       |
| ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| *Retry* on a row (and in the error view's title line)            | Sends that one record through the step again. Disabled with the reason on an error without retry data — a connection or governance error has no record to send again; resolve it instead. | No.                                                                                                                                                                                                               |
| *Resolve* on a row (and in the error view's title line)          | Takes the error off the open list for good.                                                                                                                                               | Yes — *Resolve 1 error on ?*                                                                                                                                                                                      |
| *Retry all* / *Resolve all* above the rows                       | Every open error on the step — the CLI pages them all server-side, not only the 50 the panel lists.                                                                                       | Yes — *Retry 158 open errors on ? Each record is sent through the step again — the destination receives it again …* / *Resolve 158 open errors on ? Resolved errors leave the open list and cannot be reopened …* |
| *Retry selected (n)* / *Resolve selected (n)*, with rows checked | The checked errors; a retry counts only the checked errors that can be retried, and its tooltip names the ones it skips. *Clear selection* sits beside them.                              | Yes.                                                                                                                                                                                                              |

Each modal names the count, the step, and the profile the CLI runs under — the account the answer commits to. Each action is `celigo flows retry-errors <flow> <step> [<retryDataKeys>] [--yes]` or `celigo flows resolve-errors <flow> <step> [<errorIds>] [--yes]`, run by the extension through the CLI in its own process (an argv, never a shell line), `--yes` only for *all*, the modal having asked — the CLI's own `[y/N]` needs a terminal the host has none of. The commands run against the tree's profile in whatever permission mode that profile has: a **read-mode profile gets the CLI's refusal in the panel** — with CLI 2026.10.1, `Command 'flows retry-errors' cannot run in read mode (it writes to the account). Current mode: read. A person raises this profile's mode to operate or full at a terminal ('celigo config set mode <mode>') to run operational actions; an agent must not raise it, or switch profiles, to get past this refusal.`; earlier CLI releases say `Read mode: blocked POST v1/flows/…` — with the terminal line to run instead, never a silent nothing. The CLI's outcome lines become the list's note: *Retry queued for 3 record(s). (job …)* — a retry is a job the platform runs, so the open count drains as it completes rather than dropping at once — *Resolved 158 error(s).*, and the *… matched no open error* / *… were not listed on this step* lines for keys that matched nothing; a run that changed nothing is the CLI's own sentence in the error tone, as is any other failure, each with the terminal line. While the modal or the CLI has the request the buttons wait and the list says so (*Waiting for your answer in the dialog…*, *Resolving all 158 open errors through the celigo CLI…*); one action at a time per canvas. After a completed action the list is read again — resolved errors leave it — the overlay is re-read so the step's count and the toolbar badge follow, and the payloads cached for the step's errors are dropped.

A retry takes `retryDataKey`s, not errorIds. The panel keeps naming errors by id and the host resolves the keys from a fresh listing, the way the CLI's own `flows error` does, refusing an id no longer listed (*refresh the list*) and an error without retry data (*resolve it instead*) before anything is written; the webview never holds a key, and no record, request, or response reaches a log, a modal, a command line, or a note — ids and the CLI's lines only. Every button is disabled with its reason in Restricted Mode and without the CLI, as the list itself is. Assignment, comments, tags, and the resolved-error history stay in Error Management. See [flows](/cli/commands/flows.md) for `errors`, `error`, `retry-errors`, and `resolve-errors`.

## Restricted Mode

The extension has limited support for [untrusted workspaces](https://code.visualstudio.com/docs/editing/workspaces/workspace-trust). In Restricted Mode the canvas renders, the details panel and the JSON editor work, and edits are written to the open document. Nothing spawns the `celigo` CLI: lint findings, the live overlay (its timed refresh included), the *Live errors* list and its *Retry* / *Resolve*, *Pull latest*, push, and the `npx` offer stay off until you trust the workspace, and *Live*, *Push*, and every disabled button say so in their tooltips. When you trust the workspace, open canvases refresh on their own.

> ⚠️ **`celigo.cliPath` is a restricted setting.** A workspace's own value is ignored until you trust the workspace, so an untrusted folder cannot choose the executable the extension runs.

In a virtual workspace, rendering works on any JSON document. Tree lookups, the CLI, and file edits need a local folder.

### Names and links from a cloned tree

A tree can come from someone else's repository, so the extension treats the names and files in it as untrusted input, in a trusted workspace too. Since extension 1.1.2:

* A name from the tree — a folder name, or the `profile` recorded in `.celigo/manifest.json` — cannot end the quoting of the command line *Compare*, *Pull everything*, or *Push* types into a terminal: it is quoted for the terminal's shell, typographic quotes in PowerShell, a trailing backslash or `%VAR%` in cmd.exe, and a backslash in fish included.
* Those three refuse to type a line at all when a word in it holds a control character, which a terminal would act on as a key instead of typing; the refusal names the character's code point. The CLI runs the extension starts itself (lint, the live overlay, *Pull latest*) refuse such an argument too. On Windows a name holding a double quote is refused as well, in a cmd.exe terminal line and before the CLI starts, and on every platform a document path, push reference, or profile name that starts with `-` never becomes a CLI argument. See [The canvas refuses to type a command line](#the-canvas-refuses-to-type-a-command-line).
* The details panel, the JSON editor, *Open export file* and its siblings, and the drill-down to another flow refuse a tree file reached through a symbolic link, as the CLI does: git tracks links, and one in a cloned tree could point at any file on the machine.
* A document `_id` that is not a platform id (24 hexadecimal characters) never reaches a CLI argument; the live overlay reports *live unavailable* for that document instead.
* On Windows, the CLI the extension starts is never looked up in the tree's own folder, so a `celigo.cmd` committed to a repository does not run.

## Settings

| Setting                            | Default      | What it does                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ---------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `celigo.cliPath`                   | `celigo`     | The CLI executable the extension runs for lint findings, the live overlay, and push. Leave it as `celigo` to use the one on your `PATH`, or set the path to the executable. When none is installed, the extension offers to run the CLI through `npx`; accepting writes `npx --yes @celigo/celigo-cli@<version>` here, in your user settings. Since extension 1.1.2 the value is read as a command line — a path with spaces, quoted or not, and a command with arguments (`pnpm dlx …`, `wsl celigo`, `node "/path with spaces/index.js"`) work — and a change takes effect in open canvases without reopening them. Restricted setting: a workspace's own value is ignored until the workspace is trusted. |
| `celigo.canvas.lint`               | `true`       | Run `celigo lint` on the open document and show the findings on the steps they concern. Needs the CLI.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `celigo.canvas.liveOverlay`        | `false`      | Overlay live account state — open-error counts per step, enabled or disabled on the server and the last run, whether the server copy changed since the pull — read from the account the tree is bound to, through the CLI in read mode. The overlay writes nothing; the *Live errors* list's *Retry* / *Resolve* are the canvas's only account writes, and each is an explicit click.                                                                                                                                                                                                                                                                                                                        |
| `celigo.canvas.liveRefreshSeconds` | `60`         | How often the live overlay is re-read while its canvas is visible and the window focused, in seconds — the same read-mode CLI reads as the *Live* button. `0` turns the timer off: the overlay then refreshes only on demand (the *Live* button, a save, `Celigo: Refresh Live Overlay`). Values below 15 are raised to 15. After a failed read the wait doubles, up to 10 minutes, until a read succeeds. Added in extension 1.1.0.                                                                                                                                                                                                                                                                         |
| `celigo.canvas.showComponents`     | `true`       | Show the step component chips (filters, mappings, hooks, error handling) on step cards.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `celigo.canvas.direction`          | `horizontal` | Lay the canvas out left to right (`horizontal`, as Flow Builder does) or top to bottom (`vertical`). *View › Vertical layout* flips one canvas without changing the setting; a changed setting takes over again. `Celigo: Copy Flow as Mermaid` follows the canvas.                                                                                                                                                                                                                                                                                                                                                                                                                                          |

## Commands and keybindings

| Command                                      | ID                   | Keybinding                                                         | Where                                                                                                                                                                                 |
| -------------------------------------------- | -------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Celigo: Open Flow Canvas`                   | `celigo.open`        | —                                                                  | Command Palette; the editor's context menu on a flow document; the Explorer's context menu on `flow.json`, `tool.json`, and `api.json`. Opens the canvas in the current editor group. |
| `Celigo: Open Flow Canvas to the Side`       | `celigo.openToSide`  | **Cmd/Ctrl+Shift+V** while the editor has focus on a flow document | Command Palette; the preview icon in the editor title. Opens the canvas beside the editor.                                                                                            |
| `Celigo: Copy Flow as Mermaid`               | `celigo.copyMermaid` | —                                                                  | Command Palette while a flow document is active. The toolbar's *Export › Copy Mermaid diagram* does the same.                                                                         |
| `Celigo: Push Flow with celigo (plan first)` | `celigo.push`        | —                                                                  | Command Palette while a flow document is active. The toolbar's *Push* does the same.                                                                                                  |
| `Celigo: Refresh Live Overlay`               | `celigo.refreshLive` | —                                                                  | Command Palette. The toolbar's *Live* button does the same.                                                                                                                           |
| `Celigo: Apply the JSON Panel's Edits`       | `celigo.applyJson`   | **Cmd/Ctrl+S** while a canvas is the active editor                 | Command Palette while a canvas is the active editor. The details panel's *Apply* does the same.                                                                                       |
| `Celigo: Find Node on the Canvas`            | `celigo.findNode`    | **Cmd/Ctrl+F** while a canvas is the active editor                 | Command Palette while a canvas is the active editor. Focuses *Find node* in the toolbar.                                                                                              |
| `Celigo: Show or Hide the Details Panel`     | `celigo.togglePanel` | **Cmd/Ctrl+\\** while a canvas is the active editor                | Command Palette while a canvas is the active editor. The chevron in the details panel's header and *View › Show details panel* do the same. Added in extension 1.1.0.                 |

The last three commands exist for their keybindings. They apply while a canvas is the active editor, wherever focus sits inside it, and can be rebound in Keyboard Shortcuts. Cmd/Ctrl+\ is Split Editor's key, which a webview panel has no use for; it is taken over only there.

## Troubleshooting

### The canvas asks for a window reload

A VSIX reinstalled at the same version overwrites the extension in place. A canvas opened afterwards would run the updated webview against the still-running old extension host, so the host stamps a protocol revision on every graph and the canvas shows a banner when the two differ. Run **Developer: Reload Window** from the Command Palette.

### `celigo` is not found

Lint findings, the live overlay, and push need the CLI. Install it, or point `celigo.cliPath` at the executable:

```bash
npm install -g @celigo/celigo-cli
celigo --version
```

When no `celigo` answers, the extension offers once per session to run it through `npx`, pinned to the CLI version it needs. On Windows, the npm-installed `celigo` is a `.cmd` shim; the extension runs it through `cmd.exe`, and a tree path with spaces or parentheses arrives intact. For `celigo: command not found` in a terminal, see [Troubleshooting](/cli/using-the-cli/troubleshooting.md).

Since extension 1.1.2 `celigo.cliPath` is read as a command line, with quotes honored. A bare command name keeps everything after it as arguments (`wsl celigo`, `pnpm dlx …`); for a path, the longest leading run of words that names an existing file is the executable, so `C:\Program Files\Celigo\celigo.cmd` works quoted or not, and `node "/path with spaces/index.js"` keeps its quoted argument together. A changed setting takes effect in open canvases without reopening them. Earlier versions split the setting on every space, so a path holding one failed with `ENOENT` on every call.

### The canvas refuses to type a command line

*Compare*, *Pull everything*, or *Push* shows a warning and types nothing:

```
the command line is not run: a name from the tree holds a control character (U+000A), which a terminal would act on as a key instead of typing. Rename the folder, or fix the profile in .celigo/manifest.json, and run the command yourself.
```

A folder name, or the `profile` recorded in `.celigo/manifest.json`, holds a control character — here a line feed — usually from a repository someone else committed. Rename the folder or correct the `profile` value, then run the command yourself in a terminal. In a cmd.exe terminal a similar refusal names a double quote in a name, which cmd.exe would read as the end of its quoted word when the CLI's `.cmd` launcher re-parses it. Since extension 1.1.2.

### A tree file is refused as a symbolic link

The details panel or the JSON editor shows a note such as:

```
scripts/Order Hooks/script.js is a symbolic link — the tree must not contain symlinks (they can point outside the tree); the only links a tree holds are the ones pull writes inside resource folders. Remove it, then run `celigo pull`.
```

The tree holds a symbolic link where a file or folder should be — git tracks links, so a cloned repository can carry one that points anywhere on the machine. Since extension 1.1.2 the panel refuses it, as the CLI does: remove the link, then run `celigo pull` to write the real file.

### Lint findings, the live overlay, or push are off

*Live* and *Push* say why in their tooltips. Either the workspace is in Restricted Mode — trust it, and open canvases refresh on their own — or the CLI is missing.

### Push met an unsaved buffer

Push sends what is on disk. Since extension 1.1.0 the *Push* button asks — *flow\.json has unsaved edits. Push sends what is on disk.* — and **Save all and continue** saves the document and every named related buffer before the terminal opens; Cancel leaves everything as it is. A save the editor could not make stops the push (*Push did not run: … could not be saved*): fix what the editor reports, save, and push again.

### *Retry* or *Resolve* shows a read-mode refusal

The tree's profile is in `read` mode, so the CLI refused the write before any request left your machine. With CLI 2026.10.1 the refusal reads `Command 'flows retry-errors' cannot run in read mode (it writes to the account). Current mode: read. A person raises this profile's mode to operate or full at a terminal ('celigo config set mode <mode>') to run operational actions; an agent must not raise it, or switch profiles, to get past this refusal.` (`flows resolve-errors` for *Resolve*); earlier CLI releases say `Read mode: blocked POST v1/flows/…`. The extension never overrides a profile's mode. Raise the mode yourself in a terminal — `celigo config set mode operate` (or `full`) on that profile, which since CLI 2026.10.1 asks you to type the new mode back — or use a profile whose mode allows the action, then run the action again. See [Permission modes](/cli/getting-started/profiles.md#permission-modes).

### *remote changed* shows when nothing changed

Extension 1.0.0 called the server copy *remote changed* whenever its `lastModified` differed from the pulled token, and the platform bumps that token for a flow run or a debug toggle. Since 1.1.0 the badge means `celigo diff` reported differences; a moved timestamp with matching content is a *timestamp moved* drift with no badge. If the *Drift* row says the content *was not compared*, the diff itself failed — the row quotes the CLI's reason and the `celigo diff` line to run yourself.

### A panel request stalls

Every request the details panel makes resolves to content, a note, or an error line within 8 seconds. A stalled request says so instead of loading forever, and points at a window reload. While a modal waits for your answer — a *Resolve all*, a *Pull latest* on a document with local edits — the panel says so in a muted line and the stalled note stays off; a pull has ten minutes rather than eight seconds, under a progress notification.

### Get help

For extension bugs and feature requests, contact [Celigo Support](https://docs.celigo.com/hc/en-us/requests/new) with the extension's version, your VS Code or Cursor version and operating system, the output of `celigo --version` when the CLI is involved, and a minimal reproduction. Never post API tokens, credentials, customer data, or complete request or response payloads. For failures on the CLI's side — `401 Unauthorized`, `celigo: command not found` — see [Troubleshooting](/cli/using-the-cli/troubleshooting.md); for a refused push, see [push](/cli/local-tree/push.md).

## What's next

* [The local tree](/cli/local-tree.md) — pull, status, diff, and push for the tree the canvas opens.
* [push](/cli/local-tree/push.md) — the plan, the check against the server copy, and `--prune`.
* [flows graph](/cli/commands/flows.md#celigo-flows-graph) — the same graph from the terminal, as JSON, Mermaid, or DOT.
* [AI assistant skills](/cli/using-the-cli/skills.md) — give your AI coding assistant grounded knowledge of integrator.io for editing the tree.
