← 2.1.10 Test tested · runtime-test

Setup Hook — runtime test

Hands-on runtime battle-test of Setup Hook. Result: PASS.

Setup Hook is a runtime hook event that runs initialization or maintenance commands at session start, triggered via --init, --init-only, or --maintenance CLI flags.

How It Works

Setup is registered in ~/.claude/settings.json under hooks.Setup, like any other hook event. The runtime fires it with trigger information specifying which flag invoked it. Input includes session_id, transcript_path, cwd, hook_event_name ("Setup"), and trigger ("init" or "maintenance"). The hook script receives this as JSON and can log, configure, or validate before the session begins. Hooks support command execution via type: "command" in the hook definition.

The Test Runtime

Setup hooks were tested against all three CLI patterns on January 16, 2026. For --init (normal session start) and --maintenance (maintenance-mode session), a Setup hook script was registered and invoked via bash. Both fired correctly and passed context including working directory and session ID. The hook ran before the session accepted input, allowing pre-session setup. For --init-only, the Setup hook fired and the CLI exited immediately without starting a session or waiting for a prompt. No user input required. All three triggers correctly received the hook input payload.

What This Enables

--init-only is the significant discovery: a no-session setup mode suitable for CI/CD pipelines, cron jobs, and repository bootstrapping. Standard --init and --maintenance let hooks run initialization logic before accepting interactive prompts. The trigger field in hook input allows a single Setup handler to distinguish init from maintenance without inspecting CLI environment. Combined, these unlock pre-flight validation, environment checks, and cache warming in unattended contexts.

Known Gaps

The --init, --init-only, and --maintenance flags do not appear in claude --help output, creating discoverability friction. Both --init-only and --init use trigger: "init" rather than trigger: "init-only", requiring hook logic to check for session presence if intent differentiation is critical. No documented guarantee on hook execution order when multiple Setup handlers are registered.

Primary source
⎘ 2.1.10/tests/01-setup-hook/TEST-RESULTS.mdverbatim from the corpus

Setup Hook Test Results

Feature: Setup hook event Version: 2.1.10 Status: PASS ✅ Tested: 2026-01-16

What Was Tested

The new Setup hook event that can be triggered via --init, --init-only, or --maintenance CLI flags.

Test Setup

Created hook in ~/.claude/settings.json:

"hooks": {
  "Setup": [
    {
      "hooks": [
        {
          "type": "command",
          "command": "bash /Users/ryanhunter/.claude/hooks/setup-test.sh"
        }
      ]
    }
  ]
}

Hook script logs to /tmp/setup-hook-test.log.

Test Results

--init flag

echo "hello" | claude --init -p

Result: ✅ Setup hook fires Hook input:

{
  "session_id": "...",
  "transcript_path": "...",
  "cwd": "/Users/ryanhunter/projects/claude/claude-feature-demos",
  "hook_event_name": "Setup",
  "trigger": "init"
}

--init-only flag

claude --init-only

Result: ✅ Setup hook fires, then CLI exits immediately (no session) Hook input: Same as --init with "trigger": "init"

Key insight: --init-only runs Setup hooks then exits. No prompt required, no session started. Perfect for CI/automation.

--maintenance flag

echo "test" | claude --maintenance -p

Result: ✅ Setup hook fires Hook input:

{
  "session_id": "...",
  "hook_event_name": "Setup",
  "trigger": "maintenance"
}

Hook Input Schema

Field Type Description
session_id string UUID for the session
transcript_path string Path to session transcript
cwd string Current working directory
hook_event_name string Always "Setup"
trigger string "init" or "maintenance"

Key Findings

  1. Three triggers, two behaviors:

    • --init and --maintenance start a session after Setup hook
    • --init-only exits immediately after Setup hook (no session)
  2. Trigger field distinguishes intent:

    • trigger: "init" for --init and --init-only
    • trigger: "maintenance" for --maintenance
  3. No prompt required for --init-only:

    • Perfect for CI/CD pipelines, cron jobs, repo bootstrapping
  4. Flags not in --help:

    • These flags work but aren't documented in claude --help output

Surprises

  • --init-only uses trigger: "init" not trigger: "init-only" - makes sense semantically but could trip up hook logic trying to distinguish
Evidence & receipt
◇ ed25519 receipt
idtest_6805ffcdac86fbb737aef913
alged25519
pubkey9b87705613b1e2fd064d57fa75a6b679d2856ceafad6b1daa8f982493871b6dd
sig1bc6aa69f9d04ee4f37e993437e30bcc2c55b2a80880a837d8e2e5c30d8f1ec1f7bc0d88baf1280ea4d3bfaf780060248b50c964b7664b82e110a88315ba4601

Signed with an ed25519 key held off the repo. Anyone can verify against the published public key; nobody without the secret key can forge it. Click verify: it recomputes the signature in your browser. The signature proves integrity and authorship of this exact content — not a third-party timestamp or that the underlying claim is objectively true. signedAt is when the @f3/attest pipeline ran, not when the work happened; the evidence refs carry the source dates.

Connected