Thanks for your interest in contributing! This is a small personal project but PRs and issues are welcome.
git clone https://github.com/djapexlo/ani-cli-shelf
cd ani-cli-shelf
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e . # editable install — changes to app.py take effect immediately
pip install ruff # for linting
ani-cli-shelfDependencies outside Python:
- ani-cli — must be in
PATH mpvorvlc— for playbackfzf— must exist inPATH(ani-cli-shelf bypasses it but ani-cli checks for it)
Run the linter and make sure it passes with no errors:
ruff check app.pyIf you introduce new style issues, fix them before opening the PR. The project follows ruff's default ruleset — no configuration file needed.
Version bump:
Increment ANISHELF_VERSION in app.py by 0.01 for every change session. It's at the top of the file:
ANISHELF_VERSION = "0.76"ani_shelf/
├── app.py # Everything — Streamlit app, all tabs, all logic
├── ani-cli-print # Modified ani-cli with --direct flag and anime_list.txt output
├── requirements.txt # streamlit, httpx
├── thumbnails/ # Custom posters uploaded by the user (gitignored)
└── README.md
Runtime JSON files (jikan_cache.json, favourites.json, etc.) are created on first use and are gitignored — don't commit them.
- Single-file app —
app.pyis intentionally one file. It's long (~2900 lines) but searchable. Don't split it into modules unless there's a strong reason. - Session state keys — all initialized in one block near the top (search for
ss("). Add new keys there. - Jikan rate limits — 3 req/s, 60 req/min. The
BATCH_SIZE/BATCH_DELAYdefaults in settings respect this. Don't add Jikan calls outside the existing batch flow. st.rerun()scope — inside a@st.fragment,st.rerun()only re-renders the fragment. Outside, it's a full page reload. The search tab is particularly sensitive — any full rerun resets theglobal_searchwidget.- ani-cli stores NEXT episode in
ani-hsts, not the last watched. All episode progress comparisons use strict<not<=. - Cross-platform paths — default file paths are set via
_platform_default_paths()which handles Linux, macOS, and Windows separately.
- Bug fixes for any tab or feature
- New browse/filter modes in the Seasonal tab (Jikan has many endpoints)
- UX improvements to existing panels
- Performance improvements to Jikan fetching or caching
- Replacing ani-cli with a different backend
- Cloud sync or multi-user support
- A non-Streamlit frontend
Open a GitHub issue with:
- What you did
- What you expected
- What happened instead
- Your OS and Python version (
python --version) - Your Streamlit version (
pip show streamlit)
If it's a crash, paste the full traceback from the terminal where you ran streamlit run app.py.