refactor(dev-session): Entkopplung der Gemini CLI

Ändert die Architektur des -Systems, um die Stabilität der Gemini CLI zu verbessern.

Die Gemini CLI wird nicht mehr als direkter Unterprozess von  gestartet. Stattdessen gibt  den generierten Kontext auf stdout aus, und das -Skript fängt ihn ab und startet die CLI in einem sauberen, separaten Container.

- ****: Entfernt die Funktion  und gibt den Kontext stattdessen über stdout aus.
- ****: Führt jetzt einen zweistufigen Prozess aus. Zuerst wird der Kontext von  in einem temporären Container abgerufen und dann die Gemini CLI in einem neuen Container mit dem Kontext als  gestartet.
- ****: Dokumentation aktualisiert, um die neue Architektur widerzuspiegeln.
This commit is contained in:
2026-01-25 19:40:26 +00:00
parent 125080a0ba
commit 01c4968ddf
3 changed files with 65 additions and 40 deletions

View File

@@ -2,7 +2,9 @@
## Übersicht
`dev_session.py` ist ein interaktives Kommandozeilen-Tool (CLI), das entwickelt wurde, um den Entwicklungs-Workflow durch die Integration mit Notion's "Ultimate Tasks"- und "Projects"-Datenbanken zu optimieren. Es ermöglicht Entwicklern, eine Entwicklungssitzung zu starten, indem sie ein Projekt und einen Task aus Notion auswählen, den Task-Status automatisch aktualisieren und einen formatierten Kontext für die Gemini CLI generieren.
`dev_session.py` ist ein interaktives Kommandozeilen-Tool (CLI), das den Entwicklungs-Workflow durch die Integration mit Notion optimiert. Es ermöglicht Entwicklern, ein Projekt und einen Task auszuwählen und den Task-Status automatisch zu aktualisieren.
**Wichtige Architekturänderung:** Das Skript `dev_session.py` startet die Gemini CLI nicht mehr direkt. Stattdessen generiert es einen formatierten Kontext und gibt diesen auf der Standardausgabe aus. Das übergeordnete `start-gemini.sh`-Skript fängt diesen Kontext auf und startet dann die Gemini CLI in einer sauberen, interaktiven Sitzung mit dem korrekten Startkontext. Dieser zweistufige Prozess stellt sicher, dass die Gemini CLI mit allen erforderlichen Tools und in der korrekten Umgebung läuft.
## Funktionen
@@ -33,13 +35,21 @@ Das Setup ist so konzipiert, dass es mit minimalem Aufwand sofort einsatzbereit
### 1. Sitzung starten
Führen Sie das Start-Skript aus. Es baut bei Bedarf das Docker-Image und startet den Session-Manager.
Das `start-gemini.sh`-Skript orchestriert den gesamten Startvorgang.
```bash
./start-gemini.sh
```
Das Skript führt Sie dann interaktiv durch die Auswahl eines Projekts und eines Tasks, genau wie in der Beispiel-Interaktion unten beschrieben. Nach der Auswahl startet es eine Gemini-CLI-Sitzung mit dem passenden Kontext.
**Was im Hintergrund passiert:**
1. Das Skript führt `dev_session.py` in einem temporären Docker-Container aus.
2. Sie durchlaufen den interaktiven Auswahlprozess für Projekt und Task wie gewohnt.
3. Nach Ihrer Auswahl gibt `dev_session.py` den generierten Kontext für die Gemini CLI aus und beendet sich.
4. `start-gemini.sh` fängt diese Ausgabe ab und extrahiert den Kontext.
5. Anschließend startet das Skript einen neuen, sauberen Docker-Container mit der Gemini CLI und übergibt den extrahierten Kontext als Start-Prompt.
Dieser Prozess stellt sicher, dass Ihre interaktive Gemini-Sitzung von der Notion-API-Logik entkoppelt ist und in einer stabilen Umgebung läuft.
### 2. Sitzung abschließen

View File

