{"owner":"EstrellaXD","repo":"Auto_Bangumi","hasSkills":true,"totalSkillsCount":3,"totalTokensCount":2509,"categories":["plugin-manifest","claude-rule"],"hasMcp":false,"mcpConfig":null,"found":["plugins/codex-chatgpt/plugin.json","CLAUDE.md","plugins/github-copilot/plugin.json"],"skills":{"plugins/codex-chatgpt/plugin.json":"{\n  \"schema\": 1,\n  \"id\": \"codex-chatgpt\",\n  \"name\": \"ChatGPT (Codex)\",\n  \"version\": \"1.0.0\",\n  \"min_ab_version\": \"3.3.0\",\n  \"entry\": \"ab_llm_codex.adapter:CodexChatgptAdapter\",\n  \"auth_kind\": \"device_code\",\n  \"needs_base_url\": false,\n  \"default_model\": \"gpt-5.1-codex\",\n  \"description_en\": \"Use a ChatGPT Plus/Pro subscription for title parsing via the Codex device-flow login.\",\n  \"description_zh\": \"通过 Codex device flow 登录，用 ChatGPT Plus/Pro 订阅解析标题。\",\n  \"risk_notice_en\": \"ChatGPT subscription credentials are scoped to the official Codex client; third-party use is unsanctioned and may be blocked. Use at your own risk.\",\n  \"risk_notice_zh\": \"ChatGPT 订阅凭据被限定到官方 Codex 客户端，第三方使用未获许可、可能被封锁。请自担风险。\"\n}\n","CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nAutoBangumi is an RSS-based automatic anime downloading and organization tool. It monitors RSS feeds from anime torrent sites (Mikan, DMHY, Nyaa), downloads episodes via qBittorrent, and organizes files into a Plex/Jellyfin-compatible directory structure with automatic renaming.\n\n## Development Commands\n\n### Backend (Python)\n\n```bash\n# Install dependencies\ncd backend && uv sync\n\n# Install with dev tools\ncd backend && uv sync --group dev\n\n# Run development server (port 7892, API docs at /docs)\ncd backend/src && uv run python main.py\n\n# Run tests\ncd backend && uv run pytest\ncd backend && uv run pytest src/test/test_xxx.py -v  # run specific test\n\n# Linting and formatting\ncd backend && uv run ruff check src\ncd backend && uv run black src\n\n# Add a dependency\ncd backend && uv add <package>\n\n# Add a dev dependency\ncd backend && uv add --group dev <package>\n```\n\n### Frontend (Vue 3 + TypeScript)\n\n```bash\ncd webui\n\n# Install dependencies (uses pnpm, not npm)\npnpm install\n\n# Development server (port 5173)\npnpm dev\n\n# Build for production\npnpm build\n\n# Type checking\npnpm test:build\n\n# Linting and formatting\npnpm lint\npnpm lint:fix\npnpm format\n```\n\n### Docker\n\n```bash\ndocker build -t auto_bangumi:latest .\ndocker run -p 7892:7892 -v /path/to/config:/app/config -v /path/to/data:/app/data auto_bangumi:latest\n```\n\n## Architecture\n\n```\nbackend/src/\n├── main.py                 # FastAPI entry point, mounts API at /api\n├── module/\n│   ├── api/               # REST API routes (v1 prefix)\n│   │   ├── auth.py        # Authentication endpoints\n│   │   ├── bangumi.py     # Anime series CRUD\n│   │   ├── rss.py         # RSS feed management\n│   │   ├── config.py      # Configuration endpoints\n│   │   ├── program.py     # Program status/control\n│   │   └── search.py      # Torrent search\n│   ├── core/              # Application logic\n│   │   ├── context.py     # AppContext composition root (built in create_app, on app.state.ctx)\n│   │   ├── scheduler.py   # PeriodicTask + Scheduler (generic background-loop runner)\n│   │   ├── loops.py       # The individual periodic tick functions (rss/rename/offset/calendar)\n│   │   └── offset_scanner.py\n│   ├── models/            # SQLModel ORM models (Pydantic + SQLAlchemy)\n│   ├── database/          # Async DB (aiosqlite) — repos + Database + migrations.py\n│   ├── rss/               # RSS parsing and analysis\n│   ├── downloader/        # qBittorrent integration\n│   │   ├── base.py        # Downloader Protocol + DownloaderCapabilities\n│   │   └── client/        # Download client implementations (qb, aria2, mock)\n│   ├── searcher/          # Torrent search providers (Mikan, DMHY, Nyaa)\n│   ├── parser/            # Torrent name parsing, metadata extraction\n│   │   └── analyser/      # TMDB, Mikan, OpenAI parsers\n│   ├── manager/           # File organization and renaming\n│   ├── notification/      # Notification plugins (Telegram, Bark, etc.)\n│   ├── conf/              # Configuration management, settings\n│   ├── network/           # HTTP client utilities\n│   └── security/          # JWT authentication\n\nwebui/src/\n├── api/                   # Axios API client functions\n├── components/            # Vue components (basic/, layout/, setting/)\n├── pages/                 # Router-based page components\n├── router/                # Vue Router configuration\n├── store/                 # Pinia state management\n├── i18n/                  # Internationalization (zh-CN, en-US)\n└── hooks/                 # Custom Vue composables\n```\n\n## Key Data Flow\n\n1. RSS feeds are parsed by `module/rss/` to extract torrent information\n2. Torrent names are analyzed by `module/parser/analyser/` to extract anime metadata\n3. Downloads are managed via `module/downloader/` (qBittorrent API)\n4. Files are organized by `module/manager/` into standard directory structure\n5. Periodic loops (`module/core/loops.py`) run under a `Scheduler` owned by the lifespan `AppContext` (`module/core/context.py`)\n\n## Architecture conventions (3.3+)\n\n- **Async DB throughout.** Everything runs on the async engine (`sqlite+aiosqlite`, WAL). Repositories (`database/{bangumi,rss,torrent,user,passkey}.py`) take an `AsyncSession` and are `async def`. `Database` is an async context manager owning one session with the repos attached (`db.rss`, `db.bangumi`, …).\n- **Session per operation.** Get a session via `Depends(get_db)` in routes, or `async with Database() as db:` in loops/services. Never store a session on anything that outlives one request or one loop tick. `AppContext` holds no session.\n- **Services take dependencies in their constructor** (composition, not inheritance): `RSSEngine(db)`, `TorrentManager(db)`, `Renamer(client)`, `SearchTorrent()`. They use `self.db.<repo>` internally; callers that only need a repo use `db.<repo>` directly.\n- **Downloaders** implement the `Downloader` Protocol and declare `DownloaderCapabilities`; the facade (`DownloadClient`) skips-and-logs unsupported ops rather than crashing. The qB client is reused across operations (one login), not re-authed per call.\n- **Config reloads** go through `AppContext.reload_settings()` (settings + http client + notifier + scheduler), not ad-hoc `settings.load()`.\n\n## Code Style\n\n- Python: Black (88 char lines), Ruff linter (E, F, I rules), target Python 3.10+\n- TypeScript: ESLint + Prettier\n- Run formatters before committing\n\n## Git Branching\n\n- `main`: Stable releases only\n- `X.Y-dev` branches: Active development (e.g., `3.2-dev`)\n- Bug fixes → PR to current released version's `-dev` branch\n- New features → PR to next version's `-dev` branch\n\n## Releasing\n\nAll releases are triggered by manually pushing a tag — merging a PR never releases.\n\n### Beta Version\n\n1. Update version in `backend/pyproject.toml`\n2. Update `CHANGELOG.md` with the new version heading\n3. Commit and push to the dev branch\n4. Create and push a tag with the version name (e.g., `3.2.0-beta.4`):\n   ```bash\n   git tag 3.2.0-beta.4\n   git push origin 3.2.0-beta.4\n   ```\n5. The CI/CD workflow (`.github/workflows/build.yml`) detects the tag contains \"beta\", uses the tag name as the VERSION string, generates `module/__version__.py`, and builds the Docker image (tagged `<version>` + `dev-latest`)\n\n### Stable Version\n\n1. Merge the dev branch into `main` via PR (this only runs tests and a build test)\n2. Tag the merge commit on `main` with the bare semver version and push:\n   ```bash\n   git tag 3.3.2 <merge-commit-on-main>\n   git push origin 3.3.2\n   ```\n3. CI validates the tag is `X.Y.Z` **and** points to a commit on `main` (refuses otherwise), then builds and pushes Docker images (tagged `<version>` + `latest`) and creates the GitHub release with notes from `docs/changelog/<X.Y>.md`\n\nThe VERSION is injected at build time via CI — `module/__version__.py` does not exist in the repo. At runtime, `module/conf/config.py` imports it or falls back to `\"DEV_VERSION\"`.\n\n## Database Migrations\n\nSchema migrations are tracked via a `schema_version` table in SQLite. To add a new migration:\n\n1. Append a `Migration(version, \"description\", (…SQL…), already_applied=column_exists(\"table\", \"col\"))` entry to the `MIGRATIONS` tuple in `backend/src/module/database/migrations.py` (`CURRENT_SCHEMA_VERSION` is derived from the list — do not edit it by hand)\n2. Provide an `already_applied` guard (`column_exists` / `table_exists`) so a schema created out-of-band is detected and skipped\n3. Migrations run automatically on startup via `run_migrations()` (each in a SAVEPOINT, stopping on first failure)\n\n## Notes\n\n- Documentation and comments are in Chinese\n- Uses SQLModel (hybrid Pydantic + SQLAlchemy ORM)\n- External integrations: qBittorrent API, TMDB API, OpenAI API\n- Version tracked in `/config/version.info` (for cross-version upgrade detection)\n","plugins/github-copilot/plugin.json":"{\n  \"schema\": 1,\n  \"id\": \"github-copilot\",\n  \"name\": \"GitHub Copilot\",\n  \"version\": \"1.0.0\",\n  \"min_ab_version\": \"3.3.0\",\n  \"entry\": \"ab_llm_copilot.adapter:GithubCopilotAdapter\",\n  \"auth_kind\": \"device_code\",\n  \"needs_base_url\": false,\n  \"default_model\": \"gpt-4o\",\n  \"description_en\": \"Use a GitHub Copilot subscription for title parsing via the device-flow login.\",\n  \"description_zh\": \"通过 device flow 登录，用 GitHub Copilot 订阅解析标题。\",\n  \"risk_notice_en\": \"Copilot's internal endpoint is for official clients only; third-party use may violate GitHub's terms and trigger abuse detection. Use at your own risk.\",\n  \"risk_notice_zh\": \"Copilot 内部端点仅供官方客户端使用，第三方调用可能违反 GitHub 条款并触发滥用检测。请自担风险。\"\n}\n"},"files":{"plugins/codex-chatgpt/plugin.json":"{\n  \"schema\": 1,\n  \"id\": \"codex-chatgpt\",\n  \"name\": \"ChatGPT (Codex)\",\n  \"version\": \"1.0.0\",\n  \"min_ab_version\": \"3.3.0\",\n  \"entry\": \"ab_llm_codex.adapter:CodexChatgptAdapter\",\n  \"auth_kind\": \"device_code\",\n  \"needs_base_url\": false,\n  \"default_model\": \"gpt-5.1-codex\",\n  \"description_en\": \"Use a ChatGPT Plus/Pro subscription for title parsing via the Codex device-flow login.\",\n  \"description_zh\": \"通过 Codex device flow 登录，用 ChatGPT Plus/Pro 订阅解析标题。\",\n  \"risk_notice_en\": \"ChatGPT subscription credentials are scoped to the official Codex client; third-party use is unsanctioned and may be blocked. Use at your own risk.\",\n  \"risk_notice_zh\": \"ChatGPT 订阅凭据被限定到官方 Codex 客户端，第三方使用未获许可、可能被封锁。请自担风险。\"\n}\n","CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nAutoBangumi is an RSS-based automatic anime downloading and organization tool. It monitors RSS feeds from anime torrent sites (Mikan, DMHY, Nyaa), downloads episodes via qBittorrent, and organizes files into a Plex/Jellyfin-compatible directory structure with automatic renaming.\n\n## Development Commands\n\n### Backend (Python)\n\n```bash\n# Install dependencies\ncd backend && uv sync\n\n# Install with dev tools\ncd backend && uv sync --group dev\n\n# Run development server (port 7892, API docs at /docs)\ncd backend/src && uv run python main.py\n\n# Run tests\ncd backend && uv run pytest\ncd backend && uv run pytest src/test/test_xxx.py -v  # run specific test\n\n# Linting and formatting\ncd backend && uv run ruff check src\ncd backend && uv run black src\n\n# Add a dependency\ncd backend && uv add <package>\n\n# Add a dev dependency\ncd backend && uv add --group dev <package>\n```\n\n### Frontend (Vue 3 + TypeScript)\n\n```bash\ncd webui\n\n# Install dependencies (uses pnpm, not npm)\npnpm install\n\n# Development server (port 5173)\npnpm dev\n\n# Build for production\npnpm build\n\n# Type checking\npnpm test:build\n\n# Linting and formatting\npnpm lint\npnpm lint:fix\npnpm format\n```\n\n### Docker\n\n```bash\ndocker build -t auto_bangumi:latest .\ndocker run -p 7892:7892 -v /path/to/config:/app/config -v /path/to/data:/app/data auto_bangumi:latest\n```\n\n## Architecture\n\n```\nbackend/src/\n├── main.py                 # FastAPI entry point, mounts API at /api\n├── module/\n│   ├── api/               # REST API routes (v1 prefix)\n│   │   ├── auth.py        # Authentication endpoints\n│   │   ├── bangumi.py     # Anime series CRUD\n│   │   ├── rss.py         # RSS feed management\n│   │   ├── config.py      # Configuration endpoints\n│   │   ├── program.py     # Program status/control\n│   │   └── search.py      # Torrent search\n│   ├── core/              # Application logic\n│   │   ├── context.py     # AppContext composition root (built in create_app, on app.state.ctx)\n│   │   ├── scheduler.py   # PeriodicTask + Scheduler (generic background-loop runner)\n│   │   ├── loops.py       # The individual periodic tick functions (rss/rename/offset/calendar)\n│   │   └── offset_scanner.py\n│   ├── models/            # SQLModel ORM models (Pydantic + SQLAlchemy)\n│   ├── database/          # Async DB (aiosqlite) — repos + Database + migrations.py\n│   ├── rss/               # RSS parsing and analysis\n│   ├── downloader/        # qBittorrent integration\n│   │   ├── base.py        # Downloader Protocol + DownloaderCapabilities\n│   │   └── client/        # Download client implementations (qb, aria2, mock)\n│   ├── searcher/          # Torrent search providers (Mikan, DMHY, Nyaa)\n│   ├── parser/            # Torrent name parsing, metadata extraction\n│   │   └── analyser/      # TMDB, Mikan, OpenAI parsers\n│   ├── manager/           # File organization and renaming\n│   ├── notification/      # Notification plugins (Telegram, Bark, etc.)\n│   ├── conf/              # Configuration management, settings\n│   ├── network/           # HTTP client utilities\n│   └── security/          # JWT authentication\n\nwebui/src/\n├── api/                   # Axios API client functions\n├── components/            # Vue components (basic/, layout/, setting/)\n├── pages/                 # Router-based page components\n├── router/                # Vue Router configuration\n├── store/                 # Pinia state management\n├── i18n/                  # Internationalization (zh-CN, en-US)\n└── hooks/                 # Custom Vue composables\n```\n\n## Key Data Flow\n\n1. RSS feeds are parsed by `module/rss/` to extract torrent information\n2. Torrent names are analyzed by `module/parser/analyser/` to extract anime metadata\n3. Downloads are managed via `module/downloader/` (qBittorrent API)\n4. Files are organized by `module/manager/` into standard directory structure\n5. Periodic loops (`module/core/loops.py`) run under a `Scheduler` owned by the lifespan `AppContext` (`module/core/context.py`)\n\n## Architecture conventions (3.3+)\n\n- **Async DB throughout.** Everything runs on the async engine (`sqlite+aiosqlite`, WAL). Repositories (`database/{bangumi,rss,torrent,user,passkey}.py`) take an `AsyncSession` and are `async def`. `Database` is an async context manager owning one session with the repos attached (`db.rss`, `db.bangumi`, …).\n- **Session per operation.** Get a session via `Depends(get_db)` in routes, or `async with Database() as db:` in loops/services. Never store a session on anything that outlives one request or one loop tick. `AppContext` holds no session.\n- **Services take dependencies in their constructor** (composition, not inheritance): `RSSEngine(db)`, `TorrentManager(db)`, `Renamer(client)`, `SearchTorrent()`. They use `self.db.<repo>` internally; callers that only need a repo use `db.<repo>` directly.\n- **Downloaders** implement the `Downloader` Protocol and declare `DownloaderCapabilities`; the facade (`DownloadClient`) skips-and-logs unsupported ops rather than crashing. The qB client is reused across operations (one login), not re-authed per call.\n- **Config reloads** go through `AppContext.reload_settings()` (settings + http client + notifier + scheduler), not ad-hoc `settings.load()`.\n\n## Code Style\n\n- Python: Black (88 char lines), Ruff linter (E, F, I rules), target Python 3.10+\n- TypeScript: ESLint + Prettier\n- Run formatters before committing\n\n## Git Branching\n\n- `main`: Stable releases only\n- `X.Y-dev` branches: Active development (e.g., `3.2-dev`)\n- Bug fixes → PR to current released version's `-dev` branch\n- New features → PR to next version's `-dev` branch\n\n## Releasing\n\nAll releases are triggered by manually pushing a tag — merging a PR never releases.\n\n### Beta Version\n\n1. Update version in `backend/pyproject.toml`\n2. Update `CHANGELOG.md` with the new version heading\n3. Commit and push to the dev branch\n4. Create and push a tag with the version name (e.g., `3.2.0-beta.4`):\n   ```bash\n   git tag 3.2.0-beta.4\n   git push origin 3.2.0-beta.4\n   ```\n5. The CI/CD workflow (`.github/workflows/build.yml`) detects the tag contains \"beta\", uses the tag name as the VERSION string, generates `module/__version__.py`, and builds the Docker image (tagged `<version>` + `dev-latest`)\n\n### Stable Version\n\n1. Merge the dev branch into `main` via PR (this only runs tests and a build test)\n2. Tag the merge commit on `main` with the bare semver version and push:\n   ```bash\n   git tag 3.3.2 <merge-commit-on-main>\n   git push origin 3.3.2\n   ```\n3. CI validates the tag is `X.Y.Z` **and** points to a commit on `main` (refuses otherwise), then builds and pushes Docker images (tagged `<version>` + `latest`) and creates the GitHub release with notes from `docs/changelog/<X.Y>.md`\n\nThe VERSION is injected at build time via CI — `module/__version__.py` does not exist in the repo. At runtime, `module/conf/config.py` imports it or falls back to `\"DEV_VERSION\"`.\n\n## Database Migrations\n\nSchema migrations are tracked via a `schema_version` table in SQLite. To add a new migration:\n\n1. Append a `Migration(version, \"description\", (…SQL…), already_applied=column_exists(\"table\", \"col\"))` entry to the `MIGRATIONS` tuple in `backend/src/module/database/migrations.py` (`CURRENT_SCHEMA_VERSION` is derived from the list — do not edit it by hand)\n2. Provide an `already_applied` guard (`column_exists` / `table_exists`) so a schema created out-of-band is detected and skipped\n3. Migrations run automatically on startup via `run_migrations()` (each in a SAVEPOINT, stopping on first failure)\n\n## Notes\n\n- Documentation and comments are in Chinese\n- Uses SQLModel (hybrid Pydantic + SQLAlchemy ORM)\n- External integrations: qBittorrent API, TMDB API, OpenAI API\n- Version tracked in `/config/version.info` (for cross-version upgrade detection)\n","plugins/github-copilot/plugin.json":"{\n  \"schema\": 1,\n  \"id\": \"github-copilot\",\n  \"name\": \"GitHub Copilot\",\n  \"version\": \"1.0.0\",\n  \"min_ab_version\": \"3.3.0\",\n  \"entry\": \"ab_llm_copilot.adapter:GithubCopilotAdapter\",\n  \"auth_kind\": \"device_code\",\n  \"needs_base_url\": false,\n  \"default_model\": \"gpt-4o\",\n  \"description_en\": \"Use a GitHub Copilot subscription for title parsing via the device-flow login.\",\n  \"description_zh\": \"通过 device flow 登录，用 GitHub Copilot 订阅解析标题。\",\n  \"risk_notice_en\": \"Copilot's internal endpoint is for official clients only; third-party use may violate GitHub's terms and trigger abuse detection. Use at your own risk.\",\n  \"risk_notice_zh\": \"Copilot 内部端点仅供官方客户端使用，第三方调用可能违反 GitHub 条款并触发滥用检测。请自担风险。\"\n}\n"},"items":[{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/EstrellaXD/Auto_Bangumi/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nAutoBangumi is an RSS-based automatic anime downloading and organization tool. It monitors RSS feeds from anime torrent sites (Mikan, DMHY, Nyaa), downloads episodes via qBittorrent, and organizes files into a Plex/Jellyfin-compatible directory structure with automatic renaming.\n\n## Development Commands\n\n### Backend (Python)\n\n```bash\n# Install dependencies\ncd backend && uv sync\n\n# Install with dev tools\ncd backend && uv sync --group dev\n\n# Run development server (port 7892, API docs at /docs)\ncd backend/src && uv run python main.py\n\n# Run tests\ncd backend && uv run pytest\ncd backend && uv run pytest src/test/test_xxx.py -v  # run specific test\n\n# Linting and formatting\ncd backend && uv run ruff check src\ncd backend && uv run black src\n\n# Add a dependency\ncd backend && uv add <package>\n\n# Add a dev dependency\ncd backend && uv add --group dev <package>\n```\n\n### Frontend (Vue 3 + TypeScript)\n\n```bash\ncd webui\n\n# Install dependencies (uses pnpm, not npm)\npnpm install\n\n# Development server (port 5173)\npnpm dev\n\n# Build for production\npnpm build\n\n# Type checking\npnpm test:build\n\n# Linting and formatting\npnpm lint\npnpm lint:fix\npnpm format\n```\n\n### Docker\n\n```bash\ndocker build -t auto_bangumi:latest .\ndocker run -p 7892:7892 -v /path/to/config:/app/config -v /path/to/data:/app/data auto_bangumi:latest\n```\n\n## Architecture\n\n```\nbackend/src/\n├── main.py                 # FastAPI entry point, mounts API at /api\n├── module/\n│   ├── api/               # REST API routes (v1 prefix)\n│   │   ├── auth.py        # Authentication endpoints\n│   │   ├── bangumi.py     # Anime series CRUD\n│   │   ├── rss.py         # RSS feed management\n│   │   ├── config.py      # Configuration endpoints\n│   │   ├── program.py     # Program status/control\n│   │   └── search.py      # Torrent search\n│   ├── core/              # Application logic\n│   │   ├── context.py     # AppContext composition root (built in create_app, on app.state.ctx)\n│   │   ├── scheduler.py   # PeriodicTask + Scheduler (generic background-loop runner)\n│   │   ├── loops.py       # The individual periodic tick functions (rss/rename/offset/calendar)\n│   │   └── offset_scanner.py\n│   ├── models/            # SQLModel ORM models (Pydantic + SQLAlchemy)\n│   ├── database/          # Async DB (aiosqlite) — repos + Database + migrations.py\n│   ├── rss/               # RSS parsing and analysis\n│   ├── downloader/        # qBittorrent integration\n│   │   ├── base.py        # Downloader Protocol + DownloaderCapabilities\n│   │   └── client/        # Download client implementations (qb, aria2, mock)\n│   ├── searcher/          # Torrent search providers (Mikan, DMHY, Nyaa)\n│   ├── parser/            # Torrent name parsing, metadata extraction\n│   │   └── analyser/      # TMDB, Mikan, OpenAI parsers\n│   ├── manager/           # File organization and renaming\n│   ├── notification/      # Notification plugins (Telegram, Bark, etc.)\n│   ├── conf/              # Configuration management, settings\n│   ├── network/           # HTTP client utilities\n│   └── security/          # JWT authentication\n\nwebui/src/\n├── api/                   # Axios API client functions\n├── components/            # Vue components (basic/, layout/, setting/)\n├── pages/                 # Router-based page components\n├── router/                # Vue Router configuration\n├── store/                 # Pinia state management\n├── i18n/                  # Internationalization (zh-CN, en-US)\n└── hooks/                 # Custom Vue composables\n```\n\n## Key Data Flow\n\n1. RSS feeds are parsed by `module/rss/` to extract torrent information\n2. Torrent names are analyzed by `module/parser/analyser/` to extract anime metadata\n3. Downloads are managed via `module/downloader/` (qBittorrent API)\n4. Files are organized by `module/manager/` into standard directory structure\n5. Periodic loops (`module/core/loops.py`) run under a `Scheduler` owned by the lifespan `AppContext` (`module/core/context.py`)\n\n## Architecture conventions (3.3+)\n\n- **Async DB throughout.** Everything runs on the async engine (`sqlite+aiosqlite`, WAL). Repositories (`database/{bangumi,rss,torrent,user,passkey}.py`) take an `AsyncSession` and are `async def`. `Database` is an async context manager owning one session with the repos attached (`db.rss`, `db.bangumi`, …).\n- **Session per operation.** Get a session via `Depends(get_db)` in routes, or `async with Database() as db:` in loops/services. Never store a session on anything that outlives one request or one loop tick. `AppContext` holds no session.\n- **Services take dependencies in their constructor** (composition, not inheritance): `RSSEngine(db)`, `TorrentManager(db)`, `Renamer(client)`, `SearchTorrent()`. They use `self.db.<repo>` internally; callers that only need a repo use `db.<repo>` directly.\n- **Downloaders** implement the `Downloader` Protocol and declare `DownloaderCapabilities`; the facade (`DownloadClient`) skips-and-logs unsupported ops rather than crashing. The qB client is reused across operations (one login), not re-authed per call.\n- **Config reloads** go through `AppContext.reload_settings()` (settings + http client + notifier + scheduler), not ad-hoc `settings.load()`.\n\n## Code Style\n\n- Python: Black (88 char lines), Ruff linter (E, F, I rules), target Python 3.10+\n- TypeScript: ESLint + Prettier\n- Run formatters before committing\n\n## Git Branching\n\n- `main`: Stable releases only\n- `X.Y-dev` branches: Active development (e.g., `3.2-dev`)\n- Bug fixes → PR to current released version's `-dev` branch\n- New features → PR to next version's `-dev` branch\n\n## Releasing\n\nAll releases are triggered by manually pushing a tag — merging a PR never releases.\n\n### Beta Version\n\n1. Update version in `backend/pyproject.toml`\n2. Update `CHANGELOG.md` with the new version heading\n3. Commit and push to the dev branch\n4. Create and push a tag with the version name (e.g., `3.2.0-beta.4`):\n   ```bash\n   git tag 3.2.0-beta.4\n   git push origin 3.2.0-beta.4\n   ```\n5. The CI/CD workflow (`.github/workflows/build.yml`) detects the tag contains \"beta\", uses the tag name as the VERSION string, generates `module/__version__.py`, and builds the Docker image (tagged `<version>` + `dev-latest`)\n\n### Stable Version\n\n1. Merge the dev branch into `main` via PR (this only runs tests and a build test)\n2. Tag the merge commit on `main` with the bare semver version and push:\n   ```bash\n   git tag 3.3.2 <merge-commit-on-main>\n   git push origin 3.3.2\n   ```\n3. CI validates the tag is `X.Y.Z` **and** points to a commit on `main` (refuses otherwise), then builds and pushes Docker images (tagged `<version>` + `latest`) and creates the GitHub release with notes from `docs/changelog/<X.Y>.md`\n\nThe VERSION is injected at build time via CI — `module/__version__.py` does not exist in the repo. At runtime, `module/conf/config.py` imports it or falls back to `\"DEV_VERSION\"`.\n\n## Database Migrations\n\nSchema migrations are tracked via a `schema_version` table in SQLite. To add a new migration:\n\n1. Append a `Migration(version, \"description\", (…SQL…), already_applied=column_exists(\"table\", \"col\"))` entry to the `MIGRATIONS` tuple in `backend/src/module/database/migrations.py` (`CURRENT_SCHEMA_VERSION` is derived from the list — do not edit it by hand)\n2. Provide an `already_applied` guard (`column_exists` / `table_exists`) so a schema created out-of-band is detected and skipped\n3. Migrations run automatically on startup via `run_migrations()` (each in a SAVEPOINT, stopping on first failure)\n\n## Notes\n\n- Documentation and comments are in Chinese\n- Uses SQLModel (hybrid Pydantic + SQLAlchemy ORM)\n- External integrations: qBittorrent API, TMDB API, OpenAI API\n- Version tracked in `/config/version.info` (for cross-version upgrade detection)\n","isInternal":false,"tokens":2001,"sizeBytes":8189},{"name":"plugin.json","path":"plugins/codex-chatgpt/plugin.json","rawUrl":"https://raw.githubusercontent.com/EstrellaXD/Auto_Bangumi/HEAD/plugins/codex-chatgpt/plugin.json","title":"ChatGPT (Codex)","category":"plugin-manifest","format":"json","content":"{\n  \"schema\": 1,\n  \"id\": \"codex-chatgpt\",\n  \"name\": \"ChatGPT (Codex)\",\n  \"version\": \"1.0.0\",\n  \"min_ab_version\": \"3.3.0\",\n  \"entry\": \"ab_llm_codex.adapter:CodexChatgptAdapter\",\n  \"auth_kind\": \"device_code\",\n  \"needs_base_url\": false,\n  \"default_model\": \"gpt-5.1-codex\",\n  \"description_en\": \"Use a ChatGPT Plus/Pro subscription for title parsing via the Codex device-flow login.\",\n  \"description_zh\": \"通过 Codex device flow 登录，用 ChatGPT Plus/Pro 订阅解析标题。\",\n  \"risk_notice_en\": \"ChatGPT subscription credentials are scoped to the official Codex client; third-party use is unsanctioned and may be blocked. Use at your own risk.\",\n  \"risk_notice_zh\": \"ChatGPT 订阅凭据被限定到官方 Codex 客户端，第三方使用未获许可、可能被封锁。请自担风险。\"\n}\n","frontmatter":{"schema":1,"id":"codex-chatgpt","name":"ChatGPT (Codex)","version":"1.0.0","min_ab_version":"3.3.0","entry":"ab_llm_codex.adapter:CodexChatgptAdapter","auth_kind":"device_code","needs_base_url":false,"default_model":"gpt-5.1-codex","description_en":"Use a ChatGPT Plus/Pro subscription for title parsing via the Codex device-flow login.","description_zh":"通过 Codex device flow 登录，用 ChatGPT Plus/Pro 订阅解析标题。","risk_notice_en":"ChatGPT subscription credentials are scoped to the official Codex client; third-party use is unsanctioned and may be blocked. Use at your own risk.","risk_notice_zh":"ChatGPT 订阅凭据被限定到官方 Codex 客户端，第三方使用未获许可、可能被封锁。请自担风险。"},"isInternal":false,"tokens":266,"sizeBytes":799},{"name":"plugin.json","path":"plugins/github-copilot/plugin.json","rawUrl":"https://raw.githubusercontent.com/EstrellaXD/Auto_Bangumi/HEAD/plugins/github-copilot/plugin.json","title":"GitHub Copilot","category":"plugin-manifest","format":"json","content":"{\n  \"schema\": 1,\n  \"id\": \"github-copilot\",\n  \"name\": \"GitHub Copilot\",\n  \"version\": \"1.0.0\",\n  \"min_ab_version\": \"3.3.0\",\n  \"entry\": \"ab_llm_copilot.adapter:GithubCopilotAdapter\",\n  \"auth_kind\": \"device_code\",\n  \"needs_base_url\": false,\n  \"default_model\": \"gpt-4o\",\n  \"description_en\": \"Use a GitHub Copilot subscription for title parsing via the device-flow login.\",\n  \"description_zh\": \"通过 device flow 登录，用 GitHub Copilot 订阅解析标题。\",\n  \"risk_notice_en\": \"Copilot's internal endpoint is for official clients only; third-party use may violate GitHub's terms and trigger abuse detection. Use at your own risk.\",\n  \"risk_notice_zh\": \"Copilot 内部端点仅供官方客户端使用，第三方调用可能违反 GitHub 条款并触发滥用检测。请自担风险。\"\n}\n","frontmatter":{"schema":1,"id":"github-copilot","name":"GitHub Copilot","version":"1.0.0","min_ab_version":"3.3.0","entry":"ab_llm_copilot.adapter:GithubCopilotAdapter","auth_kind":"device_code","needs_base_url":false,"default_model":"gpt-4o","description_en":"Use a GitHub Copilot subscription for title parsing via the device-flow login.","description_zh":"通过 device flow 登录，用 GitHub Copilot 订阅解析标题。","risk_notice_en":"Copilot's internal endpoint is for official clients only; third-party use may violate GitHub's terms and trigger abuse detection. Use at your own risk.","risk_notice_zh":"Copilot 内部端点仅供官方客户端使用，第三方调用可能违反 GitHub 条款并触发滥用检测。请自担风险。"},"isInternal":false,"tokens":242,"sizeBytes":793}],"systemPromptSnippet":"<yakaai_skills repo=\"EstrellaXD/Auto_Bangumi\">\n<!-- File: CLAUDE.md (Tokens: ~2001 | Category: claude-rule) -->\n# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nAutoBangumi is an RSS-based automatic anime downloading and organization tool. It monitors RSS feeds from anime torrent sites (Mikan, DMHY, Nyaa), downloads episodes via qBittorrent, and organizes files into a Plex/Jellyfin-compatible directory structure with automatic renaming.\n\n## Development Commands\n\n### Backend (Python)\n\n```bash\n# Install dependencies\ncd backend && uv sync\n\n# Install with dev tools\ncd backend && uv sync --group dev\n\n# Run development server (port 7892, API docs at /docs)\ncd backend/src && uv run python main.py\n\n# Run tests\ncd backend && uv run pytest\ncd backend && uv run pytest src/test/test_xxx.py -v  # run specific test\n\n# Linting and formatting\ncd backend && uv run ruff check src\ncd backend && uv run black src\n\n# Add a dependency\ncd backend && uv add <package>\n\n# Add a dev dependency\ncd backend && uv add --group dev <package>\n```\n\n### Frontend (Vue 3 + TypeScript)\n\n```bash\ncd webui\n\n# Install dependencies (uses pnpm, not npm)\npnpm install\n\n# Development server (port 5173)\npnpm dev\n\n# Build for production\npnpm build\n\n# Type checking\npnpm test:build\n\n# Linting and formatting\npnpm lint\npnpm lint:fix\npnpm format\n```\n\n### Docker\n\n```bash\ndocker build -t auto_bangumi:latest .\ndocker run -p 7892:7892 -v /path/to/config:/app/config -v /path/to/data:/app/data auto_bangumi:latest\n```\n\n## Architecture\n\n```\nbackend/src/\n├── main.py                 # FastAPI entry point, mounts API at /api\n├── module/\n│   ├── api/               # REST API routes (v1 prefix)\n│   │   ├── auth.py        # Authentication endpoints\n│   │   ├── bangumi.py     # Anime series CRUD\n│   │   ├── rss.py         # RSS feed management\n│   │   ├── config.py      # Configuration endpoints\n│   │   ├── program.py     # Program status/control\n│   │   └── search.py      # Torrent search\n│   ├── core/              # Application logic\n│   │   ├── context.py     # AppContext composition root (built in create_app, on app.state.ctx)\n│   │   ├── scheduler.py   # PeriodicTask + Scheduler (generic background-loop runner)\n│   │   ├── loops.py       # The individual periodic tick functions (rss/rename/offset/calendar)\n│   │   └── offset_scanner.py\n│   ├── models/            # SQLModel ORM models (Pydantic + SQLAlchemy)\n│   ├── database/          # Async DB (aiosqlite) — repos + Database + migrations.py\n│   ├── rss/               # RSS parsing and analysis\n│   ├── downloader/        # qBittorrent integration\n│   │   ├── base.py        # Downloader Protocol + DownloaderCapabilities\n│   │   └── client/        # Download client implementations (qb, aria2, mock)\n│   ├── searcher/          # Torrent search providers (Mikan, DMHY, Nyaa)\n│   ├── parser/            # Torrent name parsing, metadata extraction\n│   │   └── analyser/      # TMDB, Mikan, OpenAI parsers\n│   ├── manager/           # File organization and renaming\n│   ├── notification/      # Notification plugins (Telegram, Bark, etc.)\n│   ├── conf/              # Configuration management, settings\n│   ├── network/           # HTTP client utilities\n│   └── security/          # JWT authentication\n\nwebui/src/\n├── api/                   # Axios API client functions\n├── components/            # Vue components (basic/, layout/, setting/)\n├── pages/                 # Router-based page components\n├── router/                # Vue Router configuration\n├── store/                 # Pinia state management\n├── i18n/                  # Internationalization (zh-CN, en-US)\n└── hooks/                 # Custom Vue composables\n```\n\n## Key Data Flow\n\n1. RSS feeds are parsed by `module/rss/` to extract torrent information\n2. Torrent names are analyzed by `module/parser/analyser/` to extract anime metadata\n3. Downloads are managed via `module/downloader/` (qBittorrent API)\n4. Files are organized by `module/manager/` into standard directory structure\n5. Periodic loops (`module/core/loops.py`) run under a `Scheduler` owned by the lifespan `AppContext` (`module/core/context.py`)\n\n## Architecture conventions (3.3+)\n\n- **Async DB throughout.** Everything runs on the async engine (`sqlite+aiosqlite`, WAL). Repositories (`database/{bangumi,rss,torrent,user,passkey}.py`) take an `AsyncSession` and are `async def`. `Database` is an async context manager owning one session with the repos attached (`db.rss`, `db.bangumi`, …).\n- **Session per operation.** Get a session via `Depends(get_db)` in routes, or `async with Database() as db:` in loops/services. Never store a session on anything that outlives one request or one loop tick. `AppContext` holds no session.\n- **Services take dependencies in their constructor** (composition, not inheritance): `RSSEngine(db)`, `TorrentManager(db)`, `Renamer(client)`, `SearchTorrent()`. They use `self.db.<repo>` internally; callers that only need a repo use `db.<repo>` directly.\n- **Downloaders** implement the `Downloader` Protocol and declare `DownloaderCapabilities`; the facade (`DownloadClient`) skips-and-logs unsupported ops rather than crashing. The qB client is reused across operations (one login), not re-authed per call.\n- **Config reloads** go through `AppContext.reload_settings()` (settings + http client + notifier + scheduler), not ad-hoc `settings.load()`.\n\n## Code Style\n\n- Python: Black (88 char lines), Ruff linter (E, F, I rules), target Python 3.10+\n- TypeScript: ESLint + Prettier\n- Run formatters before committing\n\n## Git Branching\n\n- `main`: Stable releases only\n- `X.Y-dev` branches: Active development (e.g., `3.2-dev`)\n- Bug fixes → PR to current released version's `-dev` branch\n- New features → PR to next version's `-dev` branch\n\n## Releasing\n\nAll releases are triggered by manually pushing a tag — merging a PR never releases.\n\n### Beta Version\n\n1. Update version in `backend/pyproject.toml`\n2. Update `CHANGELOG.md` with the new version heading\n3. Commit and push to the dev branch\n4. Create and push a tag with the version name (e.g., `3.2.0-beta.4`):\n   ```bash\n   git tag 3.2.0-beta.4\n   git push origin 3.2.0-beta.4\n   ```\n5. The CI/CD workflow (`.github/workflows/build.yml`) detects the tag contains \"beta\", uses the tag name as the VERSION string, generates `module/__version__.py`, and builds the Docker image (tagged `<version>` + `dev-latest`)\n\n### Stable Version\n\n1. Merge the dev branch into `main` via PR (this only runs tests and a build test)\n2. Tag the merge commit on `main` with the bare semver version and push:\n   ```bash\n   git tag 3.3.2 <merge-commit-on-main>\n   git push origin 3.3.2\n   ```\n3. CI validates the tag is `X.Y.Z` **and** points to a commit on `main` (refuses otherwise), then builds and pushes Docker images (tagged `<version>` + `latest`) and creates the GitHub release with notes from `docs/changelog/<X.Y>.md`\n\nThe VERSION is injected at build time via CI — `module/__version__.py` does not exist in the repo. At runtime, `module/conf/config.py` imports it or falls back to `\"DEV_VERSION\"`.\n\n## Database Migrations\n\nSchema migrations are tracked via a `schema_version` table in SQLite. To add a new migration:\n\n1. Append a `Migration(version, \"description\", (…SQL…), already_applied=column_exists(\"table\", \"col\"))` entry to the `MIGRATIONS` tuple in `backend/src/module/database/migrations.py` (`CURRENT_SCHEMA_VERSION` is derived from the list — do not edit it by hand)\n2. Provide an `already_applied` guard (`column_exists` / `table_exists`) so a schema created out-of-band is detected and skipped\n3. Migrations run automatically on startup via `run_migrations()` (each in a SAVEPOINT, stopping on first failure)\n\n## Notes\n\n- Documentation and comments are in Chinese\n- Uses SQLModel (hybrid Pydantic + SQLAlchemy ORM)\n- External integrations: qBittorrent API, TMDB API, OpenAI API\n- Version tracked in `/config/version.info` (for cross-version upgrade detection)\n\n<!-- File: plugins/codex-chatgpt/plugin.json (Tokens: ~266 | Category: plugin-manifest) -->\n{\n  \"schema\": 1,\n  \"id\": \"codex-chatgpt\",\n  \"name\": \"ChatGPT (Codex)\",\n  \"version\": \"1.0.0\",\n  \"min_ab_version\": \"3.3.0\",\n  \"entry\": \"ab_llm_codex.adapter:CodexChatgptAdapter\",\n  \"auth_kind\": \"device_code\",\n  \"needs_base_url\": false,\n  \"default_model\": \"gpt-5.1-codex\",\n  \"description_en\": \"Use a ChatGPT Plus/Pro subscription for title parsing via the Codex device-flow login.\",\n  \"description_zh\": \"通过 Codex device flow 登录，用 ChatGPT Plus/Pro 订阅解析标题。\",\n  \"risk_notice_en\": \"ChatGPT subscription credentials are scoped to the official Codex client; third-party use is unsanctioned and may be blocked. Use at your own risk.\",\n  \"risk_notice_zh\": \"ChatGPT 订阅凭据被限定到官方 Codex 客户端，第三方使用未获许可、可能被封锁。请自担风险。\"\n}\n\n<!-- File: plugins/github-copilot/plugin.json (Tokens: ~242 | Category: plugin-manifest) -->\n{\n  \"schema\": 1,\n  \"id\": \"github-copilot\",\n  \"name\": \"GitHub Copilot\",\n  \"version\": \"1.0.0\",\n  \"min_ab_version\": \"3.3.0\",\n  \"entry\": \"ab_llm_copilot.adapter:GithubCopilotAdapter\",\n  \"auth_kind\": \"device_code\",\n  \"needs_base_url\": false,\n  \"default_model\": \"gpt-4o\",\n  \"description_en\": \"Use a GitHub Copilot subscription for title parsing via the device-flow login.\",\n  \"description_zh\": \"通过 device flow 登录，用 GitHub Copilot 订阅解析标题。\",\n  \"risk_notice_en\": \"Copilot's internal endpoint is for official clients only; third-party use may violate GitHub's terms and trigger abuse detection. Use at your own risk.\",\n  \"risk_notice_zh\": \"Copilot 内部端点仅供官方客户端使用，第三方调用可能违反 GitHub 条款并触发滥用检测。请自担风险。\"\n}\n</yakaai_skills>"}