Skip to content

claude-code

Claude Code 2.1.290 gives mod hooks the subagent's ID

Claude News

Until this release, a Claude Code mod that gates tool calls saw the same permission check whether the main session or a subagent was asking. Version 2.1.290, according to the release notes on Github, adds an agentId to that check and fixes a case where a user-installed mod could make an organization's guard skip its check.

At a glance

  • Mod authors get more data in two hooks: tool.check gains agentId and a ceiling field, and the result of turn.step now lists serverToolUses, the tool calls the API ran itself.
  • A mod hook receives the event and a next function, so a gating hook on tool.check can now branch on which agent asked and on the approval an organization requires.
  • The notes do not say what values ceiling takes or what the advisor does, and the fix for scheduled tasks after compaction only covers compactions made from this version on.

If you have not been following: according to GitHub, mods shipped in v2.1.269 as a plugin runtime that no docs page mentioned, behind the CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 flag up to v2.1.286. From v2.1.287 they load by default, and Anthropic published docs for them. The previous release, 2.1.289, according to Changelogs, gave teammates spawned through agent.spawn a consistent agent ID across plugin hook events.

tool.check now names the agent asking and the approval an organization requires

The main change for mod authors is in tool.check, the plugin hook event that fires when a tool call is checked for permission. It now carries agentId, so a hook can tell a subagent's permission check from the main session's. The question and verdict a mod's tool.check hook reads also gain a ceiling field, which names the approval an organization requires for a tool.

Two tooling additions come with it. claude plugin validate now lists each hook a mod registers at a gating site and says whether it has a .catch. Under --json the list appears as gatingHooks. The plugin hooks typings gain ThemeKey and Color types, so an editor can list the theme colors a mod's drawing can name.

A related fix in the same release: a hook with a .catch could be unloaded, and its .catch skipped, when the hook kept the hooks worker busy on a prompt or tool call. A prompt.submit hook that drops a prompt after calling next(e) used to be ignored silently. It is now reported as failed, by name.

turn.step now reports the tool calls the API ran on its own

The result of a mod's turn.step hook gains serverToolUses: the tool calls the API ran itself, which the notes identify as the advisor. Each entry carries an id, a name, the input, and a start and end. The same hook also got a correctness fix. Its result could list a tool call that a mid-response model fallback had discarded.

Several other mod fixes ship alongside. Mods no longer stay off for people who reach Claude through a gateway (ANTHROPIC_BASE_URL with ANTHROPIC_AUTH_TOKEN) and have no Anthropic account. Plugin hooks now clip and log long text instead of refusing or dropping it silently. When a refresh follows a failed reload, the mod's failure line now says the version loaded before is unloaded.

A user-installed mod can no longer switch off an organization's guard

Two fixes cover the line between user mods and organization plugins. A user-installed mod could make an organization's guard skip its check, and such a mod is now unloaded. In a separate case, a user-installed mod could get an organization's plugin unloaded. Now the mod is the one that gets unloaded.

The Bash permission checks got stricter in the same release. Read-only commands such as rg or git grep whose arguments the shell would still expand as wildcards now prompt for approval. So do certain commands whose variable names zsh reads differently from bash. Pyright no longer counts as read-only, and more forms of ps now ask before running.

Some permission rules and safety checks were not applied to a tool call after a PreToolUse hook rewrote its input, and that is fixed. Plan mode also no longer lets the auto mode classifier approve non-read-only connector tools that carry a server-pushed ask policy.

WebFetch now reports the text it skipped past 100,000 characters

WebFetch used to drop page text past 100,000 characters without saying so. It now reports how much went unread and takes an offset, so Claude can read on. The WebSearch budget in interactive sessions changes too: it refills at 100 calls an hour instead of ending after 200 calls. CLAUDE_CODE_WEB_SEARCH_REFILLS_PER_HOUR sets the rate, and 0 turns refilling off.

If you juggle background sessions, claude attach <name> and claude logs <name> now accept part of a session name in place of the id. Long sessions with hundreds of images no longer get stuck on "Request rejected as unprocessable by the model" errors. A reply stopped by the output content filter while Claude was still thinking is now retried once before the error appears.

A tool.check hook gets three arguments, and agentId comes in the second

According to Claude Code Docs, a mod is a plugin whose entry file, the hooks module, is a JavaScript or TypeScript file whose functions Claude Code calls when events happen. Every hook receives three arguments: the mods API $, the event e with its input as plain data, and next, which passes the event to other mods and then to Claude Code's own behavior.

The same docs say a hook can either watch, by returning next(e), or answer itself. Before this release, a tool.check hook saw the tool call but not who made it. Picture a guard at the server room door who now sees the badge of whoever is asking, while ceiling tells him what clearance the building manager requires for that door.

Why would a subagent ask for permission at all? A subagent is a Claude with its own context window, spawned by the main agent, that works on its own and returns a summary, so its tool calls trigger their own permission checks.

The notes leave gaps. They say ceiling names the approval an organization requires, but not which values it takes, and the advisor behind serverToolUses gets no description beyond the API running those calls itself. Oddly, the fix for scheduled tasks after compaction only covers compactions made from this version on, so conversations compacted earlier will likely still lose their tasks on resume.

Where the API definition lives now

According to GitHub, each time Claude Code loads a mod from a folder it writes type declarations to .claude-plugin/types/claude-code/index.d.ts, and the copy written by v2.1.290 is the authority on the API. No date has been given for docs that cover serverToolUses or ceiling. One fix arrives later still: the Homebrew restart failure in claude agents only goes away with the upgrade after this one.

Related stories

  1. Claude Code 2.1.288 brings back the prompt you Ctrl+C'd
  2. Claude Code ships mods, the same tool behind its /diff
  3. A Claude Code sideagent now flags what you might miss
  4. Claude Code 2.1.286 stops resume from losing your turns
  5. Claude Code writes the eval, grader included
  6. Without CLAUDE.md, Claude Code 2.1.277 reads AGENTS.md

Comments

No comments yet. Be the first.

Join the conversation

Sign in with Google to leave a comment. Your name and avatar come from your Google profile, and the comment appears after moderation.

We only use your name and avatar from Google. We never store your email address.