Coverage for src / moai_adk / hooks / session_start / state_cleanup.py: 0.00%
61 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-20 20:52 +0900
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-20 20:52 +0900
1"""State cleanup module for session_start hook
3Manages configuration loading, state validation, and cleanup scheduling.
5Responsibilities:
6- Load hook timeout from config
7- Get graceful degradation setting
8- Load complete configuration
9- Determine cleanup schedule
10"""
12import json
13import logging
14from datetime import datetime, timedelta
15from pathlib import Path
16from typing import Any, Dict, Optional
18logger = logging.getLogger(__name__)
21class StateError(Exception):
22 """Exception raised for state-related errors"""
24 pass
27def load_hook_timeout() -> int:
28 """Load hook timeout from config.json (default: 3000ms)
30 Returns:
31 Timeout in milliseconds (default: 3000)
33 Raises:
34 StateError: If config file is corrupted
35 """
36 try:
37 config_file = Path(".moai/config/config.json")
38 if config_file.exists():
39 with open(config_file, "r", encoding="utf-8") as f:
40 config = json.load(f)
41 return config.get("hooks", {}).get("timeout_ms", 3000)
42 except json.JSONDecodeError as e:
43 logger.warning(f"Config file corrupted, using default timeout: {e}")
44 except Exception as e:
45 logger.warning(f"Failed to load timeout from config: {e}")
47 return 3000
50def get_graceful_degradation() -> bool:
51 """Load graceful_degradation setting from config.json (default: True)
53 Graceful degradation allows hook to continue even if execution fails.
55 Returns:
56 True if graceful degradation enabled (default: True)
58 Raises:
59 StateError: If config file is corrupted
60 """
61 try:
62 config_file = Path(".moai/config/config.json")
63 if config_file.exists():
64 with open(config_file, "r", encoding="utf-8") as f:
65 config = json.load(f)
66 return config.get("hooks", {}).get("graceful_degradation", True)
67 except json.JSONDecodeError as e:
68 logger.warning(f"Config file corrupted, enabling graceful degradation: {e}")
69 except Exception as e:
70 logger.warning(f"Failed to load graceful_degradation from config: {e}")
72 return True
75def load_config() -> Dict[str, Any]:
76 """Load configuration from .moai/config/config.json
78 Returns:
79 Configuration dictionary (empty dict if file not found)
81 Raises:
82 StateError: If config file is corrupted
83 """
84 try:
85 config_file = Path(".moai/config/config.json")
86 if config_file.exists():
87 with open(config_file, "r", encoding="utf-8") as f:
88 return json.load(f)
89 except json.JSONDecodeError as e:
90 logger.error(f"Config file corrupted: {e}")
91 raise StateError(f"Failed to parse config.json: {e}") from e
92 except Exception as e:
93 logger.warning(f"Failed to load config: {e}")
95 return {}
98def should_cleanup_today(
99 last_cleanup: Optional[str], cleanup_days: int = 7
100) -> bool:
101 """Determine if cleanup is needed today
103 Args:
104 last_cleanup: Last cleanup date in YYYY-MM-DD format (None for first run)
105 cleanup_days: Cleanup interval in days (default: 7)
107 Returns:
108 True if cleanup is needed, False otherwise
110 Raises:
111 StateError: If date parsing fails
112 """
113 if not last_cleanup:
114 return True
116 try:
117 last_date = datetime.strptime(last_cleanup, "%Y-%m-%d")
118 next_cleanup = last_date + timedelta(days=cleanup_days)
119 return datetime.now() >= next_cleanup
120 except ValueError as e:
121 logger.warning(f"Invalid date format: {last_cleanup}: {e}")
122 return True
125def validate_cleanup_config(config: Dict[str, Any]) -> bool:
126 """Validate cleanup configuration
128 Args:
129 config: Configuration dictionary
131 Returns:
132 True if configuration is valid
134 Raises:
135 StateError: If configuration is invalid
136 """
137 cleanup_config = config.get("auto_cleanup", {})
139 # Check required fields
140 if not isinstance(cleanup_config.get("cleanup_days"), (int, float)):
141 logger.warning("cleanup_days not configured, using default 7")
143 if not isinstance(cleanup_config.get("max_reports"), (int, float)):
144 logger.warning("max_reports not configured, using default 10")
146 return True