Files
bradautomates 83da59fa78 Fix WATCH_DETAIL silently falling back to default
An inline comment on the WATCH_DETAIL value line (e.g.
`WATCH_DETAIL=balanced  # ...`) parsed as the literal "balanced  # ..."
value, failed validation, and silently reverted to the default mode.

- setup.py: move the allowed-values list off the value line in the env
  template so the wizard no longer models a trailing inline comment.
- config.py: strip a whitespace-preceded inline comment from unquoted
  values so a stray comment can't silently break selection again
  (preserves '#' inside quotes / API keys).
- SKILL.md: note to write the bare key with no trailing comment.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 17:20:07 +10:00

75 lines
2.1 KiB
Python

#!/usr/bin/env python3
"""Shared /watch configuration helpers."""
from __future__ import annotations
import os
from pathlib import Path
CONFIG_DIR = Path.home() / ".config" / "watch"
CONFIG_FILE = CONFIG_DIR / ".env"
DEFAULT_DETAIL = "balanced"
DETAILS = {"transcript", "efficient", "balanced", "token-burner"}
def read_env_file(path: Path | None = None) -> dict[str, str]:
if path is None:
path = CONFIG_FILE
values: dict[str, str] = {}
if not path.exists():
return values
try:
lines = path.read_text(encoding="utf-8").splitlines()
except OSError:
return values
for line in lines:
raw = line.strip()
if not raw or raw.startswith("#") or "=" not in raw:
continue
key, _, value = raw.partition("=")
value = value.strip()
if len(value) >= 2 and value[0] in ('"', "'") and value[-1] == value[0]:
value = value[1:-1]
else:
# Strip an inline comment (a '#' preceded by whitespace) from an
# unquoted value. Without this, `WATCH_DETAIL=balanced # note`
# parses as "balanced # note", fails validation, and silently
# falls back to the default. Keeps '#' inside quotes / API keys.
for i, ch in enumerate(value):
if ch == "#" and i > 0 and value[i - 1] in " \t":
value = value[:i].rstrip()
break
values[key.strip()] = value
return values
def get_config() -> dict[str, object]:
file_values = read_env_file()
detail = (
os.environ.get("WATCH_DETAIL")
or file_values.get("WATCH_DETAIL")
or DEFAULT_DETAIL
)
if detail not in DETAILS:
detail = DEFAULT_DETAIL
return {
"detail": detail,
"config_file": str(CONFIG_FILE),
}
def frame_cap(detail: str) -> int | None:
if detail == "efficient":
return 50
if detail == "balanced":
return 100
if detail == "token-burner":
return None
if detail == "transcript":
return None
return 100