Host-Apps und die eigenständige Engine

Status: Hosts entschieden, eigenständige Engine Entwurf

Der Engine-Server, die Host-Elementquelle und der Client sind entschieden (2026-10-22) und gebaut; monsterbrain ist der erste Host (monsterbrain ist der erste ... (DEC_HOST_ORDER)). Die eigenständige Engine weiter unten ist noch ein Vorschlag.

Ein Host ist eine App, die Inhalte selbst darstellt und deciwa darin zeigt: zuerst monsterbrain, dann VS Code. Zwei Entscheidungen bilden den Rahmen dieser Seite:

Teile

Teil

Wo

Aufgabe

Engine

deciwa-Binary: Kern, CLI, Server und die Overlay-Dateien

die gesamte Logik, .deciwa/, die JSON-API

Client

packages/client (TypeScript, npm @danwos/deciwa-client)

Engine finden, starten und stoppen, ihre Version prüfen, typisierte Aufrufe der JSON-API

Overlay

packages/ui

Karte, Panel, Balken, geführtes Review – mit einer dritten Elementquelle für Hosts (js/host.js)

Host-Adapter

packages/monsterbrain, später packages/vscode

verbindet die Erweiterungspunkte des Hosts mit Client und Overlay – klein, ohne Logik

Die Host-Adapter hängen von Client und Overlay ab, nie voneinander (deciwa ist ein Repository a... (DEC_PACKAGES)). Die Logik bleibt in deciwa-core (Die CLI ist der Master, mit... (DEC_CLI_MASTER)); die TypeScript-Teile rufen nur die Engine auf.

Engine als Server für einen Host

Ein Host spricht mit deciwa... (DEC_SERVE_API_ONLY)

$ deciwa serve --api-only --root <folder> --port 0
{"deciwa": "0.0.1", "api": 1, "port": 41873, "token": "…", "root": "/home/daniel/brain"}
  • Handshake: die erste Zeile auf stdout. root ist der Ordner mit .deciwa/ – er kann über dem Ordner liegen, den der Host geöffnet hat; der Host rechnet seine Pfade um den Unterschied um. Ohne .deciwa/ lautet die Zeile {"api": 1, "error": {"code": "no-deciwa", …}} und die Engine endet mit 2; der Host kann dann deciwa init --at <ordner> anbieten.

  • Token: jede Anfrage trägt den Header X-Deciwa-Token; andere lokale Seiten können die API nicht aufrufen. --token oder DECIWA_TOKEN setzen ihn, sonst ist er zufällig.

  • Lebensdauer: die Engine beendet sich, wenn ihr stdin geschlossen wird, und läuft so nie länger als der Host. --keep-running schaltet das ab (zum Ausprobieren im Terminal).

  • Keine Website: alles außerhalb von /api/ antwortet mit 404.

Endpunkte für Hosts, neben denen des Review-Servers (/api/page, /api/annotate, /api/reply, /api/project, /api/todo, …):

Endpunkt

Liefert

GET /api/version

app (Version der Engine), api (Hauptversion der JSON-API), root

GET /api/elements?source=<path>

die Elemente einer Datei mit Selektor, Art, Bezeichnung, Zeile, Text und Fingerabdruck – aus dem Elementindex eines Builds, sonst vom Adapter für den Dateityp

POST /api/elements {source, title, elements}

merkt sich die Elemente einer Seite, die der Host selbst gescannt hat (dargestelltes HTML), wie die Seiten einer Website in .deciwa/web-pages.json

GET /api/summary[?sources=a,b]

je Datei: Anzahl je Zustand, offene Fragen, Aufgaben für die KI, Pflicht und erledigt – ohne sources für jede Datei mit Review-Daten

GET /api/facts[?sources=a,b]

die Fakten von Faktendateien ([facts] in der Konfiguration): je Datei ihre Fakten mit Selektor, Art, Label, Überschriftenpfad, Zeile, Zustand und Gruppe, der Zustand der Freigabe der ganzen Datei (file:) und die Zahlen je Gruppe – ohne sources jede Faktendatei

POST /api/approve-facts {sources}

jedes noch nicht freigegebene Fakt dieser Faktendateien freigeben, und jede Datei als Ganzes

GET /api/events

Server-Sent Events {"type": "changed", "sources": […], "review": …, "config": …}, wenn sich .deciwa/ oder eine geprüfte Datei ändert

