Commit Graph

23 Commits

Author SHA1 Message Date
Estrella Pan
f2875d9870 chore: release 3.3.0-beta.8
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pz1EmcTPzjgEpkGQWzb8AQ
2026-07-07 11:38:00 +02:00
Estrella Pan
c1a0cf8559 perf(docker): shrink image 208MB -> 160MB
Two changes, verified with local builds:

- Drop UV_COMPILE_BYTECODE=1: shipped .pyc files were 51MB. The venv is
  root-owned and the app runs long-lived as 'ab', so bytecode only saved
  a few seconds of import time once per container start. This also
  matches the boot_overlay uv-sync path, which never compiled bytecode.
- mcp[cli] -> mcp: the app only imports mcp.server; the cli extra pulled
  typer/rich/pygments/markdown-it (~14MB) for an unused console script.
  python-dotenv, the extra's other member, is already a direct dep.

Compressed pull size drops 64.2MB -> 48.8MB. Image verified: packages
absent, no __pycache__, 'import main' succeeds; pytest and mypy green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XEnmRvBJL93fAURbRf1koK
2026-07-07 10:13:51 +02:00
Estrella Pan
c19da52497 chore: release 3.3.0-beta.7
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FAxVyRwrY7z5NotTtgnwVs
2026-07-06 16:38:20 +02:00
Estrella Pan
1dc1eb01b4 chore: release 3.3.0-beta.5
Bump version, uv lock, and CHANGELOG for 3.3.0-beta.5 — ships the
overlayfs EXDEV fix for in-app updates (needs a fresh image to take
effect) and moves the Software Update card into Settings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FAxVyRwrY7z5NotTtgnwVs
2026-07-05 12:31:12 +02:00
Estrella Pan
685711d927 chore: release 3.3.0-beta.4
Bump version, uv lock, and CHANGELOG for 3.3.0-beta.4 — bundles the login
redirect fixes, the container-startup optimizations, and the update-check
feedback improvement.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FAxVyRwrY7z5NotTtgnwVs
2026-07-05 09:42:42 +02:00
Estrella Pan
9a0347cb95 chore: release 3.3.0-beta.3
Bump version, uv lock, and CHANGELOG for the 3.3.0-beta.3 beta.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FAxVyRwrY7z5NotTtgnwVs
2026-07-04 07:42:10 +02:00
Estrella Pan
c8f402fd68 chore: bump version to 3.3.0-beta.2
CHANGELOG: fold the unreleased in-app updater + multi-provider LLM
entries into 3.3.0-beta.2 and add the WebUI UX/a11y/perf pass and
post-review backend fixes. docs/changelog/3.3.md (the release body)
gains the beta.2 highlights.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FAxVyRwrY7z5NotTtgnwVs
2026-07-03 16:23:38 +02:00
Estrella Pan
27c04f5f5d feat(update): sign update bundles (ed25519) and stop root uv sync (P1)
Closes the update-chain trust gap: the sha256 came from the same GitHub
release as the bundle (integrity, not authenticity), and the boot overlay
re-applied ab-writable content as root — including uv sync on an
attacker-controllable lockfile.

- signing: new module/update/signing.py verifies an ed25519 signature;
  public key embedded in the image at /app/ab_update_pubkey.pem (outside
  the overlay-replaceable tree, so it is the trust root). Private key lives
  only in CI (UPDATE_SIGNING_KEY secret).
- updater: discover the .zip.sig asset, verify the signature after the
  sha256 check, reject any release without a signature, retain the verified
  bundle.zip+.sig for boot re-verification, and swap them on rollback.
- boot_overlay: re-verify the signed bundle at every boot and extract the
  module tree / webui dist FROM the verified zip — never from the
  ab-writable current/ tree; read the version from the zip manifest, not
  the ab-writable applied.json; drop to the ab user before any fallback
  uv sync so lockfile build hooks can't run as root; zip-slip guard uses
  is_relative_to (also fixed in updater._safe_extract).
- CI: build.yml signs the bundle with UPDATE_SIGNING_KEY and publishes the
  .zip.sig; the build fails if the secret is unset.
- deps: cryptography made an explicit dependency.

Tests cover bad-signature reject, unsigned-release reject, legacy overlay
without a signed bundle reject, verified-bundle retention, and boot-overlay
signature verification. Full backend suite: 1079 passed.

Ops: run `gh secret set UPDATE_SIGNING_KEY < ~/.autobangumi/update-signing-key.pem`
before the 3.3 release.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FAxVyRwrY7z5NotTtgnwVs
2026-07-03 11:15:03 +02:00
Estrella Pan
93d3f1a947 feat(parser): multi-provider LLM parser with selectable fallback/primary mode
Generalizes the OpenAI-only title parser into a provider-dispatching
LLMParser (openai-compatible / Anthropic / Gemini) with a parse-mode
switch:

- fallback (default): regex parser runs first, LLM only rescues titles
  the regex can't handle — minimal LLM spend
- primary: LLM parses every title first, regex is the safety net so no
  title is dropped on LLM failure

The openai provider takes a base_url, covering any OpenAI-compatible
endpoint (DeepSeek, Ollama, LM Studio, OpenRouter, OneAPI). Anthropic
uses structured JSON output with refusal handling; Gemini uses
response_mime_type=application/json.

Config auto-migrates the legacy experimental_openai section into a new
llm section on load (migrated users get mode=primary, preserving their
original LLM-first behavior); the old section is kept for downgrade
safety and llm.api_key is redacted by the config API. Settings page
swaps the OpenAI panel for an LLM panel with provider + mode selects.

