Add README.md and AGENTS.md

This commit is contained in:
tim
2026-09-27 23:38:28 +02:00
parent 7c61bbd1e4
commit 75cc0464a2
2 changed files with 570 additions and 0 deletions
+69
View File
@@ -0,0 +1,69 @@
# Notes for coding agents
CWA Bindery is a Flask app. It downloads web fiction with a headless FanFicFare, stores each chapter in SQLite, and sends ePubs to Calibre-Web-Automated (CWA) through the CWA ingest folder.
## Commands
```bash
uv sync
uv run pytest
uv run ruff check .
uv run ruff format .
node --test "tests/js/*.test.mjs"
```
Keep the quotes around the glob in the node command. Without them, node reads `tests/js/` as a file and fails.
Start a development server with no CWA:
```bash
CONFIG_DIR=dev/config INGEST_DIR=dev/ingest TMP_DIR=dev/tmp uv run python -m bindery
```
The server has no reloader. If you change Python code, restart it. Flask reads `bindery/static` from disk on each request, so a server that is not restarted sends new JavaScript to old Python routes.
## Layout
- `bindery/fff.py` is the only module that calls FanFicFare.
- `bindery/cwa.py` talks to CWA through OPDS. Bindery never opens the CWA database.
- `bindery/diffing.py` hashes and diffs text, not HTML.
- `bindery/jobs.py` keeps the job queue in SQLite, so jobs survive a restart.
- `tests/fake_cwa.py` is a fake CWA server.
## Rules
- **Ask before assuming.** If requirements are unclear, ask.
- **Be brief.** In code comments, commit messages, and responses: say what needs saying, nothing more.
- **Succinct edits.** Change only what is necessary. Don't reformat surrounding code or add unsolicited improvements.
- **Unit tests.** Always add unit tests for code changes, and vet your changes by running existing unit tests, assessing, and writing new unit tests, or, if necessary, modifying existing tests.
- **Ruff before committing.** Run `uv run ruff check .` and `uv run ruff format .` before every commit, and commit what they change.
## Rules for the code
- The store holds each chapter as the site sent it. When Bindery builds an ePub, rules and the line-break step run only on a copy. Do not write changed text back to the store.
- Bindery identifies a chapter by its URL, after `normalize_chapterurl` from the FanFicFare adapter.
- A chapter that the site removed stays in the book. Do not delete stored chapters in an update.
- A module reads each setting as `config.NAME` at the time it needs it, not at import. Tests change a setting with `monkeypatch.setattr(config, "NAME", value)`.
- The store has no migrations. Add a new table with `CREATE TABLE IF NOT EXISTS`. Do not add columns to an existing table unless you also add a migration.
- A job must be safe to run again after a restart. Store each piece of work as soon as it is done, and keep progress in `job.result`.
- Tests for site updates replace `fff.fetch_story`, `fff.fetch_chapter` and `fff.collected_images` with `monkeypatch`. Tests never go to a story site.
- The web interface builds DOM with `h()` from `lib.js`, so text is never parsed as HTML. It uses relative URLs and hash routes, so it works under `URL_BASE`. Each request that changes data sends the header `X-Requested-With: bindery`.
- Do not download or install browsers to test the web interface. Check the JavaScript with `node --check` and the Node tests, and ask the user to test it in a browser.
## Further Notes
- Never use Tailwind CSS tags in generated HTML. Redundant tags like button.button and button.btn should not be needed.
- CSS and HTML should be native and up-to-date, using the latest language features without creating unnecessary HTML elements or complicated CSS.
- CSS should live in one or more dedicated files, never in the HTML.
- Always use vanilla JavaScript when writing frontend code, never a JavaScript framework. Code should, where possible, live in a dedicated JavaScript files.
## Commits
- New features get new commits. Keep each commit focused on one logical change.
- Do not add AI attribution lines, such as `Co-Authored-By` or session links, to commit messages.
- Each commit must pass the checks on its own.
- Push only at the request of the user.
## Writing
Write the README, error messages and UI text in plain English. Use short sentences, active voice and simple tenses. Of the modal verbs, use only "must", "can" and "will". Do not use semicolons or em-dashes.