How the Watch Skill Loads Configuration from ~/.config/watch/.env

The watch skill resolves settings from ~/.config/watch/.env by parsing the file into a dictionary while stripping quotes and inline comments, then merging values with environment variables using a strict precedence hierarchy.

The claude-video repository by bradautomates provides a video analysis skill that customizes transcription detail through external configuration. Understanding how this configuration system loads settings from ~/.config/watch/.env allows you to control processing behavior without modifying the Python source.

Configuration File Resolution

The system defines the configuration path using pathlib constants at the top of [skills/watch/scripts/config.py](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/config.py) (lines 9‑10):

CONFIG_DIR = Path.home() / ".config" / "watch"
CONFIG_FILE = CONFIG_DIR / ".env"

This construction guarantees cross-platform resolution of the absolute path ~/.config/watch/.env in the user’s home directory. The skill expects this file to contain simple key-value pairs defining runtime parameters like transcription detail levels.

Parsing Logic in read_env_file()

The read_env_file() function (lines 17‑45) implements a robust parser that converts the .env file into a plain dict[str, str]. The logic handles several edge cases:

  • Blank lines and full-line comments (starting with #) are ignored
  • Quoted values have surrounding single or double quotes stripped
  • Inline comments (a # preceded by whitespace) are removed from unquoted values, preventing stray text from corrupting API keys while preserving # characters inside quoted strings

This parsing strategy ensures that values like WATCH_DETAIL="high #quality" retain the hash character, while WATCH_DETAIL=high # comment correctly evaluates to just high.

Configuration Precedence and Validation

The get_config() function (lines 48‑62) establishes a three-tier precedence order for determining the effective detail setting:

  1. WATCH_DETAIL environment variable (highest priority via os.environ.get)
  2. Parsed .env file values (via file_values.get)
  3. DEFAULT_DETAIL = "balanced" (hard-coded fallback at line 12)

If the resolved value is not contained in the allowed DETAILS list (defined at line 14), the system automatically sanitizes the input and falls back to "balanced". This validation guarantees that downstream processing always receives a valid configuration state.

Frame Extraction Limits with frame_cap()

The configuration system includes a derived helper, frame_cap(detail) (lines 65‑74), which maps the selected detail level to a maximum frame extraction count. Other scripts in the skill use this helper to throttle video processing based on the user’s performance preferences. The function accepts the validated detail string and returns an integer limit or None for unlimited extraction.

Practical Configuration Examples

Reading the current configuration in Python:

from skills.watch.scripts import config

cfg = config.get_config()
print(cfg["detail"])        # e.g., "balanced"

print(cfg["config_file"])   # PosixPath('/home/user/.config/watch/.env')

Overriding via environment variable:

export WATCH_DETAIL=efficient
python -c "import skills.watch.scripts.config as cfg; print(cfg.get_config()['detail'])"

# Output: efficient

Creating a valid .env file:

mkdir -p ~/.config/watch
cat > ~/.config/watch/.env << 'EOF'

# Maximum transcription detail for archival videos

WATCH_DETAIL=transcript
EOF
import skills.watch.scripts.config as cfg
print(cfg.get_config()["detail"])

# Output: transcript

Determining frame limits programmatically:

from skills.watch.scripts import config

detail = config.get_config()["detail"]
max_frames = config.frame_cap(detail)
print(f"Processing up to {max_frames} frames")

Summary

  • The configuration system resolves ~/.config/watch/.env using Path.home() and validates the file’s existence before parsing
  • read_env_file() produces a clean dictionary by handling quotes, blank lines, and inline comments without breaking values containing hash characters
  • get_config() enforces a strict precedence: environment variables override .env file settings, which override the DEFAULT_DETAIL constant
  • Invalid detail values are automatically coerced to "balanced" to prevent runtime errors
  • The frame_cap() helper translates configuration choices into concrete processing limits used by the video extraction pipeline

Frequently Asked Questions

How do I manually create the ~/.config/watch/.env file?

Create the directory ~/.config/watch/ and add a .env file containing KEY=value pairs. The watch skill automatically detects and parses this file on initialization; no restart of the underlying system is required.

What happens if I specify an invalid WATCH_DETAIL value?

The get_config() function checks the resolved value against the allowed DETAILS tuple. If the value is invalid, the system silently falls back to "balanced" as defined by DEFAULT_DETAIL at line 12 of skills/watch/scripts/config.py.

Can environment variables override the .env file without modifying it?

Yes. Export WATCH_DETAIL in your shell environment before running the skill. The configuration loader checks os.environ before inspecting the .env file, giving environment variables the highest precedence in the resolution hierarchy.

Where is the configuration parsing logic tested?

The [tests/test_config.py](https://github.com/bradautomates/claude-video/blob/main/tests/test_config.py) file contains the comprehensive test suite, verifying default fallback behavior, environment variable overrides, and edge cases such as quoted strings containing hash characters.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →