Flowcharts (visual flowchart editor)
A standalone visual flowchart editor that opens as a virtual project in the sidebar: draw boxes and connectors on a canvas, organise them into swimlanes, keep a saved library of charts, and describe a chart in words to have an AI build it.
What it is
Flowcharts is a standalone visual flowchart editor inside Agent Mission Control, surfaced as a virtual project in the sidebar (it mounts the same way Decks does — a docked panel beside the projects sidebar, not a full-screen view). You draw boxes and connectors on a React Flow canvas, drop shapes from a palette, organise them into swimlanes, and keep a saved library of charts. Editing is fast: quick-connect (drag a connector onto empty canvas to spawn a connected shape), snap + alignment guides while dragging, multi-select align / distribute, and smart connectors that route orthogonally around other shapes (see Editing below). AI sessions can read and draw on the open board from a built-in Sessions tab, and a "Build with AI" on-ramp turns a one-line description into a whole chart (see Build with AI below).
A flowchart is a single graph blob: { nodes, edges, lanes }. Each chart is one
row in the flowcharts SQLite table; the whole graph is stored as one JSON
data column (charts are small, so a single-column blob is the simplest reliable
shape — it mirrors the mindmaps table).
Where to find it
How it is gated
Flowcharts is an in-development feature registered as 'flowchart' in
src/shared/unreleased-features.ts (settingKey: 'flowchartEnabled',
envVar: AMC_SHOW_FLOWCHART, status: 'in-development').
It is visible when any one of the following is true:
- The feature is marked
'shipped'in the registry (releases to everyone). - Omniscio is launched with
AMC_SHOW_FLOWCHART=1. - The user flips the Settings → Lab → Flowcharts toggle on.
No code reads settings.flowchartEnabled directly to decide visibility — the
sidebar row gate goes through isUnreleasedFeatureVisibleInRenderer('flowchart', …)
in project-visibility.ts (UNRELEASED_PROJECT_GATES), and the main-process
handlers gate on isUnreleasedFeatureVisible('flowchart', …). Doing otherwise
bypasses the env reveal path and fails the gating lint test.
Discoverability on enable
Flipping the toggle on reveals the Flowcharts sidebar row reactively — the
projects sidebar re-filters on the settings change (Dashboard's useMemo keyed on
settings), so no app refresh is needed. Omniscio also points the user to the new
row: the flowchart entry declares
sidebarLaunch: { viewId: 'flowchart', label: 'Flowcharts' }, so enabling it
fires the standard Lab-feature flash + toast, with an Open action that routes
to the __flowchart__ virtual project via the registry-driven resolver
(virtualProjectPathForSidebarLaunchViewId in useAppCustomEvents.ts). Every
gated sidebar built-in must carry such a pointer — locked by invariant J in
unreleased-feature-gating-contract.md
(guard: gated-builtin-discoverability-pointer.test.ts).
How it is mounted
Flowcharts is an amc-builtin virtual project (__flowchart__) defined once in
src/shared/integrations/flowchart.ts and assembled into the registry by
npm run integrations:reindex. Its UI manifest in
src/renderer/src/integrations/ui-registry.ts carries:
panelComponent: FlowchartEditor— the full editor shell.panelOwnsLayout: true— the panel renders its own multi-pane layout, so Omniscio suppresses the default emptySessionsSidebarfallback (same as Decks / Writer).mobilePrefersPanel: true— on a phone (Web Access mode) the panel renders in the'sessions'slot, so tapping the row lands on the editor (its internal Charts/Sessions tabs reach everything) rather than an empty session list.
FlowchartEditor assembles its own left sub-sidebar (FlowchartSidebarTabs — a
Charts | Sessions tablist), a toolbar, the React Flow canvas (wrapped in
one ReactFlowProvider), and a shape palette. Light/dark colorMode follows the
app theme via useIsDarkMode() (the dark class on <html> is the single source
of truth); the flowchart data model carries no per-chart theme override.
How it behaves
AI sessions on the board
The editor's Sessions tab is the stock session-host sidebar
(SessionHostSidebar + useFlowchartSessionHost). The SAME __flowchart__
project hosts those sessions: it is spawnable + resolver-mapped to
<userData>/flowchart-agent (SPAWNABLE_VIRTUAL_PROJECT_SENTINELS +
resolveProjectWorkDir). Selecting a session reveals its chat inside the
editor (source 'flowchart-session') rather than ejecting the user out of the
panel — mirroring the mind map's reveal. A spawned flowchart agent reads and edits
the open board through the CLI control server's flowchart routes
(cli-server-flowchart-routes.ts); an external edit emits the flowchart:changed
push so the renderer refreshes the list and reloads the open chart (preserving
undo).
It is deliberately NOT in SESSION_HOSTING_VIRTUAL_PROJECT_PATHS — that set drives
Ctrl+T / auto-select for sidebar-SELECTED virtual projects, and the Flowchart owns
its own session-open path.
Build with AI (describe → flowchart)
The headline differentiator: type a one-line description and an AI session builds the whole chart. It is NOT a bespoke generation engine — it is a regular Omniscio session (your normal per-session model picker applies) given CLI access to build the chart, so quality/cost follow your model choice and there is no separate billing path.
- On-ramp — a "Build with AI" button on the Charts empty-state + the Charts header
(
FlowchartListSidebar) opens a small "Describe your flowchart" dialog (BuildWithAiModal— aDialogShell+ aFormFieldtextarea; Ctrl/Cmd+Enter submits). - What Build does (
useFlowchartAiBuild) —createFlowchart()a fresh chart, thenlaunchSessioninto__flowchart__with the description asdraftText(pre-filled in the composer) and a BUILD primer asfirstSendPrefix(hidden setup context). It usesfirstSendPrefix, NOTinitialPrompt, so the session opens ready with the model picker — you pick a model and send, which is what preserves your model choice. The session chat reveals in place over the editor (source'flowchart-session'). A failed spawn soft-deletes the just-created blank chart (no orphan). - The build primer (
buildFlowchartBuildPromptinflowchart-spawn-prompt.ts) hands the agent the full/flowchartsCLI verb set (list / create / replace / rename / delete — "make whatever you need"), the 19FLOWCHART_NODE_TYPES, when to use swimlanes, and the validate-and-retry-on-400 loop — and tells it to set every node tox:0, y:0and let Omniscio arrange, so it spends its effort on the LOGICAL graph (nodes + edges + labels). - Auto-arrange — an LLM can't run the renderer-side elk layout, so it drops every node
on one point. When a chart arrives via the CLI unlaid-out (
isUnlaidOut: 2+ nodes coincident — the0,0sentinel), the store'sarrangeIfUnlaidOutdynamic-importsflowchart-layout.ts(keeping its heavy elk dep out of the always-on startup bundle — thelayout-lazy-loadedinvariant), runsautoLayoutFlowchart(elk) once andmergeNodePositionsthe result, folded into ONE undo entry and persisted. It fires on the liveFLOWCHART_CHANGEDreload AND on chart open (so an agent-built chart tidies even if it wasn't open at build time); an elk OR layout-load failure falls back to the manual Auto-layout button.
Locked by the ai-build-via-session invariant in the
flowchart-feature-contract:
"describe → flowchart" stays a regular session over the CLI — never a bespoke generation /
fixed-model / cost-cap path — and the primer's 0,0 sentinel stays in lock-step with the
isUnlaidOut detector.
Editing — quick-connect, snap, align, smart routing
Four interactions make the canvas fast, each backed by a PURE, unit-tested module (no
React / store / React Flow) that FlowchartCanvas.tsx wires:
- Quick-connect — drag a connector off a shape onto empty canvas and the store's
connectToNewNodecreates the node + edge in ONE commit (one undo step), opening it for rename. Wired viaonConnectStart/onConnectEnd; a drop inside a lane joins that lane. - Snap + alignment guides —
flowchart-align-guides.tscomputeSnapsnaps the dragged node's edge/center to a nearby node's (8px threshold) and returns guide segments drawn as 1px accent SVG lines in a<ViewportPortal>(onNodeDrag). - Multi-select align / distribute —
flowchart-align.tsalignNodes(6 modes) /distributeNodes(h/v) feed the store'salignSelected/distributeSelected, which bulk-apply viaapplyLayout(ONE undo step). The toolbar shows the cluster at ≥2 selected shapes (tracked in the transientselectedNodeIds). - Smart connectors —
flowchart-edge-router.tsrouteOrthogonal(Hanan-grid A* with a turn penalty + an obstacle/size CAP →nullfallback to the simple path) routes each edge AROUND other shapes. Routes are DERIVED + TRANSIENT: computed in the canvas (a memo keyed on a committed-geometry signature, recompute on drag-stop, never per frame) and injected onto the React Flow edgedata.routePoints— never persisted (model edges keep only theirroutingmode). An edge touching the dragging node drops its route to follow live.
Locked by the smart-routes-transient + snap-and-align-pure + commit-chokepoint
invariants in the
flowchart-feature-contract.
Status
In-development (default-hidden). Ships the data model, the IPC + CLI-route
surface, the React Flow editor (canvas, toolbar, shape palette, swimlanes, saved
library) with quick-connect / snap + alignment guides / multi-select align-distribute /
smart obstacle-avoiding connectors, Mermaid export (one-way, lossy), AI sessions on
the board (the Sessions tab spawning into __flowchart__), and "Build with AI"
(describe → a regular session builds the chart via the CLI, auto-arranged). Reveal via
Settings → Lab toggle or AMC_SHOW_FLOWCHART=1.
For agents
Data model — flowcharts
Created by migration src/main/db/migrations/20260627150737-flowcharts-table.ts.
flowcharts: id (PK), title, title_manually_set, data (the
{ nodes, edges, lanes } graph as JSON), is_deleted, created_at,
updated_at. Global per install (no account_id) and soft-deleted — every read
filters AND is_deleted = 0; the list query is
WHERE is_deleted = 0 ORDER BY updated_at DESC (backed by idx_flowcharts_active).
IPC channels (flowchart:*)
Defined in src/shared/ipc-channels/flowchart.ts; handlers in
src/main/ipc/flowchart-handlers.ts; Zod schemas in
src/shared/ipc-schemas/flowchart.ts; response types in
src/shared/ipc-response-map/flowchart.ts.
| Constant | Channel string | Purpose |
|---|---|---|
FLOWCHART_LIST |
flowchart:list |
list all non-deleted flowcharts |
FLOWCHART_GET |
flowchart:get |
fetch one flowchart by id |
FLOWCHART_CREATE |
flowchart:create |
create a blank flowchart |
FLOWCHART_SAVE |
flowchart:save |
persist the graph blob of an open chart |
FLOWCHART_RENAME |
flowchart:rename |
rename a flowchart |
FLOWCHART_DELETE |
flowchart:delete |
soft-delete a flowchart |
FLOWCHART_CHANGED |
flowchart:changed |
push — an external (agent) edit; refetch/reload |
Every request channel is registered in tests/integration/ipc-contract.test.ts.
Renderer
The panel mounts FlowchartEditor; state lives in the co-located Zustand store
(src/renderer/src/features/flowchart/flowchart-store.ts): the saved-charts list,
the open chart, load/save/rename/delete, and node/edge/lane mutations, with a
usePushListener on FLOWCHART_CHANGED (via useFlowchartPushEvents). The canvas
maps the stored graph to React Flow through flowchart-rf-adapter.ts; shapes come
from flowchart-shapes.tsx / ShapePalette. A flowchart-mermaid.ts helper
provides Mermaid export only (one-way and lossy — there is no Mermaid import;
positions, sizes, colors, and swimlanes drop, so never round-trip through it).
Key files
| What | Where |
|---|---|
| Migration | src/main/db/migrations/20260627150737-flowcharts-table.ts |
| Query layer | src/main/db/queries-flowchart.ts |
| IPC handlers | src/main/ipc/flowchart-handlers.ts |
| IPC channels | src/shared/ipc-channels/flowchart.ts |
| CLI control routes | src/main/services/cli/cli-server-flowchart-routes.ts |
| Session host (workdir) | src/main/services/flowchart/flowchart-session-context-provider.ts |
| Shared types | src/shared/types/flowchart.ts |
| Integration manifest | src/shared/integrations/flowchart.ts |
| Gating registry | src/shared/unreleased-features.ts (flowchart) |
| Renderer (store + UI) | src/renderer/src/features/flowchart/ |
Related
- Decks — mounts the same way: a docked panel beside the projects sidebar rather than a full-screen view, and the closest sibling in the sidebar.
Last verified 2026-09-23