Hooks
What token-optimizer runs automatically, and when. A hook is a command Claude Code fires at a fixed moment, without you asking for it.
> /plugin marketplace add alexgreensh/token-optimizer > /plugin install token-optimizer@alexgreensh-token-optimizer
Ships with token-optimizer. Installing the plugin gets these hooks.
What fires, and when
PreToolUse
- Matches
Readfor b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/read_cache.py --quiet; done; exit 0 - Matches
Bashfor b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/bash_hook.py --quiet; done; exit 0 - Matches
Agent|Taskfor b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py checkpoint-trigger --milestone pre-fanout - Matches
mcp__.*for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/refetch_guard.py --quiet; done; exit 0
PreCompact
for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py dynamic-compact-instructions --quiet; donefor b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py compact-capture --trigger auto --quiet; dofor b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/read_cache.py --clear --quiet; done; exit 0
SessionStart
Fires once when a session begins, and again after a context compaction. It is where a plugin sets up its environment, or restores state the compaction dropped.
for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py ensure-health; done; exit 0for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py quality-cache --force --quiet; done; exit- Matches
compactfor b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py compact-restore --compact; done; exit 0for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/read_cache.py --clear-compacted --quiet; done; exit 0 for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py compact-restore --new-session-only; done;
Stop
for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py compact-capture --trigger stop --quiet; dofor b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py session-end-flush --trigger stop --quiet -for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py keepwarm-arm --quiet; done; exit 0
SessionEnd
for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py session-end-flush --trigger end --defer; d
StopFailure
for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py compact-capture --trigger stop-failure --q
UserPromptSubmit
Fires before Claude sees each prompt you send. A plugin can use it to inject context, so the same instruction reaches the model every turn instead of only at session start.
for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py quality-cache --warn --quiet; done; exit 0for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py prompt-continuity --quiet; done; exit 0for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py verbosity-steer --quiet; done; exit 0
PostToolUse
- Matches
mcp__.*for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/archive_result.py --quiet; done; exit 0 - Matches
Bash|Read|Glob|Grep|Agentfor b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/archive_result.py --quiet; done; exit 0 - Matches
Bash|Read|Grep|Glob|mcp__.*for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/context_intel.py --quiet; done; exit 0 - Matches
Edit|Write|MultiEdit|NotebookEditfor b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/read_cache.py --invalidate --quiet; done; exit 0 - Matches
Bash|Read|Glob|Grep|Agent|Edit|Write|MultiEdit|NotebookEdit|mcp_for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py quality-cache --quiet --throttle-only; don
PostCompact
for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/measure.py quality-cache --force --quiet; done; exit
CwdChanged
for b in bash /bin/bash /usr/bin/bash /usr/local/bin/bash /opt/homebrew/bin/bash; do command -v "$b" >/dev/null 2>&1 && exec "$b" "${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh" "${CLAUDE_PLUGIN_ROOT}/hooks/run.py" skills/token-optimizer/scripts/read_cache.py --clear --quiet; done; exit 0
Where it lives
- hooks/module_runner.pyGitHub
Read the script
#!/usr/bin/env python3 """Runs a hook script as a module instead of as `__main__`, so CPython reuses its __pycache__ bytecode across invocations. Script-mode execution (`python foo.py`) never checks or writes __pycache__ for the file being run as __main__ -- only for things it imports. Since every hook call is a fresh process, running measure.py (35k+ lines) as a script recompiles it from source every single time: ~0.3s of pure CPython parse/compile on top of whatever the hook actually does. Module-mode goes through the import system, which does check/write __pycache__, cutting that to ~0.1s after the first call. sys.path is stripped of '' and '.' (the cwd-equivalent entries the interpreter would otherwise add) before inserting scripts_dir explicitly, so a same-named file in the invoking project's own working directory (e.g. a project that happens to have its own measure.py at its root) can never shadow the plugin's module. """ from __future__ import annotations import os import runpy import sys def _warn_readonly_scripts_dir_once(scripts_dir: str) -> None: """If scripts_dir isn't writable, __pycache__ can't be written and CPython recompiles the target from source on every call — the perf win silently evaporates. Surface it, but at most once per day per user so we don't spam stderr on the per-tool-call hot path. The marker lives in the OS temp dir (writable even when the plugin install dir is read-only, which is the whole failure mode). Best-effort: any error here must never break the hook.""" try: if os.access(scripts_dir, os.W_OK): return # normal case — bytecode cache works, stay silent import hashlib import tempfile import time tag = hashlib.sha1(scripts_dir.encode("utf-8", "replace")).hexdigest()[:12] marker = os.path.join(tempfile.gettempdir(), f".token-optimizer-ro-pyc-{tag}") try: fresh = (time.time() - os.path.getmtime(marker)) < 86400 except OSError: fresh = False if fresh: return with open(marker, "w", encoding="utf-8") as fh: fh.write(str(time.time())) sys.stderr.write( f"[Token Optimizer] note: {scripts_dir} is not writable, so Python " "bytecode (__pycache__) can't be cached — hooks will be slower than " "expected. Make the plugin scripts dir writable to restore the speedup.\n" ) except Exception: pass def main() -> int: if len(sys.argv) < 3: return 0 scripts_dir = sys.argv[1] module_name = sys.argv[2] script_args = sys.argv[3:] # Defense-in-depth: don't rely solely on run.py sanitizing these. Refuse a # module_name that isn't a bare Python identifier (blocks path separators, # dots, and traversal), and require the resolved target to actually exist in # scripts_dir. Fail OPEN (return 0) rather than raise — a hook must never # crash the tool call. Without this, any future caller that skipped run.py's # own validation would hand runpy an arbitrary-module-execution primitive. if not module_name.isidentifier(): return 0 if not os.path.isfile(os.path.join(scripts_dir, module_name + ".py")): return 0 _warn_readonly_scripts_dir_once(scripts_dir) sys.path = [p for p in sys.path if p not in ("", ".")] sys.path.insert(0, scripts_dir) sys.argv = [module_name, *script_args] runpy.run_module(module_name, run_name="__main__", alter_sys=True) return 0 if __name__ == "__main__": sys.exit(main()) - hooks/python-launcher.shRunsGitHub
Read the script
#!/usr/bin/env bash # Locate a usable Python 3 interpreter and exec it with the given arguments. # Survives: # - macOS / Linux (python3 on PATH) # - Windows python.org installs at spaced paths like "C:\Program Files\Python313\" # - Windows py-launcher-only installs (py -3) # - Windows Store Python (real installs proven alive via a flash-free # GUI-twin proof-of-life probe, console --version probe as the fallback # authority; non-functional AppExecutionAlias stubs skipped automatically) # On Windows (Git Bash/MSYS), exec prefers the GUI-subsystem twin over the # console binary to avoid the per-hook console-window flash and orphaned # conhost.exe: python.exe/python3.exe swap to pythonw.exe, and py.exe (the # py-launcher) swaps to pyw.exe beside it, so py-launcher-only installs no # longer flash (#107). See _maybe_swap_to_pythonw for the constraints. # Exits 127 with a diagnostic message if none found. set -eu # C7: extglob enables +([0-9]) in the version-number case patterns below so # the glob is anchored to the path-component boundary. Without it, * in a # case pattern crosses / and Python[23]* matches Python3-evil/python.exe. shopt -s extglob # Known-safe prefixes for Python interpreter binaries. # Binaries outside these directories are rejected even if on PATH. # This prevents a compromised PATH entry from hijacking the interpreter. # All prefixes are hardcoded (not derived from PATH-controlled binaries # like `brew --prefix`, which would be circular trust). _SAFE_PREFIXES="/usr/bin /usr/local/bin /opt/homebrew/bin /opt/homebrew/opt /home/linuxbrew/.linuxbrew/bin" _is_safe_prefix() { local IFS=$' \t\n' local binpath="$1" prefix # Reject path traversal FIRST: a '..' component lets a textual prefix match # (e.g. /usr/bin/../../tmp/evil/python3) pass the allow-list globs below yet # resolve OUTSIDE a trusted dir at exec time. Interpreter paths are absolute # and never legitimately contain a '..' path component. case "$binpath" in *"/../"*|*"/..") return 1 ;; esac for prefix in $_SAFE_PREFIXES; do case "$binpath" in "$prefix"/*) return 0 ;; esac done # Windows install locations (git-bash/MSYS path form, e.g. /c/...). # Drive-letter-anchored to preserve the anti-PATH-hijack intent. # Version-number suffixes block directory-name spoofing (e.g. Python3-evil). case "$binpath" in # C7: +([0-9]) anchors the version suffix to digits-only so a spoofed # dir name like Python3-evil cannot pass (previously * crossed / and # matched Python3-evil/python.exe). The trailing /* requires a path # separator after the version component. /[a-zA-Z]/Program\ Files/Python[23]+([0-9])/*) return 0 ;; /[a-zA-Z]/Program\ Files\ \(x86\)/Python[23]+([0-9])/*) return 0 ;; /[a-zA-Z]/Python3+([0-9])/*) return 0 ;; /[a-zA-Z]/Users/*/AppData/Local/Programs/Python/*) return 0 ;; /[a-zA-Z]/Users/*/AppData/Local/Microsoft/WindowsApps/*) return 0 ;; # All-users `py` launcher lives in the (admin-only-writable) Windows dir. # Exact filename keeps the anti-hijack intent (no wildcard in that dir). /[a-zA-Z]/Windows/py.exe) return 0 ;; /[a-zA-Z]/Windows/pyw.exe) return 0 ;; esac # C8: case-insensitive WindowsApps allow for Windows-style drive-letter # paths. On a case-insensitive FS the dir can be any casing; the drive- # letter anchor ([a-zA-Z]/) constrains this to Windows-style paths so # Linux is unaffected. case "$binpath" in /[a-zA-Z]/*) _path_contains_windowsapps "$binpath" && return 0 ;; esac return 1 } # The cache is an optional optimization only. Any setup, read, or write failure # leaves _PY_CACHE_FILE empty (or is ignored) so interpreter discovery proceeds # exactly as it did before caching was added. _PY_CACHE_FILE="" _is_msys_platform() { local platform platform=$(uname -s 2>/dev/null) || return 1 case "$platform" in MINGW*|MSYS*|CYGWIN*) return 0 ;; esac return 1 } # C8: Windows is case-insensitive, so the WindowsApps directory can appear in # any casing (WindowsApps, windowsapps, WINDOWSAPPS, Windowsapps). The old # explicit-variant patterns (*/WindowsApps/*|*/windowsapps/*) only covered # two casings and would miss others, letting a Store AppExecutionAlias stub # through unprobed or skipping a legit Store install in the safe-prefix list. # tr is POSIX and present in every supported hook env including Git Bash. _path_contains_windowsapps() { local lower lower=$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]') case "$lower" in */windowsapps/*) return 0 ;; esac return 1 } _cache_dir_is_per_user() { local cache_dir="$1" cache_real root root_real cache_real=$(CDPATH='' cd -- "$cache_dir" 2>/dev/null && pwd -P) || return 1 for root in "${XDG_CACHE_HOME:-}" "${HOME:-}"; do [ -n "$root" ] && [ -d "$root" ] || continue root_real=$(CDPATH='' cd -- "$root" 2>/dev/null && pwd -P) || continue case "$cache_real" in "$root_real"/*) return 0 ;; esac done return 1 } _cache_dir_ready() { local cache_dir="$1" if [ ! -d "$cache_dir" ]; then (umask 077; mkdir -p "$cache_dir") >/dev/null 2>&1 || return 1 fi [ -d "$cache_dir" ] && [ -w "$cache_dir" ] || return 1 if _is_msys_platform; then # Git Bash/MSYS2/Cygwin emulate POSIX ownership, so `test -O` can reject # the current user's own directory. Canonical confinement under HOME or # XDG_CACHE_HOME supplies the equivalent Windows ACL trust boundary. _cache_dir_is_per_user "$cache_dir" else # On native POSIX, require ownership rather than mere writability so a # planted - hooks/run.pyGitHub
Read the script
#!/usr/bin/env python3 """Cross-platform hook dispatcher. Invoked from hooks.json via a small bash launcher that locates a usable Python 3 interpreter on macOS, Linux, and Windows: "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/python-launcher.sh\" \"${CLAUDE_PLUGIN_ROOT}/hooks/run.py\" <script-relative-path> [args...]" The launcher handles Windows-specific gotchas (Program Files spaced paths, Microsoft Store zero-byte stubs in WindowsApps, py launcher fallback) so this file can assume it's running under a real Python 3.9+. This dispatcher resolves the target script under CLAUDE_PLUGIN_ROOT, checks it exists, and runs it with the same interpreter (sys.executable). On timeout we kill the child (Popen.kill) to avoid leaking a process holding the trends.db SQLite lock. Always exits 0 so hook failures never block the user's tool call. Windows reap note: module_runner.py runs measure.py IN-PROCESS via runpy.run_module, so the child proc IS measure.py (the trends.db lock holder), not a grandchild. On Windows we reap with plain proc.kill() (TerminateProcess of proc.pid only), NOT taskkill /F /T which would walk the PPID tree and wrongly kill the detached session-end-flush worker (the one CREATE_BREAKAWAY_FROM_JOB exists to keep alive). The SIGINT/ SIGTERM handler only fires for console Ctrl+C or in-process os.kill; an external TerminateProcess from the host bypasses Python handlers entirely. """ from __future__ import annotations import json import os import signal import subprocess import sys from pathlib import Path # Defense in depth: the launcher script already filters interpreters, but # if a user's PATH has a stale Python 3.7 that slipped through, bail early # so later imports don't explode with confusing SyntaxError noise. if sys.version_info < (3, 9): sys.exit(0) # Module-level handle so the signal handler can reach the active child when # Claude Code (or any parent) sends SIGTERM/SIGINT to run.py itself. Without # this, an external kill reaps run.py but orphans the measure.py grandchild, # which keeps the inherited stdout pipe open and makes the parent hang waiting # for EOF (the multi-minute stop-hook hang). _child_proc: subprocess.Popen | None = None def _reap(proc, posix_sig): """Reap the child process. Never raises. On Windows, the child proc IS measure.py (module_runner.py runs it in-process via runpy.run_module), so a plain ``proc.kill()`` (TerminateProcess of proc.pid only) releases the trends.db lock without walking the PPID tree and killing the detached session-end-flush worker (the one CREATE_BREAKAWAY_FROM_JOB exists to keep alive). On POSIX, the child is started with ``start_new_session=True`` so it leads its own process group; killing the group reaps any grandchildren (the launcher chain uses ``exec``, so run.py's PID is the one the host tracks). Falls back to ``proc.kill()`` when the group is already gone. """ if proc.poll() is not None: return if os.name == "nt": try: proc.kill() except OSError: try: sys.stderr.write("run.py: nt reap kill failed\n") sys.stderr.flush() except (OSError, ValueError): pass elif hasattr(os, "killpg"): try: os.killpg(os.getpgid(proc.pid), posix_sig) except (ProcessLookupError, OSError): try: proc.kill() except OSError: try: sys.stderr.write("run.py: posix reap kill failed\n") sys.stderr.flush() except (OSError, ValueError): pass else: try: proc.kill() except OSError: try: sys.stderr.write("run.py: fallback reap kill failed\n") sys.stderr.flush() except (OSError, ValueError): pass def _forward_and_exit(signum, frame): """Forward SIGTERM/SIGINT to the child, then exit. On Windows this handler only fires for console Ctrl+C or an in-process os.kill; an external TerminateProcess from the host bypasses Python handlers entirely. """ global _child_proc if _child_proc is not None: _reap(_child_proc, signal.SIGTERM) os._exit(0) def _check_consent() -> bool: """Return True if consent is given or assumed. Fail-open on any error.""" try: home = Path.home() # Resolve config path from env (set by Claude Code before hook invocation) plugin_data = os.environ.get("CLAUDE_PLUGIN_DATA", "") if plugin_data: pd = Path(plugin_data).resolve() if not str(pd).startswith(str(home)): return True # Path outside home = skip (fail-open) config_path = pd / "config" / "config.json" else: # Legacy / Codex fallback codex_home = os.environ.get("CODEX_HOME", "") if codex_home: ch = Path(codex_home).resolve() if not str(ch).startswith(str(home)): return True config_path = ch / "token-optimizer" / "config.json" else: # Honor CLAUDE_CONFIG_DIR (Claude Code's official config-dir # override) before falling back to ~/.claude. Mirrors # runtime_env.claude_home(): accept any absolute, existing, # non-symlink directory (CLAUDE_CONFIG_DIR may legitimately live # OUTSIDE $HOME — containers, CI), reject relative/symlink, else # fall back. The previous str.startswith($HOME) check both # excluded valid out-of-home dirs and sibling-prefix-matched # (/Users/alex-evil passing for /Users/alex). claude_config = os.environ.get("CLAUDE_CONFIG_DIR", "").strip() cc = None if claude_config: candidate = Path(claude_
Read the script before you install anything that runs on your machine. This is the one part of a plugin that acts without being asked.
Find the ghost tokens. Fix them. Survive compaction. Avoid context quality decay.
Repo: alexgreensh/token-optimizer

