Zweiter Notiz-Typ neben Markdown. Beide tragen dieselben Angaben, nur an
ihrer jeweils üblichen Stelle: Markdown im Frontmatter, HTML in <title>
und <meta name=…>.
- domain/archive_html.rs: Gerüst, Metadaten, Titel setzen, Rumpf lesen und
ersetzen, Text ohne Markup für den Suchindex.
- Der Scan nimmt .html auf; Doc und WikiDocEntry führen `kind` (md|html).
doc_path, set_title, write_body, ensure_ids und die Knotentext-Regel
arbeiten typbewusst; ein Knotentext darf .md oder .html sein.
- archive_create_html legt eine leere HTML-Notiz an; Anlegen schreibt nicht
mehr in den Entwurfs-Puffer, sondern liefert die ID der neuen Notiz —
die Ansicht wählt sie aus und öffnet den Editor.
- Anzeige: HTML-Notizen erscheinen als Markup statt durch den
Markdown-Renderer, mit klickbaren Wikilinks; eigenes Symbol im Baum.
- Editor: html-editor.ts auf ProseMirror (MIT, ohne Anbieter-Stufe).
DOMParser liest den Rumpf, DOMSerializer schreibt ihn zurück — gespeichert
wird, was der Editor zeigt. Werkzeugleiste mit Überschriften, Auszeichnung,
Listen, Ein-/Ausrücken, Tabellen und Links; Tastenkürzel für fett, kursiv,
Rückgängig und Zellenwechsel. Markdown behält den Rohtext-Editor mit
Live-Vorschau.
- CSP: style-src erlaubt 'unsafe-inline', sonst blockiert die Richtlinie die
Stil-Attribute in HTML-Notizen und alles erscheint unformatiert.
script-src bleibt streng.
Bisher war der Dateipfad die Identität einer Notiz: Umbenennen brach
Verweise, und der Pfad tauchte in der Oberfläche auf (Tooltips, Menüpunkte
"Dateiname ändern"/"Ordnerpfad ändern"). Jede Notiz trägt jetzt eine
technische ID im Frontmatter (id: <uuid>), die nie wechselt; der
Systempfad ist nur noch eine Eigenschaft.
- ensure_ids ergänzt fehlende IDs beim Seitenaufbau (wie ensure_node_texts);
frontmatter() schreibt sie bei jedem Anlegen als erste Zeile.
- Doc, WikiDocEntry, FolderNode und Suchtreffer führen die ID mit;
resolve_id löst sie auf den aktuellen relpath auf.
- Commands sprechen IDs: archive_read/write/set_title/delete nehmen `id`,
archive_create_doc/create_folder die ID des Elternknotens plus Namen,
panel_archive_cmd den Zielknoten als ID.
- Frontend adressiert durchgehend über IDs: Auswahl, Klapp-Zustand,
Verlauf des Zurück-Knopfs, Wikilink-Sprünge, Suchtreffer-Vormerkung und
der Zielordner-Baum des Archiv-Dialogs.
- Der Pfad ist aus der Oberfläche verschwunden: die Menüpunkte zum
Umbenennen von Datei und Ordner samt Commands (archive_rename,
archive_move, archive_move_folder) sind entfallen — es gibt nur noch den
Titel, Name und Titel können nicht mehr auseinanderlaufen.
Offen dadurch: Verschieben im Baum fehlt (ToDo: Drag & Drop).
Archiv-Dialog nebenbei überarbeitet: modales Popup im Design der
Archiv-Ansicht mit Abbrechen und zuverlässigem Escape, Zielordner über
einen einklappbaren Baum statt Pfadeingabe, zusätzlicher Knopf "Auf Platte
legen" (panel_save_as); Archivieren öffnet keinen Dateimanager mehr.
Trilium-Integration komplett zurückgenommen (Revert von 47951a6): keine
verwaltete Instanz, kein Runtime-Download, kein ETAPI, kein Keyring-Token,
kein Setup-Wizard. Das Archiv sind wieder Markdown-Dateien unter archiveHome
samt FTS5-Suche und Wikilinks.
Notizmodell (an Trilium orientiert, ohne dessen Überbau):
- Jeder Knoten besitzt eine Textdatei — ensure_node_texts legt fehlende beim
Seitenaufbau an (Ordner: gleichnamiges .md daneben, Wurzel: index.md);
Ordner und Zwillingsdatei sind EINE Notiz mit Inhalt und Kindern.
- Der angezeigte Titel steht im Frontmatter der Datei, der Datei-/Ordnername
ist technischer Verwaltungsname; move_folder nimmt den Knotentext mit.
Archiv-Ansicht (wiki-view):
- Baum links: Knoten- und Blatt-Symbole, Führungslinien pro Ebene, Dokumente
näher an der Linie als Ordner; ganze Zeile wählt aus, nur der Pfeil klappt.
- Notiz-Ansicht rechts: großer Titel (Klick bearbeitet ihn → archive_set_title),
Zurück-Knopf mit Auswahl-Verlauf, Details als Popup am Info-Knopf, Kindliste
als abgesetzter Karten-Block mit Anlage-/Änderungsdatum.
- Bearbeiten in place: Split-View aus Rohtext und Live-Vorschau, Speichern per
Knopf oder Ctrl+S (archive_read/archive_write; Frontmatter bleibt).
- Rechte Maustaste im Baum als einziger Aktionsweg (eigenes Kontextmenü,
Standard-Menü des Webviews aus); Anlegen/Umbenennen über modale Dialoge.
Feste Flächenaufteilung statt Ablösen/Andocken:
- Angedocktes Panel = Session-Begleiter (ToDo, Befehle, flüchtiger Entwurf);
der Dokument-Tab ist aus der Leiste raus.
- Archiv-Fenster = Archiv + Suche, Größe und Position einmalig beim Öffnen
aus dem Monitor des rufenden Terminal-Fensters (85 % / 92 %); Öffner-Klick
bei stehendem Fenster fokussiert und schaltet den Tab (panel-mode).
- Terminal-Fenster zu → Archiv-Fenster geht mit.
Neue Commands: archive_read, archive_write, archive_set_title.
terminal/panel/popup.html laden ihre Styles jetzt als erste Imports der
jeweiligen Entries (Kaskade wie zuvor: Fenster-CSS vor xterm/fonts); devCsp
behält unsafe-inline für die Vite-HMR-Style-Injektion.
Uebersetzt waren bisher nur die Vue-Fenster; Terminal, Panel und Popup hatten
ihre Beschriftungen hart auf Deutsch im Markup und in den Views -- ein
englisches UI blieb zur Haelfte deutsch.
Die Tabellen ziehen nach messages.ts um, dazu ein Vue-freier t() und ein
applyI18n(), das statisches Markup ueber data-i18n-Marker beschriftet.
i18n.ts bleibt der vue-i18n-Wrapper fuer die Vue-Fenster. So kommt kein Vue
in die Terminal- und Panel-Bundles (Terminal 657,02 -> 657,06 kB).
Neue Namensraeume: panel, popup, commands, archiveForm, search, wiki.
toLocaleTimeString folgt der Sprache statt fest 'de'.
Zwei Funde nebenbei:
- window.localStorage wird ueber try/catch gelesen. Gesperrter Storage
(privater Modus) wirft schon beim Lesen, und unter Node 22 ueberschattet
ein undefiniertes globales localStorage das der Testumgebung.
- Die Frontend-Tests liefen unbemerkt gegen happy-doms en-US.
test-setup.ts nagelt die Sprache fest.
49 Tests (39 bestehende, 10 neue fuer Tabellen-Paritaet, t() und applyI18n).
- Projekt-Config zieht von ai-control.json nach .ai-control/config.json um,
das Icon liegt daneben und synct mit dem Projekt.
- Jedes Projekt trägt eine UUID (id) und den Anzeigenamen (name) in der
Config; die UUID ist Registry-Schlüssel und project-Parameter aller
Commands, der Name reine Darstellung.
- Pool-Zuordnung ist maschinenlokal und liegt in der projects.json-Registry,
nicht mehr in der syncbaren Projekt-Config.
- open_terminal prüft die ID im Ordner gegen die Registry (verschobene oder
ersetzte Ordner scheitern laut).
- Import übernimmt eine mitgebrachte ID, legt Arbeitsordner und Archiv-Home
an und zieht die Archiv-Permission nach.
- Migration beim App-Start: Alt-Datei umziehen, Pool in die Registry,
Icons aus ~/.config/ai-control/icons ins Projekt, Registry auf UUIDs.
- ProjectConfig reicht unbekannte Keys per serde(flatten) durch den
Round-Trip (Regressionstest config_roundtrip_erhaelt_fremde_keys).
- Slug transliteriert Umlaute/ß (fuer statt f-r); aktiver Tab mit Akzent +
Unterstrich; kein aktiver Tab bei zugeklapptem Panel (mode.clear)
- Suche: Live-Update auch beim Löschen (<3 Zeichen: Hinweis), #tag-Filter in
der Query, Treffer öffnen im Dokument-Tab (panel_load, ohne Frontmatter);
Wiki-Sprung-Button im Dokument; Wiki-Fehler sichtbar als Toast
- Archiv-Formular am Archiv-Button (Ordner/Beschreibung/Schlagwörter);
panel_archive_cmd nimmt Meta entgegen
- Wiki-Übersicht: Zuletzt-Sektion, Backlink-Zähler, Wurzel-Eyebrow
- Themes: Panel-Farben über CSS-Variablen, applyTheme leitet sie aus dem
jeweiligen Theme ab (auch helle); gemeinsames themes.ts
- Fenster: Doppelklick maximiert; gelöstes Fenster merkt Größe/Position
(Window-ACL: set-position/outer-position/inner-size ergänzt);
open_panel_window async (GTK-Deadlock-Vorgabe); Panel-Fenster spiegelt
JS-Fehler ins Dev-Log
- Archiv pro Projekt wähl-/abwählbar (Einstellungsdialog, setzt/entfernt
Permissions); require_archive_home legt den Ordner an; ohne Archiv nur
Befehle+Dokument im Panel
- Frontend-Tests: vitest + happy-dom, 27 Tests über Modus-, Such-, Wiki-,
Editor- und Formular-Logik (npm test)
- 1-px-Fensterrahmen in Theme-Rahmenfarbe für die rahmenlosen Fenster (Linux)
- Suchfeld: Live-Suche ab 3 Zeichen mit 300-ms-Debounce, letztes Wort als
Präfix (arch → arch*); Enter sucht wörtlich (exakte FTS-Syntax)
- Gelöstes Fenster: Minimieren/Maximieren neben Andocken/Schließen
- Archiv-Home pro Projekt (archiveHome in ai-control.json); archive_panel
mit Ordner, Beschreibung und Schlagwörtern (Frontmatter + Zeitstempel-Stem)
- Archiv-Index (archive_index.rs): Scan mit Frontmatter, Wikilinks,
Backlinks; Wiki-Seiten als strukturierte Daten (Übersicht/Tag-Seiten)
- FTS5-Suche (archive_search.rs, rusqlite bundled): in-memory-Index pro
Anfrage; MCP search_archive und Panel-Suchfeld (search_run) teilen die Engine
- Panel: vier Puffer/Ansichten (Dokument, Befehle, Suche, Wiki) mit Tabs im
Fenster-Header; gemeinsame Verdrahtung panel-wiring.ts, Kachel-CSS,
Wiki-View mit Tag-Chips, Ordner-Sektionen und Backlinks
- Archivieren speichert offene Bearbeitung (flush); Tab-Wechsel speichert
statt zu blockieren; Fehler sichtbar als Panel-Toast
- Abgelöstes Fenster: rahmenlos (Linux), eigene Kopfleiste mit Tabs und
Fensterknöpfen, Theme-Kopplung über gemeinsames themes.ts
- MCP-Tools show_commands, show_archive; Befehls-History mit Kachel-Löschen
- register_mcp_server schreibt .claude.json nur bei fehlendem/abweichendem
Eintrag (claudes Live-State nicht unnötig ueberschreiben).
- Content-Editor im Panel (Rohtext-Textarea): Cmd/Ctrl+Enter speichert via
panel_set, Esc verwirft; eingehende Updates werden waehrend der Bearbeitung
gepuffert (Button "geaendert"), Speichern gewinnt.
- Archivieren zeigt die Datei danach im Dateimanager (reveal_path_cmd, cfg pro
OS). Breadth-Guard: Archiv-Ordner darf kein Home-Vorfahre sein, muss absolut
sein; expand_home loest bare ~ auf.
- Rechtschreibpruefung: Default in settings.json (spellcheckLang "de"), pro
Text per Selector ueberschreibbar.
- Archiv pro Projekt: Panel-Button „Archivieren" und MCP-Tool archive_panel
legen den Entwurf als <YYYY-MM-DD_HHMM>-<slug>.md mit Frontmatter im
Archiv-Ordner ab. Ordner in ai-control.json (archiveDir) + als
additionalDirectories/Edit in .claude/settings.json (scanbar). Kein Ordner:
Panel öffnet Ordner-Dialog, Zuruf nutzt Argument dir.
- Panel-Titel zeigt die erste Überschrift des Entwurfs (Inline-Markdown
gestrippt), Fallback „Entwurf"; Bleistift-Button macht ihn editierbar,
schreibt die Überschrift via panel_set zurück.
- Panel-Kopf zweizeilig: Titel + Edit oben, Aktionen rechtsbündig darunter.
- AI_CONTROL_PROJECT als PTY-Env für den MCP-Server.
- Andockbares Panel im Terminal-Fenster: Markdown-Rendering, Copy-Button,
normale Selektion; in eigenes Fenster ablösbar und wieder andockbar
(Splitter, panel-detached/panel-attached).
- MCP-stdio-Server (app --mcp-panel) mit Tool write_panel; schreibt in die
Datei aus AI_CONTROL_PANEL, Watcher zieht sie ins Panel.
- Provisionierung je Pool: Server-Registrierung in .claude.json (alwaysLoad),
Freigabe mcp__text-panel__write_panel in settings.json, Panel-Skill; bei
App-Start (alle Pools) und Pool-Anlage. Alte tee-Freigaben werden entfernt.
- Capability deckt panel-*-Fenster ab.
- Popup als rahmenloses Fenster mit D-Bus-Relay (popup.html/ts, Popup.vue);
GNOME-Extension schiebt es unter den Panel-Button
- Terminal: globale Schriftgröße via settings.json (terminalFontSize),
Zoom mit Ctrl/Cmd +/-/0 im Terminal
- trayLinux-Icon, Capabilities, App.vue/terminal.html angepasst
- Terminal-Einstellungen pro Projekt in ai-control.json: 5 Themes
(Paletten in terminal.ts, Fenster-BG gespiegelt in terminal.rs),
Dock-Icon (PNG/ICNS via NSApplication in RunEvent::Ready),
Fenstertitel mit Fallback Projektname; Zahnrad-Dialog mit Datei-Picker
(tauri-plugin-dialog)
- UI: Catppuccin-Mocha-Token, JetBrains Mono für Namen/Pfade/Chips,
feste Tabellenspalten, Status-Punkt mit Glow, Pool-Projekte als
Hover-Popover, Buttons ausgerichtet (Zahnrad links von Starten/Beenden)
- i18n: vue-i18n, Deutsch/Englisch, Umschalter im Header (localStorage)
- generate_context nur noch einmal expandiert (Release-Build-Fehler)
- Terminal-Fenster als eigener Prozess (--terminal <projekt>) mit eigener PTY,
startet claude-sync im Projektordner
- Projektliste: ein Button pro Zeile — grün Starten (open_terminal) bzw.
rot Beenden (stop_project, SIGTERM auf exakte PID / Ghostty-Quit)
- is_running erfasst Ghostty oder laufenden Terminal-Prozess
- Status-Kreis ohne Prozess unsichtbar