Files
claude-ai-control/memory/ai-control-pool-setup.md

14 KiB
Raw Permalink Blame History

name, description, metadata
name description metadata
ai-control-pool-setup Stand des Pool-Setups seit 2026-07-03 — Layout, Starter, was gelöscht wurde, offene Punkte
node_type type originSessionId modified
memory project e108ad75-f176-43b6-901d-c3ec19ec3961 2026-07-20T10:22:53.939Z

Stand 2026-07-20 (ersetzt die älteren Layout-Angaben unten): Projekt-Config liegt in <projekt>/.ai-control/ (config.json mit Projekt-UUID id, Anzeigename name, terminal, archiveHome; Icon als icon.png daneben — synct mit dem Projekt). ai-control.json und das zentrale icons/-Verzeichnis sind migriert (Migration läuft idempotent beim App-Start). Die Registry ~/.config/ai-control/projects.json ist über die Projekt-UUID geschlüsselt und trägt Pfad + maschinenlokale Pool-Zuordnung; alle Commands/Fensterlabels/app_ids adressieren die UUID, der Name ist Darstellung. open_terminal prüft ID im Ordner gegen die Registry. Build/Deploy: gemeinsames build.sh (OS-Weiche) + deploy-linux.sh/deploy-macos.sh/deploy-windows.ps1; auf der Linux-Box per rpm (rpm -Uvh --force, Version 0.2.0). Sicherheitsrunde II umgesetzt (PTY-Label-Prüfung, archive_panel ohne dir, write_panel-Allowlist, write_atomic, Secret-Files, PTY-Env, Bidi-Filter); Tauri-Fenster-ACL greift für App-Commands nachweislich nicht (kein __app-acl__-Manifest) — offene Punkte in OFFENE-PUNKTE.md des Control-Repos.

