mirror of
https://github.com/alexbelgium/hassio-addons.git
synced 2026-10-17 13:39:24 +02:00
Compare commits
27 Commits
f5c6851344
...
codex/acti
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0030556525 | ||
|
|
905ce7bc0f | ||
|
|
19fe564e17 | ||
|
|
6248cb3c21 | ||
|
|
eff8577e37 | ||
|
|
1bd0c6f054 | ||
|
|
976e9bcc03 | ||
|
|
1dab8b9344 | ||
|
|
7667605e6b | ||
|
|
03e470a83a | ||
|
|
b922673192 | ||
|
|
ba37ee203e | ||
|
|
55035b4ee8 | ||
|
|
fffec89eaf | ||
|
|
0073339f8c | ||
|
|
e1a0f01fb9 | ||
|
|
66b91278b9 | ||
|
|
a70bf0f0f4 | ||
|
|
1a128d62f2 | ||
|
|
0fc40f339c | ||
|
|
86395a85a0 | ||
|
|
a9cf84077b | ||
|
|
f65d5af969 | ||
|
|
74e25ba41b | ||
|
|
4d768ae1fa | ||
|
|
cc5d04c0f5 | ||
|
|
f4343a6af4 |
10
README.md
10
README.md
@@ -56,7 +56,7 @@ If you want to do add the repository manually, please follow the procedure highl
|
||||
|
||||
### Number of addons
|
||||
|
||||
- In the repository : 134
|
||||
- In the repository : 135
|
||||
- Installed : 508490
|
||||
|
||||
### Top 3
|
||||
@@ -247,6 +247,14 @@ If you want to do add the repository manually, please follow the procedure highl
|
||||
![amd64][amd64-badge]
|
||||
![ingress][ingress-badge]
|
||||
|
||||
✓  [Claude Desktop](claude_desktop/) : Claude Desktop streamed through a browser with LinuxServer Selkies
|
||||
|
||||
  
|
||||

