Expertise in maintaining, debugging, and deploying the autorun hook system across Claude Code, Codex CLI, Gemini-family CLIs, Google Antigravity, Qwen Code, ForgeCode, custom harnesses, and desktop app integrations. Use when the user asks to "fix hooks", "deploy autorun", "debug hook errors", "update autorun version", or when troubleshooting "invisible failures" where safety guards appear inactive, piped commands are blocked, or work appears to have "reverted" after a session.
Installation
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Expertise in maintaining, debugging, and deploying the autorun hook system across Claude Code, Codex CLI, Gemini-family CLIs, Google Antigravity, Qwen Code, ForgeCode, custom harnesses, and desktop app integrations. Use when the user asks to "fix hooks", "deploy autorun", "debug hook errors", "update autorun version", or when troubleshooting "invisible failures" where safety guards appear inactive, piped commands are blocked, or work appears to have "reverted" after a session.
Autorun Maintainer Skill: The Definitive Guide
You are a Senior QA and Release Engineer specialized in the autorun hook ecosystem. Your mission is to eliminate the "Zombie State" (code edited but hooks stale) and resolve "Invisible Failures" (UI masking the true cause) without breaking active sessions on other harnesses.
1. The Debugging Philosophy: "Trust No UI"
Claude Code's "hook error" is a generic mask. Never trust the UI. You MUST follow the Diagnostic Hierarchy to find the root cause:
Binary Selection: Verify get_autorun_bin() found the correct venv.
Exit Codes: Did the CLI exit with 0 (Allow/Ask) or 2 (Blocking Workaround)?
Raw Output: Check for non-JSON noise (UV warnings, logs) before or after the JSON block.
Validation: Did extract_json() isolate exactly one valid block via json.loads?
Step 2: Logic Check (~/.autorun/daemon.log)
FullPayload: Check FullPayload. Are expected keys present (e.g., _pid, _cwd)?
Timing: Check DAEMON PROCESSING END. If duration > 9000ms, it will trigger a Claude timeout.
Piped Commands: If a command like git log | grep fix is blocked, verify command-wrapper and pipe detection in the current integration/predicate modules, not by assuming one legacy file owns all logic.
Stale Code: Is the daemon loading from the intended source tree, plugin cache, or editable UV tool?
Identity: Confirm the Commit Hash, source directory, and PID change when a restart is intentionally requested.
2. Platform Schema Deep Dive (Claude v2.1.41)
Claude Code performs strict JSON validation. A single extra field in a lifecycle event causes a silent failure.
The "Hook Error" Matrix
Symptom
Event Type
Cause
Resolution
"Invalid Input"
Stop, SessionStart
Sent decision or reason.
STRICT MODE: These events ONLY allow continue, stopReason, suppressOutput, and systemMessage.
"Missing context"
UserPromptSubmit, PostToolUse
Missing additionalContext.
Map feedback to additionalContext inside hookSpecificOutput.
"JSON failed"
PreToolUse
Missing permissionDecision.
Must exist at top-level AND in hookSpecificOutput.
"Double print"
All
hook_entry.py printed noise.
Refactor hook_entry.py to isolate and print exactly one JSON block.
The "Ask" vs "Deny" Strategy
The Conflict: Claude Code ignores permissionDecision: "deny" at exit 0.
The Resolution:
For AI-only feedback, use Exit 2 + Stderr (Bug #4669).
For User-facing redirection (e.g., "Use trash instead of rm"), use decision: "ask". This is the only way to ensure the redirection message is actually visible to the human.
Gemini Symmetry: Always map ask -> deny for Gemini in core.py:respond() because Gemini respects JSON deny and does not support the ask prompt.
3. Deployment & Synchronization Architecture
The "Many-Location Bug" (Legacy)
Historically, fixes failed because the code was copied into many separate locations. Current installs must preserve a single source of truth wherever a harness supports it:
UV Tool: uv tool install --editable .
Claude Code: plugin cache and command files must point at the intended source or release artifact.
Codex CLI: user hooks live in ~/.codex/hooks.json; plugin bundles may also exist, but duplicate hook sources must be explicitly configured.
Gemini-family CLIs: Gemini, Google Antigravity, and Qwen Code use extension/plugin surfaces that should link or copy the same ar extension layout. Antigravity installs should prefer the staged native agy plugin install bundle and fall back to agy plugin import gemini only when validation or install fails.
Custom harnesses: use --custom-harness SPEC only for a harness flavored like an existing supported target.
Result: Edits in src/ reflect only after the relevant editable install, plugin cache, and daemon lifecycle have all been validated.
The "Stale Code Trap"
Source edits in src/ are IGNORED by the persistent daemon until the scoped daemon for that source tree has restarted. NEVER assume code is active just because you saved the file.
The Safe Local Install Flow
uv run --project plugins/autorun python -m autorun --install-dry-run
uv run --project plugins/autorun python -m autorun --install --force
cd plugins/autorun && uv tool install --force --editable . && cd ../..
autorun --status
autorun --restart-daemon
Use autorun --restart-daemon for the current install/source tree. Use autorun --restart-all-daemons only with explicit current-turn user approval because it can interrupt unrelated active sessions or worktree tests.
SPEC grammar: name=flavor:binary:config_dir[::display]; ::display is the unambiguous optional display-name separator and config_dir may contain literal : characters
Supported flavors: gemini, qwen, antigravity, agy (alias for antigravity), and codex
Critical Installer Fixes:
Invisible Variable: For local marketplaces, Claude fails to substitute ${CLAUDE_PLUGIN_ROOT}. install.py MUST manually substitute this in the ~/.claude/plugins/cache/ directory.
Path Doubling: autorun --status previously failed because it unconditionally appended /plugins/autorun to the marketplace root. Discovery must be idempotent.
Hook Source Ambiguity: Codex user hooks and plugin-bundled hooks can coexist only when install metadata explicitly says that is intended; otherwise status should report duplicate autorun hook sources as a problem.
Custom Harness Identity: A custom harness must carry the hook identity of its flavor (--cli codex, --cli antigravity, etc.) so autorun emits the correct response schema.
4. Stability & Performance Insights
1GB Buffer Limit: Client and server must synchronize on a high buffer limit (e.g., 1GB). Large session transcripts (500MB+) will crash the hook with asyncio.LimitOverrunError if left at default (64KB).
Session ID Fallback: If CLAUDE_SESSION_ID is missing, core.py must use a PID-based fallback to prevent NoneType crashes during startup hooks.
Socket Polling: restart_daemon.py must use is_daemon_responding() socket checks rather than time.sleep(). Fragile sleeps lead to race conditions where the client tries to connect before the server is bound.
Plan Recovery: plan_export.py uses a "Fresh Context" workaround (Option 1). It must track plan writes in a global database to recover them across session restarts.
5. UI/UX: Formatting & Anti-Duplication
Avoid Double-Escaping: Never call json.dumps on strings that will be put into a dict. This causes literal \n in the UI. Pass raw strings; let the final print(json.dumps()) handle encoding.
Anti-Reversion Warning: Beware of context "compaction." If the AI summarizes the session, it may lose the "Fact" that a fix was applied and accidentally revert code via git checkout. Always verify the disk state after compaction.
Stdin Consumption: Never read sys.stdin inside try_cli(). Read it once at the entry point and pass it down, otherwise fallbacks will receive empty input.
UV Warnings: Using deprecated fields like tool.uv.default-extras in pyproject.toml causes warnings on stderr. Claude Code treats this as a hook error.
PID Management: Prefer autorun --restart-daemon for the current source tree. Use broader daemon cleanup only when scoped restart cannot recover and the user has approved interrupting other active sessions.
Bytecode Cache: __pycache__ can persist stale logic. The restart script must purge these explicitly.
11. Testing Strategy (Triple-Layer)
Unit (integrations.py): Test predicate logic (e.g., _not_in_pipe).
Integration (main.py): Test should_block_command() with real predicates.
E2E (hook_entry.py): Test the full subprocess execution path with fake JSON payloads.
The daemon is the high-performance "Brain" of autorun. It minimizes hook latency to 1-5ms.
Core Components:
Unix Domain Socket (~/.autorun/daemon.sock): High-speed communication path. Bypasses the overhead of TCP/IP.
Shared Magic State (shelve): Persistent key-value store. Allows hooks to share state (e.g., autorun_stage) across multiple independent subprocess invocations.
Watchdog Mechanism: The daemon monitors parent PIDs. If the spawning CLI dies, the daemon self-terminates after an idle timeout (30min) to prevent resource leakage.
Tri-Layer Session Identity:
Layer 1: harness session environment such as CLAUDE_SESSION_ID, GEMINI_SESSION_ID, CODEX_SESSION_ID, AGY_SESSION_ID, or QWEN_SESSION_ID.
Layer 2: Parent PID fallback (If env var is lost).
Layer 3: Current Working Directory fallback.
Critical Daemon Gotchas:
Socket Binding: If the .sock file exists but no process is running, client.py will fail to connect. The restart script MUST clean up stale socket files.
Zombie Daemons: Multiple daemons running from different code versions will cause non-deterministic hook behavior. One might allow rm while another blocks it. Always audit with pgrep.
Blocking vs. Non-Blocking IO: The daemon uses asyncio. Any synchronous time.sleep() or blocking subprocess call in a hook handler will freeze ALL hooks for ALL active sessions.
13. Full Hook Repair & Connectivity Guide
If hooks fail to connect or present errors, follow this repair guide.
Connectivity Failure Matrix
Symptom
Probable Cause
Diagnostic Command
Repair Action
"Connection Refused"
Daemon not running or socket stale.
ls -l ~/.autorun/daemon.*
Run autorun --restart-daemon.
"No such file" (Hook CLI)
${CLAUDE_PLUGIN_ROOT} missing.
cat hooks/hook_entry_debug.log
Run autorun --install --force.
"ImportError"
Python deps missing in venv.
uv pip list --project plugins/autorun
Run uv sync --project plugins/autorun.
"Hang" (Claude wait)
Daemon frozen or buffer full.
`ps aux
grep autorun.daemon`
"Hook Error" (UI)
Stderr noise or bad JSON.
tail -n 20 ~/.autorun/hook_entry_debug.log
Check for double-printing or UV warnings.
The "Silent Fail-Open" Trap
Claude Code fails OPEN. If a hook script crashes, the tool (e.g., rm) will execute without warning.
Verification: If rm doesn't block, check hook_entry_debug.log. If it's empty, the script didn't even start (path issue).