# Claude Code v2.1.163

> Claude Code v2.1.163, released 4 Jun 2026 (2026-06-04). 20 entries read out of the shipped bundle. Unofficial, and not affiliated with Anthropic.

Web version: https://changelogs.core-directive.com/v/2.1.163

This release adds two new hook events (`SubagentStop` and a formal `Stop` hook output schema with `additionalContext`), organization-level version enforcement via `requiredMinimumVersion`/`requiredMaximumVersion` policy settings, and new `/plugin list` filter flags. Under the hood, the workflow VM received substantial security hardening against hostile Proxy objects crossing the VM boundary, and OAuth 401 recovery was improved for remote sessions.

## Changes

### SubagentStop Hook Event

**What**

A new hook event fires when a subagent finishes, complementing the existing `Stop` event which fires when the main conversation agent finishes. The hook output's `additionalContext` field is delivered back to the subagent so it can continue and act on the feedback.

**Details**

- Event name: `SubagentStop`
- Available for command-based and prompt-based hooks
- Hook output schema: `{ hookEventName: "SubagentStop", additionalContext?: string }`
- `additionalContext` is non-error feedback; the subagent continues execution so it can act on it
- Prompt-based hooks now also explicitly support `SubagentStop` alongside `Stop`, `UserPromptSubmit`, and `PreToolUse`

**Evidence**

Schema literal for the new event (search for `"Hook-specific output for the SubagentStop event"`)

### Stop Hook Output Schema with additionalContext

**What**

The `Stop` hook event now has a formal output schema with an `additionalContext` field, allowing hooks to send feedback to the model after it finishes a response so the conversation continues.

**Details**

- Hook output schema: `{ hookEventName: "Stop", additionalContext?: string }`
- `additionalContext` is non-error feedback delivered to the model; the conversation continues so the model can act on it
- Previously, the Stop hook output schema was not separately defined — it now matches the SubagentStop pattern

**Evidence**

Schema description (search for `"Hook-specific output for the Stop event. additionalContext is non-error feedback"`)

### Organization Version Enforcement (requiredMinimumVersion / requiredMaximumVersion)

**What**

Administrators can now enforce a minimum and/or maximum Claude Code version through managed policy settings. If the running version is outside the allowed range, Claude Code exits at startup with instructions on how to update or downgrade.

**Details**

- `requiredMinimumVersion`: If the running version is older than this value, Claude Code exits with a message to update using the organization's approved method.
- `requiredMaximumVersion`: If the running version is newer than this value, Claude Code exits with a message to install an approved version (`claude install <version>` may also work).
- Both settings are only enforced from managed/policy settings (`managed-settings.json` / MDM). They have no effect in user or project settings.
- Exempt commands: `update`, `install`, and `doctor` bypass the version check so users can fix the problem.
- Invalid semver values are logged as errors and ignored rather than blocking startup.

**Evidence**

Version check at startup (search for `"is older than the minimum version required by your organization"` and `"is newer than the maximum version allowed by your organization"`)

### /plugin list --enabled and --disabled Filters

**What**

The `/plugin list` command now accepts `--enabled` and `--disabled` flags to filter the output to only installed plugins matching the requested state.

**Usage**

`/plugin list --enabled # show only enabled plugins /plugin list --disabled # show only disabled plugins /plugin list # show all installed plugins (unchanged)` **Details** - Enabled/disabled status is shown as `✓ enabled` or `✗ disabled` per plugin entry. - If no plugins match the filter, a short message like "No disabled plugins." is shown. - Plugin entries also show version and scope where available. - A pending-reload indicator `— run /reload-plugins to apply` appears when the in-memory state differs from what would be loaded on next start. **Evidence** Filter flag in command rendering (search for `"/plugin list [--enabled|--disabled] - List installed plugins"`)

### Expanded Media Type Support for File Uploads

**What**

The file upload system now recognizes additional image, video, and audio formats.

**Details**

- New image formats: HEIC (`.heic`), HEIF (`.heif`), AVIF (`.avif`), TIFF (`.tif`, `.tiff`), ICO (`.ico`)
- New video formats: QuickTime/MOV (`.mov`), AVI (`.avi`), MKV (`.mkv`), M4V (`.m4v`)
- New audio format: FLAC (`.flac`)
- These MIME types are now served correctly when uploading files via the browser integration and Chrome tool

**Evidence**

MIME type map additions (search for `"image/heic"`, `"video/quicktime"`, `"audio/flac"`)

### /reload-plugins Cache Impact Warning

**What**

When `/reload-plugins` would add or remove MCP servers (changing the tool list), Claude Code now warns that the next message will re-read the whole conversation instead of using the prompt cache, and prompts you to confirm with `--force`.

**Details**

- The warning shows how many MCP servers changed, or the specific server name if only one changed.
- Use `/reload-plugins --force` to apply immediately and skip the warning.
- If ToolSearch is active and the model supports it, the warning is suppressed (tool-search mode handles dynamic tools without cache invalidation).

**Evidence**

Warning message (search for `"This reload changes MCP tools"` and `"Run /reload-plugins --force to apply"`)

### OAuth 401 Recovery for Remote Sessions

**What**

Remote sessions now wait for a rotated OAuth token after receiving a 401 error, instead of immediately propagating the failure.

**Details**

- Wait time is controlled by `CLAUDE_CODE_OAUTH_401_WAIT_MS` (default: 60,000 ms = 60 seconds for remote sessions, 0 for local sessions).
- If a valid, non-failed token appears within the timeout window, the request is retried automatically.
- For remote child sessions (workers), `CLAUDE_CODE_AUTH_FAIL_EXIT_MS` (default: 600,000 ms = 10 minutes) controls how long to tolerate unrecovered 401s before exiting with a message to the runner to recycle the session with fresh credentials.
- The "failed access token" (the specific token that got the 401) is tracked so a rotation to an identical token value is not treated as a recovery.

**Evidence**

Recovery function (search for `"OAuth 401 recovery: waiting up to"` and `"OAuth 401 unrecovered past CLAUDE_CODE_AUTH_FAIL_EXIT_MS"`)

### Workflow VM Security Hardening

**What**

The workflow VM execution environment was substantially hardened against Proxy-based attacks that could cross the JavaScript VM sandbox boundary.

**Details**

- Arrays crossing the VM boundary are now deep-cloned inside the VM sandbox. The array length is read once (preventing a Proxy `length` getter that increments from causing an infinite loop on the host thread).
- The maximum array length crossing the boundary is capped; exceeding it throws a clear error rather than hanging.
- Functions are never cloned across the boundary (they become `undefined`).
- A private `_CAP` symbol on boundary-cap errors prevents hostile Proxy traps from intercepting and suppressing the error.
- The `budget` object passed to workflows now uses `__proto__: null` to prevent prototype chain pollution.
- `agent`, `parallel`, `pipeline`, `workflow`, and `args` are injected into the VM context via `Object.defineProperty` with proper wrapping rather than being in the initial context literal.
- The `args` value is serialized with `JSON.stringify`/`JSON.parse` through the VM context to prevent host-side Proxy objects from being accessible inside the script.

**Evidence**

Cross-VM clone code (search for `"array length is not a safe integer across the workflow VM boundary"`)

### Workflow Script Static Validation via AST

**What**

Workflow scripts are now parsed with the Acorn JavaScript parser (including the `acorn-walk` tree traversal library) for accurate static validation before execution.

**Details**

- `'with' statements` are rejected: `SyntaxError: 'with' statements are not supported in workflow scripts.`
- `'await using' declarations` are rejected: `SyntaxError: 'await using' declarations are not supported in workflow scripts.`
- Identifiers starting with the internal prefix are rejected: `SyntaxError: Identifier '<name>' is reserved.`
- `import()` expressions are disallowed.
- The AST-based approach replaces simpler regex-based checks and properly handles edge cases like `await` inside async arrow functions with expression bodies.

**Evidence**

Error messages (search for `"'with' statements are not supported in workflow scripts."` and `"'await using' declarations are not supported in workflow scripts."`)

### MCP Server Failure Notification

**What**

When MCP servers fail to connect or need authentication at startup, a structured tree notification now appears listing each affected server with its status and error details.

**Details**

- The notification identifies whether each server needs authentication, has a config issue, or has failed for another reason.
- Shows a summary count: `N MCP server(s) not connected — run /mcp to authenticate, retry, or see details:`
- Servers requiring authentication are highlighted as errors; others as warnings.
- Excludes IDE-attached servers (`sse-ide`, `ws-ide` types) and servers that are marked as claudeai-proxy.

**Evidence**

Notification text (search for `"MCP server(s) not connected — run /mcp to authenticate, retry, or see details:"`)

### Builtin MCP Servers Ignored in Plugin Config

**What**

MCP server entries declared in plugin configs that refer to CLI-owned builtin servers are now silently ignored with a debug log, rather than causing a conflict or error.

**Evidence**

Log message (search for `"Builtin server is CLI-owned; ignored"`)

### Plugin LSP Extension Conflict Detection

**What**

Claude Code now detects when two or more plugins declare LSP servers claiming the same file extension, and reports the conflict rather than silently picking one.

**Details**

- Conflicts are reported as `lsp-extension-conflict` warnings, including which plugin and server name is active for the extension vs. the newcomer.
- The first plugin to register an extension wins; subsequent claims for the same extension are flagged.

**Evidence**

Conflict detection function (search for `" declares two LSP servers for"` in LSP warnings or `"already registered a server for that extension"`)

### Hermetic Mode MCP Config Filtering

**What**

MCP servers passed via `--mcp-config` CLI flags are now properly blocked when running in hermetic mode, with a warning log listing the ignored servers.

**Evidence**

Warning message (search for `"ignored in hermetic mode:"`)

### $TMPDIR Sandbox Documentation Clarified

**What**

The system prompt instruction about using `$TMPDIR` for temporary files now correctly states that `TMPDIR` is set to the sandbox-writable directory specifically in sandbox mode (the old wording implied it was set in both sandboxed and unsandboxed contexts).

**Evidence**

Updated instruction text (search for `"TMPDIR is automatically set to the correct sandbox-writable directory in sandbox mode"`)

## Bug Fixes

- Path traversal via symlinks with `..` segments is now detected correctly in the git-controlled directory check. The old implementation could miss cases where a symlink in the path was followed by a `..` component that escaped the intended root. (search for `"would overwrite tracked literal"` near the symlink traversal logic)

- The `fetchSession` error log is now counter-based, reporting "N times in a row" rather than always showing a fixed count. Previously the message was hardcoded as "10 times in a row." (search for `"fetchSession failed"`)

- Bridge `setMode` commands that are rejected (invalid mode) now fall back to `'default'` mode with a warning instead of leaving the bridge in an indeterminate state. (search for `"bridge setMode '"` and `"rejected ("`)

## In Development

Features with infrastructure added but not yet enabled. These are shipped "dark" and may become available in future versions.

### Settings Panel Category Reorganization [In Development]

**What**

A complete reorganization of the `/config` settings panel into named groups — Appearance, Model & output, Display, Input & controls, Connections, Advanced, Experimental, Internal — replacing the flat list of settings.

**Status**

Feature-flagged via `tengu_maple_sundial` (defaults to false).

**Details**

- Settings like `autoScrollEnabled`, `terminalProgressBarEnabled`, `showTurnDuration`, and `prStatusFooterEnabled` move to a Display group.
- `editorMode`, `copyOnSelect`, `fileCheckpointingEnabled`, and workflow-related toggles move to Input & controls.
- MCP/IDE connection settings move to Connections.
- Experimental settings (`switchModelsOnFlag`, `showMessageTimestamps`, `teammateMode`) get their own section.
- The `snipEnabled` and `snipDebug` settings appear in an Internal group.
- `/vim` and `/output-style` commands show a "moved to /config" redirect message when the flag is active.

**Evidence**

Category map gated on `tengu_maple_sundial` (search for `"Model & output"` near the settings group map)

- Flag `tengu_maple_sundial`: Off in both readings (read for one account on one subscription tier against v2.1.163; this account: off, anonymous baseline: off, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.

### Slash Command Menu Kind Lanes [In Development]

**What**

A visual grouping of slash commands in the menu that separates config commands, action commands, info commands, and agent commands into distinct lanes.

**Status**

Gated by `tengu_mint_lanes` feature flag or `CLAUDE_CODE_ENABLE_MENU_KIND_LANES` environment variable (both default off).

**Details**

- Commands are classified as `config` (settings-changing), `action` (one-off operations), `info` (read-only queries), and `agent` (background agent launchers).
- Source labels (`project`, `org`, `plugin`) appear on applicable commands.
- The classification map covers all known slash commands.

**Evidence**

Classification map (search for `"CLAUDE_CODE_ENABLE_MENU_KIND_LANES"`)

- Flag `tengu_mint_lanes`: Off in both readings (read for one account on one subscription tier against v2.1.163; this account: off, anonymous baseline: off, compiled default: on) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.

### Velvet Falcon Model Detection [In Development]

**What**

Infrastructure to detect and handle a new internal model variant identified as "velvet falcon."

**Status**

Gated by `tengu_velvet_falcon_model` feature flag; also overrideable via `CLAUDE_CODE_VELVET_FALCON` environment variable.

**Details**

- The model string is fetched from `clientDataCache.velvet_falcon_model` first, then from the feature flag.
- Detection returns true when the session's model string includes the configured identifier.

**Evidence**

Detection function (search for `"tengu_velvet_falcon_model"` and `"CLAUDE_CODE_VELVET_FALCON"`)

- Flag `tengu_velvet_falcon_model`: Not enough to say (read for one account on one subscription tier against v2.1.163; this account: no value returned, anonymous baseline: no value returned, compiled default: not a boolean we can read) These values were read against a different version of Claude Code, so treat them as the nearest reading available instead of one taken on this release.

### Subscription Switch Notice [In Development]

**What**

A UI component that encourages users on a usage-based (API/console) account to activate their existing Claude subscription plan with Claude Code instead.

**Status**

Shown based on a new `seenNotifications["subscription-switch"]` counter — only appears to users who have not yet seen it the configured number of times. The display logic is wired up but gated on subscription type detection.

**Details**

- Shows: "Use your existing Claude [Pro/Max/Team] plan with Claude Code · /login to activate"
- Impression count is stored in local config under `seenNotifications`.
- Telemetry event: `tengu_switch_to_subscription_notice_shown`

**Evidence**

UI component text (search for `"Use your existing Claude "` and `"/login to activate"`)
