cc-sessions
Referenz spezifischer emacsclient --eval-Rezepte zur Verwaltung von claude-code-ide.el-Sitzungen aus dem "Majordom" (oder jeder anderen Sitzung mit Zugriff auf denselben Emacs-Server). Die Grundsätze (warum genau so) finden sich in majordom.md; hier nur die fertigen Aufrufe.
KRITISCH: Der einzige sichere Startbefehl ist claude-code-ide-start
claude-code-ide-continue, claude-code-ide-resume und das alte claude-code-ide (alle ohne Argumente) – NIEMALS direkt headless aufrufen. Jeder dieser Befehle ruft, wenn für das Verzeichnis bereits eine aktive Sitzung existiert, ein blockierendes (read-string "Instance name (empty for auto): ") auf, das ohne einen live über die Tastatur agierenden Benutzer für immer hängen bleibt (empirisch für alle drei bestätigt). Die einzige Ausnahme ist ein interaktives M-x durch einen Menschen direkt.
claude-code-ide-start (Signatur (&optional instance-name continue resume)) deckt alle drei Fälle mit einem einzigen Aufruf ab, der NIEMALS interaktiv nach einem Namen fragt:
;; normaler Start eines neuen Gesprächs
(let ((default-directory "/home/eugine/job/<projekt>/")
(claude-code-ide-cli-extra-flags "--remote-control <projekt>"))
(claude-code-ide-start "<name-oder-nil>"))
;; anstelle von claude-code-ide-continue
(claude-code-ide-start "<name-oder-nil>" t nil)
;; anstelle von claude-code-ide-resume (öffnet den interaktiven Picker IM Terminal von claude,
;; nicht über den Emacs-Minibuffer – der Aufruf selbst blockiert emacsclient nicht)
(claude-code-ide-start "<name-oder-nil>" nil t)
instance-name (1. Argument) nil ⇒ automatische Nummer (vedmid-2, vedmid-3...). Gib ihn nur explizit an, wenn der Benutzer selbst ein Ziel/einen Namen für die neue Kopie vergeben hat – wenn unklar, frage den Benutzer, erfinde nichts selbst.
Vor dem Start: Vorhandenen Zustand prüfen
(mapcar (lambda (b) (list (buffer-name b) (and (get-buffer-process b) (process-status (get-buffer-process b)))))
(seq-filter (lambda (b) (string-match-p "claude-code\\[<projekt>" (buffer-name b))) (buffer-list)))
- Keine aktive Sitzung →
(claude-code-ide-start nil t nil)(nimmt das letzte Gespräch des Projekts auf, wiecontinue). - Es gibt eine aktive Sitzung → NIEMALS anhalten "zum Neustarten". Starte eine ZUSÄTZLICHE Kopie mit demselben
claude-code-ide-start(mitresume=t, wenn das Ziel die Auswahl eines bestimmten alten Gesprächs ist, oder ohne – ein neues Gespräch daneben).
Nach dem Start: Remote-Control durch tatsächliche Suche im Puffer bestätigen
Das Ausbleiben eines Hängens beweist NOCH NICHT, dass --remote-control gewirkt hat (Vorfall: Flagge vergessen – Sitzung startete sauber, blieb aber nicht-remote).
(with-current-buffer "*claude-code[<projekt>]*"
(save-excursion (goto-char (point-min))
(if (search-forward "remote-control" nil t) "FOUND" "NOT FOUND")))
Wenn NOT FOUND – nicht immer ein Fehler: Prüfe den gesamten Pufferinhalt (buffer-substring-no-properties (point-min) (point-max)). Die Zeile könnte außerhalb des gerenderten Bereichs liegen oder (bei großen Sitzungen) außerhalb des sichtbaren Scrollbacks von eat – das Terminal selbst speichert nur die letzte Historie, nicht das gesamte Gespräch.
Sitzung anhalten: Zuerst query-on-exit deaktivieren, dann stoppen
claude-code-ide-stop ist an sich sicher und HÄNGT NICHT davon ab, ob die Sitzung remote-control hatte. Aber die übliche Emacs-Abfrage "Buffer '...' has a running process; kill it?" erscheint ASYNCHRON (im process-sentinel, bereits NACHDEM claude-code-ide-stop zurückgekehrt ist) – daher schützt ein let-Wrapper um den Aufruf selbst nicht. Deaktiviere die Flagge am Prozess VORHER in einem separaten Aufruf:
(let ((proc (get-buffer-process "*claude-code[<projekt>]*")))
(when proc (set-process-query-on-exit-flag proc nil)))
(with-current-buffer "*claude-code[<projekt>]*" (claude-code-ide-stop))
Wenn es für das Verzeichnis mehrere Kopien gibt (vedmid, vedmid:2, vedmid:masazh...) – rufe claude-code-ide-stop im Kontext GENAU dieses Puffers auf (with-current-buffer), nicht über default-directory: Die Meldung bestätigt, welche genau gestoppt wurde ("Stopping Claude Code vedmid:masazh...").
Sollte die Abfrage dennoch durchrutschen und hängen bleiben (ps aux | grep emacsclient zeigt einen feststeckenden Prozess) – NIEMALS selbst versuchen zu entsperren (keine wiederholten --eval, keine Signale an emacs) – bitte den Benutzer, im Live-Emacs zu antworten. Siehe emacs.md für den vollständigen Kontext dieser Gefahr.
Navigation in interaktiven Picker-Menüs (Resume-Liste, Berechtigungsanfragen)
Die Sitzungsliste (resume) und Berechtigungsbestätigungsmenüs werden IM Terminal gerendert (nicht über den Emacs-Minibuffer) – sie werden mit normalen ANSI-Sequenzen über rohes process-send-string gesteuert, nicht über emacsclient --eval-Elisp-Aufrufe:
(process-send-string (get-buffer-process "*claude-code[<projekt>]*") "\e[B") ; Pfeil runter
(process-send-string (get-buffer-process "*claude-code[<projekt>]*") "\e[A") ; Pfeil hoch
(process-send-string (get-buffer-process "*claude-code[<projekt>]*") "\e[6~") ; Page Down
(process-send-string (get-buffer-process "*claude-code[<projekt>]*") "\r") ; Enter (bestätigen)
Lies nach jeder gesendeten Eingabe den Pufferinhalt (buffer-substring-no-properties) erneut, um die neue Cursorposition (❯) und den Titel (N of M) zu sehen, bevor du weiter navigierst oder bestätigst – nicht blind mehrere Schritte ohne Prüfung bewegen. Numerische Tasten ("3") für die direkte Auswahl eines Menüpunkts zur Bestätigung sind NICHT als funktionierend bestätigt – Navigation mit Pfeiltasten + Enter ist zuverlässiger.
Umschalten des Berechtigungsmodus (Shift+Tab) – eine andere Sache als Auto-Accept
Die Statuszeile des Terminals (⏸ manual mode on, ⏵⏵ accept edits on, ⏸ plan mode on, ⏵⏵ auto mode on) wird ausschließlich vom claude-Binary selbst gesteuert – Emacs weiß nichts davon. Der Zyklus (Shift+Tab, vier Zustände): manual → accept edits → plan → auto → manual.
(process-send-string (get-buffer-process "*claude-code[<projekt>]*") "\e[Z")
Das Umschalten löst MANCHMAL eine Zwischenabfrage zur Tool-Bestätigung aus (Do you want to proceed?) – wähle den Punkt "Yes, and switch to auto mode" über Pfeilnavigation (nicht mit Ziffer) + Enter, wenn das Ziel ist, genau in auto zurückzukehren.
claude-code-ide-toggle-auto-accept – separate Emacs-Funktion, nicht derselbe Zustand
Nicht mit dem obigen Berechtigungszyklus verwechseln. Diese Funktion schaltet nur eine Elisp-Flagge in der Sitzungsstruktur um und beeinflusst NUR das MCP-Tool openDiff (Angebot einer ediff-Vorschau vor dem Speichern der Datei): ON → ediff wird nicht angezeigt, die Datei wird sofort gespeichert (FILE_SAVED); OFF → normales ediff. Die Statuszeile des Terminals wird durch diesen Aufruf NICHT geändert.
(with-current-buffer "*claude-code[<projekt>]*" (claude-code-ide-toggle-auto-accept))
Pufferinhalt dem Benutzer zeigen "als ob er selbst schaut"
(with-current-buffer "*claude-code[<projekt>]*" (buffer-substring-no-properties (point-min) (point-max)))
Bei großen Sitzungen kürzen ((max (point-min) (- (point-max) N)) (point-max)) – der vollständige Inhalt kann megabytegroß sein, obwohl der sichtbare Scrollback von eat immer begrenzt ist (der tatsächlich gerenderte Teil wächst nicht unbegrenzt).