Skip to content

Releases: felixapel/book-translator-hub

v2.5.2 — localized settings-menu position controls and publication docs

Choose a tag to compare

@felixapel felixapel released this 26 Oct 11:23

Container image: ghcr.io/felixapel/cwa-ebook-translate-plugin:2.5.2@sha256:50abc0560627757d06871be3665fb1660e08497a4d91e57928dd161bc8c45c02 (amd64, SBOM and provenance attached).

Changed

  • Documentation: Kavita 0.9.1.4 with stock OIDC login and the managed hub on Unraid 7.3.4 are recorded as browser-accepted. The README no longer claims a multi-architecture image (it is linux/amd64 only) or a bug-bounty programme. Malformed configuration-table rows were fixed and their examples use a generic LAN address. The pull request template moved to .github/pull_request_template.md, so GitHub and Gitea apply it by default. The unused docs/assets/demo.gif from the project's former name was removed.
  • The README leads with a real screenshot of the stock CWA reader in bilingual mode (a public-domain book translated by a local model) instead of a concept illustration, and adds a features list, an at-a-glance table and install prerequisites.

Fixed

  • The settings menu's position controls showed hard-coded Spanish whatever the interface language ("↕ Mover a Top", "Libre (arrastrada)"). They are now translated in all five interface languages.

v2.5.1 — exact edge trust, Unraid exclusive shares and cache/stream fixes

Choose a tag to compare

@felixapel felixapel released this 25 Oct 19:52

Container image: ghcr.io/felixapel/cwa-ebook-translate-plugin:2.5.1@sha256:9bca080f605a72b1f840375a0708bc3dd7ccfc7c75cfbdb23427a8a4c1ac756e (amd64, SBOM and provenance attached).

Fixed

  • Bumped the Alpine packages that Alpine withdrew after the 2.5.0 candidate, so the images build again from a clean cache: nginx 1.30.6-r0 in the runtime image, and brotli-libs 1.2.1-r0, c-ares 1.34.9-r0, libcurl 8.23.0-r0 (also in the embedded btctl bootstrap Dockerfile), docker-cli 29.9.2-r0 and docker-cli-buildx 0.38.1-r0 in Dockerfile.btctl. The v2.5.0 tag exists, but its runtime image could not be built, so no 2.5.0 image was published; 2.5.1 ships the 2.5.0 changes below.

Included from 2.5.0 (tagged, no image published)

Added

  • Optional BT_EDGE_TRUSTED_PROXIES trusts at most 32 exact operator-controlled immediate edge IPs at nginx, so browsers behind that edge have separate pre-auth admission keys. Empty configuration keeps socket-peer forwarding and existing managed fingerprints. Reader/API/session routes share one address and exact User-Agent; identity assertions are consistently stripped. Enabling, changing or clearing trust requires a new reader login and translator session. Split, hub and standalone Compose inputs are supported, with actual-nginx and native Chromium contract tests; external proxy and physical stock-reader acceptance remain release gates.

Changed

  • Removed the overlay's unused streaming client code. The bundled overlay translates through /translate/batch; /translate/stream remains an API endpoint. The README, architecture and Community Applications guides now describe that behavior, and the Community Applications guide no longer contradicts its own boundary: the profile proxies CWA only and does not publish API port 8390.
  • Documented that behind an operator reverse proxy with empty edge trust all readers share one pre-auth admission budget (BT_AUTH_RATE_LIMIT_PER_MINUTE, BT_AUTH_MAX_INFLIGHT_PER_CLIENT), in ADR-006, troubleshooting and the configuration reference. The configuration reference now also lists BT_SESSION_COOKIE_NAME, BT_API_PORT and the glossary/feedback limits, and states that HTTP translation requests do not use singleflight coalescing. The README and architecture guide no longer claim that the server can enable browser persistence of translated text.
  • /stats no longer prunes. It ran cache expiry and the full cap scan as a write transaction on every uncached call, which any authenticated reader could repeat through a rate-limit-exempt route. Retention still runs on the write watermark, and /stats counts only unexpired rows, matching cache reads.
  • /translate and /translate/stream load the book glossary once per request instead of twice, and a cache lookup probes the single-text contract once when it equals the one-paragraph batch contract.
  • Startup logs a warning when BT_LOCAL_URL resolves only to public addresses, because the reader labels that provider local and uses it as a fallback without remote-fallback consent.