1018 backend tests, mypy 0, ruff clean; 131 frontend tests, vue-tsc clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTnuEgR78cBk32bLNKar3z
2026-07-03 08:51:01 +02:00
Estrella Pan
820ff29537 refactor(security): migrate JWT/password hashing from jose+passlib to pyjwt+bcrypt
Drop python-jose and passlib in favor of direct pyjwt (with pinned
decode algorithm) and bcrypt 4.x hashpw/checkpw calls. Existing
passlib-generated $2b$ hashes keep validating unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTnuEgR78cBk32bLNKar3z
2026-07-02 18:58:22 +02:00
Estrella Pan
4d7104ca7f chore: bump version to 3.3.0 and add changelog for the architecture refactor
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014w1Z6Nxy6XTRgkFXqPr9Zh
2026-07-02 15:06:42 +02:00
Estrella Pan
ded24b10da fix(downloader): fix qBittorrent SSL connection and rename verification (#923)
- Decouple HTTPS scheme selection from TLS certificate verification:
  `verify=False` always, since self-signed certs are the norm for
  home-server/NAS/Docker qBittorrent setups
- Bump connect timeout from 3.1s to 5.0s for slow TLS handshakes
- Add actionable error messages when HTTPS connection fails
- Fix `continue` → `break` bug in torrents_rename_file verification loop
- Consolidate json imports to top-level
- Add 31 unit tests for QbDownloader constructor, auth, and error handling

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 19:52:50 +01:00
Estrella Pan
b57d3c49ae feat(security): add security config UI and improve auth/MCP security
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 17:19:14 +01:00
Estrella Pan
e82e6ab128 fix(ui): fix auth routing, i18n init, and component lifecycle issues
- useAuth: replace watcher with explicit router.replace on login/logout
- useMyI18n: create single i18n instance at module level (avoid dupes)
- usePasskey: detect WebAuthn support synchronously (no onMounted)
- main.ts: import i18n from hook module instead of calling composable
- ab-add-rss: hoist useApi composables outside functions to avoid
  recreating them on each call
- calendar: prevent duplicate refreshes when already refreshing
- downloader: guard interval polling against stale activation state
- router: only mark setupChecked on successful status check
- log store: stop SSE log updates on logout
- i18n: add missing "edit" translation key (en + zh-CN)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 11:46:56 +01:00
Estrella Pan
fb2dd17c0c feat(mcp): add MCP server for LLM tool integration via SSE
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 16:42:39 +01:00
Estrella Pan
5f604e94fd perf(logging): optimize logging with rotation, async I/O, and lazy formatting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 14:10:56 +01:00
Estrella Pan
3146029d0b fix: add socksio dependency to support SOCKS proxy (#961)
When users have a SOCKS proxy configured (via HTTP_PROXY or ALL_PROXY
environment variables), httpx's AsyncClient automatically tries to use
it but fails without the socksio package installed.

Changed httpx dependency from httpx>=0.25.0 to httpx[socks]>=0.25.0 to
include the socksio package as an extra dependency.

Fixes #961

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-01-27 06:42:03 +01:00
EstrellaXD
7b5c8d9ac5 chore: upgrade Python version to 3.13
- Update requires-python to >=3.13 in pyproject.toml
- Update ruff and black target versions to py313
- Update Dockerfile to use python:3.13-alpine
- Add explicit Python 3.13 setup in CI workflow
- Regenerate uv.lock for Python 3.13

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 16:30:25 +01:00
EstrellaXD
f22f5c657f fix(test): correct TypeScript types in frontend test mocks
- Use RSS type instead of non-existent RSSItem/RSSResponse
- Add expire field to mockLoginSuccess
- Replace offset with episode_offset/season_offset in mockBangumiAPI
- Add needs_review_reason field to mockBangumiAPI
- Add missing RSS fields (connection_status, last_checked_at, last_error)
- Fix generic types in test utilities

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 16:24:31 +01:00
Estrella Pan
c044b65fef chore: bump version to 3.2.0-beta.9
Fix TypeScript error in ab-search-bar.vue and include pending changes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 19:29:12 +01:00
Estrella Pan
929a88c343 test: add comprehensive test suite for core business logic
Cover RSS engine, downloader, renamer, auth, notifications, search,
config, API endpoints, and end-to-end integration flows. When all
210 tests pass, the program's key behavioral contracts are verified.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-01-24 18:59:18 +01:00
Estrella Pan
a98a162500 feat: fix search, poster serving, and add hover overlay UI for cards
- Fix search store exports to match component expectations (inputValue,
  bangumiList, onSearch) and transform data to SearchResult format
- Fix poster endpoint path check that incorrectly blocked all requests
- Add resolvePosterUrl utility to handle both external URLs and local paths
- Move tags into hover overlay on homepage cards and calendar cards
- Show title and tags on poster hover with dark semi-transparent styling
- Add downloader API, store, and page
- Update backend to async patterns and uv migration changes
- Remove .claude/settings.local.json from tracking

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 21:20:12 +01:00
EstrellaXD
9c5474d8e9 feat: migrate backend to uv package manager
Replace pip + requirements.txt with uv for dependency management.

- Multi-stage Dockerfile using ghcr.io/astral-sh/uv builder image
- CI updated to use astral-sh/setup-uv@v4
- Ruff config moved to [tool.ruff.lint] (fixes deprecation)
- Transitive deps removed, missing direct deps added (requests, PySocks, urllib3)
- Database layer migrated to async (AsyncSession + aiosqlite)
- Tests updated to match async database interface

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 12:56:23 +01:00