From 66b91278b9a2f759b0331e85e4e8016c7b066836 Mon Sep 17 00:00:00 2001 From: alexbelgium Date: Tue, 7 Jul 2026 21:49:58 +0200 Subject: [PATCH] claude_desktop: hourly rtk+headroom gains report + headroom proxy backend - Add claude-gains-report.sh + /defaults/crontabs/root: an hourly rtk gain + headroom savings snapshot to the add-on log (heartbeat + accumulated gains). - Add svc-headroom longrun: run the headroom proxy as a local MCP backend (127.0.0.1:8787, no client routing) so headroom_compress/headroom_retrieve actually store/retrieve content and record savings. Backend only, so the Claude Desktop app's traffic is untouched (headroom #869). - Nudge headroom tool usage via a managed, idempotent CLAUDE.md block. - Bump version 1.6 -> 1.7 and update CHANGELOG. Co-Authored-By: Claude Opus 4.8 --- claude_desktop/CHANGELOG.md | 6 +++ claude_desktop/config.yaml | 2 +- claude_desktop/rootfs/defaults/crontabs/root | 4 ++ .../rootfs/etc/cont-init.d/82-claude_tools.sh | 46 +++++++++++++++++++ .../svc-headroom/dependencies.d/init-services | 0 .../etc/s6-overlay/s6-rc.d/svc-headroom/run | 16 +++++++ .../etc/s6-overlay/s6-rc.d/svc-headroom/type | 1 + .../s6-rc.d/user/contents.d/svc-headroom | 0 .../usr/local/bin/claude-gains-report.sh | 25 ++++++++++ 9 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 claude_desktop/rootfs/defaults/crontabs/root create mode 100644 claude_desktop/rootfs/etc/s6-overlay/s6-rc.d/svc-headroom/dependencies.d/init-services create mode 100755 claude_desktop/rootfs/etc/s6-overlay/s6-rc.d/svc-headroom/run create mode 100644 claude_desktop/rootfs/etc/s6-overlay/s6-rc.d/svc-headroom/type create mode 100644 claude_desktop/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/svc-headroom create mode 100755 claude_desktop/rootfs/usr/local/bin/claude-gains-report.sh diff --git a/claude_desktop/CHANGELOG.md b/claude_desktop/CHANGELOG.md index 1cbc84e228..76c3d84b01 100644 --- a/claude_desktop/CHANGELOG.md +++ b/claude_desktop/CHANGELOG.md @@ -1,3 +1,9 @@ +## 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. diff --git a/claude_desktop/config.yaml b/claude_desktop/config.yaml index 40520d3614..d97dc7d6df 100644 --- a/claude_desktop/config.yaml +++ b/claude_desktop/config.yaml @@ -90,5 +90,5 @@ slug: claude_desktop tmpfs: true udev: true url: https://github.com/alexbelgium/hassio-addons -version: "1.6" +version: "1.7" video: true diff --git a/claude_desktop/rootfs/defaults/crontabs/root b/claude_desktop/rootfs/defaults/crontabs/root new file mode 100644 index 0000000000..fbfdd3f0c5 --- /dev/null +++ b/claude_desktop/rootfs/defaults/crontabs/root @@ -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 diff --git a/claude_desktop/rootfs/etc/cont-init.d/82-claude_tools.sh b/claude_desktop/rootfs/etc/cont-init.d/82-claude_tools.sh index 313a90b0cc..71bbdbe6d3 100755 --- a/claude_desktop/rootfs/etc/cont-init.d/82-claude_tools.sh +++ b/claude_desktop/rootfs/etc/cont-init.d/82-claude_tools.sh @@ -61,6 +61,52 @@ if isinstance(data, dict): 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="" +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' + +## 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. + +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*.*?" + r"\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 hook claude' "$HOME/.claude/settings.json"; then diff --git a/claude_desktop/rootfs/etc/s6-overlay/s6-rc.d/svc-headroom/dependencies.d/init-services b/claude_desktop/rootfs/etc/s6-overlay/s6-rc.d/svc-headroom/dependencies.d/init-services new file mode 100644 index 0000000000..e69de29bb2 diff --git a/claude_desktop/rootfs/etc/s6-overlay/s6-rc.d/svc-headroom/run b/claude_desktop/rootfs/etc/s6-overlay/s6-rc.d/svc-headroom/run new file mode 100755 index 0000000000..473f6aec59 --- /dev/null +++ b/claude_desktop/rootfs/etc/s6-overlay/s6-rc.d/svc-headroom/run @@ -0,0 +1,16 @@ +#!/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 + +if bashio::config.true 'install_headroom' && command -v headroom >/dev/null 2>&1; then + bashio::log.info "svc-headroom: starting headroom proxy on 127.0.0.1:${port} (MCP backend only; no client routing)" + exec headroom proxy --host 127.0.0.1 --port "${port}" +fi + +bashio::log.info "svc-headroom: install_headroom disabled or headroom not found; idling" +exec sleep infinity diff --git a/claude_desktop/rootfs/etc/s6-overlay/s6-rc.d/svc-headroom/type b/claude_desktop/rootfs/etc/s6-overlay/s6-rc.d/svc-headroom/type new file mode 100644 index 0000000000..5883cff0cd --- /dev/null +++ b/claude_desktop/rootfs/etc/s6-overlay/s6-rc.d/svc-headroom/type @@ -0,0 +1 @@ +longrun diff --git a/claude_desktop/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/svc-headroom b/claude_desktop/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/svc-headroom new file mode 100644 index 0000000000..e69de29bb2 diff --git a/claude_desktop/rootfs/usr/local/bin/claude-gains-report.sh b/claude_desktop/rootfs/usr/local/bin/claude-gains-report.sh new file mode 100755 index 0000000000..0b8d011321 --- /dev/null +++ b/claude_desktop/rootfs/usr/local/bin/claude-gains-report.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# 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. +export HOME=/data/data +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 + +# Nothing to report if neither tool is installed — stay quiet. +if ! $have_rtk && ! $have_headroom; then exit 0; fi + +echo "===== claude gains report $(date '+%Y-%m-%d %H:%M:%S') =====" +if $have_rtk; then + echo "--- rtk gain ---" + rtk gain 2>&1 || echo "[warn] rtk gain failed" +fi +if $have_headroom; then + echo "--- headroom savings ---" + headroom savings 2>&1 || echo "[warn] headroom savings failed" +fi +echo "===== end gains report ====="