#!/usr/bin/env bash # Purpose: Resolve the Python interpreter that actually WORKS on this machine and exec it # with the given args. Skill/command docs call this instead of a bare `py` so the # same documented command runs everywhere. # Why: `py` is the Windows py-launcher (absent on Linux/macOS -> exit 127), while # `python3` is a broken MS Store shim on some Windows boxes. Neither literal is # portable. This picks the first interpreter that genuinely executes. # Usage: bash "$CLAUDETOOLS_ROOT/.claude/scripts/py.sh" [args...] # (mirrors the py/python/python3 fallback already used inside the .sh skill scripts) # Origin: added 2026-06-14 to close the py-vs-python3 doc gap (errorlog.md, GURU-KALI). set -u # A candidate is only valid if it RUNS — this skips the MS Store python3 stub, which # exists on PATH but exits non-zero (prompting a store install) instead of executing. _works() { command -v "$1" >/dev/null 2>&1 && "$1" -c 'import sys' >/dev/null 2>&1; } PY="" # 1) Honor identity.json's declared command first (authoritative per-machine), if it works. ROOT="${CLAUDETOOLS_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}" ID="$ROOT/.claude/identity.json" if [ -f "$ID" ]; then cand=$(sed -n 's/.*"command"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$ID" | head -1) [ -n "$cand" ] && _works "$cand" && PY="$cand" fi # 2) Fall back to autodetect: py (Win launcher) -> python3 -> python, first that works. if [ -z "$PY" ]; then for c in py python3 python; do _works "$c" && { PY="$c"; break; }; done fi [ -z "$PY" ] && { echo "[py.sh] no working python found (tried identity.json, py, python3, python)" >&2; exit 127; } exec "$PY" "$@"