Skip to content

Architecture Overview

Jeremiah edited this page Oct 22, 2026 · 1 revision

Architecture Overview

This page explains how the desktop app, shared packages, plugins, workers and agent tools fit together.

ChemDraft composes real chemical and graphical objects on a native document page. A molecule editor can assist with one editing session, but it does not own the page. The same document and geometry packages support interactive drawing and headless output, keeping automation aligned with the canvas.

System map

In this diagram, arrows show important calls or data dependencies rather than every package import. A worker runs JavaScript away from the main interface thread; a sidecar is a separate native executable managed by the host.

flowchart TB
  User[Desktop user] --> App[React desktop shell]
  App --> Commands[Shared CommandRegistry]
  Commands --> Workflow[Desktop workflow]
  Workflow --> Shared[document-workflow-core]
  Shared --> Core[chem-core: document and patches]
  App --> Layout[layout-engine: molecule geometry]
  App --> Art[art-engine: graphical plans]
  Layout --> Export[export-engine]
  Art --> Export
  Core --> App
  App --> Native[Tauri Rust: OS and engine boundaries]
  Native --> Sidecar[Native 3D sidecar]
  Native --> Local[Local OPSIN and optional engines]
  App --> Runtime[Persistent plugin runtime]
  Runtime --> Host[plugin-host and permission gates]
  Host --> Commands
  Host --> Workers[Per-plugin module workers]
  Workers --> API[plugin-api contracts]
  Host --> Review[Patch acceptance or direct insert gate]
  Review --> Core
  App --> ChemWorkers[Chemistry and conformer workers]
  ChemWorkers --> Adapters[RDKit and OpenChemLib adapters]
  Agent[Assistant or script] --> MCP[MCP stdio server]
  Agent --> CLI[CLI command modules]
  MCP --> CLI
  CLI --> Shared
  CLI --> Export
  CLI --> Adapters
Loading

Follow one edit

Consider inserting a molecule from a deterministic conversion of user-supplied input:

  1. A desktop control invokes a registered command. A plugin command uses the same registry, tagged with its owning plugin.
  2. The workflow obtains a typed chemistry result through an adapter or host capability. Heavy engine loading stays with the caller rather than the pure document builder.
  3. Shared document functions build native objects. The mutation is expressed as patches, such as addObject and setSelection.
  4. chem-core validates the changed data and returns the next document. Patch batches are atomic: a failed operation does not leave a partially applied document.
  5. The host records the user action as one labelled undo entry and leaves the inserted content selected.
  6. The desktop renders the new document using shared layout geometry. Export uses those same plans, so a second rendering implementation cannot drift from the canvas.

For a plugin, direct insertion additionally requires document.write and an active command owned by that plugin. Changes to existing content go through proposal review. Image recognition always goes through review because its result is uncertain.

Where state lives

chem-core owns document schemas, pages, native objects, patches and serialization. Desktop state adds tabs, undo histories, file associations, dirty flags, selection details and viewports. A viewport change does not make the chemical document dirty.

document-workflow-core contains pure document-building functions shared with the CLI and MCP. It does not import React, Tauri, DOM APIs, app state or engine loaders. Desktop workflows can orchestrate these helpers without moving desktop dependencies into the headless path.

layout-engine owns all molecule rendering math and the atom-label grammar. art-engine plans graphical strokes, markers and arrow geometry. export-engine combines document content and those plans into supported output with warnings. Compatibility parsing stays in cdx-compat; CDXML never becomes app state.

Extension lifetime and authority

The desktop creates one persistent plugin runtime and feeds current document and selection through callbacks. Switching a tab or undoing an edit must not recreate that runtime. Analyzer plugins run in individual module workers with a versioned startup handshake and complete teardown on disable, uninstall or replacement.

Panels contain declarative PluginPanelReport data, rendered by PluginReportRenderer. A plugin does not supply arbitrary app UI or receive undeclared native access. Desktop report panels have their own native windows, and closing one notifies the plugin.

The CLI and MCP call shared modules instead of importing desktop code. The MCP server invokes CLI operations in-process, allowing an engine instance to remain warm. The optional in-app agent bridge is separately gated; it is an automation aid, not an unrestricted product API.

Native and platform boundaries

Tauri owns windows, menus, file access, clipboard integration and managed native engines. macOS and Windows need different update systems: Sparkle with appcast.xml, and the Tauri updater with latest.json, respectively. Installed plugins remain same-origin: tauri://localhost on macOS and http://tauri.localhost on Windows.

Windows gives menus only to the document window. Utility windows remain document-owned and avoid stealing drawing focus or adding taskbar entries. New desktop dialogs use the shared native dialog host; browser-preview fallbacks do not define desktop behavior.

See also

Clone this wiki locally