Architecture
NodeWise Studio is an Electron app: one main process, one window, and a small preload script between them. This page shows how they divide the work and how one change travels from a click to the database and back.
The three parts
| Part | Runs in | Does | Where |
|---|---|---|---|
| Main | Node.js | Owns the database, the files, the network and every secret. Applies commands, runs the assistant's turns, reads ComfyUI. | src/main/ |
| Preload | the window, before the page | Gives the page one object, window.electronAPI, with a fixed list of calls. Nothing else of Node or Electron reaches the page. | src/preload/index.ts |
| Renderer | Chromium, sandboxed | Draws everything: the canvas (React Flow), the panels, the chat, settings. Holds a projection of the graph, never the truth. | src/renderer/ |
| Shared | both | Types, schemas, the workflow codec, the catalog of texts, lessons and built-in knowledge. Pure code, no Electron. | src/shared/ |
Rules that hold everywhere:
- Main is the only writer. The renderer asks; main checks, applies and answers with the new state.
- Secrets never reach the renderer. Keys and tokens live in main; the window learns only whether one is held and where. Security
- ComfyUI is only read. Every call to ComfyUI or an MCP server passes one read-only gate. ComfyUI is only read
- Every IPC call is checked: the sender must be the app's own page, and the input must match its schema. IPC between window and main
How a change travels
Take "the person drags a node":
- Renderer. The canvas builds a command: an
actionId(a fresh id), theexpectedRevisionId(the version the window shows),actor: 'manual', and a payload such as{ type: 'move-node', … }. Every canvas edit goes throughsrc/renderer/components/graph/commit.tstosubmitManualinsrc/renderer/services/commands/projection.ts. - Preload.
window.electronAPI.commitCommandsends it on thecommand:commitchannel. - Main, the guard.
src/main/ipc/guard.tsrefuses a sender that is not the app's page. - Main, the engine.
commitCommandinsrc/main/commands/commit.tschecks the request against its schema and, in one SQLite transaction: refuses a version that is not the current one (a conflict), applies the payload to the current graph, writes a new row ingraph_revisions, points the project at it, records the command inapplied_commands(so a repeat of the sameactionIdis answered from the record, not applied twice), and updates explanations and open proposals. - Back. Main answers
applied,historical,conflictorrejected, always with the current projection: the graph, its version and the open run. - Renderer. The stores (
src/renderer/state/) take the projection; React redraws.
Undo is the same trip with the payload restore-revision. The assistant's changes take the same trip from main
itself, with actor: 'ai' and the id of its run. Details: The command engine and history.
How an answer of the assistant travels
- The renderer starts a run (
startRun) and opens a stream onllm:stream-chat(src/renderer/services/llm/chatService.ts). - Main builds the prompt from the graph, the catalog and the recent actions, and calls the chosen model through the
AI SDK (
src/main/agent/turn.ts,src/main/llmService.ts). - Each tool call the model makes is checked and run in main: reading the catalog, searching the web, proposing a draft, or, in a build, committing a command as above.
- Main streams text, steps and new projections back; the chat and the canvas draw them as they come.
- The turn ends, pauses at the step limit, or is stopped by the person.
Details: How the assistant works.
How ComfyUI is read
The sync (src/main/mcp/sync.ts) reads node types, node packs and model files through the read-only MCP tools, or
/object_info straight from ComfyUI, and stores them in the catalog tables. Model metadata is read in the background
in batches. Details: Reading ComfyUI.
Recipes
| To add | Read |
|---|---|
| A tool for the assistant | Adding a tool for the assistant |
| A setting | Adding a setting |
| An IPC channel | IPC between window and main |
| A database migration | The database and migrations |
| A lesson | Writing a lesson |
| Built-in knowledge | Writing built-in knowledge |
| A language | Texts and languages |
| A link from the app to a wiki page | Context help ids |