Dateien ohne Build liest ihr Adapter bei Bedarf (Adapter), ein einfacher Markdown-Ordner wie eine Wissensbasis braucht also kein Sphinx: deciwa todo, show und die Projektübersicht umfassen jede Datei mit Review-Daten und jede Datei unter review.paths.

Overlay in einem Host

In einem Host bekommt das O... (DEC_HOST_ELEMENTS)

Der Host markiert seine dargestellte Ansicht:

  • jeder Block trägt data-line="<erste Quellzeile, ab 0>" – so wie markdown-it es mit seinen Token-Maps macht und wie es die Markdown-Vorschau von VS Code schon tut; die Zeilen zählen die Frontmatter mit,

  • der Host-Adapter setzt data-deciwa-source="<Pfad relativ zur Wurzel>" auf den Container.

hostElements() in packages/ui/js/host.js lädt selbst nichts: der Adapter übergibt die Elemente aus /api/elements, und jedes wird dem Block seiner Art zugeordnet, der auf seiner Zeile beginnt (Überschrift → h1–h6, Absatz → p, Listenpunkt → li, Zeile → tr, Code → pre). Elemente eines Build-Index ohne genaue Zeilen (Sphinx) werden über ihren Text gefunden. Blöcke ohne Treffer sind nicht prüfbar.

startOverlay() nimmt einige Optionen für Hosts: api (Aufrufe gehen über den Host statt über fetch), scroller (das Element, in dem der Inhalt scrollt; die Oberfläche wird darin eingehängt), keys: "review" (Tasten nur im Review-Modus – der Host behält seine eigenen Kürzel), tools: false (keine schwebende Leiste), openDoc (eine andere Datei im Host öffnen) und focus. Es liefert dock() / undock(), um das Panel in das Seitenpanel des Hosts zu setzen, sowie setReview(), focus(), refresh() und destroy(). Baumansichten geben außerdem reveal(node) mit (siehe unten).

Zeilenansichten (Quelltext): der Host markiert jede Zeile mit data-line; mit hostElements(container, elements, {ranges: true}) werden die Zeilen von line bis end jedes Elements zu einem Block zusammengefasst, verschachtelt wie die Elemente, sodass Methoden in ihrer Klasse liegen. unwrapRanges() macht das rückgängig.

Baumansichten (JSON, YAML): der Host markiert jeden Knoten des Baums mit data-pointer="<JSON Pointer>". Elemente mit einem pointer (die Daten-Adapter, JSON- und YAML-Dateien werd... (DEC_DATA_ADAPTERS)) werden dem Knoten mit demselben Pointer zugeordnet (pointerElements() in host.js). Ein Baum versteckt zugeklappte Knoten, deshalb gibt der Host reveal(node) an startOverlay(): das Overlay ruft es auf, bevor es ein Element zeigt oder öffnet, und der Host klappt die Knoten darum herum auf. Die Zustandsbalken überspringen versteckte Elemente.

In einem Diff läuft das Overlay nur auf der neuen Seite; die alte Seite ist nur lesbar. Dargestellte HTML-Dateien: der Host markiert jedes Start-Tag mit data-line; die Elemente kommen vom HTML-Adapter der Engine und werden über Zeile und Tag zugeordnet (HTML-Dateien liest ein Adap... (DEC_HTML_ADAPTER)). Nur eine Seite, die der Adapter nicht lesen kann, fällt auf den DOM-Scan des Web-Skripts zurück, dessen Elemente mit POST /api/elements an die Engine gehen.

Die monsterbrain-Erweiterung

packages/monsterbrain verbindet die Erweiterungsschnittstelle v0 von monsterbrain (docs/extensions.md im monsterbrain-Repository) mit Client und Overlay:

Erweiterungspunkt von monsterbrain

deciwa nutzt ihn für

Hintergrundprozess (onRoot, deactivate)

die Engine für den offenen Ordner starten, mit der App beenden

Aufrufe und Ereignisse

die API-Aufrufe des Fensters laufen über den Hauptprozess (der Token bleibt dort); Änderungsereignisse aktualisieren Overlays und Markierungen

Einbindung in Ansichten (mountView)

Overlay auf dargestelltem Markdown (mode: "rendered"), auf Code-Ansichten (mode: "lines", Zeilenbereiche) und auf dem Baum von JSON- und YAML-Dateien (mode: "tree", Knoten über data-pointer, reveal(node) klappt zugeklappte Knoten auf) – nicht auf der alten Seite eines Diffs