Security

Fixed

  • Unraid exclusive shares no longer break btctl. With Permit exclusive shares enabled, Unraid turns /mnt/user/<share> into the link ../<pool>/<share>, and every lifecycle command rejected paths below it: the dispatcher refused the environment file ("must use one canonical path without symbolic components") and the mount planner refused BT_STATE_DIR ("Unraid share must be one real directory"). btctl now follows only that exact link. It validates the pool directory, compares overlaps on pool paths and binds the pool path to the configured /mnt/user path, so the operator, state and Docker binds keep the configured paths. Every other symbolic link is still refused. The stock-Unraid mount plan protocol is now version 3.
  • BT_EDGE_TRUSTED_PROXIES accepts IPv4 peers only and rejects unspecified and multicast addresses. The reader listener is IPv4-only, so IPv6 peers and these addresses matched no immediate peer and left trust silently off. A retained managed configuration or environment that contains one of them now stops btctl and the hub with a configuration error; remove the entry. The proxy now warns at startup when a trusted peer is the container's own default gateway: Docker relays host and other-network connections to a published port from that address, so trusting it let them choose their client address. The configuration reference and ADR-021 describe how to trust only the edge.
  • Bumped the pinned Alpine packages in Dockerfile.btctl after Alpine withdrew the old builds: libexpat 2.9.0-r0 (also in the embedded btctl bootstrap Dockerfile), docker-cli 29.8.2-r1 and docker-cli-buildx 0.34.1-r2. libexpat 2.8.5-r0 was no longer served, which broke the docker-smoke bootstrap step on every branch.
  • Managed hub configuration retains a custom CWA login header across restarts and includes it in the deployment fingerprint. All proxy routes strip that assertion; shared validation rejects names that collide with managed context or credentials, including User-Agent.
  • A one-paragraph translation group is cached under a contract that includes the book glossary. The first visible paragraph is such a group, so adding or changing a glossary term previously kept serving its cached pre-glossary translation, and translations made with a glossary were stored under the no-glossary key. Entries already stored that way remain reachable only if the book's glossary is emptied again.
  • /translate/stream with an Anthropic-protocol provider (Anthropic, MiniMax) no longer waits for a second upstream slot while holding the first. With BT_MAX_UPSTREAM_INFLIGHT=1 every such request failed with work_budget_exhausted, and two concurrent requests blocked each other until the queue timeout.
  • A provider stream that fails after sending part of a translation now ends with provider_stream_interrupted instead of appending a complete fallback translation to the partial text and caching the result. Failures before the first delta still use an eligible fallback, and HTTP failures follow the same retry, fallback and provider_rate_limited policy as non-streamed calls.
  • Glossary terms and paragraph ratings are capped per reader across all books (BT_GLOSSARY_MAX_TENANT_ENTRIES, default 5000; BT_FEEDBACK_MAX_TENANT_ENTRIES, default 50000). The existing caps were per book, and book ids are client metadata, so one reader could grow both tables without bound. Each cap check and write now runs in one transaction.
  • CI, the release gate and the maintainer guides discover the Python suite as the tests.python package (-s tests/python -t .). Top-level discovery skipped the package's DB_PATH redirect, so the 2.4.2 fix did not apply to the main suite run: it still wrote translations.db into the checkout, and a reused file made database-backed tests depend on earlier runs.
  • The combined BT_ROLE=all container (Community Applications profile) serves the API on 127.0.0.1 only. It listened on all interfaces, so another container on the same Docker network could call the API directly instead of through the proxy.
  • Removed the overlay's IndexedDB copy of opt-in persisted translations (BookTranslatorDB). It grew without eviction, was loaded whole on every page, and "Clear all cache" did not reach it. The overlay now deletes that database on load; opt-in persistence keeps the bounded per-language localStorage cache, and the server cache is unchanged.
  • A leading <think>…</think> block from a reasoning model served without a reasoning parser is no longer cached or shown as the translation, in single, batch and streamed responses. Streams hold that block back, within the response byte cap, instead of emitting it, and a block that never closes is rejected as an invalid provider response. Cached translations that start with such a block read as misses and are replaced by the next translation. Output is left unchanged when the source paragraph itself contains <think>.
  • Opt-in browser persistence starts a fresh cache generation and removes the prior generation, so reasoning saved before the provider fix cannot bypass sanitized backend results by being displayed or exported from browser storage. Fresh translations preserve literal <think> source text.
  • EPUB export drops characters that XML 1.0 cannot represent (for example a form feed carried over from the source book), which previously produced a chapter readers could not open. Every selectable target language now has its own dc:language tag instead of 82 of them falling back to en, and the chapter declares the same language in lang/xml:lang.
  • Streamed translations are stripped and must be non-empty before they are cached, so they match non-streamed provider output. Streamed responses are closed when the stream ends, a single SSE line is bounded by BT_MAX_UPSTREAM_RESPONSE_BYTES, and openai-compatible streams connect only to the per-attempt vetted public addresses.

