Imported from JohnDeSilva/lan-streamer (
.agents/AGENTS.md). Install upstream withnpx skills add JohnDeSilva/lan-streamer --skill .agents. Copyright stays with the author.
🤖 Developer Guidelines & AI Agent Rules
This document establishes the repository-wide standards, architectural constraints, layout structure, and development workflows for AI agents.
🛠️ Tech Stack & Constraints
- UI Framework: PySide6 (
QtWidgetsstrictly; QML is prohibited). - Database Engine: SQLite with SQLAlchemy ORM. Use strictly SQLAlchemy 2.0 style queries (
select(),update(), etc.). Legacysession.query()is prohibited. - Migrations Engine: Alembic.
- Generate revisions via
make revision name="description". - Apply revisions via
make migrate. - Revision versions must exactly match the application version (
__version__in init.py). Do not create future-version migrations or bump versions solely for migrations. - Implement and write test cases verifying that database migrations handle existing data correctly without data loss.
- Generate revisions via
- APIs & Networking:
requestslibrary for Jellyfin and TMDB integrations. - Build & Executables:
uvpackage manager (uv run,uv add,uv lock). All quality controls, testing, and building targets are wrapped via the Makefile. - Video Playback Engine:
python-vlc(requires a system-wide VLC player installation).
📂 Repository Layout
- src/entrypoint.py: Startup file for compiled PyInstaller target.
- src/lan_streamer/:
- main.py: Sets up the application GUI and controller runtime.
- db/: ORM schemas (models.py), queries (queries_playback.py, queries_ui.py), serialization, and database setup.
- backend/: Background thread workers (
QThread/QWorker) for non-blocking file scanning, Jellyfin sync, and metadata updates. - scanner/: Library crawler, filename parser, and bulk-renamer.
- services/: Business-logic services (discovery, TMDB/Jellyfin metadata merging).
- playback/: Video player widget wrapper around
libvlcand OS wake-lock controller. - providers/: External client wrappers (TMDB, Jellyfin, OpenSubtitles, MyAnimeList).
- system/: Config manager, logging handler, backups, and updater.
- ui_views/: Desktop PySide6 QtWidgets view screens, stylesheet themes, and controllers.
- tests/: Structured unit, integration, and end-to-end tests (minimum 90% code coverage target).
- agent/: Remote Scan Agent package (FastAPI, SQLite, web UI, background scanning orchestration, Docker packaging).
- src/scan_agent/: Agent backend and API services.
- api/: FastAPI REST routes (health, libraries, scan, browse, metadata, rename, subtitles, watch) and SSE event stream.
- config.py: Agent configuration and desktop singleton bridge.
- db/: Standalone agent models, connection, and repository.
- scan/: Scanning orchestrator and progress broker.
- static/: Single-page web dashboard and management interface.
- tests/: Unit and integration tests for scan agent.
- Dockerfile, docker-compose.yml: Container deployment configuration.
- src/scan_agent/: Agent backend and API services.
📐 Code Standards & Style
1. Variable Naming (Strict No-Abbreviation Rule)
Do not abbreviate variable names. Use full, descriptive names:
- ❌
ep,ep_name,ep_num➔ ✅episode,episode_name,episode_number - ❌
jf_id,jf_client➔ ✅jellyfin_id,jellyfin_client - ❌
db,conn➔ ✅database,connection - ❌
tmdb_id➔ ✅tmdb_identifier
2. UI Thread Safety (Responsiveness)
- The main Qt UI thread must never freeze.
- Run all blocking IO, filesystem crawling, DB writes, and network requests in background workers (
QThread/QWorker) undersrc/lan_streamer/backend/.
3. Detailed Logging
- Use standard Python
logging. - Log all database writes, schema updates, config state changes, and filesystem mutations (renaming/deletion).
- Log key user interactions (scan initiation, view transitions, metadata mappings).
- Log background thread lifecycles (startup, progress, errors, termination).
4. Code Organization
- Keep modules small, single-purpose, and grouped under descriptive directories.
- Avoid generic filenames like
helper.pyorutils.pyin favor of specific functional terms. - Static Typing: Enforce 100% strict
mypytype checking for all production code insrc/lan_streamer/.
5. Testing URL Constraints (Strict Mock URL Rule)
- Do not use actual, live external URLs in unit, integration, or e2e tests.
- Always use mock/local domains (e.g.
example.invalid,localhost,127.0.0.1, orjellyfin.local) to avoid external network dependencies and prevent accidental network request execution during test runs.
🔄 Mandatory Developer Workflow
Every single change or task implemented on this codebase MUST strictly adhere to the following workflow in order:
Step 1: Test-First Iteration
- Define Goal: Fully understand requirements and impacts on existing features.
- Create/Update Tests: Write automated tests that cover the new feature/bugfix first (expecting them to fail initially).
- Implement: Modify application code in
src/to satisfy the tests. - Refine: Maintain a minimum code coverage threshold of 90%.
Step 2: Verification Sequence
After every change, run:
make test(ormake test-localon non-Linux) to verify tests pass and check coverage. Run the agent suites withmake test-agent(ormake test-agent-back/make test-agent-frontto target one half). On Linux all suites run inside containers (docker/Dockerfile.fedora/ubuntufor desktop,docker/Dockerfile.agent-testfor agent); CI runs each suite in a dedicated containerized job.make lintas the FINAL step to check style, Ruff format/rules, MyPy typechecking, and pre-commit conformity. Resolving all warnings and errors is mandatory.
Step 3: Documentation Synchronicity
- Instantly update
README.md,docs/codebase_guide.md, and other guides when changing features, database schemas, UI elements, or configuration options.
Step 4: Commits
- Commit incrementally with small, focused diffs using the Conventional Commits specification (e.g.
feat(ui): ...,fix(db): ...,docs: ...,test: ...).