Get the FREE Ultimate OpenClaw Setup Guide →

Notes

Scanned
npx machina-cli add skill ahundt/autorun/notes --openclaw
Files (1)
SKILL.md
4.5 KB

Clautorun Meta-Skill: The Definitive Guide to Hooks & Deployment

This document is the "Source of Truth" for maintaining and debugging the clautorun hook system. It covers the architectural "Invisible Failures," strict schema requirements for Claude Code and Gemini CLI, and the mandatory synchronization workflow.


1. The Debugging Philosophy: "Trust No UI"

Claude Code's "hook error" is a generic mask that hides the true cause. Never assume the UI tells the whole story. Use the hierarchy of logs to find the "Invisible Failure":

  1. Plumbing Check (~/.clautorun/hook_entry_debug.log):
    • Did the binary even start?
    • Did it exit with 0 or 2?
    • What was the exact raw string it printed? (Look for noise before/after JSON).
  2. Logic Check (~/.clautorun/daemon.log):
    • Did the daemon receive the request?
    • What were the keys in the FullPayload?
    • Check DAEMON PROCESSING END for millisecond timing.
  3. Source Check (~/.clautorun/daemon_startup.log):
    • Is the daemon loading from .../cache/... (STALE) or .../plugins/clautorun/src/... (FRESH)?
    • Verify the Commit Hash and PID change on every restart.

2. Platform Schema Specifications (Claude v2.1.41)

Claude Code strictly validates JSON. Violating these rules causes a "hook error" that silently disables clautorun.

The "Hook Error" Matrix

SymptomEvent TypeCauseResolution
"Invalid Input"Stop, SessionStartSent decision or reasonSTRICT MODE: Return only continue, systemMessage, etc.
"Missing context"UserPromptSubmitMissing additionalContextMap your reason to additionalContext in hookSpecificOutput.
"JSON failed"PreToolUseMissing permissionDecisionMust exist at top-level AND in hookSpecificOutput.
"Double print"Allhook_entry.py printed noiseRefactor hook_entry.py to isolate and print exactly one JSON block.

Table-Driven Enforcement (core.py)

Always use HOOK_SCHEMAS and validate_hook_response() to filter output.

  • Claude: Maps ask -> ask (shows user prompt).
  • Gemini: Maps ask -> deny (Gemini respects JSON deny).

3. Deployment & Synchronization Workflow

The "One-Liner of Truth" (Mandatory)

uv run --project plugins/clautorun python -m clautorun --install --force && \
cd plugins/clautorun && uv tool install --force --editable . && cd ../.. && \
clautorun --restart-daemon

Critical Synchronization Gotchas:

  1. The Stale Code Trap: The daemon is persistent. Code edits in src/ are ignored until clautorun --restart-daemon is run.
  2. The Invisible Variable: For local marketplaces, Claude does not substitute ${CLAUDE_PLUGIN_ROOT}. install.py must manually sed-replace this in ~/.claude/plugins/cache/ files.
  3. Editable Tool: If the tool isn't installed with --editable, hooks might pick up an old global version of clautorun instead of your repo.

4. UI/UX: Formatting & Deduplication

  • Avoid Double-Escaping: Never manually call json.dumps() on a string that goes into a dict. This causes literal \n in the UI. Pass raw strings and let the final boundary handle encoding.
  • Deduplicate: Claude shows systemMessage, hookSpecificOutput.permissionDecisionReason, and stderr (exit 2) simultaneously.
    • Rule: For rejections, clear top-level reason and systemMessage. Let specific fields handle it.
  • Exit 2 Workaround (#4669): To block a tool in Claude, you must exit with code 2 and print the reason to stderr.

5. Automated Metadata & Versioning

Metadata must never be hardcoded. Use the automated system:

  • Capture: install.py calls git describe --always --dirty=+.
  • Storage: Metadata is written to src/clautorun/metadata.json (Ignored by Git).
  • Loading: __init__.py robustly loads this at runtime.
  • Naming: Always use + for uncommitted changes (e.g., 9d9ba0f+) for professional logs.

6. Verification Sources

  • Claude Hooks Reference: https://code.claude.com/docs/en/hooks
  • Claude Schema Output: https://code.claude.com/docs/en/hooks#json-output
  • Gemini Hooks Reference: https://geminicli.com/docs/hooks/reference/
  • Claude Bug #4669 (Exit 2): https://claude.com/blog/how-to-configure-hooks

Synthetic Verification

# Test schema compliance without starting Claude:
echo '{"hook_event_name":"SessionStart"}' | clautorun

Source

git clone https://github.com/ahundt/autorun/blob/main/notes/CLAUTORUN_META_SKILL.mdView on GitHub

Overview

Notes for maintaining and debugging the Clautorun hook system. It documents the debugging hierarchy, strict platform schemas, and the mandatory synchronization workflow, helping teams diagnose invisible failures and keep clautorun reliable.

How This Skill Works

Follow the 'Trust No UI' philosophy to diagnose failures by inspecting three logs: Plumbing at ~/.clautorun/hook_entry_debug.log, Logic at ~/.clautorun/daemon.log, and Source at ~/.clautorun/daemon_startup.log. Claude Code enforces JSON via HOOK_SCHEMAS and validate_hook_response(), while the One-Liner of Truth installs updates and restarts the daemon to load fresh code. This structured workflow makes hidden issues visible and fixes predictable.

When to Use It

  • To diagnose a hook error where the UI hides the real cause.
  • To confirm the daemon is loading fresh code (not stale cache) after edits.
  • During deployment, to follow the mandatory synchronization workflow and restart daemon.
  • When encountering a 'Double print' or noisy JSON, to isolate printing to a single JSON block.
  • When you need to ensure UI/UX formatting, deduplication, and proper errorReason handling.

Quick Start

  1. Step 1: Read the Notes to understand the three-log debugging model and the deployment workflow.
  2. Step 2: Run the One-Liner of Truth to install and restart the daemon.
  3. Step 3: Inspect Plumbing (~/.clautorun/hook_entry_debug.log), Logic (~/.clautorun/daemon.log), and Source (~/.clautorun/daemon_startup.log) to confirm a fresh load and timing.

Best Practices

  • Use the three-log hierarchy (Plumbing, Logic, Source) to locate invisible failures.
  • Always apply HOOK_SCHEMAS and validate_hook_response() to filter tool outputs.
  • Check that the daemon loads from the fresh path and that Commit Hash and PID change on restart.
  • Run the One-Liner of Truth (install, restart) before testing changes.
  • Follow UI rules: avoid double-escaping, deduplicate top-level fields, and print clear reasons.

Example Use Cases

  • Diagnosing a Claude Code 'hook error' by tracing Plumbing, Logic, and Source logs.
  • Verifying fresh code load by comparing cache path vs plugins/clautorun/src on startup.
  • Applying the One-Liner of Truth to reinstall and restart the daemon.
  • Watching Commit Hash and PID updates on each restart.
  • Refactoring hook_entry.py to print only a single JSON block.

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers