from pathlib import Path import threading # Claude Code conversation directory CLAUDE_PROJECTS_DIR = Path.home() / ".claude" / "projects" # Codex conversation directory CODEX_SESSIONS_DIR = Path.home() / ".codex" / "sessions" # Plugin path for zellij-send-keys ZELLIJ_PLUGIN = Path.home() / ".config" / "zellij" / "plugins" / "zellij-send-keys.wasm" # Runtime data lives in XDG data dir DATA_DIR = Path.home() / ".local" / "share" / "amc" SESSIONS_DIR = DATA_DIR / "sessions" EVENTS_DIR = DATA_DIR / "events" # Source files live in project directory (relative to this module) PROJECT_DIR = Path(__file__).resolve().parent.parent DASHBOARD_DIR = PROJECT_DIR / "dashboard" PORT = 7400 STALE_EVENT_AGE = 86400 # 24 hours in seconds STALE_STARTING_AGE = 3600 # 1 hour - sessions stuck in "starting" are orphans CODEX_ACTIVE_WINDOW = 600 # 10 minutes - only discover recently-active Codex sessions # Cache for Zellij session list (avoid calling zellij on every request) _zellij_cache = {"sessions": None, "expires": 0} # Cache for Codex pane info (avoid running pgrep/ps/lsof on every request) _codex_pane_cache = {"pid_info": {}, "cwd_map": {}, "expires": 0} # Cache for parsed context usage by transcript file path + mtime/size # Limited to prevent unbounded memory growth _context_usage_cache = {} _CONTEXT_CACHE_MAX = 100 # Cache mapping Codex session IDs to transcript paths (or None when missing) _codex_transcript_cache = {} _CODEX_CACHE_MAX = 200 # Codex sessions dismissed during this server lifetime (prevents re-discovery) _dismissed_codex_ids = set() _DISMISSED_MAX = 500 # Serialize state collection because it mutates session files/caches. _state_lock = threading.Lock()