Frame-Skripte

Overlay in dargestellten HTML-Seiten; monsterbrain markiert Start-Tags mit data-line; Aufrufe aus Seiten erreichen nur Lesen und Feedback

Panel-Abschnitt

das deciwa-Panel der Datei, angedockt (dock()), oder Set up review für einen Ordner ohne .deciwa/

Werkzeugleiste

der Schalter Review on/off neben View · Source · Diff

Markierungen

Markierungen in Baum und Änderungsansicht aus /api/summary: 2? Fragen, eine Zahl für Aufgaben, 1! veraltet, 3/5 Pflicht, ✓

Befehle

Shift R (Review-Modus); die Tasten des Overlays in der Hilfe von monsterbrain

Kinder von Ansichten der Seitenleiste

die Fakten-Ansicht: die Fakten jeder Datei aus /api/facts, ein Klick wählt das Fakt im Review-Modus aus, die Aktion Approve all facts (Shift A)

MCP-Tools

deciwa_feedback, deciwa_show

Ansichten, die geöffnet werden, während die Engine noch startet, verbinden sich, sobald sie bereit ist. Der Review-Modus ist eine Einstellung für alle Dateien: das Overlay merkt ihn sich, und dargestellte HTML-Seiten folgen ihm.

Client

Ein TypeScript-Client für a... (DEC_CLIENT_PACKAGE)

packages/client (@danwos/deciwa-client) läuft in Node – im Haupt- oder Erweiterungsprozess des Hosts, nie in einer Seite, so bleibt der Token dort:

  • findEngine() – der Pfad aus den Einstellungen des Hosts, die mit dem Host gelieferten Engines, dann deciwa im PATH,

  • new Engine({root, enginePath, bundled}).start() – startet serve --api-only, liest den Handshake, lehnt eine andere API-Hauptversion ab (api-mismatch), startet nach einem Absturz neu (höchstens dreimal pro Minute),

  • typisierte Aufrufe (elements, page, summary, todo, annotate, hostPage, call für jeden Endpunkt) und events() mit Wiederverbindung,

  • initFolder() – deciwa init --at <ordner>.

npm test in packages/client startet die Engine des Checkouts gegen einen temporären Ordner.

Eigenständige Engine

Vorschlag: Die Engine wird mit PyInstaller gebaut, ein Ordner pro Plattform PROP_ENGINE_BINARY
status: draft
  • Inhalt: deciwa-core, -server, -cli und die Overlay-Dateien von deciwa-ui. Nicht deciwa-sphinx: Sphinx-Builds laufen weiter in der eigenen Python-Umgebung des Doku-Projekts.

  • Form: PyInstaller one-folder (startet schnell; one-file entpackt bei jedem Start), damit der Host jede Datei darin signieren kann.

  • Plattformen: linux-x64, linux-arm64, macos-arm64, macos-x64, windows-x64 – gebaut in GitHub Actions auf jeder Plattform, kurz getestet mit deciwa --version und serve --api-only gegen einen Testordner.

  • Release: ein Zip pro Plattform in den Releases von danwos/deciwa. Ein Host legt eine Engine-Version fest und holt sie beim eigenen Build; er lädt nie zur Laufzeit Code herunter.

  • Signieren: der Host signiert die mitgelieferte Engine zusammen mit seinem eigenen Code (die Notarisierung bei Apple verlangt, dass jedes Binary in der App signiert ist).

  • Größe: erwartet 20–40 MB pro Plattform; mit dem ersten Build zu messen.

Vorschlag: VS Code bekommt ein Paket pro Plattform mit der Engine darin PROP_VSCODE_PLATFORM
status: draft

vsce package --target <platform> baut ein Erweiterungspaket pro Plattform, jedes mit seiner Engine. Ein universelles Paket ohne Engine nutzt deciwa im PATH – für Plattformen ohne Build.

Frage: Welches Werkzeug baut die eigenständige Engine? Q_ENGINE_BINARY_TOOL
status: open
to: Daniel

Vorschlag: PyInstaller – weit verbreitet, einfach, kein C-Compiler. Alternativen: Nuitka (übersetzt nach C: schneller und kleiner, aber lange Builds und ein C-Compiler pro Plattform); python-build-standalone plus die installierten Pakete (keine Probleme beim Einfrieren, aber größer und viele lose Dateien).