Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions claude-code/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## [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
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
Expand Down
10 changes: 9 additions & 1 deletion claude-code/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:"
Expand Down
14 changes: 14 additions & 0 deletions claude-code/app/test/image/behaviour-pins.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading