# AGENTS.md

Guidance for coding agents working in `NibasaViewer`.
This document is intentionally explicit so tasks can be completed with minimal repo discovery.

## 1) Project Snapshot

- Stack: Python 3 + Django 4.2.
- App layout: single app, `viewer`.
- Data model: filesystem-first gallery; images/folders are not stored in Django models.
- Frontend constraint: minimize JavaScript dependencies; Bootstrap bundled JS is allowed when required, and custom JavaScript should be avoided unless explicitly requested.
- Auth: Django built-in auth; gallery views are login-protected.
- Image flow: originals from `GALLERY_ROOT`, thumbnails cached in `THUMBNAILS_ROOT`.

## 2) Source of Truth and Rule Files

- Primary in-repo agent guidance exists in `CLAUDE.md`.
- `AGENTS.md` (this file) complements `CLAUDE.md` for day-to-day agent execution.
- Cursor rules search result: no `.cursorrules` and no files in `.cursor/rules/`.
- Copilot rules search result: no `.github/copilot-instructions.md` present.
- If Cursor/Copilot rule files are added later, treat them as additional required constraints.

## 3) Environment and Setup Commands

- Create venv: `.venv/bin/python -m venv .venv`
- Activate venv (bash): `source .venv/bin/activate`
- Install deps: `pip install -r requirements.txt`
- Apply migrations: `.venv/bin/python manage.py migrate`
- Run server: `.venv/bin/python manage.py runserver`

Local configuration is loaded from `.env` via `.venv/bin/python-dotenv`.

Use this minimum `.env` content for gallery paths:

```env
GALLERY_ROOT=/path/to/images
THUMBNAILS_ROOT=/path/to/thumb-cache
```

Notes:

- `GALLERY_ROOT` and `THUMBNAILS_ROOT` are parsed as `pathlib.Path` in `settings.py`.
- Both are optional at import time and default to `None` when unset/empty.
- Paths do not need to be inside `BASE_DIR`.

## 4) Build / Lint / Test Commands

There is no dedicated linter or formatter config in-repo (no `ruff`, `flake8`, `black`, `mypy`, `pyright`, `tox`, or `pytest` config files detected).

Use these commands as the standard validation set:

- Django system checks: `.venv/bin/python manage.py check`
- Migration consistency check: `.venv/bin/python manage.py makemigrations --check --dry-run`
- Python syntax sanity: `.venv/bin/python -m compileall NibasaViewer viewer`
- Run Django tests (all): `.venv/bin/python manage.py test`

Single-test execution patterns (important for fast iteration):

- Single test module: `.venv/bin/python manage.py test viewer.test`
- Single test class: `.venv/bin/python manage.py test viewer.test.GalleryViewTests`
- Single test method: `.venv/bin/python manage.py test viewer.test.GalleryViewTests.test_search_action_url_uses_nested_path`

Notes:

- If there are currently no tests, add focused tests near the changed behavior before large refactors.
- Prefer `.venv/bin/python manage.py test ...` style labels over introducing a second test runner.

## 5) Operational Commands

- Pre-generate thumbnails: `.venv/bin/python manage.py makethumbnails`
- Create auth user (shell):
  - `.venv/bin/python manage.py shell`
  - `from django.contrib.auth.models import User`
  - `User.objects.create_user('<USERNAME>', '<EMAIL>', '<PASSWORD>')`
- Collect static files (deploy-time): `.venv/bin/python manage.py collectstatic`

## 6) Architecture and Change Boundaries

- Keep gallery metadata in filesystem, not DB tables.
- Do not introduce image/folder models unless explicitly requested by humans.
- Keep URL/data flow consistent:
  - `/imgs/` -> `GALLERY_ROOT`
  - `/thumbs/` -> `THUMBNAILS_ROOT`
  - `/gallery/` -> directory browsing and image view routing
- Preserve lazy thumbnail generation behavior unless task explicitly changes performance strategy.

### Recent changes notes