v2.4.2 — Werkzeug security update and startup config validation

Choose a tag to compare

@felixapel felixapel released this 06 Oct 07:49

Changed

  • The Community Applications profile and the managed hub are browser-accepted with CWA 4.0.8.

Security

  • Updated Werkzeug to 3.1.9 (CVE-2026-102598) and the development-only source-map-js to 1.2.2 (GHSA-68fv-2mgg-jv7q, event-loop denial of service). The v2.4.1 runtime image ships Werkzeug 3.1.8.

Fixed

  • Numeric BT_* settings now fail startup with the variable's name when they are malformed, and the previously unchecked limits (BT_TIMEOUT, BT_MAX_CONCURRENT, token ceilings, paragraph, scope, content-length, glossary and feedback caps) reject zero or negative values instead of failing later at request time.
  • The Python test suite no longer writes translations.db into the checkout.

v2.4.1 — Stable reader tenants, auth and supply-chain fixes

Choose a tag to compare

@felixapel felixapel released this 05 Oct 18:52

Changed

  • Corrected the public installation, provider-default, compatibility and
    performance documentation to match the managed local-provider template and
    bounded runtime contracts.
  • Moved external reverse-proxy guidance to a superseding decision record; it
    is not a managed or certified deployment topology.
  • Historical performance and offline-cache statements describe the work at the
    time of those releases; they are not latency, availability or browser-storage
    guarantees for a new deployment.
  • Every CWA and Kavita reader entry and page reload starts with translation
    OFF, even when an older mode is stored; book text is sent only after manual
    activation. OFF skips paragraph scans and content observation.
  • Reader asset URLs are versioned from VERSION plus the packaged overlay
    files, so the one-year immutable cache cannot keep stale JavaScript or CSS
    between builds that share a version. Missing packaged assets fail startup.

Fixed

  • The reader proxy now re-resolves a named reader upstream through the container's DNS servers from /etc/resolv.conf (Docker's 127.0.0.11 on user-defined networks) instead of once at nginx startup, so recreating CWA or Kavita (new container IP) no longer leaves the hub returning 502 until it is restarted. IP literals and names that exist only in /etc/hosts (such as host.docker.internal from extra_hosts) keep a static proxy_pass, because nginx's runtime resolver cannot see them.
  • Bumped the pinned Alpine libexpat in Dockerfile.btctl and the embedded btctl bootstrap Dockerfile to 2.8.5-r0; Alpine no longer serves 2.8.4-r0, which broke the docker-smoke bootstrap step.
  • Restored image builds after Alpine 3.24 withdrew more pinned packages: the runtime image now pins libcrypto3/libssl3 3.5.9-r0 and pcre2 10.49-r0; the operator image and embedded bootstrap pin pcre2 10.49-r0, nghttp2-libs 1.70.0-r0 and docker-cli 29.8.2-r0.
  • Managed CWA readers keep one cache and glossary tenant per CWA user. CWA re-signs its session cookie on every response, so the previous cookie-hash tenant changed on every session exchange: server cache hits lasted at most five minutes and per-book glossaries disappeared. Cookies that name a user are now probed one at a time and the tenant follows the proven user id (ADR-020).
  • The cwa_session authentication mode (Community Applications profile and reference Compose) keeps one cache and glossary tenant per CWA user. Its tenant was a hash of the CWA cookies, which CWA re-signs on every response, so it changed on almost every request. It now uses the same single-cookie user identity as managed readers, keyed by a private cwa_tenant_key beside DB_PATH and scoped to BT_CWA_AUTH_URL.
  • Cache and glossary tenants of managed installs now survive btctl reinstall and upgrade. Subjects were keyed by reader_session_key, which uninstall deletes to revoke browser sessions, so every hub upgrade orphaned all existing tenants. They now use a private tenant_key kept with the translation data; an install restarted in place seeds it from its current session key. Upgrading from a 2.4.0 runtime via uninstall/install still starts new tenants once. Split and Unraid installs keep their tenants too: the subject is scoped to the reader's authority URL instead of the connector id, which they regenerate per install.
  • Enforced exact Origin, CSRF and CORS boundaries for managed reader-session
    exchange, and covered the exact Origin path in the Community Applications
    smoke gate.
  • Prevented stale translation state across reader navigation, iframe
    replacement and saved-preference changes.
  • Fixed setTargetLanguage scope in frontend script (static/translator.js)
    preventing runtime ReferenceError on dynamic target language switching.
  • Completed IndexedDB cache write path (persistToIndexedDB) to persist cached
    book chapters asynchronously across reader sessions.
  • Propagated HTTP stream errors immediately via raise_for_status() on
    /translate/stream to prevent stalled SSE requests.
  • Hardened RFC 6265 cookie header tokenization in reader_session.py against
    malformed, quoted, or trailing semicolons in upstream authentication headers.
  • Hardened cross-platform filesystem locking, permissions, and directory flushing
    in btctl_core.py and test contracts for Windows environments.
  • Kept the exact Kavita 0.9.1.4 native-account fixture contract explicit;
    it does not establish public-browser or OIDC acceptance.
  • Kept hub smoke response headers in a runner-owned temporary file and accepted
    equivalent Docker tmpfs-size representations during managed hub validation.
  • Pinned patched OpenSSL and libuuid runtime packages.
  • CWA no longer translates earlier clipped columns, waits for a page turn
    after delayed content, or jumps backward when translation reflows the
    chapter; admission and rendering are limited to visible source nodes.
  • Calibre tables of contents (div.calibre1 > ul > li > a) are translated
    link by link while keeping their destinations.

Security

  • Upgraded urllib3 to 2.8.0 (PYSEC-2026-4175, PYSEC-2026-4176, PYSEC-2026-4177) and the jsdom test dependency undici to 8.11.2, so the pip-audit and npm audit gates pass again.
  • Removed the unreferenced legacy deploy/unraid/my-book-translator-hub.xml example. It published API port 8390 with BT_AUTH_MODE=disabled and BT_ALLOW_INSECURE_AUTH=true by default, the exact topology the runtime boundary forbids. Managed installs use btctl; Community Applications uses the separate digest-pinned listing.
  • CWA reader-session exchange now ignores ambient browser cookies and forwards
    only selected CWA authentication cookies to its validation probe.

v2.4.0 — Streaming translation and reader controls

Choose a tag to compare

@felixapel felixapel released this 05 Sep 09:09

Book Translator Hub v2.4.0

This historical release introduced streamed translation, surrounding-paragraph context, EPUB language detection, and target-language controls for the reader overlay.

  • /translate/stream renders model output progressively, with buffered or cached fallback paths.
  • BT_CONTEXT_WINDOW controls how surrounding text is supplied as translation context.
  • Source-language detection uses available book metadata and text hints; readers can choose their target language.
  • The session broker exchanges supported reader credentials for short-lived hub sessions. Exact reader versions and authentication modes require their own acceptance checks.
  • Translation caching includes a server-side SQLite cache. Browser persistence is optional and subject to browser storage limits and configuration.

Corrections to the original announcement

These notes replace earlier unqualified claims about 160 ms latency, zero-wait page turns, universal Kavita compatibility, complete offline books, guaranteed isolation, and fully backward-compatible upgrades. They were not established release guarantees. Latency and translation quality depend on the model, hardware, workload, network, and cache state. Consult the documentation at the selected release tag and validate the complete reader flow before upgrading.

The immutable v2.4.0 tag and its source remain unchanged. Subsequent authentication, reader-navigation, and runtime hardening on the main branch are not part of this historical tag. Follow the repository pull requests and changelog for the next patch release and its acceptance status.

v2.3.2 — Instant Viewport Rush & Top-3 Paragraph Low-Latency Pipeline

Choose a tag to compare

@felixapel felixapel released this 04 Sep 14:16

[2.3.2] - 2026-09-04

Added

  • Instant Viewport Rush: First 1, 2, and 3 uncached visible paragraphs on every page are dispatched concurrently in parallel micro-requests directly to /translate.
  • Progressive Per-Paragraph Rendering: Each of the top 3 paragraphs appears in the reader DOM the instant its individual inference completes (~1.9s - 2.2s total for all 3 paragraphs).
  • Reader Navigation Keyboard Shortcuts: ArrowRight, ArrowLeft, PageDown, PageUp, Space with fast 80ms settle detection.
  • Cross-Endpoint Bidirectional Cache Interoperability: Single-paragraph translations saved by /translate are immediately recognized as cache hits by /translate/batch, and vice versa.

Fixed

  • Unblocked Page-Turn Detector: Background prefetching no longer freezes page turn recognition, allowing instant cancellation of background work to prioritize the reader's new visible page immediately.

v2.3.1 — Zero-Wait Directional Lookahead & SQLite MMAP Cache

Choose a tag to compare

@felixapel felixapel released this 04 Sep 14:16

[2.3.1] - 2026-09-04

Added

  • Zero-Wait Directional Lookahead Prefetch: Translates upcoming pages ahead of the reader for an instantaneous 0ms page-turn experience.
  • Directional Paragraph Queue Sorting: Visible viewport first, forward paragraphs next, backward paragraphs last.
  • Instant TTFT Initial Micro-Chunking: Micro-chunking for low-latency initial paragraph response.

Performance

  • High-Throughput SQLite WAL PRAGMAs: 256MB mmap, 64MB RAM page cache, and in-memory temp tables for sub-millisecond cache lookups.

v2.3.0 — Universal reader hub, adaptive batching & decoupled proxy

Choose a tag to compare

@felixapel felixapel released this 03 Sep 16:14

[2.3.0] - 2026-09-03

Added

  • Added draggable floating translator interface with pointer and touch events,
    viewport boundary clamping, quick-position controls, and persistent geometry
    stored in localStorage under bt_pos (ADR-018).
  • Added architectural support and guidance for master reverse proxy (SWAG)
    decoupling using HTTP sub_filter injection, allowing stock readers (CWA, Kavita)
    to stay online independently while the hub runs in pure API mode (BT_ROLE=api).
  • Configured Gunicorn worker heartbeat tmpdir to /dev/shm across standalone API
    and supervised hub runtimes to eliminate spurious heartbeat timeouts during heavy inference.
  • Pinned updated Alpine 3.24 dependencies in base container images and exporter
    bootstrap: pcre2=10.48-r0, libcurl=8.22.0-r0, and libexpat=2.8.4-r0.

