Omniscio documentation
Browse all documentation
  1. Getting Started13
  2. Sessions & Agents115
  3. Inbox & Notifications59
  4. Projects & Tasks95
  5. Automation & Scheduling75
  6. Knowledge & Memory26
  7. AI Features60
  8. Integrations100
  9. Plugins & Marketplace33
  10. Cloud & Teams56
  11. Settings & Customization58
  12. Account & Billing28
  13. Troubleshooting84
  14. CLI & API Reference22
  15. Legal & Policies4
  16. Uncategorised22

Mind Map — notes, layers, AI and the internals (part 2)

The second half of the Mind Map page: hidden notes attached to a node, drilling into a layer behind one, themes and layout, importing, exporting and sharing a map, the two AI features (which cost money), how a map behaves under your finger on a phone, and what is still rough.

What it is

This is part 2 of the Mind Map page. It covers everything around the map itself — the notes hidden on a node, layers, how the map looks, getting one in and out, the AI features, touch, and the parts still worth knowing about.

Where to find it

The same Mind Map panel as part 1 — all of this is reached from inside an open map.

How it behaves

Hidden notes on a node (annotations)

Any node can carry a note — a free-text comment that stays hidden on the canvas (it's not the node's label). It's for a side thought, a reminder, or a comment an AI agent leaves for you.

  • A node with a note shows a small note icon in its top-left corner (only nodes that have a note show it, so the map stays clean). Hover the icon to peek at the note (read-only); click / tap it to open an editable box.
  • Add or edit a note four ways — the icon, right-click → Add note / Edit note, the n shortcut, or (on a phone) the Note button in the action bar — for the selected node. Any node can have one, including the center "main" node.
  • In the editor: type your note (it can be multiple lines — Enter makes a new line), then Save or just click away to keep it; Esc or Cancel discards. Clearing the text and saving removes the note (the icon disappears).
  • Notes are undoable like node text (Ctrl+Z), travel with a node when you copy/paste it, and are included in the JSON export. (They're intentionally left out of the Markdown/Mermaid text exports and the public Share page.)
  • An AI agent can annotate for you. A session (or any tool driving Omniscio's local API) can set or clear a single node's note without touching the rest of the map — and if you have that map open, the note appears live.

Layers (a sub-map drilled in behind a node)

Any node can hold one layer — a full mind map of its own, anchored to that node. Think of it as flipping the node over to a fresh canvas: the rest of the map steps aside, you work on that node's layer, then flip back. It's how you tuck a detail-heavy sub-topic out of the main picture until you want it. One layer per node — pressing "layer" again on a node just takes you back into the layer it already has; it never piles a second blank one on top. To go deeper, nest: a node inside a layer gets its own layer.

  • Open a node's layer — select a node and press l. If it has no layer yet, a fresh blank one opens with its root in edit mode, ready to type; if it already has a layer, this drops you straight back into it. (No second blank layer is ever stacked.)
  • Flip in and out — ] / [ toggle between the base map and the selected node's layer.
  • See which nodes have a layer — a small layer badge sits at a node's top-right whenever it has one (distinct from the collapse-count circle). Tap the badge to open the layer — so it works on a phone with no keyboard.
  • Know where you are / get back out — while you're inside a layer, a slim bar at the canvas's top-left reads "In a layer" (with a Layers icon) and a Map link straight back to the main map, plus a back button and a crumb per drill step (e.g. In a layer · Map › Plans › Q3). So a blank sub-canvas never looks like your map vanished — it's clearly a separate layer, one click from home. On a plain (un-drilled) map the bar isn't shown at all.
  • Remove a layer from the trail — middle-click a crumb to delete that layer. If the layer has more than one node it asks you to confirm first; a nearly-empty layer goes instantly, and Ctrl+Z brings it back. ("Map" isn't a layer so it can't be removed; a normal left-click still just jumps to that depth.)
  • Nest freely — a node inside a layer has its own single layer, and so on, so you can drill as deep as a topic needs.
  • Saving & undo — layers live inside the same saved map (nothing extra to manage; deleting or copy/pasting a node carries its layer along). Anything you build inside a layer saves right away — even on a brand-new map you haven't named yet. Undo is per-view: Ctrl+Z undoes what you're looking at, and moving in and out of layers never loses history.
  • No clutter — open a layer, change your mind without typing anything, and the empty layer removes itself (and its badge) when you leave, so blank layers never pile up. A map that never uses layers is byte-for-byte the same as before.

Layers are bounded by generous guardrails — one layer per node, 12 levels of nesting, and a 20,000-node budget across a map's layers. You won't hit the nesting or node limits by hand; they exist so a runaway or malicious import can't blow up the app.

Look & layout (themes, direction, background)

  • Color mode button cycles Light / Dark / Follow-app (default Follow-app).
  • Visual theme picker restyles the whole mind-map view — sidebar, header, canvas — with any of the app's 13 built-in themes, without changing the rest of the app. Both are global view preferences (the per-map override is set from the toolbar; the global defaults live in Settings → Appearance → Mind Map).
  • Flow-direction button rotates the map through the four directions; the choice is saved per map.
  • Tidy columns — nodes at the same level line up on the edge nearest the center (their left edges in the default left→right view; right / top / bottom in the other directions), so a column of different-width boxes reads as one clean line rather than a ragged stack. It's automatic — the widest box in a column anchors the line and the narrower ones slide in to meet it.
  • Dotted-grid background toggle (on by default, remembered).
  • The floating zoom controls in the canvas's bottom-right corner (the +/− and fit-to-view stack) wear the same glassy "bubble" look as the nodes — a translucent, softly-shadowed panel that recolors with the active theme (and frosts on the glass themes) — so they read as part of the map rather than a separate widget. They sit bottom-right so they stay clear of the bottom-left "Press ? for shortcuts" hint. Their behavior is unchanged.
  • Smooth node motion — whenever the map rearranges (dropping a node on a new parent, adding/deleting, collapsing/expanding, flipping direction, undo/redo, or a drag that snaps back), the nodes glide to their new positions in a short (~180ms) ease instead of jumping. The node you're actively dragging still tracks your cursor exactly — the glide only plays as things settle. It switches off automatically on very large maps (to stay fast) and when your system reduce-motion / low-power setting is on.

Import, export & sharing

The toolbar's low-frequency actions are grouped into labeled dropdown menus so the bar stays uncluttered — map creation/import under a New menu, AI under an AI menu, and the formats below under an Export & Share menu — while the everyday view controls (fit, zoom, dotted background, flow direction, color mode, theme) stay visible on the bar. The Export & Share menu re-imports and exports several formats:

  • JSON — the native format (Import / the JSON export), fully re-importable.
  • Markdown outline — the Markdown export writes an indented - bullet list (.md); Import outline turns a pasted indented list (or a .md file) back into a map, with several top-level items getting one synthesized root.
  • Mermaid — View as Mermaid opens a read-only panel with a rendered picture (when small enough), copy-able source, and a .mmd download. Pasting a Mermaid mindmap (or opening a .mmd/.mermaid file) is auto-detected and becomes an editable map.
  • PNG — a raster image of the canvas.
  • Share — publishes a self-contained, interactive, read-only web page (an HTML+SVG view, mobile-friendly, themed to match the map). The viewer can zoom (scroll-wheel / pinch / on-screen + / −), pan (drag), tap a node to fold or unfold its branch, Fit to re-frame, Expand all (a button that appears once they've folded something, then re-opens every branch and re-fits the view), and switch light / dark with an on-page sun/moon button — all from one small inline script (no external libraries), and the page renders full-screen. It opens fitted to the whole map and can be pulled back to about half that size for breathing room before it stops (bounded — it never shrinks to an unreadable blob). Folding is by tapping the node (there is no per-node fold "circle" — that affordance was removed so the page matches the canvas). The page carries the map's own theme colors (the surface palette + accent), read from the app's live theme at share time so the baked page can't drift from a hardcoded list, and opens in the map's chosen color mode — falling back to the viewer's device setting, then a neutral palette if a theme can't be read. The share runs its own JavaScript because an html artifact's runnable doc is served under sandbox allow-scripts (the React-artifact mechanism); the only viewer-controlled bytes (node text + title) stay XML-escaped, and every theme color is validated as a plain R G B triplet before it reaches the page. An existing link is a snapshot of the map at share time — re-share to update it. The page now ships the whole map fully expanded: branches you collapsed in the editor are included and open by default, so collapsing no longer hides anything from a viewer (it only sets your own editor view). A viewer can fold branches themselves and then Expand all to reopen everything.

AI assist (uses Claude — billable)

Both live in the toolbar's AI dropdown menu.

  • Expand with AI asks Claude to brainstorm a handful of child ideas for the selected node and inserts them (undoable).
  • Generate map with AI turns a typed topic into a whole starter map.

Both need an API-key account (an OAuth-only login can't call the model API → a friendly "add an API key" message), use the cheap Haiku model, and are bounded by a daily spend cap (mindmapAiCostCapUsd, default $1).

AI sessions (a chat that reads & edits your map)

A "Maps / Sessions" tab at the top of the saved-maps list opens a list of AI chat sessions for mind maps — the same session experience as the rest of Omniscio (Needs You / Live / Paused / … sections, a "+ New session" button, and the right-click pause / rename / archive / snooze menu). It reuses the shared session-host seam (the same one the SMS and KMS Sessions tabs use).

  • "+ New session" (shown when a map is open) starts a Claude session that already knows the open map and can read and rewrite it for you — ask it to brainstorm, reorganize, expand a branch, summarize, or tidy up. It edits through Omniscio's validated internal /mindmaps API (so it can never save a broken map) and waits for your instruction rather than editing on its own. Unlike "Expand / Generate with AI", this uses your chosen session model, not the capped Haiku.
  • Opening a session opens a split view (desktop): the map on one side, the chat on the other, resizable, so you watch the agent rebuild / expand / reorganize the map live as you talk to it. A Split toggle on the Maps/Sessions strip collapses to chat-only (and re-expands) — auto-split is on by default (mindmapSessionSplit); your divider width is remembered. On a phone the chat replaces the map (too narrow to split); the map auto-saves and is one tab away.
  • When the AI changes the map, the open editor refreshes live and the change stays undoable (Ctrl+Z reverts the AI) — this is what makes the split view show edits as they happen. If you're actively editing a node, your edit wins (last-writer-wins for that rare overlap).
  • The sessions live in a hidden internal __mindmap__ project (never a sidebar row); each session is bound to the map it was started from.

On a phone (touch)

Mobile always opens full-screen. With no keyboard, the editor shows an on-screen action bar at the bottom — Add child, Add sibling, Rename, Note (add/edit the node's hidden note), Delete, Cut / Copy / Paste (Cut/Copy show only with a non-root node selected; Paste shows only once you've copied something), Collapse/expand, Expand all (an extra button that shows only while a branch is collapsed), Undo, Redo — wired to the same actions the keyboard and the desktop right-click menu use. The bar scrolls sideways so every button stays reachable. Add child and Add sibling carry distinct icons that picture where the new node lands — a + nested down-and-right for a child, straight below for a sibling — so you can tell them apart at a glance (a phone has no hover tooltip to lean on). The saved-maps list opens as a bottom-sheet drawer. Pan, pinch-zoom, tap-to-select, and drag-to-re-parent work on the canvas — a long-press just grabs the node to drag it; it does not pop a menu (the desktop right-click menu would collide with the drag, so on a phone Cut/Copy/Paste live on the action bar instead). In the saved-maps drawer a long-press behaves the opposite way — there's no drag to collide with, so press-and-hold a map row opens its Rename / Delete menu (the row has no trash button to tap). Editing a node slides it above the on-screen keyboard so the box you're typing into is never hidden behind it. You reach Mind Map from the account menu (the entry appears only when the feature is on).

Limitations / known issues

  • Gated / in-development — hidden until a developer flips it to shipped.
  • A published share link is a frozen content snapshot — the page itself is interactive (pan / zoom / fold / Expand all), but the map data is captured at share time, so re-share to push later edits.
  • The shared page is always laid out left→right regardless of the map's flow direction (honoring the map's direction is a planned follow-up).
  • Touch and drag gestures are unit-tested but not automated end-to-end (a real touchscreen can't be emulated in the test harness) — they get a manual check.
  • AI needs an API-key account (OAuth-only logins can't call the model API), and is capped at $1/day by default.
  • An agent can do everything you can, except take the in-app PNG. As of 2026-09-08 the CLI covers the whole feature: list, read, create, import, save, rename, delete, export (JSON / Markdown / Mermaid / PNG), open, annotate a node, write a whole map with AI (POST /mindmaps/generate), expand one node with AI (POST /mindmaps/:id/nodes/:nodeId/expand), and publish the share page (POST /mindmaps/:id/share, which hands back the public link). Themes, flow direction, folds and layers have no route of their own — they live inside the map's saved data, so an agent changes them by saving the map. The one thing that stays in-app is the PNG taken from the live canvas; the CLI's format=png renders the share page instead, which is always the fully-expanded map.
  • 2000-node cap per map; the Mermaid picture is officially experimental and degrades to text when a given map can't render.

For agents

How it works (internals)

  • Feature folder: src/renderer/src/features/mindmap/ — the canvas (MindMapCanvas.tsx), node (MindMapNode.tsx), toolbar, and the Zustand store (mindmap-store.ts). Every structural edit routes through the store's one commit() chokepoint (which pushes undo history and schedules the debounced save); auto-layout is layout.ts (d3-hierarchy → screen axes per direction). Horizontal (left→right / right→left) sibling spacing keeps a constant visible gap — a d3 separation sets each pair's center-to-center distance to their half-heights plus a fixed edge gap, so the whitespace you see between two stacked boxes is the same no matter how tall either one is (only the center distance grows to clear a taller box); a single-line pair stays at the original 40px gap (byte-for-byte). On the canvas the heights come from the browser's real text measurement (measureText, via mindmap-node-size.ts), so the gap is constant in rendered pixels; the share page and PNG use the shared char-estimate. Vertical (top→bottom / bottom→top) layouts use the same constant-visible-gap idea on the WIDTH axis, tuned so a vertical map's gaps match a horizontal map's: a sibling pair sits its half-widths plus a fixed edge gap apart (the same 10px whitespace horizontal uses), so narrow nodes sit tight and only a wide node spreads (just enough to clear); different-parent branches get a wider gap to set them apart (the same as horizontal's branch gap). Like horizontal, the canvas measures each node's real width so the gap stays a true constant on screen (off-DOM — the share page and tests — falls back to the char-estimate). (Before, vertical maps were spaced ~2× looser than horizontal — the reported "way too spread out".) Nodes are center-anchored (React Flow nodeOrigin = [0.5, 0.5], the shared NODE_ORIGIN_CENTER constant), so a parent and a node stacked directly above/below it line up on center and the connector between them is a straight line regardless of the boxes' widths (a parent that fans out to several children keeps the gentle curve). The shared/exported web page centers its boxes the same way, and the PNG export frames that same center-anchored geometry — see invariant 61 in the contract. On top of that, same-level siblings align on their INNER edge — the edge facing the root (left edges in left→right, right in right→left, top/bottom for the vertical directions) — so a column of differently-sized boxes reads as one clean line instead of a ragged one. layoutGroup shifts each node toward the root along the growth axis by half its shortfall from the column's widest/tallest node; the widest/tallest box doesn't move and equal-size columns are byte-identical, so no overlap is introduced. On the canvas the shift uses each node's real rendered width (the browser's own text measurement, measureText), so the edges line up to the pixel — a character-count estimate can't, because a proportional font draws every letter a different width (the share page and PNG keep their own fixed box width, which already matches what they draw). This shift is on the depth (growth) axis only — orthogonal to the cross-axis that makes the stacked connectors straight, which is why both hold at once (invariant 63). The share page and PNG inherit it for free (they read the same laid-out positions).
  • Node-snap glide: mindmap-anim.ts owns the animation — a pure shouldAnimatePositions gate (off above MM_ANIM_MAX_NODES = 300 visible nodes, so the 2000-node path pays nothing) plus a useAnimationWindow hook that arms a short class window. The canvas adds mm-animate-positions during that window — armed by the [data] reflow effect for store-driven changes, and synchronously in onNodeDragStop for the snap-back / no-op case + same-paint timing — and a CSS transition: transform on .react-flow__node:not(.dragging) (globals.css) animates the move. Killed under prefers-reduced-motion + html.low-power; layout output is byte-identical (invariant 57 in the contract).
  • Selection is O(changed nodes), not a re-layout: the d3 layout + structural node derivation is deriveBaseNodes, memoized on [data, spacing, fontSize, balance] — NOT selection. Selecting or arrow-navigating only flips the selected/editing flag on the ≤2 affected nodes through the reference-stable withSelection overlay (the twin of the drag withLockOn), and MindMapNode is React.memo'd — so the other nodes skip re-render and no layout runs on a selection. On a big map that's the difference between repainting ~2 nodes and re-laying-out + repainting the whole map (the old code re-ran the full layout twice per selection — the render effect AND the auto-pan reveal). The auto-pan reveal reads the SAME memoized base positions (posById), so the view can never glide to coordinates that disagree with what's drawn. See invariant 71 in the contract.
  • Data model: a mindmaps SQLite table (id, title, a JSON data blob of nodes, soft-delete flag, timestamps). A map is one rooted tree, capped at 2000 nodes, validated for a single root and no cycles on every save (src/shared/mindmap-structure.ts).
  • Node notes: an optional note?: string on each node (inert-when-unused, like side/layers; bounded by MAX_NODE_NOTE_LEN at the Zod boundary AND the layer normalizer). The store's setNodeNote routes through commit() (undoable + autosaved, root allowed, blank clears); the popover open-state is notePopoverId (mirrors editingId, pauses the canvas keyboard). The icon + hover-peek live in MindMapNode.tsx; the editor is MindMapNoteEditor.tsx (reuses AnchoredPopover). The AI writes one node's note via PATCH /mindmaps/:id/nodes/:nodeId (read-modify-write the blob, emits MINDMAP_CHANGED). Full invariants + tests: the mind-map contract.
  • Layers (one sub-map per node): a node carries an optional layers array (each entry { id, data }, data a full MindMapData) holding at most one layer. The store holds rootData (the whole map) plus a layerPath (the drill trail); activeData is always the projected view at that path (projectView in layer-nav.ts), so every existing structural action, undo/redo, and the autosave operate on the view and commit folds it back into rootData — one global undo timeline regardless of depth, and a layer-free map projects to itself byte-for-byte. addLayerToSelected is enter-if-exists (it drills into a node's existing layer rather than stacking a second). Persistence + JSON/CLI import run through the iterative, depth-/visit-bounded normalizer in src/shared/mindmap-layers.ts, which enforces one-layer-per-node by collapsing to the content-bearing layer (deep mindmapDataHasRealContent, never a blind drop) and caps nesting at 12 deep / a 20k-node budget; the Zod .max stays a generous parse tolerance (its .catch would bulk-drop a node's layers, so the real 1-cap lives in the normalizer). The same content walk powers isDraftBlank, so a fresh unnamed map with content only inside a layer still promotes + saves. The node's layer badge and the mindmap-layer-breadcrumb bar are the only new UI surfaces.
  • IPC: mindmap-handlers.ts exposes list/get/create/save/rename/delete, import / import-outline / export-file, and the two billable AI channels (mindmap:ai-expand, mindmap:ai-generate). Pure conversion modules are shared: mindmap-markdown.ts and mindmap-mermaid.ts. The share page is generated by share-html.ts.
  • Deep link + CLI create: an omniscio://mindmap/<id> link (built by mindmapDeepLink in src/main/services/deep-link.ts) opens a specific saved map in-app — both the protocol/deep-link path and the in-chat clickable link funnel through ONE renderer chokepoint (src/renderer/src/lib/open-mindmap-by-id.ts): feature-gate → store.openMap(id) → the existing open-mindmap reveal event, with a "map not found" toast on a deleted map. It NAVIGATES only — never mutates. The CLI create/import/get routes hand that link back as a url field so an agent can give the user a one-click link, and POST /mindmaps additionally accepts a nested { text, children } tree for a one-shot structured create (flattened ITERATIVELY in src/shared/mindmap-tree.ts, then the same validateMindMapStructure).
  • AI sessions (session-host): the "Sessions" tab is useMindMapSessionHost (mindmap-session-host.ts) + the shared SessionHostSidebar; sessions spawn into the hidden, spawnable __mindmap__ virtual project (seeded by ensure-mindmap-project.ts, hidden by filterVisibleProjects). The agent reads / edits via the /mindmaps CLI routes; each mutating route emits MINDMAP_CHANGED, which useMindmapPushEvents → applyExternalMindmapChange turns into a live, undo-preserving reload of the open map. See .claude/memory/contracts/session-host-contract.md.
  • Gating: registered in src/shared/unreleased-features.ts as mindmap (status: 'in-development'); the UI gates only through isUnreleasedFeatureVisible / the Optional Features toggle / AMC_SHOW_MINDMAP. Headless CLI routes (/mindmaps/*, read + non-AI mutations) return 404 when the feature is off and never expose the billable AI actions.

Mind Map skill (/mind-map)

A bundled Claude Code skill that generates a mind map from source material -- vault notes, local files, or Google Docs. Instead of dumping raw data into the import endpoint (which produces an unusable flat list), the skill interviews the user about scope, angle, and depth, synthesizes a properly structured Markdown outline, validates it against node/depth budgets, and creates the map via the CLI.

How to use it

In any Claude Code session, invoke it with:

/mind-map

(or say "make a mind map from my vault notes about X", "mind map from this file", "visualize as mind map", or similar). The skill walks through these steps:

  1. Feature gate -- checks whether Mind Map is enabled; if not, enables it automatically (or directs you to approve it in your inbox if approval-gated).
  2. Source resolution -- reads vault notes (/kms/search + /kms/notes/:id), local files (Read tool), or Google Docs (via /gog skill).
  3. Interview -- asks up to 4 questions (source, angle, depth tier, preview preference), skipping any the user already answered. Never guesses.
  4. Synthesis -- builds a Markdown outline following structural rules: 5-7 top branches, 2-6 word labels, rolled-up counts instead of flat lists.
  5. Validation -- six-point checklist (node count, depth, label length, single-child branches, fat branches, root check). All must pass.
  6. Preview -- shows the outline if the user opted in; accepts approve, change, or reject.
  7. Creation -- imports the outline via POST /mindmaps/import, renames the map, and populates hidden annotations for rolled-up detail.

Depth tiers and limits

Tier Typical nodes Typical levels When to use
Overview 15-25 3 Presentations, quick summaries
Standard 25-40 4 Most maps (default)
Detailed 40-100 5-10 User must request this tier

Hard ceilings: 100 nodes, 10 levels. These are never exceeded without explicit user instruction.

What it does NOT do

  • Pick layout direction (that is a canvas setting the user controls).
  • Use the built-in AI expand/generate endpoints.
  • Modify existing mind maps (always creates a new one).
  • Spawn additional sessions.

The skill file lives at .claude/skills/mind-map/SKILL.md.

Related

  • Mind Map part 1 — opening a map, the library, and building one with the keyboard or the mouse.
  • kms.md — the other panel where your notes live, and where a map can be imported from.
  • artifact-sharing.md — publishing something you made so it can be opened elsewhere.

Last verified 2026-09-23