feat: add configuration module with YAML loading and defaults

Made-with: Cursor
This commit is contained in:
cottongin
2026-03-10 02:26:11 -04:00
parent 0c48edb5f7
commit db94c25b44
7 changed files with 128 additions and 0 deletions

Binary file not shown.

View File

@@ -0,0 +1,72 @@
from dataclasses import dataclass
from pathlib import Path
from typing import Any
import yaml
@dataclass
class Config:
pulse_color: str = "#FF9500"
pulse_width: int = 4
pulse_speed: float = 1.5
pulse_opacity_min: float = 0.3
pulse_opacity_max: float = 1.0
sound_enabled: bool = True
sound_name: str = "Glass"
sound_volume: float = 0.5
poll_interval: float = 0.5
cooldown: float = 3.0
auto_dismiss: int = 300
FIELD_MAP: dict[str, dict[str, str]] = {
"pulse": {
"color": "pulse_color",
"width": "pulse_width",
"speed": "pulse_speed",
"opacity_min": "pulse_opacity_min",
"opacity_max": "pulse_opacity_max",
},
"sound": {
"enabled": "sound_enabled",
"name": "sound_name",
"volume": "sound_volume",
},
"detection": {
"poll_interval": "poll_interval",
"cooldown": "cooldown",
},
"timeout": {
"auto_dismiss": "auto_dismiss",
},
}
DEFAULT_CONFIG_PATH = Path.home() / ".cursor-flasher" / "config.yaml"
def load_config(path: Path = DEFAULT_CONFIG_PATH) -> Config:
"""Load config from YAML, falling back to defaults for missing values."""
if not path.exists():
return Config()
with open(path) as f:
raw = yaml.safe_load(f)
if not raw or not isinstance(raw, dict):
return Config()
overrides: dict[str, Any] = {}
for section, mapping in FIELD_MAP.items():
section_data = raw.get(section, {})
if not isinstance(section_data, dict):
continue
for yaml_key, field_name in mapping.items():
if yaml_key in section_data:
overrides[field_name] = section_data[yaml_key]
return Config(**overrides)