MindMap Studio

by 冬季蚊子
5
4
3
2
1
Score: 51/100

Description

在Obsidian中将Markdown笔记渲染为思维导图,并实现更改导图回写Markdown。Render Markdown notes as mind maps in Obsidian and enable writing back changes made to the mind map to Markdown.

Reviews

No reviews yet.

Stats

4
stars
288
downloads
0
forks
28
days
0
days
0
days
0
total PRs
0
open PRs
0
closed PRs
0
merged PRs
1
total issues
0
open issues
1
closed issues
132
commits

Latest Version

7 hours ago

Changelog

中文 | English

0.1.7 是一次可靠性与工程门禁版本:修复「节点文本编辑失败毫无反馈」「工具栏图标尺寸兜底压掉主题变量通道」两处缺陷,补上两处此前从未被类型检查覆盖的真实类型错误;同时完成一轮性能去平方(数学公式重排的节点反查)与工程门禁收紧——三个发布相关配置纳入 tsc、依赖矩阵与文档清单纳入机械校验。无破坏性变更(.mindmap.md 格式、命令 ID 与设置项均未变)。

  • 节点文本编辑失败不再毫无反馈:在弹窗中编辑节点文本时,若底层操作失败,此前 Promise 拒绝被静默吞掉——用户点了「在弹窗中编辑」却毫无反应,也无法判断是自己操作有误还是插件出错;现在会弹出明确提示,且不触碰写回与保存通道(引擎状态、保存调度均保持原样,不会写入半成品)
  • 工具栏图标尺寸兜底不再压掉主题变量通道:图标尺寸此前依赖官方内部类名消费 --icon-size 变量;新增的自包含兜底规则 specificity 高于官方规则,若把尺寸写死就会连变量通道一起覆盖,导致「跟随官方尺寸体系 / 允许用户与主题覆盖」的设计失效。现走 var(--icon-size, 16px):变量在位时跟随变量,官方改名致其不再消费时回落到 16px,两条失效路径都兜住
  • 依赖矩阵的一处类型逃逸:ModuleGroup 联合类型遗漏了 domain,而 9 个模块边界块中有 8 个把 domain 列为允许依赖——该声明此前完全逃过类型检查。已补入类型(并明确标注「禁止跨组导入」清单有意不含 domain,否则会与依赖矩阵语义相反)
  • LICENSE 校验器的 8 处类型违规:plain-text-parser.mjs 此前不在类型检查视野内,其行级 token 形状是无约束的 Record<string, unknown>;现已补上精确形状定义,token 字段名一并纳入门禁
  • 数学公式重排的节点反查从平方级降为线性:含行内公式的导图在公式定稿后需把每个公式元素反查回所属节点以重排尺寸,此前逐个元素各走一遍全树遍历(元素数 × 节点数);现改为一次遍历建「节点 → DOM 组」映射、逐元素沿祖先链查表,复杂度 O(节点数 + 元素数 × 祖先链深度)。查表未命中时逐个回落原全树扫描(宁可慢、不可错),覆盖引擎在建表后重渲染的情形
  • 段落文本不再重复拼接:Markdown 解析时同一份段落内容此前拼接两遍(显示文本与解析期快照各一次),现复用同一字符串
  • 三个发布相关配置纳入类型门禁:eslint.config.mts / stylelint.config.mjs / manifest.json 现在参与 build 前置的类型检查(manifest.json 的 JSON 语法错误在构建期即被拦下,不必等到发布扫描),并因此退役了 ESLint 的「默认工程」兜底配置
  • 模块解析切到 bundler:旧选项在 TypeScript 6 起被标记弃用、7 将移除,编辑器会持续报错。实测对现有 400+ 处无扩展名导入零改动通过;同时明确不使用「忽略弃用警告」的静音开关——它在当前锁定的 TypeScript 版本下反而会报配置错误并真的阻断构建
  • 文档清单校验覆盖子目录:AGENTS.md 的 docs/ 清单此前只校验顶层文件,docs/agents/ 下的详录虽已登记却从不被检查——指向不存在的文件无人拦截。现已纳入
  • 依赖与配置的显式声明:死代码检查补上项目文件边界(结论与原推断一致,零残留);写盘失败回调改用函数类型属性,类型层面即无隐含 this,日后传入未绑定方法引用仍会被拦下
  • AGENTS.md 重构为索引 + 详录:主文件 1628 行 → 183 行,保留硬规则(Don't/Do 配对)、决策表、编号工作流、命令表与索引;112 条设计约定与架构/测试详录迁至 docs/agents/ 四份文档。未登记的超限文件数只允许递减这一约束不变
  • 行数统计口径统一:此前文档登记值与实测的「差异」实为两套统计口径不同所致;现已统一为校验脚本的口径,并在文档中标注了不要用 PowerShell 统计行数
  • 测试全量 60 文件 / 1820 例(0.1.6 为 58 / 1765)
  • 文档:README 中英双语补齐快捷键表(搜索、撤销/重做、编辑、删除、适应画布、缩放到选区,含各自的让位条件);开发环境要求 Node 20+
  • 需要 Obsidian 1.13.0+,仅桌面端;.mindmap.md 格式、命令 ID 与设置项均未变更——纯修复 / 性能版本,无需迁移
  • ⚠ 本轮 styles.css 有变化(新增图标尺寸自包含兜底规则),更新时需同时替换 main.js 与 styles.css,不能只换 main.js
  • 无新增设置项、无新增第三方依赖

  • Editing node text no longer fails silently: when editing a node's text in the modal, a failed underlying operation used to be swallowed — the command appeared to do nothing and there was no way to tell whether the input was rejected or the plugin failed. It now shows an explicit error, and the write-back and save channels stay untouched (engine state and save scheduling are left alone, so no half-finished content is written)
  • The toolbar icon-size fallback no longer overrides the theme variable channel: icon sizing previously relied on an Obsidian-internal class name to consume the --icon-size variable. The new self-contained fallback rule is more specific than the official rule, so a hard-coded value would suppress the variable channel too — defeating the "follow the official sizing / let users and themes override it" design. The value is now var(--icon-size, 16px): it follows the variable when present, and falls back to 16px if the official class is renamed and stops consuming it, so both failure paths are covered
  • A type escape in the dependency matrix: the ModuleGroup union type was missing domain, although 8 of the 9 module boundary blocks list it as an allowed dependency — the declaration was therefore never type-checked. The type is fixed (with an explicit note that the "forbidden cross-group import" list deliberately excludes domain, which would otherwise invert the dependency matrix)
  • 8 type violations in the LICENSE checker: plain-text-parser.mjs was outside the type-checked surface, so its line-token shape was an unconstrained Record<string, unknown>. A precise shape is now declared, which also brings the token field names under the gate
  • Node lookups during math re-measurement go from quadratic to linear: after inline formulas settle, a mind map with formulas must map each formula element back to its owning node to re-measure layout. Each element previously triggered its own full-tree walk (elements × nodes). It now builds a node → DOM-group map in a single traversal and walks each element's ancestor chain, giving O(nodes + elements × depth). Elements that miss the map fall back individually to the original full-tree scan (slower but never wrong), which covers cases where the engine re-renders after the map was built
  • Paragraph text is no longer concatenated twice: Markdown parsing previously joined the same paragraph content twice (once for display text, once for the parse-time snapshot); the same string is now reused
  • Three release-related configs are now type-checked: eslint.config.mts / stylelint.config.mjs / manifest.json take part in the type check that precedes build (so a JSON syntax error in manifest.json is caught at build time rather than at release scanning), which also retired ESLint's "default project" fallback configuration
  • Module resolution moved to bundler: the old option is deprecated from TypeScript 6 and removed in 7, so editors report it continuously. Verified to pass with zero changes to the 400+ extension-less imports; the "ignore deprecation" silencer is deliberately not used — on the currently pinned TypeScript version it raises a configuration error and genuinely blocks the build
  • The docs manifest check now covers subdirectories: the docs/ list in AGENTS.md previously validated top-level files only, so the detailed records under docs/agents/ were registered but never checked — a pointer to a non-existent file went unnoticed. They are now covered
  • Explicit declarations for dependencies and config: the dead-code check now declares project file boundaries (the conclusion matches the previous inference, with zero findings); the save-failure callback is declared as a function-typed property, so there is no implicit this at the type level and passing an unbound method reference would still be caught
  • AGENTS.md refactored into an index plus detailed records: the main file went from 1628 to 183 lines, keeping hard rules (paired Don't/Do), a decision table, numbered workflows, a command table and an index; the 112 design conventions plus architecture/testing details moved into four documents under docs/agents/. The existing constraint stands — the number of over-limit files without a registered exemption may only decrease
  • Line-count measurement unified: the previously reported "discrepancy" between registered and measured values was in fact two different counting conventions. Everything now uses the validation script's convention, and the docs note that PowerShell's line count should not be used
  • Full suite: 60 files / 1820 cases (0.1.6: 58 / 1765)
  • Docs: the Chinese and English READMEs gained a keyboard-shortcut table (search, undo/redo, edit, delete, fit to canvas, zoom to selection, including when each one yields to Obsidian); development now requires Node 20+
  • Requires Obsidian 1.13.0+, desktop only; the .mindmap.md format, command IDs and settings are unchanged — a fix/performance release with no migration needed
  • ⚠ styles.css changed in this release (a self-contained icon-size fallback rule was added). Update both main.js and styles.css — replacing only main.js is not enough
  • No new settings, no new third-party dependencies

README file from

Github

English | 中文

🧠 MindMap Studio

Mind map rendering for Markdown inside Obsidian. Open .mindmap.md — a normal Markdown file — and edit it as a mind map; the Markdown outline round-trips. Powered by the simple-mind-map engine, developed by WinterMosquito.

🚀 Quick start

  1. Create: run Create new mind map (command palette or ribbon) — name it (default = prefix + date); the MindMap2026-09-06.mindmap.md file is created and opens as a mind map.
  2. Edit: the file is ordinary Markdown, so its outline becomes the map — add/edit/delete nodes, drag to rearrange, attach images or links.
  3. Back & save: use Switch to Markdown to return anytime; edits are written back to the file (layout & viewport live in the plugin's data.json).

A .mindmap.md note shown as a mind map in Obsidian

✨ Why MindMap Studio

The plugin is a rendering layer, not a file-format converter. .mindmap.md files are 100% standard Markdown — your notes, links, backlinks, search and Git all work as usual. A Markdown outline is parsed into a mind map; when you edit the map, the changes are written back as Markdown.

🚀 Features

  • Markdown-native: .mindmap.md is ordinary Markdown (headings + lists). No proprietary format.
  • Round-trip fidelity: unedited lines are written back verbatim (frontmatter preserved; blank lines between paragraphs and standalone --- separators are normalised); headings #–###### map to node levels 1–6, nested lists to deeper levels.
  • Obsidian-native wikilinks: [[note]] shows as its link text, with hover preview and graded modifier clicks (matching Obsidian): plain click = current tab, Ctrl/Command+click = new tab, +Alt = new tab group, plus Shift = new window; the add-link dialog searches notes and other documents (.canvas / .base) plus non-image vault files (attachments); images go through Add image. Links whose target does not exist yet render in a muted colour (like Obsidian's reading view), resolved by the plugin from Obsidian's metadata cache; hover/click is left to Obsidian core (no pre-check on that path). New document links follow Obsidian's own settings: with Use [[Wikilinks]] on (the official default) they are written as [[wikilinks]] (keeping the dedicated document icon); with it off they are written as [label](path.md), and the path form follows New link format. Attachments and images always keep the wikilink embed form (![[report.pdf]] / [[archive.zip]]). A node shows the alias (the note name when there is none); editing the text of a pure wikilink node edits that alias and writes back [[note|new alias]]. Attaching a wikilink — dropping a vault file (notes / images / attachments, any type) onto the node, or picking one in the add-link dialog — turns a completely empty node into a pure wikilink by writing the link's display name as its text; a node that already has any content (text, an image or an existing link — a pure-wikilink node included) keeps it, and the new link becomes a child node. A URL on its own node stays icon-only (no text).
  • Rich node content (clickable links + inline syntax): links inside a node render as clickable text — click to open, Ctrl/Command+click for a new tab (+Alt for a new tab group, plus Shift for a new window); every link on a line is clickable (no longer only the first one). Hover preview has two levels: hovering a specific link text previews that link (important for multi-link lines and when the first link is an external URL), while hovering anywhere else on the node previews the link the node carries (vault targets only). A URL mixed with other content is shown as a clickable address instead of a bare icon. Inline syntax renders inside nodes the way Obsidian's reading view shows it: **bold** / __bold__, *italic* / _italic_, `inline code` (including double-backtick spans), ~~strikethrough~~, ==highlight==, ***bold italic***; inline math $…$ renders via MathJax and a single-line $$…$$ renders as a block (centred) formula (falls back to the literal text until loaded; multi-line block math stays literal); \*escaped\* / \$ consume the backslash and show the literal character, and %%comments%% are hidden inside the node (kept in the file; a line that is nothing but a comment stays literal). The raw text stays verbatim in the file; links inside paragraph (multi-line) nodes are clickable too. Very long nodes (> 2000 chars) show the beginning plus … (with a hover explanation) — the full text stays in the file, which also keeps oversized text from slowing the canvas down. Double-clicking such a node edits the actual line from the file (wikilink, URL and inline syntax stay visible and editable).
  • Images: vault image suggestions, uniform sizing, ![[path]] round-trip; drag the corner handle to resize a node image — the size is written back as Obsidian's official embed syntax (![[img.png|300]] width-only, |300x150 explicit, ![alt|300](https://raw.githubusercontent.com/wintermosquito/Obsidian-Mindmap-Studio/HEAD/url) for external images); clear a node's text and the node becomes image-exclusive — an image-exclusive node has no text, so node search never matches it. Inline images also render in text/paragraph nodes (its first line; links inside a paragraph are clickable too, see above).
  • Opens at 100% with the whole map centred; Fit to canvas zooms out for an overview and Reset zoom returns to 100% while keeping the visible content in place (auto-arrange ends with fit-to-canvas); six layouts (switching a layout auto-arranges and fits the map) with per-file connector styles (Auto follows the layout; curve / direct / elbow — switchable for Logical structure / Mind map / Organization chart; the other three are fixed-straight and show Auto), node search, auto-arrange, performance mode for large maps, fast text node rendering (every text node is rendered by the plugin — large maps open several times faster; double-click then opens the edit dialog, see Settings), PNG export; assisted drag reparenting — drop near a node's center to nest as its child, or between two siblings to insert in between (with live highlight).
  • Persistence: layout, viewport and "open as" preference are kept per file (in plugin data), surviving reopen, rename, and view switching.
  • Central node ↔ filename: editing the central node renames the .mindmap.md file (Obsidian updates links/backlinks).

📖 Usage

1) Create & open a mind map

  • Run Create new mind map (command palette or ribbon) → a naming dialog appears (default = prefix + date; duplicates get a numeric suffix) → the MindMap2026-09-06.mindmap.md file is created and opens in the mind-map view.
  • Any .mindmap.md file opens from its context menu → Open as mind map (or the same command), and goes back via Open as Markdown. The view you chose is remembered.
  • The command palette also lists Create mind map in current folder, Search nodes, Fit to canvas, Arrange mind map and Export as PNG — the same actions as the toolbar.

2) How Markdown becomes a map

Every .mindmap.md is 100% standard Markdown — the plugin renders it as a mind map and writes your edits back:

# Project plan              ← central node (= file name)
## Goals                    ← first-level child node (#)
- Milestone 1               ← child node (list)
- Milestone 2
###### Details              ← level-6 heading
- Seventh-level item        ← list nested under a heading → level 7

#–###### → node levels 1–6 · nested lists go deeper · [[note]] / [[note|alias]] → clickable link (the node shows the alias) · bare URLs → clickable address · inline syntax renders inside nodes (**bold** / __bold__, *italic* / _italic_, `inline code`, ~~strikethrough~~, ==highlight==, ***bold italic***; $…$ inline math and single-line $$…$$ block formulas render via MathJax; \*escaped\* / \$ show literally and %%comments%% are hidden — a comment-only line stays literal) · ![[img]] → image (|300 sets the size) · paragraphs & fenced code stay as text (links inside paragraphs are clickable too).

Non-image embeds such as ![[report.pdf]] on a node of their own are shown as an attachment icon: click the icon, or Ctrl/Command+click the node, to open it (PDF, audio, video); hovering the node triggers Obsidian's native preview as well. Mixed with other descriptive text, they render as a clickable text link instead. Neither is rendered inline — a mind-map node cannot host Obsidian's inline media view.

Files dragged in from your system (images / PDFs / audio & video / notes / any other file) need a selected node first (a notice appears otherwise): they are copied into the "default location for new attachments" and attached to that node (embeddable types are written as embeds ![[report.pdf]], everything else as links [[archive.zip]]); holding Ctrl (Windows/Linux) / Option (macOS) instead skips the copy and inserts an absolute link to the original location [file name](file:///…) (wrapped in <…> only when the path contains spaces or brackets; clicking opens it in your system's default app) — the same behaviour as Obsidian's drag & drop.

3) Everyday actions (in the mind-map view)

Want to Do
Edit a node's text Double-click the node (or press F2; text inputs keep F2; with no node selected F2 belongs to Obsidian = rename the file). With Fast text node rendering on (the default) every text node is plugin-rendered, so double-click opens a plugin dialog: a pure wikilink node edits its alias (saving writes [[note|new alias]]); any other node edits the actual line from the file — [[wikilink]], URL and **bold** syntax stay visible and editable, with a live "the node will show" preview — and saving writes that line back verbatim. Turn the setting off to get the engine's inline editor back for plain text nodes (nodes with links / inline syntax / very long text keep the dialog)
Follow a link in a node Click the link text (current tab); Ctrl/Command+click (new tab — anywhere on the node works, falling back to the node's own link), add Alt for a new tab group, add Shift for a new window; hover that link for Obsidian's native preview (unresolved targets are not previewed)
Add a child / sibling Right-click the node → Add child node / Add sibling node (siblings also via Enter)
Delete a node Right-click → Delete node
Add a link Select a node → toolbar/menu Add link (pick a vault note or paste a URL). A wikilink fills a completely empty node (text = display name); a node with any existing content (text, image or link) gets a linked child node; a URL on its own node stays icon-only
Add an image Select a node → Add image (from vault, clipboard, or a file)
Attach by drag & drop Drag any vault file from the file explorer onto a selected node — it becomes the node's link (completely empty node: text becomes the display name; a node with any existing content: a linked child node is created); dragging an image sets the node image. With nothing selected, a linked node is created under the root (images need a selected node)
Drag files in from your system Select a node first, then drop system files onto the canvas (otherwise a notice asks you to): images become the node image, other files are copied into the vault and attached by type (notes → wikilink, everything else → attachment; embeddable types are written as ![[report.pdf]]). Hold Ctrl (Win/Linux) / Option (mac) to skip the copy and insert an absolute link [file name](file:///…) instead (wrapped in <…> only when the path contains spaces or brackets)
Rearrange Drag near another node's center to nest as its child; drag between two siblings to insert in between (the drop target highlights — override its colour with the CSS variable --mm-drag-target-color, defaults to orange)
Resize a node image Hover the image, drag its bottom-right handle (aspect ratio preserved)
Make a node image-only Clear the node's text: double-click → empty, or right-click → Remove text
Clean the layout Toolbar: Auto arrange, Reset zoom (100%), Fit to canvas, zoom in/out
Find a node Toolbar search box
Split a node's links Editing such a node splits automatically: document/attachment links mixed with text move into child nodes (the node keeps its text; images and external URLs stay) — turn it off in settings. Command Split all mixed links in document batch-processes the whole file, including untouched notes — the whole batch counts as one step, so one Ctrl/Command+Z undoes it
Export Toolbar Export PNG
Back to Markdown Switch to Markdown (restores source/preview mode)

Keyboard shortcuts (in the mind-map view)

Keys Action When it is not intercepted
Ctrl/Cmd+F Open the search box —
Ctrl/Cmd+Z Undo —
Ctrl/Cmd+Shift+Z Redo —
Ctrl+Y Redo Windows/Linux only — macOS leaves Cmd+Y alone
F2 Edit the selected node With no node selected F2 belongs to Obsidian (rename the file); inside a text input F2 is left alone
Delete / Backspace Delete the selected node Inside a text input, while a node is being edited, or with no node selected
Shift+1 Fit to canvas Inside a text input
Shift+2 Zoom to the selection (falls back to fit-to-canvas when nothing is selected) Inside a text input
Tab / Enter Add a child / sibling node Handled by the engine, not by the plugin

Undo/redo go through the engine's own history. Very large maps keep fewer undo steps, because the history is capped by a fixed memory budget rather than a fixed step count.

4) Saving & persistence

  • Unedited lines are written back verbatim (frontmatter preserved; blank lines between paragraphs and standalone --- separators are normalised); editing a pure wikilink node (the whole line is one wikilink) edits its alias, written back as [[note|new alias]] (clearing the text drops the alias and keeps the link; nodes that mix text and a link still round-trip as "text + link").
  • Layout, viewport and "open as" are kept per file in the plugin data.json; node image sizes go into the note itself as official embed syntax (![[img|300]]).
  • Editing the central node renames the .mindmap.md (Obsidian updates links/backlinks).
  • Only one mind-map editing instance per .mindmap.md (Obsidian itself lets you open the same file in as many tabs as you want): opening it in a second tab shows a notice and hands the view back, so two copies can never overwrite each other's saves. The note's reading view can still be open next to the mind map.
  • If the file is changed outside Obsidian (sync folder, another window), auto-save skips that round with a one-time notice instead of overwriting the other change; after repeated write failures auto-save is suspended with a notice (manual save still works).
  • Config is local; no telemetry, and the plugin makes no network requests — nothing is sent anywhere.
  • Files outside the vault are only ever touched when you ask for it: an absolute file:/// link (created by holding Ctrl/Option while dropping a file) is handed to your system's default app when you click it. The plugin does not read, copy or upload those files.

5) Deliberate differences from Obsidian

The mind-map view is a third kind of view (neither reading nor editing view), so a few interactions follow this view's semantics. All of them are registered (see AGENTS.md K56 ⑤; the second-tab and side-button rows are K102 / K111):

Item Obsidian This plugin
F2 Renames the current file Same: with no node selected F2 goes to Obsidian (rename the file); with a node selected it edits that node (selecting the central node amounts to renaming the file, since its text is the file name)
Auto-update links on rename Setting "Automatically update internal links" (on by default) Same: setting "Automatically update internal links" (on by default); turning it off leaves links untouched and skips reference cleanup on delete
Link syntax for new links Follows the "Use [[Wikilinks]]" / "New link format" settings Same, for document links only: with Wikilinks on (the official default) it writes [[wikilinks]]; with Wikilinks off it writes [label](path.md); rewrites keep your existing path prefix. Attachments and images always keep the wikilink embed form (![[report.pdf]] / [[archive.zip]])
[[ suggestions Inline suggestions in the editor The source-line dialog is a plain textarea (no inline suggestions) → use the vault-file suggestions in the Add link dialog
Backlinks / Outgoing links / Unlinked mentions panes Core plugins Not duplicated — Obsidian's own panes act on the current file and work while the mind-map view is open
Clicking a non-renderable vault file (zip / docx / …) Opens in the default system app Same
Same file in a second tab Allowed — "open as many tabs as you want"; Ctrl+clicking a link to a file that is already open makes a new tab A notice appears and the view is handed back to the existing tab: one mind-map editing instance per .mindmap.md (two instances = two engines + two save pipelines, whose interleaved saves lose edits). The note's reading view can still be open alongside
Mouse side-button back / forward Follows the navigation history Same: side buttons follow Obsidian's navigation history in the mind-map view; switching views is not a navigation point — back goes straight to the previous navigation point (usually the previous note). Use Switch to Markdown (toolbar button or command palette), or Open as Markdown from the file context menu, to return to the note's Markdown view

The full Markdown ↔ mind-map mapping rules live in docs/markdown-mindmap-standard.md.

⚙️ Settings

Everything lives in Settings → MindMap Studio (stored locally in the plugin's data.json):

Setting Default Notes
Default layout / line style / theme Logical structure / Auto / Default Used when creating a new mind map
Auto-save On Writes edits to the note while you work
Enable node dragging On Drag nodes to change hierarchy and order
Auto-split mixed links On An edited node that mixes links with description text moves document/attachment links into child nodes (images and external URLs stay)
Automatically update internal links On Mirrors Obsidian's setting of the same name — vault renames/deletes update references in maps
Performance mode / Node count threshold On / 500 Above the threshold only in-view nodes are drawn — large maps stay responsive
Fast text node rendering On All text-bearing nodes are rendered by the plugin (skips the engine's per-character text measuring) — opening large maps is several times faster; double-click then opens the edit dialog (see above). Applies to maps opened afterwards
Export image scale 2 PNG export resolution multiplier
Language 中文 UI language

📦 Install

  • Community plugins (once listed): Settings → Community plugins → search MindMap Studio.
  • From GitHub releases (recommended): download the latest release assets (main.js, manifest.json, styles.css) from the repo Releases page, copy them into <vault>/.obsidian/plugins/mindmap-studio/, reload Obsidian, then enable the plugin in Settings → Community plugins. (Each release also attaches LICENSE and THIRD-PARTY-NOTICES.md for licence compliance — no need to copy those into the plugin folder.)
  • Build from source: npm install && npm run build produces main.js; copy it together with manifest.json and styles.css into the plugin folder.

Requires Obsidian 1.13.0 or later. Desktop only (Windows, macOS, Linux). Config is stored locally (plugin data.json); no telemetry and no network requests. main.js is built in CI and attached to each GitHub Release (it is not committed to the repo).

🛠 Development

npm install
npm run dev      # watch mode
npm run build    # type-check + production bundle (main.js)
npm test         # regression suite (vitest)
npm run lint     # ESLint (the official obsidianmd ruleset, warnings are errors)
npm run lint:css # stylesheet rules — mirrors the community-directory scanner's stylelint set
npm run check:release   # release metadata guard (versions.json / manifest / README)
npm run verify:visual   # headless-Chrome render & contract checks (add `-- --perf` for a real-clock baseline)

The engine (vendor/simple-mind-map.cjs) is vendored and must not be hand-edited; rebuild from upstream source when upgrading. Bundled third-party licences are listed in vendor/THIRD-PARTY-NOTICES.md.

⚖️ License

MIT — see the LICENSE file in the repository root. The plugin bundles the simple-mind-map engine and its dependencies under their own licences (MIT / BSD-3-Clause); those notices live in vendor/THIRD-PARTY-NOTICES.md and are attached — together with LICENSE — to every GitHub release, so the declarations accompany each distributed copy of the bundle.