Mind Max
A personal VS Code / Cursor extension that renders a Markdown file as a
navigable, editable mind map. You focus on one node at a time: the left rail
is the parent (upline), the right rail is the children (downline), and the
center is the current node's editable Markdown — with animated connectors
between them. A whole-file overview canvas and a DFS search round it out.
Scope: one file = one self-contained mind map. The heading hierarchy of
the currently open file is the whole tree. Links to other files are one-way
jumps, not part of the back-chain.
How a note becomes a map
- Inside a file, ATX headings (
#, ##, ###, …) define the hierarchy. A
heading's parent is the nearest shallower heading, so a ### directly under a
# (skipping ##) still nests correctly.
- Text before the first heading is the file root block (the map's center).
- Custom inline directives (their
( … ) argument may contain nested parens):
[image](https://github.com/Harrisous/MindMax/blob/HEAD/link) — renders the image inline. Relative paths resolve against
the file's folder; http(s) and data: URLs work too.
[note](https://github.com/Harrisous/MindMax/blob/HEAD/text) — a margin comment (Google-Docs style) anchored to its line.
The comment is the text; edit/delete it from the bubble. Plain text only
(not math-rendered).
[file](https://github.com/Harrisous/MindMax/blob/HEAD/link) — a right-rail jump card (red border + 📄) that opens
another file fresh as its own map. One-way: no parent/back-chain.
[hyper](https://github.com/Harrisous/MindMax/blob/HEAD/link) — a clickable 🔗 link pill below the center card; opens
another file at its main heading.
- Math:
$…$ (inline) and $$…$$ (display) render with KaTeX right in
the editor; the raw source is revealed when the selection touches the formula.
Using it
Run “Mind Map: Open” from the Command Palette and pick any workspace .md
(the last-opened file is pinned). The panel toolbar has:
- 📂 Open — re-target the panel at another file.
- 🗺 Overview — toggle the interactive whole-file canvas (below).
- 🔍 Find (Ctrl/Cmd + F) — search this file (below).
- − / 100% / + — zoom (also Ctrl + −/+/0 and Ctrl + mouse-wheel).
- Auto-save / Manual + Save — editing the center node writes back into
the exact byte range of the source file (auto = debounced ~400 ms). A file
watcher picks up external edits (the panel ignores its own writes for ~2 s).
Navigation: click a card, or use the keyboard — ← parent, → / Enter
focus child, ↑ / ↓ move the child selection, Alt + arrows works while
the editor is focused. The gold ⌂ top tab jumps to the file's root.
Add a child from the right rail: a heading in the same file, a brand-new
linked file, or a link to an existing file.
Overview canvas (n8n-style)
🗺 Overview shows the whole file as a tidy left-to-right tree you can edit:
- Click a node to re-center the tree on it (an ↑ back-node climbs up);
double-click to open it in the focus editor.
- Drag to reposition; drop onto another node to re-parent (migrate).
- Long-press (~400 ms) + drag moves a node with its whole subtree, drawn
cheaply as a circle showing the direct-child count.
- + / × (and the Delete key) add / delete heading nodes.
- ▤ Auto-arrange tidies the layout.
Structural edits (add / delete / migrate) are written back to the .md
(delete and migrate ask for confirmation). Node positions are remembered in a
sidecar <dir>/.mindmap/<base>.json and reloaded next time.
Search (Ctrl/Cmd + F)
The find widget runs a depth-first search over the current file and lists
the matching blocks in document order. Title and body are matched
(case-insensitive); each result shows its heading path and a context snippet.
Enter / ↓ steps to the next match, Shift+Enter / ↑ to the
previous, clicking a result jumps to it — each step focuses that block and
highlights the term in the editor. Esc closes.
Develop / run
npm install
npm run build # webview (Vite) + host (esbuild) -> dist/
Press F5 (uses .vscode/launch.json) to launch the Extension Development
Host with the examples/llm-intro/ demo folder open, then run “Mind Map:
Open”.
| Script |
What it does |
npm run build |
Build webview + host into dist/ |
npm run watch:host / watch:webview |
Rebuild on change |
npm run typecheck |
tsc --noEmit |
npm run smoke |
Headless checks: parser, outline, balanced-paren directives, markdown surgery, and DFS search |
npm run package |
Build a .vsix (needs @vscode/vsce) |
The GUI can't run in a headless environment — smoke covers the pure host
logic; the webview behaviors are verified by pressing F5.
Layout of the code
| Area |
Files |
| Extension host |
src/extension.ts, src/MindMapPanel.ts, src/workspace.ts, src/layout.ts |
| Parsing / graph / edits |
src/parser/parseFile.ts, src/parser/buildGraph.ts, src/parser/edit.ts |
| Shared (host + webview) |
src/shared/types.ts, src/shared/directives.ts |
| Webview shell (React) |
webview/App.tsx, webview/bridge.ts, webview/main.tsx |
| Webview components |
webview/components/Editor.tsx, Canvas.tsx, Connectors.tsx |
| CodeMirror extensions |
webview/cm/directives.ts, cm/math.ts, cm/search.ts |
| Styles |
webview/styles.css |
Protocol: the host owns the parsed model and answers webview messages
(navigate, save, requestOutline, saveLayout, createNode/deleteNode/
moveNode, search, openFile, home); it pushes back render, outline,
searchResults, and error. See src/shared/types.ts.
Settings
mindmap.autoOpen (default false) — open the map on startup if an
index.md is found in the workspace root.
mindmap.indexFile (default index.md) — file used by autoOpen.
The primary entry point is the “Mind Map: Open” picker, which works on any
.md regardless of these settings.
License
MIT.