AI 能帮助你实现,但是不能替代你思考;
大脑里放不下太多节点 —— 把它们倒进图里,让思考可计算、可回溯、可成环。
一个用 Rust + Tauri 2 + SQLite 写的 macOS 桌面应用,把"评论 / 回复"建模成有向图, 并通过 GraphViz 渲染出来。
- 多张图 —— 每个主题一张图,互不干扰。
- 评论 / 回复 —— 每个节点都可以被回复,自然形成树状的思考脉络。
- app_id 引用形成"环" —— 给节点起一个易记的 ID(如
root、hypothesis-1), 在任意节点里通过⟲ Ref by app_id引用一个已存在的 ID,就会画出一条 回边,让图形成环。对回归型 / 递归型思考特别有用: A → B → C ⟲ A,可以一眼看出"我又绕回来了"。 - 导出
.gv/ 直接渲染 —— 一键导出 GraphViz 源文件,或调用dot渲染成 PDF,再交给/Applications/Graphviz.app查看。 - 思维路径搜索 —— 输入两个
关键字,用 BFS 找出所有路径, 把"从想法 A 到结论 B 是怎么走过来的"显式呈现。
| 依赖 | 说明 |
|---|---|
| macOS | 10.13+ |
| Xcode CLT | xcode-select --install |
| Rust | 1.77+(cargo 可用即可) |
| Node.js | 18+,用于跑 @tauri-apps/cli |
| GraphViz | brew install graphviz(dot 必须在 PATH 里),或装 Graphviz.app |
应用本身把 SQLite 静态链接进了二进制,不需要额外安装 sqlite。
cd /Users/xlisp/RustPro/graphviz-comment-reply
npm install # 装 Tauri CLI
npm run dev # 开发模式(首次约 3–5 分钟编译 Tauri 依赖树)打包成可分发的 .app / .dmg:
npm run build
# 产物位于 target/release/bundle/
# macos/ThoughtGraph.app
# dmg/ThoughtGraph_0.1.0_*.dmg (仅 GUI)要打同时包含 MCP server 的 DMG(推荐,给 Claude Desktop 用):
./scripts/build-dmg.sh
# 产物位于 dist/ThoughtGraph-<version>-<arch>.dmg
# .app 内嵌 thoughtgraph-mcp,安装后路径稳定:
# /Applications/ThoughtGraph.app/Contents/Resources/bin/thoughtgraph-mcp本地数据库存放位置:
~/Library/Application Support/com.chanshunli.thoughtgraph/thoughtgraph.sqlite3
导出的 .gv / .pdf 也在同目录的 exports/ 子目录下。
左上角 + → 输入图名 → 创建。 图名可重复,但建议用主题区分(如 Q2 战略复盘)。
左侧 + New comment → 输入:
- app_id:图内唯一 ID,建议短而可记(如
root、idea-1、risk-A)。 - Content:正文,支持多行。
选中一个节点 → 工具栏 ↳ Reply → 填新节点的 app_id 和正文。
回复会在两节点之间生成一条 kind='reply' 的实线边。
选中一个节点 → 工具栏 ⟲ Ref by app_id → 填目标 app_id(必须已存在于本图)。
- 生成一条
kind='ref'的虚线红色边。 - 当目标 app_id 是当前节点的祖先时 —— 环形成,这正是用于回归思考的关键。
| 按钮 | 行为 |
|---|---|
| Export .gv | 在 exports/<图名>.gv 写入 DOT 源码,弹窗告诉你路径 |
| Render → PDF | 调用 dot -Tpdf 渲染并用系统默认应用打开 |
| Open in Graphviz.app | 导出 .gv 后用 /Applications/Graphviz.app 打开 |
| Show DOT | 在右下角实时显示当前图的 DOT 源码 |
右侧 Thinking path search 面板:
- 输入 From app_id 与 To app_id
- 点击 Find shortest paths → 返回最多 10 条最短路径
- 每条路径会标出每一步是
↳ reply还是⟲ ref,方便区分"自然展开"和"回边"。
graphs(id, name, description, created_at, updated_at)
nodes(id, graph_id, app_id, content, created_at) -- UNIQUE(graph_id, app_id)
edges(id, graph_id, from_node_id, to_node_id, kind, label)
kind ∈ {'reply', 'ref'}
- reply 边:父评论 → 子回复,构成"树骨架"。
- ref 边:任意节点 → 任意已存在节点,可形成环。
- 删除节点会级联删除其子树和相关边。
导出的 DOT 大致长这样:
digraph "Q2 战略复盘" {
rankdir=LR;
n1 [label="root\n核心问题:用户留存为什么下降?"];
n2 [label="hypo-A\n是不是 onboarding 太长?"];
n3 [label="data-1\n抽样显示完成率 41%"];
n1 -> n2 [arrowhead=vee];
n2 -> n3 [arrowhead=vee];
n3 -> n1 [arrowhead=vee, style=dashed, color="#cc5555", constraint=false]; // ⟲ 回到 root
}graphviz-comment-reply/
├── package.json # @tauri-apps/cli
├── src/ # 桌面端前端(Tauri,纯 HTML/CSS/JS,无构建步骤)
│ ├── index.html
│ ├── styles.css
│ └── main.js
├── src-tauri/ # Rust + Tauri 2 后端
│ ├── Cargo.toml
│ ├── tauri.conf.json
│ ├── build.rs
│ ├── capabilities/default.json
│ ├── icons/...
│ └── src/
│ ├── main.rs # 入口
│ ├── lib.rs # Tauri Builder、插件注册、command 列表
│ ├── db.rs # SQLite schema 与 CRUD
│ ├── graph.rs # DOT 渲染、dot 进程调用、BFS 路径搜索
│ └── commands.rs # Tauri command 包装
├── mcp-server/ # MCP server(共享同一 SQLite)
├── web-server/ # Web 版后端(Rust,跨平台 HTTP;复用 db.rs / graph.rs)
│ ├── Cargo.toml
│ └── src/main.rs # tiny_http + 单端点 POST /api/invoke 分派
├── web-py/ # Web 版后端(纯 Python,零编译;受限 Windows 用)
│ ├── server.py # 镜像 web-server 的 dispatch / db / graph
│ ├── run.bat # Windows 启动
│ └── run.sh # Linux / macOS 启动
└── web-src/ # Web 版前端(与桌面端 src/ 同源,仅 invoke 改 fetch)
Q: 启动后报 graphviz dot not found?
A: 先 brew install graphviz,或确认 /usr/local/bin/dot、/opt/homebrew/bin/dot
其中之一存在。
Q: 我可以引用一个还没创建的 app_id 吗? A: 不行。引用边要求目标节点已存在。建议先把所有想法节点建好,再补引用。
Q: 删除节点会断我的环吗? A: 会。删除会级联清掉所有指入 / 指出该节点的边。
Q: 想换图标?
A: 用你自己的 512×512 RGBA PNG 替换 src-tauri/icons/icon.png,然后重跑
iconutil 那一段生成 icon.icns。
Q: 数据库怎么备份?
A: 直接复制 ~/Library/Application Support/com.chanshunli.thoughtgraph/thoughtgraph.sqlite3。
web-server/ 是一个独立的 Rust 二进制 thoughtgraph-web,把 Tauri 桌面端的全部
后端能力(db.rs / graph.rs)原样复用,用 HTTP 暴露出来,配合 web-src/
里的纯前端(HTML/CSS/JS)在浏览器里使用。专门用于:
- 公司里跑不了 Tauri 工具链的 Windows 电脑
- 想把 ThoughtGraph 装在一台 NAS / 服务器上远程访问的场景
与桌面版的关系:完全独立。共享 src-tauri/ 里的 db 和 graph 两个 crate 模块
(通过 path 依赖),所以 schema、DOT 渲染、路径搜索全部一致;SQLite 文件可互通。
不会动到桌面端任何代码。
| 依赖 | 说明 |
|---|---|
| Rust | 1.77+(rustup 装好即可) |
| GraphViz | 可选。装了 dot 就走系统二进制(更快);没装也行,前端自带 Viz.js(WASM Graphviz)走浏览器渲染 |
| 浏览器 | 任意现代浏览器 |
无需 Node.js / Tauri CLI / Xcode。前端 web-src/vendor/viz-standalone.js
是 Viz.js 3.14.0(WASM 移植的 Graphviz,约 1.4MB),点 Render 按钮时在浏览器里
直接把 DOT 渲成 SVG,新开标签页里用浏览器原生「打印 / 另存为 PDF」即可得到 PDF。
整个链路无需任何系统级 dot 二进制。
cargo run -p thoughtgraph-web --release
# 或者编译后直接跑:
cargo build -p thoughtgraph-web --release
./target/release/thoughtgraph-web # Linux / macOS
./target/release/thoughtgraph-web.exe # Windows启动后会打印类似:
ThoughtGraph Web server
database : C:\Users\<you>\AppData\Roaming\thoughtgraph\thoughtgraph.sqlite3
exports : C:\Users\<you>\AppData\Roaming\thoughtgraph\exports
web-src : <repo>\web-src
listen : http://127.0.0.1:8888
Open http://127.0.0.1:8888 in your browser.
打开浏览器访问 http://127.0.0.1:8888 即可使用,UI 与桌面版一致。
| 变量 | 默认 | 作用 |
|---|---|---|
HOST |
127.0.0.1 |
监听地址;改成 0.0.0.0 可被同网段其它机器访问 |
PORT |
8888 |
监听端口 |
THOUGHTGRAPH_DATA_DIR |
OS 默认数据目录 / thoughtgraph |
整个数据目录(DB + exports) |
THOUGHTGRAPH_DB |
<data_dir>/thoughtgraph.sqlite3 |
单独指定 sqlite 文件位置 |
THOUGHTGRAPH_WEB_SRC |
<binary>/../web-src 或 CWD |
静态前端目录 |
DOT_BIN |
自动查找 | 强制指定 dot 二进制路径(Windows 上 PATH 没配置时很有用) |
操作系统默认数据目录:
- Windows:
%APPDATA%\thoughtgraph\ - Linux:
~/.local/share/thoughtgraph/ - macOS:
~/Library/Application Support/thoughtgraph/(注意:与桌面版的com.chanshunli.thoughtgraph/不是同一个目录,避免冲突;如需共用同一份数据, 设THOUGHTGRAPH_DB指向桌面版的 sqlite 文件即可)
单端点 POST /api/invoke:
curl -X POST http://127.0.0.1:8888/api/invoke \
-H 'Content-Type: application/json' \
-d '{"cmd":"create_graph","args":{"name":"demo","description":""}}'cmd 与 args 的形状与桌面版 Tauri command 一一对应(参数名是 camelCase)。
渲染 / 导出类命令在响应里额外返回 url 字段(如 /exports/demo.gv),浏览器
直接打开即可下载。所有命令列表见 web-server/src/main.rs 中的 dispatch 函数。
-
装 Rust:https://rustup.rs
-
(可选) 装 GraphViz:https://graphviz.org/download/,安装时勾选"Add to PATH"。 不装也行 —— 浏览器侧的 Viz.js 会兜底渲染。
-
git clone本仓库 -
在仓库根目录执行:
cargo run -p thoughtgraph-web --release
-
浏览器打开
http://127.0.0.1:8888
如果装了 dot 但不在 PATH,加一个环境变量再跑:
set DOT_BIN=C:\Program Files\Graphviz\bin\dot.exe
cargo run -p thoughtgraph-web --release如果公司电脑因为安全策略不允许编译生成 .exe(典型报错:link.exe 报错、
没装 MSVC build tools、AV 拦截链接器)、也装不了 GraphViz,用 web-py/ 下的
纯 Python 版本 + 前端自带的 Viz.js(WASM)即可:
- 不需要 Rust、不需要 Node、不需要 MSVC、不需要 GraphViz,只要装好 Python 3.9+ (Microsoft Store 搜 "Python 3" 免管理员安装亦可)。
- 全部用 Python 标准库写(
http.server+sqlite3),不产生任何二进制文件, 只跑.py源码。 - 渲染走前端 Viz.js(
web-src/vendor/viz-standalone.js,WASM 移植的 Graphviz), 浏览器内直接生成 SVG;想要 PDF 就用浏览器的「打印 / 另存为 PDF」。 - 后端逻辑完全镜像 Rust 版:相同的 SQLite schema、相同的 DOT 输出、相同的路径
搜索语义;前端
web-src/一字不改地复用。SQLite 数据库文件与 Rust 版兼容。
启动:
cd path\to\thought-graph\web-py
run.bat或手动:
python server.pyLinux / macOS:
cd thought-graph/web-py
./run.sh环境变量与 Rust 版完全一致(HOST、PORT、THOUGHTGRAPH_DATA_DIR、
THOUGHTGRAPH_DB、THOUGHTGRAPH_WEB_SRC、DOT_BIN)。
数据库默认路径也一致,所以 Rust web 版、Python web 版、桌面 Tauri 版
可以指向同一个 SQLite 文件互通(用 THOUGHTGRAPH_DB 显式指定)。
mcp-server/ 是一个独立的 Rust 二进制,把同一个 SQLite 数据库暴露为
Model Context Protocol server,让 Claude Desktop 当作长期记忆来用:
- 跨会话读写 / 搜索图谱
- 13 个工具:CRUD、
add_reference(成环)、search_nodes(FTS5)、find_paths、render_graph等 - 与 GUI app 共享同一份 SQLite(已开启 WAL,并发安全)
- 自动维护 FTS5 全文索引(由触发器同步
nodes↔nodes_fts)
编译并接入 Claude Desktop:
cargo build -p thoughtgraph-mcp --release把可执行文件路径写进 ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"thoughtgraph": {
"command": "/Users/xlisp/RustPro/graphviz-comment-reply/target/release/thoughtgraph-mcp"
}
}
}MIT