---
title: Mind Map — notes, layers, AI and the internals (part 2)
---

# Mind Map — notes, layers, AI and the internals (part 2)

## What it is

This is part 2 of the [Mind Map](mindmap.md) 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](mindmap.md) — 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](mindmap.md) — opening a map, the library, and building one with the keyboard or the mouse.
- [kms.md](kms.md) — the other panel where your notes live, and where a map can be imported from.
- [artifact-sharing.md](artifact-sharing.md) — publishing something you made so it can be opened elsewhere.

