Files
metube/AGENTS.md
2026-04-10 08:38:32 +03:00

2.3 KiB

Agent Guidelines

README.md size constraint

The README.md is synced to Docker Hub, which has a 25,000 character limit. Any change to README.md must keep the file under 25,000 characters (wc -c README.md). If an addition would exceed the limit, trim existing prose elsewhere — prefer tightening verbose descriptions over removing sections.

Tech stack

  • Backend: Python 3.13+, aiohttp, python-socketio 5.x, yt-dlp
  • Frontend: Angular 21, TypeScript, Bootstrap 5, SASS, ngx-socket-io
  • Package managers: uv (Python), pnpm (frontend)
  • Container: Multi-stage Docker (Node builder + Python runtime), multi-arch (amd64/arm64)

Build & test commands

# Frontend (run from ui/)
pnpm install --frozen-lockfile
pnpm run lint
pnpm run build
pnpm exec ng test --watch=false

# Backend (run from repo root)
uv sync --frozen --group dev
python -m compileall app
uv run pytest app/tests/

All of these run in CI (.github/workflows/main.yml) on every push to master and must pass.

Code style

Follow .editorconfig:

  • Python: 4-space indent
  • Everything else (TypeScript, YAML, JSON, HTML): 2-space indent
  • UTF-8, LF line endings, trim trailing whitespace, final newline

Frontend additionally uses ESLint (ui/eslint.config.js) and Prettier (config in ui/package.json: printWidth=100, singleQuote=true).

Project structure

app/main.py          — HTTP server, Socket.IO events, REST API routes, Config class
app/ytdl.py          — Download queue logic, yt-dlp integration
app/subscriptions.py — Channel/playlist subscription manager
app/state_store.py   — JSON-based persistent storage with atomic writes
app/dl_formats.py    — Video/audio codec/quality mapping
app/tests/           — pytest tests (asyncio_mode=auto)
ui/src/app/          — Angular standalone components (no NgModules)

Key conventions

  • Backend configuration lives in the Config class in app/main.py with env-var defaults in _DEFAULTS. New env vars go there.
  • Real-time communication uses Socket.IO events, not REST polling.
  • Frontend uses standalone Angular components with inject() for DI, RxJS Subjects for state, and takeUntilDestroyed() for cleanup.
  • State is persisted as JSON files via AtomicJsonStore in app/state_store.py.
  • No pre-commit hooks — linting and tests are enforced in CI only.