@@ -352,29 +352,7 @@ def generate_cli_context(project_title: str, task_title: str, task_id: str, read
# --- CLI Execution ---
def start_gemini_cli(initial_context: str):
"""Startet die Gemini CLI als interaktiven Subprozess und übergibt den Startkontext."""
print("\n--- Übergebe an Gemini CLI... ---")
print("Die Gemini CLI wird jetzt gestartet. Sie können direkt mit der Arbeit beginnen.")
try:
# Der Befehl, um die Gemini CLI zu starten
command = ["gemini"]
# Starte den Prozess
# stdin=subprocess.PIPE, um den Kontext zu senden
# text=True für String-basierte Ein-/Ausgabe
process = subprocess.Popen(command, stdin=subprocess.PIPE, text=True)
# Schreibe den initialen Kontext in die Standard-Eingabe der CLI
# Ein Zeilenumbruch am Ende simuliert das Drücken der Enter-Taste.
process.communicate(input=initial_context + '\n')
except FileNotFoundError:
print("\n❌ FEHLER: Der 'gemini'-Befehl wurde nicht gefunden.")
print("Stellen Sie sicher, dass die Gemini CLI korrekt im Container installiert und im PATH verfügbar ist.")
except Exception as e:
print(f"\n❌ Ein unerwarteter Fehler ist beim Starten der Gemini CLI aufgetreten: {e}")
# Die start_gemini_cli Funktion wird entfernt, da das aufrufende Skript jetzt die Gemini CLI startet.
import shutil
import argparse
@@ -526,9 +504,13 @@ def start_interactive_session():
print(f"git checkout -b {suggested_branch_name}")
print("------------------------------------------------------------------")
# CLI-Kontext generieren und die interaktive Session starten
# CLI-Kontext generieren und an stdout ausgeben, damit das Startskript ihn aufgreifen kann
cli_context = generate_cli_context(project_title, task_title, task_id, readme_path)
start_gemini_cli(cli_context)
print("\n---GEMINI_CLI_CONTEXT_START---")
print(cli_context)
print("---GEMINI_CLI_CONTEXT_END---")
# Das Skript beenden, damit das aufrufende Shell-Skript die Gemini CLI starten kann
exit(0)
# --- Main Execution ---

View File

@@ -1,20 +1,53 @@
#!/bin/bash
#!/bin/sh
# Definiere den Namen für das Docker-Image und den Container
IMAGE_NAME="gemini-dev-env"
CONTAINER_NAME="gemini-session"
# Sicherstellen, dass der Config-Ordner existiert, damit Docker ihn als Ordner und nicht als Datei mountet
# Sicherstellen, dass der Config-Ordner existiert
mkdir -p .gemini-config
echo "Räume alte 'gemini-session' auf, falls vorhanden..."
sudo docker rm -f gemini-session > /dev/null 2>&1
# Prüfen, ob das Docker-Image existiert
if ! docker image inspect "$IMAGE_NAME" &> /dev/null;
then
echo "Docker-Image '$IMAGE_NAME' nicht gefunden. Baue es jetzt aus 'gemini.Dockerfile'..."
docker build -t "$IMAGE_NAME" -f gemini.Dockerfile .
if [ $? -ne 0 ]; then
echo "FEHLER: Docker-Image konnte nicht gebaut werden."
exit 1
fi
fi
echo "Räume alte '$CONTAINER_NAME' auf, falls vorhanden..."
docker rm -f "$CONTAINER_NAME" > /dev/null 2>&1
echo "Starte eine neue, interaktive Gemini-Session..."
# --env-file .env lädt deine Variablen automatisch
# -v .../.gemini-config:/root/.config sorgt dafür, dass deine Settings (Modellwahl) gespeichert bleiben
sudo docker run -it --rm \
--env-file .env \
# Führe dev_session.py im Hintergrund aus und fange die Ausgabe ab
# Der Kontext für die Gemini CLI wird von dev_session.py in speziellen Markierungen ausgegeben
DEV_SESSION_OUTPUT=$(docker run -i --rm \
-v "$(pwd):/app" \
-v "$(pwd)/.gemini-config:/root/.config" \
--name gemini-session \
gemini-dev-env \
bash -c "python3 dev_session.py"
-w /app \
--name "${CONTAINER_NAME}-temp" \
"$IMAGE_NAME" \
python3 dev_session.py 2>&1)
# Extrahiere den CLI-Kontext aus der Ausgabe
CLI_CONTEXT=$(echo "$DEV_SESSION_OUTPUT" | sed -n '/---GEMINI_CLI_CONTEXT_START---/,/---GEMINI_CLI_CONTEXT_END---/{//!p}')
# Gib die Ausgaben von dev_session.py (außer dem Kontext) vor dem Start der CLI aus
echo "$DEV_SESSION_OUTPUT" | sed '/---GEMINI_CLI_CONTEXT_START---/,/---GEMINI_CLI_CONTEXT_END---/d'
# Starte die Gemini CLI mit dem extrahierten Kontext
# Die --initial-prompt Option sorgt dafür, dass der Kontext als erste Eingabe dient
docker run -it --rm \
-v "$(pwd):/app" \
-v "$(pwd)/.gemini-config:/root/.config" \
-w /app \
--name "$CONTAINER_NAME" \
"$IMAGE_NAME" \
gemini --initial-prompt "$CLI_CONTEXT"
# Nach Beendigung der Session (z.B. durch Strg+C) wird aufgeräumt
echo "Session beendet."