Ctrl K
ComunidadGuías…

switch_mode.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""Umschalten zwischen Dev- und Offizieller Version in Claude Desktop.

Aendert die MCP-Konfiguration in claude_desktop_config.json:
  - Dev:       Quellcode aus dem Projektordner, .venv-Python
  - Offiziell: Installierte Version, system/venv-Python

Plattformunabhaengig: Windows, macOS und Linux.

Nutzung:
  python switch_mode.py          # Zeigt aktuellen Modus
  python switch_mode.py dev      # Wechselt auf Dev-Version
  python switch_mode.py official # Wechselt auf offizielle Version
"""

import json
import os
import sys

from _setup_claude import eintrag_bauen  # liegt neben diesem Skript

# ── Plattform-Pfade ────────────────────────────────────────────


def _claude_config_path():
    if sys.platform == "win32":
        return os.path.join(os.environ.get("APPDATA", ""), "Claude", "claude_desktop_config.json")
    elif sys.platform == "darwin":
        return os.path.join(os.path.expanduser("~"), "Library", "Application Support", "Claude", "claude_desktop_config.json")
    else:
        return os.path.join(os.path.expanduser("~"), ".config", "Claude", "claude_desktop_config.json")


def _data_dir():
    if sys.platform == "win32":
        return os.path.join(os.environ.get("LOCALAPPDATA", ""), "BewerbungsAssistent")
    else:
        return os.path.join(os.path.expanduser("~"), ".bewerbungs-assistent")


def _venv_python(base_dir):
    if sys.platform == "win32":
        return os.path.join(base_dir, ".venv", "Scripts", "python.exe")
    else:
        return os.path.join(base_dir, ".venv", "bin", "python")


def _installed_python(data_dir):
    if sys.platform == "win32":
        return os.path.join(data_dir, "python", "Scripts", "python.exe")
    else:
        return os.path.join(data_dir, "venv", "bin", "python")


# ── Pfade ──────────────────────────────────────────────────────

CONFIG_PATH = _claude_config_path()

PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))

MODES = {
    "dev": {
        "python": _venv_python(PROJECT_DIR),
        "src": os.path.join(PROJECT_DIR, "src"),
        "data_dir": _data_dir(),
        "label": "Dev",
    },
    "official": {
        "python": _installed_python(_data_dir()),
        "src": os.path.join(_data_dir(), "src"),
        "data_dir": _data_dir(),
        "label": "Offiziell",
    },
}

MCP_KEY = "bewerbungs-assistent"


# ── Hilfsfunktionen ───────────────────────────────────────────

def load_config():
    if not os.path.exists(CONFIG_PATH):
        return {"mcpServers": {}}
    with open(CONFIG_PATH, "r", encoding="utf-8-sig") as f:  # BOM-fest, wie _setup_claude.lese_config
        return json.load(f)


def save_config(config):
    os.makedirs(os.path.dirname(CONFIG_PATH), exist_ok=True)
    with open(CONFIG_PATH, "w", encoding="utf-8") as f:
        json.dump(config, f, indent=2, ensure_ascii=False)


def detect_current_mode(config):
    """Erkennt den aktuellen Modus anhand des PYTHONPATH."""
    entry = config.get("mcpServers", {}).get(MCP_KEY, {})
    pythonpath = entry.get("env", {}).get("PYTHONPATH", "")

    if os.path.normcase(pythonpath) == os.path.normcase(MODES["dev"]["src"]):
        return "dev"
    elif os.path.normcase(pythonpath) == os.path.normcase(MODES["official"]["src"]):
        return "official"
    return None


def get_version(src_dir):
    """Liest __version__ aus dem Quellcode."""
    init = os.path.join(src_dir, "bewerbungs_assistent", "__init__.py")
    if not os.path.exists(init):
        return "?"
    with open(init, "r", encoding="utf-8") as f:
        for line in f:
            if line.startswith("__version__"):
                return line.split("=")[1].strip().strip('"').strip("'")
    return "?"


def switch_to(mode_name):
    mode = MODES[mode_name]

    # Pruefen ob Python existiert
    if not os.path.exists(mode["python"]):
        print(f"FEHLER: Python nicht gefunden: {mode['python']}")
        sys.exit(1)

    # Pruefen ob Quellcode existiert
    pkg_dir = os.path.join(mode["src"], "bewerbungs_assistent")
    if not os.path.isdir(pkg_dir):
        print(f"FEHLER: Quellcode nicht gefunden: {pkg_dir}")
        sys.exit(1)

    config = load_config()

    # Eine Regel fuer den Eintrag (#1238): was der Mensch unter env eingetragen hat (API-Schluessel,
    # verlegter Datenordner, Port), bleibt; nur PYTHONPATH folgt dem Modus.
    server = config.setdefault("mcpServers", {})
    server[MCP_KEY] = eintrag_bauen(mode["python"], mode["src"], mode["data_dir"], server.get(MCP_KEY))

    save_config(config)

    version = get_version(mode["src"])
    print(f"Umgeschaltet auf: {mode['label']} (v{version})")
    print(f"  Python:    {mode['python']}")
    print(f"  Quellcode: {mode['src']}")
    print(f"  Daten:     {mode['data_dir']}")
    print()
    print("Claude Desktop muss neu gestartet werden, damit die Aenderung wirkt.")


def show_status():
    config = load_config()
    current = detect_current_mode(config)

    print("=== Bewerbungs-Assistent: Modus-Status ===\n")
    print(f"  Plattform: {sys.platform}")
    print(f"  Config:    {CONFIG_PATH}")
    print()

    if current:
        mode = MODES[current]
        version = get_version(mode["src"])
        print(f"  Aktiver Modus: {mode['label']} (v{version})")
    else:
        entry = config.get("mcpServers", {}).get(MCP_KEY, {})
        pythonpath = entry.get("env", {}).get("PYTHONPATH", "(nicht konfiguriert)")
        print(f"  Aktiver Modus: Unbekannt")
        print(f"  PYTHONPATH:    {pythonpath}")

    print()
    for name, mode in MODES.items():
        version = get_version(mode["src"])
        exists = os.path.exists(mode["python"]) and os.path.isdir(
            os.path.join(mode["src"], "bewerbungs_assistent")
        )
        marker = " <-- aktiv" if name == current else ""
        status = "OK" if exists else "FEHLT"
        print(f"  [{name:9s}] v{version:8s}  ({status}){marker}")
        print(f"              Python: {mode['python']}")
        print(f"              Source: {mode['src']}")
        print()

    print("Nutzung: python switch_mode.py [dev|official]")


# ── Main ───────────────────────────────────────────────────────

if __name__ == "__main__":
    if len(sys.argv) < 2:
        show_status()
    elif sys.argv[1] in ("dev", "official"):
        switch_to(sys.argv[1])
    else:
        print(f"Unbekannter Modus: {sys.argv[1]}")
        print("Nutzung: python switch_mode.py [dev|official]")
        sys.exit(1)