From 3f70ed56b919a6c29e4f77f59e4e2598966d0baa Mon Sep 17 00:00:00 2001 From: LayerTM <1336785+LayerTM@users.noreply.github.com> Date: Tue, 10 Nov 2026 12:32:59 +0100 Subject: [PATCH 1/2] Do not install hass-mcp's test launcher over the system test Every hass-mcp wheel declares a `test = pytest:main` console script. pip put it in /usr/local/bin, ahead of /usr/bin on PATH, so any program that ran `test` by name got a Python traceback instead of the system command. The image build now removes that launcher (and fails if a file of that name is ever something else), and the image checks assert that nothing in /usr/local shadows a system command and that `test` run by name is the system one. --- claude-code/CHANGELOG.md | 8 ++++++++ claude-code/Dockerfile | 10 +++++++++- claude-code/app/test/image/behaviour-pins.sh | 14 ++++++++++++++ claude-code/config.yaml | 2 +- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/claude-code/CHANGELOG.md b/claude-code/CHANGELOG.md index 8459069..5914f7e 100644 --- a/claude-code/CHANGELOG.md +++ b/claude-code/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [1.62.7] — 2026-11-10 + +### Fixed +- A program that runs the `test` command by name gets the system one again. The bundled hass-mcp + package installed a development launcher under that name ahead of it on the path; the launcher + is no longer installed, and every image is now checked for a bundled command that hides a system + command. + ## [1.62.6] — 2026-11-10 ### Fixed diff --git a/claude-code/Dockerfile b/claude-code/Dockerfile index 9ee5e9a..77472bd 100644 --- a/claude-code/Dockerfile +++ b/claude-code/Dockerfile @@ -211,6 +211,11 @@ RUN arch="$(dpkg --print-architecture)" \ # the HA Token is set): entity/service queries against the Core API. # Pillow: Python imaging for ad-hoc crops/resizes of dashboard screenshots # (ImageMagick's `magick` covers the CLI side). +# hass-mcp's wheel also declares a `test = pytest:main` console script (a +# development entry point, pytest is not a dependency). Installed into +# /usr/local/bin, it would replace the system `test` for anything that runs +# it by name, so it is removed here; the build fails if a file of that name +# is ever something else. # upstream: pypi homeassistant-cli ARG HASS_CLI_VERSION=1.0.0 # upstream: pypi hass-mcp @@ -220,7 +225,10 @@ ARG PILLOW_VERSION=13.0.0 RUN pip install --no-cache-dir --break-system-packages \ "homeassistant-cli==${HASS_CLI_VERSION}" \ "hass-mcp==${HASS_MCP_VERSION}" \ - "Pillow==${PILLOW_VERSION}" + "Pillow==${PILLOW_VERSION}" \ + && if [ -e /usr/local/bin/test ]; then \ + grep -qx 'from pytest import main' /usr/local/bin/test && rm /usr/local/bin/test; \ + fi # Force HTTPS for GitHub clones (plugin marketplaces) — the container has no SSH key. RUN git config --system url."https://github.com/".insteadOf "git@github.com:" diff --git a/claude-code/app/test/image/behaviour-pins.sh b/claude-code/app/test/image/behaviour-pins.sh index c10f5a3..79ebc34 100644 --- a/claude-code/app/test/image/behaviour-pins.sh +++ b/claude-code/app/test/image/behaviour-pins.sh @@ -30,6 +30,20 @@ IMG=5.0.0 rm -rf "${P}" mkdir -p "${P}" +# --- the image as built: nothing bundled shadows a system command --------------- +# /usr/local/bin comes first on PATH, so a bundled tool's stray entry point +# with the name of a system command (a Python package's `test` launcher, say) +# would replace that command for every program that runs it by name. +shadowed="" +for f in /usr/local/bin/* /usr/local/sbin/*; do + [ -e "${f}" ] || continue + for d in /usr/sbin /usr/bin /sbin /bin; do + if [ -e "${d}/${f##*/}" ]; then shadowed="${shadowed} ${f} (${d}/${f##*/})"; break; fi + done +done +eq "nothing in /usr/local shadows a system command" "${shadowed}" "" +eq "test run by name on PATH is the system's" "$(PATH="${BASE_PATH}" env test 1 -eq 1 2>&1; echo "exit $?")" "exit 0" + # --- 0. the real CLI under a prompt API command line ------------------------------ # A prompt API run reads no settings files (--setting-sources ''), so the secrets # guard's hook reaches it only through the managed settings. With only the diff --git a/claude-code/config.yaml b/claude-code/config.yaml index b955374..2d51dc2 100644 --- a/claude-code/config.yaml +++ b/claude-code/config.yaml @@ -1,5 +1,5 @@ name: "Claude Code" -version: "1.62.6" +version: "1.62.7" slug: claude-code description: "Claude Code AI assistant embedded in Home Assistant — web console with tabs, clipboard, file attachments, browser testing, and a bundled HA skill pack" url: "https://github.com/LayerTM/ClaudeInHA" From f2e0ed77de66c23a6a99896ffb29d40fea47bafa Mon Sep 17 00:00:00 2001 From: LayerTM <1336785+LayerTM@users.noreply.github.com> Date: Tue, 10 Nov 2026 12:49:13 +0100 Subject: [PATCH 2/2] List the test launcher fix under the coming 1.63.0 The fix ships with the next minor release instead of a patch of its own, so the add-on version stays at 1.62.6 until that release sets it. --- claude-code/CHANGELOG.md | 2 +- claude-code/config.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/claude-code/CHANGELOG.md b/claude-code/CHANGELOG.md index 5914f7e..801459f 100644 --- a/claude-code/CHANGELOG.md +++ b/claude-code/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [1.62.7] — 2026-11-10 +## [1.63.0] — 2026-11-10 ### Fixed - A program that runs the `test` command by name gets the system one again. The bundled hass-mcp diff --git a/claude-code/config.yaml b/claude-code/config.yaml index 2d51dc2..b955374 100644 --- a/claude-code/config.yaml +++ b/claude-code/config.yaml @@ -1,5 +1,5 @@ name: "Claude Code" -version: "1.62.7" +version: "1.62.6" slug: claude-code description: "Claude Code AI assistant embedded in Home Assistant — web console with tabs, clipboard, file attachments, browser testing, and a bundled HA skill pack" url: "https://github.com/LayerTM/ClaudeInHA"