Changed

  • Added managed cloud-oriented batching: a configurable browser/group maximum,
    an optional CJK-aware source-token budget, and background-only prefetch
    pacing reduce provider request pressure without delaying the first visible
    paragraph. Compatibility defaults retain count-only grouping.
  • Added sanitized provider rate-limit metadata, explicit pre-provider replay
    safety for HTTP 429, and fixed-cardinality provider/batch metrics. Ambiguous
    or provider-originated failures remain terminal until an explicit retry.
  • Documented the universal one-container hub as the default CWA/Kavita install,
    with explicit reader switches, topology-specific provider cutover and rollback,
    and split deployment retained as an advanced isolation option.
  • Made Gemini a complete server-side backend in quick-start examples using the
    stable gemini-3.5-flash-lite model; local vLLM and fallback providers are now
    described as optional instead of implied deployment requirements.
  • Expanded lifecycle, troubleshooting, compatibility and security guidance for
    hub operation, Gemini API errors, private key handling, regenerated browser
    sessions and per-reader isolation.
  • Moved generated Compose credentials into mode-0600 raw environment files,
    introduced split state schema 3, retained read-only doctor/uninstall support
    for former inline-environment schema 2, and required Docker Compose 2.30 or
    newer for new Compose installations.
  • Reduced reader latency with a one-paragraph first visible request followed by
    bounded five-paragraph batches, removed the unconditional client delay,
    reused fixed-provider HTTP connections per worker, and committed each cache
    batch in one SQLite transaction.
  • Added keyboard retry and settings-dialog focus management, bounded custom DNS
    resolver capacity, full discovered backend coverage, universal hub smoke and
    opt-in deep provider diagnosis.

Fixed

  • Normalized fresh universal-hub data directories before inspecting private
    reader credentials, so caller-owned mode-0700 paths work for non-root
    Compose and root Unraid while retained UID-101 keys remain distinguishable
    from credentials created by a failed install attempt.
  • Ran read-only hub credential and data verification as the owning runtime UID,
    allowing reinstall and non-root Compose operation to traverse retained
    mode-0700 reader directories without adding Docker capabilities.
  • Journaled universal-hub installs before persistent mutation, preserved exact
    cleaned retry evidence, removed only session keys created by a failed attempt,
    and surfaced cleanup failures instead of leaving an ambiguous partial runtime.
  • Corrected the immutable release sequence so the identical annotated tag is
    verified on the GitHub mirror before authoritative Gitea publication begins.
  • Added fixed-cardinality translation latency buckets so cloud batch tuning can
    observe tail movement without book, reader or request labels.
  • Propagated adaptive batching through both hub and split managed installs,
    rejected browser/API batch-limit mismatches before startup, made provider
    429 terminal before retry/fallback, and kept safe browser retry bounds and
    visible-work priority stable across reader DOM rediscovery.
  • Updated Gemini/OpenAI-compatible request contracts for current Gemini models,
    including omission of deprecated sampling fields and invalid prefilled model
    turns.

[2.3.0-rc.1] - Unreleased candidate

Security

  • Added a reader-neutral, five-minute maximum session broker. Raw CWA cookies,
    Kavita access tokens and exact Kavita OIDC cookie chunks are accepted only by
    the same-origin exchange route, validated against the pinned reader account
    endpoint, never persisted, and replaced with an opaque HttpOnly cookie bound
    to the connector, public origin, observed address and User-Agent.
  • Ordinary translation routes now strip bearer credentials and, in managed
    reader-session mode, every reader cookie. Provider HTTP clients ignore
    inherited proxy variables, expired cache rows are deleted on lookup, DOM
    restoration uses pristine clones, and uninstall removes the connector secret
    without removing translations.
  • Lifecycle mutation now binds execution to immutable plan inputs and journals
    recoverable install attempts before the first owned runtime mutation.
  • The managed v2.1.4 migration path now recognizes the exact historical
    Community Applications ghcr.io/felixapel/cwa-ebook-translate-plugin:latest
    reference only after the container's immutable image ID is probed in a
    network-disabled sandbox and reports version 2.1.4. Other mutable latest
    references remain rejected.

