From e63241c6993eb78eea1c635e174e159e052293dd Mon Sep 17 00:00:00 2001 From: suusuu0927 <269936893+suusuu0927@users.noreply.github.com> Date: Wed, 22 Apr 2026 07:39:06 +0900 Subject: [PATCH] fix(observe): skip Windows AppInstallerPythonRedirector.exe in resolve_python_cmd (#1511) On Windows 10/11 without Python installed from the Microsoft Store, the "App Execution Alias" stubs at %LOCALAPPDATA%\Microsoft\WindowsApps\python.exe and python3.exe are symlinks to AppInstallerPythonRedirector.exe. These stubs neither launch Python nor honor `-c`; calls print a bare "Python " line and exit, silently breaking every JSON-parsing step in observe.sh. Net effect: observations.jsonl is never written, CLV2 appears installed correctly, and the only residual artifact is `.last-purge`. This commit: 1. Adds `_is_windows_app_installer_stub` helper that detects the stub via `command -v` output and optional `readlink -f` resolution. 2. Teaches `resolve_python_cmd` to skip stub candidates and fall through to the next real interpreter (typically C:\...\Python3xx\python.exe). 3. Exports the stub-aware CLV2_PYTHON_CMD before sourcing detect-project.sh, which already honors an already-set value, so the shared helper does not re-resolve and re-select the stub. POSIX-compatible. No behavior change on macOS / Linux / WSL where no such stub exists. Refs: observations.jsonl empty on Windows Claude Desktop users. --- .../continuous-learning-v2/hooks/observe.sh | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/skills/continuous-learning-v2/hooks/observe.sh b/skills/continuous-learning-v2/hooks/observe.sh index d08b6d0f..9ed6cf8b 100755 --- a/skills/continuous-learning-v2/hooks/observe.sh +++ b/skills/continuous-learning-v2/hooks/observe.sh @@ -27,18 +27,45 @@ if [ -z "$INPUT_JSON" ]; then exit 0 fi +_is_windows_app_installer_stub() { + # Windows 10/11 ships an "App Execution Alias" stub at + # %LOCALAPPDATA%\Microsoft\WindowsApps\python.exe + # %LOCALAPPDATA%\Microsoft\WindowsApps\python3.exe + # Both are symlinks to AppInstallerPythonRedirector.exe which, when Python + # is not installed from the Store, neither launches Python nor honors "-c". + # Calls to it hang or print a bare "Python " line, silently breaking every + # JSON-parsing step in this hook. Detect and skip such stubs here. + local _candidate="$1" + [ -z "$_candidate" ] && return 1 + local _resolved + _resolved="$(command -v "$_candidate" 2>/dev/null || true)" + [ -z "$_resolved" ] && return 1 + case "$_resolved" in + *AppInstallerPythonRedirector.exe|*AppInstallerPythonRedirector.EXE) return 0 ;; + esac + # Also resolve one level of symlink on POSIX-like shells (Git Bash, WSL). + if command -v readlink >/dev/null 2>&1; then + local _target + _target="$(readlink -f "$_resolved" 2>/dev/null || readlink "$_resolved" 2>/dev/null || true)" + case "$_target" in + *AppInstallerPythonRedirector.exe|*AppInstallerPythonRedirector.EXE) return 0 ;; + esac + fi + return 1 +} + resolve_python_cmd() { if [ -n "${CLV2_PYTHON_CMD:-}" ] && command -v "$CLV2_PYTHON_CMD" >/dev/null 2>&1; then printf '%s\n' "$CLV2_PYTHON_CMD" return 0 fi - if command -v python3 >/dev/null 2>&1; then + if command -v python3 >/dev/null 2>&1 && ! _is_windows_app_installer_stub python3; then printf '%s\n' python3 return 0 fi - if command -v python >/dev/null 2>&1; then + if command -v python >/dev/null 2>&1 && ! _is_windows_app_installer_stub python; then printf '%s\n' python return 0 fi @@ -52,6 +79,11 @@ if [ -z "$PYTHON_CMD" ]; then exit 0 fi +# Propagate our stub-aware selection so detect-project.sh (which is sourced +# below) does not re-resolve and silently fall back to the App Installer stub. +# detect-project.sh honors an already-set CLV2_PYTHON_CMD. +export CLV2_PYTHON_CMD="${CLV2_PYTHON_CMD:-$PYTHON_CMD}" + # ───────────────────────────────────────────── # Extract cwd from stdin for project detection # ─────────────────────────────────────────────