84 Commits

Author SHA1 Message Date
marcus hinz 47951a615b Trilium als Archiv: verwaltete Instanz pro Projekt, MD-Archiv und Dokument-Tab entfernt
- domain/trilium.rs: Runtime-Download (gepinnt 0.104.0), Instanz pro Projekt auf 127.0.0.1
  mit FNV-Port, ETAPI (archive_note, search_notes), Token im Keyring
- Setup bis aufs Passwort automatisiert: trilium_connect macht new-document (skipDemoDb),
  set-password und ETAPI-Login; Modul-Flag erst nach Token-Erfolg
- write_panel legt direkt eine Trilium-Notiz an (text|path, folder/description/tags);
  noteopen-Kanal, das Terminal-Fenster öffnet die Notiz (ersetzt archive_panel)
- MD-Altbestand raus: archive*/wiki*, archiveHome samt Permissions, panel_set/panel_load/
  wiki_open, panel_archive*/archive_docs/*_archive_home, reveal_path, spellcheck
- Dokument-Tab raus: Panel = ToDo/Befehle/Suche + Archiv-Knopf (trilium_open);
  panel-view/archive-form gelöscht, Markup/CSS/Messages bereinigt
- Lösch-Stufe Archiv: Instanz stoppen, Trilium-Datadir und Keyring-Token löschen
2026-07-24 21:42:03 +02:00
marcus hinz f58b9887c7 Archiv-Navigator: Baum nur Ordner + flache Inhaltsliste (Zeilen: öffnen/umbenennen/löschen), Ordner/Dokument anlegen (Dateiname ohne Stempel, Datum im Frontmatter), Write-back geöffneter Archiv-Dokumente über Quell-Verknüpfung; Ablösen übergibt aktiven Tab 2026-07-23 21:17:41 +02:00
marcus hinz 1523856ea7 Modul-System (Registry Backend+Frontend, generierte Tabs, Settings-Sektion); ToDo-Modul: persistente Liste mit Anlegen/Bearbeiten im Panel (todos_add/todos_update, Formular mit Abbrechen); alte Hook-Todoliste (OFFENE-PUNKTE.md) komplett entfernt 2026-07-23 11:35:29 +02:00
marcus hinz 513e1a768f Dopplungen konsolidiert: settings.json-Permissions-Helfer, pool.json-Lesen über read_pool, gemeinsame Helfer für Pool-Anlage, Projekt-Config, Icon-Übernahme und Running-Guard 2026-07-22 12:58:38 +02:00
marcus hinz f7a99b1176 README: Windows-follows wieder rein, nur Installer-Erwähnungen bleiben draußen 2026-07-22 12:38:00 +02:00
marcus hinz 8e95332552 README: Windows und AppImage gestrichen — beides wird nicht ausgeliefert 2026-07-22 12:35:54 +02:00
marcus hinz 704255e471 README: Screenshots ergänzt — Linux-Tray-Popups (GNOME/Cinnamon), Panel-Entwurf, Befehlskacheln, Archiv-Suche
Aufgenommen auf der VM-Flotte (0.3.0, echte App): Popups nach Auto-
Aktivierung der paketierten Extensions; Panel-Shots über ein Demo-Projekt
mit Inhalten über die Panel-Kanaldateien.
2026-07-22 12:04:48 +02:00
marcus hinz 257b2ca2ef Cinnamon-Extension automatisch aktivieren; README: Desktop-Integration explizit
- Neu cinnamon.rs: erweitert org.cinnamon enabled-extensions idempotent um
  ai-control-popup@local; Aufruf im SNI-Zweig von init_tray (is_cinnamon).
- README: GNOME-/Cinnamon-Extension und KWin-Script mit Pfad und Aufgabe
  benannt, Auto-Aktivierung dokumentiert (inkl. GNOME-Randfall nach
  Erstinstallation); Cinnamon-X11-Aussage korrigiert (Initial-Fokus).
2026-07-22 11:22:44 +02:00
marcusH f13186e667 macos: unbenutzte Konstante MOVE_DISMISSED entfernt
Der Settings-Key steht in settings.rs, die Konstante war ein
Ueberbleibsel und hat beim Release-Build gewarnt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 10:55:12 +02:00
marcusH ea08563411 Version 0.3.0, Selbstinstallation nach ~/Applications, Gatekeeper im README
Erster Start aus DMG oder Downloads bietet einmalig an, sich nach
~/Applications zu kopieren und von dort neu zu starten — der Weg dorthin
braucht kein Administrator-Passwort, anders als /Applications. Ein DMG
kann das nicht selbst leisten: der Applications-Alias darin ist ein
absoluter Symlink auf /Applications.

Die Kopie erbt per ditto die Quarantäne des Downloads, deshalb wird sie
am Ziel gelöst — sonst käme beim Neustart erneut die Gatekeeper-Warnung
für dieselbe, gerade laufende App. Ablehnen merkt sich die App
(moveOfferDismissed), im Debug-Build fragt sie nie.

README: ~/Applications als gleichwertiger Installationsort, dazu der
Weg über System-Einstellungen -> Datenschutz & Sicherheit fuer alle, die
kein Terminal aufmachen wollen.

0.8 ist fuer den Windows-Stand reserviert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 10:47:36 +02:00
marcusH 0faa1e48fd README: Anthropic-Abschnitt auf zwei klare Aussagen gebracht
"Claude and Anthropic" führt jetzt mit den beiden Punkten, auf die es
ankommt: keine Verbindung zu Anthropic, und kein Einfluss auf Lizenz
oder Nutzung — was mit Claude Code erlaubt ist, ist es hier auch, nicht
mehr und nicht weniger; jede Anfrage läuft unter dem eigenen Login.

Die Belege bleiben darunter: keine Tokens in der App, /login macht
claude selbst, Credentials im Keychain, Warnung vor dem Datei-Fallback.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 10:04:43 +02:00
marcusH a6dd567c0a README: Architekturübersicht, CSP-Zeile nachgezogen
Neuer Abschnitt Architecture: die drei Prozessrollen des einen Binaries
(aus Project layout hierher gezogen, dort steht jetzt ein Verweis), der
gemeinsame Look über die Plattformen und der Anchor-Kontrakt als
Tabelle — ein Codepfad show_popup, drei Herkünfte der Platzierung.

Dazu der ehrliche Linux-Absatz: Desktop x Sessiontyp x Tray-Host ist
eine breite Matrix, die kein Release ganz testet; auf einer ungetesteten
Kombination läuft das Popup, kann aber beim ersten Mal woanders landen
als am Icon.

Die CSP-Zeile im Sicherheitsmodell nennt jetzt style-src ohne
unsafe-inline und den Grund, warum die Fenster-Styles in eigenen
CSS-Dateien liegen. An tauri.conf.json gegengelesen: unsafe-inline gibt
es nur in der devCsp.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 09:56:08 +02:00
marcusH 4bc4174d24 README: Verbrauch und Ein-Klick-Session in die Feature-Liste
Beides konnte die App längst, stand aber nur weiter unten zwischen den
Konzepten — für den Verbrauch gab es sogar einen Screenshot, aber keine
Zeile Text.

Zeitraum und Kostenangabe an der UI abgelesen: UsageList bietet 7 oder
30 Tage, die Spalte weist die Kosten als Schätzung aus.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 09:47:55 +02:00
marcusH df828daea9 Pools können auf ein vorhandenes Config-Verzeichnis verweisen
Wer claude schon benutzt, hat einen fertigen Login in ~/.claude. Bisher
begann ai-control trotzdem bei null: jeder Pool war ein neu angelegtes
Verzeichnis, der erste Sessionstart verlangte /login. Ein Pool kann jetzt
stattdessen auf ein bestehendes Verzeichnis zeigen.

pool.json trägt dafür optional `dir` (home-kontrahiert). Der Pool-Ordner
ist dann nur die Hülle für diese Datei; pool_config_dir() löst auf und
ist die einzige Stelle, über die Sessionstart, Verbrauchsstatistik,
Panel-Provisionierung und Keychain-Name gehen.

Zeigt ein Pool auf claudes Default-Verzeichnis, bleibt CLAUDE_CONFIG_DIR
ungesetzt: claude nimmt dieses Verzeichnis von sich aus und damit den
unsuffixierten Keychain-Eintrag, an dem der bestehende Login hängt (am
Keychain gegengeprüft — "Claude Code-credentials" ohne Suffix neben den
suffixierten Pool-Einträgen). Ein Verweis auf ein anderes Verzeichnis
setzt die Variable wie gewohnt.

Das verwiesene Verzeichnis gehört der App nicht: dort entsteht nur die
Panel-Ausstattung (Skill, MCP-Eintrag, Freigabe-Ergänzung, alles
additiv), keine settings.json-Grundausstattung. Löschen trifft nur die
Hülle; Runtime-Symlinks und das Zurücksetzen des Keychain-Eintrags sind
gesperrt. Ein Verzeichnis kann nur ein Pool belegen, Ziele innerhalb von
pools/ sind ausgeschlossen.

In der UI erscheint der Knopf nur, wenn ~/.claude existiert und noch
kein Pool darauf zeigt; die Liste zeigt den Pfad unter dem Namen und
statt "Zurücksetzen" den Hinweis, dass die Anmeldung claude gehört.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 09:43:00 +02:00
marcusH 6b4afd2bc5 Name aICentral: README neu, sichtbare Titel umgestellt
README trägt jetzt aICentral mit der Tagline "Get Claude Code organized"
als eigene Zeile, dazu ein Hinweis auf die Unabhängigkeit von Anthropic
(Claude/Claude Code als fremde Marken, rein beschreibend genannt).

Sichtbare Stellen mitgezogen: Hauptfenster-Titel, Überschrift der
Verwaltung, Seitentitel, Linux-Tray-Titel und der AppImage-Hinweis
unter GNOME. Technische Bezeichner bleiben ai-control — Binary,
Identifier, SNI-Id und der Popup-Fenstertitel, auf den KWin-Script und
GNOME-Extension matchen.

Außerdem im README: deploy-macos.sh und deploy-windows.ps1 ergänzt, die
Installationswege pro OS beschrieben (macOS nach ~/Applications, das
Build-Bundle wandert danach nach macos.noindex), Panel-Tabs englisch
benannt und die Zweisprachigkeit der Oberfläche erwähnt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 09:10:47 +02:00
marcus hinz e7f98dd072 CSP: style-src ohne unsafe-inline — Fenster-Styles aus den HTML-Köpfen nach src/*-window.css
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.
2026-07-21 19:04:36 +02:00
marcus hinz bbb06e0814 Popup auf SNI-Desktops: Activate-Koordinaten (Anchor::Click) + Cinnamon-Extension
- SNI-Activate-Koordinaten gehen als Anchor::Click durch; Cinnamon liefert
  echte Werte, bei (0,0) bleibt der Cursor-Fallback (KDE/XFCE).
- Neue Cinnamon-Extension ai-control-popup@local: platziert das Popup unter
  Wayland am Zeiger (Work-Area-geklemmt, set_position ist dort wirkungslos)
  und gibt ihm unter X11 den initialen Fokus (Muffins Focus-Stealing-
  Prevention verwirft das present() der App).
- Extension in deb/rpm nach /usr/share/cinnamon/extensions paketiert.
- README: Cinnamon-Abschnitte und Installer-Teststand aktualisiert.

Verifiziert in der VM-Flotte: Cinnamon Wayland + X11, XFCE, KDE (Wayland),
GNOME (Wayland).
2026-07-21 11:24:18 +02:00
marcusH 1fa9ffcf1b i18n bis in die Terminal- und Panel-Fenster
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).
2026-07-20 22:36:19 +02:00
marcusH 92f34cb64d macOS: API-Key nicht mehr ueber die Kommandozeile an security
add-generic-password bekam den Key als -w-Argument; damit stand er fuer die
Dauer des Aufrufs in der Prozessliste und war per ps fuer jeden Nutzer des
Rechners lesbar. Jetzt kommt -w ohne Wert, security liest das Secret ueber
stdin (zweimal, Eingabe und Bestaetigung). Die Eingabeaufforderungen landen
auf stderr und werden aus der Fehlermeldung geschnitten.
2026-07-20 22:17:21 +02:00
marcusH e15e128fd3 deploy-macos.sh installiert nach ~/Applications
Bisher hat das Skript nur das Dev-Bundle aus Launch Services ausgetragen und
den DMG-Pfad ausgegeben; installiert wurde von Hand. Linux und Windows
installieren in ihren Deploy-Skripten, macOS war der Ausreisser.

Jetzt: alte Kopie austragen und loeschen (ditto merget sonst in ein
bestehendes Bundle hinein), neues Bundle per ditto nach ~/Applications,
lsregister -f. Guards vorweg gegen fehlendes Bundle und laufende Instanz --
eine laufende App haelt Dateien offen und ergaebe ein halb ueberschriebenes
Bundle.
2026-07-20 22:08:35 +02:00
marcus hinz e6226cfc9f README überarbeitet: aiCentral-Branding, alle sechs MCP-Tools, UUID-Registry, Sicherheitsmodell (CSP/Capabilities), dreistufiges Projekt-Löschen, Build/Deploy-Stand, Installer-Teststand mit offenen X11-Befunden 2026-07-20 20:43:09 +02:00
marcus hinz cf2c25df79 Archiv-Wechsel mit Migrations-Option
Bei gesetztem Archiv-Home fragt ein Dialog nach: Dokumente ins neue
Archiv verschieben (Checkbox, standardmäßig aus — nichts wandert
implizit) oder liegen lassen. change_archive_home_cmd setzt das neue
Home, zieht auf Wunsch die Einträge um (gleiche Platte rename, sonst
Kopie + Löschen; Kollision im Ziel bricht laut ab) und nimmt die Rechte
des alten Ordners zurück.
2026-07-20 13:48:49 +02:00
marcus hinz 347fc70982 Veraltete autogenerierte Permissions entfernt (remove_project, delete_project) 2026-07-20 13:37:34 +02:00
marcus hinz 6c765ff7b5 Projekt löschen in drei Stufen mit Artefakt-Vorschau; Listen-Scroll gefixt
Eskalationsleiter: 'integration' nimmt nur die ai-control-Spuren zurück
(Registry, .ai-control/, Archiv-Rechte + Todo-Hook in settings.json,
Panel-Dateien, .desktop — Ordner, memory/ und Claude-Code-Grundgerüst
bleiben), 'archive' löscht zusätzlich das Archiv, 'full' den Projekt-
ordner mit Arbeitsordner-Flag. delete_preview liefert die konkrete
Artefaktliste; der Dialog zeigt sie je Stufe. Ersetzt delete_project/
remove_project (Handler, App-ACL-Manifest und Capability nachgezogen).

Außerdem: main scrollt nicht mehr — Toolbars und Fehlerzeile stehen,
nur die Listen scrollen (alle drei Tabs, .list-scroll).
2026-07-20 13:37:02 +02:00
marcus hinz 6682040cc0 Command-History: stabile ID je Eintrag statt Index+Text-Abgleich
write_commands vergibt jedem Eintrag eine UUID; commands_delete löscht
darüber. Doppelklick oder ein zweites Fenster laufen ins 'bereits
entfernt' statt auf verschobene Indizes.
2026-07-20 13:37:02 +02:00
marcus hinz ab1c561d6c Robustheit: App-Settings-Lesepfad, Pool-Round-Trip, Archiv per create_new
- write_app_setting: nur eine fehlende Datei ergibt ein frisches Objekt;
  unlesbares/kaputtes JSON bricht ab, statt die übrigen App-Settings zu
  verwerfen.
- struct Pool reicht unbekannte Keys per serde(flatten) durch; Umbenennen
  schreibt den gelesenen Bestand zurück.
- Archiv-Dokumente entstehen über create_new (Kollisionsgarantie vom
  Dateisystem statt exists()-Vorabblick — TOCTOU beim Maschinen-Sync).
2026-07-20 13:37:02 +02:00
marcus hinz 446f52ca6d Settings-Dialog: feste Höhe min(60rem, 94vh) 2026-07-20 12:20:10 +02:00
marcus hinz 8068471120 Settings-Dialog: fester Kopf/Fuß mit scrollendem Mittelteil, Feinschliff
Breite min(48rem, 94vw), Schließen-Kreuz, kräftigerer Rahmen; Kopfzeile
und Aktionsleiste stehen fest, nur der Gruppen-Mittelteil scrollt, wenn
das Fenster niedriger ist als der Inhalt. Todo-Zeile über die volle
Dialogbreite; Aktions-Buttons einheitlich 10.5rem.
2026-07-20 12:01:21 +02:00
marcus hinz b743de5f34 Sicherheitsrunde II: PTY-Label, Tool-Grenzen, atomare Schreibvorgänge
- term_start nur noch für das eigene term-<projekt>-Fenster — das
  (abgelöste) Panel-Fenster kann keine Shell mehr starten und beschreiben.
  Die Tauri-ACL greift für App-Commands nachweislich nicht (kein
  __app-acl__-Manifest, Prüfung gegen tauri 2.11.5); die Label-Prüfung
  ist damit die Schranke, nicht deren Verdopplung.
- archive_panel verliert das dir-Argument: Archiv-Home samt dauerhafter
  Rechtevergabe (additionalDirectories + Edit-Allow) setzt nur noch die
  UI mit Nutzer-Dialog, kein Tool-Argument des Modells.
- write_panel(path) liest nur noch aus Projekt-, Arbeits- und
  Archiv-Ordnern (canonicalize, symlink-fest), reguläre Dateien bis 2 MB
  mit hartem Byte-Cap — der promptfreie Weg umgeht das
  Read-Permission-Modell von Claude Code nicht mehr.
- write_atomic (temp + rename) für alle JSON-Config-Schreiber: Projekt-
  Config, .claude/settings.json, Registry, App-Settings, pool.json,
  Pool-settings.json, claudes .claude.json, Todo-Hook.
- write_secret_file: create_new mit 0600 statt schreiben-und-abdichten;
  kein umask-Fenster, Symlinks werden nicht gefolgt.
- PTY-Umgebung: geerbte ANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN entfernt.
- panel_file & Geschwister prüfen die Projekt-ID (zweite Linie).
- Befehlskacheln filtern Bidi-/Zero-Width-Zeichen aus Anzeige und
  Zwischenablage; der Lösch-Abgleich behält den Originaltext.
2026-07-20 12:01:21 +02:00
marcus hinz 23f6562f50 Settings-Dialog neu: drei Gruppen, festes Zeilen-Grid, Sofort-Schreiber abgesetzt
Darstellung (Titel/Theme/Dock-Icon), Ordner (Projekt/Arbeitsordner/Archiv)
und Session (Todoliste) als Gruppen mit Eyebrow-Überschriften; jede Zeile
im Grid Label | Wert | Aktionen. Pfade ~-kontrahiert mit vollem Pfad im
Hover-Pop. Die Ordner-Gruppe schreibt sofort und ist als eigene Fläche
abgesetzt (eigener Hinweis); „gilt ab nächstem Start" hängt an der
Darstellungs-Gruppe statt global. Nur ProjectList.vue + i18n-Schlüssel.
2026-07-20 11:06:40 +02:00
marcus hinz a1c95dae4a Build und Deploy getrennt: gemeinsames build.sh, Deploy-Skripte pro OS
build.sh baut nur noch (OS-Weiche für die Bundle-Liste: macOS app,dmg,
Linux deb,rpm, Git-Bash nsis); die macOS-Nachbereitung (lsregister,
.noindex) zieht nach deploy-macos.sh um. deploy-linux.sh installiert das
jüngste Bundle (dnf: rpm -Uvh --force, apt: dpkg -i),
deploy-windows.ps1 startet den NSIS-Installer.
2026-07-20 11:01:33 +02:00
marcus hinz b9d006184a Projekt-Identität und -Config neu: .ai-control/config.json mit UUID und Name
- 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).
2026-07-20 11:01:33 +02:00
marcusH 6d44f77671 Sicherheitsrunde: Befehlsinjektion, Pool-Pfad, Namensprüfung, Bild-Beacon
Vier Befunde aus einer Prüfung entlang der Angriffsflächen (MCP-Tools,
Command-Grenze, Credentials, Schreibpfade und Abhängigkeiten):

- todo.rs: Der SessionStart-Hook interpolierte den Projektpfad unquotiert in
  eine Shell-Kommandozeile, die Claude Code bei jedem Sessionstart ausfuehrt.
  Ein Ordner `repo$(...)` -- etwa aus einem geklonten Fremd-Repo -- ergab
  dauerhafte Codeausfuehrung; ein Leerzeichen zerbrach den Hook still.
  Der Pfad wird jetzt gequotet, inklusive Apostroph.
- project_pool_dir: Der Pool-Name kommt aus der ai-control.json im
  Projektordner, also aus einer versionierten Datei. Ungeprueft bestimmte er
  mit ../ ein beliebiges Verzeichnis als CLAUDE_CONFIG_DIR, dessen
  settings.json wiederum apiKeyHelper traegt -- ein Kommando, das beim
  Sessionstart laeuft. Jetzt durch check_name abgesichert.
- check_name: Steuerzeichen, Backslash und fuehrender Punkt werden abgelehnt.
  Ein Newline im Projektnamen hing bisher eigene Schluessel an die .desktop-
  Datei; Exec= braucht keinen Schraegstrich, den der alte Check verbot.
- markdown.ts: Bilder duerfen nur noch lokale Ziele laden. Ein auswaertiges
  <img> laedt ohne Zutun und meldet damit IP, Zeitpunkt und im Pfad kodierte
  Daten -- der Panelinhalt stammt aus einer LLM-Session, ist also
  injizierbar. Schema-relative URLs (//host/x) waren durch ein zu laxes
  Muster erfasst. Links bleiben auswaerts erlaubt, jetzt mit
  rel="noopener noreferrer". escapeHtml escaped zusaetzlich das Apostroph.

Dazu cargo audit nachgeholt: plist 1.9.0 -> 1.10.0 hebt quick-xml auf 0.41.0
und schliesst RUSTSEC-2026-0194/0195 fuer den Laufzeitpfad. Die zweite
Instanz von quick-xml 0.39.4 bleibt ueber wayland-scanner im Lockfile --
ein proc-macro, das nur zur Compile-Zeit laeuft und ausgelieferte
Protokoll-XMLs parst, nicht im Binary landet.

77 Rust-Tests, 39 Frontend-Tests.
2026-07-19 23:47:29 +02:00
marcusH e245600235 Aufräumrunde zur Bugfix-Runde: Suche entzerrt, Flatten-Fix vervollständigt
- archive_search: match_expr in search() aufgelöst. sanitize_query lief zweimal
  pro Anfrage, und die Leer-Entscheidung stand an zwei Stellen mit leicht
  abweichender Bedingung.
- Der Tag-Filter geht jetzt durch dieselbe Quoting-Regel wie der Volltext. Ein
  leerer Tag ergab tags:"" und damit einen Syntaxfehler — erreichbar durch das
  angetippte #, den ersten Tastendruck jeder Tag-Suche.
- sanitize_query von 26 auf 12 Zeilen: split('"') und split_whitespace statt
  handgeschriebenem Tokenizer. Gleiches Ergebnis fuer alle Testeingaben.
- TerminalConfig bekommt ebenfalls serde flatten. Der Block wird als Ganzes
  mitgeschrieben, ein terminal.fontSize waere also weiterhin verloren gegangen;
  set_terminal_config_in traegt die unbekannten Keys jetzt herueber.
- markdown.test.ts enthielt ein literales NUL-Byte, wodurch git die Datei als
  binaer behandelte. Der Test erzeugt das Zeichen jetzt selbst.
- Kleineres: commands_delete-Bedingung als direkter Vergleich, eine
  Verschachtelungsebene in pool.rs, zwei redundante Kommentarbloecke.
  commands_delete benennt sich in der Doku als Provisorium.
2026-07-19 23:22:25 +02:00
marcusH b127269e89 Bugfix-Runde Panel/Archiv: Datenverlust, Suche, Löschen, Markdown
- ProjectConfig reicht unbekannte Keys durch (serde flatten). Bisher verlor
  jeder read-modify-write die Felder neuerer Versionen; so ging archiveHome
  bei der Pool-Zuweisung durch einen älteren Build verloren.
- Archiv-Suche: Nutzereingabe wird in einen FTS5-Ausdruck übersetzt, der nicht
  scheitern kann. ai-control, C++ oder eine halbe Phrase warfen bisher einen
  Syntaxfehler — bei der Live-Suche in jedem Tippzwischenstand.
- commands_delete: Befehlstext als Identität, Indizes werden geprüft. Bisher
  Panik oder Löschen der falschen Kachel, wenn die Panel-Indizes der Datei
  hinterherhingen.
- Archivieren überschreibt keine Datei mehr: Der Stempel hat Minutenauflösung,
  bei Kollision wird -2, -3, ... angehängt.
- archive_panel prüft erst auf leeres Panel, dann wird das Archiv-Home gesetzt;
  bisher blieb ein umkonfiguriertes Home trotz Meldung "nicht archiviert".
- Kaputte .claude.json eines Pools wird nicht mehr durch eine frische ersetzt;
  nur eine fehlende Datei rechtfertigt das.
- Archiv-Formular leert beim Schließen — sonst galten Ordner und Schlagwörter
  des vorigen Dokuments unbemerkt fürs nächste.
- Markdown fürs Panel entschärft (src/markdown.ts): rohes HTML wird als Text
  ausgegeben, Link- und Bildziele auf harmlose Schemata beschränkt. Das Panel
  teilt sich den Webview mit dem Terminal, dessen term_write in die PTY
  schreibt; ohne CSP war das ein Weg von Fremdinhalt zu Befehlsausführung.

Regressionstests je Fix: 73 Rust-Tests, 35 Frontend-Tests.
2026-07-19 23:04:17 +02:00
marcus hinz 1345ef799c panel-update: erst auf Dokument schalten, dann Inhalt setzen
Der Modus-Umschalter restauriert beim Wechsel den gemerkten Dokument-Titel;
kam ein Dokument aus der Suche, überschrieb das den frisch gesetzten Titel —
der Wiki-Sprung lief damit ins Leere.
2026-07-19 17:21:26 +02:00
marcus hinz 286513def8 Refinement-Runde Panel/Wiki: Bedienung, Themes, Archiv-Wahl, Frontend-Tests
- 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)
2026-07-19 17:08:05 +02:00
marcus hinz 81a663e020 Panel-Feinschliff: Fensterrahmen, Live-Suche, Min/Max im gelösten Fenster
- 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
2026-07-19 15:32:05 +02:00
marcus hinz 994d5070f0 Archiv-Wiki im Panel: vier Tabs, FTS5-Suche, strukturierbares Archiv
- 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
2026-07-19 15:25:40 +02:00
marcus hinz d4d455fa08 Popup-Fokus auf SNI-X11-Desktops: present() nach jedem Map
Muffin (Cinnamon) mappt das Popup ohne Fokus — das set_focus aus show_popup
läuft vor dem Map und fällt der Focus-Stealing-Prevention zum Opfer; ohne
initialen Fokus greift das Blur-Schließen nie. Ein map-event-Handler ruft
present(), GTK besorgt sich unter X11 dabei den echten Server-Timestamp.

Registriert nur unter X11 außerhalb von GNOME: auf GNOME/Wayland zeigt die
Extension das Popup, dort brach das Fokus-Grab den Klick-Weg (Ubuntu/Kubuntu).
Bestätigt auf Mint/Cinnamon, Ubuntu und Kubuntu.
2026-07-17 19:37:05 +02:00
marcus hinz be1e4aad3f Popup-Blur-Guard ohne Timer: Sperre fällt mit dem ersten Focused(true)
Bisher löste ein Thread die Sperre nach 350 ms (geraten gegen das
spuriose Focused(false), das KDE direkt nach show/set_focus feuert).
Jetzt steht die Sperre ab dem Anzeigen und fällt deterministisch mit
dem ersten echten Fokus-Event des Popups.
2026-07-17 00:17:17 +02:00
marcus hinz 3fe911040d KWin-Script lauffähig unter Plasma 6: KPackageStructure + frameGeometry-Objekt
- metadata.json: ohne KPackageStructure=KWin/Script verwirft KWin 6 das
  Paket schon beim Einsammeln (isScriptLoaded blieb false)
- main.js: KWin-Scripts laufen in reiner QJSEngine ohne QML-Globals,
  Qt.rect warf 'Qt is not defined' — die Engine konvertiert ein
  {x,y,width,height}-Objekt selbst nach QRectF
2026-07-16 20:47:23 +02:00
marcus hinz 8aba0eb315 GNOME-Extension: Popup schließt bei Klick auf Desktop/Shell-Chrome
Klick auf leere Fläche wechselt den Fensterfokus nicht, der Blur-Pfad
der App greift dort nicht. Solange das Popup offen ist, fängt ein
captured-event-Handler am Stage solche Klicks ab und relayt Hide per
D-Bus; Klicks auf den Panel-Button toggeln weiter selbst.
2026-07-15 20:10:33 +02:00
marcus hinz 9a99bca466 Modul-Split: Fachlogik nach domain/, OS-Code nach platform/, Tauri-Verdrahtung in app.rs/commands.rs
- lib.rs nur noch Prozessrollen-Dispatch + Panic-Tracer
- KWin-Script als KDE-Pendant zur GNOME-Extension (Popup ans Zeiger-
  Rechteck), wird von deb/rpm mit ausgeliefert
- SNI-Tray auf ksni (pure Rust), appindicator-Depends entfallen
2026-07-15 20:10:33 +02:00
marcus hinz cf844c45da Linux: nativer SNI-Tray für Nicht-GNOME-Desktops, pfadtragende fs-Fehler, Panic-Tracer
- Tray verzweigt: GNOME -> Extension/D-Bus, KDE/Cinnamon/LXQt -> natives
  SNI-Tray-Icon mit Menue (libappindicator liefert keine Klick-Events)
- fs-Aufrufe nennen bei Fehlern den Pfad statt bloss 'os error 2';
  is_dir-Guard in list_pools_in und Usage-Auswertung
- Panic-Hook schreibt kopierbaren Backtrace (profile.release debug = 1)
- AppImage unter GNOME gesperrt (rfd-Dialog), Verweis auf deb/rpm
- deb/rpm liefern die GNOME-Extension mit; Appindicator als Depends
- Bundle-Targets um deb/rpm/appimage erweitert
2026-07-12 18:06:35 +02:00
marcus hinz b1a2291aef EOB 2026-07-12 00:35:09 +02:00
marcus hinz ce4e48e311 SVG-Icons statt ICNS, Popup-Höhe an Monitor begrenzt, GNOME-Shell-Extension für Popup-Positionierung, Bundle-Targets explizit 2026-07-11 21:45:20 +02:00
marcus.hinz 165501c8f9 Panel: Clobber-Schutz, Content-Editor, Archiv-Reveal/Guard, Rechtschreib-Sprache
- 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.
2026-07-11 14:24:16 +02:00
marcus.hinz e2e9992b1c Panel: Entwürfe archivieren, Titel aus Überschrift, Titel-Edit
- 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.
2026-07-11 13:40:17 +02:00
marcus.hinz 8aa758ae64 Entwurfs-Panel mit MCP-Tool write_panel
- 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.
2026-07-11 12:44:51 +02:00