- Startseite
- Documentation
- Sitzungen
- Sitzungswechsel und Liste der zuletzt verwendeten Sitzungen
Sitzungswechsel und Liste der zuletzt verwendeten Sitzungen
Dieses Dokument beschreibt, wie der Coding-Agent zuletzt verwendete Sitzungen ermittelt, --resume-Ziele auflöst, Sitzungsauswahldialoge anzeigt und die aktive Laufzeitsitzung wechselt.
Der Schwerpunkt liegt auf dem aktuellen Implementierungsverhalten, einschließlich Fallback-Pfaden und Einschränkungen.
Implementierungsdateien
Abschnitt betitelt „Implementierungsdateien“../src/session/session-manager.ts../src/session/agent-session.ts../src/cli/session-picker.ts../src/modes/components/session-selector.ts../src/modes/controllers/selector-controller.ts../src/main.ts../src/sdk.ts../src/modes/interactive-mode.ts../src/modes/utils/ui-helpers.ts
Ermittlung zuletzt verwendeter Sitzungen
Abschnitt betitelt „Ermittlung zuletzt verwendeter Sitzungen“Verzeichnisbereich
Abschnitt betitelt „Verzeichnisbereich“SessionManager speichert Sitzungen standardmäßig in einem cwd-bezogenen Verzeichnis:
~/.xcsh/agent/sessions/--<cwd-encoded>--/*.jsonl
SessionManager.list(cwd, sessionDir?) liest ausschließlich dieses Verzeichnis, sofern kein explizites sessionDir angegeben wird.
Zwei Auflistungspfade mit unterschiedlichen Nutzdaten
Abschnitt betitelt „Zwei Auflistungspfade mit unterschiedlichen Nutzdaten“Es gibt zwei verschiedene Auflistungs-Pipelines:
-
getRecentSessions(sessionDir, limit)(Willkommens-/Zusammenfassungsansicht)- Liest nur ein 4-KB-Präfix (
readTextPrefix(..., 4096)) aus jeder Datei. - Parst Header + früheste Benutzertextvorschau.
- Gibt ein schlankes
RecentSessionInfo-Objekt mit verzögertenname- undtimeAgo-Gettern zurück. - Sortiert nach Datei-
mtimeabsteigend.
- Liest nur ein 4-KB-Präfix (
-
SessionManager.list(...)/SessionManager.listAll()(Sitzungsauswahl für Wiederaufnahme und ID-Abgleich)- Liest vollständige Sitzungsdateien.
- Erstellt
SessionInfo-Objekte (id,cwd,title,messageCount,firstMessage,allMessagesText, Zeitstempel). - Verwirft Sitzungen mit null
message-Einträgen. - Sortiert nach
modifiedabsteigend.
Metadaten-Fallback-Verhalten
Abschnitt betitelt „Metadaten-Fallback-Verhalten“Für aktuelle Zusammenfassungen (RecentSessionInfo):
- Präferenz für den Anzeigenamen:
header.title-> erste Benutzereingabe ->header.id-> Dateiname - Der Name wird für kompakte Anzeigen auf 40 Zeichen gekürzt
- Steuerzeichen/Zeilenumbrüche werden aus titelabgeleiteten Namen entfernt/bereinigt
Für SessionInfo-Listeneinträge:
titleistheader.titleoder der neueste Kompaktierungs-shortSummaryfirstMessageist der Text der ersten Benutzernachricht oder"(no messages)"
--continue-Auflösung und Terminalnavigations-Präferenz
Abschnitt betitelt „--continue-Auflösung und Terminalnavigations-Präferenz“SessionManager.continueRecent(cwd, sessionDir?) löst das Ziel in dieser Reihenfolge auf:
- Terminalspezifischen Breadcrumb lesen (
~/.xcsh/agent/terminal-sessions/<terminal-id>) - Breadcrumb validieren:
- Das aktuelle Terminal kann identifiziert werden
- Das Breadcrumb-cwd stimmt mit dem aktuellen cwd überein (aufgelöster Pfadvergleich)
- Die referenzierte Datei ist noch vorhanden
- Wenn der Breadcrumb ungültig/fehlend ist, auf die neueste Datei nach mtime im Sitzungsverzeichnis zurückfallen (
findMostRecentSession) - Wenn keine Datei gefunden wird, eine neue Sitzung erstellen
Die Terminal-ID-Ableitung bevorzugt den TTY-Pfad und greift auf umgebungsbasierte Bezeichner zurück (KITTY_WINDOW_ID, TMUX_PANE, TERM_SESSION_ID, WT_SESSION).
Breadcrumb-Schreibvorgänge erfolgen nach bestem Bemühen und sind nicht fatal.
Auflösung des Wiederaufnahmeziels beim Start (main.ts)
Abschnitt betitelt „Auflösung des Wiederaufnahmeziels beim Start (main.ts)“--resume <value>
Abschnitt betitelt „--resume <value>“createSessionManager(...) verarbeitet einen zeichenkettenbasierten --resume-Wert in zwei Modi:
-
Pfadähnlicher Wert (enthält
/,\\oder endet mit.jsonl)- direktes
SessionManager.open(sessionArg, parsed.sessionDir)
- direktes
-
ID-Präfix-Wert
- Treffer in
SessionManager.list(cwd, sessionDir)überid.startsWith(sessionArg)suchen - Wenn kein lokaler Treffer und
sessionDirnicht erzwungen,SessionManager.listAll()versuchen - Der erste Treffer wird verwendet (keine Mehrdeutigkeitsabfrage)
- Treffer in
Verhalten bei projektübergreifenden Treffern:
- Wenn das cwd der gefundenen Sitzung vom aktuellen cwd abweicht, fragt die CLI, ob in das aktuelle Projekt verzweigt werden soll
- Ja ->
SessionManager.forkFrom(...) - Nein -> Fehler wird ausgelöst (
Session "..." is in another project (...))
Kein Treffer -> Fehler wird ausgelöst (Session "..." not found.).
--resume (kein Wert)
Abschnitt betitelt „--resume (kein Wert)“Wird nach der anfänglichen Sitzungsmanager-Erstellung behandelt:
- Lokale Sitzungen mit
SessionManager.list(cwd, parsed.sessionDir)auflisten - Wenn leer:
No sessions foundausgeben und frühzeitig beenden - TUI-Auswahldialog öffnen (
selectSession) - Wenn abgebrochen:
No session selectedausgeben und frühzeitig beenden - Wenn ausgewählt:
SessionManager.open(selectedPath)
--continue
Abschnitt betitelt „--continue“Verwendet SessionManager.continueRecent(...) direkt (Breadcrumb-First-Verhalten wie oben beschrieben).
Interna der auswahlbasierten Sitzungsauswahl
Abschnitt betitelt „Interna der auswahlbasierten Sitzungsauswahl“CLI-Auswahldialog (src/cli/session-picker.ts)
Abschnitt betitelt „CLI-Auswahldialog (src/cli/session-picker.ts)“selectSession(sessions) erstellt eine eigenständige TUI mit SessionSelectorComponent und löst genau einmal auf:
- Auswahl -> gibt den ausgewählten Pfad zurück
- Abbruch (Esc) -> gibt
nullzurück - Hartes Beenden (Ctrl+C-Pfad) -> stoppt die TUI und ruft
process.exit(0)auf
Interaktiver In-Sitzungs-Auswahldialog (SelectorController.showSessionSelector)
Abschnitt betitelt „Interaktiver In-Sitzungs-Auswahldialog (SelectorController.showSessionSelector)“Ablauf:
- Sitzungen aus dem aktuellen Sitzungsverzeichnis über
SessionManager.list(currentCwd, currentSessionDir)abrufen SessionSelectorComponentim Editor-Bereich übershowSelector(...)einbinden- Rückrufe:
- Auswahl -> Auswahldialog schließen und
handleResumeSession(sessionPath)aufrufen - Abbruch -> Editor wiederherstellen und neu rendern
- Beenden ->
ctx.shutdown()
- Auswahl -> Auswahldialog schließen und
Verhalten der Sitzungsauswahl-Komponente
Abschnitt betitelt „Verhalten der Sitzungsauswahl-Komponente“SessionList unterstützt:
- Pfeil-/Seitennavigation
- Eingabe zur Auswahl
- Esc zum Abbrechen
- Ctrl+C zum Beenden
- Fuzzy-Suche über Sitzungs-ID/Titel/cwd/erste Nachricht/alle Nachrichten/Pfad
Darstellungsverhalten bei leerer Liste:
- Zeigt eine Meldung an, anstatt abzustürzen
- Eingabe bei leerer Liste hat keine Wirkung (kein Rückruf)
- Esc/Ctrl+C funktionieren weiterhin
Hinweis: Der UI-Text lautet Press Tab to view all, aber diese Komponente hat derzeit keinen Tab-Handler, und die aktuelle Verdrahtung listet nur Sitzungen im aktuellen Bereich auf.
Ausführung des Laufzeit-Sitzungswechsels (AgentSession.switchSession)
Abschnitt betitelt „Ausführung des Laufzeit-Sitzungswechsels (AgentSession.switchSession)“switchSession(sessionPath) ist der zentrale In-Process-Wechselpfad.
Lebenszyklus/Zustandsübergang:
previousSessionFileerfassen- Hook-Ereignis
session_before_switchauslösen (reason: "resume", abbrechbar) - Wenn abgebrochen ->
falsezurückgeben, kein Wechsel - Vom aktuellen Agent-Ereignisstrom trennen
- Aktiven Generierungs-/Werkzeugablauf abbrechen
- Warteschlangen für Steuerungs-/Folgemeldungen/Nächste-Runde-Nachrichtenpuffer leeren
- Sitzungsschreiber leeren (
sessionManager.flush()), um ausstehende Schreibvorgänge zu persistieren sessionManager.setSessionFile(sessionPath)- Aktualisiert den Sitzungsdateizeiger
- Schreibt Terminal-Breadcrumb
- Lädt Einträge / migriert / löst Blobs auf / indiziert neu
- Bei fehlender/ungültiger Datei: Initialisiert eine neue Sitzung unter diesem Pfad und schreibt den Header neu
agent.sessionIdaktualisieren- Kontext über
buildSessionContext()neu aufbauen - Hook-Ereignis
session_switchauslösen (reason: "resume",previousSessionFile) - Agent-Nachrichten durch neu aufgebauten Kontext ersetzen
- Standardmodell aus
sessionContext.models.defaultwiederherstellen, wenn verfügbar und im Modellregister vorhanden - Denk-Ebene wiederherstellen:
- Wenn der Zweig bereits
thinking_level_changeenthält, gespeicherte Sitzungsebene anwenden - Andernfalls Standard-Denk-Ebene aus Einstellungen ableiten, auf Modellkapazität begrenzen, setzen und neuen
thinking_level_change-Eintrag anfügen
- Wenn der Zweig bereits
- Agent-Listener neu verbinden und
truezurückgeben
UI-Zustandswiederherstellung nach interaktivem Wechsel
Abschnitt betitelt „UI-Zustandswiederherstellung nach interaktivem Wechsel“SelectorController.handleResumeSession führt UI-Reset um switchSession herum durch:
- Ladeanimation stoppen
- Statuscontainer leeren
- Ausstehende Nachrichten-UI und ausstehende Werkzeugzuordnung zurücksetzen
- Streaming-Komponenten-/Nachrichtenreferenzen zurücksetzen
session.switchSession(...)aufrufen- Chat-Container leeren und aus Sitzungskontext neu rendern (
renderInitialMessages) - Aufgaben aus neuen Sitzungsartefakten neu laden
Resumed sessionanzeigen
Der sichtbare Gesprächs-/Aufgabenstatus wird also aus der neuen Sitzungsdatei neu aufgebaut.
Wiederaufnahme beim Start vs. In-Sitzungs-Wechsel
Abschnitt betitelt „Wiederaufnahme beim Start vs. In-Sitzungs-Wechsel“Wiederaufnahme beim Start (--continue, --resume, direktes Öffnen)
Abschnitt betitelt „Wiederaufnahme beim Start (--continue, --resume, direktes Öffnen)“- Die Sitzungsdatei wird vor
createAgentSession(...)ausgewählt. sdk.tserstelltexistingSession = sessionManager.buildSessionContext().- Agent-Nachrichten werden einmalig während der Sitzungserstellung wiederhergestellt.
- Modell/Denken werden während der Erstellung ausgewählt (einschließlich Wiederherstellungs-/Fallback-Logik).
- Der interaktive Modus führt dann
#restoreModeFromSession()aus, um den persistierten Moduszustand wieder aufzunehmen (derzeit plan/plan_paused).
In-Sitzungs-Wechsel (/resume-artiger Auswahlpfad)
Abschnitt betitelt „In-Sitzungs-Wechsel (/resume-artiger Auswahlpfad)“- Verwendet
AgentSession.switchSession(...)in einer bereits laufendenAgentSession. - Nachrichten/Modell/Denken werden sofort an Ort und Stelle neu aufgebaut.
- Hook-Ereignisse
session_before_switch/session_switchwerden ausgelöst. - UI-Chat/Aufgaben werden aktualisiert.
- Nach dem Wechsel wird kein dedizierter Moduswiederherstellungsaufruf im Auswahlpfad durchgeführt; das Moduswiederaufnahmeverhalten ist nicht symmetrisch mit dem Start-
#restoreModeFromSession().
Fehler- und Randfall-Verhalten
Abschnitt betitelt „Fehler- und Randfall-Verhalten“Abbruchpfade
Abschnitt betitelt „Abbruchpfade“- CLI-Auswahldialogabbruch -> gibt
nullzurück, Aufrufer gibtNo session selectedaus, Prozess endet frühzeitig. - Interaktiver Auswahldialogabbruch -> Editor wird wiederhergestellt, keine Sitzungsänderung.
- Hook-Abbruch (
session_before_switch) ->switchSession()gibtfalsezurück.
Leere Listenpfade
Abschnitt betitelt „Leere Listenpfade“- CLI
--resume(kein Wert): Leere Liste gibtNo sessions foundaus und beendet. - Interaktiver Auswahldialog: Leere Liste zeigt Meldung an und bleibt abbrechbar.
Fehlende/ungültige Zielsitzungsdatei
Abschnitt betitelt „Fehlende/ungültige Zielsitzungsdatei“Beim Öffnen/Wechseln zu einem bestimmten Pfad (setSessionFile):
- ENOENT -> wird als leer behandelt -> neue Sitzung wird unter diesem genauen Pfad initialisiert und persistiert.
- Fehlerhafter/ungültiger Header (oder effektiv nicht lesbare geparste Einträge) -> wird als leer behandelt -> neue Sitzung wird initialisiert und persistiert.
Dies ist Wiederherstellungsverhalten, kein harter Fehler.
Schwerwiegende Fehler
Abschnitt betitelt „Schwerwiegende Fehler“Wechseln/Öffnen kann bei echten E/A-Fehlern (Berechtigungsfehler, Schreibfehler usw.) weiterhin Ausnahmen auslösen, die an die Aufrufer weitergegeben werden.
Einschränkungen beim ID-Präfix-Abgleich
Abschnitt betitelt „Einschränkungen beim ID-Präfix-Abgleich“- Der ID-Abgleich verwendet
startsWithund nimmt den ersten Treffer in der sortierten Liste. - Keine Mehrdeutigkeits-UI, wenn mehrere Sitzungen denselben Präfix teilen.
SessionManager.list(...)schließt Sitzungen mit null Nachrichten aus, sodass diese Sitzungen nicht über ID-Abgleich/Listenauswahl wiederaufgenommen werden können.