Erweiterungen (Schnittstelle v0)

Instabil. Abgeleitet nur aus dem, was die erste Erweiterung, deciwa, braucht; sie ändert sich mit der nächsten Erweiterung. Kein Marketplace, keine Sandbox: Eine Erweiterung läuft mit vollem Node-Zugriff im Hauptprozess, deshalb lädt monsterbrain nur Ordner, die in seinen Einstellungen stehen (Settings → Extensions, gespeichert in settings.json).

"extensions": [
  { "path": "/home/daniel/workspace/deciwa/packages/monsterbrain", "options": { "enginePath": "…" } }
]

options wird der Erweiterung unverändert übergeben; "enabled": false behält einen Eintrag, ohne ihn zu laden. Änderungen gelten nach einem Neustart (Restart to apply).

Manifest

Der Ordner der Erweiterung hat eine package.json mit einem Feld monsterbrain:

"monsterbrain": {
  "id": "deciwa", "name": "deciwa", "api": 0,
  "main": "dist/main.cjs",
  "view": "dist/view.js",
  "frame": "dist/frame.js"
}

Teil

Läuft in

Geladen

main

Hauptprozess (Node, CommonJS)

require() beim Start, dann activate(ctx); deactivate(), bevor die App beendet wird (höchstens 3 s)

view

dem Fenster

als Skript von mb://ext/<id>/…

frame

gerenderten HTML-Seiten (Frames mit Sandbox)

wird der Seite hinzugefügt, wenn monsterbrain sie zeigt (mb://file/<page>?mbx)

api muss zur Schnittstellenversion passen (EXTENSION_API in src/shared/extensions.ts); andere Versionen lehnt monsterbrain ab.

Erweiterungspunkte

Punkt

Hauptprozess (ctx)

Fenster (window.mbx.register(id, contribution))

Hintergrundprozess

ctx.onRoot(cb) – sofort mit dem offenen Ordner aufgerufen und bei jedem Wechsel; deactivate() beim Beenden

–

Aufrufe und Events

ctx.handle(method, fn), ctx.emit(event, data)

channel.call(method, …args), channel.on(event, cb)

Einbinden in Ansichten

–

mountView(v) für jede gerenderte Ansicht; gibt das Aufräumen zurück

Abschnitt im Panel

–

panel: { title, mount(el, {path, kind}) } – ein Abschnitt im rechten Panel

Toolbar

–

toolbar: { mount(el, {path, kind}) } – ein Element im Kopf der Datei, neben View / Source / Diff

Markierungen

ctx.decorate({path: {badge, color, title}})

im Baum, in der Änderungsansicht und in Suchergebnissen angezeigt

Befehle

–

commands: [{id, title, key, run}] – Tasten wirken, wenn gerade nichts in ein Feld getippt wird; in der Hilfe (F1) unter dem Namen der Erweiterung aufgeführt; ohne run nur aufgeführt

MCP-Tools

ctx.tool({name, description, params, readOnly, run})

–

Agent-Aktionen

ctx.agent({action, prompt, meta}) – gibt eine Anfrage an die Claude-Code-Session des offenen Ordners weiter; hört keine zu → kann der Nutzer eine starten, die sie bekommt, sobald sie bereit ist. Gibt {sent, session, started} zurück. Nur auf einen Klick oder eine Taste des Nutzers

–

Konzepte

ctx.concepts(path) – die Konzepte, zu denen eine Datei gehört: zuerst das, in dessen Ordner sie liegt, dann die, die sie (oder einen Ordner darüber) unter results: aufführen; jedes mit folder, title, open, status, results

–

Außerdem auf ctx: root(), open(path, {tab, highlight, newTab}), state(), log(), options, path.

Ansichten

mountView(v) bekommt jede gerenderte Markdown-Ansicht und jede Code-Ansicht (Quelltext mit Zeilennummern):

Feld

path

Dateipfad relativ zum offenen Ordner

kind

die Dateiart: markdown, code, json, yaml, text, …

role

view (die Datei), diff (die neue Seite eines Diffs), before (die alte Seite, aus Git)

rev

die Git-Revision der Seite before

mode

rendered (Markdown so, wie es ein Leser sieht) oder lines (die Code-Ansicht; auch der Tab Source einer Markdown-Datei)

element

der Inhalt. rendered: Jeder Block trägt data-line – seine erste Quellzeile in der Datei, ab 0 gezählt, Frontmatter mitgezählt (wie in der Markdown-Vorschau von VS Code). lines: ein <pre> mit einem Element pro Zeile, jedes mit data-line; eine Erweiterung darf Zeilen in eigene Elemente gruppieren – ein geänderter Text bekommt ein neues <pre>

scroller

das Element, in dem der Inhalt scrollt (position: relative), für absolut platzierte UI

Eine Ansicht wird neu eingebunden, wenn sich ihr Inhalt ändert. Tasten, die eine Erweiterung selbst behandelt, sollten preventDefault() aufrufen; monsterbrain ignoriert sie dann.

HTML-Seiten

HTML-Dateien werden in einem Frame mit sandbox="allow-scripts allow-popups" gezeigt. monsterbrain markiert jedes Start-Tag mit data-line (die Zeile, in der es beginnt, ab 0 gezählt) und setzt vor die Skripte des Frames eine Brücke: window.mbx.path (der Pfad der Seite), window.mbx.call(id, method, …args) und window.mbx.on(id, event, cb) – vom Fenster an den Hauptteil der Erweiterung weitergereicht. Jedes Skript der Seite kann solche Aufrufe senden, deshalb erreichen sie nur Handler, die mit ctx.handle(method, fn, { frames: true }) registriert sind. Nur Seiten des Arbeitsverzeichnisses bekommen die Skripte, nicht die alte Seite eines Diffs.