Claude Code 2.1.118
Vim visual and visual-line modes, custom themes, MCP-tool hooks, `/cost` and `/stats` merged into `/usage`, WSL inheriting Windows managed settings, and a long list of MCP OAuth fixes.
This article is a summary based on official documentation.
What changed
Claude Code 2.1.118 (April 23, 2026) — Vim picks up visual and visual-line modes, themes can now be customized and shipped by plugins, hooks can invoke MCP tools directly, /cost and /stats are merged into /usage, and a cluster of long-standing MCP OAuth and credential issues are fixed.
New features
-
Vim visual mode (
v) and visual-line mode (V)Vim mode had no way to select ranges or apply operators across lines.
vnow selects by character,Vby line, both with operator support and visual feedback. -
Custom themes and plugin-shipped themes
Built-in themes couldn’t be extended, so organization branding and personal preferences had no home.
/themenow lets you create and switch between named custom themes, and you can hand-edit JSON files under~/.claude/themes/. Plugins can ship themes via athemes/directory. -
Hooks can invoke MCP tools directly
Hooks previously needed a wrapper to call an MCP tool. Hook config now supports
type: "mcp_tool"for direct MCP tool invocation. -
DISABLE_UPDATESenv var blocks all update pathsDISABLE_AUTOUPDATERonly blocked automatic updates, leaving manualclaude updateopen.DISABLE_UPDATESblocks every update path — including manual — for organizations that need strict version pinning. -
WSL inherits Windows-side managed settings
Windows managed policies didn’t reach WSL, leaving WSL users exempt from enterprise controls. The new
wslInheritsWindowsSettingspolicy key lets WSL inherit Windows-side managed settings. -
Auto mode
"$defaults"in rule listsOverriding
autoMode.allow/autoMode.soft_deny/autoMode.environmentreplaced the built-in list entirely, so adding a few custom rules meant re-declaring everything. Include"$defaults"to extend the built-in list instead of replacing it. -
“Don’t ask again” on the auto mode opt-in
The auto mode opt-in prompt now supports “Don’t ask again.”
-
claude plugin tagfor plugin release tagsManual tagging led to format mistakes.
claude plugin tagcreates a release git tag with version validation. -
--continue/--resumefinds/add-dirsessionsSessions that added the current directory later via
/add-dirwere missed by resume discovery. They now show up in search. -
/colorsyncs to claude.ai/code under Remote ControlAccent color set via
/colorused to diverge between the terminal and Remote Control. The two now stay in sync when Remote Control is connected. -
/modelhonors custom gateway name/description overridesWhen using
ANTHROPIC_BASE_URLwith a gateway,/modelignoredANTHROPIC_DEFAULT_*_MODEL_NAME/_DESCRIPTIONoverrides. The picker now reflects them.
Improvements
-
/cost+/statsmerged into/usageCost and stats were split across two commands, making it hard to remember what was where. They’re unified under
/usagewith both previous names kept as typing shortcuts that open the relevant tab. -
Plugin updates skipped due to dependency conflicts are now visible
Auto-update silently skipped plugins when another plugin’s version constraint blocked them. Skips now surface in
/doctorand the/pluginErrors tab.
Notable fixes
MCP / OAuth
/mcpmenu OAuth actions — fixed Authenticate/Re-authenticate hidden forheadersHelper-configured servers; fixed HTTP/SSE MCP servers with custom headers stuck in “needs authentication” after a transient 401.- Missing
expires_in— fixed re-authentication prompts every hour when the OAuth response omittedexpires_in. - Step-up authorization — fixed silent refresh when
insufficient_scope403 named a scope the current token already had; now prompts for re-consent. - OAuth timeout / cancel — fixed unhandled promise rejection when the OAuth flow timed out or was cancelled.
- Cross-process refresh lock — fixed OAuth refresh proceeding without the lock under contention.
- macOS keychain race — fixed concurrent MCP token refresh overwriting a freshly-refreshed OAuth token, which caused unexpected “Please run /login” prompts.
- Server-side revocation before local expiry — fixed refresh failure when the server revoked a token before its local expiry.
Credentials and sessions
- Credential save crash on Linux/Windows — fixed corruption of
~/.claude/.credentials.json. /loginwithCLAUDE_CODE_OAUTH_TOKEN—/loginhad no effect when the env token was set. The env token is now cleared so disk credentials take effect.- Remote session overwriting local
modelsetting — fixed~/.claude/settings.jsonbeing updated just from connecting to a remote session. - Subagent
cwdonSendMessageresume — explicitcwdat spawn time is now restored on resume.
UI and input
- “New messages” scroll pill and
/pluginbadges — fixed unreadable text. - Plan acceptance under
--dangerously-skip-permissions— dialog offered “auto mode” instead of “bypass permissions”; fixed. Alt+K/Alt+X/Alt+^/Alt+_freezing input — fixed.- Pasting paths starting with
/— typeahead no longer shows “No commands match” when a pasted file path begins with/.
Hooks, plugins, file watchers
- Agent-type hooks on non-
Stopevents — no longer fail with “Messages are required for agent hooks” when wired to other events. prompthooks re-firing — no longer re-fire on tool calls made by an agent-hook verifier subagent./forkdisk bloat — fork no longer writes the full parent conversation to disk per fork; it writes a pointer and hydrates on read.- Re-running
plugin installon wrong-version dep — now re-resolves when the installed dependency is at the wrong version. - File watcher unhandled errors — fixed crashes on invalid paths or fd exhaustion.
Remote Control
- Archive-on-blip — Remote Control sessions no longer get archived on transient CCR initialization blips during JWT refresh.
Notes
/costand/statsstill work as shortcuts, but if you reference them in docs or scripts, consider pointing to/usage.- For strict enterprise version pinning, use
DISABLE_UPDATESrather thanDISABLE_AUTOUPDATER— the former blocks manualclaude updatetoo. - Vim visual mode only matters if you already use Vim mode; users on the default mode aren’t affected.
wslInheritsWindowsSettingsis only meaningful when managed settings are deployed on both Windows and WSL.