Changed

  • Managed reader preflight can now bind a mutable container tag to an explicit
    immutable Docker image ID; the install and doctor fail closed if that exact
    runtime image changes.
  • Generalized schema-2 lifecycle state, generated resources and browser
    contracts from CWA-specific fields to explicit stock-reader connectors while
    retaining schema-1 CWA compatibility.
  • Updated the pinned Alpine runtime closure to the exact packages still
    available for the immutable base image, including nginx 1.30.4-r1.
  • Replaced the accumulated, overlapping documentation set with one indexed
    guide hierarchy for installation, operations, reference material,
    maintainers, and durable architecture decisions.
  • Moved automated tests under tests/, live probes and benchmarks under
    tools/, and Python dependency inputs and hash locks under requirements/.
  • Narrowed the Docker build context to runtime inputs and removed obsolete
    systemd and legacy Unraid template artifacts from the supported tree.
  • Added repository guidance and documentation contracts so CI, contributor
    commands, release checks, and public docs stay aligned with the canonical
    layout.
  • Pinned the lock compiler's build frontend to a reviewed non-yanked release
    instead of retaining a withdrawn transitive candidate.

Added

  • Added a stock Kavita v0.9.0.2 EPUB connector for the exact
    /library/:libraryId/series/:seriesId/book/:chapterId route and
    .book-content DOM, including SPA teardown, route-derived cache scopes and
    one bounded session refresh/replay after 401.
  • Added unit, real-Chromium and real-container coverage for separate CWA/Kavita
    connectors, Kavita native authentication, unsupported manga/PDF isolation,
    credential stripping and reader-neutral lifecycle artifacts.

v2.3.0-rc.1 — Universal reader hub, adaptive batching & decoupled proxy

Choose a tag to compare

@felixapel felixapel released this 03 Sep 15:23

[2.3.0-rc.1] - 2026-09-03

Added

  • Added draggable floating translator interface with pointer and touch events,
    viewport boundary clamping, quick-position controls, and persistent geometry
    stored in localStorage under bt_pos (ADR-018).
  • Added architectural support and guidance for master reverse proxy (SWAG)
    decoupling using HTTP sub_filter injection, allowing stock readers (CWA, Kavita)
    to stay online independently while the hub runs in pure API mode (BT_ROLE=api).
  • Configured Gunicorn worker heartbeat tmpdir to /dev/shm across standalone API
    and supervised hub runtimes to eliminate spurious heartbeat timeouts during heavy inference.
  • Pinned updated Alpine 3.24 dependencies in base container images and exporter
    bootstrap: pcre2=10.48-r0, libcurl=8.22.0-r0, and libexpat=2.8.4-r0.

Changed

  • Added managed cloud-oriented batching: a configurable browser/group maximum,
    an optional CJK-aware source-token budget, and background-only prefetch
    pacing reduce provider request pressure without delaying the first visible
    paragraph. Compatibility defaults retain count-only grouping.
  • Added sanitized provider rate-limit metadata, explicit pre-provider replay
    safety for HTTP 429, and fixed-cardinality provider/batch metrics. Ambiguous
    or provider-originated failures remain terminal until an explicit retry.
  • Documented the universal one-container hub as the default CWA/Kavita install,
    with explicit reader switches, topology-specific provider cutover and rollback,
    and split deployment retained as an advanced isolation option.
  • Made Gemini a complete server-side backend in quick-start examples using the
    stable gemini-3.5-flash-lite model; local vLLM and fallback providers are now
    described as optional instead of implied deployment requirements.
  • Expanded lifecycle, troubleshooting, compatibility and security guidance for
    hub operation, Gemini API errors, private key handling, regenerated browser
    sessions and per-reader isolation.
  • Moved generated Compose credentials into mode-0600 raw environment files,
    introduced split state schema 3, retained read-only doctor/uninstall support
    for former inline-environment schema 2, and required Docker Compose 2.30 or
    newer for new Compose installations.
  • Reduced reader latency with a one-paragraph first visible request followed by
    bounded five-paragraph batches, removed the unconditional client delay,
    reused fixed-provider HTTP connections per worker, and committed each cache
    batch in one SQLite transaction.
  • Added keyboard retry and settings-dialog focus management, bounded custom DNS
    resolver capacity, full discovered backend coverage, universal hub smoke and
    opt-in deep provider diagnosis.

