feat: accept IDE session hooks without dropping model settings (#1265)

IDEs can pass their own Claude hooks through
`_meta.claudeCode.options.settings.hooks` on `session/new` and
`session/load`. Before this change, any session settings replaced
`CLAUDE_MODEL_CONFIG` entirely, so adding a single hook dropped the
deployment's `modelOverrides` / `availableModels`. The two are now
merged, and the session settings win per key.

The wrapper does not merge hooks itself: Claude Code already runs the
hooks of every settings tier, so user and project hooks keep running
next to the session ones. Hooks stay scoped to their session, and a
`session/load` with different settings recreates the query, which
replaces or removes them.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Maksim Zheltoukhov
2026-10-12 13:00:07 +02:00
committed by GitHub
parent b3bed2f763
commit fe8b69edd4
5 changed files with 302 additions and 28 deletions

View File

@@ -17,6 +17,7 @@ It describes only this adapter.
- [Claude tools and ACP fields](#claude-tools-and-acp-fields)
- [Diff patch](#diff-patch)
- [Plan file](#plan-file)
- [Session hooks](#session-hooks)
- [Permission presentation](#permission-presentation)
- [Goal](#goal)
- [Recommended config values](#recommended-config-values)
@@ -496,6 +497,21 @@ The plan text goes out as before in these cases:
AIR then shows the in-memory `plan` text.
A client that is not AIR always gets the whole SDK input, like upstream.
## Session hooks
The adapter accepts session hooks from any client, without a capability.
AIR puts the hooks into `_meta.claudeCode.options.settings.hooks` of `session/new` and `session/load`:
```json
{ "claudeCode": { "options": { "settings": { "hooks": { "Stop": [{ "hooks": [{ "type": "command", "command": "..." }] }] } } } }
```
- The settings go to the flag settings tier of that session only. Other sessions and the settings files do not change.
- Claude Code runs the hooks of every settings tier, so the user, project and IDE hooks of one event all run. `src/tests/session-hooks.test.ts` checks this with the Claude Code binary.
- `CLAUDE_MODEL_CONFIG` stays in effect (see [Model configuration](model-configuration.md#precedence)).
- A `session/load` with different settings recreates the query, so it applies the new hooks.
- Claude asks for no hook trust step.
## Permission presentation
The adapter uses standard ACP permission requests and responses.