Coverage for session_buddy / di / config.py: 100.00%
21 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-04 00:43 -0800
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-04 00:43 -0800
1"""Type-safe configuration for dependency injection.
3This module provides type-safe configuration classes for the Oneiric-backed
4service container, replacing string-based keys with proper type-based
5dependency resolution.
7Phase: Week 7 Day 1 - ACB DI Refactoring
8"""
10from __future__ import annotations
12import os
13from dataclasses import dataclass
14from pathlib import Path
17@dataclass(frozen=True)
18class SessionPaths:
19 """Type-safe path configuration for session management.
21 This class replaces string-based DI keys (like "paths.claude_dir") with
22 a proper type-based configuration object that works correctly with Bevy's
23 type checking system.
25 Attributes:
26 claude_dir: Root directory for Claude session data (~/.claude)
27 logs_dir: Directory for session logs (~/.claude/logs)
28 commands_dir: Directory for slash commands (~/.claude/commands)
29 data_dir: Directory for database storage (~/.claude/data)
31 Example:
32 >>> paths = SessionPaths.from_home()
33 >>> print(paths.claude_dir)
34 PosixPath('/Users/username/.claude')
36 >>> # Use with DI container
37 >>> depends.set(SessionPaths, paths)
38 >>> resolved = depends.get_sync(SessionPaths)
40 """
42 claude_dir: Path
43 logs_dir: Path
44 commands_dir: Path
45 data_dir: Path
47 @classmethod
48 def from_home(cls, home: Path | None = None) -> SessionPaths:
49 """Create SessionPaths from home directory.
51 Args:
52 home: Optional home directory path. If None, uses current user's home
53 directory via os.path.expanduser("~"). This method respects the
54 HOME environment variable, making it test-friendly.
56 Returns:
57 SessionPaths instance with directories based on the home path.
59 Example:
60 >>> # Use default home directory
61 >>> paths = SessionPaths.from_home()
63 >>> # Use custom home (useful for testing)
64 >>> test_home = Path("/tmp/test_home")
65 >>> paths = SessionPaths.from_home(test_home)
67 """
68 if home is None:
69 # Use os.path.expanduser to respect HOME environment variable
70 # This is test-friendly, unlike Path.home() which uses system APIs
71 home = Path(os.path.expanduser("~"))
73 claude_dir = home / ".claude"
75 return cls(
76 claude_dir=claude_dir,
77 logs_dir=claude_dir / "logs",
78 commands_dir=claude_dir / "commands",
79 data_dir=claude_dir / "data",
80 )
82 def ensure_directories(self) -> None:
83 """Create all configured directories if they don't exist.
85 This method is idempotent and safe to call multiple times.
86 Uses mkdir(parents=True, exist_ok=True) to handle missing parent
87 directories gracefully.
89 Example:
90 >>> paths = SessionPaths.from_home()
91 >>> paths.ensure_directories()
92 >>> assert paths.claude_dir.exists()
93 >>> assert paths.logs_dir.exists()
94 >>> assert paths.data_dir.exists()
96 """
97 self.claude_dir.mkdir(parents=True, exist_ok=True)
98 self.logs_dir.mkdir(parents=True, exist_ok=True)
99 self.commands_dir.mkdir(parents=True, exist_ok=True)
100 self.data_dir.mkdir(parents=True, exist_ok=True)