Draw, edit and keep graph notes. An Obsidian plugin now; an app, a VS Code plugin and a JavaScript library next. Offline and private.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗ThoughtKnot turns what you know into a map you can see, change and share. You write things and the links between them as plain text, and it draws them. You can edit a graph by typing or by dragging the drawing.
It is one product with several ways in. The Obsidian plugin works now, on desktop and phone, offline. A standalone app, a VS Code plugin and a JavaScript library come next.
Status: in development. It is not in the community plugin directory yet. It is built in ten slices. Slices 1 to 4 are done, and slice 5 is in progress.
| You want to | Go to |
|---|---|
| Use it | How to use ThoughtKnot |
| Know what it sends, and when | Privacy and network use |
| Build it or change it | Developing and CONTRIBUTING.md |
| See how it fits together | How the packages fit |
packages/obsidian: the plugin.packages/graph-spec: the graph format library in plain JavaScript. It reads graphs, checks their rules and answers
questions about them. It is one file with no dependencies, so a web page or Node can load it.python/graph_spec: the same library in Python. It also draws with Graphviz and runs extra checks with Grafeo. Its
answers are tested against the JavaScript library on every shared case.graph-spec-libraries-<version>.tar.gz. SHA256SUMS lists every
file in the release with its SHA-256.manifest.json, versions.json and styles.css: the files the plugin store reads. CI builds main.js from a tag
and attaches it to each release. It is never committed.Each layer uses only the one below it. So a new host, such as a VS Code extension or a desktop app, reuses everything below the hosts as it is.
hosts packages/obsidian packages/claude-code <- packages/app, packages/vscode
\ /
core packages/core host-free: reading, drawing, edits, undo
|
format packages/graph-spec <=> python/graph_spec
(JavaScript) held to the same answers (Python)
packages/graph-spec: the graph format. It reads GQL blocks and runs the spec's rules, with no dependencies. Guide:
packages/graph-spec/GUIDE.md.python/graph_spec: the same format in Python, function for function. It adds the Graphviz drawing and the Grafeo
checks. Shared tests hold the two to the same answers. Guide: python/graph_spec/GUIDE.md.packages/core: the editor core, on top of graph-spec. It works out what to draw, the problems and their fixes, zoom,
edits and undo. It uses no Obsidian, editor or Node module, so it runs on a phone too. Guide:
packages/core/GUIDE.md.packages/sync: sync between an owner's devices, beside the core. Each note is one Automerge text, sealed on disk and
copied by Syncthing. Guide: packages/sync/GUIDE.md.packages/boundary: the line between the owner's personal layer and a corporate one. What crosses is plain text,
with no key, and AI-made content labelled. Guide: packages/boundary/GUIDE.md.packages/web: the web layer, a read-only site of static files built from what crossed. No server. Guide:
packages/web/GUIDE.md.packages/obsidian: the Obsidian plugin. It puts the core's drawings and edits on Obsidian's page. Guide:
packages/obsidian/GUIDE.md.packages/claude-code: the Claude Code host. Its /graph <note> command draws a note's graph in a pane. It also
serves a browser editor on your own machine, on the same core. Guide:
packages/claude-code/GUIDE.md.The short version for every app is the privacy page. It says what is kept, where, for how long, and how to delete it.
The short version, for the plugin, the app and the browser editor, is the privacy page.
The plugin makes no network request of its own. There are no analytics, no update checks, no remote images and no databases. Graphviz, the one runtime dependency, is bundled and runs on your device.
The one exception: AI models you set up. The plugin can ask an AI model to propose changes to a graph. It sends content only to AI models you have set up yourself, and only when you send it. AI is off until you turn it on (Use AI models, in the plugin's settings) and set up a model.
Where your text ends up. A model at a remote address receives the text you are shown. It keeps it under its provider’s own terms and retention, so it leaves your control once sent. A model at localhost runs on your device, so the text stays on your device.
Requests go straight from your device to the address you gave, through Obsidian's own request function. There is no server of ours in between, and no AI vendor's library inside the plugin.
Obsidian follows redirects; point a model only at an address you trust. Obsidian also adds headers of its own to each request, beyond those shown before you send.
You need Node 24 or later. CONTRIBUTING.md says how the code is written and how each rule is checked.
npm ci
git config core.hooksPath .githooks
npm test
npm run typecheck
npm run lint
npm run build
The second line turns on the pre-commit check. It refuses any staged file that looks confidential or personal:
CI runs the same check over every file, so a commit that skipped the hook is still caught.
A fresh clone needs only these steps. CI runs them exactly as written here, in a fresh clone:
So setting up never depends on a maintainer's machine.
Only collaborators can open pull requests and issues for now, and each pull request's conversation is locked when it opens. Ideas and questions are welcome in GitHub Discussions. CONTRIBUTING.md says how to ask to join.
The plugin is tested from installed files, not from the plugin store.
npm run build writes main.js once. npm run dev writes it on every save.node scripts/reset-test-vault.mjs copies main.js, manifest.json and styles.css into the test vault's
.obsidian/plugins/thoughtknot/, as real files.Obsidian Sync carries the files to a phone when it syncs installed community plugins. A new build reaches the vault only when you run the reset again. Releases are still built only by CI, from a tag.
To try the drawing in an ordinary browser first, run node packages/obsidian/harness/build.mjs <folder>. It builds a
page that draws a sample note with the real plugin and a small stand-in for Obsidian. Serve the folder and open it.
The Python library has its own pinned setup (uv, Python 3.14):
cd python/graph_spec
uv sync --locked
uv run --locked python -m unittest discover -s tests
A host that uses the Python library sets three values after importing it: graph_spec.CLASSIFICATION_NOTE,
graph_spec.OWNER_ENGINE and graph_spec.WRITTEN_BY. The defaults name no machine or person. No classification note is
read until one is set.
npm ci..npmrc sets ignore-scripts=true.npm audit signatures before every build.v in front. Each has SHA256SUMS for every file.
Once the repository is public, each also gets a build provenance attestation. GitHub keeps those only for public
repositories owned by a person.scripts/public-readiness.mjs runs in CI and before every release. It
checks every branch and tag for secrets and for anything confidential or personal. It checks that every commit comes
from a no-reply address. It also sets up a fresh clone from the steps above alone.--settings) checks the repository's settings. Collaborators only
may open pull requests and issues. Every action is pinned and the token is read-only. A fork's workflows run only once
approved. Secret scanning with push protection, Dependabot alerts and fixes, and CodeQL are on.ThoughtKnot uses semantic versions, with one catch before 1.0.0. Then a step in the leftmost part that is not 0 may change or remove what the library exports. So 0.7 to 0.8 may break your code. A patch step, such as 0.8.0 to 0.8.1, never does. Each release's notes have a "Library changes" section. It lists what was added, changed or removed.
Mozilla Public License 2.0 (MPL-2.0). See LICENSE.
The graph spec's own text is under CC-BY-4.0, so anyone may build on the format if they credit it. See LICENSE-SPEC.md for the files it covers.
The layout engine, @viz-js/viz, compiles Graphviz (Eclipse Public License 2.0) into WebAssembly. See
THIRD_PARTY_NOTICES.md, which ships with every release.
packages/app: the desktop app, for macOS, Windows and Linux. It runs the browser editor in a Tauri window, over a
plain folder of notes, offline, with no server inside. Guide: packages/app/GUIDE.md.packages/vscode: the VS Code extension. It runs the browser editor in a VS Code tab beside a Markdown note, over
the note's workspace folder. Guide: packages/vscode/GUIDE.md.