Seit 2026-07-03 produktiv:

  • Pools: ~/.config/ai-control/pools/<pool>/ = CLAUDE_CONFIG_DIR. pool.json (name, credentialType), oauth: .credentials.json, apikey: apikey + apiKeyHelper in pool-settings.json. Pools (umbenannt 2026-07-03 abends): privateDefault (vorher Mx9Privat; oauth), apiDefault (vorher TestWürth; apikey — 2026-07-03 kurz auf oauth, am selben Tag zurück auf apikey via apiKeyHelper in Pool-settings.json; model claude-sonnet-5). Alle 7 Projekte → privateDefault; apiDefault derzeit ohne Projekt. Pool-Wechsel eines Projekts = nur noch ai-control.json ändern (einzige Quelle; zieht beim nächsten Start). Pool-Umbenennung ändert den Pfad und damit den Keychain-Suffix — alte Einträge greifen dann nicht mehr.
  • CLAUDE.md, commands/, settings.json liegen als physische Kopien in jedem Pool — bewusst poolspezifisch, keine Symlinks.
  • Zuordnung: ~/claude-projects/<projekt>/ai-control.json { "pool": ... }.
  • Starter: ~/Applications/Ghostty-<projekt>.app, LSEnvironment setzt nur noch XDG_CONFIG_HOME (stabil, nie poolabhängig). Alle Ghostty-Configs starten command = ~/.local/bin/claude-sync (ggf. mit --add-dir-Args). claude-sync löst seit 2026-07-04 den Pool selbst auf (liest ./ai-control.json im CWD, exportiert CLAUDE_CONFIG_DIR, laut scheiternd ohne Pool), macht git pull davor und commit+push danach. claude-start ist gelöscht — in claude-sync integriert. Env/plist tragen keinen Pool mehr.
  • Pool-Guard (seit 2026-07-04): claude-sync schreibt Sentinel .ai-control-running in den Projekt-Root (Inhalt pool=CLAUDE_CONFIG_DIR, pid; FD offen gehalten, nach claude-Ende gelöscht, in .gitignore). Vorab-Check (Endstand 2026-07-03 spät): Fensterzahl statt Prozesszustand, ohne Apple-Events — ghostty-wincount <app-pid> (Swift-Helfer, CGWindowListCopyWindowInfo onScreenOnly + Layer 0; Binary ~/.local/bin/ghostty-wincount, Quelle ~/claude-projects/robotunits/bin/ghostty-wincount.swift; App-pid via ps+grep auf den App-Pfad). Das Skript läuft selbst in Fenster 1; ≥2 → Arbeitsfenster existiert → open -a (Launch Services, kein Prompt) + 4 s + Exit 0; sonst → Sentinel-pid und FD-Holder kill -9, Sentinel kommentarlos löschen, normal starten. Gescheiterte Vorstufen: tty-Heuristik (Zombie behält totes tty), Schreiber-PID-Check (claude-sync-Bash überlebt Ghosttys X-Close manchmal kopflos), osascript count/activate (Automation-Prompt „App X will App Y steuern" = NOGO). Bekannte Grenze: minimierte/Space-fremde Fenster zählen als unsichtbar. Traps in claude-sync: EXIT löscht Sentinel, HUP/TERM killt claude (claude läuft als Hintergrund-Kind mit <&0 — sonst stdin=/dev/null! — und wait), INT no-op; greifen aber bei Ghostty-X/Quit oft nicht (hartes Kill), Rest-Aufräumen beim nächsten Start ist der Normalfall. Alle 7 Ghostty-Configs (~/.config-ghostty/<projekt>/ghostty/config): wait-after-command = false; claude-sync zeigt Schlussmeldungen per sleep (2 s aktivieren, 3 s Ende, 5 s Fehler), dann schließt das Fenster selbst. SessionStart-Hook ~/claude-projects/robotunits/bin/pool-guard in allen 7 Projekt-settings.json: Sentinel fehlt / Pool-Mismatch / Schreiber-PID tot → rot blinkender Banner auf /dev/tty + kill des claude-Elternprozesses. RAW-Nutzung außerhalb der Projekte bleibt frei; RAW-Start IM Projekt wird beendet. Achtung: greift auch bei /clear in Sessions, die noch ohne Sentinel gestartet wurden.
  • Gelöscht: ~/.claude (komplett), Keychain-Eintrag Claude Code-credentials, ~/claude-pools. Unterhaltungen (90 MB) + history.jsonl nach Mx9Privat umgezogen — /resume pro Pool.
  • App-Code (~/projects/ai-control, Tauri): Kernlogik mit injizierbarem Home, 22 Tests (./build.sh-Toolchain: CARGO_HOME=~/tools/.cargo; node via fnm, nur in interaktiver zsh). Commands unassign_pool/create_project/delete_project, seit 2026-07-04 restart_project (osascript-Quit → warten → open) + Modal in ProjectList: nach Umhängen eines laufenden Projekts Restart-Angebot inkl. Hinweis, dass der claude-sync-Push beim Abschießen entfällt.
  • Eingebautes Terminal (2026-07-04, Prototyp, funktioniert laut Marcus): src-tauri/src/terminal.rs (portable-pty, Commands open_terminal/term_start/term_write/term_resize) + terminal.html/src/terminal.ts (xterm.js, Output base64-Events, Capability term-*). „Terminal"-Button in ProjectList öffnet pro Klick ein eigenes Fenster; PTY startet zsh -ic claude-sync im Projektordner — Pool/Sentinel/git-Sync unverändert bei claude-sync, App setzt kein CLAUDE_CONFIG_DIR. Fenster-X killt Kind + schließt PTY (HUP wie Ghostty-X, Abschluss-Push entfällt). Damit Weg frei, die Ghostty-Starter abzulösen ("wir haben alles in der Hand"). Offen: Scrollback-Restore, Fensterposition merken.
  • Stand 2026-07-04 abends, alles committed+gepusht (bis inkl. Todo-Feature): UI komplett auf Catppuccin-Mocha-Token + JetBrains Mono (frontend-design-Skill; Plugin frontend-design war kaputt — installPaths in installed_plugins.json zeigten nach Pool-Umbenennung noch auf Mx9Privat, gefixt), i18n de/en (vue-i18n, Umschalter im Header). Pools: löschbar mit Zuordnungs-Auflösung, „Neu anmelden" löscht vorher den suffixierten Keychain-Eintrag (nur bei ungenutztem Pool, Warn-Dialog), Renew entfernt (Datei-Refresh-Token tot, Keychain hat Vorrang), hasCredentials (apikey-Dateicheck) mit Start-Blockierung. Verbrauch-Tab: usage_stats parst /projects//.jsonl (Dedup message.id+requestId, Preistabelle Fable 10/50 Opus 5/25 Sonnet 3/15 Haiku 1/5, Cache 1.25x/0.1x), Pool-Zeilen aggregiert + Projekte aufklappbar; apiDefault hat keinerlei Transcripts (Marcus' apiKey-Abfragen vom 04.07. liefen nachweislich nicht über claude-code auf diesem Rechner — Console zeigt die Wahrheit). Projekt-Wizard (create_project_full: Scaffold nach 08-07-Muster inkl. pool-guard-Hook, Arbeitsordner anlegen/verknüpfen) + Löschen (Guard bei laufender Session, optional Arbeitsordner aus additionalDirectories mit). Todo-Feature nur Projektebene (robotunits-Muster: OFFENE-PUNKTE.md + jq-SessionStart-Hook, zuschaltbar in Wizard+Zahnrad; Pool-Ebene bewusst nicht). App heißt ai-control (Cargo-Paket umbenannt), Hand-Icon (Tray per include_bytes + Template-Icon; Dock-Icon der Terminals via NSApplication nur in RunEvent::Ready). 38 Rust-Tests. Offen/geplant: Baustein-Bibliothek (CLAUDE.md-Marker-Mechanismus, Konzept steht: ~/.config/ai-control/blocks/, verwaltete Abschnitte zwischen ai-control:block-Markern), weitere Wizard-Optionen, Split privates Repo / offizielles GitHub-Repo (Ist-Stand als Initial-Commit ohne History; OAuth-Login-Teil wegen ToS-Grauzone fürs öffentliche Repo rausnehmen — apiKey-Teil unkritisch), Vitest für UI-Tests (Vorschlag steht), Dock-Name macOS/Wayland „später überlegen".
  • Alter Zwischenstand (Commit f747379 = Terminal + Start/Beenden-Button): (a) ProjectList: ein Button pro Zeile — grün „Starten" (open_terminal) / rot „Beenden" (neues Command stop_project: SIGTERM auf exakte PIDs per pgrep -f -- "--terminal <projekt>$", sonst Ghostty-Quit; NIE Quit über die App-Bundle-ID — träfe die Haupt-App); is_running = Ghostty ODER --terminal-Prozess; Status-Kreis ohne Prozess unsichtbar. (b) Terminal-Config-Dialog (Zahnrad): terminal: { theme, icon, title } in projekt-ai-control.json (pool-Feld jetzt Option, Datei bleibt bei unassign wenn terminal gesetzt); 5 Themes (mocha/dracula/solarized-dark/gruvbox/one-dark, Paletten in terminal.ts, Fenster-BG gespiegelt in terminal.rs theme_background — muss synchron bleiben); Icon = PNG/ICNS-Pfad via tauri-plugin-dialog-Picker, gesetzt per NSApplication.applicationIconImage (objc2, nur in RunEvent::Ready — in setup() überschreibt macOS es wieder); Titel: Fenstertitel + Header, leer → Projektname. tauri::generate_context! darf nur 1× expandieren (_EMBED_INFO_PLIST, fällt nur im Release-Build auf).
  • Dock-Grenze macOS: Hover-Label im Dock = Bundle-Name, zur Laufzeit nicht öffentlich änderbar; Wrapper-Bundle pro Projekt von Marcus abgelehnt („verlieren zu viel"). Windows/X11: Titel+Icon greifen fensterbasiert; Wayland-Docks bräuchten .desktop pro Projekt (xdg-toplevel-icon nur KDE). → „da müssen wir was überlegen, nicht jetzt".

Frische Pools zeigen Promo-/Upsell-Banner („Werbung"), privateDefault nicht — Ursache ungeklärt (Stand 2026-07-04, nicht weiter vertiefen): Hochsetzen der Zähler in der Pool-.claude.json (tipsHistory.fable-5-promo-2, passesUpsellSeenCount) half nicht, ebenso wenig cachedGrowthBookFeatures.tengu_birch_lantern = "off" (einziger Flag-Unterschied der Pools). Kein Settings-Switch vorhanden.

Stand 2026-07-05 (Session GitHub-Release, alles committed bis 0ebdaf0):

  • Projekt-Registry statt festem Root: ~/.config/ai-control/projects.json (Name → Pfad, Home-Pfade ~-kontrahiert), Alt-Layout-Scan komplett entfernt — ohne Registry keine Projekte. Marcus' 7 Projekte migriert. Neue Commands add_project (Import bestehender Ordner, UI „Projekt importieren …"), remove_project (nur Eintrag), set_project_dir (Root im ⚙︎-Dialog änderbar; schreibt autoMemoryDirectory + Edit-Permission um). Arbeitsordner nachträglich im ⚙︎-Dialog erfassbar/entfernbar (additionalDirectories + Edit-Permission, ~-kontrahiert).
  • Icons zentral: ~/.config/ai-control/icons/<projekt>.<ext> (NICHT Pool — Marcus' Entscheidung: gemeinsames Resourcen-Verzeichnis, kein Umzug bei Pool-Wechsel, nichts im Quell-Repo). Alle 7 Projekte migriert. Nicht ladbares Icon crasht den Tray nicht mehr (eprintln + Eintrag ohne Icon; vorher Crash-Ursache: gelöschtes icon.png).
  • Terminal: claudeCommand in App-settings.json (Default claude; bei Marcus claude-sync), App setzt CLAUDE_CONFIG_DIR aus dem Projekt-Pool selbst. Terminal-Fenster aktiviert sich beim Öffnen (Starter yieldActivationToApplicationWithBundleIdentifier + activate im Ready-Event — Aktivierung seit macOS 14 kooperativ, sonst Pop-under). Tray-Menü listet Projekte mit Icon + grünem Statuspunkt (56×36-RGBA im Icon-Slot, muda skaliert auf 18 pt); Klick startet bzw. fokussiert (NSRunningApplication über PID).
  • Session-Sync: Watcher synct per Projekt das umgebende Git-Repo (add/commit/pull --rebase/push inline), git-sync-Skript-Kopplung raus.
  • GitHub-reif: README englisch mit Screenshots (docs/), MIT-Lizenz, Anthropic-Lizenz-Hinweis (reine Pool-Verwaltung, OAuth-Login macht claude selbst). Deploy-Falle: nach rm -rf+cp nach ~/Applications lsregister -f nötig, sonst „App weg" in Spotlight.
  • 51 Rust-Tests. Zwischenfall: Commit im falschen Repo (Shell-cwd springt auf ~/claude-projects/ai-control zurück — bei git-Befehlen immer explizit cd ~/projects/ai-control), per amend+force-with-lease bereinigt.
  • Veröffentlicht 2026-07-05: github.com/mHinz-hub/ai-control — main = Squash-Commit ohne History (Gitea behält volle History; Remote github im App-Repo, HTTPS mit Fine-grained-PAT im macOS-Keychain; SSH-Key des Rechners gehört zum Arbeits-Account ex08802409_wdp, NICHT für mHinz-hub nutzbar). Tag v0.1.0 + Release mit DMG-Asset (build.sh baut app+dmg; CI=true wegen TCC). FUNDING.yml → buymeacoffee.com/marcusH. poolSyncDir in settings.json steuert Pool-Runtime-Verlinkung (bei Marcus ~/claude-projects/pool; ungesetzt = lokal). Release-Flow künftig: Gitea entwickeln → git commit-tree Squash → force-push github main → Tag → DMG via API hochladen.

Agenda 2026-07-05 (alt): Sync-Test auf neuem Mac (pool-Repo mit Symlink-Runtime: clonen, link-pool-runtime bzw. Pool-Anlage über die App, /resume-Übernahme prüfen).

Why: Getrennte Zugänge pro Pool, multi-account-keychain.

Agenda 2026-07-04: Start/Stopp-Architektur grundsätzlich besprechen — Stand vom 2026-07-03 spät (wincount/kill-9/Sentinel-Reste) funktioniert im Test, ist aber Flickwerk um Ghosttys unzuverlässiges Kill-Verhalten herum; Marcus will eine saubere Lösung statt Workarounds. Außerdem: Pool-Guard + Kaltstart über Starter testen; App: UI aufräumen, Projekte managen, Defaults/Standardverhalten (z. B. Todolist); Linux gesondert; Open-Source-Frage („works for my workflow") entschieden nach Feinschliff; außerdem Ghostty und Zed besprechen. Stand App: beta-0.8 gepusht (Tray statt Dock, Autostart-Schalter, Fenster startet unsichtbar, Restart-Dialog).

How to apply — offen (Stand 2026-07-03): (1) Sync-Konzept für ~/.config/ai-control inkl. Unterhaltungen, Secrets-Frage (git). (2) UI kennt die drei neuen Commands nicht. (3) Erledigt durch Integration in claude-sync (2026-07-04): der „Flicker" betraf das gelöschte claude-start; claude-sync läuft in den Ghostty-Wrappern nachweislich interaktiv.