(self)
| 372 | """ |
| 373 | |
| 374 | def __init__(self): |
| 375 | global PID_FILE, SOCKET_FILE, LOG_FILE |
| 376 | |
| 377 | # Load config and apply logging — done here, not at module level, |
| 378 | # so importing core.daemon for CLI helpers doesn't trigger side effects. |
| 379 | self._config = get_config() |
| 380 | DAEMON_DIR.mkdir(parents=True, exist_ok=True) |
| 381 | |
| 382 | log_level = self._config.get("daemon", "log_level", default="INFO") |
| 383 | set_log_level(log_level) |
| 384 | |
| 385 | log_file_path = self._config.get("daemon", "log_file", default=str(LOG_FILE)) |
| 386 | setup_file_logging(log_file_path) |
| 387 | |
| 388 | # Override path constants from config so all other functions see them. |
| 389 | PID_FILE = Path(self._config.get("daemon", "pid_file", default=str(DAEMON_DIR / "codey-v2.pid"))) |
| 390 | SOCKET_FILE = Path(self._config.get("daemon", "socket_file", default=str(DAEMON_DIR / "codey-v2.sock"))) |
| 391 | LOG_FILE = Path(log_file_path) |
| 392 | |
| 393 | self.state = get_state_store() |
| 394 | self.server = DaemonServer(self.state, shutdown_callback=self._trigger_shutdown) |
| 395 | self.executor = TaskExecutor(self.state, self._config) |
| 396 | from core.planner_v2 import get_planner |
| 397 | self.planner = get_planner() |
| 398 | # Give DaemonServer access to the planner so _handle_command can queue steps. |
| 399 | self.server.planner = self.planner |
| 400 | from core.background import get_background_manager, get_file_watch_manager |
| 401 | self.background = get_background_manager() |
| 402 | self.file_watch = get_file_watch_manager() |
| 403 | self.running = True |
| 404 | self._reload_requested = False |
| 405 | |
| 406 | # Register signal handlers |
| 407 | signal.signal(signal.SIGTERM, self._handle_sigterm) |
| 408 | signal.signal(signal.SIGUSR1, self._handle_sigusr1) |
| 409 | |
| 410 | # Wire ProjectMemory: load CODEY.md and config.json at boot (never evicted) |
| 411 | try: |
| 412 | from core.memory import memory as _mem |
| 413 | from core.codeymd import find_codeymd, read_codeymd |
| 414 | from pathlib import Path as _Path |
| 415 | |
| 416 | # Load CODEY.md if it exists |
| 417 | _codeymd_path = find_codeymd() |
| 418 | if _codeymd_path: |
| 419 | _codeymd_content = read_codeymd() |
| 420 | if _codeymd_content and not _codeymd_content.startswith("[ERROR]"): |
| 421 | _mem.add_to_project(_codeymd_path, _codeymd_content, is_protected=True) |
| 422 | info(f"ProjectMemory: loaded {_codeymd_path}") |
| 423 | |
| 424 | # Load config.json if it exists |
| 425 | _config_path = _Path.home() / ".codey-v2" / "config.json" |
| 426 | if _config_path.exists(): |
| 427 | _config_content = _config_path.read_text(encoding="utf-8", errors="replace") |
| 428 | _mem.add_to_project(str(_config_path), _config_content, is_protected=True) |
| 429 | info(f"ProjectMemory: loaded {_config_path}") |
| 430 | except Exception as _e: |
| 431 | warning(f"ProjectMemory initialization skipped: {_e}") |
nothing calls this directly
no test coverage detected