Fixed

  • Normalized fresh universal-hub data directories before inspecting private
    reader credentials, so caller-owned mode-0700 paths work for non-root
    Compose and root Unraid while retained UID-101 keys remain distinguishable
    from credentials created by a failed install attempt.
  • Ran read-only hub credential and data verification as the owning runtime UID,
    allowing reinstall and non-root Compose operation to traverse retained
    mode-0700 reader directories without adding Docker capabilities.
  • Journaled universal-hub installs before persistent mutation, preserved exact
    cleaned retry evidence, removed only session keys created by a failed attempt,
    and surfaced cleanup failures instead of leaving an ambiguous partial runtime.
  • Corrected the immutable release sequence so the identical annotated tag is
    verified on the GitHub mirror before authoritative Gitea publication begins.
  • Added fixed-cardinality translation latency buckets so cloud batch tuning can
    observe tail movement without book, reader or request labels.
  • Propagated adaptive batching through both hub and split managed installs,
    rejected browser/API batch-limit mismatches before startup, made provider
    429 terminal before retry/fallback, and kept safe browser retry bounds and
    visible-work priority stable across reader DOM rediscovery.
  • Updated Gemini/OpenAI-compatible request contracts for current Gemini models,
    including omission of deprecated sampling fields and invalid prefilled model
    turns.

[2.3.0-rc.1] - Unreleased candidate

Security

  • Added a reader-neutral, five-minute maximum session broker. Raw CWA cookies,
    Kavita access tokens and exact Kavita OIDC cookie chunks are accepted only by
    the same-origin exchange route, validated against the pinned reader account
    endpoint, never persisted, and replaced with an opaque HttpOnly cookie bound
    to the connector, public origin, observed address and User-Agent.
  • Ordinary translation routes now strip bearer credentials and, in managed
    reader-session mode, every reader cookie. Provider HTTP clients ignore
    inherited proxy variables, expired cache rows are deleted on lookup, DOM
    restoration uses pristine clones, and uninstall removes the connector secret
    without removing translations.
  • Lifecycle mutation now binds execution to immutable plan inputs and journals
    recoverable install attempts before the first owned runtime mutation.
  • The managed v2.1.4 migration path now recognizes the exact historical
    Community Applications ghcr.io/felixapel/cwa-ebook-translate-plugin:latest
    reference only after the container's immutable image ID is probed in a
    network-disabled sandbox and reports version 2.1.4. Other mutable latest
    references remain rejected.

Changed

  • Managed reader preflight can now bind a mutable container tag to an explicit
    immutable Docker image ID; the install and doctor fail closed if that exact
    runtime image changes.
  • Generalized schema-2 lifecycle state, generated resources and browser
    contracts from CWA-specific fields to explicit stock-reader connectors while
    retaining schema-1 CWA compatibility.
  • Updated the pinned Alpine runtime closure to the exact packages still
    available for the immutable base image, including nginx 1.30.4-r1.
  • Replaced the accumulated, overlapping documentation set with one indexed
    guide hierarchy for installation, operations, reference material,
    maintainers, and durable architecture decisions.
  • Moved automated tests under tests/, live probes and benchmarks under
    tools/, and Python dependency inputs and hash locks under requirements/.
  • Narrowed the Docker build context to runtime inputs and removed obsolete
    systemd and legacy Unraid template artifacts from the supported tree.
  • Added repository guidance and documentation contracts so CI, contributor
    commands, release checks, and public docs stay aligned with the canonical
    layout.
  • Pinned the lock compiler's build frontend to a reviewed non-yanked release
    instead of retaining a withdrawn transitive candidate.

Added

  • Added a stock Kavita v0.9.0.2 EPUB connector for the exact
    /library/:libraryId/series/:seriesId/book/:chapterId route and
    .book-content DOM, including SPA teardown, route-derived cache scopes and
    one bounded session refresh/replay after 401.
  • Added unit, real-Chromium and real-container coverage for separate CWA/Kavita
    connectors, Kavita native authentication, unsupported manga/PDF isolation,
    credential stripping and reader-neutral lifecycle artifacts.

v2.2.2

Choose a tag to compare

@felixapel felixapel released this 17 Jul 08:47

Trivy-clean runtime image. Strips setuptools/wheel/pip after install. SHA 59c3fe8.