Compare commits
4 Commits
408eef8a0f
...
fix/ai-aut
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16e2c6aac5 | ||
|
|
3ac46b0cd5 | ||
|
|
c8ca11604e | ||
|
|
0f5b646078 |
BIN
.github/stargazer_map.png
vendored
|
Before Width: | Height: | Size: 404 KiB After Width: | Height: | Size: 64 KiB |
BIN
.github/stats.png
vendored
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 1.9 KiB |
BIN
.github/stats_addons.png
vendored
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 4.5 KiB |
55
.github/workflows/on_issues_ai_triage.yaml
vendored
@@ -362,6 +362,50 @@ jobs:
|
||||
"$EXECUTION_FILE" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Did the run die because the Claude credential is bad? The action
|
||||
# reports this uselessly — the failure surfaces as "--json-schema was
|
||||
# provided but Claude did not return structured_output", which points
|
||||
# at the schema and not at auth. The execution file carries the truth.
|
||||
#
|
||||
# A bad credential shows up in more than one shape, and both have been
|
||||
# seen in production within a week:
|
||||
# * revoked token -> error "authentication_failed", HTTP 401
|
||||
# * malformed token -> error "invalid_request", api_error_status
|
||||
# null, and the reason only in the SDK's message text ("Invalid
|
||||
# Authorization header value from CLAUDE_CODE_OAUTH_TOKEN: it
|
||||
# contains a line break at character 62").
|
||||
# Matching only the first shape reported the second as a generic
|
||||
# workflow fault, so the text marker is checked too — but only on an
|
||||
# object the SDK itself flagged as an API error, so an issue body that
|
||||
# merely mentions the secret's name cannot fake one. A false positive
|
||||
# would change only the message: this branch exits 1 either way.
|
||||
hit_auth_failure() {
|
||||
[ -n "${EXECUTION_FILE:-}" ] && [ -s "${EXECUTION_FILE:-}" ] || return 1
|
||||
jq -e '(type == "array") and
|
||||
any(.[]?;
|
||||
(type == "object") and
|
||||
(((.error? // "") == "authentication_failed") or
|
||||
((.error_status? // 0) == 401) or
|
||||
((.api_error_status? // 0) == 401) or
|
||||
(((.is_api_error_message? // false) == true) and
|
||||
(tostring | test("CLAUDE_CODE_OAUTH_TOKEN|Invalid auth token")))))' \
|
||||
"$EXECUTION_FILE" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# The SDK's own words are far more useful than anything this script
|
||||
# can infer — "it contains a line break at character 62" names the
|
||||
# exact defect. Surface it verbatim when present.
|
||||
auth_failure_detail() {
|
||||
[ -n "${EXECUTION_FILE:-}" ] && [ -s "${EXECUTION_FILE:-}" ] || return 0
|
||||
jq -r 'if type == "array" then
|
||||
[ .[]? | select(type == "object")
|
||||
| select((.is_api_error_message? // false) == true)
|
||||
| tostring
|
||||
| capture("(?<m>Invalid Authorization header value[^\"]*|Invalid auth token[^\"]*)")
|
||||
| .m ] | first // ""
|
||||
else "" end' "$EXECUTION_FILE" 2> /dev/null || true
|
||||
}
|
||||
|
||||
# GATE 1 — did the action itself run? This is checked BEFORE looking
|
||||
# at the payload, because the action can fail *after* having written
|
||||
# a valid structured output: the object would sail through the shape
|
||||
@@ -380,6 +424,17 @@ jobs:
|
||||
if [ "${CLASSIFY_OUTCOME:-}" = "failure" ]; then
|
||||
restore_needs_info
|
||||
|
||||
# Checked before anything else, because it is the one failure with
|
||||
# a specific remedy and it takes down every tier at once — tier 1
|
||||
# cannot label, so tier 2's batch is empty and the whole pipeline
|
||||
# goes quiet while each run still fails in a way that reads like a
|
||||
# per-issue problem. Say plainly what is wrong and what to do.
|
||||
if hit_auth_failure; then
|
||||
DETAIL=$(auth_failure_detail)
|
||||
echo "::error::CLAUDE_CODE_OAUTH_TOKEN is being rejected${DETAIL:+ — $DETAIL}. This is NOT a problem with issue #$ISSUE: every AI workflow is down until the credential is fixed. Regenerate with 'claude setup-token' and re-enter the secret in the CR_PAT environment as a SINGLE line with no line break or trailing newline. Set the AI_DISABLED repo variable to 'true' to silence these runs meanwhile."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ...with one exception. Exhausting the turn budget is NOT a
|
||||
# workflow fault: the action ran fine and this particular issue was
|
||||
# just too tangled to finish inside the turn budget. Treating it as systemic
|
||||
|
||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.2 KiB |
BIN
aurral/stats.png
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
baikal/stats.png
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
bazarr/stats.png
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 1.5 KiB |
@@ -1,4 +1,8 @@
|
||||
|
||||
## 0.6.27.3 (2026-08-30)
|
||||
- Doc: explain in the README that Calibre-Web's optional extras (metadata, kobo, gdrive, gmail, goodreads, ldap, oauth, comics) are already installed by the LinuxServer base image, that `pip install calibreweb[...]` inside the container is useless and not persistent, and that the cover fields on the Edit Metadata page are gated on `Enable Uploads` plus the user's `Upload` permission (https://github.com/alexbelgium/hassio-addons/issues/1143)
|
||||
- Fix: remove the Dockerfile step that claimed to install the Calibre binaries into `/opt/calibre`. There is no `wget` in the image, so the command failed silently and left the layer empty; the binaries are and were provided at start by the default `linuxserver/mods:universal-calibre` docker mod
|
||||
|
||||
## 0.6.27.2 (2026-08-23)
|
||||
- Fix: trust the whole supervisor network range for the ingress auth header instead of the addon's own address, which changes across restarts. The list is only written when that range is missing, so an entry added in the calibre-web admin page is no longer erased on every start (https://github.com/alexbelgium/hassio-addons/pull/3010)
|
||||
|
||||
|
||||
@@ -35,11 +35,9 @@ RUN \
|
||||
&& echo '#!/bin/sh' > /usr/bin/xdg-desktop-menu && chmod +x /usr/bin/xdg-desktop-menu \
|
||||
&& echo '#!/bin/sh' > /usr/bin/xdg-mime && chmod +x /usr/bin/xdg-mime
|
||||
|
||||
# Install calibre binaries (provides calibredb required for book downloads)
|
||||
# hadolint ignore=DL4006
|
||||
RUN \
|
||||
wget -nv -O- https://download.calibre-ebook.com/linux-installer.sh | sh /dev/stdin install_dir=/opt/calibre
|
||||
ENV PATH="/opt/calibre:${PATH}"
|
||||
# By default the calibre binaries (calibredb, ebook-convert, ebook-meta) are installed at start by
|
||||
# the linuxserver/mods:universal-calibre docker mod, set as the default DOCKER_MODS in config.yaml.
|
||||
# The xdg-* stubs above keep its calibre_postinstall step quiet.
|
||||
|
||||
# Global LSIO modifications
|
||||
COPY ha_lsio.sh /ha_lsio.sh
|
||||
|
||||
@@ -97,6 +97,18 @@ This addon supports mounting both local drives and remote SMB shares:
|
||||
- **Local drives**: See [Mounting Local Drives in Addons](https://github.com/alexbelgium/hassio-addons/wiki/Mounting-Local-Drives-in-Addons)
|
||||
- **Remote shares**: See [Mounting Remote Shares in Addons](https://github.com/alexbelgium/hassio-addons/wiki/Mounting-remote-shares-in-Addons)
|
||||
|
||||
### Optional Calibre-Web features
|
||||
|
||||
Calibre-Web documents optional extras that a manual installation adds with `pip install calibreweb[metadata]` and similar. **You do not need to install anything here**: the LinuxServer base image this add-on builds on installs Calibre-Web's `requirements.txt` *and* its full `optional-requirements.txt` into the application's virtualenv, so the gdrive, gmail, goodreads, ldap, oauth, metadata, comics and kobo dependencies are all present already. Running `pip install calibreweb[...]` inside the container is not a supported way to enable them: it installs the PyPI distribution of Calibre-Web over an installation that already has those dependencies, and it can disturb the versions the base image pinned. It is also thrown away, because the Supervisor recreates the add-on container on restart.
|
||||
|
||||
Optional features are switched on in the Calibre-Web web interface, not in the add-on options, under `Admin` -> `Basic Configuration` -> `Feature Configuration` (for example `Enable Uploads`, `Enable Kobo sync`, `Use Goodreads`).
|
||||
|
||||
**Book covers.** The `Fetch Cover from URL` and `Upload Cover from Local Disk` fields only appear on a book's `Edit Metadata` page when `Enable Uploads` is ticked in `Feature Configuration` **and** the logged-in user has the `Upload` permission (`Admin` -> the user -> `Upload`). A missing Python package is not what hides them.
|
||||
|
||||
**Conversion, metadata embedding and the other Calibre integrations** use command-line binaries such as `ebook-convert`, `ebook-meta` and `calibredb`. Those are installed at start by the `linuxserver/mods:universal-calibre` docker mod, which is the shipped default of the `DOCKER_MODS` option. If you set `DOCKER_MODS` yourself, keep `linuxserver/mods:universal-calibre` in the list (mods are separated by `|`) or those binaries disappear.
|
||||
|
||||
**Other compatible Python packages** can be installed from the add-on's custom script (see the section below); `pip` there points at Calibre-Web's own virtualenv. Such a script runs on every start, and it has to, since the container's writable layer does not persist.
|
||||
|
||||
### Custom Scripts and Environment Variables
|
||||
|
||||
This addon supports custom scripts and environment variables:
|
||||
|
||||
@@ -116,5 +116,5 @@ schema:
|
||||
slug: calibre-web
|
||||
udev: true
|
||||
url: https://github.com/alexbelgium/hassio-addons/tree/master/calibre_web
|
||||
version: "0.6.27.2"
|
||||
version: "0.6.27.3"
|
||||
video: true
|
||||
|
||||
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.4 KiB |
BIN
codex/stats.png
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 1.7 KiB |
BIN
emby/stats.png
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 1.7 KiB |
BIN
ente/stats.png
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
gitea/stats.png
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
grav/stats.png
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
immich/stats.png
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 1.4 KiB |
BIN
inadyn/stats.png
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.3 KiB |
BIN
joal/stats.png
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
joplin/stats.png
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
kometa/stats.png
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.4 KiB |
BIN
komga/stats.png
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
lidarr/stats.png
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.4 KiB |
BIN
mealie/stats.png
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
monica/stats.png
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
mylar3/stats.png
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.4 KiB |
BIN
nzbget/stats.png
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
piwigo/stats.png
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.4 KiB |
BIN
plex/stats.png
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
radarr/stats.png
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 1.7 KiB |