|
||||
![aarch64][aarch64-badge]
|
||||
![amd64][amd64-badge]
|
||||
![ingress][ingress-badge]
|
||||
|
||||
✓  [Cleanuparr](cleanuparr/) : Automatically removes stuck and unwanted downloads from your *arr and download clients
|
||||
|
||||
  
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## source-20260708-2 (08-07-2026)
|
||||
- Minor bugs fixed
|
||||
## source-20260708 (08-07-2026)
|
||||
- Minor bugs fixed
|
||||
## source-20260706-update (06-07-2026)
|
||||
- Minor bugs fixed
|
||||
## source-20260706 (06-07-2026)
|
||||
|
||||
@@ -127,5 +127,5 @@ slug: birdnet-go-dev
|
||||
udev: true
|
||||
url: https://github.com/alexbelgium/hassio-addons
|
||||
usb: true
|
||||
version: "source-20260706"
|
||||
version: "source-20260708-2"
|
||||
video: true
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
## 1.8 (08-07-2026)
|
||||
|
||||
- Expose the Headroom live savings dashboard on mapped port `8787` when `install_headroom` is enabled, while keeping the proxy local-only if the port mapping is disabled.
|
||||
- Map `8787/tcp` by default and document the dashboard URL.
|
||||
|
||||
## 1.7 (07-07-2026)
|
||||
|
||||
- Add an hourly rtk + headroom token-savings report to the add-on log (`claude-gains-report.sh`, seeded via `/defaults/crontabs/root` and run by the base image's cron). Lets you confirm at a glance that both tools keep running and see accumulated gains — if the numbers stop growing, the tool has stopped working.
|
||||
- Run the Headroom optimization proxy as a supervised local backend (`svc-headroom` on 127.0.0.1:8787) so the `headroom_compress`/`headroom_retrieve` MCP tools can actually store/retrieve compressed content and record savings. It is a **backend only** — no client's `ANTHROPIC_BASE_URL` is routed through it, so the Claude Desktop app (which force-overrides it, [headroom #869](https://github.com/headroomlabs-ai/headroom/issues/869)) is unaffected. Previously the MCP server was registered but had no backend, so it recorded no savings.
|
||||
- Nudge Claude to use the headroom compression tools via a managed, idempotent block appended to the user's `CLAUDE.md` (removed automatically when `install_headroom` is disabled).
|
||||
|
||||
## 1.6 (07-07-2026)
|
||||
|
||||
- Fix default desktop launch failing when `install_headroom` is enabled (the default): the code rewrote the launch to `headroom wrap claude-desktop …`, but `headroom wrap` only supports coding-agent CLIs (`claude`, `codex`, ...) with arguments after `--`, so it produced an invalid command that left the app unlaunched. Leave the plain launch intact and instead register the `headroom` MCP server (`headroom mcp serve`) in Claude Desktop's config, exposing the `headroom_compress`/`headroom_retrieve`/`headroom_stats` tools inside the app. This is the supported headroom integration for Desktop, which overrides `ANTHROPIC_BASE_URL` so transparent proxy compression is not possible ([headroom #869](https://github.com/headroomlabs-ai/headroom/issues/869)). Disabling the option removes the entry again.
|
||||
- Make the autostart resilient: if the launch command fails to start, fall back to the plain Claude Desktop launch so the app always comes up.
|
||||
|
||||
## 1.5 (07-07-2026)
|
||||
|
||||
- Change the default Claude Desktop data location to `/data/data`.
|
||||
|
||||
@@ -59,7 +59,6 @@ RUN curl -fsSLo /usr/share/keyrings/claude-desktop-archive-keyring.asc https://d
|
||||
apt-get install -y --no-install-recommends \
|
||||
claude-desktop \
|
||||
python3-pip \
|
||||
gnome-keyring \
|
||||
libsecret-1-0 \
|
||||
dbus-x11 \
|
||||
git gh && \
|
||||
|
||||
@@ -25,6 +25,7 @@ Claude Desktop sign-in requires a claude.ai plan that supports the Desktop app.
|
||||
- Baked-in `git` and GitHub CLI (`gh`) with optional startup credential configuration.
|
||||
- Custom script support through the repository standard `claude_desktop.sh` script.
|
||||
- Optional bundled Claude Code optimization tools: headroom, rtk, and caveman.
|
||||
- Headroom dashboard exposed on mapped port `8787` when `install_headroom` is enabled.
|
||||
- Low-power defaults: GPU device mapping, `AUTO_GPU=1`, `SELKIES_FRAMERATE=30`, `/tmp` tmpfs, and `$HOME/.cache` redirected to `/tmp/cache`.
|
||||
|
||||
## Options
|
||||
@@ -38,7 +39,7 @@ Claude Desktop sign-in requires a claude.ai plan that supports the Desktop app.
|
||||
| `DRINODE` | | Optional GPU device override for Selkies. |
|
||||
| `DNS_server` | `8.8.8.8` | DNS server used by the standard DNS module. |
|
||||
| `auto_update` | `true` | Check Anthropic's apt repository and upgrade `claude-desktop` at add-on startup. |
|
||||
| `install_headroom` | `true` | Make the baked-in `headroom` command available and log a usage hint. |
|
||||
| `install_headroom` | `true` | Register the baked-in `headroom` MCP server in Claude Desktop, start the Headroom proxy backend, and expose the Headroom dashboard on mapped port `8787` at `/dashboard` when that port is open. This exposes the `headroom_compress`/`headroom_retrieve`/`headroom_stats` context-compression tools inside the app. (Claude Desktop overrides `ANTHROPIC_BASE_URL`, so transparent proxy compression is not possible — MCP is the supported path; see [headroom #869](https://github.com/headroomlabs-ai/headroom/issues/869).) Disabling removes the MCP entry and stops the backend/dashboard service. |
|
||||
| `install_rtk` | `true` | Configure the rtk Claude Code `PreToolUse` hook in the persistent Claude Code settings. |
|
||||
| `install_caveman` | `true` | Install the caveman Claude Code plugin into the persistent Claude Code home. |
|
||||
| `install_github_cli` | `true` | Enable first-start checks and setup for the baked-in `git` and `gh` commands. |
|
||||
@@ -63,6 +64,10 @@ The add-on includes the repository standard custom-script executor. On first sta
|
||||
|
||||
Persistent state is stored in the configured `data_location`. Claude Desktop stores sign-in data below `~/.config/Claude`, and Claude Code/tool configuration is stored below `~/.claude`. Volatile cache data is redirected to `/tmp/cache` through `$XDG_CACHE_HOME` and `$HOME/.cache`.
|
||||
|
||||
## Headroom dashboard
|
||||
|
||||
When `install_headroom` is enabled, the add-on starts the local Headroom proxy backend and maps port `8787` by default. Open `http://<home-assistant-host>:8787/dashboard` to view the Headroom live savings dashboard. If you disable the `8787/tcp` port mapping, the backend binds to localhost for MCP use only and the dashboard is not externally exposed.
|
||||
|
||||
[aarch64-shield]: https://img.shields.io/badge/aarch64-yes-green.svg
|
||||
[amd64-shield]: https://img.shields.io/badge/amd64-yes-green.svg
|
||||
[maintenance-shield]: https://img.shields.io/maintenance/yes/2026.svg
|
||||
|
||||
@@ -53,11 +53,11 @@ options:
|
||||
panel_admin: false
|
||||
panel_icon: mdi:robot-happy
|
||||
ports:
|
||||
3000/tcp: null
|
||||
3001/tcp: null
|
||||
8787/tcp: 8787
|
||||
ports_description:
|
||||
3000/tcp: Web interface
|
||||
3001/tcp: Web interface https
|
||||
8787/tcp: Headroom dashboard and proxy
|
||||
privileged:
|
||||
- SYS_ADMIN
|
||||
- DAC_READ_SEARCH
|
||||
@@ -90,5 +90,5 @@ slug: claude_desktop
|
||||
tmpfs: true
|
||||
udev: true
|
||||
url: https://github.com/alexbelgium/hassio-addons
|
||||
version: "1.5"
|
||||
version: "1.8"
|
||||
video: true
|
||||
|
||||
@@ -13,4 +13,22 @@ dbus-update-activation-environment --all >/dev/null 2>&1 || true
|
||||
|
||||
# --password-store=gnome-libsecret forces Electron onto the libsecret backend instead of
|
||||
# falling back to plaintext (and warning that the sign-in will not be saved).
|
||||
claude-desktop --no-sandbox --disable-dev-shm-usage --password-store=gnome-libsecret
|
||||
CLAUDE_DESKTOP_COMMAND_FILE="/tmp/claude-desktop-command"
|
||||
DEFAULT_CLAUDE_DESKTOP_COMMAND="claude-desktop --no-sandbox --disable-dev-shm-usage --password-store=gnome-libsecret"
|
||||
if [ -s "$CLAUDE_DESKTOP_COMMAND_FILE" ]; then
|
||||
CLAUDE_DESKTOP_COMMAND="$(cat "$CLAUDE_DESKTOP_COMMAND_FILE")"
|
||||
else
|
||||
CLAUDE_DESKTOP_COMMAND="$DEFAULT_CLAUDE_DESKTOP_COMMAND"
|
||||
fi
|
||||
if bashio::config.true 'install_headroom'; then
|
||||
export ANTHROPIC_BASE_URL="http://127.0.0.1:8787"
|
||||
fi
|
||||
|
||||
# Launch the configured command. If a custom/wrapped command fails to start, fall back to
|
||||
# the plain Claude Desktop launch so the desktop app still comes up for the user.
|
||||
if ! sh -c "$CLAUDE_DESKTOP_COMMAND"; then
|
||||
if [ "$CLAUDE_DESKTOP_COMMAND" != "$DEFAULT_CLAUDE_DESKTOP_COMMAND" ]; then
|
||||
echo "autostart: '$CLAUDE_DESKTOP_COMMAND' failed; falling back to default Claude Desktop launch" >&2
|
||||
exec sh -c "$DEFAULT_CLAUDE_DESKTOP_COMMAND"
|
||||
fi
|
||||
fi
|
||||
|
||||
4
claude_desktop/rootfs/defaults/crontabs/root
Normal file
4
claude_desktop/rootfs/defaults/crontabs/root
Normal file
@@ -0,0 +1,4 @@
|
||||
# Hourly rtk + headroom token-savings report to the add-on log (heartbeat + gains).
|
||||
# Seeded to /data/data/crontabs/root by init-crontab-config and run by svc-cron; edit the
|
||||
# persistent copy to customize. Output goes to /proc/1/fd/1 so it shows in the add-on log.
|
||||
0 * * * * /usr/local/bin/claude-gains-report.sh > /proc/1/fd/1 2>&1
|
||||
@@ -4,21 +4,136 @@ set -e
|
||||
set -o pipefail
|
||||
mkdir -p "$HOME/.claude"
|
||||
|
||||
CLAUDE_DESKTOP_COMMAND_FILE="/tmp/claude-desktop-command"
|
||||
DEFAULT_CLAUDE_DESKTOP_COMMAND='claude-desktop --no-sandbox --disable-dev-shm-usage --password-store=gnome-libsecret'
|
||||
printf '%s\n' "$DEFAULT_CLAUDE_DESKTOP_COMMAND" > "$CLAUDE_DESKTOP_COMMAND_FILE"
|
||||
|
||||
# headroom's "wrap"/proxy routing works by setting ANTHROPIC_BASE_URL, which the Claude Desktop
|
||||
# Electron app force-overrides to the production endpoint (headroom #869), so transparent
|
||||
# compression cannot be applied to the desktop launch. The integration that does work with
|
||||
# Claude Desktop is headroom's MCP server, which exposes the headroom_compress/headroom_retrieve/
|
||||
# headroom_stats tools inside the app. Register it in Claude Desktop's MCP config, leaving the
|
||||
# plain launch untouched. The merge is idempotent and preserves any other MCP servers.
|
||||
CLAUDE_DESKTOP_CONFIG="$HOME/.config/Claude/claude_desktop_config.json"
|
||||
if bashio::config.true 'install_headroom'; then
|
||||
if command -v headroom &> /dev/null; then
|
||||
bashio::log.info "headroom $(headroom --version 2> /dev/null || true) available. Use 'headroom wrap claude' or MCP mode from Claude Code."
|
||||
bashio::log.info "headroom $(headroom --version 2> /dev/null || true) available; registering the headroom MCP server for Claude Desktop"
|
||||
HEADROOM_BIN="$(command -v headroom)" CLAUDE_DESKTOP_CONFIG="$CLAUDE_DESKTOP_CONFIG" python3 - <<'PY' || bashio::log.warning "Unable to register the headroom MCP server automatically"
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
path = Path(os.environ["CLAUDE_DESKTOP_CONFIG"])
|
||||
try:
|
||||
data = json.loads(path.read_text()) if path.exists() else {}
|
||||
if not isinstance(data, dict):
|
||||
data = {}
|
||||
except Exception:
|
||||
if path.exists():
|
||||
path.rename(path.with_suffix(path.suffix + ".bak"))
|
||||
data = {}
|
||||
servers = data.get("mcpServers")
|
||||
if not isinstance(servers, dict):
|
||||
servers = {}
|
||||
data["mcpServers"] = servers
|
||||
servers["headroom"] = {"command": os.environ.get("HEADROOM_BIN", "headroom"), "args": ["mcp", "serve"]}
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text(json.dumps(data, indent=2) + "\n")
|
||||
PY
|
||||
else
|
||||
bashio::log.warning "headroom is not available"
|
||||
fi
|
||||
elif [ -f "$CLAUDE_DESKTOP_CONFIG" ]; then
|
||||
bashio::log.info "Removing the headroom MCP server from Claude Desktop"
|
||||
CLAUDE_DESKTOP_CONFIG="$CLAUDE_DESKTOP_CONFIG" python3 - <<'PY' || bashio::log.warning "Unable to remove the headroom MCP server automatically"
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
path = Path(os.environ["CLAUDE_DESKTOP_CONFIG"])
|
||||
data = json.loads(path.read_text())
|
||||
if isinstance(data, dict):
|
||||
servers = data.get("mcpServers")
|
||||
if isinstance(servers, dict) and servers.pop("headroom", None) is not None:
|
||||
if not servers:
|
||||
data.pop("mcpServers", None)
|
||||
path.write_text(json.dumps(data, indent=2) + "\n")
|
||||
PY
|
||||
fi
|
||||
|
||||
# Guide Claude to actually use the headroom compression tools so the MCP integration produces
|
||||
# real savings (otherwise the tools sit unused and `headroom savings` stays empty). Managed,
|
||||
# idempotent block appended to the user's global CLAUDE.md; removed when headroom is disabled.
|
||||
CLAUDE_MD="$HOME/.claude/CLAUDE.md"
|
||||
HEADROOM_GUIDE_BEGIN="<!-- BEGIN headroom (managed by claude_desktop addon) -->"
|
||||
if bashio::config.true 'install_headroom'; then
|
||||
mkdir -p "$(dirname "$CLAUDE_MD")"
|
||||
if ! { [ -f "$CLAUDE_MD" ] && grep -qF "$HEADROOM_GUIDE_BEGIN" "$CLAUDE_MD"; }; then
|
||||
bashio::log.info "Adding headroom usage guidance to CLAUDE.md"
|
||||
{
|
||||
[ -s "$CLAUDE_MD" ] && printf '\n'
|
||||
cat <<'MD'
|
||||
<!-- BEGIN headroom (managed by claude_desktop addon) -->
|
||||
## Headroom context compression
|
||||
|
||||
A local Headroom proxy (127.0.0.1:8787) backs the `headroom` MCP tools. To save context tokens:
|
||||
when you produce or read a **large, structured** blob you will keep referring to — file listings,
|
||||
search results, JSON/config dumps, big command outputs, roughly >500 tokens — call
|
||||
`mcp__headroom__headroom_compress` on it and keep the returned compressed text + `hash` instead of
|
||||
the raw content. Call `mcp__headroom__headroom_retrieve` with that hash when you need the full
|
||||
original back. Skip compression for error/stack-trace output (Headroom deliberately protects it)
|
||||
and for small or one-off content. Use `mcp__headroom__headroom_stats` to check savings.
|
||||
<!-- END headroom (managed by claude_desktop addon) -->
|
||||
MD
|
||||
} >> "$CLAUDE_MD"
|
||||
fi
|
||||
elif [ -f "$CLAUDE_MD" ] && grep -qF "$HEADROOM_GUIDE_BEGIN" "$CLAUDE_MD"; then
|
||||
bashio::log.info "Removing headroom usage guidance from CLAUDE.md"
|
||||
CLAUDE_MD="$CLAUDE_MD" python3 - <<'PY' || bashio::log.warning "Unable to remove headroom guidance automatically"
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
path = Path(os.environ["CLAUDE_MD"])
|
||||
text = path.read_text()
|
||||
pattern = re.compile(
|
||||
r"\n*<!-- BEGIN headroom \(managed by claude_desktop addon\) -->.*?"
|
||||
r"<!-- END headroom \(managed by claude_desktop addon\) -->\n?",
|
||||
re.DOTALL,
|
||||
)
|
||||
new = pattern.sub("", text)
|
||||
if new != text:
|
||||
path.write_text(new)
|
||||
PY
|
||||
fi
|
||||
|
||||
if bashio::config.true 'install_rtk'; then
|
||||
if command -v rtk &> /dev/null; then
|
||||
if [ -f "$HOME/.claude/settings.json" ] && grep -q 'rtk' "$HOME/.claude/settings.json"; then
|
||||
if [ -f "$HOME/.claude/settings.json" ] && grep -q 'rtk hook claude' "$HOME/.claude/settings.json"; then
|
||||
bashio::log.info "rtk Claude Code hook already configured"
|
||||
else
|
||||
bashio::log.info "Configuring rtk Claude Code hook"
|
||||
rtk init -g || bashio::log.warning "rtk hook configuration failed"
|
||||
RTK_NONINTERACTIVE=1 rtk init -g || bashio::log.warning "rtk global files configuration failed"
|
||||
python3 - <<'PY' || bashio::log.warning "Unable to configure rtk hook automatically"
|
||||
import json
|
||||
from pathlib import Path
|
||||
path = Path.home() / ".claude" / "settings.json"
|
||||
try:
|
||||
data = json.loads(path.read_text()) if path.exists() else {}
|
||||
if not isinstance(data, dict):
|
||||
data = {}
|
||||
except Exception:
|
||||
if path.exists():
|
||||
path.rename(path.with_suffix(path.suffix + ".bak"))
|
||||
data = {}
|
||||
hooks = data.setdefault("hooks", {})
|
||||
pre = hooks.setdefault("PreToolUse", [])
|
||||
rtk_entry = {"matcher": "Bash", "hooks": [{"type": "command", "command": "rtk hook claude"}]}
|
||||
if not any("rtk hook claude" in json.dumps(entry) for entry in pre if isinstance(entry, dict)):
|
||||
pre.append(rtk_entry)
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text(json.dumps(data, indent=2) + "\n")
|
||||
PY
|
||||
fi
|
||||
else
|
||||
bashio::log.warning "rtk is not available"
|
||||
@@ -49,7 +164,7 @@ if bashio::config.true 'install_caveman'; then
|
||||
bashio::log.info "caveman Claude Code plugin already configured"
|
||||
else
|
||||
bashio::log.info "Installing caveman Claude Code plugin"
|
||||
curl --connect-timeout 10 --max-time 60 -fsSL https://raw.githubusercontent.com/JuliusBrussee/caveman/main/install.sh | bash || bashio::log.warning "caveman install failed (offline?)"
|
||||
curl --connect-timeout 10 --max-time 60 -fsSL https://raw.githubusercontent.com/JuliusBrussee/caveman/main/install.sh | bash >/dev/null || bashio::log.warning "caveman install failed (offline?)"
|
||||
fi
|
||||
else
|
||||
bashio::log.info "Disabling caveman Claude Code plugin"
|
||||
|
||||
@@ -29,15 +29,13 @@ if bashio::config.has_value 'github_token'; then
|
||||
token="$(bashio::config 'github_token')"
|
||||
mkdir -p "$HOME/.config/gh"
|
||||
chmod 700 "$HOME/.config/gh"
|
||||
export GH_TOKEN="$token"
|
||||
export GITHUB_TOKEN="$token"
|
||||
if gh auth status --hostname github.com > /dev/null 2>&1; then
|
||||
if env -u GH_TOKEN -u GITHUB_TOKEN gh auth status --hostname github.com > /dev/null 2>&1; then
|
||||
bashio::log.info "GitHub CLI already authenticated for github.com"
|
||||
else
|
||||
bashio::log.info "Configuring GitHub CLI authentication for github.com"
|
||||
printf '%s\n' "$token" | gh auth login --hostname github.com --with-token || bashio::log.warning "GitHub CLI authentication failed"
|
||||
printf '%s\n' "$token" | env -u GH_TOKEN -u GITHUB_TOKEN gh auth login --hostname github.com --with-token || bashio::log.warning "GitHub CLI authentication failed"
|
||||
fi
|
||||
gh auth setup-git --hostname github.com || bashio::log.warning "GitHub CLI git credential setup failed"
|
||||
env -u GH_TOKEN -u GITHUB_TOKEN gh auth setup-git --hostname github.com || bashio::log.warning "GitHub CLI git credential setup failed"
|
||||
else
|
||||
bashio::log.info "GitHub CLI available. Set github_token to authenticate gh and git operations."
|
||||
fi
|
||||
|
||||
25
claude_desktop/rootfs/etc/s6-overlay/s6-rc.d/svc-headroom/run
Executable file
25
claude_desktop/rootfs/etc/s6-overlay/s6-rc.d/svc-headroom/run
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/with-contenv bashio
|
||||
# Headroom optimization proxy — runs ONLY as a local backend for the headroom MCP tools
|
||||
# (headroom_compress / headroom_retrieve, registered in 82-claude_tools.sh). It is NOT a
|
||||
# traffic router: no client's ANTHROPIC_BASE_URL is pointed at it, so the Claude Desktop
|
||||
# Electron app (which force-overrides ANTHROPIC_BASE_URL — headroom #869) and every other
|
||||
# client are unaffected. Without this backend the MCP tools cannot store/retrieve compressed
|
||||
# content and no savings are ever recorded.
|
||||
declare port=8787
|
||||
declare host=127.0.0.1
|
||||
|
||||
# Expose the built-in Headroom dashboard only when the add-on option is enabled
|
||||
# and Home Assistant has mapped the Headroom port. The port is mapped by default
|
||||
# in config.yaml, so users can open http://<ha-host>:8787/dashboard to inspect
|
||||
# live savings, while disabling install_headroom still leaves the service idle.
|
||||
if [[ -n "$(bashio::addon.port "${port}")" ]]; then
|
||||
host=0.0.0.0
|
||||
fi
|
||||
|
||||
if bashio::config.true 'install_headroom' && command -v headroom >/dev/null 2>&1; then
|
||||
bashio::log.info "svc-headroom: starting headroom proxy on ${host}:${port}; dashboard available at /dashboard when the port is mapped (MCP backend only; no client routing)"
|
||||
exec headroom proxy --host "${host}" --port "${port}" --code-aware
|
||||
fi
|
||||
|
||||
bashio::log.info "svc-headroom: install_headroom disabled or headroom not found; idling"
|
||||
exec sleep infinity
|
||||
@@ -0,0 +1 @@
|
||||
longrun
|
||||
34
claude_desktop/rootfs/usr/local/bin/claude-gains-report.sh
Executable file
34
claude_desktop/rootfs/usr/local/bin/claude-gains-report.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/with-contenv bashio
|
||||
# Hourly rtk + headroom token-savings snapshot for the add-on log.
|
||||
# Invoked by cron (see /defaults/crontabs/root); its stdout is redirected to /proc/1/fd/1,
|
||||
# so the report appears in the add-on log. Doubles as a heartbeat: if the numbers stop
|
||||
# growing, the corresponding tool has stopped working.
|
||||
# with-contenv supplies HOME from the s6 envdir, so this honors a custom `data_location`
|
||||
# (see 20-folders.sh) instead of hardcoding /data/data; it also makes bashio::config
|
||||
# available for the install_headroom gate below.
|
||||
export NO_COLOR=1 # keep the add-on log free of ANSI color codes
|
||||
export PATH="/lsiopy/bin:/usr/local/bin:/usr/bin:/bin:${PATH}"
|
||||
|
||||
have_rtk=false; command -v rtk >/dev/null 2>&1 && have_rtk=true
|
||||
have_headroom=false; command -v headroom >/dev/null 2>&1 && have_headroom=true
|
||||
|
||||
# headroom is pip-installed unconditionally at build time, so its binary is on PATH even
|
||||
# when install_headroom is off — gate on the same config svc-headroom checks, and only
|
||||
# fall back to have_headroom as a secondary availability guard.
|
||||
headroom_enabled=false
|
||||
if bashio::config.true 'install_headroom' && $have_headroom; then
|
||||
headroom_enabled=true
|
||||
fi
|
||||
|
||||
# Nothing to report if neither tool is active — stay quiet.
|
||||
if ! $have_rtk && ! $headroom_enabled; then exit 0; fi
|
||||
|
||||
echo "===== claude gains report $(date '+%Y-%m-%d %H:%M:%S') ====="
|
||||
if $headroom_enabled; then
|
||||
echo "--- headroom savings ---"
|
||||
headroom savings 2>&1 || echo "[warn] headroom savings failed"
|
||||
elif $have_rtk; then
|
||||
echo "--- rtk gain ---"
|
||||
rtk gain 2>&1 || echo "[warn] rtk gain failed"
|
||||
fi
|
||||
echo "===== end gains report ====="
|
||||
@@ -1,3 +1,8 @@
|
||||
## 0.146.1-3 (2026-07-08)
|
||||
- Fix forced HTTPS redirect loop on the plain-HTTP UI by re-adding the `assume_ssl` disable workaround.
|
||||
- Export `PUBLIC_PORT` alongside `public_hostname` so generated links point at port 3214.
|
||||
- Document `public_hostname` in README (accepts hostname or server IP).
|
||||
|
||||
## 0.146.1-2 (06-07-2026)
|
||||
- Minor bugs fixed
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG BUILD_FROM=ghcr.io/manyfold3d/manyfold-solo:0.135.0
|
||||
ARG BUILD_FROM=ghcr.io/manyfold3d/manyfold-solo:latest
|
||||
FROM ${BUILD_FROM}
|
||||
|
||||
# hadolint ignore=DL3041
|
||||
|
||||
@@ -53,6 +53,7 @@ Local development alternative on the HA host:
|
||||
## Options
|
||||
|
||||
- `secret_key_base`: App secret used by Rails to sign/encrypt sessions and tokens. See [Secret Key Base](#secret-key-base) below.
|
||||
- `public_hostname`: Hostname or server IP used to generate links (mailer and "Open in slicer" download URLs). Leave blank to auto-detect from Home Assistant's configured external URL, falling back to `homeassistant.local`.
|
||||
- `puid` / `pgid`: Ownership applied to writable mapped directories (`/config` paths).
|
||||
- `multiuser`: Toggle Manyfold multiuser mode.
|
||||
- `library_path`: Scanned/indexed path.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: "Manyfold"
|
||||
slug: manyfold
|
||||
description: "Manyfold 3D model manager as a Home Assistant add-on, using the upstream image with configurable library/index paths."
|
||||
version: "0.146.1-2"
|
||||
version: "0.146.1-3"
|
||||
url: "https://github.com/alexbelgium/hassio-addons/tree/master/manyfold"
|
||||
image: ghcr.io/alexbelgium/manyfold-{arch}
|
||||
arch:
|
||||
|
||||
@@ -153,16 +153,39 @@ generate_secret() {
|
||||
head -c 64 /dev/urandom | od -An -tx1 | tr -d ' \n'
|
||||
}
|
||||
|
||||
# Manyfold's production.rb sets config.assume_ssl = PUBLIC_HOSTNAME.present?,
|
||||
# with no separate env var to opt out. assume_ssl makes Rails treat every
|
||||
# request as if it arrived over HTTPS (for a proxy that terminates SSL
|
||||
# upstream), which is wrong here: this add-on serves plain HTTP directly on
|
||||
# port 3214 with no TLS termination, so it produces bad https:// redirects
|
||||
# (e.g. to /users/sign_in) that browsers can't complete. Force it back off
|
||||
# via an initializer dropped into whichever app directory is found, since we
|
||||
# still need PUBLIC_HOSTNAME set for correct link generation elsewhere.
|
||||
disable_assume_ssl() {
|
||||
local app_dir="$1"
|
||||
local initializer_dir="${app_dir}/config/initializers"
|
||||
[[ -d "$initializer_dir" ]] || return 0
|
||||
|
||||
cat > "${initializer_dir}/manyfold_addon_disable_assume_ssl.rb" << 'EOF'
|
||||
# Added by the Manyfold Home Assistant add-on: this add-on has no
|
||||
# SSL-terminating reverse proxy in front of it, so assuming SSL produces
|
||||
# incorrect https:// redirects on a plain-HTTP port.
|
||||
Rails.application.config.assume_ssl = false
|
||||
EOF
|
||||
}
|
||||
|
||||
start_manyfold() {
|
||||
if [[ -x /usr/src/app/bin/docker-entrypoint.sh ]]; then
|
||||
log "Starting Manyfold via /usr/src/app/bin/docker-entrypoint.sh foreman start"
|
||||
cd /usr/src/app
|
||||
disable_assume_ssl /usr/src/app
|
||||
exec ./bin/docker-entrypoint.sh foreman start
|
||||
fi
|
||||
|
||||
if [[ -x /app/bin/docker-entrypoint.sh ]]; then
|
||||
log "Starting Manyfold via /app/bin/docker-entrypoint.sh foreman start"
|
||||
cd /app
|
||||
disable_assume_ssl /app
|
||||
exec ./bin/docker-entrypoint.sh foreman start
|
||||
fi
|
||||
|
||||
@@ -189,8 +212,10 @@ start_manyfold() {
|
||||
|
||||
if [[ -d /usr/src/app ]]; then
|
||||
cd /usr/src/app
|
||||
disable_assume_ssl /usr/src/app
|
||||
elif [[ -d /app ]]; then
|
||||
cd /app
|
||||
disable_assume_ssl /app
|
||||
fi
|
||||
|
||||
if command -v bundle >/dev/null 2>&1; then
|
||||
@@ -272,6 +297,7 @@ export MANYFOLD_MULTIUSER="$MULTIUSER"
|
||||
export MANYFOLD_LIBRARY_PATH="$LIBRARY_PATH"
|
||||
export MANYFOLD_THUMBNAILS_PATH="$THUMBNAILS_PATH"
|
||||
export PUBLIC_HOSTNAME
|
||||
export PUBLIC_PORT="3214"
|
||||
export RAILS_LOG_LEVEL="$LOG_LEVEL"
|
||||
export MANYFOLD_LOG_LEVEL="$LOG_LEVEL"
|
||||
export WEB_CONCURRENCY
|
||||
|
||||
Reference in New Issue
Block a user