{"owner":"blakeblackshear","repo":"frigate","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md",".github/copilot-instructions.md"],"skills":{"AGENTS.md":"# Agent Instructions for Frigate NVR\n\nThis document provides coding guidelines and best practices for contributing to Frigate NVR, a complete and local NVR designed for Home Assistant with AI object detection.\n\n## Project Overview\n\nFrigate NVR is a realtime object detection system for IP cameras that uses:\n\n- **Backend**: Python 3.13+ with FastAPI, OpenCV, TensorFlow/ONNX\n- **Frontend**: React with TypeScript, Vite, TailwindCSS\n- **Architecture**: Multiprocessing design with ZMQ and MQTT communication\n- **Focus**: Minimal resource usage with maximum performance\n\n## Code Review Guidelines\n\nWhen reviewing code, do NOT comment on:\n\n- Missing imports - Static analysis tooling catches these\n- Code formatting - Ruff (Python) and Prettier (TypeScript/React) handle formatting\n- Minor style inconsistencies already enforced by linters\n\n## Python Backend Standards\n\n### Python Requirements\n\n- **Compatibility**: Python 3.13+\n- **Language Features**: Use modern Python features:\n  - Pattern matching\n  - Type hints (comprehensive typing preferred)\n  - f-strings (preferred over `%` or `.format()`)\n  - Dataclasses\n  - Async/await patterns\n\n### Code Quality Standards\n\n- **Formatting**: Ruff (configured in `pyproject.toml`)\n- **Linting**: Ruff with rules defined in project config\n- **Type Checking**: Use type hints consistently\n- **Testing**: unittest framework - use `python3 -u -m unittest` to run tests\n- **Language**: American English for all code, comments, and documentation\n- **Punctuation**: Do not use em dashes in documentation, comments, or strings; reword with standard punctuation (commas, colons, parentheses, or separate sentences)\n\n### Logging Standards\n\n- **Logger Pattern**: Use module-level logger\n\n  ```python\n  import logging\n\n  logger = logging.getLogger(__name__)\n  ```\n\n- **Format Guidelines**:\n  - No periods at end of log messages\n  - No sensitive data (keys, tokens, passwords)\n  - Use lazy logging: `logger.debug(\"Message with %s\", variable)`\n- **Log Levels**:\n  - `debug`: Development and troubleshooting information\n  - `info`: Important runtime events (startup, shutdown, state changes)\n  - `warning`: Recoverable issues that should be addressed\n  - `error`: Errors that affect functionality but don't crash the app\n  - `exception`: Use in except blocks to include traceback\n\n### Error Handling\n\n- **Exception Types**: Choose most specific exception available\n- **Try/Catch Best Practices**:\n  - Only wrap code that can throw exceptions\n  - Keep try blocks minimal - process data after the try/except\n  - Avoid bare exceptions except in background tasks\n\n  Bad pattern:\n\n  ```python\n  try:\n      data = await device.get_data()  # Can throw\n      # ❌ Don't process data inside try block\n      processed = data.get(\"value\", 0) * 100\n      result = processed\n  except DeviceError:\n      logger.error(\"Failed to get data\")\n  ```\n\n  Good pattern:\n\n  ```python\n  try:\n      data = await device.get_data()  # Can throw\n  except DeviceError:\n      logger.error(\"Failed to get data\")\n      return\n\n  # ✅ Process data outside try block\n  processed = data.get(\"value\", 0) * 100\n  result = processed\n  ```\n\n### Async Programming\n\n- **External I/O**: All external I/O operations must be async\n- **Best Practices**:\n  - Avoid sleeping in loops - use `asyncio.sleep()` not `time.sleep()`\n  - Avoid awaiting in loops - use `asyncio.gather()` instead\n  - No blocking calls in async functions\n  - Use `asyncio.create_task()` for background operations\n- **Thread Safety**: Use proper synchronization for shared state\n\n### Documentation Standards\n\n- **Module Docstrings**: Concise descriptions at top of files\n  ```python\n  \"\"\"Utilities for motion detection and analysis.\"\"\"\n  ```\n- **Function Docstrings**: Required for public functions and methods\n\n  ```python\n  async def process_frame(frame: ndarray, config: Config) -> Detection:\n      \"\"\"Process a video frame for object detection.\n\n      Args:\n          frame: The video frame as numpy array\n          config: Detection configuration\n\n      Returns:\n          Detection results with bounding boxes\n      \"\"\"\n  ```\n\n- **Comment Style**:\n  - Explain the \"why\" not just the \"what\"\n  - Keep lines under 88 characters when possible\n  - Use clear, descriptive comments\n\n### File Organization\n\n- **API Endpoints**: `frigate/api/` - FastAPI route handlers\n- **Configuration**: `frigate/config/` - Configuration parsing and validation\n- **Detectors**: `frigate/detectors/` - Object detection backends\n- **Events**: `frigate/events/` - Event management and storage\n- **Utilities**: `frigate/util/` - Shared utility functions\n\n## Frontend (React/TypeScript) Standards\n\n### Internationalization (i18n)\n\n- **CRITICAL**: Never write user-facing strings directly in components\n- **Always use react-i18next**: Import and use the `t()` function\n\n  ```tsx\n  import { useTranslation } from \"react-i18next\";\n\n  function MyComponent() {\n    const { t } = useTranslation([\"views/live\"]);\n    return <div>{t(\"camera_not_found\")}</div>;\n  }\n  ```\n\n- **Translation Files**: Add English strings to the appropriate json files in `web/public/locales/en`\n- **Namespaces**: Organize translations by feature/view (e.g., `views/live`, `common`, `views/system`)\n\n### Code Quality\n\n- **Linting**: ESLint (see `web/.eslintrc.cjs`)\n- **Formatting**: Prettier with Tailwind CSS plugin\n- **Type Safety**: TypeScript strict mode enabled\n\n### Component Patterns\n\n- **UI Components**: Use Radix UI primitives (in `web/src/components/ui/`)\n- **Styling**: TailwindCSS with `cn()` utility for class merging\n- **State Management**: React hooks (useState, useEffect, useCallback, useMemo)\n- **Data Fetching**: Custom hooks with proper loading and error states\n\n### ESLint Rules\n\nKey rules enforced:\n\n- `react-hooks/rules-of-hooks`: error\n- `react-hooks/exhaustive-deps`: error\n- `no-console`: error (use proper logging or remove)\n- `@typescript-eslint/no-explicit-any`: warn (always use proper types instead of `any`)\n- Unused variables must be prefixed with `_`\n- Comma dangles required for multiline objects/arrays\n\n### File Organization\n\n- **Pages**: `web/src/pages/` - Route components\n- **Views**: `web/src/views/` - Complex view components\n- **Components**: `web/src/components/` - Reusable components\n- **Hooks**: `web/src/hooks/` - Custom React hooks\n- **API**: `web/src/api/` - API client functions\n- **Types**: `web/src/types/` - TypeScript type definitions\n\n## Testing Requirements\n\n### Backend Testing\n\n- **Framework**: Python unittest\n- **Run Command**: `python3 -u -m unittest`\n- **Location**: `frigate/test/`\n- **Coverage**: Aim for comprehensive test coverage of core functionality\n- **Pattern**: Use `TestCase` classes with descriptive test method names\n  ```python\n  class TestMotionDetection(unittest.TestCase):\n      def test_detects_motion_above_threshold(self):\n          # Test implementation\n  ```\n\n### Test Best Practices\n\n- Always have a way to test your work and confirm your changes\n- Write tests for bug fixes to prevent regressions\n- Test edge cases and error conditions\n- Mock external dependencies (cameras, APIs, hardware)\n- Use fixtures for test data\n\n## Development Commands\n\n### Python Backend\n\n```bash\n# Run all tests\npython3 -u -m unittest\n\n# Run specific test file\npython3 -u -m unittest frigate.test.test_ffmpeg_presets\n\n# Check formatting (Ruff)\nruff format --check frigate/\n\n# Apply formatting\nruff format frigate/\n\n# Run linter\nruff check frigate/\n\n# Type check\npython3 -u -m mypy --config-file frigate/mypy.ini frigate\n\n# Regenerate the OpenAPI spec after adding, changing, or removing an API\n# endpoint or its auth dependency — outputs docs/static/frigate-api.yaml,\n# annotated with each endpoint's auth requirement (admin / any / camera /\n# public). NEVER edit that file by hand. CI runs the --check variant and fails\n# if it is out of date. (from repo root)\npython3 generate_api_auth_spec.py\npython3 generate_api_auth_spec.py --check\n```\n\n### Frontend (from web/ directory)\n\n```bash\n# Start dev server (AI agents should never run this directly unless asked)\nnpm run dev\n\n# Build for production\nnpm run build\n\n# Run linter\nnpm run lint\n\n# Fix linting issues\nnpm run lint:fix\n\n# Format code\nnpm run prettier:write\n\n# E2E: first-time setup\nnpm install\nnpx playwright install chromium\n\n# E2E: build the app and run all tests\nnpm run e2e:build && npm run e2e\n\n# E2E: interactive UI for debugging\nnpm run e2e:ui\n\n# E2E: run a specific spec\nnpx playwright test --config e2e/playwright.config.ts e2e/specs/live.spec.ts\n\n# E2E: filter by name, or run only desktop/mobile\nnpx playwright test --config e2e/playwright.config.ts --grep=\"severity tab\"\nnpx playwright test --config e2e/playwright.config.ts --project=desktop\n\n# E2E: regenerate mock data after backend model changes (from repo root)\nPYTHONPATH=. python3 web/e2e/fixtures/mock-data/generate-mock-data.py\n\n# Regenerate config translations from Pydantic models — outputs to\n# web/public/locales/en/config/{global,cameras}.json. NEVER edit those\n# JSON files by hand; change the Pydantic field title/description and\n# re-run this script. (from repo root)\npython3 generate_config_translations.py\n\n# Extract i18n keys from source into the locale files after adding\n# new t() calls. Use the :ci variant to verify the locale files are\n# in sync with source (fails if extraction would change anything).\nnpm run i18n:extract\nnpm run i18n:extract:ci\n```\n\n### Docker Development\n\nAI agents should never run these commands directly unless instructed.\n\n```bash\n# Build local image\nmake local\n\n# Build debug image\nmake debug\n```\n\n## Common Patterns\n\n### API Endpoint Pattern\n\n```python\nfrom fastapi import APIRouter, Request\nfrom frigate.api.defs.tags import Tags\n\nrouter = APIRouter(tags=[Tags.Events])\n\n@router.get(\"/events\")\nasync def get_events(request: Request, limit: int = 100):\n    \"\"\"Retrieve events from the database.\"\"\"\n    # Implementation\n```\n\nAfter adding, changing, or removing an endpoint (or its auth dependency), regenerate the OpenAPI spec with `python3 generate_api_auth_spec.py` so `docs/static/frigate-api.yaml` stays in sync and the endpoint's auth requirement is documented. CI enforces this via the `--check` variant; never edit that file by hand.\n\n### Configuration Access\n\n```python\n# Access Frigate configuration\nconfig: FrigateConfig = request.app.frigate_config\ncamera_config = config.cameras[\"front_door\"]\n```\n\n### Database Queries\n\n```python\nfrom frigate.models import Event\n\n# Use Peewee ORM for database access\nevents = (\n    Event.select()\n    .where(Event.camera == camera_name)\n    .order_by(Event.start_time.desc())\n    .limit(limit)\n)\n```\n\n## Common Anti-Patterns to Avoid\n\n### ❌ Avoid These\n\n```python\n# Blocking operations in async functions\ndata = requests.get(url)  # ❌ Use async HTTP client\ntime.sleep(5)  # ❌ Use asyncio.sleep()\n\n# Hardcoded strings in React components\n<div>Camera not found</div>  # ❌ Use t(\"camera_not_found\")\n\n# Missing error handling\ndata = await api.get_data()  # ❌ No exception handling\n\n# Bare exceptions in regular code\ntry:\n    value = await sensor.read()\nexcept Exception:  # ❌ Too broad\n    logger.error(\"Failed\")\n\n# Returning exceptions in JSON responses\nexcept ValueError as e:\n    return JSONResponse(\n        content={\"success\": False, \"message\": str(e)},\n    )\n```\n\n### ✅ Use These Instead\n\n```python\n# Async operations\nimport aiohttp\nasync with aiohttp.ClientSession() as session:\n    async with session.get(url) as response:\n        data = await response.json()\n\nawait asyncio.sleep(5)  # ✅ Non-blocking\n\n# Translatable strings in React\nconst { t } = useTranslation();\n<div>{t(\"camera_not_found\")}</div>  # ✅ Translatable\n\n# Proper error handling\ntry:\n    data = await api.get_data()\nexcept ApiException as err:\n    logger.error(\"API error: %s\", err)\n    raise\n\n# Specific exceptions\ntry:\n    value = await sensor.read()\nexcept SensorException as err:  # ✅ Specific\n    logger.exception(\"Failed to read sensor\")\n\n# Safe error responses\nexcept ValueError:\n    logger.exception(\"Invalid parameters for API request\")\n    return JSONResponse(\n        content={\n            \"success\": False,\n            \"message\": \"Invalid request parameters\",\n        },\n    )\n```\n\n## WebSocket Broadcasts\n\nOutbound WebSocket broadcasts go through a per-recipient classifier in `frigate/comms/ws.py` that enforces camera-level access. **The classifier is fail-closed: any topic it doesn't recognize is dropped for every client.** New outbound topics must be classified there or they'll silently disappear.\n\n## Project-Specific Conventions\n\n### Configuration Files\n\n- Main config: `config/config.yml`\n\n### Directory Structure\n\n- Backend code: `frigate/`\n- Frontend code: `web/`\n- Docker files: `docker/`\n- Documentation: `docs/`\n- Database migrations: `migrations/`\n\n### Code Style Conformance\n\nAlways conform new and refactored code to the existing coding style in the project:\n\n- Follow established patterns in similar files\n- Match indentation and formatting of surrounding code\n- Use consistent naming conventions (snake_case for Python, camelCase for TypeScript)\n- Maintain the same level of verbosity in comments and docstrings\n\n## Additional Resources\n\n- Documentation: https://docs.frigate.video\n- Main Repository: https://github.com/blakeblackshear/frigate\n- Home Assistant Integration: https://github.com/blakeblackshear/frigate-hass-integration\n",".github/copilot-instructions.md":"# GitHub Copilot Instructions for Frigate NVR\n\nThis document provides coding guidelines and best practices for contributing to Frigate NVR, a complete and local NVR designed for Home Assistant with AI object detection.\n\n## Project Overview\n\nFrigate NVR is a realtime object detection system for IP cameras that uses:\n\n- **Backend**: Python 3.13+ with FastAPI, OpenCV, TensorFlow/ONNX\n- **Frontend**: React with TypeScript, Vite, TailwindCSS\n- **Architecture**: Multiprocessing design with ZMQ and MQTT communication\n- **Focus**: Minimal resource usage with maximum performance\n\n## Code Review Guidelines\n\nWhen reviewing code, do NOT comment on:\n\n- Missing imports - Static analysis tooling catches these\n- Code formatting - Ruff (Python) and Prettier (TypeScript/React) handle formatting\n- Minor style inconsistencies already enforced by linters\n\n## Python Backend Standards\n\n### Python Requirements\n\n- **Compatibility**: Python 3.13+\n- **Language Features**: Use modern Python features:\n  - Pattern matching\n  - Type hints (comprehensive typing preferred)\n  - f-strings (preferred over `%` or `.format()`)\n  - Dataclasses\n  - Async/await patterns\n\n### Code Quality Standards\n\n- **Formatting**: Ruff (configured in `pyproject.toml`)\n- **Linting**: Ruff with rules defined in project config\n- **Type Checking**: Use type hints consistently\n- **Testing**: unittest framework - use `python3 -u -m unittest` to run tests\n- **Language**: American English for all code, comments, and documentation\n\n### Logging Standards\n\n- **Logger Pattern**: Use module-level logger\n\n  ```python\n  import logging\n\n  logger = logging.getLogger(__name__)\n  ```\n\n- **Format Guidelines**:\n  - No periods at end of log messages\n  - No sensitive data (keys, tokens, passwords)\n  - Use lazy logging: `logger.debug(\"Message with %s\", variable)`\n- **Log Levels**:\n  - `debug`: Development and troubleshooting information\n  - `info`: Important runtime events (startup, shutdown, state changes)\n  - `warning`: Recoverable issues that should be addressed\n  - `error`: Errors that affect functionality but don't crash the app\n  - `exception`: Use in except blocks to include traceback\n\n### Error Handling\n\n- **Exception Types**: Choose most specific exception available\n- **Try/Catch Best Practices**:\n  - Only wrap code that can throw exceptions\n  - Keep try blocks minimal - process data after the try/except\n  - Avoid bare exceptions except in background tasks\n\n  Bad pattern:\n\n  ```python\n  try:\n      data = await device.get_data()  # Can throw\n      # ❌ Don't process data inside try block\n      processed = data.get(\"value\", 0) * 100\n      result = processed\n  except DeviceError:\n      logger.error(\"Failed to get data\")\n  ```\n\n  Good pattern:\n\n  ```python\n  try:\n      data = await device.get_data()  # Can throw\n  except DeviceError:\n      logger.error(\"Failed to get data\")\n      return\n\n  # ✅ Process data outside try block\n  processed = data.get(\"value\", 0) * 100\n  result = processed\n  ```\n\n### Async Programming\n\n- **External I/O**: All external I/O operations must be async\n- **Best Practices**:\n  - Avoid sleeping in loops - use `asyncio.sleep()` not `time.sleep()`\n  - Avoid awaiting in loops - use `asyncio.gather()` instead\n  - No blocking calls in async functions\n  - Use `asyncio.create_task()` for background operations\n- **Thread Safety**: Use proper synchronization for shared state\n\n### Documentation Standards\n\n- **Module Docstrings**: Concise descriptions at top of files\n  ```python\n  \"\"\"Utilities for motion detection and analysis.\"\"\"\n  ```\n- **Function Docstrings**: Required for public functions and methods\n\n  ```python\n  async def process_frame(frame: ndarray, config: Config) -> Detection:\n      \"\"\"Process a video frame for object detection.\n\n      Args:\n          frame: The video frame as numpy array\n          config: Detection configuration\n\n      Returns:\n          Detection results with bounding boxes\n      \"\"\"\n  ```\n\n- **Comment Style**:\n  - Explain the \"why\" not just the \"what\"\n  - Keep lines under 88 characters when possible\n  - Use clear, descriptive comments\n\n### File Organization\n\n- **API Endpoints**: `frigate/api/` - FastAPI route handlers\n- **Configuration**: `frigate/config/` - Configuration parsing and validation\n- **Detectors**: `frigate/detectors/` - Object detection backends\n- **Events**: `frigate/events/` - Event management and storage\n- **Utilities**: `frigate/util/` - Shared utility functions\n\n## Frontend (React/TypeScript) Standards\n\n### Internationalization (i18n)\n\n- **CRITICAL**: Never write user-facing strings directly in components\n- **Always use react-i18next**: Import and use the `t()` function\n\n  ```tsx\n  import { useTranslation } from \"react-i18next\";\n\n  function MyComponent() {\n    const { t } = useTranslation([\"views/live\"]);\n    return <div>{t(\"camera_not_found\")}</div>;\n  }\n  ```\n\n- **Translation Files**: Add English strings to the appropriate json files in `web/public/locales/en`\n- **Namespaces**: Organize translations by feature/view (e.g., `views/live`, `common`, `views/system`)\n\n### Code Quality\n\n- **Linting**: ESLint (see `web/.eslintrc.cjs`)\n- **Formatting**: Prettier with Tailwind CSS plugin\n- **Type Safety**: TypeScript strict mode enabled\n- **Testing**: Vitest for unit tests\n\n### Component Patterns\n\n- **UI Components**: Use Radix UI primitives (in `web/src/components/ui/`)\n- **Styling**: TailwindCSS with `cn()` utility for class merging\n- **State Management**: React hooks (useState, useEffect, useCallback, useMemo)\n- **Data Fetching**: Custom hooks with proper loading and error states\n\n### ESLint Rules\n\nKey rules enforced:\n\n- `react-hooks/rules-of-hooks`: error\n- `react-hooks/exhaustive-deps`: error\n- `no-console`: error (use proper logging or remove)\n- `@typescript-eslint/no-explicit-any`: warn (always use proper types instead of `any`)\n- Unused variables must be prefixed with `_`\n- Comma dangles required for multiline objects/arrays\n\n### File Organization\n\n- **Pages**: `web/src/pages/` - Route components\n- **Views**: `web/src/views/` - Complex view components\n- **Components**: `web/src/components/` - Reusable components\n- **Hooks**: `web/src/hooks/` - Custom React hooks\n- **API**: `web/src/api/` - API client functions\n- **Types**: `web/src/types/` - TypeScript type definitions\n\n## Testing Requirements\n\n### Backend Testing\n\n- **Framework**: Python unittest\n- **Run Command**: `python3 -u -m unittest`\n- **Location**: `frigate/test/`\n- **Coverage**: Aim for comprehensive test coverage of core functionality\n- **Pattern**: Use `TestCase` classes with descriptive test method names\n  ```python\n  class TestMotionDetection(unittest.TestCase):\n      def test_detects_motion_above_threshold(self):\n          # Test implementation\n  ```\n\n### Test Best Practices\n\n- Always have a way to test your work and confirm your changes\n- Write tests for bug fixes to prevent regressions\n- Test edge cases and error conditions\n- Mock external dependencies (cameras, APIs, hardware)\n- Use fixtures for test data\n\n## Development Commands\n\n### Python Backend\n\n```bash\n# Run all tests\npython3 -u -m unittest\n\n# Run specific test file\npython3 -u -m unittest frigate.test.test_ffmpeg_presets\n\n# Check formatting (Ruff)\nruff format --check frigate/\n\n# Apply formatting\nruff format frigate/\n\n# Run linter\nruff check frigate/\n```\n\n### Frontend (from web/ directory)\n\n```bash\n# Start dev server (AI agents should never run this directly unless asked)\nnpm run dev\n\n# Build for production\nnpm run build\n\n# Run linter\nnpm run lint\n\n# Fix linting issues\nnpm run lint:fix\n\n# Format code\nnpm run prettier:write\n```\n\n### Docker Development\n\nAI agents should never run these commands directly unless instructed.\n\n```bash\n# Build local image\nmake local\n\n# Build debug image\nmake debug\n```\n\n## Common Patterns\n\n### API Endpoint Pattern\n\n```python\nfrom fastapi import APIRouter, Request\nfrom frigate.api.defs.tags import Tags\n\nrouter = APIRouter(tags=[Tags.Events])\n\n@router.get(\"/events\")\nasync def get_events(request: Request, limit: int = 100):\n    \"\"\"Retrieve events from the database.\"\"\"\n    # Implementation\n```\n\n### Configuration Access\n\n```python\n# Access Frigate configuration\nconfig: FrigateConfig = request.app.frigate_config\ncamera_config = config.cameras[\"front_door\"]\n```\n\n### Database Queries\n\n```python\nfrom frigate.models import Event\n\n# Use Peewee ORM for database access\nevents = (\n    Event.select()\n    .where(Event.camera == camera_name)\n    .order_by(Event.start_time.desc())\n    .limit(limit)\n)\n```\n\n## Common Anti-Patterns to Avoid\n\n### ❌ Avoid These\n\n```python\n# Blocking operations in async functions\ndata = requests.get(url)  # ❌ Use async HTTP client\ntime.sleep(5)  # ❌ Use asyncio.sleep()\n\n# Hardcoded strings in React components\n<div>Camera not found</div>  # ❌ Use t(\"camera_not_found\")\n\n# Missing error handling\ndata = await api.get_data()  # ❌ No exception handling\n\n# Bare exceptions in regular code\ntry:\n    value = await sensor.read()\nexcept Exception:  # ❌ Too broad\n    logger.error(\"Failed\")\n```\n\n### ✅ Use These Instead\n\n```python\n# Async operations\nimport aiohttp\nasync with aiohttp.ClientSession() as session:\n    async with session.get(url) as response:\n        data = await response.json()\n\nawait asyncio.sleep(5)  # ✅ Non-blocking\n\n# Translatable strings in React\nconst { t } = useTranslation();\n<div>{t(\"camera_not_found\")}</div>  # ✅ Translatable\n\n# Proper error handling\ntry:\n    data = await api.get_data()\nexcept ApiException as err:\n    logger.error(\"API error: %s\", err)\n    raise\n\n# Specific exceptions\ntry:\n    value = await sensor.read()\nexcept SensorException as err:  # ✅ Specific\n    logger.exception(\"Failed to read sensor\")\n```\n\n## Project-Specific Conventions\n\n### Configuration Files\n\n- Main config: `config/config.yml`\n\n### Directory Structure\n\n- Backend code: `frigate/`\n- Frontend code: `web/`\n- Docker files: `docker/`\n- Documentation: `docs/`\n- Database migrations: `migrations/`\n\n### Code Style Conformance\n\nAlways conform new and refactored code to the existing coding style in the project:\n\n- Follow established patterns in similar files\n- Match indentation and formatting of surrounding code\n- Use consistent naming conventions (snake_case for Python, camelCase for TypeScript)\n- Maintain the same level of verbosity in comments and docstrings\n\n## Additional Resources\n\n- Documentation: https://docs.frigate.video\n- Main Repository: https://github.com/blakeblackshear/frigate\n- Home Assistant Integration: https://github.com/blakeblackshear/frigate-hass-integration\n"},"files":{"AGENTS.md":"# Agent Instructions for Frigate NVR\n\nThis document provides coding guidelines and best practices for contributing to Frigate NVR, a complete and local NVR designed for Home Assistant with AI object detection.\n\n## Project Overview\n\nFrigate NVR is a realtime object detection system for IP cameras that uses:\n\n- **Backend**: Python 3.13+ with FastAPI, OpenCV, TensorFlow/ONNX\n- **Frontend**: React with TypeScript, Vite, TailwindCSS\n- **Architecture**: Multiprocessing design with ZMQ and MQTT communication\n- **Focus**: Minimal resource usage with maximum performance\n\n## Code Review Guidelines\n\nWhen reviewing code, do NOT comment on:\n\n- Missing imports - Static analysis tooling catches these\n- Code formatting - Ruff (Python) and Prettier (TypeScript/React) handle formatting\n- Minor style inconsistencies already enforced by linters\n\n## Python Backend Standards\n\n### Python Requirements\n\n- **Compatibility**: Python 3.13+\n- **Language Features**: Use modern Python features:\n  - Pattern matching\n  - Type hints (comprehensive typing preferred)\n  - f-strings (preferred over `%` or `.format()`)\n  - Dataclasses\n  - Async/await patterns\n\n### Code Quality Standards\n\n- **Formatting**: Ruff (configured in `pyproject.toml`)\n- **Linting**: Ruff with rules defined in project config\n- **Type Checking**: Use type hints consistently\n- **Testing**: unittest framework - use `python3 -u -m unittest` to run tests\n- **Language**: American English for all code, comments, and documentation\n- **Punctuation**: Do not use em dashes in documentation, comments, or strings; reword with standard punctuation (commas, colons, parentheses, or separate sentences)\n\n### Logging Standards\n\n- **Logger Pattern**: Use module-level logger\n\n  ```python\n  import logging\n\n  logger = logging.getLogger(__name__)\n  ```\n\n- **Format Guidelines**:\n  - No periods at end of log messages\n  - No sensitive data (keys, tokens, passwords)\n  - Use lazy logging: `logger.debug(\"Message with %s\", variable)`\n- **Log Levels**:\n  - `debug`: Development and troubleshooting information\n  - `info`: Important runtime events (startup, shutdown, state changes)\n  - `warning`: Recoverable issues that should be addressed\n  - `error`: Errors that affect functionality but don't crash the app\n  - `exception`: Use in except blocks to include traceback\n\n### Error Handling\n\n- **Exception Types**: Choose most specific exception available\n- **Try/Catch Best Practices**:\n  - Only wrap code that can throw exceptions\n  - Keep try blocks minimal - process data after the try/except\n  - Avoid bare exceptions except in background tasks\n\n  Bad pattern:\n\n  ```python\n  try:\n      data = await device.get_data()  # Can throw\n      # ❌ Don't process data inside try block\n      processed = data.get(\"value\", 0) * 100\n      result = processed\n  except DeviceError:\n      logger.error(\"Failed to get data\")\n  ```\n\n  Good pattern:\n\n  ```python\n  try:\n      data = await device.get_data()  # Can throw\n  except DeviceError:\n      logger.error(\"Failed to get data\")\n      return\n\n  # ✅ Process data outside try block\n  processed = data.get(\"value\", 0) * 100\n  result = processed\n  ```\n\n### Async Programming\n\n- **External I/O**: All external I/O operations must be async\n- **Best Practices**:\n  - Avoid sleeping in loops - use `asyncio.sleep()` not `time.sleep()`\n  - Avoid awaiting in loops - use `asyncio.gather()` instead\n  - No blocking calls in async functions\n  - Use `asyncio.create_task()` for background operations\n- **Thread Safety**: Use proper synchronization for shared state\n\n### Documentation Standards\n\n- **Module Docstrings**: Concise descriptions at top of files\n  ```python\n  \"\"\"Utilities for motion detection and analysis.\"\"\"\n  ```\n- **Function Docstrings**: Required for public functions and methods\n\n  ```python\n  async def process_frame(frame: ndarray, config: Config) -> Detection:\n      \"\"\"Process a video frame for object detection.\n\n      Args:\n          frame: The video frame as numpy array\n          config: Detection configuration\n\n      Returns:\n          Detection results with bounding boxes\n      \"\"\"\n  ```\n\n- **Comment Style**:\n  - Explain the \"why\" not just the \"what\"\n  - Keep lines under 88 characters when possible\n  - Use clear, descriptive comments\n\n### File Organization\n\n- **API Endpoints**: `frigate/api/` - FastAPI route handlers\n- **Configuration**: `frigate/config/` - Configuration parsing and validation\n- **Detectors**: `frigate/detectors/` - Object detection backends\n- **Events**: `frigate/events/` - Event management and storage\n- **Utilities**: `frigate/util/` - Shared utility functions\n\n## Frontend (React/TypeScript) Standards\n\n### Internationalization (i18n)\n\n- **CRITICAL**: Never write user-facing strings directly in components\n- **Always use react-i18next**: Import and use the `t()` function\n\n  ```tsx\n  import { useTranslation } from \"react-i18next\";\n\n  function MyComponent() {\n    const { t } = useTranslation([\"views/live\"]);\n    return <div>{t(\"camera_not_found\")}</div>;\n  }\n  ```\n\n- **Translation Files**: Add English strings to the appropriate json files in `web/public/locales/en`\n- **Namespaces**: Organize translations by feature/view (e.g., `views/live`, `common`, `views/system`)\n\n### Code Quality\n\n- **Linting**: ESLint (see `web/.eslintrc.cjs`)\n- **Formatting**: Prettier with Tailwind CSS plugin\n- **Type Safety**: TypeScript strict mode enabled\n\n### Component Patterns\n\n- **UI Components**: Use Radix UI primitives (in `web/src/components/ui/`)\n- **Styling**: TailwindCSS with `cn()` utility for class merging\n- **State Management**: React hooks (useState, useEffect, useCallback, useMemo)\n- **Data Fetching**: Custom hooks with proper loading and error states\n\n### ESLint Rules\n\nKey rules enforced:\n\n- `react-hooks/rules-of-hooks`: error\n- `react-hooks/exhaustive-deps`: error\n- `no-console`: error (use proper logging or remove)\n- `@typescript-eslint/no-explicit-any`: warn (always use proper types instead of `any`)\n- Unused variables must be prefixed with `_`\n- Comma dangles required for multiline objects/arrays\n\n### File Organization\n\n- **Pages**: `web/src/pages/` - Route components\n- **Views**: `web/src/views/` - Complex view components\n- **Components**: `web/src/components/` - Reusable components\n- **Hooks**: `web/src/hooks/` - Custom React hooks\n- **API**: `web/src/api/` - API client functions\n- **Types**: `web/src/types/` - TypeScript type definitions\n\n## Testing Requirements\n\n### Backend Testing\n\n- **Framework**: Python unittest\n- **Run Command**: `python3 -u -m unittest`\n- **Location**: `frigate/test/`\n- **Coverage**: Aim for comprehensive test coverage of core functionality\n- **Pattern**: Use `TestCase` classes with descriptive test method names\n  ```python\n  class TestMotionDetection(unittest.TestCase):\n      def test_detects_motion_above_threshold(self):\n          # Test implementation\n  ```\n\n### Test Best Practices\n\n- Always have a way to test your work and confirm your changes\n- Write tests for bug fixes to prevent regressions\n- Test edge cases and error conditions\n- Mock external dependencies (cameras, APIs, hardware)\n- Use fixtures for test data\n\n## Development Commands\n\n### Python Backend\n\n```bash\n# Run all tests\npython3 -u -m unittest\n\n# Run specific test file\npython3 -u -m unittest frigate.test.test_ffmpeg_presets\n\n# Check formatting (Ruff)\nruff format --check frigate/\n\n# Apply formatting\nruff format frigate/\n\n# Run linter\nruff check frigate/\n\n# Type check\npython3 -u -m mypy --config-file frigate/mypy.ini frigate\n\n# Regenerate the OpenAPI spec after adding, changing, or removing an API\n# endpoint or its auth dependency — outputs docs/static/frigate-api.yaml,\n# annotated with each endpoint's auth requirement (admin / any / camera /\n# public). NEVER edit that file by hand. CI runs the --check variant and fails\n# if it is out of date. (from repo root)\npython3 generate_api_auth_spec.py\npython3 generate_api_auth_spec.py --check\n```\n\n### Frontend (from web/ directory)\n\n```bash\n# Start dev server (AI agents should never run this directly unless asked)\nnpm run dev\n\n# Build for production\nnpm run build\n\n# Run linter\nnpm run lint\n\n# Fix linting issues\nnpm run lint:fix\n\n# Format code\nnpm run prettier:write\n\n# E2E: first-time setup\nnpm install\nnpx playwright install chromium\n\n# E2E: build the app and run all tests\nnpm run e2e:build && npm run e2e\n\n# E2E: interactive UI for debugging\nnpm run e2e:ui\n\n# E2E: run a specific spec\nnpx playwright test --config e2e/playwright.config.ts e2e/specs/live.spec.ts\n\n# E2E: filter by name, or run only desktop/mobile\nnpx playwright test --config e2e/playwright.config.ts --grep=\"severity tab\"\nnpx playwright test --config e2e/playwright.config.ts --project=desktop\n\n# E2E: regenerate mock data after backend model changes (from repo root)\nPYTHONPATH=. python3 web/e2e/fixtures/mock-data/generate-mock-data.py\n\n# Regenerate config translations from Pydantic models — outputs to\n# web/public/locales/en/config/{global,cameras}.json. NEVER edit those\n# JSON files by hand; change the Pydantic field title/description and\n# re-run this script. (from repo root)\npython3 generate_config_translations.py\n\n# Extract i18n keys from source into the locale files after adding\n# new t() calls. Use the :ci variant to verify the locale files are\n# in sync with source (fails if extraction would change anything).\nnpm run i18n:extract\nnpm run i18n:extract:ci\n```\n\n### Docker Development\n\nAI agents should never run these commands directly unless instructed.\n\n```bash\n# Build local image\nmake local\n\n# Build debug image\nmake debug\n```\n\n## Common Patterns\n\n### API Endpoint Pattern\n\n```python\nfrom fastapi import APIRouter, Request\nfrom frigate.api.defs.tags import Tags\n\nrouter = APIRouter(tags=[Tags.Events])\n\n@router.get(\"/events\")\nasync def get_events(request: Request, limit: int = 100):\n    \"\"\"Retrieve events from the database.\"\"\"\n    # Implementation\n```\n\nAfter adding, changing, or removing an endpoint (or its auth dependency), regenerate the OpenAPI spec with `python3 generate_api_auth_spec.py` so `docs/static/frigate-api.yaml` stays in sync and the endpoint's auth requirement is documented. CI enforces this via the `--check` variant; never edit that file by hand.\n\n### Configuration Access\n\n```python\n# Access Frigate configuration\nconfig: FrigateConfig = request.app.frigate_config\ncamera_config = config.cameras[\"front_door\"]\n```\n\n### Database Queries\n\n```python\nfrom frigate.models import Event\n\n# Use Peewee ORM for database access\nevents = (\n    Event.select()\n    .where(Event.camera == camera_name)\n    .order_by(Event.start_time.desc())\n    .limit(limit)\n)\n```\n\n## Common Anti-Patterns to Avoid\n\n### ❌ Avoid These\n\n```python\n# Blocking operations in async functions\ndata = requests.get(url)  # ❌ Use async HTTP client\ntime.sleep(5)  # ❌ Use asyncio.sleep()\n\n# Hardcoded strings in React components\n<div>Camera not found</div>  # ❌ Use t(\"camera_not_found\")\n\n# Missing error handling\ndata = await api.get_data()  # ❌ No exception handling\n\n# Bare exceptions in regular code\ntry:\n    value = await sensor.read()\nexcept Exception:  # ❌ Too broad\n    logger.error(\"Failed\")\n\n# Returning exceptions in JSON responses\nexcept ValueError as e:\n    return JSONResponse(\n        content={\"success\": False, \"message\": str(e)},\n    )\n```\n\n### ✅ Use These Instead\n\n```python\n# Async operations\nimport aiohttp\nasync with aiohttp.ClientSession() as session:\n    async with session.get(url) as response:\n        data = await response.json()\n\nawait asyncio.sleep(5)  # ✅ Non-blocking\n\n# Translatable strings in React\nconst { t } = useTranslation();\n<div>{t(\"camera_not_found\")}</div>  # ✅ Translatable\n\n# Proper error handling\ntry:\n    data = await api.get_data()\nexcept ApiException as err:\n    logger.error(\"API error: %s\", err)\n    raise\n\n# Specific exceptions\ntry:\n    value = await sensor.read()\nexcept SensorException as err:  # ✅ Specific\n    logger.exception(\"Failed to read sensor\")\n\n# Safe error responses\nexcept ValueError:\n    logger.exception(\"Invalid parameters for API request\")\n    return JSONResponse(\n        content={\n            \"success\": False,\n            \"message\": \"Invalid request parameters\",\n        },\n    )\n```\n\n## WebSocket Broadcasts\n\nOutbound WebSocket broadcasts go through a per-recipient classifier in `frigate/comms/ws.py` that enforces camera-level access. **The classifier is fail-closed: any topic it doesn't recognize is dropped for every client.** New outbound topics must be classified there or they'll silently disappear.\n\n## Project-Specific Conventions\n\n### Configuration Files\n\n- Main config: `config/config.yml`\n\n### Directory Structure\n\n- Backend code: `frigate/`\n- Frontend code: `web/`\n- Docker files: `docker/`\n- Documentation: `docs/`\n- Database migrations: `migrations/`\n\n### Code Style Conformance\n\nAlways conform new and refactored code to the existing coding style in the project:\n\n- Follow established patterns in similar files\n- Match indentation and formatting of surrounding code\n- Use consistent naming conventions (snake_case for Python, camelCase for TypeScript)\n- Maintain the same level of verbosity in comments and docstrings\n\n## Additional Resources\n\n- Documentation: https://docs.frigate.video\n- Main Repository: https://github.com/blakeblackshear/frigate\n- Home Assistant Integration: https://github.com/blakeblackshear/frigate-hass-integration\n",".github/copilot-instructions.md":"# GitHub Copilot Instructions for Frigate NVR\n\nThis document provides coding guidelines and best practices for contributing to Frigate NVR, a complete and local NVR designed for Home Assistant with AI object detection.\n\n## Project Overview\n\nFrigate NVR is a realtime object detection system for IP cameras that uses:\n\n- **Backend**: Python 3.13+ with FastAPI, OpenCV, TensorFlow/ONNX\n- **Frontend**: React with TypeScript, Vite, TailwindCSS\n- **Architecture**: Multiprocessing design with ZMQ and MQTT communication\n- **Focus**: Minimal resource usage with maximum performance\n\n## Code Review Guidelines\n\nWhen reviewing code, do NOT comment on:\n\n- Missing imports - Static analysis tooling catches these\n- Code formatting - Ruff (Python) and Prettier (TypeScript/React) handle formatting\n- Minor style inconsistencies already enforced by linters\n\n## Python Backend Standards\n\n### Python Requirements\n\n- **Compatibility**: Python 3.13+\n- **Language Features**: Use modern Python features:\n  - Pattern matching\n  - Type hints (comprehensive typing preferred)\n  - f-strings (preferred over `%` or `.format()`)\n  - Dataclasses\n  - Async/await patterns\n\n### Code Quality Standards\n\n- **Formatting**: Ruff (configured in `pyproject.toml`)\n- **Linting**: Ruff with rules defined in project config\n- **Type Checking**: Use type hints consistently\n- **Testing**: unittest framework - use `python3 -u -m unittest` to run tests\n- **Language**: American English for all code, comments, and documentation\n\n### Logging Standards\n\n- **Logger Pattern**: Use module-level logger\n\n  ```python\n  import logging\n\n  logger = logging.getLogger(__name__)\n  ```\n\n- **Format Guidelines**:\n  - No periods at end of log messages\n  - No sensitive data (keys, tokens, passwords)\n  - Use lazy logging: `logger.debug(\"Message with %s\", variable)`\n- **Log Levels**:\n  - `debug`: Development and troubleshooting information\n  - `info`: Important runtime events (startup, shutdown, state changes)\n  - `warning`: Recoverable issues that should be addressed\n  - `error`: Errors that affect functionality but don't crash the app\n  - `exception`: Use in except blocks to include traceback\n\n### Error Handling\n\n- **Exception Types**: Choose most specific exception available\n- **Try/Catch Best Practices**:\n  - Only wrap code that can throw exceptions\n  - Keep try blocks minimal - process data after the try/except\n  - Avoid bare exceptions except in background tasks\n\n  Bad pattern:\n\n  ```python\n  try:\n      data = await device.get_data()  # Can throw\n      # ❌ Don't process data inside try block\n      processed = data.get(\"value\", 0) * 100\n      result = processed\n  except DeviceError:\n      logger.error(\"Failed to get data\")\n  ```\n\n  Good pattern:\n\n  ```python\n  try:\n      data = await device.get_data()  # Can throw\n  except DeviceError:\n      logger.error(\"Failed to get data\")\n      return\n\n  # ✅ Process data outside try block\n  processed = data.get(\"value\", 0) * 100\n  result = processed\n  ```\n\n### Async Programming\n\n- **External I/O**: All external I/O operations must be async\n- **Best Practices**:\n  - Avoid sleeping in loops - use `asyncio.sleep()` not `time.sleep()`\n  - Avoid awaiting in loops - use `asyncio.gather()` instead\n  - No blocking calls in async functions\n  - Use `asyncio.create_task()` for background operations\n- **Thread Safety**: Use proper synchronization for shared state\n\n### Documentation Standards\n\n- **Module Docstrings**: Concise descriptions at top of files\n  ```python\n  \"\"\"Utilities for motion detection and analysis.\"\"\"\n  ```\n- **Function Docstrings**: Required for public functions and methods\n\n  ```python\n  async def process_frame(frame: ndarray, config: Config) -> Detection:\n      \"\"\"Process a video frame for object detection.\n\n      Args:\n          frame: The video frame as numpy array\n          config: Detection configuration\n\n      Returns:\n          Detection results with bounding boxes\n      \"\"\"\n  ```\n\n- **Comment Style**:\n  - Explain the \"why\" not just the \"what\"\n  - Keep lines under 88 characters when possible\n  - Use clear, descriptive comments\n\n### File Organization\n\n- **API Endpoints**: `frigate/api/` - FastAPI route handlers\n- **Configuration**: `frigate/config/` - Configuration parsing and validation\n- **Detectors**: `frigate/detectors/` - Object detection backends\n- **Events**: `frigate/events/` - Event management and storage\n- **Utilities**: `frigate/util/` - Shared utility functions\n\n## Frontend (React/TypeScript) Standards\n\n### Internationalization (i18n)\n\n- **CRITICAL**: Never write user-facing strings directly in components\n- **Always use react-i18next**: Import and use the `t()` function\n\n  ```tsx\n  import { useTranslation } from \"react-i18next\";\n\n  function MyComponent() {\n    const { t } = useTranslation([\"views/live\"]);\n    return <div>{t(\"camera_not_found\")}</div>;\n  }\n  ```\n\n- **Translation Files**: Add English strings to the appropriate json files in `web/public/locales/en`\n- **Namespaces**: Organize translations by feature/view (e.g., `views/live`, `common`, `views/system`)\n\n### Code Quality\n\n- **Linting**: ESLint (see `web/.eslintrc.cjs`)\n- **Formatting**: Prettier with Tailwind CSS plugin\n- **Type Safety**: TypeScript strict mode enabled\n- **Testing**: Vitest for unit tests\n\n### Component Patterns\n\n- **UI Components**: Use Radix UI primitives (in `web/src/components/ui/`)\n- **Styling**: TailwindCSS with `cn()` utility for class merging\n- **State Management**: React hooks (useState, useEffect, useCallback, useMemo)\n- **Data Fetching**: Custom hooks with proper loading and error states\n\n### ESLint Rules\n\nKey rules enforced:\n\n- `react-hooks/rules-of-hooks`: error\n- `react-hooks/exhaustive-deps`: error\n- `no-console`: error (use proper logging or remove)\n- `@typescript-eslint/no-explicit-any`: warn (always use proper types instead of `any`)\n- Unused variables must be prefixed with `_`\n- Comma dangles required for multiline objects/arrays\n\n### File Organization\n\n- **Pages**: `web/src/pages/` - Route components\n- **Views**: `web/src/views/` - Complex view components\n- **Components**: `web/src/components/` - Reusable components\n- **Hooks**: `web/src/hooks/` - Custom React hooks\n- **API**: `web/src/api/` - API client functions\n- **Types**: `web/src/types/` - TypeScript type definitions\n\n## Testing Requirements\n\n### Backend Testing\n\n- **Framework**: Python unittest\n- **Run Command**: `python3 -u -m unittest`\n- **Location**: `frigate/test/`\n- **Coverage**: Aim for comprehensive test coverage of core functionality\n- **Pattern**: Use `TestCase` classes with descriptive test method names\n  ```python\n  class TestMotionDetection(unittest.TestCase):\n      def test_detects_motion_above_threshold(self):\n          # Test implementation\n  ```\n\n### Test Best Practices\n\n- Always have a way to test your work and confirm your changes\n- Write tests for bug fixes to prevent regressions\n- Test edge cases and error conditions\n- Mock external dependencies (cameras, APIs, hardware)\n- Use fixtures for test data\n\n## Development Commands\n\n### Python Backend\n\n```bash\n# Run all tests\npython3 -u -m unittest\n\n# Run specific test file\npython3 -u -m unittest frigate.test.test_ffmpeg_presets\n\n# Check formatting (Ruff)\nruff format --check frigate/\n\n# Apply formatting\nruff format frigate/\n\n# Run linter\nruff check frigate/\n```\n\n### Frontend (from web/ directory)\n\n```bash\n# Start dev server (AI agents should never run this directly unless asked)\nnpm run dev\n\n# Build for production\nnpm run build\n\n# Run linter\nnpm run lint\n\n# Fix linting issues\nnpm run lint:fix\n\n# Format code\nnpm run prettier:write\n```\n\n### Docker Development\n\nAI agents should never run these commands directly unless instructed.\n\n```bash\n# Build local image\nmake local\n\n# Build debug image\nmake debug\n```\n\n## Common Patterns\n\n### API Endpoint Pattern\n\n```python\nfrom fastapi import APIRouter, Request\nfrom frigate.api.defs.tags import Tags\n\nrouter = APIRouter(tags=[Tags.Events])\n\n@router.get(\"/events\")\nasync def get_events(request: Request, limit: int = 100):\n    \"\"\"Retrieve events from the database.\"\"\"\n    # Implementation\n```\n\n### Configuration Access\n\n```python\n# Access Frigate configuration\nconfig: FrigateConfig = request.app.frigate_config\ncamera_config = config.cameras[\"front_door\"]\n```\n\n### Database Queries\n\n```python\nfrom frigate.models import Event\n\n# Use Peewee ORM for database access\nevents = (\n    Event.select()\n    .where(Event.camera == camera_name)\n    .order_by(Event.start_time.desc())\n    .limit(limit)\n)\n```\n\n## Common Anti-Patterns to Avoid\n\n### ❌ Avoid These\n\n```python\n# Blocking operations in async functions\ndata = requests.get(url)  # ❌ Use async HTTP client\ntime.sleep(5)  # ❌ Use asyncio.sleep()\n\n# Hardcoded strings in React components\n<div>Camera not found</div>  # ❌ Use t(\"camera_not_found\")\n\n# Missing error handling\ndata = await api.get_data()  # ❌ No exception handling\n\n# Bare exceptions in regular code\ntry:\n    value = await sensor.read()\nexcept Exception:  # ❌ Too broad\n    logger.error(\"Failed\")\n```\n\n### ✅ Use These Instead\n\n```python\n# Async operations\nimport aiohttp\nasync with aiohttp.ClientSession() as session:\n    async with session.get(url) as response:\n        data = await response.json()\n\nawait asyncio.sleep(5)  # ✅ Non-blocking\n\n# Translatable strings in React\nconst { t } = useTranslation();\n<div>{t(\"camera_not_found\")}</div>  # ✅ Translatable\n\n# Proper error handling\ntry:\n    data = await api.get_data()\nexcept ApiException as err:\n    logger.error(\"API error: %s\", err)\n    raise\n\n# Specific exceptions\ntry:\n    value = await sensor.read()\nexcept SensorException as err:  # ✅ Specific\n    logger.exception(\"Failed to read sensor\")\n```\n\n## Project-Specific Conventions\n\n### Configuration Files\n\n- Main config: `config/config.yml`\n\n### Directory Structure\n\n- Backend code: `frigate/`\n- Frontend code: `web/`\n- Docker files: `docker/`\n- Documentation: `docs/`\n- Database migrations: `migrations/`\n\n### Code Style Conformance\n\nAlways conform new and refactored code to the existing coding style in the project:\n\n- Follow established patterns in similar files\n- Match indentation and formatting of surrounding code\n- Use consistent naming conventions (snake_case for Python, camelCase for TypeScript)\n- Maintain the same level of verbosity in comments and docstrings\n\n## Additional Resources\n\n- Documentation: https://docs.frigate.video\n- Main Repository: https://github.com/blakeblackshear/frigate\n- Home Assistant Integration: https://github.com/blakeblackshear/frigate-hass-integration\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# Agent Instructions for Frigate NVR\n\nThis document provides coding guidelines and best practices for contributing to Frigate NVR, a complete and local NVR designed for Home Assistant with AI object detection.\n\n## Project Overview\n\nFrigate NVR is a realtime object detection system for IP cameras that uses:\n\n- **Backend**: Python 3.13+ with FastAPI, OpenCV, TensorFlow/ONNX\n- **Frontend**: React with TypeScript, Vite, TailwindCSS\n- **Architecture**: Multiprocessing design with ZMQ and MQTT communication\n- **Focus**: Minimal resource usage with maximum performance\n\n## Code Review Guidelines\n\nWhen reviewing code, do NOT comment on:\n\n- Missing imports - Static analysis tooling catches these\n- Code formatting - Ruff (Python) and Prettier (TypeScript/React) handle formatting\n- Minor style inconsistencies already enforced by linters\n\n## Python Backend Standards\n\n### Python Requirements\n\n- **Compatibility**: Python 3.13+\n- **Language Features**: Use modern Python features:\n  - Pattern matching\n  - Type hints (comprehensive typing preferred)\n  - f-strings (preferred over `%` or `.format()`)\n  - Dataclasses\n  - Async/await patterns\n\n### Code Quality Standards\n\n- **Formatting**: Ruff (configured in `pyproject.toml`)\n- **Linting**: Ruff with rules defined in project config\n- **Type Checking**: Use type hints consistently\n- **Testing**: unittest framework - use `python3 -u -m unittest` to run tests\n- **Language**: American English for all code, comments, and documentation\n- **Punctuation**: Do not use em dashes in documentation, comments, or strings; reword with standard punctuation (commas, colons, parentheses, or separate sentences)\n\n### Logging Standards\n\n- **Logger Pattern**: Use module-level logger\n\n  ```python\n  import logging\n\n  logger = logging.getLogger(__name__)\n  ```\n\n- **Format Guidelines**:\n  - No periods at end of log messages\n  - No sensitive data (keys, tokens, passwords)\n  - Use lazy logging: `logger.debug(\"Message with %s\", variable)`\n- **Log Levels**:\n  - `debug`: Development and troubleshooting information\n  - `info`: Important runtime events (startup, shutdown, state changes)\n  - `warning`: Recoverable issues that should be addressed\n  - `error`: Errors that affect functionality but don't crash the app\n  - `exception`: Use in except blocks to include traceback\n\n### Error Handling\n\n- **Exception Types**: Choose most specific exception available\n- **Try/Catch Best Practices**:\n  - Only wrap code that can throw exceptions\n  - Keep try blocks minimal - process data after the try/except\n  - Avoid bare exceptions except in background tasks\n\n  Bad pattern:\n\n  ```python\n  try:\n      data = await device.get_data()  # Can throw\n      # ❌ Don't process data inside try block\n      processed = data.get(\"value\", 0) * 100\n      result = processed\n  except DeviceError:\n      logger.error(\"Failed to get data\")\n  ```\n\n  Good pattern:\n\n  ```python\n  try:\n      data = await device.get_data()  # Can throw\n  except DeviceError:\n      logger.error(\"Failed to get data\")\n      return\n\n  # ✅ Process data outside try block\n  processed = data.get(\"value\", 0) * 100\n  result = processed\n  ```\n\n### Async Programming\n\n- **External I/O**: All external I/O operations must be async\n- **Best Practices**:\n  - Avoid sleeping in loops - use `asyncio.sleep()` not `time.sleep()`\n  - Avoid awaiting in loops - use `asyncio.gather()` instead\n  - No blocking calls in async functions\n  - Use `asyncio.create_task()` for background operations\n- **Thread Safety**: Use proper synchronization for shared state\n\n### Documentation Standards\n\n- **Module Docstrings**: Concise descriptions at top of files\n  ```python\n  \"\"\"Utilities for motion detection and analysis.\"\"\"\n  ```\n- **Function Docstrings**: Required for public functions and methods\n\n  ```python\n  async def process_frame(frame: ndarray, config: Config) -> Detection:\n      \"\"\"Process a video frame for object detection.\n\n      Args:\n          frame: The video frame as numpy array\n          config: Detection configuration\n\n      Returns:\n          Detection results with bounding boxes\n      \"\"\"\n  ```\n\n- **Comment Style**:\n  - Explain the \"why\" not just the \"what\"\n  - Keep lines under 88 characters when possible\n  - Use clear, descriptive comments\n\n### File Organization\n\n- **API Endpoints**: `frigate/api/` - FastAPI route handlers\n- **Configuration**: `frigate/config/` - Configuration parsing and validation\n- **Detectors**: `frigate/detectors/` - Object detection backends\n- **Events**: `frigate/events/` - Event management and storage\n- **Utilities**: `frigate/util/` - Shared utility functions\n\n## Frontend (React/TypeScript) Standards\n\n### Internationalization (i18n)\n\n- **CRITICAL**: Never write user-facing strings directly in components\n- **Always use react-i18next**: Import and use the `t()` function\n\n  ```tsx\n  import { useTranslation } from \"react-i18next\";\n\n  function MyComponent() {\n    const { t } = useTranslation([\"views/live\"]);\n    return <div>{t(\"camera_not_found\")}</div>;\n  }\n  ```\n\n- **Translation Files**: Add English strings to the appropriate json files in `web/public/locales/en`\n- **Namespaces**: Organize translations by feature/view (e.g., `views/live`, `common`, `views/system`)\n\n### Code Quality\n\n- **Linting**: ESLint (see `web/.eslintrc.cjs`)\n- **Formatting**: Prettier with Tailwind CSS plugin\n- **Type Safety**: TypeScript strict mode enabled\n\n### Component Patterns\n\n- **UI Components**: Use Radix UI primitives (in `web/src/components/ui/`)\n- **Styling**: TailwindCSS with `cn()` utility for class merging\n- **State Management**: React hooks (useState, useEffect, useCallback, useMemo)\n- **Data Fetching**: Custom hooks with proper loading and error states\n\n### ESLint Rules\n\nKey rules enforced:\n\n- `react-hooks/rules-of-hooks`: error\n- `react-hooks/exhaustive-deps`: error\n- `no-console`: error (use proper logging or remove)\n- `@typescript-eslint/no-explicit-any`: warn (always use proper types instead of `any`)\n- Unused variables must be prefixed with `_`\n- Comma dangles required for multiline objects/arrays\n\n### File Organization\n\n- **Pages**: `web/src/pages/` - Route components\n- **Views**: `web/src/views/` - Complex view components\n- **Components**: `web/src/components/` - Reusable components\n- **Hooks**: `web/src/hooks/` - Custom React hooks\n- **API**: `web/src/api/` - API client functions\n- **Types**: `web/src/types/` - TypeScript type definitions\n\n## Testing Requirements\n\n### Backend Testing\n\n- **Framework**: Python unittest\n- **Run Command**: `python3 -u -m unittest`\n- **Location**: `frigate/test/`\n- **Coverage**: Aim for comprehensive test coverage of core functionality\n- **Pattern**: Use `TestCase` classes with descriptive test method names\n  ```python\n  class TestMotionDetection(unittest.TestCase):\n      def test_detects_motion_above_threshold(self):\n          # Test implementation\n  ```\n\n### Test Best Practices\n\n- Always have a way to test your work and confirm your changes\n- Write tests for bug fixes to prevent regressions\n- Test edge cases and error conditions\n- Mock external dependencies (cameras, APIs, hardware)\n- Use fixtures for test data\n\n## Development Commands\n\n### Python Backend\n\n```bash\n# Run all tests\npython3 -u -m unittest\n\n# Run specific test file\npython3 -u -m unittest frigate.test.test_ffmpeg_presets\n\n# Check formatting (Ruff)\nruff format --check frigate/\n\n# Apply formatting\nruff format frigate/\n\n# Run linter\nruff check frigate/\n\n# Type check\npython3 -u -m mypy --config-file frigate/mypy.ini frigate\n\n# Regenerate the OpenAPI spec after adding, changing, or removing an API\n# endpoint or its auth dependency — outputs docs/static/frigate-api.yaml,\n# annotated with each endpoint's auth requirement (admin / any / camera /\n# public). NEVER edit that file by hand. CI runs the --check variant and fails\n# if it is out of date. (from repo root)\npython3 generate_api_auth_spec.py\npython3 generate_api_auth_spec.py --check\n```\n\n### Frontend (from web/ directory)\n\n```bash\n# Start dev server (AI agents should never run this directly unless asked)\nnpm run dev\n\n# Build for production\nnpm run build\n\n# Run linter\nnpm run lint\n\n# Fix linting issues\nnpm run lint:fix\n\n# Format code\nnpm run prettier:write\n\n# E2E: first-time setup\nnpm install\nnpx playwright install chromium\n\n# E2E: build the app and run all tests\nnpm run e2e:build && npm run e2e\n\n# E2E: interactive UI for debugging\nnpm run e2e:ui\n\n# E2E: run a specific spec\nnpx playwright test --config e2e/playwright.config.ts e2e/specs/live.spec.ts\n\n# E2E: filter by name, or run only desktop/mobile\nnpx playwright test --config e2e/playwright.config.ts --grep=\"severity tab\"\nnpx playwright test --config e2e/playwright.config.ts --project=desktop\n\n# E2E: regenerate mock data after backend model changes (from repo root)\nPYTHONPATH=. python3 web/e2e/fixtures/mock-data/generate-mock-data.py\n\n# Regenerate config translations from Pydantic models — outputs to\n# web/public/locales/en/config/{global,cameras}.json. NEVER edit those\n# JSON files by hand; change the Pydantic field title/description and\n# re-run this script. (from repo root)\npython3 generate_config_translations.py\n\n# Extract i18n keys from source into the locale files after adding\n# new t() calls. Use the :ci variant to verify the locale files are\n# in sync with source (fails if extraction would change anything).\nnpm run i18n:extract\nnpm run i18n:extract:ci\n```\n\n### Docker Development\n\nAI agents should never run these commands directly unless instructed.\n\n```bash\n# Build local image\nmake local\n\n# Build debug image\nmake debug\n```\n\n## Common Patterns\n\n### API Endpoint Pattern\n\n```python\nfrom fastapi import APIRouter, Request\nfrom frigate.api.defs.tags import Tags\n\nrouter = APIRouter(tags=[Tags.Events])\n\n@router.get(\"/events\")\nasync def get_events(request: Request, limit: int = 100):\n    \"\"\"Retrieve events from the database.\"\"\"\n    # Implementation\n```\n\nAfter adding, changing, or removing an endpoint (or its auth dependency), regenerate the OpenAPI spec with `python3 generate_api_auth_spec.py` so `docs/static/frigate-api.yaml` stays in sync and the endpoint's auth requirement is documented. CI enforces this via the `--check` variant; never edit that file by hand.\n\n### Configuration Access\n\n```python\n# Access Frigate configuration\nconfig: FrigateConfig = request.app.frigate_config\ncamera_config = config.cameras[\"front_door\"]\n```\n\n### Database Queries\n\n```python\nfrom frigate.models import Event\n\n# Use Peewee ORM for database access\nevents = (\n    Event.select()\n    .where(Event.camera == camera_name)\n    .order_by(Event.start_time.desc())\n    .limit(limit)\n)\n```\n\n## Common Anti-Patterns to Avoid\n\n### ❌ Avoid These\n\n```python\n# Blocking operations in async functions\ndata = requests.get(url)  # ❌ Use async HTTP client\ntime.sleep(5)  # ❌ Use asyncio.sleep()\n\n# Hardcoded strings in React components\n<div>Camera not found</div>  # ❌ Use t(\"camera_not_found\")\n\n# Missing error handling\ndata = await api.get_data()  # ❌ No exception handling\n\n# Bare exceptions in regular code\ntry:\n    value = await sensor.read()\nexcept Exception:  # ❌ Too broad\n    logger.error(\"Failed\")\n\n# Returning exceptions in JSON responses\nexcept ValueError as e:\n    return JSONResponse(\n        content={\"success\": False, \"message\": str(e)},\n    )\n```\n\n### ✅ Use These Instead\n\n```python\n# Async operations\nimport aiohttp\nasync with aiohttp.ClientSession() as session:\n    async with session.get(url) as response:\n        data = await response.json()\n\nawait asyncio.sleep(5)  # ✅ Non-blocking\n\n# Translatable strings in React\nconst { t } = useTranslation();\n<div>{t(\"camera_not_found\")}</div>  # ✅ Translatable\n\n# Proper error handling\ntry:\n    data = await api.get_data()\nexcept ApiException as err:\n    logger.error(\"API error: %s\", err)\n    raise\n\n# Specific exceptions\ntry:\n    value = await sensor.read()\nexcept SensorException as err:  # ✅ Specific\n    logger.exception(\"Failed to read sensor\")\n\n# Safe error responses\nexcept ValueError:\n    logger.exception(\"Invalid parameters for API request\")\n    return JSONResponse(\n        content={\n            \"success\": False,\n            \"message\": \"Invalid request parameters\",\n        },\n    )\n```\n\n## WebSocket Broadcasts\n\nOutbound WebSocket broadcasts go through a per-recipient classifier in `frigate/comms/ws.py` that enforces camera-level access. **The classifier is fail-closed: any topic it doesn't recognize is dropped for every client.** New outbound topics must be classified there or they'll silently disappear.\n\n## Project-Specific Conventions\n\n### Configuration Files\n\n- Main config: `config/config.yml`\n\n### Directory Structure\n\n- Backend code: `frigate/`\n- Frontend code: `web/`\n- Docker files: `docker/`\n- Documentation: `docs/`\n- Database migrations: `migrations/`\n\n### Code Style Conformance\n\nAlways conform new and refactored code to the existing coding style in the project:\n\n- Follow established patterns in similar files\n- Match indentation and formatting of surrounding code\n- Use consistent naming conventions (snake_case for Python, camelCase for TypeScript)\n- Maintain the same level of verbosity in comments and docstrings\n\n## Additional Resources\n\n- Documentation: https://docs.frigate.video\n- Main Repository: https://github.com/blakeblackshear/frigate\n- Home Assistant Integration: https://github.com/blakeblackshear/frigate-hass-integration\n","category":"root","tokens":3331},{"name":"copilot-instructions.md","path":".github/copilot-instructions.md","title":"copilot-instructions.md","content":"# GitHub Copilot Instructions for Frigate NVR\n\nThis document provides coding guidelines and best practices for contributing to Frigate NVR, a complete and local NVR designed for Home Assistant with AI object detection.\n\n## Project Overview\n\nFrigate NVR is a realtime object detection system for IP cameras that uses:\n\n- **Backend**: Python 3.13+ with FastAPI, OpenCV, TensorFlow/ONNX\n- **Frontend**: React with TypeScript, Vite, TailwindCSS\n- **Architecture**: Multiprocessing design with ZMQ and MQTT communication\n- **Focus**: Minimal resource usage with maximum performance\n\n## Code Review Guidelines\n\nWhen reviewing code, do NOT comment on:\n\n- Missing imports - Static analysis tooling catches these\n- Code formatting - Ruff (Python) and Prettier (TypeScript/React) handle formatting\n- Minor style inconsistencies already enforced by linters\n\n## Python Backend Standards\n\n### Python Requirements\n\n- **Compatibility**: Python 3.13+\n- **Language Features**: Use modern Python features:\n  - Pattern matching\n  - Type hints (comprehensive typing preferred)\n  - f-strings (preferred over `%` or `.format()`)\n  - Dataclasses\n  - Async/await patterns\n\n### Code Quality Standards\n\n- **Formatting**: Ruff (configured in `pyproject.toml`)\n- **Linting**: Ruff with rules defined in project config\n- **Type Checking**: Use type hints consistently\n- **Testing**: unittest framework - use `python3 -u -m unittest` to run tests\n- **Language**: American English for all code, comments, and documentation\n\n### Logging Standards\n\n- **Logger Pattern**: Use module-level logger\n\n  ```python\n  import logging\n\n  logger = logging.getLogger(__name__)\n  ```\n\n- **Format Guidelines**:\n  - No periods at end of log messages\n  - No sensitive data (keys, tokens, passwords)\n  - Use lazy logging: `logger.debug(\"Message with %s\", variable)`\n- **Log Levels**:\n  - `debug`: Development and troubleshooting information\n  - `info`: Important runtime events (startup, shutdown, state changes)\n  - `warning`: Recoverable issues that should be addressed\n  - `error`: Errors that affect functionality but don't crash the app\n  - `exception`: Use in except blocks to include traceback\n\n### Error Handling\n\n- **Exception Types**: Choose most specific exception available\n- **Try/Catch Best Practices**:\n  - Only wrap code that can throw exceptions\n  - Keep try blocks minimal - process data after the try/except\n  - Avoid bare exceptions except in background tasks\n\n  Bad pattern:\n\n  ```python\n  try:\n      data = await device.get_data()  # Can throw\n      # ❌ Don't process data inside try block\n      processed = data.get(\"value\", 0) * 100\n      result = processed\n  except DeviceError:\n      logger.error(\"Failed to get data\")\n  ```\n\n  Good pattern:\n\n  ```python\n  try:\n      data = await device.get_data()  # Can throw\n  except DeviceError:\n      logger.error(\"Failed to get data\")\n      return\n\n  # ✅ Process data outside try block\n  processed = data.get(\"value\", 0) * 100\n  result = processed\n  ```\n\n### Async Programming\n\n- **External I/O**: All external I/O operations must be async\n- **Best Practices**:\n  - Avoid sleeping in loops - use `asyncio.sleep()` not `time.sleep()`\n  - Avoid awaiting in loops - use `asyncio.gather()` instead\n  - No blocking calls in async functions\n  - Use `asyncio.create_task()` for background operations\n- **Thread Safety**: Use proper synchronization for shared state\n\n### Documentation Standards\n\n- **Module Docstrings**: Concise descriptions at top of files\n  ```python\n  \"\"\"Utilities for motion detection and analysis.\"\"\"\n  ```\n- **Function Docstrings**: Required for public functions and methods\n\n  ```python\n  async def process_frame(frame: ndarray, config: Config) -> Detection:\n      \"\"\"Process a video frame for object detection.\n\n      Args:\n          frame: The video frame as numpy array\n          config: Detection configuration\n\n      Returns:\n          Detection results with bounding boxes\n      \"\"\"\n  ```\n\n- **Comment Style**:\n  - Explain the \"why\" not just the \"what\"\n  - Keep lines under 88 characters when possible\n  - Use clear, descriptive comments\n\n### File Organization\n\n- **API Endpoints**: `frigate/api/` - FastAPI route handlers\n- **Configuration**: `frigate/config/` - Configuration parsing and validation\n- **Detectors**: `frigate/detectors/` - Object detection backends\n- **Events**: `frigate/events/` - Event management and storage\n- **Utilities**: `frigate/util/` - Shared utility functions\n\n## Frontend (React/TypeScript) Standards\n\n### Internationalization (i18n)\n\n- **CRITICAL**: Never write user-facing strings directly in components\n- **Always use react-i18next**: Import and use the `t()` function\n\n  ```tsx\n  import { useTranslation } from \"react-i18next\";\n\n  function MyComponent() {\n    const { t } = useTranslation([\"views/live\"]);\n    return <div>{t(\"camera_not_found\")}</div>;\n  }\n  ```\n\n- **Translation Files**: Add English strings to the appropriate json files in `web/public/locales/en`\n- **Namespaces**: Organize translations by feature/view (e.g., `views/live`, `common`, `views/system`)\n\n### Code Quality\n\n- **Linting**: ESLint (see `web/.eslintrc.cjs`)\n- **Formatting**: Prettier with Tailwind CSS plugin\n- **Type Safety**: TypeScript strict mode enabled\n- **Testing**: Vitest for unit tests\n\n### Component Patterns\n\n- **UI Components**: Use Radix UI primitives (in `web/src/components/ui/`)\n- **Styling**: TailwindCSS with `cn()` utility for class merging\n- **State Management**: React hooks (useState, useEffect, useCallback, useMemo)\n- **Data Fetching**: Custom hooks with proper loading and error states\n\n### ESLint Rules\n\nKey rules enforced:\n\n- `react-hooks/rules-of-hooks`: error\n- `react-hooks/exhaustive-deps`: error\n- `no-console`: error (use proper logging or remove)\n- `@typescript-eslint/no-explicit-any`: warn (always use proper types instead of `any`)\n- Unused variables must be prefixed with `_`\n- Comma dangles required for multiline objects/arrays\n\n### File Organization\n\n- **Pages**: `web/src/pages/` - Route components\n- **Views**: `web/src/views/` - Complex view components\n- **Components**: `web/src/components/` - Reusable components\n- **Hooks**: `web/src/hooks/` - Custom React hooks\n- **API**: `web/src/api/` - API client functions\n- **Types**: `web/src/types/` - TypeScript type definitions\n\n## Testing Requirements\n\n### Backend Testing\n\n- **Framework**: Python unittest\n- **Run Command**: `python3 -u -m unittest`\n- **Location**: `frigate/test/`\n- **Coverage**: Aim for comprehensive test coverage of core functionality\n- **Pattern**: Use `TestCase` classes with descriptive test method names\n  ```python\n  class TestMotionDetection(unittest.TestCase):\n      def test_detects_motion_above_threshold(self):\n          # Test implementation\n  ```\n\n### Test Best Practices\n\n- Always have a way to test your work and confirm your changes\n- Write tests for bug fixes to prevent regressions\n- Test edge cases and error conditions\n- Mock external dependencies (cameras, APIs, hardware)\n- Use fixtures for test data\n\n## Development Commands\n\n### Python Backend\n\n```bash\n# Run all tests\npython3 -u -m unittest\n\n# Run specific test file\npython3 -u -m unittest frigate.test.test_ffmpeg_presets\n\n# Check formatting (Ruff)\nruff format --check frigate/\n\n# Apply formatting\nruff format frigate/\n\n# Run linter\nruff check frigate/\n```\n\n### Frontend (from web/ directory)\n\n```bash\n# Start dev server (AI agents should never run this directly unless asked)\nnpm run dev\n\n# Build for production\nnpm run build\n\n# Run linter\nnpm run lint\n\n# Fix linting issues\nnpm run lint:fix\n\n# Format code\nnpm run prettier:write\n```\n\n### Docker Development\n\nAI agents should never run these commands directly unless instructed.\n\n```bash\n# Build local image\nmake local\n\n# Build debug image\nmake debug\n```\n\n## Common Patterns\n\n### API Endpoint Pattern\n\n```python\nfrom fastapi import APIRouter, Request\nfrom frigate.api.defs.tags import Tags\n\nrouter = APIRouter(tags=[Tags.Events])\n\n@router.get(\"/events\")\nasync def get_events(request: Request, limit: int = 100):\n    \"\"\"Retrieve events from the database.\"\"\"\n    # Implementation\n```\n\n### Configuration Access\n\n```python\n# Access Frigate configuration\nconfig: FrigateConfig = request.app.frigate_config\ncamera_config = config.cameras[\"front_door\"]\n```\n\n### Database Queries\n\n```python\nfrom frigate.models import Event\n\n# Use Peewee ORM for database access\nevents = (\n    Event.select()\n    .where(Event.camera == camera_name)\n    .order_by(Event.start_time.desc())\n    .limit(limit)\n)\n```\n\n## Common Anti-Patterns to Avoid\n\n### ❌ Avoid These\n\n```python\n# Blocking operations in async functions\ndata = requests.get(url)  # ❌ Use async HTTP client\ntime.sleep(5)  # ❌ Use asyncio.sleep()\n\n# Hardcoded strings in React components\n<div>Camera not found</div>  # ❌ Use t(\"camera_not_found\")\n\n# Missing error handling\ndata = await api.get_data()  # ❌ No exception handling\n\n# Bare exceptions in regular code\ntry:\n    value = await sensor.read()\nexcept Exception:  # ❌ Too broad\n    logger.error(\"Failed\")\n```\n\n### ✅ Use These Instead\n\n```python\n# Async operations\nimport aiohttp\nasync with aiohttp.ClientSession() as session:\n    async with session.get(url) as response:\n        data = await response.json()\n\nawait asyncio.sleep(5)  # ✅ Non-blocking\n\n# Translatable strings in React\nconst { t } = useTranslation();\n<div>{t(\"camera_not_found\")}</div>  # ✅ Translatable\n\n# Proper error handling\ntry:\n    data = await api.get_data()\nexcept ApiException as err:\n    logger.error(\"API error: %s\", err)\n    raise\n\n# Specific exceptions\ntry:\n    value = await sensor.read()\nexcept SensorException as err:  # ✅ Specific\n    logger.exception(\"Failed to read sensor\")\n```\n\n## Project-Specific Conventions\n\n### Configuration Files\n\n- Main config: `config/config.yml`\n\n### Directory Structure\n\n- Backend code: `frigate/`\n- Frontend code: `web/`\n- Docker files: `docker/`\n- Documentation: `docs/`\n- Database migrations: `migrations/`\n\n### Code Style Conformance\n\nAlways conform new and refactored code to the existing coding style in the project:\n\n- Follow established patterns in similar files\n- Match indentation and formatting of surrounding code\n- Use consistent naming conventions (snake_case for Python, camelCase for TypeScript)\n- Maintain the same level of verbosity in comments and docstrings\n\n## Additional Resources\n\n- Documentation: https://docs.frigate.video\n- Main Repository: https://github.com/blakeblackshear/frigate\n- Home Assistant Integration: https://github.com/blakeblackshear/frigate-hass-integration\n","category":".github","tokens":2624}]}