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

1"""Type-safe configuration for dependency injection. 

2 

3This module provides type-safe configuration classes for the Oneiric-backed 

4service container, replacing string-based keys with proper type-based 

5dependency resolution. 

6 

7Phase: Week 7 Day 1 - ACB DI Refactoring 

8""" 

9 

10from __future__ import annotations 

11 

12import os 

13from dataclasses import dataclass 

14from pathlib import Path 

15 

16 

17@dataclass(frozen=True) 

18class SessionPaths: 

19 """Type-safe path configuration for session management. 

20 

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. 

24 

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) 

30 

31 Example: 

32 >>> paths = SessionPaths.from_home() 

33 >>> print(paths.claude_dir) 

34 PosixPath('/Users/username/.claude') 

35 

36 >>> # Use with DI container 

37 >>> depends.set(SessionPaths, paths) 

38 >>> resolved = depends.get_sync(SessionPaths) 

39 

40 """ 

41 

42 claude_dir: Path 

43 logs_dir: Path 

44 commands_dir: Path 

45 data_dir: Path 

46 

47 @classmethod 

48 def from_home(cls, home: Path | None = None) -> SessionPaths: 

49 """Create SessionPaths from home directory. 

50 

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. 

55 

56 Returns: 

57 SessionPaths instance with directories based on the home path. 

58 

59 Example: 

60 >>> # Use default home directory 

61 >>> paths = SessionPaths.from_home() 

62 

63 >>> # Use custom home (useful for testing) 

64 >>> test_home = Path("/tmp/test_home") 

65 >>> paths = SessionPaths.from_home(test_home) 

66 

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("~")) 

72 

73 claude_dir = home / ".claude" 

74 

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 ) 

81 

82 def ensure_directories(self) -> None: 

83 """Create all configured directories if they don't exist. 

84 

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. 

88 

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() 

95 

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)