Repository navigation
Architecture
github-actions[bot] edited this page Oct 19, 2026
·
10 revisions
ThoughtKnot is built in layers. Each layer only uses the ones below it, so a new app can be added on top without changing what is underneath.
This page describes main, which the nightly build is made from. The latest release is 0.7.0: ✅ is in it, 🌙 is only in the nightly build, 🟡 is being built and ⏳ is planned.
The drawing is made from
requirements/architecture.gql, a
graph note kept in the repository. Each box is a part, and each six-sided box is an interface between layers. A dashed
box is planned.
flowchart TB
subgraph plugins["Plug-ins"]
built_in_exports["Built-in data exports<br/><i>:Part</i>"]
end
subgraph apps["Apps"]
obsidian["Obsidian plugin<br/><i>:Part</i>"]
claude_code["Browser editor, from Claude Code<br/><i>:Part</i>"]
standalone["Standalone app (Tauri)<br/><i>:Part</i>"]
vscode["VS Code plugin<br/><i>:Part</i>"]
end
subgraph display["Display layer"]
display_part["Display layer<br/><i>:Part</i>"]
end
subgraph core["Core"]
core_part["Core<br/><i>:Part</i>"]
end
subgraph library["Graph format library"]
graph_spec_js["Graph format library (JavaScript)<br/><i>:Part</i>"]
graph_spec_py["Graph format library (Python)<br/><i>:Part</i>"]
end
host_interface{{"Host interface (DisplayHost)<br/><i>:Interface</i>"}}
plugin_interface{{"Plug-in interface<br/><i>:Interface</i>"}}
storage_interface{{"Storage interface<br/><i>:Interface</i>"}}
problem_shapes{{"Problems and fixes (Language Server Protocol shapes)<br/><i>:Interface</i>"}}
plugins -->|uses| display
apps -->|uses| display
display -->|uses| core
core -->|uses| library
graph_spec_js -.-|offers| problem_shapes
core_part -.-|offers| plugin_interface
core_part -.-|offers| storage_interface
display_part -.-|offers| host_interface
obsidian -->|implements| host_interface
claude_code -->|implements| host_interface
standalone -->|implements| host_interface
vscode -->|implements| host_interface
built_in_exports -->|implements| plugin_interface
classDef planned stroke-dasharray: 5 5,opacity:0.7
class standalone,vscode planned
| Layer | What it does | Parts |
|---|---|---|
| Plug-ins | Add exports, theme colours and, later, diagram types, steps, storage and AI providers, through one checked interface. | Built-in data exports |
| Apps | Put the editor where people work, each through a small adapter of its own. |
Obsidian plugin Browser editor, from Claude Code Standalone app (Tauri) (⏳ Planned, standalone_app)VS Code plugin (⏳ Planned, vscode_plugin) |
| Display layer | Draws the card, the details and the forms with the web page alone, the same in every app. | Display layer |
| Core | Works out what to draw, the problems and their fixes, and every edit, with no app inside. | Core |
| Graph format library | Reads a graph written in a note and checks it against the rules, in JavaScript and Python. |
Graph format library (JavaScript) Graph format library (Python) |
Every interface between layers has a contract: a set of checks that any app or plug-in runs against itself. If it passes, it fits.
| Interface | Where it is defined | Requirements |
|---|---|---|
| Host interface (DisplayHost) |
packages/core/src/display/host.tschecks: packages/core/src/display/host-contract.ts
|
🟡 host_contract_published🟡 hosts_pass_contract
|
| Plug-in interface |
packages/core/src/plugins.tschecks: packages/core/src/plugins-contract.ts
|
🟡 plugin_interface🟡 plugin_manifest_limits🟡 plugin_contract_suites🟡 plugin_theme_tokens
|
| Storage interface | Not written yet | ⏳ storage_contract
|
| Problems and fixes (Language Server Protocol shapes) | packages/graph-spec/src/reader/problem-codes.json |
✅ lsp_shapes🟡 problem_codes
|
flowchart LR
N["A note<br/><i>:Note</i>"] -->|read by| L["Graph format library<br/><i>:Layer</i>"]
L -->|graph and problems| C["Core<br/><i>:Layer</i>"]
C -->|layout source| G["Graphviz, in a worker<br/><i>:Engine</i>"]
G -->|picture| D["Display layer<br/><i>:Layer</i>"]
D -->|card, details, forms| A["The app<br/><i>:Host</i>"]
A -->|an edit| C
C -->|new text| N
- The graph format library reads each
gqlblock of the note and checks it against the rules. - The core works out what to draw, the problems and their fixes. It writes a layout source that is the same, byte for byte, in JavaScript and Python.
- Graphviz lays the drawing out in a worker, so the page never freezes.
- The display layer shows the card, the details and the forms, using only the web page.
- The app gives the few things only it knows: icons, notices, menus, its language.
- An edit goes back through the core, which writes the new text into the note. The note is always the one store.
flowchart LR
s10(["§10 Hosts — one core, Obsidian first, VS Code later<br/><i>:Section</i>"])
subgraph g_released["✅ Released"]
host_free_core["host_free_core<br/><i>:Requirement</i>"]
format_as_library["format_as_library<br/><i>:Requirement</i>"]
lsp_shapes["lsp_shapes<br/><i>:Requirement</i>"]
one_colour_map["one_colour_map<br/><i>:Requirement</i>"]
end
s10 --- g_released
| Requirement | Where it stands | Level | Rule |
|---|---|---|---|
host_free_core |
✅ Released | must | The core must not import obsidian or vscode. |
format_as_library |
✅ Released | must | The reader, the rules, completeness and the layout source must live in their own package, which the plugin uses, and the vault must carry only a generated, read-only copy of each release. |
lsp_shapes |
✅ Released | must | Problems, fixes and suggestions must use the shapes of the Language Server Protocol |
one_colour_map |
✅ Released | should | Theme colours should reach each host through one mapping table. |
flowchart LR
s43(["§43 Plug-ins, layers and their contracts<br/><i>:Section</i>"])
subgraph g_released["✅ Released"]
affected_tests_by_imports["affected_tests_by_imports<br/><i>:Requirement</i>"]
end
s43 --- g_released
subgraph g_part["🟡 Being built"]
plugin_interface["plugin_interface<br/><i>:Requirement</i>"]
plugin_manifest_limits["plugin_manifest_limits<br/><i>:Requirement</i>"]
plugin_contract_suites["plugin_contract_suites<br/><i>:Requirement</i>"]
hosts_pass_contract["hosts_pass_contract<br/><i>:Requirement</i>"]
end
s43 --- g_part
subgraph g_open["⏳ Planned"]
layers_checked["layers_checked<br/><i>:Requirement</i>"]
plugin_rtl["plugin_rtl<br/><i>:Requirement</i>"]
end
s43 --- g_open
| Requirement | Where it stands | Level | Rule |
|---|---|---|---|
plugin_interface |
🟡 Being built | must | Diagram types, data exports, graph steps and sources, storage backends, AI providers and the commands and panels a plug-in adds must be reached through one typed, versioned plug-in interface, published with the library, and the built-in ones must register through it too. |
plugin_manifest_limits |
🟡 Being built | must | A plug-in must declare in a manifest the extension points and host abilities it uses and get nothing else, and a plug-in that throws or runs too long must be stopped and named, never leave a drawing blank. |
plugin_contract_suites |
🟡 Being built | must | Each extension point must ship a contract suite that any plug-in can run against itself, and every built-in must pass it in CI. |
hosts_pass_contract |
🟡 Being built | must | Every host's adapter, Obsidian's, the browser page's, the standalone app's and VS Code's, must pass the one shared host contract suite in CI, run against the real adapter. |
layers_checked |
⏳ Planned | must | Each layer must import only the layers below it, from the graph format library through the core, the display layer and the plug-ins to the hosts, checked in CI on every change. |
affected_tests_by_imports |
✅ Released | must | The quick test run must choose, besides the tests named after a changed module, every test that reaches it through the import graph, by importing it directly or through others or by naming it to build, and run the whole suite only for a change no test reaches or one every test shares. |
plugin_rtl |
⏳ Planned | must | Every plug-in must work in a right-to-left language: what it adds reads in the host's direction, keeps the person's names in their own direction and uses logical sides only, checked by its extension point's contract suite (Roger, 18 Oct 2026). |
- How ready the layers are for other languages, right-to-left scripts, plug-ins, themes and contract tests: design review.
- The whiteboard, a board for brainstorming with several people that decomposes into graph items: whiteboard design.
- Graph notes in Microsoft 365 Copilot Cowork: Copilot Cowork skill design.
- An AI breaking prose into a graph shown as a proposal: text to graph design.
- Claude showing a graph, walking you through it and taking your decision: Claude presents and decides design.
Using it
The project
Building it
Designs