- The image view was refactored to match the gallery layout and styling; `viewer/templates/image_view.html` now uses the shared `viewer/static/css/styles.css` file and Bootstrap/Font Awesome includes like `gallery_view.html`.
- `_render_image` in `viewer/views.py` now exposes additional context keys used by the template and tests: `prev_url`, `next_url`, `prev_thumb`, `next_thumb`, `back_url`, `back_thumb`, `home_url`, `home_thumb`, and `image_meta` (dictionary with `filename`, `width`, `height`, `filesize`, `created`, `modified`). Agents modifying image-view behavior should update tests in `viewer/test.py` as well.
- The top-bar sort button for the image view was replaced by an Info button (`fa-circle-info`) which shows a dropdown containing image metadata. The dropdown is vertically scrollable for long content.
- The displayed main image now uses the same drop shadow and rounded corners as thumbnails (styles added to `viewer/static/css/styles.css`).
 - The gallery view and image view were split into focused modules: `viewer/directory.py` handles directory browsing and search, `viewer/image.py` handles single-image rendering and metadata, `viewer/common.py` contains shared helpers (URL/query builders, sort helpers, breadcrumbs), and `viewer/utils.py` contains thumbnail helpers (`THUMB_SIZE`, `is_image_file`, `make_thumbnail`). `viewer/views.py` is now a thin delegating layer that routes requests to those modules.
 - The image view (`viewer/image.py`) exposes richer context keys used by the template and tests: `prev_url`, `next_url`, `prev_thumb`, `next_thumb`, `back_url`, `back_thumb`, `home_url`, `home_thumb`, and `image_meta` (dictionary with `filename`, `width`, `height`, `filesize`, `created`, `modified`). Agents modifying image-view behavior should update tests in `viewer/test.py` as well.
 - The top-bar sort button for the gallery view remains; the image view uses an Info button (`fa-circle-info`) which shows a dropdown containing image metadata. The dropdown is vertically scrollable for long content.
 - Thumbnails are 128×128 (`THUMB_SIZE`) and generated lazily on-demand in `viewer/utils.py`; `IMAGE_EXTENSIONS` provides fast extension-based filtering. A management command `.venv/bin/python manage.py makethumbnails` exists for batch pre-generation.

## 7) Code Style Guidelines (Repository-Specific)

### Imports

- Use grouped imports with section comments where practical:
  - Standard library imports
  - Third-party/Django imports
  - Project/local imports
- Keep import order deterministic within each group.
- Follow existing style in touched file; do not mass-reformat untouched files.

### Formatting

- Follow existing formatting conventions in each file.
- Current codebase uses a traditional style with explicit spacing and readability comments.
- Avoid introducing unrelated formatting churn in files not functionally changed.
- Keep lines readable; wrap long imports or argument lists clearly.

### Naming

- Functions/variables: `snake_case`.
- Constants: `UPPER_SNAKE_CASE` (see `CELLS_PER_ROW`, `THUMB_SIZE`).
- Class names: `PascalCase`.
- URL names: descriptive snake_case names (`gallery_view_root`, `gallery_view_path`).

### Types and Data Shapes

- `pathlib.Path` is the preferred filesystem primitive.
- Accept `str` inputs only when ergonomics require it; normalize to `Path` early.
- Type hints are not strictly enforced across the repo; add them when they clarify non-obvious APIs.
- Do not introduce heavy typing frameworks or strict type-checking configs unless asked.

### Error Handling

- Catch specific exceptions when behavior should differ by failure mode.
- Use broad `except Exception` only for intentionally best-effort operations (e.g., thumbnail generation), and keep side effects minimal.
- Never swallow exceptions in critical control paths without rationale.
- User-facing 404/invalid-path behavior should remain explicit and predictable.

### Django View and URL Practices

- Protect gallery routes with `@login_required` unless requirement changes.
- Keep view context keys explicit and template-friendly.
- Preserve pagination constants and behavior unless task explicitly changes UX.
- Use `redirect`/`render` idioms already established in `viewer/views.py`.

### Template / Frontend Constraints

- Minimize JavaScript dependencies wherever possible.
- Bootstrap's own bundled JavaScript is allowed when needed for UI behaviors (offcanvas/dropdowns/tooling).
- Avoid custom project JavaScript unless explicitly requested.
- Keep HTML/CSS compatible with older browsers; prefer conservative layout features.
- Maintain dark-theme image-viewing emphasis and existing navigation metaphors.

## 8) Performance Expectations

- Prefer extension-based image filtering (`is_image_file`) over MIME-content probing.
- Avoid repeated heavy filesystem traversals in hot request paths when simple caching/slicing works.
- Keep thumbnail generation on-demand unless batch generation is requested.

## 9) Safety and Config Hygiene

- Never commit secrets or production-specific local settings.
- Keep `.env` local and out of version control; use `.env.example` as a template.
- Avoid destructive git operations unless explicitly requested.
- Do not revert unrelated working tree changes made by humans.

## 10) Agent Workflow Checklist

When implementing a change, follow this minimum loop:

1. Read relevant files and preserve local conventions.
2. Make the smallest change that satisfies the request.
3. Run focused validation commands first, then broader checks.
4. Report what changed, why, and exactly which commands were run.

Suggested pre-handoff command bundle:

- `.venv/bin/python manage.py check`
- `.venv/bin/python manage.py test` (or a targeted test label)
- `.venv/bin/python -m compileall NibasaViewer viewer`

This repository values stability, compatibility, and straightforward Django patterns over novelty.
