← 2.1.10 Release

2.1.10 (2.1.10)

Battle-tested: 2026-01-16

Claude Code 2.1.10 (released 2026-01-16) introduces the Setup hook event type, a new lifecycle phase that fires before SessionStart and enables repository initialization, CI bootstrapping, and scheduled maintenance workflows.

Epistemic status: changelog-derived and partially runtime-verified. Features marked UNTESTED in the source were not runtime-confirmed; claims about those features are derived from the changelog only.

What changed

The headline addition is a new hook event: Setup. It fires on three CLI triggers: --init, --init-only, and --maintenance. The hook input payload includes a trigger field ("init" or "maintenance"), a session_id, and the standard cwd and transcript_path fields.

The --init-only flag is the automation-oriented variant: Claude runs the Setup hooks and exits without starting a session. This makes it suitable for CI steps or bootstrapping scripts where no interactive session is wanted.

Secondary changes in 2.1.10 are bug fixes and UX polish: a heredoc template crash on expressions like ${index + 1} was fixed, keystroke capture was improved, and file suggestions were surfaced as attachments. VSCode install-count and trust-warning additions were also shipped. The non-Setup features were not runtime-verified in the battle-test run; they are changelog-derived.

What the tests found

Two features reached PASS status during the 2026-01-16 battle-test run.

Setup hook (PASS). Three invocation forms were confirmed working:

echo "hi" | claude --init -p          # Setup fires, then SessionStart, session continues
claude --init-only                     # Setup fires, process exits; no session
echo "run diagnostics" | claude --maintenance -p  # trigger: "maintenance"

A session-aware initialization workflow was validated: a Setup hook creates a /tmp/claude-sessions/{session_id}/ directory, and SessionStart hooks can read from that shared state in the same run.

Heredoc fix (PASS). Template literals containing ${index + 1} no longer crash.

One notable limitation surfaced: --init-only passes trigger: "init" in the hook payload, identical to --init. A hook cannot distinguish between the two modes from the payload alone; external state tracking is required.

"hook input gives you session_id even in --init-only mode. a session id for a session that doesn't exist... so it's more like 'execution id' than 'session id' in the init-only case."

Why it matters

Setup completes the hook lifecycle surface. Before 2.1.10, hooks covered SessionStart, PreToolUse, PostToolUse, and SubagentStop. Setup adds a phase that precedes all of those, giving automation authors a guaranteed pre-session entry point for environment validation, dependency installation, and config generation.

The --init-only pattern in particular is a job-runner primitive: claude --init-only || exit 1 as a CI preflight step requires no interactive session and exits with a meaningful status code.

Caveats

--init, --init-only, and --maintenance are not listed in claude --help as of 2.1.11. They function as documented here but carry undocumented-flag risk: behavior may change without deprecation notice. Five features from this release (OAuth URL copy, keystroke capture, file-attachment UX, and two VSCode items) remain UNTESTED in the battle-test record; treat changelog descriptions of those as unverified.

3features tested
    Evidence & receipt
    • file2.1.10/SUMMARY.md
    ◇ ed25519 receipt
    idrelease_ff946ce6b0ff0f957875277a
    alged25519
    pubkey9b87705613b1e2fd064d57fa75a6b679d2856ceafad6b1daa8f982493871b6dd
    sig85ea115214ddbdc9df50876cd1c9c90a8b0c7aad4807415845e8adaeb7cc29b2dfe9b5364ba28e2425b0749b206658028e89a8f724f00ea7605fa109e22c200b

    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