# Claude Code v2.1.169

> Claude Code v2.1.169, released 8 Jun 2026 (2026-06-08). 19 entries read out of the shipped bundle. Unofficial, and not affiliated with Anthropic.

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

This release introduces a `--safe-mode` flag for troubleshooting with all customizations disabled, a new bundled `/design-sync` skill for syncing React design systems to `claude.ai/design`, and a `disableBundledSkills` setting to strip out Claude Code's built-in skills/workflows. The whole UI also completes a terminology shift from "remote session" to "cloud session". Windows sandbox networking gets a significant upgrade with WFP filter management via `srt-win`. Several UX fixes land as well, including more reliable up/down arrow key behavior in text input and clearer error messages from the SendFile tool.

## Changes

### Safe Mode (`--safe-mode` / `CLAUDE_CODE_SAFE_MODE`)

**What**

A new opt-in mode that disables all per-user and per-project customizations for a session. Designed for troubleshooting when Claude Code behaves unexpectedly and you want to isolate whether a plugin, hook, or CLAUDE.md is the cause.

**Usage**

`claude --safe-mode # or CLAUDE_CODE_SAFE_MODE=1 claude` **Details** - Disables: CLAUDE.md, skills, plugins, plugin hooks, MCP servers (auto-discovered and claude.ai), custom agents, output styles, workflows, custom themes, and custom keybindings - Managed policy settings and hooks (from your organization's policy) still apply - The UI surfaces a warning banner so you know safe mode is active - Settings dialogs show "disabled in safe mode" labels next to affected options - To exit safe mode: remove the flag or unset the env var and restart (`claude` will tell you which applies) - The `--agents` flag is silently ignored in safe mode (user-supplied agents are disabled) **Evidence** Safe mode toggle (search for `"CLAUDE_CODE_SAFE_MODE"` and `"--safe-mode"`) — `C9()` function at line ~3884

### `/design-sync` Skill — Sync React Design Systems to Claude Design

**What**

A new bundled skill that bundles your React component library (from Storybook or a bare package) and uploads it to `claude.ai/design` so the Design agent can generate accurate mocks using your real components.

**Usage**

`# In Claude Code: /design-sync # or say: "sync my design system to Claude Design"` **Details** - Requires claude.ai authentication (not available via Bedrock, Vertex, or third-party providers) - Not available when `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` is set - Upgrades your claude.ai login scope on first use to include `user:design:read` and `user:design:write` - Uses a `DesignSync` tool that reads and writes your org's design-system projects on `claude.ai/design` - Creates a `design-sync.config.json` in your project to track configuration across re-syncs - Bundles `_ds_bundle.js` (component code) and `_ds_bundle.css` (styles) - Includes comparison screenshots to verify visual fidelity before upload - A `design-sync.config.json` cache enables incremental re-syncs that carry forward unchanged components **Evidence** Bundled skill (search for `"design-sync"` or `"Push a React design system to claude.ai/design"`) — `pE9` skill definition at line ~733477

### `disableBundledSkills` Setting

**What**

A new settings option that removes all skills and workflows that ship bundled with Claude Code. Built-in slash commands remain typable but are hidden from the model. Your own plugins, `.claude/skills/`, and `.claude/commands/` are unaffected.

**Usage**

`// In settings.json or settings.local.json: { "disableBundledSkills": true }` Or via environment variable:

`CLAUDE_CODE_DISABLE_BUNDLED_SKILLS=1 claude` **Details** - Equivalent to setting `CLAUDE_CODE_DISABLE_BUNDLED_SKILLS=1` - Affects skills like `/review`, `/init`, `/deep-research`, and now `/design-sync`, but NOT user-created commands in `.claude/` - The setting is documented inline: "Disable the skills and workflows that ship with Claude Code: bundled skills and workflows are removed entirely; built-in slash commands stay typable but are hidden from the model." **Evidence** Settings schema addition (search for `"disableBundledSkills"`) — added to settings schema at line ~11677

### Windows Sandbox Network Filtering (WFP / `srt-win`)

**What**

Full Windows Filtering Platform (WFP) integration for the Windows sandbox using the `srt-win` tool. Enables per-process network isolation via Windows discriminator groups and WFP filters, analogous to the macOS sandbox's network control.

**Usage**

`// In settings.json (windows-specific): { "windows": { "groupName": "my-sandbox-group", "groupSid": "S-1-...", "sublayerGuid": "..." } }` **Details** - Requires a one-time installation: `npx sandbox-runtime windows-install` (triggers one UAC prompt) - After install, you must log out and back in so the discriminator group SID enters your token - While the group SID is absent from your token, WFP filter-0 PERMITs all traffic — no connectivity disruption during setup - Default proxy port range is 60080–60089 (configurable); must match the range passed to `srt-win wfp install` - `--group-sid` overrides `groupName` lookup — use for domain environments where name resolution is unreliable - `SRT_WIN_PATH` environment variable overrides the `srt-win.exe` search path - Windows sandbox commands now run via `srt-win exec` instead of directly through cmd/PowerShell **Evidence** `srt-win` integration (search for `"srt-win.exe"` or `"Windows sandbox needs a one-time install"`) — `$38()`, `YD7()`, `Oh6()` at line ~241773

### LSP `diagnostics` Setting

**What**

A new `diagnostics` boolean option on each LSP server entry in `lspServers` that controls whether `publishDiagnostics` notifications are automatically injected into the agent context after file edits.

**Usage**

`// In settings.json: { "lspServers": [ { "name": "my-lsp", "command": "...", "diagnostics": false } ] }` **Details** - Defaults to `true` — current behavior is unchanged unless you explicitly set `false` - Setting to `false` keeps LSP navigation features (go-to-definition, hover, completions) active while suppressing automatic error/warning injection after edits - Useful when diagnostics are noisy or slow down the agent loop on large projects **Evidence** Settings schema addition (search for `"Whether to push publishDiagnostics into the agent context after edits"`) — added to `lspServers` schema at line ~11733

### "Remote Session" Renamed to "Cloud Session" Throughout

**What**

All user-facing text that previously said "remote session", "remote agent", or "background tasks" (in the context of cloud-based agents) now says "cloud session" or "cloud agent". This is a branding/terminology update with no behavior change.

**Details**

- UI banners, status lines, settings descriptions, error messages, confirmation dialogs
- The `remote` settings key is now described as "Cloud session configuration" rather than "Remote session configuration"
- Skill prompts like "When the user wants to schedule a recurring remote agent" now read "cloud agent"

**Evidence**

Mass rename (search for `"Cloud session details dismissed"` or `"Cloud agent launched"`)

### `ctrl+x ctrl+b` Added as a Background Task Shortcut

**What**

The keybinding to background the current task (send it to run in the background) now accepts both `ctrl+b` and the tmux-safe chord `ctrl+x ctrl+b`. This prevents conflicts in tmux sessions where `ctrl+b` is the prefix key.

**Details**

- Both shortcuts trigger the `task:background` action in the Task context
- In tmux, the displayed hint automatically shows `ctrl+x ctrl+b` instead of `ctrl+b`
- The previous `ctrl+x again to archive` binding hint is removed; `ctrl+x ctrl+b` is the canonical form

**Evidence**

Keybinding table change (search for `"ctrl+x ctrl+b"`) — `dA8` keybinding table at line ~11817

### Text Input Arrow Key Behavior Fixed

**What**

Up and down arrow keys in the main prompt input now correctly detect whether the cursor is on the first or last line of a multi-line input using the cursor's actual rendered line position. Previously, off-by-one errors in raw text offset calculations could cause the keys to fall through to message history navigation at the wrong moment.

**Details**

- Affects the main input box and the plan-editing input
- `disableCursorMovementForUpDownKeys: true` is set on these components to route the logic through the new line-position check
- No change for single-line inputs

**Evidence**

Input component change (search for `"disableCursorMovementForUpDownKeys"`) — structural changes to `x4f` and `B4f` at line ~11568

### SendFile Tool Rejects URLs with a Clear Error

**What**

When the SendFile (file-delivery) tool receives a path that looks like a URL (`https://...`, `ftp://...`, etc.), it now returns an actionable error message instead of silently failing or producing a confusing "file not found" error.

**Details**

- New error text: `"looks like a URL, not a local file path. This tool can only send files that exist on the local filesystem — download or write the content to a local file first, then pass that path."`
- The tool description is also updated to clarify: "Files must already exist on the local filesystem — the tool sends files, it doesn't fetch URLs or render content."

**Evidence**

Validation logic (search for `"looks like a URL, not a local file path"`) — file path validator at line ~28934

### `/agents --json` Gains `--all` Flag

**What**

The `claude agents --json` scripting command now accepts an `--all` flag that includes completed (archived) sessions in the output, not just currently active ones.

**Usage**

`claude agents --json --all` **Details** - Without `--all`, `--json` continues to show only active sessions (renamed from "live sessions" to "active sessions" in the help text) - With `--all`, the full agent view list — including completed sessions — is returned as JSON - Useful for post-run scripting or auditing completed cloud agent sessions **Evidence** CLI option addition (search for `"With --json: include completed sessions"`) — `--all` option at line ~23293

### Job Persistence Security: Non-Allowlisted Keys Stripped on Load

**What**

When Claude Code resumes a persisted background job, it now strips any `providerEnv` keys or `respawnFlags` tokens from the saved state that are not on the internal allowlist. This prevents unintended environment leakage from older or externally-modified job state.

**Details**

- A warning is logged when stripping occurs: `[jobs] stripped non-allowlisted providerEnv key(s) from persisted job state`
- Duplicate `respawnFlags` tokens (same flag specified multiple times) are also deduplicated — the last occurrence wins for flags that take a value
- Behavior is transparent to users; jobs continue to resume normally

**Evidence**

Job state sanitizer (search for `"[jobs] stripped non-allowlisted providerEnv key(s)"`) — `nY7()` and `XXH()` at line ~219333

### Permission Mode Downgrade Notification

**What**

When Claude Code detects that a session is trying to use `bypass` or `auto` permission mode but the required disclaimer has not been accepted interactively, the mode is silently downgraded to `default` and a notice is emitted.

**Details**

- Previously the mode downgrade was not explicitly surfaced; now the message `"Permission mode downgraded to default — bypass/auto requires accepting the disclaimer interactively first"` is shown
- Affects sessions spawned non-interactively (e.g., from scripts or cloud sessions) that request an elevated permission mode without having gone through the interactive acceptance flow

**Evidence**

Downgrade notice (search for `"Permission mode downgraded to default"`) — `JO7` constant at line ~220750

### Git `credential.interactive=false` Injected for Cloud Sessions

**What**

Git commands run inside cloud sessions now automatically inject `GIT_CONFIG_KEY_N=credential.interactive` / `GIT_CONFIG_VALUE_N=false` via the `GIT_CONFIG_COUNT` mechanism. This prevents git from hanging waiting for interactive credential input when cloning or fetching in a headless cloud environment.

**Evidence**

Git env helper (search for `"credential.interactive"`) — `kF()` function at line ~223497

### `ctrl+g` Keybinding in Hook/Script Dialogs Rendered Consistently

**What**

The "edit in `$EDITOR`" hint in hook confirmation dialogs and script prompts now renders through the standard keybinding display component (`K$`) rather than as a plain text string. This means it respects custom keybinding remaps and displays consistently with other shortcuts.

**Evidence**

Component change (search for `"edit script in $EDITOR"`) — structural change in `B_A` at line ~11873

### `/goal` Error Message Updated

**What**

The error shown when `/goal` cannot run because hooks are restricted now says "hooks are restricted" instead of "hooks are disabled", better matching the actual condition (which covers both `disableAllHooks` and `allowManagedHooksOnly` settings).

**Evidence**

Error string change (search for `"/goal can't run while hooks are restricted"`)

## Bug Fixes

- Fixed incorrect path-component splitting in URL-to-filename conversion where `A` (the path array) was referenced as `z` in certain code paths, causing incorrect encoding of URL path segments (search for `"A.split"` in the URL path normalizer — `nJ` structural change at line ~11580).

- Fixed `loadMarkdownFilesFromDir` timeout log message which incorrectly reported the function name as `loadMarkdownFiles` (search for `"loadMarkdownFilesFromDir: ripgrep timed out scanning"`).

## In Development

Features with infrastructure added but not yet enabled.

### Refusal Continuation — Silent Retry with Fallback Model [In Development]

**What**

When the model refuses a request for safety reasons, Claude Code will silently retry with a designated fallback model. If the fallback model responds successfully, the conversation continues as if nothing happened; if the fallback also refuses, the refusal is shown normally.

**Status**

Feature-flagged. Gated by a server-side `refusal_fallback_prompt` feature flag that must be present in the account's beta header list.

**Details**

- A `refusalFallbackModelLatch` tracks which fallback model was activated and what the previous model override was, so the model is restored after the retry turn
- The detection function `fTK()` returns `false` unless `On8()` (refusal continuation enabled) AND `refusal_fallback_prompt` is absent from the beta list
- Infrastructure includes latch set/clear/update functions and a `refusalFallbackOccurred` flag for telemetry

**Evidence**

Gated by server-side flag (search for `"refusal_fallback_prompt"`) — `fTK()` at line ~122285, `refusalFallbackModelLatch` state at line ~2551

### Claude Design Contextual Tip [In Development]

**What**

A new contextual tip "Designing a UI? Claude Design can mock 5 versions of your screen before you build — claude.ai/design" will appear periodically for users who are working on front-end code, pointing them to the new `/design-sync` skill.

**Status**

Feature-flagged. Gated by `tengu_cedar_plume` server-side flag.

**Details**

- Only shown to first-party claude.ai sessions (`hq()` check)
- Respects a 15-session cooldown so it doesn't repeat too often
- Also requires the user to be in a context where design suggestions are relevant (`cb9()` check)

**Evidence**

Tip gated by feature flag (search for `"tengu_cedar_plume"`) — `claude-design-contextual` tip at line ~25202

- Flag `tengu_cedar_plume`: Off in both readings (read for one account on one subscription tier against v2.1.169; 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.
