# Claude Code v2.1.265

> Claude Code v2.1.265, released 8 Sep 2026 (2026-09-08). 511 entries read out of the shipped bundle. Unofficial, and not affiliated with Anthropic.

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

This build carries 50 gated additions with nothing switched on, the largest a new "tether" request-threading protocol that would let the API thread requests together server-side instead of resending full context each turn. A rewritten Artifact permission system with five-way ask classification sits behind CLAUDE_CODE_ARTIFACT_FIVE_CLASS_ASKS, alongside a separate targeted str_replace edit operation for the artifact database that appears in at least three of the dormant entries. A new mechanism lets Claude Code signal when an internal "advisor tool" becomes available, and the SDK/host initialize call gains a workspaceTrust option for programmatically granting directory trust. Plugins also get a windowed ui.open/ui.close surface capped at 8 panes each, and SDK-registered in-process MCP servers can now skip a round-trip handshake at session start, though these too are not yet user-facing.

Plugins pick up a real command API this release: they can register, run, list, and describe their own slash commands via a new `$.command` namespace, and that same execution path can now be intercepted and rewritten by command.run/command.describe hooks. The Projects tool gains a "Project memory" section backed by new project_memory_list and project_memory_read tool methods, letting Claude read (not write) a project's remembered files. Hook event names now support wildcard and negation patterns plus a `classic.` namespace for internal plugin hooks, and organization-managed policyHelper settings scripts get a retryable execution engine with backoff, now also honored from remote managed settings. /design and /slides are new commands that generate artifacts from a brief, and /import can now bring in configuration from Cursor IDE in addition to Codex and Gemini CLI.

MCP servers using newer HTTP connections now automatically retry with a legacy HTTP+SSE method if the initial handshake fails, and this fallback was later rewritten behind its own dedicated gate. The `/plan share` subcommand that published a plan as a claude.ai artifact has been removed, and a related plan-artifact command appears removed as well, with the standalone `/design` local command possibly gone too. A fix restored the claude auto-mode defaults, reset, config, and critique subcommands, which had stopped working because they were attaching to the wrong command object. Path safety checks now fall back to a shared-ancestor path when the OS blocks realpath resolution with EPERM or EACCES, and creating a worktree no longer throws when no WorktreeCreate hook is configured at all.

## What probably matters to you

Anything you can use today, anything that visibly changes, and anything worth poking at. One line each, open for detail.

### New "tether" request-threading protocol for API continuity (gated, off by default)

New gated 'tether' system can thread API requests together server-side instead of resending full context each turn

**Unclear.** Nothing has been read about whether tengu_curious_tower or tengu_curious_tower_stateless_models is on or off for any account, so it's unclear whether this is active anywhere yet.

**What**

A new subsystem decides, for each assistant turn, whether an API request should continue a previous server-side "thread" or start a fresh one. It tracks thread state per agent, retries when the server rejects a thread continuation (for reasons like `thread_not_found`, `thread_fingerprint_mismatch`, or `thread_already_continued`), and can fall back specific models or agents to the older stateless mode if thread continuation isn't accepted.

This is controlled by gates including `tengu_curious_tower` and `tengu_curious_tower_stateless_models`.

**Why**

If enabled, this could reduce the need to resend full conversation context on every request by letting the server keep track of continuity itself, with a fallback for models or agents that don't support it.

- Flag `tengu_curious_tower`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Flag `tengu_curious_tower_stateless_models`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: not a boolean we can read)
- Area: API Protocol
- Tier: Nothing to try yet
- Useful: 5/5
- Signal: 5/5
- Present in the build but not switched on

### New 'advisor tool' feature, gated off by default (tengu_reflective_wolf)

A new gated mechanism lets Claude Code tell the model when an 'advisor tool' becomes available or unavailable

**Unclear.** The gate `tengu_reflective_wolf` was read off for this site's account and the anonymous baseline before this release; no reading has been taken under this release, so what it does for a user and whether it's active here is unknown.

**What**

A new internal mechanism, referred to as the 'advisor tool,' can now send the model a message announcing when this tool becomes available or unavailable, with wording like "The advisor tool is no longer available" or "is available." This is controlled by a feature gate (a server-side switch Anthropic can turn on for some accounts and not others) called `tengu_reflective_wolf`.

**Why**

This lets Claude Code inform the model mid-conversation about changes in what tools it can use, so the model doesn't keep trying to use something that's gone away or miss something newly available.

- Flag `tengu_reflective_wolf`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: off, compiled default: not a boolean we can read)
- Area: Advisor Tool
- Tier: Nothing to try yet
- Useful: 5/5
- Signal: 4/5
- Present in the build but not switched on

### Whole new Artifact consent model built behind CLAUDE_CODE_ARTIFACT_FIVE_CLASS_ASKS, off by default

A rewritten Artifact permission system with five-way ask classification exists behind an off-by-default flag

**What**

A substantial rewrite of the Artifact tool's permission logic, covering uploads, reads, comments, and replies, is now wired up behind a gate. When active, it adds a fast path for uploads already approved earlier in the session, and classifies permission requests into five categories (things like whether a path needs asking, whether a read rule applies, spelling flags, requests from outside the current scope, and hard-linked files), plus a more detailed split for unknown, someone-else's, or co-written content. Comments and replies also gain a new ruling flow instead of always prompting for approval. When the gate is off, Claude Code keeps using the older single-path deny/ask logic.

**Why**

This is a foundational change to how Claude Code decides when to ask for permission around artifacts, potentially reducing unnecessary prompts by handling more cases with specific rules instead of one blanket approval check. Its gate, `tengu_artifact_five_class_asks`, has not been read for this account, so it's not known whether this new logic is active anywhere yet.

- Area: Artifacts
- Tier: Nothing to try yet
- Useful: 5/5
- Signal: 4/5
- Present in the build but not switched on

### Artifact DB str_replace action is built but flagged off

A new str_replace write action for the artifact database is built but not yet exposed to users

**What**

A new `str_replace` action for the artifact database's `write_db` tool is now fully implemented, including its schema and permission checks. It would let a single exact, unique piece of text inside one field of a stored document be swapped out (via `field`, `old_str`, `new_str`, `replace_all`, and `if_version` parameters) without resending the whole document. However, it's currently gated behind internal flags and isn't exposed.

**Why**

This lays groundwork for more efficient, targeted edits to artifact documents, but it isn't available to use yet.

- Flag `tengu_umber_stile`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Flag `tengu_umber_lattice`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: on, compiled default: off)
- Area: Artifacts
- Names: `str_replace`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 4/5
- Present in the build but not switched on

### Artifact database gains str_replace, optimistic concurrency, batch admin/interact levels

Artifact database tool adds find-and-replace edits, version-conflict protection, and admin-level access

**What**

The artifact database tool (which Claude uses to store and query structured data behind an artifact) gained several new capabilities:

- `str_replace`: edit one field of a stored document by supplying the exact old text and its replacement, instead of resending the whole document; the text must match exactly once in that field, and a `replace_all` option is available for multiple matches.

- `if_version`: an optional check that rejects a write with a `version_mismatch` error if the document changed since it was last read, guarding against overwriting newer data.

- `as_level`: lets a read or write act with 'interact' or 'admin' access level instead of the caller's default.

New structured error types were also added so failures are more specific: no match found for the replacement text, an ambiguous (non-unique) match, the target field missing, the target field not being a string, or a version mismatch.

**Why**

Targeted find-and-replace edits mean Claude no longer has to resend an entire document just to change one field, and the version check guards against two writers silently overwriting each other's changes to the same document.

- Flag `tengu_umber_stile`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Area: Artifacts
- Names: `str_replace`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 4/5
- Present in the build but not switched on

### Artifact permission-ask classifier reworked into five named classes with a rollout gate

Artifact permission prompts now sort into five distinct classes instead of one generic ask

**Unclear.** Whether the `tengu_artifact_five_class_asks` gate is enabled for this site's account is unread, so no reading can be reported.

**What**

Artifacts (Claude Code's generated files/apps) that need to ask permission before taking some action are now classified into one of five named categories: `delete`, `access_change`, `standing_job`, `public_change`, or `foreign_read`. Each class carries its own metadata about whether and how the answer can be remembered. A new consent cache keyed by account and conversation also remembers past answers within that scope.

**Why**

Sorting asks into specific classes instead of one generic permission check lets Claude Code apply different remembering rules to different kinds of risk, for example treating a delete differently from a one-time read.

- Area: Artifacts
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 4/5
- Present in the build but not switched on

### Artifact-database str_replace edit op, gated off by default

Artifact database gains a targeted str_replace edit operation, currently gated off

**What**

The artifact database tool is gaining a new `str_replace` write operation that lets Claude edit a single string field in place by matching an exact old string and replacing it with a new one, instead of having to resend the whole document. It supports `replace_all` (to replace every match) and `if_version` (to only apply if the document is at an expected version), and it's wired into the existing `write_db`/batch write path with new `edit`, `ifVersion`, and `asLevel` parameters.

It also produces specific error messages when things go wrong: no match found, an ambiguous match, a missing field, a field that isn't a string, or a version mismatch.

**Why**

This makes small edits to artifact database documents cheaper and less error-prone than rewriting the whole document, but the feature is currently controlled by a setting nothing has been read about, so it isn't confirmed as active.

- Flag `tengu_umber_stile`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Area: Artifacts
- Names: `str_replace`, `if_version`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 4/5
- Present in the build but not switched on

### Artifact-database write gains a string-replace op and optimistic versioning

Artifact database writes gain a string-replace operation and version-checked writes

**What**

The artifact database's `db_write` action (used to store structured data alongside an artifact) gets two additions:

- A new `strReplace` write operation that finds and replaces text within a field, with an optional `replaceAll` flag to replace every match instead of just the first.

- An `ifVersion` check that only performs the write if the document is still at the expected version number, an approach called optimistic concurrency control that avoids overwriting someone else's more recent change.

Write results can now also report the document's new version number in the tool output.

**Why**

This makes it possible to do targeted text edits within an artifact's stored data instead of rewriting whole fields, and to guard against two writes clobbering each other when the underlying document has changed since it was last read.

- Flag `tengu_umber_stile`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Flag `tengu_umber_lattice`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: on, compiled default: off)
- Area: Artifacts
- Names: `str_replace`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 4/5
- Present in the build but not switched on

### New 'Projects' thread recap classification path, gated off by default

A new 'Projects' recap mode for the background classifier can summarize thread status, currently unread/off

**What**

Claude Code has a background classifier (`tengu_bg_classify`) that works out the state of a conversation turn behind the scenes. It has gained a new `projectsRecap` mode: when called with `projectsRecap: true`, it skips its usual preclassify/heuristic logic, uses a different system prompt (which can be swapped out remotely), and asks the model to produce a recap "card" describing the thread's status as one of needs_reply, needs_approval, done, failed, or working, plus a short "happened" summary. If the model's response isn't valid JSON, it retries once.

Results and failures of this new path are recorded under a `projects_thread_recap` telemetry event, with failure reasons such as `heuristic_engine`, `line_truncated`, `parse_failed`, and `side_query_failed`.

**Why**

This looks like groundwork for a "Projects" feature that shows a quick status recap of a conversation thread (needs a reply, needs approval, done, failed, or still working) without a person having to read the whole thread.

- Flag `tengu_projects_thread_recap`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Flag `tengu_projects_thread_recap_prompt`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: not a boolean we can read)
- Area: Projects
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 4/5
- Present in the build but not switched on

### New artifact 'ask class' consent/remember system

A new unified consent system governs sensitive artifact actions like delete and access changes

**Unclear.** Whether unattended foreign reads are actually allowed to proceed depends on the `tengu_artifact_foreign_read_unasked` gate, which has not been read for this release.

**What**

A new consent system now governs a set of sensitive artifact operations: deleting an artifact, changing whether it's public, changing who can access it, standing (recurring) jobs, and reading an artifact someone else owns. Approving one of these actions can now cover its related files for the rest of the conversation, so the same consent isn't asked for repeatedly. A new telemetry event also records when a foreign (someone else's) artifact is read without being asked about first.

**Why**

This reduces repeated approval prompts for related artifact actions within a single conversation, while still tracking cases where a foreign read happens without an explicit ask.

- Area: Artifacts
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 4/5
- Present in the build but not switched on

### SDK MCP servers can now skip the control-channel handshake via manifests

SDK-registered in-process MCP servers can now skip a round-trip handshake at session start

**What**

A new `sdkMcpServerManifests` field on `set_servers` lets the host application pre-run an MCP server's own `initialize` and `tools/list` calls in-process and hand the results directly to the CLI. The CLI then uses those results to answer its own MCP client's handshake locally, instead of exchanging `mcp_message` control messages back and forth before the first turn.

**Why**

Registering multiple in-process MCP servers this way costs no control-channel round trips before the first turn, which should make sessions with several SDK-provided MCP servers start faster.

- Flag `tengu_sdk_mcp_manifests`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: on)
- Area: MCP
- Names: `sdkMcpServerManifests`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 4/5
- Present in the build but not switched on

### SDK/host `initialize` gains a `workspaceTrust` option to programmatically grant directory trust

SDK/host initialize can now grant directory trust programmatically via a validated workspaceTrust option

**What**

The `initialize` request now accepts a `workspaceTrust` option (`{accepted, directory}`) that a host or SDK client can use to grant trust for a working directory without the user seeing Claude Code's own trust dialog. A new handler checks that the directory is an absolute path, that it resolves to the same trust key as the session's working directory, and that it isn't a screened or untrusted network path, before recording durable trust for it and re-applying project settings. A telemetry event records the outcome. On the SDK side, if `accepted` is true but `directory` isn't an absolute path (checked against both POSIX and Windows path separators), the whole trust object is discarded and a warning is logged instead of being applied.

**Why**

This lets a host application that has already confirmed directory trust with the user pass that confirmation through safely, with validation in place to stop a malformed or relative path from being accepted as trusted.

- Area: SDK
- Names: `workspaceTrust`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 4/5
- Present in the build but not switched on

### New plugin host APIs: command.list, command.register, command.run, ui.open, ui.close

Plugins can now list, register, and run slash commands, and open or close a UI surface

**What**

Plugins (add-on packages that extend Claude Code) now have access to new host operations, functions the host application exposes for plugin code to call:

- `command.list` - list existing slash commands

- `command.register` - register a new slash command, including its name, description, argument hint, and whether it runs immediately

- `command.run` - programmatically run a command

- `ui.open` and `ui.close` - open or close a UI surface

**Why**

This gives plugin authors more direct control over slash commands and interface panels, so a plugin can define and trigger its own commands and manage its own UI without relying on the user typing them manually.

- Area: Plugins
- Names: `command.list`, `command.register`, `command.run`, `ui.open`, `ui.close`
- Tier: Use it now
- Useful: 5/5
- Signal: 3/5

### Plugin SDK gains a `command` namespace: register/run/list slash commands

Plugins can now register, run, and list slash commands through a new `$.command` API

**What**

The plugin SDK now includes a `command` namespace, mirroring the existing `tool` namespace:

- `$.command.register` defines a new slash command, taking `{ name, description, argumentHint?, immediate? }`, where `name` must be letters, digits, `_` or `-`, up to 64 characters

- `$.command.run` invokes a command programmatically

- `$.command.list` enumerates available commands

The internal bridge that governs which events plugins can send now also allows `command.list` and `command.register`, each with real validation (checking name and description) and a guard against registering mid-turn.

**Why**

This gives plugins a dedicated way to define and manage their own slash commands, rather than only being able to work with tools.

- Area: Plugins
- Names: `command.register`, `command.run`, `command.list`
- Tier: Use it now
- Useful: 5/5
- Signal: 3/5

### Plugin commands can now be registered/run/described via new $.command.* hook API

Plugins can now register, run, list and describe their own slash commands via a new command API

**What**

Plugins can now define and manage their own slash commands through a new API:

- `command.register` - registers a new slash command, rejecting it if the name collides with another plugin's command, a built-in command, or an MCP command, and capping how many commands a single plugin can register

- `command.run` - lets a plugin queue up a command to run in the current session

- `command.list` - lists available commands along with where each one comes from (built-in, plugin, user, or MCP)

- `command.describe` - lets a hook dynamically change a command's description, argument hint, or whether it's hidden

A plugin-registered command that doesn't have a matching `command.run` hook to actually handle it now shows a clear explanatory message instead of doing nothing, telling the plugin author to add a `command.run` hook.

**Why**

This lets plugin authors add fully custom slash commands to Claude Code rather than being limited to built-in commands, and gives clear feedback when a plugin command is registered but not wired up to do anything yet.

- Area: Plugins
- Tier: Use it now
- Useful: 5/5
- Signal: 3/5

### /design command reworked into four routed modes (types, canvas, hub, consent)

/design command's internal dispatch rewritten into four routed modes

**What**

The `/design` command's internal logic was rewritten to pick between four modes — `consent`, `types`, `canvas`, and `hub` — each with its own description, menu text, argument hint, and file-loading behavior; canvas mode now loads design canvas files specifically. The command also gained flags controlling whether subcommands must be used bare and whether it survives a bundled kill switch, and its policy gate (the check for whether an organization allows it) is now skipped for the `types` and `canvas` modes.

**Why**

This restructures how `/design` behaves depending on mode, and means the `types` and `canvas` modes are no longer subject to the same organization policy gate as the rest of the command, which admins should be aware of when managing `/design` availability.

- Area: Design Command
- Names: `/design`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### Command execution can now be intercepted by command.run/command.describe hooks

Slash-command execution can now be intercepted and rewritten by command.run/command.describe hooks

**What**

Slash commands now pass through a new hook chain when they run, keyed on two hook events named `command.run` and `command.describe`. A hook (a custom script that reacts to Claude Code's behavior) can observe or rewrite the text a command prints before it's shown, using a `next()` pattern to pass control along the chain. Claude Code also now shows a clearer error message when a queued command never actually ran, explaining that it did not go through `command.run`.

**Why**

This gives hooks a formal way to intercept and modify slash-command output, and gives users a clearer explanation when a command was queued but never executed.

- Area: Hooks
- Names: `command.run`, `command.describe`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### Hook event names gain a wildcard/negation pattern grammar and a 'classic.' namespace

Hook event names now support wildcard and negation patterns, and internal plugin hooks are namespaced as `classic.`

**What**

Hooks (scripts that run automatically at points like `PreToolUse`, before a tool call executes) can now be registered against event name patterns, not just exact names. A pattern can be `*` (matches everything), `<prefix>.*` (matches everything under a prefix), or either form prefixed with `!` to negate it. Separately, internally-defined plugin hook events are now namespaced with a `classic.` prefix, so `PreToolUse` becomes `classic.PreToolUse` internally.

**Why**

Wildcard and negation patterns let a single hook registration cover a group of related events instead of listing each one individually. The `classic.` namespace distinguishes built-in plugin hook events from other event sources as the hook system grows more general.

- Area: Hooks
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### New retryable policy-helper execution engine with backoff, added under 'settings_policy_helpers_per_os'

Claude Code adds a retryable engine for organization-managed 'policyHelper' settings scripts, with backoff on transient failures

**What**

Claude Code now supports `policyHelper`, a mechanism for organizations to run an executable at startup that computes managed settings for a machine. This release adds a full execution engine for that: arming and running the helper (or a pre-approved static payload instead of running anything), a remote consent/approval flow shown through a managed-settings dialog, the ability to re-arm a helper mid-session, and automatic retries with increasing wait times between attempts.

Retries only happen for failures judged temporary, such as the helper exiting with a nonzero code, timing out, not being a file, or its interpreter being unavailable. Failures judged permanent, such as a bad path, an oversized file, a parse failure, an invalid envelope, or a value rejected by the settings schema, are not retried.

**Why**

This makes organization-managed settings more resilient to one-off glitches (like a flaky script or a slow interpreter) while failing fast on configuration mistakes that retrying can't fix.

- Area: Managed Settings
- Names: `policyHelper`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### New tool methods project_memory_list and project_memory_read

New project_memory_list and project_memory_read tool methods let Claude read (not write) a project's remembered memory files

**What**

The Project tool gains two new methods:

- `project_memory_list` lists a project's memory files (what Claude has remembered about the project across separate chats), showing each file's path, size, and last-updated time, capped at a maximum number of entries with a notice if the list was cut short.

- `project_memory_read` reads the contents of one memory file by its path, returning the content and a notice if the server truncated it for being too large.

These memory files are separate from a project's regular docs, and this tool can only read memory, not write to it.

**Why**

This lets Claude look back at what it has previously remembered about a project in past sessions, giving it continuity across chats without needing the docs to be re-read each time.

- Area: Project Memory
- Names: `project_memory_list`, `project_memory_read`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### Projects tool gains a "project memory" section

Projects tool now includes a 'Project memory' section listing files remembered across chats

**What**

The context Claude Code loads when working on a project now includes a new '## Project memory' section, listing files that have been remembered for that project across different chat sessions, alongside existing docs, files, and synced sources. A new validation step checks incoming project-memory data and drops any entries that don't match the expected structure. The memory files come with a note pointing to `project_memory_read` and `project_memory_list` for reading them, and an instruction to treat their contents as data rather than as instructions, the same way documentation files are treated.

**Why**

This lets Claude Code carry forward remembered project information between separate chat sessions, while explicitly guarding against memory content being misread as instructions to follow.

- Area: Project Memory
- Names: `project_memory_read`, `project_memory_list`
- Tier: Use it now
- Useful: 4/5
- Signal: 3/5

### Directory/file sync can be remotely muted via an 'emergency switch'

Cloud session file sync can now be remotely paused by Anthropic via an 'emergency switch'

**What**

The system that syncs files and directories for cloud sessions can now be paused remotely by Anthropic through what's called an 'emergency switch.' Claude Code checks this switch both when sync starts and periodically afterward. When it's tripped, file uploads and pulls stop and the user sees a warning message explaining that sync was paused on that machine, instead of sync silently continuing to run.

**Why**

This gives Anthropic a way to halt file syncing on a given machine if something goes wrong, and tells the user clearly when that has happened rather than leaving sync failing silently.

- Area: Cloud Sync
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 3/5
- Present in the build but not switched on

### New 'classifier-only' tool category: some tools can only be allowed by the auto-mode classifier, never by saved rules or hooks

Some tools can now only be allowed by the auto-mode classifier, ignoring saved allow rules and hooks

**What**

A tool can now be marked `classifierOnly`, meaning its permission decisions must go through the automatic classifier that decides whether to allow tool calls in auto mode. For such a tool:

- Saved "always allow" rules no longer let it through

- Hook-based allows are ignored

- Outside of auto mode, the tool is denied outright with the message "Only the auto-mode classifier can allow [tool name]"

**Why**

This gives certain tools a stricter permission path that can't be bypassed by a standing allow rule or a hook, ensuring the auto-mode classifier is always the one making the call for them.

- Area: Auto Mode
- Names: `classifierOnly`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 3/5
- Present in the build but not switched on

### New attested-Artifact-type marking/revocation system

Artifacts can now carry trust badges marking them as pinned, templated, or first-party types

**What**

Claude Code now tracks "attested" marks on Artifacts (generated documents or files shown in a side panel), such as being an organization-pinned instance, a pipeline instance, a template instance, or a first-party type, each with an issue and revoke timestamp. When applicable, Artifact tool output can show a trust badge like "attested: a published first-party Artifact type" or a note that an organization's admins pinned it for its type.

**Why**

This gives you a way to tell, directly in the Artifact output, whether a given Artifact type is officially sanctioned, such as being published by Anthropic or pinned by your organization's admins, rather than an arbitrary or unverified type.

- Area: Artifacts
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 3/5
- Present in the build but not switched on

### New env-gated 'five class asks' artifact permission behavior

New env variable CLAUDE_CODE_ARTIFACT_FIVE_CLASS_ASKS toggles a permission-asking behavior for artifacts, logged via telemetry

**Unclear.** What the permission-asking behavior actually changes when turned on is not described in the finding.

**What**

A new environment variable, `CLAUDE_CODE_ARTIFACT_FIVE_CLASS_ASKS`, controls a permission-asking behavior for artifacts (defaulting to off if unset). The setting is read once and fixed for the life of the process, and whether it was on is recorded in telemetry.

**Why**

The finding doesn't specify what the "five class asks" behavior itself does when enabled, only that it exists and is now controllable and logged.

- Area: Artifacts
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 3/5
- Present in the build but not switched on

### New pane-management system for plugin UI panels

Plugins can now open UI panels, capped per plugin, with a hook that can veto closing one

**What**

Claude Code has a new system for managing UI panels ('panes') that plugins can open, each tracked by an id, title, owning plugin, and focus state. A single plugin can only have a limited number of panes open at once; opening another beyond that limit requires closing one first. Closing a pane now runs an asynchronous `ui.close` hook chain first, so a hook can intervene and keep the pane open instead of letting it close.

**Why**

This gives plugins a structured way to present multiple panels while preventing any one plugin from opening an unlimited number of them, and lets hooks control cleanup behavior when a pane is about to close.

- Area: UI Panels
- Names: `ui.close`
- Tier: Nothing to try yet
- Useful: 4/5
- Signal: 3/5
- Present in the build but not switched on

### Cursor IDE config import (`/import`)

/import can now bring in configuration from Cursor IDE, not just Codex and Gemini CLI

**What**

The `/import` command gains a large new importer for Cursor IDE configuration. It scans both the user-level `~/.cursor` directory and project-level `.cursor/` (plus `.agents/skills`) for `mcp.json`, `rules/*.mdc` files, skills, commands, `hooks.json`, and `.cursorrules`, then converts what it finds into Claude Code MCP servers, skills, `CLAUDE.md` instructions, and slash commands.

Safety checks along the way include:

- Refusing to follow symlinks

- Flagging values that look like credentials

- Refusing to import settings scoped with `workspaceFolder`

- Enforcing size caps and de-duplicating imported items

Some Cursor features can't be mapped and are called out explicitly: hooks, `.cursorignore`, Cursor Memories, Custom Modes, and Team Rules. Messaging elsewhere in `/import` about unmapped items and project-level config now also mentions `.cursor/` alongside the existing `.codex/` and `.gemini/` directories. Importing from Cursor requires Claude Code v2.1.265 or later.

**Why**

This lets people moving from Cursor to Claude Code bring over their existing rules, MCP servers, and commands automatically instead of recreating them by hand, while the safety checks and explicit list of unmapped features keep the import honest about what it can and can't do.

- Area: Internals
- Names: `/import`
- Tier: Use it now
- Useful: 5/5
- Signal: 2/5

### New /design and /slides commands to create artifacts from published types

New /design and /slides commands generate Design and Slides artifacts from a brief

**What**

Two new slash commands are available:

- `/design` creates a Design artifact (a visual mockup) from a short brief you give it

- `/slides` creates a Slides deck artifact from a short brief you give it

Both work by having Claude look up the matching published artifact type and generate a new artifact from it.

**Why**

These give you a quick way to turn a plain-text description into a starting draft of a visual design or a slide deck, without having to set up the artifact yourself.

- Area: Slash Commands
- Names: `/design`, `/slides`
- Tier: Use it now
- Useful: 5/5
- Signal: 2/5

### policyHelpers now honored from remote managed settings too

policyHelpers can now be delivered via remote managed settings, not just admin-controlled policy sources

**What**

`policyHelpers` (settings that let an admin point to a program computing part of the managed configuration) can now be honored not only from admin-controlled policy sources but also when delivered as a plain policy payload through remote managed settings, the same way any other remote settings key is delivered. If a helper or payload touches anything covered by the managed-settings approval dialog, the settings still have to be verified and approved for that session first. The related `policyHelper` setting itself is still never honored when delivered remotely.

**Why**

This widens where `policyHelpers` configuration can come from while keeping the approval-dialog safeguard in place for anything sensitive, and keeps a stricter line for `policyHelper` specifically, which remains local-only.

- Area: Managed Settings
- Names: `policyHelpers`
- Tier: Use it now
- Useful: 3/5
- Signal: 3/5

### Auto mode classifier gains a 'flag instead of block' delivery mode for classifier-only tools

Auto mode classifier can now flag and allow an action instead of blocking it outright

**Unclear.** Whether `tengu_auto_mode_decision` affects this behavior is unclear, since no reading of that gate has been taken yet.

**What**

Auto mode uses a classifier to decide whether to allow, block, or ask about actions from tools marked as "classifier-only." Such tools can now set `onBlock: 'flag'`. With this set, if the classifier would normally block the action, refuse to review it, or give no verdict, the action is instead allowed to proceed but is tagged with a `decisionReason` explaining it was "Flagged by the classifier, delivered with its warning: ..." rather than being denied.

A related safeguard was also added: if a classifier-only tool ends up sending the classifier nothing to evaluate, the action is now denied outright with an explicit message noting the classifier was given nothing to judge.

**Why**

This lets certain tools proceed with a visible warning instead of being hard-blocked whenever the classifier is unsure or unavailable, while still catching the edge case where a tool accidentally gives the classifier no input to judge.

- Area: Auto Mode
- Names: `onBlock`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### New "Panes" plugin UI surface added, wired to ui.open/ui.close hooks

A new 'Panes' UI system renders the windowed panes plugins open via ui.open/ui.close

**What**

A full "Panes" interface has been added to support the new plugin windowing feature: internal state tracking which panes are open, shown, focused, or closing; functions to open, close, and focus panes; a per-plugin maximum pane count; and a rendered "Pane" visual component. It's driven by the `ui.open` and `ui.close` plugin events, and the Pane surface is now registered alongside existing UI surfaces like the above-prompt banner and the diff dialog.

**Why**

This is the visual half of the plugin pane system: it's what actually draws a plugin's pane on screen and lets multiple panes be tracked, focused, and closed.

- Area: UI Panels
- Names: `ui.open`, `ui.close`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### New network-off read consent path: attestedReadConsented can bypass the ask-permission prompt

A new consent check can let network-off reads of artifacts or URLs skip the permission prompt

**Unclear.** The finding doesn't say what establishes attestedReadConsented or in what situations it becomes true.

**What**

When network access is turned off, reading an artifact or URL normally still requires an 'ask' permission prompt unless it's your own artifact. Now there's an additional check, `attestedReadConsented`, that can also satisfy this requirement: if it returns true, the read is allowed to proceed without the usual prompt, even without ownership.

**Why**

This adds another path for skipping the read-permission prompt when network access is disabled, reducing unnecessary interruptions in cases where consent has already been established.

- Area: Permissions
- Names: `attestedReadConsented`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Plugin SDK gains a windowed `ui.open`/`ui.close` surface, capped at 8 panes per plugin — no renderer found for the 'currently shown' selector

Plugins can now open persistent UI panes via ui.open/ui.close, capped at 8 panes per plugin

**What**

Claude Code's plugin system (add-ons that extend its functionality) gains two new events, `ui.open` and `ui.close`, that let a plugin open and close its own titled, persistent pane in the interface. The system tracks which panes are open, which one is focused, which one is currently shown, and where each is placed. Each plugin can have at most 8 panes open at once; trying to open a 9th requires closing one first.

**Why**

This gives plugins a proper windowed UI surface to display their own persistent content, rather than being limited to simpler one-off UI elements.

- Area: UI Panels
- Names: `ui.open`, `ui.close`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Static system prompt mode (tengu_carved_slate) strips dynamic content from agent prompts when on

A new staticSystemPromptEnabled flag can strip dynamic content from agent system prompts

**What**

A new setting, `staticSystemPromptEnabled`, when turned on, changes how the system prompt (the instructions given to an agent before a conversation starts) is built for both the general-purpose agent and the main session. When enabled, the prompt builders skip generating dynamic sections, such as the call that gathers environment information and the block that reports the platform version, producing a more static, fixed prompt instead.

**Why**

Skipping dynamic content makes the system prompt more predictable and reusable, which can help in cases where a fixed prompt is preferred over one that changes based on environment details. As of this release the setting has not been read as on for this site's account or the anonymous baseline.

- Flag `tengu_carved_slate`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: on, compiled default: not a boolean we can read)
- Area: System Prompt
- Names: `staticSystemPromptEnabled`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### `claude import` gains Cursor support

claude import and /import can now pull configuration from Cursor, not just Codex and Gemini

**What**

The `claude import` command and its `/import` slash command can now import from Cursor, in addition to the existing Codex and Gemini sources. Running `/import` (or `claude import`) now offers `cursor` as a source option, and it brings in Cursor's instruction files, MCP servers, commands, subagents, and skills, the same way it already did for the other two tools.

**Why**

This lets people switch to Claude Code from Cursor without having to manually recreate their setup: their existing configuration is picked up automatically.

- Flag `tengu_import`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: on, compiled default: off)
- Area: Internals
- Names: `/import`, `claude import`, `cursor`
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### New $.fs.* filesystem API for plugins with read/write size limits

Plugins get a new file system API for reading, writing, and listing files, capped at 4MB

**What**

Plugins now have a filesystem API with `readFile`, `writeFile`, `exists`, `stat`, and `listDir` operations, all scoped to a resolved working directory. Both reads and writes are capped at 4,194,304 bytes (4MB); exceeding the limit returns an explicit refusal saying the file is over the byte limit.

**Why**

This lets plugins interact directly with files on disk in a controlled way, with a size limit that prevents a plugin from reading or writing unexpectedly huge files.

- Area: Plugins
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### New --attach-serve CLI flag to attach a headless client to an existing cloud session

New `--attach-serve` flag connects a headless client to an already-running cloud session instead of starting a new one

**What**

A new command-line flag, `--attach-serve`, lets a headless (non-interactive) Claude Code launch attach to an existing cloud session by its ID (in the form `cse_...`) instead of creating a new one. It can't be combined with `--cloud` or `--remote`, and it only works when the launch is already running in the non-interactive stream-json serve mode.

**Why**

This lets a local, headless client join and serve an existing cloud session in progress, rather than always spinning up a brand-new one.

- Area: Cloud Sessions
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### Slash commands can now supply custom argument autocompletion

Slash commands and skills can define custom argument autocompletion suggestions

**What**

Slash commands and skills can now define a `getArgumentCompletions` callback. As you type arguments for a command in the prompt input, Claude Code calls this callback to generate custom suggestions specific to that command, instead of relying only on generic completion.

**Why**

This lets command and skill authors offer relevant, context-aware suggestions while typing arguments, making custom commands easier to use correctly.

- Area: Slash Commands
- Names: `getArgumentCompletions`
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### Workflow tool gains resumeFromRunId: reads a stored run journal and restarts the script from it

Workflow's resumeFromRunId now actually reloads a saved run and restarts the script from it

**What**

The `Workflow` tool's `resumeFromRunId` option now does real work: when given a run ID, Claude Code validates it, reads back a stored journal of that earlier run, and pulls out the saved script body to pick up the workflow from where it left off, instead of starting fresh. The message shown when a background workflow finishes has also changed: rather than showing a literal example run ID, it now tells you to relaunch with `Workflow({scriptPath, resumeFromRunId})` using the run ID from the summary.

**Why**

This makes it practical to resume a long-running or interrupted workflow using the run ID Claude Code already gives you in its completion summary, instead of that field existing but not actually restoring anything.

- Area: Workflows
- Names: `resumeFromRunId`
- Tier: Use it now
- Useful: 4/5
- Signal: 2/5

### --system-prompt-snapshot now defaults on universally, not just for the built-in prompt

--system-prompt-snapshot's documented default is now described as always-on, not just for the built-in prompt

**What**

The help text for `--system-prompt-snapshot` now describes the setting as on by default in all cases, rather than only by default for the built-in system prompt (previously, using `--system-prompt` or `--append-system-prompt` turned snapshotting off automatically). With the default on, the system prompt - including any text passed via `--system-prompt` or `--append-system-prompt` - is rendered once on the conversation's first request, and every later request or resume reuses that exact recorded version, even if a later launch passes different prompt text, until the conversation compacts (summarizes and trims its history).

Relatedly, when snapshotting is on, a `set_model` system-prompt override now takes effect at the next compaction rather than at the next turn.

**Why**

This means custom system prompts set via `--system-prompt` or `--append-system-prompt` are now also locked in from the first request by default, so changing that text on a later launch of the same conversation won't retroactively change what's already been recorded - only a fresh conversation or a compaction will pick up new text.

- Area: System Prompt
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### 1M-context alias switching gets structured refusal reasons

Switching to a 1M-context model now gives a specific reason when it's refused

**What**

When you use `/model` to switch to a `[1m]`-suffixed model alias (one offering a 1 million token context window), Claude Code now checks for three specific reasons the switch might not be allowed, each with its own message and tracking: 1M context is turned off via the `CLAUDE_CODE_DISABLE_1M_CONTEXT` setting, the model or carrier doesn't support 1M context, or the alias simply has no 1M variant for the current mode. Only if none of these apply does it fall back to the older Opus-1M check.

**Why**

This gives clearer, more specific feedback when a 1M-context model switch is refused, instead of one generic message covering several different underlying reasons.

- Area: Models
- Names: `/model`, `CLAUDE_CODE_DISABLE_1M_CONTEXT`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Artifact db read/write gains an 'as_level' run-as parameter with server-confirmed enforcement

Artifact db_read/db_write can now run 'as' a different access level, with confirmation of whether the server enforced it

**What**

The `db_read` and `db_write` operations on artifacts can now take an `asLevel` parameter (shown in results as `as_level`), which asks the request to run as if it were at a different access level than the caller normally has. The result reports `as_level_confirmed` (drawn from the server's `levelConfirmed` field), stating whether the server actually enforced that level. When it isn't confirmed, a caveat message is shown.

**Why**

This lets a database read or write simulate running under different access rules, while flagging clearly when the requested level wasn't actually guaranteed, so results aren't mistaken for having been checked under that level when they weren't.

- Area: Artifacts
- Names: `asLevel`, `as_level_confirmed`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Artifact-database writes gain as_level and version pinning

Artifact database reads/writes can now use a reduced access level and pin to a document version

**What**

Artifact database `write_db` and `read_db` calls can now pass an `as_level` parameter set to `interact` or `admin`, letting Claude act with a reduced access level to test what a less-privileged viewer would be able to do. Writes can also pin themselves to a specific document version using `if_version`, which fails with a `version_mismatch` error if the document was changed in the meantime.

**Why**

`as_level` lets you check how an artifact behaves for users with limited permissions, and `if_version` protects against accidentally overwriting a document that changed since it was last read.

- Area: Artifacts
- Names: `as_level`, `if_version`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Code block renderer gains a 'diff' format with unified-diff parsing and validation

Code display component gains a validated 'diff' format alongside plain source, plus a wrap/truncate display option

**What**

The internal `Code` component used to render code blocks now accepts a `format` value of `"diff"` in addition to the existing `"source"`. When set to `"diff"`, the text is run through a unified-diff hunk parser that checks the `@@ -a,b +c,d @@` header numbers are valid and within bounds, rejecting malformed input with errors like "no @@ hunk header found" or a header that isn't within the expected number of lines.

A companion `wrap` prop now controls how long lines are displayed, taking either `"wrap"` or `"truncate-end"`.

**Why**

This lets Claude Code render diff output as a distinct, validated format rather than treating it as plain source text, and lets long lines in code blocks be wrapped or truncated instead of always displaying one way.

- Area: UI Components
- Names: `diff`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Hook registration: duplicate once-only event registration now throws, and pattern-based event names supported

Hook registration now rejects registering the same once-only event twice and validates names as patterns

**What**

When a hook (custom code that runs on a specific event) is registered with `on(event, ...)`, event names are now validated as patterns rather than plain names. Registering the same once-only event more than once now throws an error reading "registered twice." Error messages for hook registration also now refer to a 'pattern' instead of an 'event' in their wording.

**Why**

This catches a mistake, accidentally registering the same one-time hook event twice, that previously could pass silently, and the wording change reflects that event names are now matched as patterns rather than exact strings.

- Area: Hooks
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### MCP channel flags require plugin:/server: tagging

--channels and its development-channels flag now require explicit plugin: or server: tags

**What**

Values passed to the `--channels` flag and to `--dangerously-load-development-channels` must now be tagged, in the form `plugin:<name>@<marketplace>` or `server:<name>`. An entry without one of these tags is now rejected with an explicit error explaining the required formats.

**Why**

Requiring the tag removes ambiguity about whether a channel entry refers to a plugin or an MCP server, catching malformed flag values immediately instead of letting them silently fail or resolve incorrectly.

- Area: MCP
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### New 'command.run' hook pipeline for slash-command dispatch

Slash commands can now be intercepted and their output overridden by a new 'command.run' hook

**What**

Running a slash command (like `/compact`) can now be routed through a new `command.run` hook chain before it executes. Hooks are user- or project-defined scripts that run at specific points in Claude Code's workflow. With this change:

- A hook can intercept a slash command before it runs

- A hook's own output text can "retell" (override) the text the command would otherwise have produced

**Why**

This lets hook authors customize or replace what happens when a slash command runs, rather than only reacting to it afterward.

- Area: Hooks
- Names: `command.run`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### New "Pane" keybinding context added

A new "Pane" keybinding context adds tab, enter, escape, and scroll key mappings for panes

**What**

Claude Code added a new keybinding context called "Pane", with default mappings including:

- `tab` / `shift+tab` for moving to the next/previous element above the prompt

- `enter` / `escape` for pressing/leaving the pane

- arrow keys, page keys, `home`, and `end` for scrolling within the pane

**Why**

This gives panes their own dedicated set of keyboard controls for navigation and scrolling, which you can further customize like other keybindings.

- Area: Terminal UI
- Names: `Pane`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### New "allow_plugin_directory_search" HIPAA/ZDR policy control

New `allow_plugin_directory_search` policy setting controls plugin directory search under compliance modes like HIPAA

**What**

A new policy permission key, `allow_plugin_directory_search`, has been added alongside the existing `allow_plugin_skill_search` setting. It's available both under HIPAA compliance mode and in the general list of enterprise policy keys, and it governs whether plugin directory search is allowed under restrictive compliance settings.

**Why**

This gives organizations using strict compliance modes (such as HIPAA or zero data retention) a separate, explicit control over plugin directory search, rather than only being able to control plugin skill search.

- Area: Compliance
- Names: `allow_plugin_directory_search`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### New CLI flag --attach-serve for desktop app helper sessions

New hidden --attach-serve flag lets the desktop app attach a helper session to a bound cloud session

**Unclear.** Exactly how the desktop app uses this attached helper session isn't stated.

**What**

A new hidden command-line flag, `--attach-serve <session_id>`, attaches a serve-only helper process to a cloud session that was bound and spawned by the Claude Desktop app. It is explicitly not meant for interactive use.

**Why**

This supports the desktop app's internal machinery for managing cloud sessions rather than being a feature for everyday command-line use.

- Area: Desktop App
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### New as_level parameter lets read_db/write_db simulate another access level

New `as_level` parameter lets read_db/write_db preview access as a lower-privileged user

**What**

The `read_db` and `write_db` artifact tools gain a new `as_level` parameter, which can be set to `interact` or `admin`. This lets the caller check what a page's access rules would allow at that access level, without actually changing the caller's own real permission level.

**Why**

This is useful for testing or previewing what a less-privileged user would be able to see or do in an artifact's database, without needing to lower or change your own actual access.

- Area: Artifacts
- Names: `as_level`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Plugin runtime API gains command hooks and UI window controls

Plugins can now register and run their own commands and open or close their own UI windows

**What**

The interface that plugins use to talk to Claude Code has grown new capabilities:

- `command.list`, `command.register`, `command.run`, and `command.describe` let a plugin define, list, describe, and run its own custom commands.

- `ui.open` and `ui.close` let a plugin open and close its own UI window, with options for the window's id, title, and whether it takes focus.

**Why**

This gives plugin authors more control over how their plugin presents itself and interacts with the user, beyond just running in the background.

- Area: Plugins
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Project memory browsing methods added to the artifact/project protocol

Projects gain the ability to list and read project memory files

**What**

The project/artifact system now supports two new actions: `project_memory_list` and `project_memory_read`, alongside the existing `project_info`, `project_read`, and `project_search`. These come with their own descriptions shown in the interface ('List project memory', 'Read project memory file') and are backed by a real tool that reads documents from a project's memory store.

**Why**

This lets Claude Code browse and read a project's stored memory files directly, rather than only being able to read general project documents, making project-level context easier to retrieve.

- Area: Project Memory
- Names: `project_memory_list`, `project_memory_read`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Slash commands/skills gain menuDescription and policyGate fields

Slash commands and skills can now define a shorter menuDescription and a policyGate to hide or disable them

**What**

Command and skill definitions can now include two new optional fields:

- `menuDescription` — a shorter description shown in menus or listing screens, separate from the full description

- `policyGate` — a policy-based check that can hide or disable a command based on a `.policy` condition

Both fields are now copied through when commands and skills are registered.

**Why**

This lets command and skill authors show a more concise description in compact UI listings while keeping a fuller description elsewhere, and lets administrators or the system disable specific commands based on policy.

- Area: Slash Commands
- Names: `menuDescription`, `policyGate`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Telemetry relay can forward individual signal types instead of always OTLP for all three

Telemetry export can now send metrics, logs, and traces to different destinations instead of forcing all three to OTLP

**What**

The `OTEL_METRICS_EXPORTER`, `OTEL_LOGS_EXPORTER`, and `OTEL_TRACES_EXPORTER` environment variables are now each computed individually based on the `telemetry.forward_to` configuration setting, rather than always being fixed to `"otlp"` (a standard telemetry export protocol).

**Why**

This lets you route metrics, logs, and traces to different backends per signal type instead of being forced to send all three the same way, giving more flexible control over where telemetry data ends up.

- Area: Telemetry
- Names: `OTEL_METRICS_EXPORTER`, `OTEL_LOGS_EXPORTER`, `OTEL_TRACES_EXPORTER`, `telemetry.forward_to`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### policyHelpers `onFailure`/`retries` per-OS validation messages added

Claude Code now warns when `onFailure` or `retries` are set on the wrong `policyHelper` key, and can refuse to start if an OS-admin helper fails

**What**

Admin-managed `policyHelpers.<os>` entries (per-operating-system scripts that compute managed settings at startup) can now declare `onFailure` (`"continue"` or `"refuse"`) and `retries` to control whether a failing helper blocks Claude Code's startup and how many times it's retried. New validation messages explain two rules:

- setting `onFailure` or `retries` on the singular, non-per-OS `policyHelper` key is ignored, with a warning, since those keys only apply to the per-OS entries

- when `onFailure: refuse` is set (or there's no static fallback) and the policy comes from an OS-admin source like MDM or the managed settings file, a failing helper is now startup-fatal: Claude Code won't start until it's fixed

**Why**

This makes clear to administrators which settings actually take effect on which config key, and lets them enforce that a broken policy helper stops Claude Code from starting rather than silently falling back.

- Area: Managed Settings
- Names: `onFailure`, `retries`
- Tier: Use it now
- Useful: 3/5
- Signal: 2/5

### Classifier can now auto-answer approval prompts in plan mode, not just auto mode

Claude Code's classifier can now auto-approve some tool prompts in plan mode, not just auto mode

**What**

Claude Code has a built-in classifier that can automatically answer a tool's permission request without showing a prompt to the person using it. Previously this only worked when the session's permission mode was exactly `auto`. Now it also works in `plan` mode, subject to an additional helper check.

As a safeguard, the classifier now also checks that the permission mode hasn't changed between when the approval request was first raised and when it's actually answered, so a mode switch mid-flight can't cause an approval meant for one mode to be applied under another.

**Why**

This lets more tool approvals in plan mode be handled automatically instead of always interrupting the user, while the added mode-consistency check prevents a stale approval decision from slipping through if the permission mode changes partway through.

- Area: Permissions
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Remote/cloud sessions: 'take back' held but unsent messages via Esc

Pressing Escape in a remote or cloud session can now take back a message that hasn't been sent yet

**What**

In remote and cloud sessions, messages you type while Claude is busy get queued and held until it's ready. Now, pressing Escape while idle with such a held message can reclaim it instead of triggering a full interrupt of the session, showing a notice that the message "wasn't sent to the cloud session."

**Why**

This gives you a way to cancel a message you typed but changed your mind about, without having to interrupt the whole cloud session just to stop it from being sent.

- Area: Sessions
- Names: `Esc`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Workflow tool can now recover a script from resumeFromRunId alone

The Workflow tool can now reconstruct a script to resume from just a run ID if the script path lookup fails

**What**

The `Workflow` tool (which runs scripted, multi-agent tasks) can now recover and resume a run using only `resumeFromRunId` when its `scriptPath` cannot be resolved. Internally, it looks up stored data for that run ID and reconstructs the script needed to continue. The tool can also now return a 'refused' outcome specifically for a resume request that doesn't succeed.

**Why**

This makes resuming an interrupted or background workflow more reliable: you no longer necessarily need a working script path on hand, since the run ID alone can be enough to pick the workflow back up.

- Area: Workflows
- Names: `resumeFromRunId`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### --fallback-model no longer claims to require --print

The --fallback-model CLI help no longer says it only works with --print

**Unclear.** The help text change implies broader applicability but does not confirm the flag's actual behavior changed in interactive mode.

**What**

The help text for the `--fallback-model` flag used to say '(only works with --print)', meaning it only applied when running Claude Code in headless mode via `--print`. That qualifier has been removed from the help output, suggesting the flag now also applies in normal interactive mode.

**Why**

If `--fallback-model` now works outside `--print`, it means an automatic backup model (used when the primary model is overloaded or unavailable) can kick in during regular interactive sessions too, not just scripted/headless runs.

- Area: Elsewhere
- Names: `--fallback-model`
- Tier: Use it now
- Useful: 2/5
- Signal: 2/5

### /plugin stats help line gated behind tengu_lantern_prism

The /plugin stats help line's visibility is confirmed tied to the tengu_lantern_prism gate

**What**

The help line "`/plugin stats` - Show skill usage and context costs", shown in `/plugin` help, continues to be shown or hidden conditionally, and this behavior is now confirmed to be controlled by the `tengu_lantern_prism` setting (with an environment variable override available).

**Why**

This confirms the mechanism gating whether the `/plugin stats` help text appears, which matters if that line seems to be missing.

- Flag `tengu_lantern_prism`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: on, compiled default: off)
- Area: Plugins
- Names: `/plugin stats`, `tengu_lantern_prism`
- Tier: Use it now
- Useful: 2/5
- Signal: 2/5

### Persisted tool results are now size-capped with truncation reporting

Large tool results saved to disk are now capped in size, with the response noting when truncation happened

**What**

When Claude Code saves a large tool result to disk, it now caps the amount of content it writes, by default limiting it to 1GiB (about one gigabyte). If the content had to be cut down to fit that limit, the trimmed result now includes a `truncatedAtBytes` field noting how much was kept.

**Why**

This keeps very large tool outputs from consuming unbounded disk space, while making it clear when a saved result has been shortened so it isn't mistaken for the complete output.

- Area: Tool Results
- Names: `truncatedAtBytes`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### New allowlist forwards Bun/mimalloc GC tuning env vars only for remote sessions

Remote sessions now pass through Bun and mimalloc garbage-collection tuning environment variables to spawned processes

**What**

A new allowlist of environment variables related to memory management tuning is now forwarded to spawned processes, but only when `CLAUDE_CODE_REMOTE` is set to true. The variables are `BUN_GC_TIMER_INTERVAL`, `BUN_GC_TIMER_DISABLE`, `BUN_GC_RUNS_UNTIL_SKIP_RELEASE_ACCESS`, `BUN_IDLE_GC_SECONDS`, and `MIMALLOC_PURGE_HOLES_MIN_INTERVAL`. These control garbage collection (automatic memory cleanup) timing in Bun, the JavaScript runtime Claude Code uses, and in mimalloc, a memory allocator library.

**Why**

This lets remote sessions be tuned for memory behavior via environment variables without affecting local sessions, which don't get these variables passed through.

- Area: Sessions
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### --plugin-dir now accepts a folder containing multiple plugins

--plugin-dir can now point at a folder holding several plugins at once

**What**

The `--plugin-dir` flag, previously used to load a single plugin from a directory, can now also be pointed at a directory that itself contains multiple plugin folders. Claude Code detects this case, loads each child folder that has a valid plugin manifest as its own plugin, and logs which children were loaded and which were skipped for lacking a manifest.

**Why**

This makes it easier to load a whole collection of local plugins for a session in one go, without repeating the `--plugin-dir` flag for each one individually.

- Area: Plugins
- Names: `--plugin-dir`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### AbovePrompt panes gain focus/click and digit-jump navigation

Panes above the prompt can now be focused by clicking or by pressing their number key

**What**

The panes shown above the input prompt (the "AbovePrompt" area) can now be focused directly:

- Clicking a pane focuses it

- Pressing a digit key jumps focus to the correspondingly numbered pane

- Focus automatically resets if the underlying pane data changes out from under you

**Why**

This makes it faster to navigate between multiple panes shown above the prompt without needing to cycle through them one at a time.

- Area: UI Panels
- Names: `AbovePrompt`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### Cursor added as supported agent-import/config source

The import command and config review now recognize Cursor as a source, alongside Codex and Gemini

**What**

The command that imports agent configuration and the related config-review messaging now recognize Cursor as a source, alongside the existing Codex and Gemini support. Claude Code can review a project's `.cursor` directory directly, the same way it already reads `.codex` and `.gemini`.

**Why**

Users who configure Cursor for a project can now bring that setup into Claude Code without manually recreating it.

- Area: Internals
- Names: `cursor`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### Import-fallback recognition extended to Cursor, alongside Codex/Gemini

CLAUDE.md import-fallback handling now recognizes Cursor alongside Codex and Gemini

**What**

Claude Code can fall back to importing instructions written for other AI coding tools when reading `CLAUDE.md` files. The marker pattern and source list used for this now recognize `cursor` as a third supported source, alongside the existing `codex` and `gemini` handling.

**Why**

Projects that already have Cursor-specific instruction files can now have those instructions picked up and merged by Claude Code the same way Codex and Gemini instructions already were.

- Area: Internals
- Names: `cursor`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### New 'mid-command' autocomplete suggestion mode and tab-to-complete mid-argument

Tab can now complete a command in the middle of what you've typed, not just at the end

**What**

The prompt input's autocomplete now supports a "mid-command" suggestion type, which applies a completion in the middle of a command line you're already typing rather than only at the cursor's end position. Pressing Tab now checks for this kind of mid-command completion first before falling back to its other existing tab-completion behavior.

**Why**

This lets you fix or complete an earlier part of a command you're typing without needing to retype everything after it, making command-line editing with Tab more flexible.

- Area: Command Line
- Names: `Tab`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### New pane scroll/paging keybinding actions

Six new keybinding actions let panes be scrolled and paged with dedicated shortcuts

**What**

Six new keybinding actions have been added: `pane:scrollUp`, `pane:scrollDown`, `pane:pageUp`, `pane:pageDown`, `pane:top`, and `pane:bottom`, shown in the UI as "scroll", "page up", "page down", "top", and "bottom".

**Why**

This gives users dedicated key shortcuts to scroll and jump through the contents of a pane, which they can customize like other keybindings.

- Area: Terminal UI
- Names: `pane:scrollUp`, `pane:scrollDown`, `pane:pageUp`, `pane:pageDown`, `pane:top`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### New plugin-directory search view in the /plugin menu

The /plugin menu gets a dedicated directory/search screen separate from the existing marketplace browsing view

**What**

The `/plugin` menu now has a distinct "directory search" screen, reached via `/plugin directory` or `/plugin search`, separate from the existing screen for browsing a plugin marketplace. It has its own title in the menu so it's clearly labeled as a different view.

**Why**

Separating search from browsing gives a clearer path to finding a specific plugin instead of scrolling through a marketplace listing.

- Area: Plugins
- Names: `/plugin directory`, `/plugin search`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### Official plugin/category allowlist expanded with enterprise integrations

Official plugin categories now include 19 more enterprise integrations like Salesforce, Jira, and BigQuery

**What**

The list of categories recognized as official, first-party plugins has grown by 19 entries. The additions cover enterprise data-source integrations including Asana, BigQuery, Confluence, Datadog, Google Drive, Grafana, HubSpot, Jira, Linear, Notion, PagerDuty, Redshift, Salesforce, Sentry, and Snowflake, plus three internal categories used for Claude Tag.

**Why**

This list feeds trust and gating checks throughout Claude Code, so plugins in these new categories are now recognized as official/first-party rather than treated as third-party.

- Area: Marketplace
- Names: `Asana`, `BigQuery`, `Confluence`, `Jira`, `Salesforce`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### cursor import support added at parity with codex/gemini

The /import command now supports importing configuration from Cursor, alongside Codex and Gemini

**What**

The `/import` command, which brings configuration like instruction files, MCP servers, commands, subagents, and skills from another tool into Claude Code, now supports Cursor as a source, alongside the existing Codex and Gemini support. This is reflected in the command's usage text, its validation, and its telemetry.

**Why**

Users switching from Cursor, or using it alongside Claude Code, can now bring their existing setup over with `/import cursor` instead of recreating it by hand. Importing from Cursor requires Claude Code v2.1.265 or later.

- Area: Internals
- Names: `/import`, `cursor`
- Tier: Use it now
- Useful: 3/5
- Signal: 1/5

### Command-line suggestions add a 'mid-command' completion mode

Command-line autocomplete can now suggest completions partway through a command, not just at the start

**What**

Claude Code's command-line input now supports a `mid-command` autocomplete mode. Previously, slash-command-style suggestions only appeared when starting to type from the beginning of the input; now they can also trigger partway through a command that's already been started.

**Why**

This makes autocomplete more useful when editing or extending a command already in progress, rather than only when typing from scratch.

- Area: Command Line
- Tier: You'll notice
- Useful: 3/5
- Signal: 1/5

### OTEL resource attributes now include user.groups

Telemetry can now include your group memberships as a user.groups attribute, alongside your email

**What**

Claude Code's telemetry data can now include a `user.groups` attribute, a comma-joined list of your group names, sent alongside the existing `enduser.id` and `user.email` attributes. It's only added if none of the group names themselves contain commas or `=` characters, and only if the combined, URL-encoded string is 255 characters or shorter.

**Why**

This gives telemetry consumers group-level identity information to go with individual user identity, useful for organizations that want to break down usage by team or group rather than just by person.

- Area: Telemetry
- Names: `user.groups`
- Tier: You'll notice
- Useful: 3/5
- Signal: 1/5

### "Code" added as a recognized UI block component alongside Button/Input/Select/Svg

Interactive dialogs can now render a "Code" block component alongside Button, Input, Select and Svg

**What**

The restricted list of components that interactive dialogs (in both the terminal and desktop app) are allowed to render now includes a `Code` element, treated as a block-level component the same way `Button`, `Input`, `Select`, and `Svg` already are.

**Why**

This lets interactive dialogs display formatted code blocks directly, rather than being limited to the previous set of form-style elements.

- Area: UI Components
- Names: `Code`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### .cursorrules recognized as a project instructions/memory file

Claude Code now reads .cursorrules files as project instructions

**What**

Claude Code now scans for a `.cursorrules` file (the rules file used by the Cursor editor) as one of the files it reads for project instructions and memory, alongside files like `agents.md`, `agents.override.md`, and `gemini.md`.

**Why**

Projects that already have Cursor rules set up will have those instructions picked up automatically, without needing to duplicate them into a Claude-specific file.

- Area: Internals
- Names: `.cursorrules`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### Artifact 'list' capability output gains instructions fields

Artifact list results now report instructions text length and whether it was clipped or unavailable

**What**

The result of listing artifacts can now include `instructions`, `instructions_chars`, `instructions_clipped`, and `instructions_unavailable` fields, alongside the existing `instructions_file` field.

**Why**

This gives more detail about an artifact's instructions text directly in the list result, including its length and whether it was cut short or couldn't be retrieved, rather than only pointing to a separate instructions file.

- Area: Artifacts
- Names: `instructions_chars`, `instructions_clipped`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### Button hotkeys can now be lowercase letters, not just digits

Plugin button hotkeys can now be a lowercase letter, not just a digit

**What**

The hotkey property on the plugin-facing Button component now accepts a single lowercase letter from a to z, in addition to the digits 0 through 9 it already accepted.

**Why**

This gives plugin authors more available hotkey options for buttons, since digits alone limited them to ten possible shortcuts.

- Area: Plugins
- Names: `hotkey`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### Marketplace manifest schema now recognizes marketplace_name and is_official fields

Marketplace listings can now include a marketplace name and an official-status flag

**What**

The schema for marketplace entries, used for listing skills and plugins, now recognizes two additional fields: `marketplace_name` and `is_official`. These are parsed and made available on entries as `marketplaceName` and `isOfficial`.

**Why**

This lets a marketplace listing identify itself by name and mark whether it's an official source, which could help distinguish official plugin/skill sources from third-party ones.

- Area: Marketplace
- Names: `marketplace_name`, `is_official`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### New 'Pane' keyboard-focus context for plugins

A new 'Pane' keyboard-focus context covers when a plugin's own pane is focused

**What**

Claude Code's keybinding system has a new focus context called `Pane`, active when a plugin's pane has keyboard focus. This joins existing contexts like `Chat` and `AbovePrompt`, which determine which keyboard shortcuts apply depending on where focus currently is.

**Why**

This lets keybindings be scoped specifically to plugin panes, so shortcuts can behave differently when a plugin's own interface is focused versus the main chat.

- Area: Terminal UI
- Names: `Pane`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### New marketplace/skill tag categories for connector integrations

Marketplace/skill tags now include many SaaS connector names like Asana, Jira, Salesforce, and Snowflake

**What**

The recognized set of category tags for plugins and skills in the marketplace has grown to include a range of SaaS connector names:

- `asana`

- `bigquery`

- `confluence`

- `datadog`

- `google-drive`

- `grafana`

- `hubspot`

- `jira`

- `linear`

- `notion`

- `pagerduty`

- `redshift`

- `salesforce`

- `sentry`

- `snowflake`

Also added are internal tags `claude-tag-data-viz`, `claude-tag-oncall`, and `claude-tag-troubleshoot`.

**Why**

These tags let plugins and skills that integrate with these specific services be labeled and found more precisely in the marketplace.

- Area: Marketplace
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### No-op 'enable' tools for already-connected device tool families

New no-op "enable" tools tell Claude the browser/device tools are already connected and ready

**What**

Claude Code now registers tools named `enable__mcp__claude-in-chrome`, `enable__mcp__remote-devices__Claude_Browser`, and `enable__mcp__remote-devices__computer`. These tools do nothing; their entire purpose is to tell Claude that the corresponding browser or remote-device tools are already available and connected, so there's no separate step needed to turn them on. They only appear when a remote or connected-device session is set up.

**Why**

This prevents Claude from trying to call a nonexistent "enable" step before using browser or remote-device tools, instead directing it straight to the real tools when a device is already connected.

- Area: Elsewhere
- Names: `enable__mcp__claude-in-chrome`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### Plugin marketplace gains a "directory" tab/view

The plugin marketplace UI adds a 'directory' view alongside discover and installed views

**Unclear.** What the new 'directory' view looks like or how a user navigates to it is not described.

**What**

The plugin marketplace interface now recognizes a `directory-search` view, mapped to the string `"directory"`, sitting alongside existing views like `discover-plugins` and `installed`.

**Why**

This suggests a new way to browse or search plugins by directory within the marketplace, though the finding doesn't describe what the view looks like or how it's reached.

- Area: Marketplace
- Names: `directory`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### policyHelpers entries gain a retries setting for helper execution failures

Per-OS `policyHelpers` entries can now set `retries` to control retry attempts after a failed run

**What**

A new `retries` setting on per-OS `policyHelpers.<os>` entries controls how many additional times a failing policy helper (a script that computes managed settings at startup) is retried before it's counted as a failure. A run counts as failed if the helper couldn't launch, exited with a non-zero code, or timed out. Retries use randomized backoff starting at 250ms and doubling up to 4 seconds between attempts.

**Why**

This gives administrators a way to tolerate transient failures, like a flaky network call inside the helper script, without immediately treating the whole policy helper as failed.

- Area: Managed Settings
- Names: `retries`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### ui.invalidate now supports invalidating command.describe

The ui.invalidate plugin operation can now also invalidate command.describe

**What**

The `ui.invalidate` host operation, which plugins use to signal that something needs to be recomputed, now accepts `"command.describe"` as a valid target, in addition to the existing `ui.render`, `prompt.section`, `prompt.context`, and `tool.describe`.

**Why**

This lets a plugin force Claude Code to refresh how a command describes itself, rather than only being able to invalidate rendering, prompt content, or tool descriptions.

- Area: Plugins
- Names: `ui.invalidate`, `command.describe`
- Tier: Use it now
- Useful: 2/5
- Signal: 1/5

### Artifact publish sources can live in the session scratchpad, not just the working directory

Artifact publish can now pull local files from the session scratchpad directory, not just the working directory

**What**

The publish tool's `files` and `root` parameters now state that local source files can come from either the working directory or the session's scratchpad directory (a private working-storage folder your system prompt names). Previously, only the working directory was allowed as a source location.

**Why**

This lets you publish artifacts built from files kept in the scratchpad area, not just files sitting in the main project directory, giving more flexibility in where source material for a publish can live.

- Area: Artifacts
- Names: `scratchpad`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### OTEL telemetry now attaches user.groups when present and safe to encode

Telemetry data now includes a user.groups field listing the session's groups, when it's safe to encode

**What**

Claude Code's OTEL telemetry (OpenTelemetry, the system used to export usage and performance data) now attaches a `user.groups` attribute listing the groups associated with the current session, joined together with commas. This is only added when none of the group names themselves contain a comma or equals sign, and when the combined text stays under 255 characters; otherwise the attribute is left off entirely.

**Why**

This lets organizations see group membership in their telemetry data without risking malformed or oversized attribute values.

- Area: Telemetry
- Names: `user.groups`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### --plugin-dir help text now documents loading a folder of plugins

--plugin-dir help text now documents that a folder of plugins can be passed

**What**

The command-line help text for the `--plugin-dir` flag now explains that it can also load a directory containing multiple plugins, with each one loaded as a separate child plugin.

**Why**

This makes it clear that `--plugin-dir A --plugin-dir B.zip` can be used to load a folder of plugins at once, not just a single plugin directory or archive, requiring Claude Code v2.1.265 or later.

- Area: Plugins
- Names: `--plugin-dir`
- Tier: Use it now
- Useful: 1/5
- Signal: 0/5

## New Features

### New contextual tip advertises Claude Code Desktop's iOS Simulator pane

New tip promotes Claude Code Desktop's per-session iOS Simulator pane for iOS app work

**What**

A new contextual tip, shown on macOS when the current conversation is recognized as iOS app development, tells users that Claude Code Desktop gives each session its own iOS Simulator pane, where Claude tests the app, fixes what it finds, and checks again.

**Why**

This surfaces a relevant Claude Code Desktop feature to users doing iOS development from the CLI, pointing them toward a workflow where Claude can visually verify iOS app changes itself.

- Flag `tengu_magical_pixel`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Area: Claude Code Desktop
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

## Improvements

### Dev-intent absorption wired into headless/SDK sessions

Headless and SDK sessions now run dev-intent detection over the conversation, previously only in interactive sessions

**What**

Headless and SDK-driven sessions (ones run programmatically rather than through the interactive terminal) now feed every message in the conversation, including the initial messages and each new assistant, user, or attachment message, into a detector that looks for signals of developer intent. Currently this includes a detector for building an iOS app (`ios_app`). When it finds a match, Claude Code emits an internal `dev_intent` system message and records a `dev_intent_detect` telemetry event. Previously, headless and SDK sessions did not run this detection at all.

**Why**

This extends a detection feature that already existed elsewhere to headless and SDK sessions, so those session types can also pick up on signals like someone building a specific kind of app.

- Area: SDK
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Artifact reads gain awareness of cross-organization sharing and a type-contract paging parameter

Artifact reads now flag cross-organization sharing and add a paging parameter for type info

**What**

The Artifact tool's file/page read action now tracks whether an artifact is `external`, meaning it was shared from another organization, and shows distinct messaging for that case: "shared with you from another organization", describing it as authored by someone outside the user's organization. This is separate from the existing public/owner/writer distinctions.

A new `typePage` parameter (default `"none"`) controls whether the Artifact's type contract text (a description of its expected structure) is fetched and included when reading it, so that text doesn't have to be refetched on every read.

**Why**

This lets Claude, and the messaging shown around an artifact read, distinguish artifacts shared across organizations from the user's own, and avoids repeatedly refetching type contract text that hasn't changed.

- Flag `tengu_cobalt_plinth_larch`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: off, compiled default: off)
- Area: Artifacts
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Reading a first-party artifact's own files can skip approval

Reading your own first-party artifact's files can now skip the approval prompt entirely

**What**

When Claude Code reads files or assets belonging to the user's own artifact (a generated document, app, or similar output), it can now skip asking for approval altogether if that artifact was made from a published first-party Artifact type. There's also a shortcut for resources that were already read and approved earlier under the same display name, avoiding a repeat prompt.

**Why**

This reduces unnecessary approval prompts for content the user already owns and that comes from a trusted, first-party artifact type, while still requiring approval in other cases.

- Area: Artifacts
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### MCP connector manifest validation now catches unknown/misspelled tool names and offers fuzzy-match rename suggestions

MCP connector manifests now get checked for unknown or misspelled tool names, with rename suggestions

**What**

MCP (Model Context Protocol) connector manifests declare which tools they provide. Claude Code now cross-checks each declared tool name against the connector's actual tool names. If a declared name is just a near-miss (different case, or underscores instead of spaces, for example), it's auto-corrected. If it doesn't match anything close, Claude Code now flags it as an unknown tool, showing the connector name, the unmatched tool names, and the tools that do actually exist.

**Why**

This catches typos or stale entries in a connector's manifest early, so a misconfigured tool name shows up as a clear warning instead of silently failing or being ignored.

- Area: MCP
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### New plugin-directory hot-reload watcher with debounce and circuit breaker

Claude Code now watches plugin folders and reports live when plugins load, unload, or need a reload/restart

**What**

Claude Code now watches the folders where plugins live and reacts automatically when something changes there. When a plugin's files change, Claude Code reloads it and tells you what happened:

- the plugin loaded or unloaded

- the plugin didn't load, with a pointer to run `/plugin` for details

- the change is held pending until you run `/reload-plugins`

- the change requires a full restart to take effect

**Why**

This means editing or updating a plugin can take effect without manually reloading or restarting Claude Code in many cases, while still telling you clearly when a manual step like `/reload-plugins` or a restart is actually required.

- Area: Plugins
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### /model 1M-context aliases get explicit availability checks

Switching to a 1M-context model with /model now gives a specific error explaining exactly why it isn't available

**What**

When you use `/model` to switch to a model variant with a 1M-token context window (a larger amount of conversation history the model can see at once), Claude Code now checks upfront whether that switch can actually work, and tells you exactly which of three problems applies:

- 1M context has been turned off in this environment via the `CLAUDE_CODE_DISABLE_1M_CONTEXT` setting

- the target model doesn't support a 1M-token window at all

- the alias you picked has no 1M variant available for the current mode

Each case shows a distinct message, and in the disabled case it tells you which command to run instead.

**Why**

Previously an unavailable 1M switch would presumably just fail or silently do something else; now you get a clear reason and, where relevant, a suggested fix, so you don't have to guess why the switch didn't take.

- Area: Models
- Names: `/model`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### New artifact document versioning guidance text

New guidance text explains how to safely update artifact documents using version numbers

**What**

Claude Code has new built-in guidance explaining how to edit "artifact" documents safely when multiple edits might happen. Every time a document is read or written, the response includes a version number. To update the document with `update` or `str_replace`, that version must be passed back as `if_version`. If the document has changed since that version was read, the write is refused and nothing is applied.

**Why**

This prevents one edit from silently overwriting changes made in between, since a write only succeeds if it's based on the document's current version.

- Area: Artifacts
- Names: `if_version`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Edit/Write tools can now detect that a file changed on a *different host* since it was read remotely

Edit and Write now detect if a file changed on a different remote host since it was last read, with a clearer error message

**Unclear.** Whether the tengu_edit_tool_stale_read, tengu_edit_tool_not_read_hypothetical, and tengu_write_tool_not_read_hypothetical gates are enabled for any user is unknown; nothing has been read about them.

**What**

When a file was read through a remote call (a read served by another machine rather than locally), the Edit and Write tools now record a `readBaseline` at read time, a size and hash of the file's contents. Before writing, they re-read a bounded portion of the file and compare it against that baseline. If the file no longer matches, instead of the generic staleness warning, Claude Code now shows a specific message naming the host: "File has been modified on {host} since this session read it. Read it again there..."

This builds on the earlier change to the read-before-write rule for remote calls: on top of deciding whether a call counts as already read, Claude Code can now also tell whether the remote file has since changed on that other host.

**Why**

This makes it clear when a file was edited on a different machine after Claude Code read it remotely, telling you exactly where to re-read it from rather than leaving you with a generic and less actionable staleness error.

- Area: Multi-Host Sessions
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Directory-sync git worker gains mid-turn shipping and a streaming change-feed hookup

Directory sync can now ship changes mid-turn and streams changes through a live change feed

**Unclear.** The exact trigger conditions for mid-turn shipping and what consumes the streaming change feed are not stated.

**What**

Directory sync, the feature that keeps a cloud or remote session's copy of your files in step with your machine, has been restructured. Previously it only snapshotted and shipped changes at the end of a turn; now that shipping is organized around named points, including turn end and before running a command, with a new mid-turn shipping capability. The sync engine's interface also now exposes a streaming connection wired to a live change feed.

**Why**

This suggests directory sync can push and pick up file changes more promptly during a session rather than only at turn boundaries, though the finding doesn't specify exactly when mid-turn shipping triggers.

- Area: Cloud Sync
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Watch tool refuses to (re)start a watch after an unapproved comment-reply ask in the same session

Claude Code won't retry starting an artifact watch after you already declined a related reply request in the same session

**What**

The `watch` action on artifacts (which lets Claude monitor an artifact, for example to reply to comments on it) now checks whether an earlier request in the same session to let Claude reply to that artifact's comments was declined. If it was declined and hasn't since been separately approved, Claude Code now refuses to start or restart the watch outright, telling the model that only your own next message can trigger asking again - it won't automatically re-ask on its own.

**Why**

This stops Claude from repeatedly re-requesting a permission you already turned down within a session, closing a path where a declined request could otherwise resurface through a different tool.

- Area: Artifacts
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### directory_sync init/delta schema gains a 'muted' flag for the emergency kill switch

Directory sync's status messages now include a 'muted' flag for when Anthropic's remote kill switch has disabled it

**What**

Directory sync (`cloud_session.directory_sync`), which uploads and installs files to keep a cloud session's directory in step, now reports a `muted` boolean in its status messages. It is `true` whenever Anthropic's remote emergency switch has disabled directory sync on that machine, meaning nothing is being uploaded or installed.

**Why**

This gives a clear, visible signal in the sync status output for when directory sync has been centrally disabled, rather than leaving it unclear why uploads and installs have stopped.

- Area: Cloud Sync
- Names: `muted`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### New approval-record checks for pinned/edit database writes

Certain database writes now require a matching prior approval, tracked per session, before they're allowed

**What**

Some database writes that first read back the stored document — such as string-replace style edits, or writes pinned to a specific version using `if_version` — now must match a prior approval recorded earlier in the same session. This is tracked in a new map called `dbWriteOpSights`. If no matching approval record exists, or the recorded operation or version doesn't match what's being written, the write is refused with a new error.

**Why**

This closes a gap where a write could otherwise happen without the approval that was supposed to govern it, ensuring a write only proceeds when it matches what was actually approved.

- Area: Artifacts
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### New pre-write consent check when creating artifact-type instances

Creating a private artifact type now runs an extra permission check before asking you to approve it

**What**

Before Claude Code asks you to approve creating a new private artifact from a type, it now runs an additional check first. This check consults a permission-ruling helper tagged `type_create`, and if that ruling says the action should be confirmed with you (and it hasn't already been remembered as approved for that type and slug), Claude Code returns a 'read' action instead of going straight to the create-artifact approval prompt.

**Why**

This adds an extra layer of permission checking before creating a new artifact type, potentially changing what prompt or action you see compared to going straight to a create-artifact approval request.

- Area: Artifacts
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### MCP OAuth: registration deferred when discovery already offered it

MCP OAuth login now delays client registration when the server's discovery info already offers it

**What**

When Claude Code connects to an MCP (Model Context Protocol) server that uses OAuth login, it now checks the server's discovery metadata for a `registration_endpoint` or support for `client_id_metadata_document_supported`. If either is present, a new `registrationOfferedByDiscovery` flag is set, and if there's no access or refresh token yet, Claude Code defers registering itself as a client until the actual authentication step instead of trying to register right away.

**Why**

Previously, missing client info could fail immediately; now, if the server's discovery data already offers a way to register, Claude Code waits and lets registration happen at authentication time instead of failing early.

- Area: MCP
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### OTEL exporter distinguishes rejected payloads from destination failures

OTEL exporter now separates rejected payloads from real connection failures, and stops counting rejections against the circuit breaker

**What**

When Claude Code sends telemetry (OTEL) data to an external destination and gets back an HTTP 400, 413, 415, 422, or 431 response, it's now treated as the destination rejecting the payload itself, rather than a connection or service failure. This is logged, but only roughly once every 100 occurrences, and it no longer counts toward the circuit breaker (the mechanism that temporarily stops sending to a failing destination). Other kinds of failures still count and can still trip the breaker, taking the destination offline for 30 seconds.

**Why**

This stops a destination that's rejecting malformed or unexpected payloads from being mistakenly treated as unreachable and temporarily cut off, while still protecting against destinations that are genuinely failing.

- Area: Telemetry
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Subagent prompt now documents automatic CLAUDE.md injection

Claude Code now tells the orchestrating model that subagents already receive CLAUDE.md automatically

**What**

When the main Claude Code assistant spins up a subagent (a separate Claude instance handling a sub-task, launched via the Task/agent tool), the instructions given to the orchestrating model now explain that the subagent already receives the same `CLAUDE.md` project instruction files that were loaded at the start of the session. This applies to all subagents except the built-in `Explore` and `Plan` agent types, which don't get these files injected.

**Why**

Previously the orchestrating model might have re-read `CLAUDE.md` itself or pasted its rules into the subagent's prompt, wasting effort on something the subagent already had. Documenting this should make orchestration a bit more efficient and avoid redundant instructions being stuffed into subagent prompts.

- Area: Subagents
- Names: `CLAUDE.md`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### No-op "enable computer use" tool added, tells Claude to just call the tools directly

New no-op tool tells Claude to call remote-devices computer tools directly instead of enabling them first

**What**

A new pseudo-tool called `enable__mcp__remote-devices__computer` has been added. Its description says it does nothing, and its result text instructs Claude to use the `mcp__remote-devices__computer_*` tools directly rather than trying to enable them first. It also includes guidance on what to tell the user if the remote computer's Claude app isn't responding.

**Why**

This steers Claude away from a false step of trying to 'enable' remote-device computer control, pointing it straight at the tools that actually do the work, and gives it a fallback message to relay if the remote device isn't responding.

- Area: Elsewhere
- Names: `mcp__remote-devices__computer`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### /design command splits preview-and-hub features from local-agent sessions

/design now disables preview/hub features (import, export, status, canvas skill) in local-agent sessions

**What**

The `/design` command now depends on a `previewAndHub` setting to decide which subcommands are reachable. Local-agent entrypoints explicitly run it with `previewAndHub` turned off, while the normal interactive path keeps it turned on. With it off, the `import`, `export`, and `status` subcommands, free-form design prompts, and the design canvas skill become unreachable, while consent and revoke (and `types`, if enabled) remain available.

**Why**

This limits the fuller Claude Design experience — the canvas, hub, and related import/export/status features — to normal interactive sessions, keeping local-agent sessions restricted to the more basic consent-related functionality.

- Area: Design Command
- Names: `/design`, `previewAndHub`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### OTLP exporter can now route through a Cloud-gateway-issued collector URL

Telemetry export can now route through a collector URL issued by a Cloud gateway session, and stops if that session ends

**What**

Claude Code's OTLP telemetry exporter (the component that sends usage and performance data out via the OpenTelemetry protocol) can now resolve its destination address through a Cloud gateway session. When it does, it refreshes the connection headers on every call, and if the gateway session that originally provided the collector's address has since ended, it deliberately fails and drops that batch of telemetry rather than sending it somewhere stale.

**Why**

This keeps telemetry from being sent to a collector address that's no longer valid once the underlying Cloud session is gone, at the cost of losing whatever data was in flight at that moment.

- Area: Telemetry
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Sandbox/path-escape check now rejects backslash paths and verifies file identity by inode

Sandbox path checks now reject backslash paths outright and verify file identity by inode after resolving symlinks

**What**

The check that decides whether a file path stays within an allowed sandbox boundary now rejects any path containing a backslash, since such paths can't be resolved reliably on the current platform. Separately, after successfully resolving a path with `realpath`, it now also compares the device and inode numbers (via a new `statBigint` helper) of the original path and the resolved target before concluding the path is genuinely "inside" the boundary.

**Why**

The inode comparison guards against a file being swapped out between the moment its path is resolved and the moment it's actually accessed, closing a gap an attacker could otherwise use to trick the sandbox boundary check.

- Area: Sandbox
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Artifact publish: new "mcp" store-write capability kind and "durable_declined" live-subscription state

Artifacts add an "mcp" write capability and a new "declined" state for live comment replies

**What**

When Claude publishes an artifact (a generated document, app, or file shown alongside the conversation) that writes to a store, it now recognizes a new "mcp" store-write kind alongside the existing "data" and "write_db" kinds, with its own instruction text for the model.

Separately, for artifacts that can respond live to comments, there's now a "durable_declined" result: this covers the case where a request to let Claude reply to comments was asked for but not approved, distinct from the existing "durable_refused" case where the server itself rejected it.

**Why**

The added "mcp" kind lets artifacts write through MCP (Model Context Protocol, a way for Claude to connect to external tools and services) connections, and the new "durable_declined" state gives a clearer, more specific message when a live-reply request simply wasn't approved rather than being rejected by the server.

- Area: Artifacts
- Names: `durable_declined`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Plugin directory detection now recurses to find nested plugin marker files

Plugin detection now looks inside subfolders instead of only checking the top-level directory

**What**

When Claude Code scans a directory to see if it contains a plugin, it now recurses into subdirectories (skipping ones starting with a dot) instead of only checking the top level. If a directory itself looks like a plugin, it's reported as one; otherwise, it's reported as a `collection`, with separate lists of valid child entries and entries that were skipped.

**Why**

This lets Claude Code find plugins that are nested inside folders rather than requiring plugin marker files to sit directly at the top level, and lets it report which nested items were recognized versus skipped.

- Area: Plugins
- Tier: You'll notice
- Useful: 3/5
- Signal: 1/5

### Workflow agent-card detail view becomes expandable, with tool-call and sub-task activity panes

Workflow monitor's agent detail card can now expand to show tool calls and nested sub-tasks

**What**

The agent detail card in the workflow monitor (the terminal view that tracks agents running inside a `Workflow`) can now expand and collapse. Expanding it reveals:

- An "Activity" section listing the agent's tool calls, with a note like "last N of M tool calls" when the list is truncated

- An " expand" hint showing more detail is available

- Nested groups of sub-tasks, shown with proper indentation

The keybinding for expanding and collapsing the card now uses a dedicated `detailExpandable` setting instead of just scrolling, and the first time a card is expanded, Claude Code logs a `workflow_agent_card_detail` telemetry event.

**Why**

This gives more visibility into what an individual agent within a workflow is actually doing, tool call by tool call and sub-task by sub-task, directly from the monitor view instead of requiring a separate lookup.

- Area: Workflows
- Tier: You'll notice
- Useful: 3/5
- Signal: 1/5

### File-modified-since-read errors now name the host when multi-host sessions are involved

The 'file changed since you read it' error now names which host to re-read the file on, in multi-host sessions

**What**

When Claude Code detects that a file was modified after it was last read, and the session spans multiple hosts (machines), the error message now tells the model exactly which host to re-read the file on, using an explicit `_host` parameter in the `Read` tool call. Previously the message was generic and didn't specify a host.

**Why**

In multi-host sessions, a file with the same path can exist independently on different machines. Naming the host removes ambiguity about where the file actually changed, so the model re-reads the correct copy before retrying the write.

- Area: Multi-Host Sessions
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Managed settings sources: helper config from lower-priority sources is now ignored with a warning when merged

When merging managed settings from multiple sources, policy-helper configuration from lower-priority sources is now ignored with a warning

**What**

When `managedSourcesBehavior` is set to `"merge"` (composing every managed settings source, such as MDM or a managed settings file, instead of only using the highest-priority one), policy-helper configuration keys found in a non-highest-priority source are now explicitly ignored, and Claude Code surfaces a warning about it. Previously this configuration would silently merge in.

**Why**

Policy helper configuration is now read only from the highest-priority managed settings source. The warning makes this explicit instead of letting an admin believe a lower-priority source's helper settings were taking effect when they weren't.

- Area: Managed Settings
- Names: `managedSourcesBehavior`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### SessionStart hook execution now honors an abort signal

SessionStart hooks can now be aborted mid-run instead of always running to completion

**What**

The `SessionStart` hook pipeline, which runs when a session begins or resumes, now accepts an abort signal. If that signal fires before the hooks finish, Claude Code returns whatever hook messages were already collected instead of continuing on to steps like reloading skills or checking watched paths.

**Why**

This allows session startup to be cut short cleanly if needed, without waiting for every `SessionStart` hook step to finish first.

- Area: Hooks
- Names: `SessionStart`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Non-standard image formats are normalized to PNG before resize/compress

Uncommon image formats like TIFF, AVIF, and BMP are now converted to PNG before resizing or compressing

**What**

When Claude Code resizes or compresses an image, it now checks the decoded format against an allowed list (`png`, `jpeg`, `gif`, `webp`). Anything outside that list, such as TIFF, AVIF, or BMP, is now converted to PNG before any size or dimension calculations happen. Previously, only `jpg` was specially handled by treating it as `jpeg`.

**Why**

This lets Claude Code handle a wider range of image formats reliably during resize and compression, instead of only correctly handling a small fixed set.

- Area: Images
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### file_read tool result can now inline the file's full content

Reading a file with the Artifact tool can now include the full file content in the result

**What**

When the Artifact tool's file_read (read-file) action returns a result, if that result includes the file's `content` as text, the full content is now appended below the summary line. If it's a "reading copy" of the file, a note explains that reserved tag names have been neutralized in it.

**Why**

This means Claude no longer necessarily needs to make a separate Read call to see the file's contents after a file_read, since they can be delivered inline, unless it actually intends to edit the saved copy.

- Area: Artifacts
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### In-terminal plugin form widgets (text input, dropdown) gain mouse click focus support

Plugin text inputs and dropdowns in the terminal UI can now be focused with a mouse click

**What**

Claude Code's in-terminal UI for plugins (add-ons that extend Claude Code) includes form widgets like text inputs and dropdowns. These were rewritten around a shared helper that tracks keyboard focus state, and both widget types now respond to mouse clicks on their container, gaining focus when clicked. A new click handler filters out clicks caused by window activation or drag-and-drop, so only genuine clicks trigger focus.

**Why**

Previously these widgets could likely only be focused via keyboard navigation; now clicking them with a mouse in a terminal that supports mouse input works too.

- Area: Plugins
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Comment threads can show 'presence' info when list-size budget allows

Artifact comment threads can now show who's currently viewing or typing, space permitting

**What**

When listing comments on an artifact, Claude Code can now compute and display extra "presence" information for each comment, such as who is currently viewing or typing. This is only added when it fits within the response's overall size limit, and is tracked with new `presenceText` and `presenceShown` fields.

**Why**

This gives more collaborative context on comment threads when there's room to show it, without pushing a response over its size limit when there isn't.

- Area: Artifacts
- Names: `presenceText`, `presenceShown`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Artifact durable-subscribe now short-circuits when the relay isn't served, and distinguishes relay-unavailable from subscribe-forbidden

Artifact live-subscribe now tells apart a relay that's down from a subscribe that's forbidden

**What**

When Claude Code tries to set up a durable (persistent, live-updating) subscription to an artifact, it now checks upfront whether the relay service needed to deliver updates is even available, and if not, skips with a `relay_not_served` result. It also now separates three distinct outcomes that previously could get conflated:

- `relay_unavailable` - the relay service is currently down (records the HTTP status it got back)

- `subscribe_forbidden` (`durable_refused`) - the subscription is outright not allowed

- `durable_declined` - an automatic session chose not to subscribe

**Why**

Separating these cases means Claude Code (and anyone debugging subscription problems) can tell whether a failed live artifact update is a temporary infrastructure hiccup or a permissions issue, rather than seeing one generic failure.

- Area: Artifacts
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Plugin browse/install listing now resolves catalog entries through an async enrichment step

Plugin browse/install lists now resolve each entry through an extra lookup step before showing it

**What**

When Claude Code builds the list of plugins to show for browsing or installing, it now runs each plugin through a new resolution step (per marketplace, in parallel) before filtering and sorting the list. This step checks whether a plugin's install location should be rewritten to point at a local development copy instead of the normal one, and updates the displayed entry accordingly. The same resolution happens on the single-plugin refresh path after a marketplace refresh.

**Why**

This ensures that if a plugin has a local development override in place, the plugin list and install flow reflect that override correctly instead of showing stale or mismatched install locations.

- Area: Plugins
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Turn dispatch now waits for pending hooks before starting

Starting a new turn now waits for any pending hooks to finish first

**What**

When Claude Code starts a brand-new turn (not resuming an existing one already in progress), it now waits for any pending or deferred hooks to complete via `awaitPendingHooks` before proceeding. If the wait is interrupted by something other than the user actually cancelling (the abort signal), it's silently absorbed rather than surfaced as an error.

**Why**

This prevents a new turn from starting while hook-related work is still outstanding, avoiding a race where hook results might arrive after the turn has already begun.

- Area: Hooks
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New diagnostics for unreadable plugin component folders

Plugin loading now logs an error when a component folder can't be read, instead of silently treating it as missing

**What**

When Claude Code loads a plugin, it checks for default folders like commands, agents, skills, output-styles, themes, and workflows. Previously, if checking one of these folders failed for any reason, it was silently treated the same as the folder simply not existing. Now, if the failure is something other than 'not found' (for example a permissions problem), Claude Code logs an error and records a distinct diagnostic entry for it.

**Why**

This makes it easier to notice and diagnose real problems with a plugin's folder structure, rather than having them silently masked as an ordinary missing folder.

- Area: Plugins
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Resume-session dialog can show 'instant' summary resume when a summary is precomputed

Resume dialog now says 'instant' when a session summary is already precomputed

**What**

The dialog Claude Code shows when resuming a previous session now checks whether a summary of that session has already been precomputed. When it has, the recommended option's label changes from 'Resume from summary (recommended)' to 'Resume from summary (instant, recommended)'.

**Why**

This tells you upfront that resuming from the summary will be fast in this case, because the work of summarizing has already been done ahead of time.

- Area: Sessions
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Batch artifact-db writes report unconfirmed access level

Batch artifact-database writes now warn when the access level they ran at wasn't confirmed by the server

**What**

When the artifact database falls back to writing a batch of changes one at a time (rather than all at once), it now keeps track of whether the access level you asked for (`as_level`) was actually confirmed by the server for each write. If a level was requested but never confirmed, any error message for that write now adds a warning that the operation may have run at your own access level instead of the one you asked for.

**Why**

This makes it clearer when a batch write silently used different permissions than intended, instead of leaving you to assume the requested level was honored.

- Area: Artifacts
- Names: `as_level`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Untrusted-content wrapping added to web-fetch-style summarization prompts

Fetched web page content is now wrapped as untrusted data before being summarized, with a warning to ignore embedded instructions

**What**

When Claude Code builds a prompt to summarize content fetched from a web page, it now wraps that content in an explicit "untrusted content" fence, with text before and after warning the model to treat it as data, not as instructions. Any text embedded in the page that tries to direct an AI assistant (for example, telling it to ignore its instructions, leak data, or hide something) is now flagged as a finding to report rather than something to act on.

**Why**

This guards against prompt injection: a malicious or compromised web page could otherwise embed hidden instructions that a summarization step might follow. Wrapping fetched content as untrusted data keeps those instructions from being treated as commands.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### WebFetch's claude.ai artifact exception widened to cover shorter artifact URLs

WebFetch's exception for claude.ai artifact links now also matches the shorter claude.ai/artifact/{id} URL form

**What**

The `WebFetch` tool has a special carve-out allowing it to fetch claude.ai artifact links using your logged-in claude.ai session. That carve-out now also matches the shorter URL form `claude.ai/artifact/{id}`, in addition to the longer `claude.ai/code/artifact/{uuid}` form it already covered.

**Why**

This means fetching a claude.ai artifact link via its shorter URL now benefits from the same authenticated access as the longer form, rather than being treated as an ordinary, unauthenticated fetch.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### policyHelpers per-source shadowing warning gated behind `managedSourcesBehavior: "merge"`

Claude Code now warns when multiple managed settings sources define conflicting policy helper config under merge mode

**What**

Managed settings (configuration an organization's admin pushes down to Claude Code) can come from more than one source, combined according to a `managedSourcesBehavior` setting. When that setting is `"merge"` and more than one source defines a `policyHelper` (an executable that computes managed settings at startup), Claude Code now warns that only the highest-priority source's helper configuration is actually honored, and it records a telemetry event when this happens.

**Why**

Without this warning, an admin might assume that policy helper settings from multiple merged sources all take effect, when in fact only one source's helper config is used. The warning surfaces that mismatch instead of silently ignoring the lower-priority sources.

- Area: Managed Settings
- Names: `managedSourcesBehavior`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### policyHelpers per-entry onFailure and retries settings now validated for effect

Claude Code now flags policy helpers that require success but have no fallback settings

**What**

A `policyHelper` (an executable an admin uses to compute managed settings at startup) can be set to `onFailure="require"`, meaning Claude Code must have that helper's output to proceed. Claude Code now checks for the case where such a helper has no usable `defaultSettings` to fall back on, which would otherwise mean a failing helper silently produces nothing. If this is caught in a normal configuration it's shown as a warning; if it comes from an OS-level managed policy source (like MDM, a mobile device management system, or the managed settings file), Claude Code refuses to start until it's fixed.

**Why**

This prevents a misconfigured policy helper from silently leaving Claude Code without any working settings. Admin-managed configurations are held to a stricter standard: a broken required helper with no fallback blocks startup entirely rather than failing quietly.

- Area: Managed Settings
- Names: `onFailure`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New refusal reasons for wake subscription registration on cloud/relay sessions

Two new error reasons explain why a cloud session couldn't register a wake subscription

**What**

When a cloud-hosted Claude Code session can't register a wake subscription (a mechanism used to notify a session when it should wake up and act), it now gets one of two specific explanations instead of a generic failure:

- `relay_not_served`: the cloud session cannot register wake subscriptions at all

- `relay_unavailable`: the session's gateway refused to carry the wake subscription, most often because the organization doesn't have this feature enabled

These apply specifically to cloud sessions that reach the artifact service only through a session gateway.

**Why**

This gives clearer, more actionable messages when a cloud session's wake subscription fails to register, distinguishing an inherent limitation of the session type from an organization-level feature restriction.

- Area: Cloud Sessions
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Large project memory files are now offloaded to a local_file pointer instead of inlined

Large project memory files are now offloaded to a downloadable file instead of being pasted in full

**What**

When reading project memory files, content that stays under a certain size is still returned inline as before. Content that exceeds that size threshold is now written to a local file, and a pointer to that file (a `local_file` reference) is returned instead of embedding the full text directly.

**Why**

This keeps large remembered files from bloating the conversation context, since only a reference is included by default rather than the entire file's contents, following the same offload-to-file approach already used for other project uploads.

- Area: Project Memory
- Names: `local_file`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Recovered background tasks now explicitly state they were marked failed/stopped

Recovered background task messages now confirm they were marked failed or stopped

**What**

When Claude Code restarts after a crash and recovers background tasks that were running before, the messages shown for them now add an explicit line stating the new status: 'They have been marked failed.' for tasks that didn't finish, and 'They have been marked stopped.' for tasks that may have been stopped mid-run.

**Why**

This removes ambiguity about what happened to a task that was interrupted by a crash, so it's clear the task's status has already been resolved rather than left hanging.

- Area: Background Agents
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Background agent completion notification split into headline + detail

Background agent recovery notifications now show a short headline plus a longer detail message

**What**

Notifications about background agents (tasks that keep running separately from the main conversation) recovered across sessions are now built from two parts, a short headline and a longer detail, instead of one combined sentence. This applies to three cases:

- A background agent that finished before the previous session ended but whose result was never reported.

- A background agent from a previous session that couldn't be automatically restarted.

- A background agent that was automatically restarted from its saved transcript after a crash.

**Why**

Splitting the message into a headline and detail makes it easier to scan what happened to a background agent at a glance, while still keeping the fuller explanation available for anyone who wants it.

- Area: Background Agents
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Artifact 'shared database' description now names the actual MCP servers built for the session

Artifact database help text now names the actual MCP servers built for the session instead of a generic description

**What**

The "Separate tools" explanation shown for artifact database access now checks whether the `data` and `endpoints` MCP servers were actually built for the current session, and if so, names them individually instead of describing one generic artifact database tool. This includes a new description for server-run endpoints covering `get_endpoints`, `call_endpoint`, and `run_script`.

**Why**

This makes the help text more accurate for a given session, telling the reader specifically which tools are available rather than a one-size-fits-all description that might not match what's actually set up.

- Area: Artifacts
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Artifact result text can be returned inline instead of requiring a Read, when multi-file mode is on

Small text files saved by Artifact tools can now return their contents inline, skipping a separate Read

**What**

When an Artifact tool saves output to a local file, its description now notes that for a small published text file, the file's contents come back directly in the tool's result data. This happens when `multiFileOn` is set, meaning a separate `Read` call to fetch the contents is no longer necessary. The same applies when reading a file's published path inside an artifact: the result now includes the small text file's contents directly rather than only its saved location.

**Why**

This saves an extra step: instead of saving a file and then reading it back, small text output is available immediately in the same result.

- Area: Artifacts
- Names: `multiFileOn`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Plugin manifests can now be filled in from marketplace-entry metadata

Plugin manifests can now be auto-filled from marketplace listing metadata

**What**

When Claude Code merges a plugin's manifest with its entry in a marketplace listing, any of the following fields that are missing from the manifest are now filled in from the marketplace entry, if available: `displayName`, `description`, `author`, `homepage`, `repository`, `license`, and `keywords`.

**Why**

This means plugin authors don't need to duplicate metadata in both the manifest and the marketplace listing; missing details in the manifest can be backfilled automatically.

- Area: Marketplace
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### MCP server delete confirmation can note a version-scoped condition

MCP server delete confirmation can now note it applies only to a specific version

**What**

When confirming deletion of an MCP server (a connected external tool server), the confirmation screen can now show an extra note like "(only if still at version X)" when a specific version applies, in addition to the existing warning and detail text.

**Why**

This helps avoid accidentally deleting the wrong version of a server configuration by making the version condition visible at the point of confirmation.

- Area: MCP
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Artifact command display now shows the artifact's title where available

Artifact command output now shows the artifact's title instead of just its raw URL

**What**

A new helper resolves and formats an artifact's title for display, and is now used across several artifact-tool actions — listing, reading, pinning, unpinning, and deleting assets. Command summaries for these actions now show a quoted title, like `of "My Design"`, instead of just the raw artifact URL.

**Why**

This makes it much easier to tell which artifact a command acted on at a glance, rather than having to recognize it by URL alone.

- Area: Artifacts
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Background agent stop/fail notifications now separate a short summary from a longer note

Notifications for stopped or failed background agents now split a short summary from a longer explanation

**What**

When a background agent (a task running outside your direct view), a background shell command, or a web-fetch launch stops or fails, the notification you get now carries two parts: a short `summary` line and a longer `note` (also called `body`) with the details. Individual agent notifications now start with a fixed line like `Background agent "X"`, with the fuller explanation moved into the note.

**Why**

Separating a quick summary from the longer explanation makes it easier to scan notifications at a glance while still having the full detail available when you need it.

- Area: Background Agents
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Oversized-output error message now warns about byte-limited saved files

Error messages for oversized tool output now warn when the saved file itself was truncated

**What**

When a tool's output is too large to show directly and Claude Code saves it to a file instead, that saved file can itself be cut off at a byte limit. Now, when this happens, the error message shown to Claude explicitly notes that the saved file only contains the first N bytes or characters of the original output, that it may end in the middle of a structure, and that trying to parse it as JSON can therefore fail.

**Why**

This extra warning helps Claude (and anyone reading the error) understand why a saved file might fail to parse, instead of appearing to be a mysterious JSON error.

- Area: Tool Results
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Worktree checkout now parallelized via git's checkout.workers, capped at 16

Git worktree checkouts now run in parallel using git's checkout.workers, capped at 16

**What**

When Claude Code checks out a git worktree (a separate working copy of a repository), it now speeds this up by using git's `checkout.workers` setting, which lets git parallelize the checkout across multiple workers. If the repository doesn't already have `checkout.workers` configured, Claude Code sets it for the operation itself, choosing a value between 1 and 16. This applies both when quickly resuming an existing worktree and when creating a new one.

**Why**

Parallelizing the checkout can make worktree setup noticeably faster, especially for larger repositories, without requiring any configuration from you.

- Area: Worktrees
- Names: `checkout.workers`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Auth status message adapts to Cloud gateway sessions

`claude auth status` now shows a Cloud-gateway-specific sign-in hint instead of the generic one

**What**

When Claude Code is running through a Cloud gateway and you're not logged in, `claude auth status` (and its JSON output) now tells you to start `claude` and sign in with `/login`, instead of showing the generic "run claude auth login" message. The reported authentication method for these sessions also now shows as `none` rather than `third_party`.

**Why**

The old generic instructions didn't apply to sessions running through a Cloud gateway, so this makes the sign-in guidance actually match how you're running Claude Code.

- Area: Auth
- Names: `claude auth status`, `/login`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### /model default-save now confirms the write and reports failure/unconfirmed states

/model's default-save now waits to confirm the write and reports saved, unconfirmed, or failed instead of assuming success

**What**

When you save a model as your default with `/model ... default`, Claude Code now waits (up to a timeout) to confirm the setting was actually written to disk, and reports one of three outcomes:

- `saved` — the write was confirmed

- `unconfirmed` — confirmation didn't arrive in time, typically because `settings.json` was still being written

- `failed` — the write genuinely failed, along with the underlying error

**Why**

Before this, saving a default model just assumed it worked. Now if the save didn't actually go through, you're told so instead of thinking your default changed when it didn't.

- Area: Models
- Names: `/model`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Settings permission-editing prompt distinguishes user-level vs project-level .claude folder

The prompt asking to let Claude edit settings now says whether it's your user-level or this project's .claude folder

**What**

When Claude Code asks for permission to edit its own settings files, the confirmation prompt now shows different wording depending on where those files live: your personal, user-level `~/.claude` folder, or this project's own `.claude` folder.

**Why**

Previously the prompt didn't distinguish the two, which could make it unclear whether you were granting access to settings that apply everywhere you use Claude Code or just to the current project. The clearer wording makes it easier to decide whether to allow the edit.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Clearer managed-settings gateway sign-in error message

Gateway sign-in error now explains itself in plain language instead of naming the internal forceLoginMethod setting

**What**

When a machine's managed settings (an admin-controlled settings file) require signing in through a cloud gateway, Claude Code used to show the raw internal error "forceLoginMethod is 'gateway' in managed settings". It now shows a plain-language message instead: managed settings on this machine configure a cloud gateway sign-in, and the user should run `/login` from an interactive terminal to authenticate. This applies both to the CLI's login-validation path and to a separate stderr early-exit path.

**Why**

The old message exposed an internal setting name that meant nothing to most users. The new wording tells people what's actually happening and what to do about it.

- Area: Auth
- Names: `/login`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Cursor recognized as an ignore/config source and telemetry source

Claude Code now recognizes .cursor directories for ignore rules and context, and tracks Cursor in import telemetry

**What**

Claude Code now treats `.cursor` directories the same way it already treats `.windsurfrules` and `.clinerules`, for deciding what belongs to a project's worktree and context. The older `.cursorrules` file is no longer part of that list. Separately, internal usage tracking for imports now records a `cursor` flag alongside the existing ones.

**Why**

This keeps Cursor's project files properly recognized as configuration rather than being treated as ordinary files, matching how other editor-specific config directories are already handled.

- Area: Internals
- Names: `.cursor`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New hook-timing guard message for classic hooks calling turn.complete-style APIs

New warning explains why calling certain APIs from most hooks would freeze, and tells you to use turn.complete instead

**What**

A hook is a script you configure to run automatically at certain points in a session, such as when a session starts or ends. Claude Code now shows a specific warning if code tries to call something like a "turn complete" style API from inside most hooks (any hook except `SessionStart`, `Setup`, or `SessionEnd`). The warning explains that doing so would deadlock, because the call would wait on the very turn the hook is currently holding open, and suggests submitting from the `turn.complete` event instead.

**Why**

This turns a confusing hang into a clear, actionable error message, making it much easier to diagnose why a hook script that calls the wrong API at the wrong time freezes instead of failing outright.

- Area: Hooks
- Names: `turn.complete`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Bash command comparison for approval matching reworked

The check that matches bash commands for permission approval was rewritten to handle more command-prefix forms

**What**

When Claude Code decides whether two bash commands should be treated as the same for permission or approval purposes, it previously did this by stripping a literal `cd <directory> && ` prefix. That logic has been replaced with a more general comparison that also correctly handles the way Windows quotes a `cd` prefix.

**Why**

This makes permission matching for bash commands more reliable on Windows, reducing cases where a command that should be recognized as already-approved is instead treated as new and prompts for approval again.

- Area: Permissions
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Opus 1M-context restriction extended to opusplan[1m]

The 1M-context restriction that blocks certain Sonnet model switches now also blocks opusplan[1m]

**What**

Claude Code has a check that prevents switching to a 1-million-token context window for certain models, previously applied to `sonnet[1m]`, `sonnet-4-6[1m]`, and `sonnet-5[1m]`. That same restriction now also applies to the model string `opusplan[1m]`.

**Why**

This closes a gap where `opusplan[1m]` could be selected without the same 1M-context restriction that already applied to the equivalent Sonnet variants.

- Area: Models
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New artifact database error kinds surfaced verbatim

Artifact database now reports specific edit-conflict errors instead of a generic failure

**What**

When Claude Code's artifact database rejects an edit, it now passes through several specific error reasons instead of collapsing them into a generic failure: `edit_no_match`, `edit_ambiguous`, `edit_field_missing`, `edit_field_not_string`, and `version_mismatch`.

**Why**

This makes it clearer why an edit to an artifact failed, for example because the text to replace couldn't be found, matched more than one place, or the artifact had been changed by someone else in the meantime, rather than just showing an unhelpful generic error.

- Area: Artifacts
- Names: `edit_no_match`, `edit_ambiguous`, `version_mismatch`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Bash permission matching now accounts for a leading "cd <cwd> &&" wrapper

Bash permission rules now match commands even when prefixed with "cd &&"

**What**

When Claude Code checks whether a Bash command is allowed by your permission rules, it now also recognizes commands written as `cd <folder> && <command>` as matching a rule written for the bare `<command>`, as long as the folder matches the current working directory.

**Why**

Before this, a permission rule written for a plain command could fail to match if Claude first changed directory and chained the command with `&&`, even though the actual working directory was the same one the rule expected. This closes that gap so such commands are recognized correctly.

- Area: Permissions
- Names: `cd`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### JVM truststore build for agent-proxy now reuses an existing truststore instead of rebuilding every time

Agent-proxy reuses an existing JVM truststore instead of rebuilding it on every run

**What**

Claude Code's agent-proxy component (used for routing traffic through a local proxy, including for Java-based tools) installs a certificate authority (CA) into the Java Virtual Machine's truststore. Previously this was rebuilt every time. Now it first checks a small sidecar record of the previously installed CA; if that matches the current CA and the truststore file still exists, it skips rebuilding and logs "reusing JVM truststore at," recording `reused: true` for tracking.

**Why**

Skipping unnecessary truststore rebuilds should make repeated proxy setup faster when nothing about the certificate has actually changed.

- Area: Agent Proxy
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Deferred/blocked tool messaging generalized for a 'tool search absent' mode

Tool-availability messages get a mode for when tool search itself isn't available

**What**

Claude Code shows notices about tools that aren't immediately available, such as MCP (Model Context Protocol) servers still connecting. This messaging now has a distinct mode for when tool search (the feature that lets Claude look tools up rather than having them all listed) isn't available at all. In that mode, the wording changes:

- tools are called "tool" instead of "deferred tool"

- instructions say "Do not call them" instead of "Do not search for them — X will return no match"

- still-connecting MCP servers are described as tools that "will be announced here" rather than tools to look up via the tool-search tool

**Why**

This keeps the guidance Claude sees accurate and non-misleading in setups where tool search isn't an option, instead of referring to a search capability that doesn't exist there.

- Area: Tool Search
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Plugin list command now batches marketplace plugin lookups and filters by an install-eligibility check

`claude plugin list` now filters and batches marketplace plugin lookups for eligibility

**What**

When listing available plugins, `claude plugin list` now filters out plugins that fail an install-eligibility check and fetches the remaining plugin details through a new batched lookup helper, instead of iterating and looking up each marketplace plugin individually.

**Why**

Batching the lookups should make listing available plugins faster, and filtering out ineligible plugins up front keeps the results limited to plugins that can actually be installed.

- Area: Plugins
- Names: `claude plugin list`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Agent detail card gains sub-task display and an 'expand' hint

The workflow agent status card now shows sub-tasks, a truncated tool-call count, and an 'expand' hint

**What**

The status card shown for an agent within a workflow (a multi-agent task) now displays a list of its sub-tasks alongside its tool calls. When there are many tool calls, the card shows a capped summary like 'last N of M tool calls' instead of listing everything, and the Activity section header now includes a dedicated hint telling you the card can be expanded.

**Why**

This makes it easier to see at a glance what a busy agent has been doing without the card becoming unreadably long, while making clear that more detail is available if you expand it.

- Area: Workflows
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### str_replace edits to artifact live-file data are now checked as an 'update' permission rule

Editing artifact live data with str_replace is now checked and can be denied as an 'update' permission rule

**What**

When a `str_replace` operation is used to edit artifact files or live-document data, Claude Code now treats it the same as a database 'update' operation for the purposes of matching your permission rules. If a rule denies it, you'll see a message explaining that a str_replace counts as an update and that nothing was written.

**Why**

This closes a gap where editing artifact live data via str_replace might not have been checked against 'update' permission rules the same way other update operations are, so your existing rules for controlling updates now apply consistently to this kind of edit too.

- Area: Artifacts
- Names: `str_replace`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Plugin marketplace listings enriched from each plugin's own plugin.json

Plugin marketplace listings now fill in missing display info by reading the plugin's own plugin.json

**What**

When browsing or installing a plugin, if the marketplace listing is missing details like `displayName`, `description`, `author`, `homepage`, `repository`, `license`, or `keywords`, Claude Code now fetches the plugin's source code and reads its `.claude-plugin/plugin.json` file to fill in those fields for display.

**Why**

This means plugin listings show more complete information even when the marketplace entry itself is sparse, by falling back to metadata the plugin author already included in their own project.

- Area: Marketplace
- Names: `plugin.json`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Model switch failures are now surfaced to the user

Claude Code now tells you when switching models fails instead of failing silently

**What**

If you switch models (for example with a model-switch command) and the switch does not succeed, Claude Code now shows a 'Model switch failed' message. Previously this kind of failure was not surfaced at all.

**Why**

Before this change, a failed model switch could leave you unsure whether you were talking to the model you asked for. Now you get a clear signal when the switch didn't go through.

- Area: Models
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Remote-control bridge now waits for in-flight OAuth refresh before exiting/registering

Remote Control now waits for an in-progress login token refresh before registering the device

**What**

When you run `claude remote-control` to connect a device (so you can continue a local session from your phone or another computer), the setup process now waits for any in-progress OAuth token refresh (the background renewal of your login credentials) to finish before it registers the device or exits, up to a new capped wait time (`OAUTH_REFRESH_EXIT_WAIT_CAP_MS`).

**Why**

This avoids a race where Remote Control tries to register or exit while your login token is mid-refresh, which could otherwise leave the connection in a bad state.

- Area: Remote Control
- Names: `claude remote-control`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Chord-timeout keybinding now surfaces a user-visible notification

A timed-out keybinding chord now shows an on-screen notification, not just a log entry

**What**

If you start a keybinding chord (a sequence like pressing a leader key followed by another key) and don't finish it in time, Claude Code now shows an immediate notification naming the chord that was cancelled. Before, this was only recorded in the log where you wouldn't see it.

**Why**

This makes it clear in the moment why your key sequence didn't do anything, instead of leaving you to wonder or dig through logs.

- Area: Terminal UI
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Local slash-command results can now be patched into an already-queued message (deferred slash commands)

Slash commands can now finish their output after being queued and patch it into your queued message

**What**

When a local slash command's output isn't ready yet but you've already queued a message containing it, Claude Code can now go back and patch the queued message once the result arrives, rather than requiring the result up front. This works by finding a queued message that starts with `<local-command-stdout>` or `<local-command-stderr>` and rewriting its contents in place, paired with new internal helpers that build the initial placeholder message and track it by a `deferredSlashUuid`.

**Why**

This lets a local slash command's result show up correctly even if it finishes after the message using it has already been queued for sending, instead of the message being stuck with stale or missing output.

- Area: Slash Commands
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New fuzzy slash-command autocomplete matching helpers

Slash-command autocomplete gets new fuzzy-matching helpers to avoid pointless popups

**What**

New internal matching functions let slash-command autocomplete match a partially-typed `/command` against the command's full name, its short alias (the part after a colon), or its display label. The matching only offers suggestions if at least one candidate is actually longer than what you've typed, so autocomplete won't pop up when what you typed already exactly matches a command.

**Why**

This avoids showing an autocomplete popup that offers nothing new once you've already typed a full, exact command name.

- Area: Slash Commands
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### PR/MR-creation detection extended to GitLab CLI and raw GitHub API calls

Claude Code now recognizes PR/MR creation via GitLab CLI and raw GitHub API calls, not just gh pr create

**What**

Claude Code detects when you create a pull request or merge request so it can track this activity. That detection now covers more cases:

- Composite shell commands that combine `gh pr create` or `glab mr create` with allowed extra calls (like `gh`/`glab auth`, config commands, or `api /user`) are recognized, via a new helper replacing the previous simpler check.

- Creating a pull request through a raw `gh api` call that POSTs to `/repos/OWNER/REPO/pulls` is now also recognized as PR creation, through a separate new helper.

Both paths feed the same telemetry event and pull-request contribution tracking as before.

**Why**

Previously, using GitLab's CLI or hitting the GitHub API directly instead of the standard `gh pr create` command could mean Claude Code failed to notice you'd created a pull or merge request. This closes that gap so tracking stays accurate regardless of which tool or command shape you use.

- Area: Telemetry
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Bash permission check now lets a bare 'cd <safe-subdir>' (plus further safe commands) skip the outside-working-directory block

A bare `cd ` followed by other safe commands no longer triggers the outside-working-directory permission check

**What**

When Claude Code checks whether a bash command needs extra permission because it runs outside your working directory, it now recognizes a specific safe pattern: a compound command (several commands chained together) that starts with `cd`, `chdir`, or `pushd` to a plain relative directory name. The directory can't contain wildcards, environment variables, `..`, or other shell special characters, and it must already be a directory you're allowed to read. Every command chained after it must also be safe and already permitted.

When all of that holds, Claude Code skips the extra "outside working directory" permission prompt entirely.

**Why**

This cuts down on unnecessary permission prompts for a common, harmless pattern: changing into a subdirectory you already have access to and then running further already-permitted commands there. It only applies on non-Windows systems.

- Area: Permissions
- Names: `cd`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Plan-review 'view as artifact' step removed from ExitPlanMode UI

Exiting plan mode no longer offers to show the plan as an artifact before running it

**What**

Previously, when Claude finished writing a plan, it could ask "Claude has written up a plan. Would you like to review it as an artifact first?" before moving on. That step has been removed: exiting plan mode now goes straight to the confirmation prompt asking whether to execute the plan.

**Why**

This simplifies the plan-review flow to one fewer step, though it means the option to view the plan as a separate artifact document first is no longer offered here.

- Area: Plan Mode
- Names: `ExitPlanMode`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Remote session: ability to retract an unsent first prompt

Remote sessions can now show that you took back your first command-line message before it was sent

**What**

When starting a remote session with a prompt given on the command line, that first message is briefly withheld before being sent to the cloud session. Claude Code now recognizes a distinct outcome where you took that message back before it was sent, showing the notice: "You took back your first message (the one given on the command line) — it wasn't sent to the cloud session." This is separate from the existing messages for when sending or confirming the message fails.

**Why**

This gives clearer feedback distinguishing a deliberate retraction of your first message from an actual send failure.

- Area: Sessions
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Resumed sessions now synthesize interrupted tool_result stubs for trailing unresolved tool calls

Resuming a session now fills in stub results for tool calls that never got a response

**What**

When a session is resumed, if it was interrupted while a tool call was still waiting for a result, Claude Code now creates a synthetic `tool_result` entry for that call, marked with `toolDenialKind: "interrupted"`, instead of leaving it unresolved. These unresolved calls are tracked in a new `outTrailingUnresolvedToolUseIds` set, and the IDs of calls that got a fabricated result are returned as a new `answeredToolUseIds` field, which is passed through to the headless (non-interactive) runner as well.

**Why**

This keeps a resumed session's transcript consistent by ensuring every tool call has a matching result, even if the original run was cut off before the tool call finished, avoiding dangling or malformed conversation state.

- Area: Sessions
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New per-agent transcript polling hook for the workflow monitor TUI

Workflow monitor's agent-detail view now polls each agent's transcript in the background and shows a loading state

**What**

The workflow monitor's terminal display (the TUI that shows agents running as part of a `Workflow`) now has a background hook that repeatedly polls for each agent's transcript, keyed by its run and agent ID. While a transcript is still being fetched, the detail card shows a "loading" state; once fetched, the result is cached and reused, and the poll reschedules itself automatically. The agent-detail card that renders this reads the transcript's tasks and tool calls once available.

**Why**

This keeps the workflow monitor's per-agent detail view responsive and up to date without blocking on a slow transcript fetch, showing a clear loading indicator instead of a stalled or empty pane.

- Area: Workflows
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Pin/unpin denial wording softened from 'requires' to 'someone else's'

The message shown when pinning is denied changed its wording

**What**

When Claude Code denies a request to pin an artifact because there's no live consent surface (no way to ask you in the moment), the reason text shown changed from "Pinning someone else's artifact requires a live consent surface" to a softer phrasing that just describes it as someone else's artifact.

**Why**

This is a wording change to an internal denial message; it doesn't change when pinning is allowed or denied.

- Area: Artifacts
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Artifact live-file preservation message now reports non-tracked live files separately

Artifact copy/reseed messages now separately report other live files that were kept or changed

**What**

When Claude Code copies or reseeds an artifact and reports which "live" files were kept as-is, the message now also reports on other live files that were kept or changed, appending a separate "; other live files kept or changed:" note when the file list is provided in a Map-like structure.

**Why**

This gives a fuller picture of what happened to all live files during a copy or reseed, not just the ones explicitly preserved unchanged.

- Area: Artifacts
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Artifact asset read/list tool-use summaries drastically simplified

Artifact tool's read/list-asset summaries were shortened to brief fixed text, dropping detailed approval-scope explanations

**What**

The short descriptions Claude Code shows for the artifacts tool's `read_asset` and `list_assets` actions (used when displaying what a tool call is about to do) were replaced with two brief, fixed sentences. The previous versions explained in more detail how approval scope worked, including the difference between reading your own artifacts versus others', and coverage of server-side copies.

**Why**

This simplifies what's shown to the reader when these actions run, though it means less detail is surfaced about exactly what access is being used.

- Area: Artifacts
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Same simplification applied to artifact list_files/read_file summaries

Artifact tool's list_files/read_file summaries were similarly shortened, dropping detailed co-write and approval explanations

**What**

The short descriptions shown for the artifacts tool's `list_files` and `read_file` actions were also cut down to two brief, fixed sentences, replacing more detailed text that had explained co-writing, type-publisher distinctions, and approval scope.

**Why**

This matches the same simplification made to the artifact read/list-asset summaries, trading detailed explanation for shorter, simpler text shown to the reader.

- Area: Artifacts
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Artifact verify-diagnostics 'no row' message gains an extra explanation

Artifact verify-diagnostics message now also explains older pages that don't report diagnostics at all

**What**

When Claude Code checks an artifact (a generated file or page shown to the user) for runtime diagnostics and finds none, it shows an explanatory message. That message now also covers the case where the artifact's page runtime simply doesn't report diagnostics at all, which happens with older artifact pages, in addition to the existing cases of a missing viewer or an owner-only artifact.

**Why**

This gives a clearer, more accurate explanation when no diagnostics show up for an older artifact page, instead of leaving it looking like an unexplained gap.

- Area: Artifacts
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Directory sync: dedup logic and wording change for 'changedDuringRead'

Directory sync avoids repeating the same 'still being written' warning and now says 'sync' instead of 'turn'

**What**

When Claude Code notices a file is still being written to during directory sync, it shows a warning that the file's contents haven't settled yet. This warning now avoids repeating itself: if the same set of files triggers it again, it won't be re-appended. The wording also changed slightly, now saying the file will go out "with the next sync that finds it at rest" instead of "the next turn that finds it at rest."

**Why**

This reduces redundant warning spam when the same files keep showing up as still being written, and the wording change more accurately describes that the check happens on sync, not just once per conversation turn.

- Area: Cloud Sync
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Gateway session messaging simplified/unified for Remote Control

Remote Control's gateway-blocked message is now a single generic explanation instead of two separate cases

**What**

When a Claude Code session can't use Remote Control because it's routed through an enterprise or cloud gateway, it now shows one generic message saying the session uses a gateway that doesn't support Remote Control. Previously this distinguished between a session signed in via `/login` to an enterprise cloud gateway and one set up via the `CLAUDE_CODE_USE_GATEWAY` environment variable.

**Why**

This simplifies the explanation shown to users, though the underlying limitation, that gateway-routed sessions can't use Remote Control, is unchanged.

- Area: Remote Control
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### policyHelper singular field now also warns for ignored onFailure/retries

Claude Code now warns if onFailure or retries is set on the singular policyHelper entry, since those are ignored there

**What**

The `onFailure` and `retries` settings on a `policyHelper` entry only take effect on the per-operating-system `policyHelpers` entries, not on the single, non-per-OS `policyHelper` key. Claude Code now warns explicitly when either setting is placed on the singular `policyHelper` entry, since it will be silently ignored there.

**Why**

Without this warning, an admin could set `onFailure` or `retries` on the singular `policyHelper` entry and reasonably assume it works, when in fact it's silently discarded. The warning catches that mistake instead of letting it fail quietly.

- Area: Managed Settings
- Names: `policyHelper`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### New explicit messages for project memory being unreachable via the remote-session bridge

Clearer error messages explain when project memory isn't reachable over a remote session or is turned off

**What**

Claude Code now shows explicit messages when project memory can't be used. One message explains that project memory tools throw an error when running through the remote-session bridge, because that bridge has no memory access. A separate message explains when memory access is simply turned off or the server doesn't yet support it, noting that this is re-checked the next time context is rebuilt or a new session starts.

**Why**

These messages make it clear why project memory isn't working in a given situation, distinguishing a structural limitation (remote-session bridge) from a temporary or configuration-based one (access off or not yet supported), and confirming it will be re-checked later rather than staying broken indefinitely.

- Area: Project Memory
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Remote-io stdin now explicitly warns and is ignored outside bridge/byoc hosts

Remote sessions now explicitly discard and warn about unexpected stdin input

**What**

A new `discardStdinLane` method drains and throws away any data arriving on the process's standard input (stdin) stream during remote sessions. The first time it sees non-empty input, it logs a warning explaining that only a 'bridge' or 'byoc' (bring-your-own-compute) host treats stdin as a real input channel; for other setups, control input is expected to come through the session stream instead.

**Why**

This makes it clear when stdin input is being silently ignored rather than leaving it unexplained, which should help diagnose cases where someone expects piped input to reach a remote session but it isn't the right channel for their setup.

- Area: Sessions
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### File sync pause/resume messaging now frames itself as an Anthropic-controlled emergency switch

File sync pause/resume messages now describe an Anthropic-controlled 'emergency switch'

**What**

New user-facing messages explain that file syncing between a local machine and a cloud session can be paused or resumed by an 'emergency switch' controlled by Anthropic. These messages cover cases where a file upload was in progress when sync paused, and cases where two-way sync between local and cloud is affected.

**Why**

This gives a clearer explanation when file sync unexpectedly stops or resumes, making it clear the pause is a deliberate, centrally-controlled action rather than a bug or connection failure.

- Area: Cloud Sync
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### New 'durable_declined' live-subscription state gets its own message

A new durable_declined live-subscription state now shows its own distinct message

**What**

When an artifact's live subscription (the mechanism that keeps a published artifact updating live) has the state `durable_declined`, Claude Code now shows a distinct message for it instead of falling back to a generic message used for other states.

**Why**

This gives users clearer, more specific feedback about why a live subscription isn't active in this particular case, building on the live-subscription support for artifacts published from a type.

- Area: Artifacts
- Names: `durable_declined`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Skill capability wording distinguishes core (callable) vs. declared skills

Skill wording now says 'calling' a core capability versus 'declaring' others

**What**

When Claude Code needs to extract a skill's type definitions because its authoring guidance isn't otherwise available, the message it shows now distinguishes between skills: for core, built-in skills it says "calling this capability," while for other, declared skills it keeps saying "declaring this capability."

**Why**

This makes the guidance more accurate, since core skills are invoked directly ("called") while other skills are only declared for use, helping anyone reading the message understand the distinction correctly.

- Area: Skills
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Truncated tool-output persist message now distinguishes cap-truncation from oversized full save

The message shown when a tool's saved output was cut off now says clearly that only part of it was kept

**What**

When a tool's output is too large to keep in full and gets saved to a file, Claude Code now shows one of two distinct messages: the existing one when the whole output was saved, and a new one when the output was truncated at a byte limit, which states that only the first N bytes were saved.

**Why**

This makes it clear when you're looking at a partial save rather than the complete output, instead of using the same wording for both cases.

- Area: Tool Results
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Diagnostics "no row" message now covers older-page case

Diagnostics "no data" message now also explains an older page can't capture diagnostics

**What**

The verify-diagnostics screen's message for when no diagnostic row is found now adds another possible reason: the page you're on may be an older version that can't capture diagnostics at all. This is in addition to the existing reasons (older than 24 hours, or not readable).

**Why**

This gives a clearer explanation when diagnostics are missing, so you're not left guessing whether it's a timing issue, a permissions issue, or simply an outdated page.

- Area: Artifacts
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Tool-result-saved message now reports truncation

Message about a large tool result saved to a file now notes when it was truncated

**What**

When a large tool result gets saved to a file instead of shown inline, the message telling you it was saved can now also note that the saved file was truncated to the first N bytes.

**Why**

This makes clear when the saved copy isn't the complete result, so you know to expect it may be incomplete rather than assuming the full output was preserved.

- Area: Tool Results
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Project memory read/list actions added

Two new project memory actions get readable descriptions: listing and reading memory files

**What**

When Claude Code shows what a tool call is doing, two new project-memory actions now get readable descriptions:

- `project_memory_list` shows as "List project memory"

- `project_memory_read` shows as "Read memory {path}" or "Read project memory file"

**Why**

This makes it clearer to users what's happening when Claude Code lists or reads its stored project memory, instead of showing an unlabeled or raw action name.

- Area: Project Memory
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### forceLoginGatewayUrl validation loosened from strict URL to non-empty string

forceLoginGatewayUrl now accepts any non-empty string instead of requiring a valid URL

**What**

The `forceLoginGatewayUrl` setting, which points the login screen at a gateway URL, used to require a syntactically valid URL. It now only requires a non-empty string, so any text value is accepted.

**Why**

This loosens validation on an admin-controlled setting used to force login through a gateway, meaning malformed values that aren't real URLs will no longer be rejected up front.

- Area: Auth
- Names: `forceLoginGatewayUrl`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### New codepoint 94180 blocked as an invisible/steganographic character

A new hidden character, U+16FE4, is now blocked as a potential steganography risk

**What**

Claude Code's checks for invisible or hidden characters now also flag codepoint 94180 (U+16FE4), alongside characters it already blocked such as the zero-width no-break space (65279) and the tag character range (917504-917999).

**Why**

This closes another way invisible characters could be smuggled into text, since such characters can be used to hide instructions or content that isn't visibly displayed.

- Area: Permissions
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Frozen-Artifact-type publish note now supports a customizable message

The message shown when publishing to a type-locked Artifact URL can now be customized per store

**What**

When you try to publish a data file to an Artifact URL that's locked to a specific type, Claude Code previously always showed the same fixed notice. That notice can now be generated dynamically based on the store's declared type, release, and type slug, rather than always being the same fixed text.

**Why**

This means the guidance you see when hitting a type-locked Artifact URL can now reflect the specific store and type involved, making the message more relevant to your situation instead of always reading the same generic text.

- Area: Artifacts
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Directory sync large-turn warnings can now suppress the local notify while still reporting

Directory sync can now record an oversize-file warning without repeatedly notifying the user

**What**

When directory sync detects that a turn is too large to sync (hitting the `overCap` or `oversizeLeftOut` conditions), it now has the option to record that report internally without popping up the disruptive notification to the user every single time, for example to avoid renotifying about the same oversize file list repeatedly.

**Why**

This should reduce repetitive, distracting notifications when the same oversize condition keeps recurring, while the underlying report is still tracked.

- Area: Cloud Sync
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### System trust store CA install is also now skipped when already installed

System-wide CA trust install is also skipped when the certificate is already installed

**What**

Similarly to the JVM truststore change, the system trust store installer now checks whether the current certificate authority (CA) is already recorded as installed on the system. If so, it logs "CA already in the system trust store; install skipped," records `agent_proxy_system_trust` with `reused: true`, and skips rerunning the operating-system-specific install step.

**Why**

This avoids redundant, potentially slow OS-level trust store operations when the certificate hasn't changed since it was last installed.

- Area: Agent Proxy
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Background workflow resume guidance text reworked

The message shown when a background workflow can't auto-resume now points to 'the run id from the summary' instead of showing a raw ID

**What**

When Claude Code can't find the completion record for a background workflow (a multi-agent task that ran without blocking your session), it shows a message explaining how to pick up where things left off. That message used to insert the literal run ID value directly into the example command. Now it instead tells you to use 'the run id from the summary', and the notification's internal structure was reorganized.

**Why**

This is a wording and formatting change to the recovery instructions shown in this edge case, making the guidance more generic rather than tied to a specific embedded value.

- Area: Workflows
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Slash-command autocomplete now shows a hidden-match count

Slash-command autocomplete now shows a '+N' count when multiple commands match

**What**

The autocomplete helper for finishing a partially-typed slash command now only suggests a completion when it's actually longer than what you typed. When more than one full command matches, the suggested text now appends a count of the extra matches, shown as `<suffix> +N`.

**Why**

This tells you at a glance that there are more matching commands than the one shown, instead of only ever seeing a single guess.

- Area: Slash Commands
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Model-switch confirmation toast now distinguishes saved vs session-only, with a persistent toast for the latter

Model-switch toast now says whether the new default was actually saved, and stays visible if it wasn't

**What**

After switching your model with the hotkey, Claude Code now checks whether the new default model was actually saved before showing the confirmation message. The toast now only says "and saved as your default for new sessions" when that check confirms it was saved.

- If the switch was saved (or the save check failed), the toast disappears after 3 seconds, as before.

- If the switch was session-only (not saved), the toast now stays visible until you dismiss it.

**Why**

Previously the confirmation toast could claim a model change was saved as your default even when it was only for the current session. This makes the message accurate and gives session-only changes a persistent toast so you're less likely to miss that it won't carry over to new sessions.

- Area: Models
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Artifact file paths and root can now reference the scratchpad directory

Artifact publish tool's file path description now mentions the scratchpad directory as a valid location

**What**

The descriptions for the `files` parameter and root-relative source paths in the artifact publish tool now explicitly mention that a path can point into your scratchpad directory (a temporary working area), not just the regular working directory.

**Why**

This clarifies to the model that files kept in the scratchpad directory are valid sources when publishing an artifact, not only files in the main working directory.

- Area: Artifacts
- Names: `scratchpad`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Artifact publish source verification now allows the workspace scratchpad as a trusted root

Artifact publish now trusts files from the session's scratchpad directory as well

**What**

When Claude Code re-checks that a file being published as part of an artifact actually comes from a trusted location, it now also accepts the session's scratchpad directory (a working-storage folder for the session) as valid, in addition to the working directory and any additional working directories already allowed.

**Why**

This lets artifact publishing work with files placed in the scratchpad directory without being rejected as coming from an untrusted location.

- Area: Artifacts
- Names: `scratchpad`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### New `classic.*` hook turn-block guidance distinguishes SessionStart/Setup/SessionEnd from other classic hooks

Clearer error guidance when a classic hook other than SessionStart/Setup/SessionEnd tries to block the turn

**What**

When a plugin's classic-style hook (an older hook format) other than `SessionStart`, `Setup`, or `SessionEnd` tries to make a plugin API call that would block waiting on the current conversation turn, Claude Code now returns a specific error explaining that the turn may already be held by that hook, and directing the caller to submit from a later event such as `turn.complete` instead.

**Why**

This gives plugin authors a clearer, actionable error instead of a silent hang or a confusing failure when their hook code blocks on the turn at the wrong point in the hook lifecycle.

- Area: Hooks
- Names: `turn.complete`
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Artifact file-cache tool text changed from 'save' to 'read'

Artifact file-cache progress text now says 'read' instead of 'save' for reads

**What**

The progress text shown while Claude Code performs an artifact `read_file` action changed from "save file " to "read ", and for `read_asset` it changed from "save asset " to "read asset ". Additionally, a destination arrow that used to show where a file was going is now suppressed when the destination is just a default directory.

**Why**

The old "save" wording was misleading for what is actually a read operation; this makes the progress text match what's actually happening, and hides irrelevant destination arrows for default-location reads.

- Area: Artifacts
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### New 'thought for Ns' formatter helper added

New helper formats elapsed thinking time as 'thought for Ns'

**What**

A small new formatting function turns elapsed thinking time into a string like "thought for 3s", rounding to the nearest second with a minimum of 1 second shown.

**Why**

This is a small display helper for showing how long Claude spent thinking, ensuring the displayed time never rounds down to zero seconds.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### Wording tweak: "another person's artifact" -> "someone else's artifact"

Wording change: artifacts owned by others are now described as "someone else's artifact"

**What**

The message shown when a session can only read a summary of an artifact it doesn't own was reworded from "another person's artifact" to "someone else's artifact."

**Why**

This is a small tone tweak to the wording with no functional change.

- Area: Artifacts
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### 'sharp' removed from native-addon leak diagnostic message

The native-addon memory-leak warning no longer mentions 'sharp' as an example, only node-pty

**What**

When Claude Code warns that native memory usage may indicate a leak in a native addon (a compiled module outside plain JavaScript), the message used to list `sharp` and `node-pty` as example addons that might be responsible. It now lists only `node-pty`.

**Why**

This narrows the example in the diagnostic message; it suggests `sharp` is no longer relevant to this warning, though the finding doesn't say why it was removed.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### New spinner/verb flavor text: "Kerfuffling" and "Transmogrifying"

Two new whimsical status words, "Kerfuffling" and "Transmogrifying", added to Claude Code's working spinner

**What**

While Claude Code is working on a request, it shows a rotating status word next to the spinner. Two new ones have been added: "Kerfuffling" and "Transmogrifying".

**Why**

This is a cosmetic addition to the set of playful words shown while Claude is thinking or working; it doesn't change functionality.

- Area: Elsewhere
- Names: `Kerfuffling`, `Transmogrifying`
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### Spill-to-tool-results error message now distinguishes project_read from project_memory_read

Error when a large result fails to save now names whether it came from project_read or project_memory_read

**What**

When a tool result is too large and gets spilled into separate tool-results storage, and that save fails, the error message now says specifically which method triggered it: "project_read: spill to tool-results failed" or "project_memory_read: spill to tool-results failed", instead of one generic message.

**Why**

This makes it clearer, when something goes wrong saving a large result, exactly which operation caused it, which helps with diagnosing failures.

- Area: Project Memory
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### "thought for Ns" status line replaces per-kind thinking duration text for completed thoughts

Completed thinking steps now show a plain "thought for Ns" status line

**What**

When Claude finishes a thinking step, the status line now shows a simple "thought for Ns" message, where N is the number of seconds elapsed (rounded, with a minimum of 1 second), replacing separate wording that varied by thinking type.

**Why**

This gives a consistent, simple way to see how long Claude spent thinking on a completed step.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

## Bug Fixes

### MCP connections gain legacy HTTP+SSE fallback on initialize failure

MCP servers using newer HTTP now automatically retry with an older HTTP+SSE connection method if the newer one fails

**Unclear.** Gate state for `tengu_flag` and `tengu_mcp_legacy_sse_fallback` is unread, so whether this fallback is active for any given account is unknown.

**What**

MCP (Model Context Protocol, the standard Claude Code uses to talk to external tool servers) connections that use the newer 'Streamable HTTP' method now fall back automatically if the server rejects the initial connection request, for example with a "405 Method Not Allowed" error. Claude Code closes the failed connection and retries using the older HTTP+SSE (Server-Sent Events) connection method instead of giving up.

**Why**

Some MCP servers only support the older connection method. This fallback lets Claude Code connect to those servers automatically instead of failing outright.

- Flag `tengu_mcp_legacy_sse_fallback`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: on)
- Area: MCP
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### Legacy HTTP+SSE fallback for MCP servers rewritten with a dedicated gate

MCP servers can fall back to a legacy HTTP+SSE connection method if the normal connection fails

**Unclear.** Nothing has been read yet about whether the tengu_mcp_legacy_sse_fallback gate is on or off for any account.

**What**

When connecting to an MCP server (a protocol Claude Code uses to talk to external tool servers) over HTTP, Claude Code now tries a normal initialize request first. If that fails, it can fall back to an older connection method called HTTP+SSE (Server-Sent Events), using a capped number of retries. Whether this fallback is used gets recorded in telemetry as `negotiatedLegacySse`.

This fallback path is controlled by a gate called `tengu_mcp_legacy_sse_fallback`.

**Why**

This helps Claude Code keep working with older MCP servers that only support the legacy connection style, instead of failing outright when the modern connection method doesn't succeed.

- Flag `tengu_mcp_legacy_sse_fallback`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: on)
- Area: MCP
- Names: `negotiatedLegacySse`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### auto-mode CLI subcommands fixed to attach to the right command object

Fixed a bug that stopped the claude auto-mode defaults, reset, config, and critique subcommands from working

**What**

The `claude auto-mode` subcommands `defaults`, `reset`, `config`, and `critique` were being attached to the wrong internal command object, meaning they weren't properly registered under `auto-mode`. This has been fixed so they now work as expected.

**Why**

Before this fix, these subcommands could fail to run properly because of a plumbing mistake rather than any issue with what they were meant to do; now `claude auto-mode defaults`, `reset`, `config`, and `critique` work correctly.

- Area: Auto Mode
- Names: `claude auto-mode`
- Tier: You'll notice
- Useful: 3/5
- Signal: 1/5

### Marketplace attestation conflicts are now detected and dropped

Claude Code now detects and drops conflicting plugin marketplace attestations

**What**

A new check scans installed plugin sources and their `officialAttestation.marketplace` value (a claim about which marketplace officially vouches for a plugin). If that value conflicts with a value previously seen for the same source, or doesn't match any known marketplace, the source is removed from the map of accepted attestations.

**Why**

This prevents a plugin source from keeping an official-marketplace attestation that has become inconsistent or unverifiable, reducing the chance of trusting a plugin based on a stale or conflicting claim.

- Area: Plugins
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Process exit now waits for in-flight OAuth token refresh

Claude Code now waits for an in-flight OAuth token refresh to finish before exiting

**What**

If Claude Code is in the middle of refreshing its OAuth login token (the credential used to authenticate with Anthropic) when the process tries to exit, it now waits for that refresh to finish first, up to a timeout, instead of exiting immediately. If the refresh doesn't finish in time, Claude Code logs a message and records a telemetry event, then exits anyway.

**Why**

This avoids exiting mid-refresh, which could otherwise leave the saved credentials in an inconsistent state.

- Area: Auth
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### New "unknown_tools" error case for artifact MCP manifests

Publishing an artifact now fails clearly if its MCP manifest lists tool names the connector doesn't actually have

**What**

When publishing an artifact page whose manifest declares an MCP (Model Context Protocol) connector, Claude Code checks that the tool names listed for that connector actually exist. If they don't, publishing is now rejected with a specific `unknown_tools` error explaining that the `tools` field must list that connector's own top-level tool names, with a hint for connectors that work like an MCP gateway (a connector that itself exposes multiple underlying servers' tools).

**Why**

This gives a clear, specific error instead of a vague failure when an artifact's manifest references tools that don't exist in the current session, making it easier to fix the manifest.

- Area: Artifacts
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Plugin skills are now de-duplicated against user-level skills and other plugins by real path

Plugin skills are now skipped if the same skill already exists at the user level or in another plugin

**What**

When Claude Code loads skills (packaged instructions for a particular kind of task) bundled inside a plugin, it now checks whether that same skill file, resolved to its real underlying file path, is already loaded either as a personal user-level skill or by another plugin. If so, the duplicate is skipped rather than loaded twice, and a log message names which duplicate was skipped and why.

**Why**

This avoids the same skill appearing more than once when it's reachable through multiple paths, such as a symlink, which previously could have caused confusing duplicate entries.

- Area: Skills
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Image handling: specific decode-failure diagnostics for CMYK JPEGs and animated WebP

Claude Code now gives specific error messages for CMYK JPEGs and animated WebP images it can't decode

**What**

When an image fails to decode, Claude Code now checks for two specific cases and reports a tailored reason instead of a generic failure message:

- a CMYK JPEG (a JPEG using a four-color printing color model instead of the usual RGB), reported as "it is a CMYK JPEG, which Claude Code cannot decode"

- an animated WebP file, reported as "it is an animated WebP whose first frame Claude Code cannot decode"

**Why**

This makes it clear why a particular image failed to load, so a user can tell the problem is a specific unsupported format rather than a generic error, and can convert the image accordingly.

- Area: Images
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### realpath resolution now falls back to a 'launch ancestry' path when EPERM/EACCES occurs

Path safety checks now fall back to a shared-ancestor path if the OS blocks realpath resolution

**Unclear.** The finding marks this fallback path itself as 'unverified', so how reliable it is in practice is unclear.

**What**

Claude Code resolves file paths using a system call that also checks whether a path is actually a symlink pointing somewhere unexpected. When that system call fails with a permissions error (EPERM or EACCES), Claude Code now tries a fallback: it computes the common ancestor directory between the current working directory and the 'launch' path (the directory Claude Code was started from), and re-runs its symlink-safety checks using that ancestor path instead of giving up immediately.

**Why**

Previously a permissions error during this check would simply fail. The fallback lets Claude Code keep working in more restrictive environments instead of erroring out.

- Area: File System
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Symlinked .git worktree detection: dotted-git-target check added

Git repo root detection adds a check for a symlinked .git target before falling back

**What**

When Claude Code determines the root directory of a Git repository, it now performs an additional check: whether the path formed by joining a candidate directory with `.git` resolves back to that same directory. If so, that directory is returned as the repo root. This check runs before the existing fallback logic.

**Why**

This affects how Claude Code identifies the repository root in setups where `.git` is a symlink, such as certain worktree configurations, changing which directory gets treated as the root in those cases.

- Area: Git
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Verify-diagnostics entry truncation no longer stops early

Verify-diagnostics results no longer stop early when one entry is too big to fit

**What**

When Claude Code packs diagnostic entries into a tool result that has a size limit, it used to stop adding entries entirely as soon as one entry was too large to fit. Now it skips that oversized entry and keeps going, so smaller entries later in the list can still be included.

**Why**

This means a single large diagnostic entry no longer causes every entry after it to be dropped, so the result can include more of the useful, smaller diagnostics instead of truncating early.

- Area: Artifacts
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### MCP client tool lists refresh after reconnect, with new timing telemetry

MCP tool lists now refresh automatically after a server reconnects

**What**

When an MCP (Model Context Protocol) server reconnects, Claude Code now re-fetches that server's list of tools and merges them back into the available tools, tracked through a new pending-refresh set. The code also adds timing markers around the tool setup step to measure how long it takes.

**Why**

This keeps the available tool list accurate after a reconnect, so tools from a server that dropped and came back are properly refreshed instead of possibly going stale.

- Area: MCP
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Publish file-map validation errors now name the actual base directory instead of a fixed phrase, and gained a 'pass a relative path' hint

Publish validation errors now name the real base folder and suggest using a relative path

**What**

When publishing files (for example, to an artifact or site) fails because a file falls outside the allowed folder, the error message used to always say "the working directory" no matter what folder was actually being used. Now it names the actual base folder the publish was rooted at. These errors also gained a new hint suggesting the reader pass a relative path instead.

**Why**

The old wording could be misleading if the publish base wasn't literally the working directory, making it hard to understand why a file was rejected. Naming the real folder, plus the added hint, makes it clearer how to fix the path.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Workflow resume now validates the target run before compiling the script

Resuming a workflow now checks the target run is actually finished before compiling its script

**What**

When resuming a workflow by its run ID, Claude Code now checks upfront whether that run is still active - either "running" or "paused" without having actually exited - and refuses to resume if so, with the message that resuming now would run two copies of its agents against the same journal. It also now waits for the run's journal to finish being written before proceeding. Previously, this check only happened after the workflow script had already been compiled.

**Why**

Checking earlier avoids wasted work compiling a script for a resume that's going to be rejected anyway, and prevents accidentally running two sets of agents against the same underlying run at once.

- Area: Workflows
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### WorktreeCreate hook failure no longer throws when no hook is configured

Creating a worktree no longer errors when no WorktreeCreate hook is configured at all

**What**

When Claude Code creates a git worktree (a separate working copy of a repository, used for isolated sessions), it can run a `WorktreeCreate` hook beforehand. Previously, if that hook produced zero commands to run, Claude Code always threw an error saying "hook is configured but did not run." Now it first checks whether any `WorktreeCreate` hook is configured at all; if none is configured, it silently continues instead of erroring, and only throws that error when a hook actually is configured but failed to run.

**Why**

This stops Claude Code from throwing a confusing "hook is configured but did not run" error in the common case where a user simply hasn't set up a `WorktreeCreate` hook. The error is now reserved for the case it actually describes: a configured hook that didn't run, for example because the workspace isn't trusted or its matcher didn't apply.

- Area: Worktrees
- Names: `WorktreeCreate`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Plugin path-not-found errors now surface the underlying errno

Plugin path-not-found errors now include the underlying system error code

**What**

When a plugin or marketplace manifest references a path that can't be found and there's an associated system error number (errno), the error message now includes that errno and suggests checking for self-referential symlinks, broken network mounts, or permissions problems, then running `/reload-plugins`. The error message also now distinguishes a genuine "path not found" from a case where the path couldn't even be checked in the first place (a stat error), reporting the errno for that case too.

**Why**

Including the actual errno and separating "not found" from "couldn't be checked" gives much more specific information for diagnosing why a plugin path is broken, instead of a generic not-found message that could mask the real cause.

- Area: Plugins
- Names: `/reload-plugins`
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### URLs with embedded credentials now rejected

URLs containing a username or password, like user:pass@host, are now rejected during normalization

**What**

A URL-handling function that previously accepted any `http` or `https` URL now rejects URLs that embed a username or password, such as `user:pass@host`. Instead of processing the URL, it returns nothing.

**Why**

URLs with embedded credentials can leak sensitive information or be used to disguise the real destination of a link. Rejecting them closes off that risk.

- Area: Permissions
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Screenshot tool now returns correctly namespaced media type

Fixed a bug where the screenshot tool returned an incomplete media type instead of a proper one like image/png

**What**

The built-in screenshot tool now correctly returns a full media type such as `image/png`, instead of just the raw suffix on its own. This also fixes related mix-ups where the tool's returned path and base64 image data were not being passed back correctly.

**Why**

A malformed media type could cause screenshots to be misinterpreted or rejected downstream, so this fix makes screenshots taken by Claude Code display and pass through correctly.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Legacy HTTP+SSE MCP transport gets a guarded OAuth-avoidance dial path

Older MCP servers using the legacy HTTP+SSE protocol no longer get wrongly prompted into an OAuth login flow

**What**

For MCP servers (external tools Claude Code connects to) that use the older HTTP+SSE connection method rather than newer transports, Claude Code now checks whether a 401 "unauthorized" response on the connection request really means the server wants OAuth login. If the server's earlier setup request didn't return a 405 "method not allowed" response, the 401 is treated as a genuine OAuth prompt. If it did return 405, Claude Code now refuses to start an OAuth flow at all.

**Why**

This avoids incorrectly launching an OAuth sign-in flow against MCP servers that don't actually require one, which previously could have interrupted the user with an unnecessary login prompt.

- Area: MCP
- Tier: You'll notice
- Useful: 2/5
- Signal: 1/5

### Early no-op success result now carries send-echo fields

Early no-result success responses in headless turns now include the same send-echo timing fields as normal results

**What**

When a headless turn ends immediately without actually querying the model (an early success case with no real turns taken), the result it returns now includes the same send-echo fields that normal results carry. Previously this early-exit case only returned the plain result text with none of those extra fields.

**Why**

This makes the shortcut, zero-turn success response consistent with normal results, so anything reading these fields (such as timing data) gets them even in this early-exit case.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Model-switch confirmation now waits for save-as-default to complete before showing final message

Model-switch confirmation now waits for the save-as-default write to finish before claiming success

**What**

When switching models through the model picker, Claude Code now shows a loading state while it waits for the choice to be saved as the default for new sessions. The confirmation message only says the model was "saved as your default for new sessions" once that save has actually completed successfully.

**Why**

Previously the confirmation could claim the save succeeded before the write was actually done, which risked telling the reader something had been saved when it hadn't finished yet.

- Area: Models
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Interrupted-turn tool-use answers now also suppressed from re-prompting via answeredToolUseIds

Resuming an interrupted turn now also skips re-prompting for tool uses listed in answeredToolUseIds

**What**

When Claude Code resumes a conversation turn that was interrupted, it keeps track of which tool uses (individual tool calls) have already been answered so it doesn't ask about them again. Previously this set only included tool-use ids from the resumed turn's tool list and any currently pending permission request. Now it also includes every id listed in `answeredToolUseIds`.

**Why**

This should prevent Claude Code from re-prompting for permission on tool calls that were already answered before an interruption, avoiding redundant or confusing repeat prompts.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Verify tool now refuses url-less calls for delegated-observation agents

The verify tool now rejects url-less calls made on behalf of delegated observation agents

**What**

The `verify` tool, used to check a published artifact, now blocks calls that leave out the `url` parameter when the call comes from a delegated-observation agent context. Previously there was a fallback that would check the most recently published artifact if no url was given; that fallback is not available to this kind of agent, so the call is now refused with a message explaining that the artifact url must be passed explicitly.

**Why**

This prevents a confusing failure where a delegated-observation agent would rely on a fallback that doesn't actually work for it, and instead gives a clear, immediate error telling it to pass the url directly.

- Area: Artifacts
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### OAuth refresh-lock telemetry no longer crashes the release path

A telemetry failure can no longer block releasing the OAuth token refresh lock

**What**

When Claude Code releases its internal lock on refreshing an OAuth authentication token, it emits telemetry events for 'releasing' and, on error, 'release_error'. Both of these telemetry calls are now individually wrapped in their own error handling, so a failure in sending the telemetry itself can no longer prevent the lock from actually being released or the error from being logged.

**Why**

This is a reliability fix: previously, a telemetry hiccup during token refresh could interfere with releasing the lock or recording the error, which could affect authentication flows. Now the telemetry is best-effort and can't get in the way.

- Area: Auth
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### New SSE POST error classifier to distinguish real failures from benign JSON-RPC responses

Claude Code now tells apart real SSE connection failures from harmless error-looking responses

**What**

When posting to an MCP server's streaming endpoint (SSE, a way servers push data over an HTTP connection) fails with an HTTP 400, 404, or 405 status, Claude Code now looks inside the response body to check whether it's actually a harmless JSON-RPC response with a null ID, rather than a real connection failure.

**Why**

This avoids treating a technically error-coded but benign server response as a genuine connection problem, which should cut down on false failure reports for some MCP servers.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Windows-reserved-name protection extended to generic identifier sanitizer

The general-purpose name sanitizer now avoids producing Windows-reserved names like CON or NUL

**What**

Claude Code's general-purpose function for cleaning up identifiers, such as those used for artifact or file names, now checks whether the cleaned-up result matches a name Windows reserves for devices (`CON`, `PRN`, `AUX`, `NUL`, `COM1`-`COM9`, `LPT1`-`LPT9`). If it does, an underscore is added to the front of the name.

**Why**

Windows treats these names specially and can fail to create a file or folder with one of them, so this prevents Claude Code from generating an identifier that would break on Windows.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Cancelling with an empty prompt in remote mode now cancels held remote messages

Pressing cancel on an empty prompt in remote mode now cancels any held remote messages

**What**

When you press cancel with an empty prompt while a session is in remote mode, Claude Code now cancels any messages that were being held for remote delivery, instead of doing nothing in that situation.

**Why**

This gives you a way to clear out pending remote messages by cancelling on an empty input, rather than that action being a no-op with no visible effect.

- Area: Sessions
- Tier: You'll notice
- Useful: 1/5
- Signal: 1/5

### Permission-negotiation ordering fix: abort now takes priority over the 'session committed' hang

Fixed an ordering bug so cancelling a tool permission request no longer gets stuck behind a 'session committed' check

**What**

When Claude Code decides whether to run a tool, there's a shared internal check for whether the session has already been "committed" to an answer; if so, it used to return a promise that never resolves, effectively hanging that path. Previously, the abort (cancel) path used a differently named function for this, and the order of checks meant a cancellation could still get caught by the "already committed" hang. Now both the abort path and the normal path use the same function, and the check for an abort signal runs before the "already committed" check.

**Why**

This fixes a case where cancelling a tool permission request (like denying a tool from running) could hang instead of completing, by making sure an abort is always honored ahead of the session-committed state.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Interrupt handling: variable fix in queued-interrupt path

A queued-interrupt code path now stores the correct variable instead of a mismatched one

**Unclear.** The finding doesn't state what the old, incorrect variable caused to go wrong in practice.

**What**

In the part of interrupt handling that runs when there's no live session, the value saved into `pendingInterrupt` was changed from one local variable to a different one.

**Why**

This looks like a correctness fix ensuring the right interrupt value is queued and later acted on when no live session is present.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Bug fix: worktree cwd-access error used wrong exception variable

Fixed a bug where a working-directory access error showed the wrong variable in its message

**What**

When Claude Code's CLI setup failed to access a git worktree's working directory, the error message it printed was mistakenly built from an unrelated outer variable instead of the actual error that was caught. This has been fixed so the message now correctly reflects the real error.

**Why**

The error message shown to users in this failure case will now actually describe the problem that occurred, instead of showing incorrect or misleading text.

- Area: Worktrees
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### Import command dedupes 'Review these' warnings

/import no longer repeats the same warning multiple times in its 'Review these:' list

**Unclear.** The `tengu_import_apply` gate mentioned alongside this change is unread, so nothing can be said about whether it is switched on.

**What**

When `/import` applies imported configuration and shows a 'Review these:' list of warnings, it now collects those warnings into a set that removes duplicates before displaying them, rather than a plain list that could show the same warning text more than once.

**Why**

If multiple imported items produced the same warning, you previously would have seen it repeated; now each distinct warning is shown only once, making the review list easier to read.

- Area: Internals
- Names: `/import`
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### Model names are now normalized (trimmed + lowercased) when resolving a session model

Model names are now trimmed and lowercased when Claude Code resolves which model a session uses

**What**

When Claude Code figures out which model a session should use, any resolved model name that comes back as a string is now cleaned up: extra whitespace is trimmed and the name is converted to lowercase before being used.

**Why**

This avoids mismatches caused by stray spaces or inconsistent capitalization in model names, so a model reference is recognized correctly regardless of how it was typed or supplied.

- Area: Models
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### Likely bug fix: postKeptResponse referenced the wrong variable

Fixed a bug where a remote session's postKeptResponse used the wrong response data

**What**

In the code that manages remote sessions, a method called `postKeptResponse` was sending a control response built from a variable belonging to an outer, unrelated scope instead of its own parameter. It now correctly uses its own parameter's data when sending the response.

**Why**

This was a bug that could cause the wrong response data to be sent back for a kept response in a remote session; fixing it ensures the response actually sent matches the one that was meant to be kept.

- Area: Sessions
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### Diff-hunk generation now skips non-regular files instead of marking them 'restricted'

Diffing uncommitted changes now silently skips symlinks and other non-regular files

**What**

When Claude Code computes diff hunks to show context about uncommitted changes, files that aren't regular files (such as symlinks or device files) are now classified as `not-regular-file` and skipped silently. Previously, these files were grouped into a 'restricted' list, which meant they were surfaced to the user.

**Why**

This keeps diff output focused on actual file changes, quietly leaving out entries for symlinks and similar special files instead of flagging them as restricted.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### Tabs component gains a stable-height mode, used to fix Settings/Gates panel jitter

Settings and Gates panels no longer jitter thanks to a new stable-height mode for tabbed panels

**What**

The shared tabbed-panel component used across Claude Code's UI now supports a `stableHeight` mode with a `contentHeight` setting. When enabled, the content area uses a fixed height instead of a flexible maximum height. The Settings dialog now turns this on, with its height calculated to fit within the terminal window.

**Why**

This fixes visual jitter in the Settings and Gates panels, where the panel's size used to shift as you switched between tabs with differing amounts of content.

- Area: UI Components
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### Theme picker now cancels its preview on unmount

Closing the theme picker now always cancels its live preview, even if closed unexpectedly

**What**

The theme picker now cancels its in-progress theme preview whenever the component is removed from the screen, in addition to the existing cases where cancelling was already handled explicitly.

**Why**

This prevents a theme preview from being left active if the theme picker closes in a way that wasn't already covered by explicit cancel handling, avoiding a stuck or lingering preview state.

- Area: Elsewhere
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### Bug fix: SessionsV2Client.postEvents read the wrong variable for sequence_num

Fixed a bug where session event posting logged the wrong sequence number

**What**

The internal function that posts session events (`SessionsV2Client.postEvents`) was reading the `sequence_num` value from the wrong variable — one that wasn't the actual result returned by the request. It now correctly reads `sequence_num` from the parsed result.

**Why**

This fixes incorrect sequence numbers being recorded for session events, which could otherwise throw off anything that relies on events being tracked in the right order.

- Area: Session Management
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### Remote headless client host-request logger bug fix: correct outcome value now logged

Fixed a bug where the remote headless client's request logger recorded the wrong outcome value

**What**

An internal logging helper used by the headless (non-interactive) cloud client was recording telemetry with an `outcome` value taken from an unrelated outer-scope variable instead of the actual outcome parameter passed into the function. It now correctly logs the outcome that was actually passed in.

**Why**

This fixes inaccurate outcome data being recorded for host requests made by the remote headless client, which would have made related telemetry unreliable.

- Area: Telemetry
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

## In Development

### Directory/file sync engine gains a distinct 'muted' state

Directory/file sync now has a distinct 'muted' state, separate from shutdown or another-writer conflicts

**What**

The engine that syncs project directories and files now tracks a 'muted' state as its own distinct condition, separate from shutdown or another window/session writing elsewhere. When muted, a sync pass returns early without treating the watcher as unhealthy or logging a retry warning, unlike other paused states such as `held_for_command`. The status shown to the user and the underlying status data both now carry this muted flag, with a message about an 'emergency switch' pausing sync on that machine.

**Why**

This gives Claude Code a clean way to represent a sync pause that was triggered externally, so the UI and internal health checks don't mistake it for an error or a conflict with another session.

- Area: Cloud Sync
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Artifact tool actions being consolidated into list/read with a scope parameter

Artifact tool messages now describe actions as unified list/read calls with a scope, not old per-type names

**Unclear.** The gate `tengu_cobalt_plinth_damson` behind this change last read off for this site's account and off for the anonymous baseline, with no reading yet under this release; the related `tengu_artifact_toolset` gate is unread, so nothing can be said about whether either is switched on.

**What**

When Claude Code's artifact tools (used for uploading, listing, deleting, and reading files attached to a conversation) report results back, the text shown now uses a smaller set of action names. Instead of separate names like `list_assets`, `read_file`, and `list_files`, results now describe a unified `list` action or a unified `read` action, with a `scope` (such as `assets` or `files`) or a `path` telling you what it acted on. This affects the result text from `asset_upload`, `asset_list`, `asset_delete`, `file_list`, and `file_read`.

A related guidance change updates the instructions for finding older artifacts: instead of the old two-step `list_files` then `read_file` sequence, guidance now points to `list` with `scope: "files"` followed by `read` with a `path` argument.

**Why**

This is a wording and structure change in how artifact actions are named and described, continuing a consolidation of artifact tool actions into fewer, more general names.

- Flag `tengu_cobalt_plinth_damson`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: off, compiled default: off)
- Area: Artifacts
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### MCP config building gets a new 'five-class' entries cache, gated off by default

MCP config building gets a new caching layer, currently unread/off

**What**

A new memoized (cached) value is now computed for MCP server (Model Context Protocol, a way of connecting external tools) configurations, using an `afterStartup: true` option, and it feeds into the hook that manages MCP connections. The underlying function only does anything beyond passing its input through unchanged if a related switch is turned on.

**Why**

As described, this adds caching infrastructure for MCP server configs, but by default the new function is a no-op, so no behavior changes unless the switch is enabled.

- Flag `tengu_cobalt_plinth_loquat`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Area: MCP
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### SDK MCP servers can now hand over a pre-captured manifest instead of handshaking live

SDK MCP servers can now skip live handshakes by supplying a pre-captured manifest at initialization

**What**

When starting an SDK MCP server (a Model Context Protocol server run through the SDK), Claude Code's `initialize` control request can now include `sdkMcpServerManifests` — a description of a server's capabilities captured ahead of time. Servers that provide a valid, correctly versioned manifest this way skip the usual back-and-forth handshake over the control channel and are registered directly from the manifest.

If a manifest is malformed, missing required fields, or built against a different MCP protocol version than expected, Claude Code ignores it, logs the problem, and falls back to having that server handshake live as before.

**Why**

Skipping the live handshake for servers that already have a valid manifest can make startup faster and more predictable, while the fallback ensures a bad or outdated manifest doesn't silently break a server's connection.

- Area: MCP
- Names: `sdkMcpServerManifests`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Artifact-DB "MCP switch" latched behind tengu_cobalt_plinth_loquat, off by default

A new, currently unread 'artifact MCP switch' can route artifact tools through an MCP-server path instead of building entries directly

**What**

Claude Code has added internal groundwork for what its code calls the 'artifact MCP switch': a session-level setting that, when turned on, would route the artifact tool family through a Model Context Protocol (MCP) server path instead of the usual direct construction of tool entries. The setting is decided once per session and reported via telemetry.

**Why**

This is infrastructure for a future change in how artifact tools are wired up; nothing is known yet about whether it is active for any given account.

- Flag `tengu_cobalt_plinth_loquat`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Area: Artifacts
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Artifact reads gain a five-class consent latch

Reading someone else's shared artifact can now be auto-allowed via a remembered consent choice

**Unclear.** Whether this consent flow is active depends on the `tengu_lantern` and `tengu_artifact_five_class_asks` gates, which have not been read for this release.

**What**

When Claude Code reads an artifact someone else shared, it now checks for a per-conversation "class consent" setting. If that consent has already been granted, matching reads are automatically allowed with no prompt, showing the message "Reading ... needs no approval." Otherwise, the read goes through a new approval flow before falling back to the previous ask/deny logic. The wording used when describing this has also changed from "another person's artifact" to "someone else's artifact."

**Why**

This avoids repeatedly prompting for permission to read artifacts from the same source once the reader has already consented, while still asking the first time or when no such consent exists.

- Area: Artifacts
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### New PaneDock UI for docked side panes in the main transcript view

A new PaneDock layout can now dock side panes in the main transcript view

**Unclear.** The finding does not say what content this PaneDock actually displays.

**What**

The main transcript screen (where the conversation is shown) can now render a new `PaneDock` component alongside the existing content. Its width is calculated automatically, and it only appears when the terminal is in fullscreen mode, the main view is active, and no other dock is currently in use.

**Why**

This lays the groundwork for docking additional side panels into the main view, sitting alongside the existing IDE-selection panel infrastructure.

- Area: UI Panels
- Names: `PaneDock`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### New 'artifact summon forecast' preview when Claude is busy

Claude now previews whether it would be allowed to auto-reply to a new artifact comment while it's still busy

**Unclear.** The gate `tengu_madrone_spindle_newel` controlling this is unread for this release, so whether it is enabled here is unknown.

**What**

When a new comment or summon arrives on an artifact (a generated document or piece of content) while Claude is still busy handling something else, Claude Code now runs a quick permission-only check to forecast whether its eventual automatic reply would actually be allowed. It then posts an early status, either 'working' or a decline, instead of waiting until the busy work finishes to find out the reply was going to be blocked.

**Why**

This gives earlier, more accurate feedback about pending artifact replies instead of leaving the requester waiting only to learn later that permission would have been denied.

- Flag `tengu_madrone_spindle_newel`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: off, compiled default: not a boolean we can read)
- Area: Artifacts
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### New internal 'workspaceTrust' field on SDK initialize

SDK initialize gains an internal workspaceTrust field so a host app can pre-approve a directory's trust dialog

**What**

The SDK's session-initialize request now accepts an optional, internal-only `workspaceTrust` object with `accepted` and `directory` fields. This lets a host application (the example given is Claude Desktop's Code tab connecting over SSH or WSL) tell the Claude Code CLI that it already showed the user a trust dialog for the working directory, before the CLI process was even started.

**Why**

Normally Claude Code shows its own trust dialog the first time it opens a directory. This lets a host that already handled that confirmation pass it through, so the CLI records the directory as trusted the same way it would if the dialog had run locally, avoiding a redundant prompt.

- Area: SDK
- Names: `workspaceTrust`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Resume-return flow can reuse a precomputed compaction summary

Resuming a session can now reuse an already-computed summary instead of recalculating it

**Unclear.** No reading of any of these gates has been taken under this release, so their state in this version is unknown.

**What**

When Claude Code prompts you about resuming a session after a period of inactivity, it can now reuse a summary of the conversation that was already computed ahead of time (`hasPrecomputedSummary`), rather than recomputing it. This is controlled by a new gate, `tengu_gleaming_fair_reuse`, layered on top of the existing resume-notice feature. When reuse applies, the resume flow can skip a full recompute (`"skipped_no_summary"`) or detect that a precomputed summary has gone stale (`"summary_gone"`).

**Why**

Avoiding a redundant compaction pass (the process of condensing conversation history into a summary) when resuming should make the resume prompt appear faster in the cases where it applies.

**Gate state** `tengu_gleaming_fair` remains off by default and off for this site's account per the last reading, taken before this release; `tengu_gleaming_fair_reuse` was reading on for this site's account and off for the anonymous baseline, also before this release. No reading of either gate, or of `tengu_resume_return_action`, has been taken under this release yet.

- Flag `tengu_gleaming_fair`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: off, compiled default: off)
- Flag `tengu_gleaming_fair_reuse`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: off, compiled default: off)
- Area: Sessions
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Projects thread-state stamping on artifact comment replies, gate not in resolved table

New internal tracking of time and reply counts since the last human message, used for Projects artifact comment replies

**Unclear.** Whether this is active for any accounts is unknown; the related gates (`tengu_projects_thread_state_stamp`, `tengu_projects_thread_state`) haven't been read.

**What**

Claude Code now has a mechanism, referred to internally as `thread_state`, that stamps queued replies with how long it's been since a human last wrote a message and how many automated replies have happened since then. It's used when composing replies to comment threads on Projects artifacts sent via MCP (the protocol Claude Code uses to talk to external tools and services).

**Why**

The feature sits behind flags that haven't been read as on or off for this account, so it's not yet clear what behavior it enables for users.

- Area: Projects
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### iOS Simulator tip gated behind tengu_magical_pixel (default off)

A new tip about Claude Code Desktop's iOS Simulator pane is gated behind an unread flag

**What**

Claude Code can show contextual tips in the CLI. A new one, `desktop-ios-simulator`, tells users that Claude Code Desktop gives each session its own iOS Simulator pane. It only shows up when several conditions are all met: you're on macOS, the plugin/desktop feature is enabled, HIPAA mode is off, the session's detected intent includes building an iOS app, and an internal flag resolves true.

**Why**

This surfaces a Desktop-specific capability to relevant users at the right moment, rather than showing it broadly.

- Flag `tengu_magical_pixel`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Area: Claude Code Desktop
- Names: `tengu_magical_pixel`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### New "Pane" UI component/site type

A new "Pane" UI component type has been added, with its own tracking in app state

**Unclear.** What a "Pane" is used for or what it displays is not stated.

**What**

A new `Pane` component has been added to the recognized list of renderable components, mapped internally to a `PaneSite` identifier. App state now has a dedicated `panes` slot to track them.

**Why**

The finding does not say what a pane looks like or does on screen, only that the component type and its state tracking now exist.

- Area: UI Panels
- Names: `Pane`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### New per-org DB verbs / run-script capability gates for artifacts (default off)

New per-organization capability flags for database verbs and run-script support in Artifacts, off by default

**What**

A new gates system for Artifact tooling exposes two capability flags, `dbVerbsOn` and `runScriptOn`, controlling database-verb and run-script capabilities per organization. Both default to false until explicitly registered/enabled.

**Why**

This lays groundwork for organizations to selectively enable database-write verbs and script-running capabilities within Artifacts, but since both default off, no behavior changes until an organization is switched on.

- Area: Artifacts
- Names: `dbVerbsOn`, `runScriptOn`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Project thread recap feature gated off (tengu_projects_thread_recap)

A richer "recap" format for project task status is being built, gated off by default

**What**

A new function can present a project's task or thread status using a richer "recap" object, with a headline, what's needed, whether it needs you specifically, what happened, and a reply, instead of the older flat set of fields. This only activates under certain internal conditions and when the `tengu_projects_thread_recap` setting is turned on.

**Why**

Setting details map: nothing has been read about whether `tengu_projects_thread_recap` or `tengu_projects_thread_recap_prompt` is switched on, so this richer status format is not yet something readers should expect to see.

- Flag `tengu_projects_thread_recap`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Flag `tengu_projects_thread_recap_prompt`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: not a boolean we can read)
- Area: Projects
- Names: `tengu_projects_thread_recap`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Precomputed conversation-compaction rehydration, gated off

Claude Code can reuse a precomputed conversation summary instead of compacting fresh, gated off

**What**

Claude Code is building a way to reuse a conversation summary or "compaction" (the process that shrinks a long conversation to free up space) that was computed and cached ahead of time, rather than always running compaction fresh when it's needed. Before accepting a cached summary, it checks that it matches the right session and model, isn't too old, and that the token count didn't grow or shrink outside expected bounds; a mismatch on any of these (session, model, timestamp, age, growth, shrinkage, or a missing boundary marker) causes it to fall back to running compaction normally.

**Why**

The flag server currently returns this feature as off for this site's account (and off by default), so it isn't active yet, but it's designed to make compaction faster by reusing precomputed work when it's safe to trust.

- Flag `tengu_sepia_moth`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: off, compiled default: off)
- Flag `tengu_amber_packet`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: off, compiled default: off)
- Area: Compaction
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Artifact database write op gains str_replace, alongside set/update/delete/batch

Artifact database writes now support a str_replace operation alongside set, update, delete and batch

**What**

The artifact database's write system (the storage layer artifacts use to save documents) now recognizes a fourth kind of write operation called `str_replace`, alongside the existing `set`, `update`, `delete`, and `batch` operations. A `str_replace` request specifies a field, an old string, a new string, whether to replace all occurrences, and an idempotency key.

**Why**

This gives artifacts a targeted way to swap out a specific string within a field, rather than having to rewrite the whole document with `set` or `update`.

- Area: Artifacts
- Names: `str_replace`
- Tier: Nothing to try yet
- Useful: 3/5
- Signal: 3/5
- Present in the build but not switched on

### Pinning an artifact can auto-allow without asking under the five-class-asks experiment

Pinning someone else's artifact can now be auto-allowed instead of prompting, under an experiment

**Unclear.** Whether the `tengu_artifact_five_class_asks` experiment is active for any given user is unread and unknown.

**What**

The `pin` artifact tool (used to add an artifact to your own saved list) now has a new early check. When a certain artifact-consent experiment is active and the session isn't in plan mode, pinning an artifact you don't own is now automatically allowed, with the internal reason "Pinning someone else's artifact to the user's own list" - skipping the usual ask-or-deny step that used to handle all such pins.

Separately, the `delete` action for artifacts, when a related feature is turned on, now builds a more detailed classification of the request before deciding whether to ask for permission, rather than always falling back to a plain ask (which previously defaulted to declining if left unanswered).

**Why**

This reduces interruptions for what appears to be treated as a low-risk action - saving someone else's artifact to your own list - while other artifact actions like delete still go through more careful permission checks.

- Area: Artifacts
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### Watch tool can now auto-allow a no-op watch that 'arms no replies'

Watching an artifact that doesn't need reply permission is now auto-allowed without asking

**What**

Under the same artifact-consent experiment, starting a `watch` on an artifact that wouldn't require permission to reply to its comments (and has no existing ruling on it yet) is now automatically allowed, with the reason "Watching an artifact arms no replies", instead of going through the full ask/consent process.

**Why**

This cuts down on unnecessary permission prompts for watches that can't lead to Claude posting replies on your behalf, since there's nothing to approve in that case.

- Area: Artifacts
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### Adaptive websocket keepalive interval for Artifact live connections, config-gated and off by default

Artifact live-connection keepalive pings can now stretch out during idle periods

**What**

A new module can, when configured via a settings/remote-config key, stretch the ping interval used to keep Artifact websocket connections alive (both the presence-tracking socket and the live-subscribe socket) up to a longer 'idle keepalive' interval once a connection has been idle for a while, instead of always pinging at the normal fixed interval.

**Why**

Sending fewer keepalive pings during idle periods can reduce unnecessary network chatter for Artifact connections that aren't actively being used.

- Area: Artifacts
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### "advisor_tool" added to several telemetry/context-injection category sets

"advisor_tool" added as a new telemetry/context-injection category

**Unclear.** What event or feature the "advisor_tool" category actually classifies is not stated.

**What**

A new category token, `advisor_tool`, has been added to at least three internal lists used for categorizing telemetry and context-injection events, joining existing categories like `remote_session_change` and `workflow_size_guideline_change`.

**Why**

The finding does not say what triggers this category or what it is used to track, only that it now exists in these lists.

- Area: Advisor Tool
- Names: `advisor_tool`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 3/5
- Present in the build but not switched on

### New gate defined: message_threads

A new feature gate named message_threads was added to the internal gate table

**Unclear.** What message_threads actually enables is not described in this finding.

**What**

A new feature gate, `message_threads`, was registered internally alongside other existing gates in Claude Code's feature-gate table.

**Why**

This just adds the gate's definition; the finding doesn't describe what feature it controls or whether it's active for any account.

- Area: Message Threads
- Names: `message_threads`
- Tier: Nothing to try yet
- Useful: 1/5
- Signal: 3/5
- Present in the build but not switched on

### Bridge-initiated /clear can now auto-dismiss a pending local dialog, behind a kill-switch gate

A remote bridge session's /clear command can now automatically dismiss a local dialog blocking it

**What**

When a command sent from a remote 'bridge' session is a `/clear` command, Claude Code now recognizes this and automatically dismisses any dialog currently open in the local session, rather than leaving that dialog in the way. It also records a telemetry event when this happens.

**Why**

Previously, a local dialog box could block a `/clear` request coming from a remote session, leaving things stuck. This change lets that clear command go through without requiring someone at the local machine to close the dialog first.

- Area: Elsewhere
- Names: `/clear`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### SDK MCP update gains a retry-skip condition tied to a new gate

Claude Code now also skips waiting for an SDK MCP update to finish under an additional internal condition

**Unclear.** The finding does not say what the new condition (`Mp() && !Ji`) represents in user-facing terms.

**What**

When Claude Code updates an SDK MCP server (a Model Context Protocol server run through the SDK), it decides whether to wait for that update to finish before continuing, or to let it run in the background. Previously that decision only checked whether a retry had failed. Now it also skips the wait when a second, newly added internal condition is true.

**Why**

This affects internal timing only; a reader would not see it directly beyond Claude Code potentially proceeding without waiting on an SDK MCP update in more cases than before.

- Area: MCP
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### 'Emergency switch' wiring added to cloud file-sync push

Cloud file sync gains a live mute/recheck control tied to the tengu_violin_mute setting

**Unclear.** placeholder

**What

- Area: Cloud Sync
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### db_write schema gains as_level / as_level_confirmed fields

Artifact db_write validation gains new as_level and as_level_confirmed fields

**Unclear.** What as_level and as_level_confirmed actually represent or enable is not established by this finding.

**What**

The validation rules for the `db_write` artifact action now accept two new optional fields: `as_level` (up to 16 characters) and `as_level_confirmed`, in addition to the existing fields it already validated.

**Why**

This is internal validation groundwork; the finding doesn't say what these fields control or when they take effect for a user.

- Area: Artifacts
- Names: `as_level`, `as_level_confirmed`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### Live turn-state row gated behind an 'isTranscriptV2Enabled' check

The classic in-turn status row now only shows when a newer transcript display mode isn't already handling it

**Unclear.** Nothing here indicates whether the reader's own account will see the newer transcript display, since the gate that controls it is not addressed.

**What**

Claude Code's display of what it's doing mid-turn (a spinner or status line while it's working) now has two possible sources. A new component checks whether a `StateRowSourceContext` is already supplying status information (such as remote-connection or reply-channel state); if not, it falls back to showing the classic status row. A separate, newer live-status row is now shown only when `isTranscriptV2Enabled` is on.

**Why**

This is internal plumbing to avoid showing two status indicators at once as Claude Code's transcript display evolves. It shouldn't change what you see day-to-day, but it's part of the groundwork for a newer transcript rendering path.

- Area: Transcript
- Names: `isTranscriptV2Enabled`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

### New `attach` session-opener path with a `serveOnly` mode

A new 'attach' session-opening path supports a reduced serveOnly feature set

**Unclear.** What surfaces this new attach/serveOnly session path to users, and what it's for, is not shown by the finding.

**What**

A new way of opening a session, called `attach`, has been added. It supports a `serveOnly` mode that, when turned on, gives the session a smaller set of available features instead of the normal full set.

**Why**

The finding doesn't say what triggers this attach path or what a serve-only session is used for, so the practical effect on a reader isn't clear yet.

- Area: Cloud Sessions
- Names: `serveOnly`
- Tier: Nothing to try yet
- Useful: 2/5
- Signal: 2/5
- Present in the build but not switched on

## Internal Changes

### New "dev_intent" system message classifies conversations as iOS app development

Claude Code now internally flags conversations as iOS app development

**What**

A new internal system message, `dev_intent` with kind `ios_app`, is sent at most once per conversation when Claude has written, read, or run something iPhone-specific in Swift - for example editing a `.swift` file, in the main thread or a subagent, where the work is iPhone-specific rather than a macOS-only app or server-side Swift package. This lets hosts like Claude Code Desktop react to the detection, such as by showing the new iOS Simulator tip.

**Why**

This is the detection mechanism behind features like the iOS Simulator tip, letting Claude Code recognize iOS development work automatically rather than requiring the user to say so.

- Area: Claude Code Desktop
- Tier: Under the hood
- Useful: 3/5
- Signal: 3/5

### Hook engine reworked into explicit core/managed layering with unified result merging

Hook execution engine rebuilt with a clearer core/managed split and unified result merging

**What**

The internal system that runs hooks has been reorganized. It now clearly separates "core" hook handling from "managed" hook handling, and adds a merge step that combines results from multiple hooks - things like permission decisions, extra context to inject, and file paths to watch - using a priority order where a deny always beats an ask, and an ask always beats an allow. Classic shell-based hooks and newer function-based hooks are now handled through the same unified path, including tracking blocked commands and results tied to `WorktreeCreate` events (which fire when a worktree, an isolated copy of a repository, is being created).

**Why**

This is an internal restructuring that makes hook behavior more consistent regardless of whether a hook is a shell script or a function, and ensures that when multiple hooks weigh in on the same action, the strictest decision wins.

- Area: Hooks
- Names: `WorktreeCreate`
- Tier: Under the hood
- Useful: 3/5
- Signal: 3/5

### New telemetry: tether decision/outcome/echo-audit events

New telemetry events track the tether feature's threading decisions, outcomes, and echo audits

**Unclear.** Nothing has been read about whether tengu_curious_tower, tengu_tether_decision, tengu_tether_live_outcome, or tengu_tether_echo_audit is on or off for any account.

**What**

Three new telemetry event names were added alongside the new "tether" request-threading feature:

- one fired when deciding whether to create or continue a server-side thread

- one recording the final outcome of a live threaded request

- one auditing any divergence between the conversation turns sent and the turns echoed back by the server

**Why**

This telemetry supports monitoring the new tether feature's behavior and catching cases where what was sent doesn't match what came back.

- Flag `tengu_curious_tower`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: off)
- Area: API Protocol
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### Echo-audit diffing of received vs sent assistant turns

New audit compares assistant turns as sent versus as echoed back by the server, classifying any mismatches

**Unclear.** Nothing has been read about whether the tengu_tether_echo_audit gate is on or off for any account.

**What**

A new helper compares the shape of an assistant turn's content as it was sent against how the server echoed it back, and classifies any differences it finds: reordered content, a turn split into two, a dropped turn, added or dropped tool calls, a tool's name changing, content dropped by the caller, and similar cases. Results are reported through the `tengu_tether_echo_audit` telemetry event.

**Why**

This lets Claude Code detect and categorize cases where the server's record of a conversation turn doesn't match what was actually sent, as part of the new tether threading system.

- Area: API Protocol
- Tier: Under the hood
- Useful: 2/5
- Signal: 3/5

### Hook messages can now be deferred and released later in the REPL

Hook messages can now be held back and inserted into the transcript later instead of immediately

**What**

When a hook (an automated script that runs at certain points in a session) produces a message meant for the transcript, Claude Code can now hold that message back instead of showing it right away. New methods, `deferHookMessages` and `releasePendingHookMessages`, let the session controller queue up a hook's messages and only add them to the visible transcript when explicitly released later. This plumbing is threaded through session setup, clearing a conversation, and replying after a resume; in the tool-use context the same mechanism is called `deferSessionStartHooks`/`releaseDeferredSessionStartHooks`.

**Why**

This gives Claude Code control over the timing of hook output, so hook messages can be lined up with the right moment in a session rather than appearing as soon as the hook finishes.

- Area: Hooks
- Names: `deferHookMessages`, `releasePendingHookMessages`
- Tier: Under the hood
- Useful: 3/5
- Signal: 2/5

### New 'Claude Tag connector writes' system-prompt clause for Slack-delegated sessions

New system-prompt section eases write restrictions for sessions started from Slack

**What**

For sessions started from Slack (referred to internally as "Claude Tag"), the system prompt now includes a new "Claude Tag connector writes" section. It lists the tool name prefixes for that session's connector tools (tools linking out to other services via MCP, the protocol Claude uses to talk to external tools) and tells the model that writes made through those specific tools are not blocked merely because there's no visible user request behind them.

Hard blocks still apply regardless: exposing credentials or secrets, destructive actions, changing permissions, and messaging other people are still restricted.

**Why**

This lets Claude act more freely through a Slack session's own connected tools - for example, following up on a delegated task - without being blocked purely because the action wasn't triggered by a visible chat message, while keeping the more dangerous categories of action off-limits.

- Area: Slack Integration
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Prompt submission can now stamp thread state on cron-fired agent turns

Cron-triggered prompts can now stamp thread state onto the resulting agent turn

**Unclear.** What consumes the `thread_state` attachment or what practical difference it makes to a scheduled run isn't stated.

**What**

When a scheduled (cron) prompt fires and the session isn't a "peer" session, the command Claude Code enqueues now carries a `stampThreadState` flag, and a new `thread_state` attachment can be added to the message list while the prompt is processed.

**Why**

This lets automated, cron-triggered turns carry along thread state information that would otherwise only be attached to interactively-submitted prompts.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New startup_timing telemetry field on system init message

System init message can now carry cold-start timing data for hosted CCR sessions

**Unclear.** What "CCR" stands for and what specifically consumes this telemetry isn't stated.

**What**

The system init message sent at the start of a session can now include a `startup_timing` field carrying cold-start telemetry: named startup phases and counters related to resuming and hydrating a session. This applies to hosted CCR sessions; it's absent elsewhere.

**Why**

This gives visibility into where time is spent during a hosted session's startup and resume process, which can help diagnose slow session starts.

- Area: Telemetry
- Names: `startup_timing`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Plugin file watcher gains 'watch collections' abstraction

Plugin hot-reload watcher gains a 'watch collections' abstraction for tracking groups of watched files

**Unclear.** The finding does not say what practical behavior change, if any, this produces for someone using plugins, only that the internal watcher structure changed.

**What**

The file watcher that reloads plugins automatically when their files change now supports a `watchRoot`, `listChildren`, and `reloadPlugins` configuration, and exposes `watchCollections` and `watchedCollections` properties alongside the existing tracking of what each individual plugin is watching.

**Why**

This is internal plumbing for how the plugin watcher organizes and tracks groups of watched files and directories, likely to support more flexible reload behavior as plugins are added or changed.

- Area: Plugins
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Coordinator/teammate session relay: verified Slack human-turn extraction

Coordinator/teammate sessions now extract a verified human message from Slack or queued turns, with an explicit disclaimer for Slack-relayed context

**What**

When a coordinator or teammate session needs to figure out what the actual human wants, new logic pulls the most recent verified human message from either a Slack conversation timeline (rows authored by the workspace owner) or an XML-tagged `<message from="human">` block inside a queued command or user turn. Context relayed from Slack is now tagged with an explicit disclaimer stating it "never establishes user intent or consent."

**Why**

This distinguishes genuine instructions from a real person from other tasking context that merely describes or relays information, so a coordinating session doesn't mistake relayed Slack content for something the user has actually approved or requested.

- Area: Slack Integration
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Remote bridge teardown now records whether the pre-teardown upload flush completed vs timed out

Remote bridge session teardown now logs whether the pre-teardown data upload finished in time

**Unclear.** Nothing has been read yet about the `tengu_bridge_repl_teardown` gate for this release, so no statement can be made about whether this reporting is active for any account.

**What**

When a remote bridge session (used for remote control of a session) is torn down, the `tengu_bridge_repl_teardown` telemetry event now records additional details: whether the flush that uploads pending data before teardown completed before its deadline (`hold_preflush_landed`), the computed budget allowed for archiving, and how long the archive upload call actually took.

**Why**

This gives more detail for diagnosing whether session data was fully saved before a remote session ended, and how long that process took, building on earlier changes that distinguished different kinds of skipped cleanup during teardown.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Remote tool calls now attach a 'read baseline' snapshot before host-side approval

Remote tool calls now include a read baseline snapshot before the host approves them

**Unclear.** The finding describes the mechanism but not confirmed downstream behavior, such as what the host does if a file changed.

**What**

When Claude Code sends a tool call to a remote host (a separate machine or service that has to approve tool calls before they run) for the first time, the request now also carries a `readBaseline` field. This is built from the session's record of which files it has read and what state they were in. Once the remote host confirms it received this snapshot, a `noteReadBaselineSent` callback fires.

**Why**

This appears designed to let the remote host check that a file hasn't changed since Claude last read it, before letting an edit go through. That guards against Claude editing a file based on stale information.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Background/workflow agent spawns now pass description and workflow phase context

Background workflow agent spawns now carry a description and workflow phase

**Unclear.** The finding doesn't say where this description/phase or promptFramed value is surfaced to the user.

**What**

When Claude Code spawns a background agent as part of a workflow, the spawn call now includes `description` (taken from the agent's label) and `workflowPhase` (taken from the agent's phase). The progress updates sent for workflow agents also now include a `promptFramed` value.

**Why**

This gives background workflow agents more context about which workflow and phase they belong to, which should make their progress and purpose easier to track.

- Area: Background Agents
- Names: `workflowPhase`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Cloud gateway sign-in check reworked with desktop-app-aware error and new required flag

Cloud gateway sign-in check reworked with a clearer error and desktop-app-aware handling

**What**

Before using the Cloud gateway as its provider, Claude Code now checks three things instead of one: that the route is actually set to gateway, that there's no gateway authentication, and that no gateway server process is running. Previously it only checked a single administrator-policy condition.

The error message shown when not signed in now reads: "Not signed in to the Cloud gateway - run `/login`. (With `CLAUDE_CODE_USE_GATEWAY`, set `ANTHROPIC_BASE_URL` and `ANTHROPIC_AUTH_TOKEN`.)" — pointing to those environment variables as an escape hatch. It also now shows a distinct error when credentials are managed by the desktop app instead.

**Why**

This gives a more accurate check for whether the Cloud gateway is actually usable, and a clearer error message that tells users how to work around a sign-in problem using environment variables, or explains that their desktop app is managing credentials instead.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Cloud sync snapshot builder gains a heldTree parameter and basis-aware 'lacking' handling

Cloud sync snapshot builder adds a heldTree option for tracking which files are missing

**Unclear.** The finding doesn't say what `heldTree` represents conceptually or what user-visible effect this has on sync behavior.

**What**

The internal function that builds a git snapshot (covering checkout, head, basis, and parent commits) for cloud and remote sync now accepts a new `heldTree` option, which is validated as a git object id. It uses this to work out which file paths are "lacking" relative to both the basis and the held tree, adding an extra asynchronous check before deciding what stays staged.

**Why**

This refines how the sync process figures out which files are missing or need attention when building a snapshot, by comparing against an additional reference point (the held tree) rather than just the basis.

- Area: Cloud Sync
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### MCP prewait gains a waitRemoteServerNames option

MCP client wait step gains a waitRemoteServerNames option

**Unclear.** What waitRemoteServerNames actually does with the server names it's passed isn't stated.

**What**

Before dispatching a turn, Claude Code's command loop waits for MCP (Model Context Protocol) clients to be ready. That wait call now accepts a new `waitRemoteServerNames` option, alongside the existing `localOnly` and `waitForDeferrable` options.

**Why**

This suggests the wait step can now target specific remote MCP servers by name rather than only distinguishing local versus deferrable clients, though the finding doesn't say how the new option is used.

- Area: MCP
- Names: `waitRemoteServerNames`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Non-PreToolUse hooks can be routed through a new 'classic' hook chain

Non-PreToolUse hooks can now be routed through a separate 'classic' hook execution chain

**Unclear.** What determines whether an event is gated as a 'classic' hook, and what practical difference this makes for hook authors, isn't specified.

**What**

Claude Code's main hook-execution logic now checks, for hook events other than `PreToolUse` (which runs before a tool call executes and can block it), whether the event is gated as a "classic" hook. If so, it delegates to a separate function that runs managed and plugin hook handlers on their own and merges the results back in, then re-enters the main hook logic marked as part of that classic chain.

**Why**

This adds a distinct execution path for certain hook events, letting managed and plugin hooks be processed separately before being merged with normal hook results.

- Area: Hooks
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Functionhooks event registry expands: ui.open/ui.close, command.run/command.describe, classic.PreToolUse

Hooks system adds ui.open/ui.close and command.run/command.describe event types, and renames PreToolUse internally

**Unclear.** What triggers ui.open/ui.close and command.run/command.describe, and whether these are usable by end users yet, isn't stated.

**What**

Claude Code's internal hooks system (which lets external scripts run in response to specific events) now includes new event types: `ui.open`, `ui.close`, `command.run`, and `command.describe`. The existing `PreToolUse` event (which runs before a tool call executes and can block it) has been renamed internally to `classic.PreToolUse`, though it still behaves the same way.

**Why**

This expands what hooks can react to, adding events tied to UI opening/closing and command execution/description, alongside the existing tool-call hooks.

- Area: Hooks
- Names: `ui.open`, `ui.close`, `command.run`, `command.describe`, `classic.PreToolUse`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Turn-stream user_message_uuid stamping extended for mid-turn folded prompts

SDK streaming protocol documents how mid-turn folded-in messages get stamped with a user_message_uuid

**What**

The SDK's streaming protocol documentation for `user_message_uuid`/`user_message_uuids` (identifiers used to match streamed events back to the user message that triggered them) was rewritten to cover a new case: when a turn is started by a synthetic (system-generated, not user-typed) prompt, and a queued user message gets folded into that turn partway through, the first non-ping stream event after that fold-in now gets stamped with the echoed identifier, in addition to the turn's very first event. A turn started by a normal typed prompt still only stamps its first event.

**Why**

This lets SDK clients correctly associate stream events with the right user message even when messages get merged into an already-running turn, rather than only being able to track the turn's initial trigger.

- Area: SDK
- Names: `user_message_uuid`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Session event stream can connect in control-only mode

Session event stream connections can now request a control-only mode that skips the full event feed

**What**

When a client connects to a session's events stream with `controlOnly` configured, it now appends a `control_only=1` parameter to the connection URL, subscribing only to control messages instead of the full stream of session events.

**Why**

This lets a client that only needs to send or receive control messages, rather than the complete event feed, use a lighter-weight connection.

- Area: Sessions
- Names: `control_only=1`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Task/agent orchestration state gains teamContext and ultraplanSessionUrl tracking

Internal task-orchestration state now tracks team context and an ultraplan session URL

**Unclear.** What teamContext and ultraplanSessionUrl represent, and what a user would see change because of this, are not shown by the evidence.

**What**

Claude Code's internal state bridge for managing tasks and subagents (background work items and the specialized agents that handle them) now includes a `setTaskKillState` updater that specifically tracks changes to `teamContext` and `ultraplanSessionUrl`, alongside existing accessors for the current model, the task list, and a registry of named agents.

**Why**

This is internal bookkeeping. The evidence doesn't say what a reader would notice differently as a result.

- Area: Elsewhere
- Names: `teamContext`, `ultraplanSessionUrl`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New `workspace_trust_recorded` field in initialize response, marked @internal

Session startup response now internally reports whether workspace trust was actually saved

**What**

When a Claude Code session starts up (via the SDK or CLI), the initialization response now includes an internal `workspace_trust_recorded` field. It reports `true` if the session's workspace trust decision (whether you've told Claude Code this folder is safe to work in) was actually saved as a trusted directory, or a falsy result if nothing durable was recorded — for example, because the path is obfuscated, reached over a network path, not a real directory, keyed wrong, failed to write, or because it's a home-directory session where trust is only kept for that session.

**Why**

This field is marked internal-only, so it's not something end users interact with directly, but it gives tooling built on Claude Code visibility into whether a workspace trust decision actually persisted or silently didn't.

- Area: Workspace Trust
- Names: `workspace_trust_recorded`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### RemoteSessionManager tracks and reports 'withholdable held' sends

Remote session manager now tracks and reports which held sends can be safely cancelled

**What**

For sessions run through remote infrastructure, messages can be held or queued before being sent. The `RemoteSessionManager` now tracks whether any held send is "withholdable" — meaning it hasn't been issued yet and can be released or cancelled without side effects — via a new `tellWithholdableHeld()` method called whenever a held send is released, gated, withdrawn, or settled. It also gained `hasWithholdableHeldSend()` and `cancelHeldSends()` methods, and fires a new `onWithholdableHeldChanged` callback whenever the set of cancellable held sends changes.

**Why**

This lets code that manages remote sessions detect when there are pending sends that can be safely bulk-cancelled, rather than having to guess or track this by hand, which should make cancelling stale or unwanted queued messages more reliable.

- Area: Sessions
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Tool execution context exposes new capabilities: file history, dedup, isolation latch

Tool execution context gains new internal capabilities for file history, read deduplication, and isolation

**Unclear.** What most of these new fields (agentWorktree, isolationLatch, turnMcpClients, etc.) actually enable for tools is not shown by the evidence.

**What**

The internal context object passed to tool calls (the data each tool gets access to when it runs) gained a batch of new capabilities, including:

- `agentWorktree`, `readFileState`, `getFileHistoryState`, and `applyFileHistoryOp`, for tracking and modifying file history

- `dynamicSkillDirTriggers` and `nestedMemoryAttachmentTriggers`, related to skills and memory attachment

- `dedupUnchangedReads`, `setArtifactReadVersion`, and `getArtifactReadObservation`, related to deduplicating unchanged file reads

- `turnMcpClients` and `isolationLatch`

**Why**

This is internal plumbing that expands what tools can access during execution. The evidence doesn't describe a user-visible behavior change beyond what's already documented for `dedupUnchangedReads` (which lets an individual read opt out of the existing suppression of re-reads of unchanged files).

- Area: Tooling Architecture
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### User message schema gains an internal file_attachments field

User messages in the SDK now support an internal file_attachments field

**What**

The schema for user-role messages used by the Claude Code SDK now accepts an optional `file_attachments` array. Each entry can include `file_uuid`, `file_name`, `is_image`, `sha256`, and `file_size`, matching the shape already used by `SDKUserMessageReplay`.

**Why**

This appears intended for remote clients that need to attach files to a prompt, giving them a defined structure for describing attached files alongside a message.

- Area: SDK
- Names: `file_attachments`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Hook events: PreToolUse split into classic vs. new, and two new synchronous hook events added

PreToolUse hooks are now split into a classic and new form, plus two new synchronous hook events

**Unclear.** What distinguishes the new 'classic.PreToolUse' from a non-classic PreToolUse, and what command.run/command.describe hooks are used for, is not explained in the finding.

**What**

The logic that warns when a hook blocks a turn now specifically matches `classic.PreToolUse` rather than a plain `PreToolUse` event, implying `PreToolUse` (a hook that runs before a tool call executes and can block it) now has both a classic and a newer variant. Two new events, `command.run` and `command.describe`, have also been added to the set of hook events where submitting mid-hook will wait on the current turn to finish.

**Why**

This affects how hooks interact with turn timing: hooks tied to `command.run` and `command.describe` now behave like other turn-blocking hook events, so anything relying on those events should account for that wait.

- Area: Hooks
- Names: `classic.PreToolUse`, `command.run`, `command.describe`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Hook registry gains command.describe as a core hook event

Claude Code adds a new internal hook event called command.describe

**Unclear.** What functionality actually uses the new command.describe hook is not established by this finding.

**What**

Claude Code's internal hook system (the machinery that lets different parts of the app react to events) now includes a new core event named `command.describe`, alongside existing ones like `agent.offer`, `tool.describe`, `session.start`, and the `turn.start`/`turn.step`/`turn.complete` events.

**Why**

This is internal plumbing rather than something a reader interacts with directly. It suggests Claude Code now has a defined point for describing commands, similar to how it already describes tools, but the finding doesn't say what consumes this event yet.

- Area: Hooks
- Names: `command.describe`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Headless MCP prewait can now wait for specific remote MCP servers by name, not just local-only

Headless MCP startup wait can now target specific named remote servers, not just local ones

**What**

The headless-mode wait-for-MCP-servers-to-be-ready logic now accepts a `waitRemoteServerNames` option. Combined with the existing `localOnly` setting, this lets Claude Code also wait on specific named non-local (remote) MCP servers, rather than only being able to wait for local servers. Telemetry for this wait (`tengu_headless_mcp_prewait`) gains two new fields, `remoteByNamePendingBefore` and `remoteByNamePendingAfter`.

**Why**

In headless mode, this lets a run wait for particular remote MCP servers it depends on to finish connecting before proceeding, rather than only being able to wait on local ones.

- Area: MCP
- Names: `waitRemoteServerNames`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### SDK query() now supports a separate stdin lane alongside the initial prompt

The SDK's query() function can now take a live stream of input separately from the initial prompt text

**Unclear.** The finding does not say what user-visible behavior, if any, changes as a result of separating these two input paths.

**What**

The Claude Agent SDK's `query()` function builds the connection used to talk to Claude Code programmatically. Internally, it now keeps the initial text prompt separate from a raw stream of additional input (an async iterable or generator) instead of forcing everything into a single combined stream before sending it off.

**Why**

This is an internal plumbing change for SDK integrations that feed input as a stream rather than a single string; it should make that kind of streaming input more reliable to construct.

- Area: SDK
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Project memory read route added, refuses over CCR bridge

A new route lets Claude Code read a project's stored memory, but not when connecting through the CCR bridge

**Unclear.** What "melange_memory" and "project_memory_list" are used for elsewhere, and what the CCR bridge is, are not explained in the finding.

**What**

Claude Code can now fetch a project's memory (referred to internally as "melange_memory") via a `GET /detail?include=melange_memory` request, feeding a `project_memory_list`. This read is explicitly refused when a certain bridge condition is active, described as the "CCR bridge."

**Why**

The restriction means that if you're connecting through the CCR bridge, this new project-memory read simply won't be available, so behavior may differ depending on how your session is connected.

- Area: Project Memory
- Names: `project_memory_list`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### iOS/Swift developer-intent detection added to session telemetry

Claude Code now detects when you're building an iOS/Swift app and logs that as a telemetry signal

**Unclear.** The finding doesn't say what this telemetry signal is used for beyond being recorded.

**What**

Claude Code now watches for signs that you're working on an iOS app: edits to `.swift` files, Bash commands that look like `simctl` or `xcodebuild` (Apple's simulator and build tools), tool results mentioning iOS SDK strings, and Xcode project settings like `SDKROOT = iphoneos`. The first time it sees both a Swift file edit and one of these other signals in the same conversation, it records a `dev_intent` telemetry event tagged `ios_app`.

**Why**

This is a background telemetry signal, not a user-facing feature: it doesn't change how Claude Code behaves in an iOS project, it just records that this kind of work happened.

- Area: Telemetry
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### MCP SDK clients can now replay a host-supplied manifest instead of a full handshake

MCP connections can now skip the handshake by replaying a pre-supplied server manifest, with fallback if it's invalid

**What**

When Claude Code connects to an MCP server (a service providing extra tools) via its SDK-based client, it can now be given a ready-made "host manifest" — essentially a pre-validated result of the initial handshake and tool listing — and replay that directly instead of performing the normal handshake over the control channel. If the supplied manifest is malformed, incomplete (paginated tool lists aren't supported this way), or otherwise fails, Claude Code falls back to doing the real handshake and records which specific problem occurred.

**Why**

This can make MCP server connections faster by skipping a round-trip when a trusted manifest is already available, while still falling back safely if that shortcut doesn't work out.

- Area: MCP
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New Artifact editor state fields: frozenDbStrReplace, typeShipsInstructions, attestedTypeArtifacts, mcpServersBuilt, dbWriteOpSights, askClassPending/Taken/Consent

Artifact runtime state gains several new internal tracking fields, including one for database write operations

**Unclear.** What user-visible behavior, if any, these new state fields enable is not described in the finding.

**What**

Claude Code's internal state for the Artifact editor gained a batch of new tracking fields, including `frozenDbStrReplace`, `typeShipsInstructions`, `attestedTypeArtifacts`, `mcpServersBuilt`, `dbWriteOpSights`, and `askClassPending`/`Taken`/`Consent`. The `dbWriteOpSights` field specifically tracks database write operations by tool-use ID and by slug.

**Why**

These are internal bookkeeping additions rather than user-facing features on their own; they suggest Claude Code is tracking more detail about database writes and permission-asking state within artifacts, but the finding doesn't describe what visible behavior they drive.

- Area: Artifacts
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Compaction precompute cache and hasPrecomputedSummary flag

Conversation compaction now supports a precomputed summary, tracked via a new hasPrecomputedSummary flag

**Unclear.** The finding doesn't say when or how a precomputed summary gets produced, or what user-visible effect it has.

**What**

When Claude Code compacts a long conversation (condensing history to save context space), it now passes a `precompute` object from session state through a new step before running the summarizer, and the confirmation shown to the user after compaction includes a new `hasPrecomputedSummary` flag.

**Why**

This suggests compaction can now reuse a summary computed ahead of time rather than always generating one fresh, which could make compaction faster in some cases, though the finding doesn't describe when a precomputed summary becomes available.

- Area: Elsewhere
- Names: `hasPrecomputedSummary`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Session/control channel gains a 'controlOnly' mode

Sessions can now run in a 'controlOnly' mode that skips arming the send watchdog

**Unclear.** What causes a session to be set to controlOnly mode, and what practical scenario it supports, is not stated.

**What**

Session setup now supports a `controlOnly` flag that gets passed through session configuration to the underlying session client and stream setup. When `controlOnly` is set, the mechanism that watches for send failures (the "send watchdog") is not armed after a successful send acknowledgment.

**Why**

This appears to support a mode where a session is used only for control messages rather than normal message sending, though the finding doesn't say what triggers this mode or what it's used for.

- Area: Sessions
- Names: `controlOnly`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Workspace trust plumbed into init config and SDK session request

Workspace trust status is now passed into session setup and checked against trusted network directories

**Unclear.** What happens as a result of this workspace-trust check (e.g. what gets blocked or warned) is not stated.

**What**

A `workspaceTrust` setting from init configuration is now passed through to session setup, where it's used to run a new workspace-trust check. That check considers the current working directory, a list of trusted network directories, and storage state, and runs during setup when the host owns the terminal's standard input.

**Why**

This threads workspace trust information deeper into session initialization, likely as part of deciding what a session is allowed to do in an untrusted workspace, though the finding doesn't specify the effect of the check's result.

- Area: Workspace Trust
- Names: `workspaceTrust`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New 'relay_unavailable' status/latch state for artifact sync

Artifact syncing gains a relay_unavailable status, plus a header reporting sandbox network egress restrictions

**What**

The system that syncs artifacts (files Claude Code shares back, such as generated documents) now recognizes a new status, `relay_unavailable`, and a corresponding "latched" variant, alongside the existing `no_originator` and `subscribe_forbidden` statuses. Separately, on relay-related network requests, Claude Code now reads a new response header, `x-ccr-sandbox-egress`, which can report whether outbound network access is `disabled`, `restricted`, or `unrestricted`.

**Why**

This gives Claude Code a clearer, more specific signal when artifact syncing can't reach its relay server, and lets it know about sandbox network restrictions that might affect that syncing.

- Area: Artifacts
- Names: `x-ccr-sandbox-egress`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New hook events: WorktreeCreate / WorktreeRemove now gate feature availability via eE()

Worktree create/remove UI now also checks a broader capability gate, not just whether hooks are registered

**Unclear.** What other conditions the broader capability check considers beyond hook registration is not stated.

**What**

The `WorktreeCreate` and `WorktreeRemove` hook events, which already fire when a worktree (an extra working copy of your repo used for isolation) is created or removed, are now also checked against a broader capability lookup. Two new helper functions use this combined check to decide whether the worktree create/remove UI should be shown, rather than checking only whether hooks are registered for those events.

**Why**

This means the worktree UI's availability can now depend on more than just whether you've registered a hook for it, though the finding doesn't specify what else the capability check considers.

- Area: Worktrees
- Names: `WorktreeCreate`, `WorktreeRemove`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Directory sync journal state machine reworked with generation-owed tracking and idle/failure strikes

Directory sync's internal state tracking reworked to handle stuck or unacknowledged uploads

**What**

Directory sync (the feature that keeps a synced copy of your working directory in the cloud) has had its internal bookkeeping reworked. It now tracks whether a given version of the synced state ("generation") has been uploaded but not yet acknowledged or refused by the sync service, and notifies you differently depending on whether the upload was refused versus simply not taken yet. The logic also now waits for specific points in a turn (turn boundaries) before treating an unpublished state as something to act on, rather than reacting immediately.

**Why**

This should make directory sync's status reporting more accurate, distinguishing a sync that failed from one that simply hasn't been processed yet, and avoids premature action on sync state that's still in flight.

- Area: Cloud Sync
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Permission-check pipeline gained a pre-hook adjustment step (uot) before deny/ask evaluation

Tool permission checks now let a hook adjust the decision before deny/ask logic runs

**What**

Before Claude Code decides whether to deny or ask about a tool call, both of its permission-decision code paths now run a new step that lets a hook (custom code that runs at a specific point in Claude Code's process) inspect and potentially adjust the in-progress permission decision before the deny or ask branches are evaluated.

**Why**

This opens a point where custom hook logic can influence permission outcomes earlier in the pipeline, ahead of the standard deny/ask evaluation.

- Area: Hooks
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Onboarding flow adds a 'gateway' auth path condition alongside OAuth

Onboarding now also treats a 'gateway' authentication setup as equivalent to OAuth for its flow

**Unclear.** Nothing has been read yet about how the `tengu_began_setup` or `tengu_onboarding_step` gates affect this on any account.

**What**

During onboarding, Claude Code previously decided whether to show the OAuth (the standard login-and-authorize flow) step based on one condition. It now also checks a second condition: whether the account is set up with a "gateway" authentication path. If so, that also feeds the same `oauthEnabled` telemetry field and affects whether the OAuth step is shown. A related preflight-skip condition was also adjusted.

**Why**

This should make onboarding behave correctly for accounts using a gateway-based authentication setup, rather than only accounting for standard OAuth.

- Area: Terminal UI
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Thread-recap prompt for Projects is now server-overridable

The prompt used to recap a Projects thread can now be overridden from the server

**What**

Claude Code's prompt for summarizing ("recapping") a Projects thread is now read from a server-supplied config value, falling back to a built-in default when that value is unset or blank.

**Why**

This lets Anthropic adjust the thread-recap prompt for Projects without shipping a new client release, rather than only being able to update it via a full built-in default baked into the app.

- Flag `tengu_projects_thread_recap_prompt`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: no value returned, compiled default: not a boolean we can read)
- Area: Projects
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Auto-mode permission pipeline wired to honor classifier-only tools' onBlock behavior

Auto-mode permission logic now honors what a classifier-only tool wants to happen when it's blocked

**What**

Building on the new `classifierOnly` tool setting, the main auto-mode permission logic now checks a tool's configured `onBlock` behavior:

- If it's set to `"refuse"` and either a hook requested a confirmation prompt or the host re-asks for every allow, the request is denied with an explanation.

- If it's set to `"flag"`, the request is automatically allowed but flagged, instead of going through the normal ask/allow decision process.

**Why**

This lets classifier-only tools declare exactly how they should fail or be flagged when blocked, rather than falling through to the same generic ask/allow handling as ordinary tools.

- Area: Auto Mode
- Names: `onBlock`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### SDK stream-json schema: new `historical` and `runner_exit` fields, and expanded meta-turn uuid-folding semantics

SDK message format adds `historical` and `runner_exit` fields, and clarifies how mid-turn user messages get folded in

**What**

The SDK's stream-json message schema (the structured format used to stream session data) gains two new internal fields:

- `historical`, a true/false flag stamped when Remote Control's bridge flushes past history to the session server, marking a message as replayed rather than live

- `runner_exit`, set by the self-hosted runner when a session process fails to start or exits abnormally

Documentation for the existing `user_message_uuid`/`user_message_uuids` fields was also expanded, describing how a synthetic or scheduled turn now echoes the uuid of a user message that gets folded into it partway through.

**Why**

These additions give tools consuming the SDK's message stream more precise ways to tell replayed history apart from live messages, to detect abnormal runner exits, and to trace which user message a mid-turn update relates to.

- Area: SDK
- Names: `historical`, `runner_exit`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Ambient-credential detection updated for a new /api/artifacts/mcp endpoint

Ambient-credential detection for MCP now special-cases a new /api/artifacts/mcp endpoint

**What**

The internal helper that detects ambient credentials and OAuth needs for MCP server connections (replacing an older helper) now treats URLs under the `/api/artifacts/mcp` path differently from other MCP URLs. Related plumbing (`artifactsMcpEntries`, `artifactsMcpEdgeEntries`) and new OAuth scope constants for the artifacts MCP server were added, split into management, data, endpoints, and comments scopes.

**Why**

This lays groundwork for an artifacts-specific MCP server to be authenticated and scoped separately from other MCP connections, with finer-grained permission scopes.

- Area: MCP
- Names: `/api/artifacts/mcp`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New helper reads a 'typeLock' slug on agent/skill type objects

A new 'typeLock' slug field is being read on agent/skill type objects, alongside the existing typeSlug

**What**

A small new helper function reads a `typeLock.slug` value off agent and skill type objects, falling back to the existing `typeSlug` field if `typeLock` isn't present. This points to a `typeLock` field being introduced as a newer, more specific way of identifying an artifact's type than `typeSlug` was.

**Why**

This builds on the type-locking mechanism that already blocks changing a type-locked artifact's contract or language when publishing; this change extends how that lock's type is identified, giving it its own slug rather than reusing the general type slug.

- Area: Artifacts
- Names: `typeLock`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Subagent spawn now threads request shape (foreground/background) and carries hook context across resumed skill-loaded turns

Subagent spawning now tracks foreground/background request shape and carries hook context through resumed skill-loading turns

**What**

When Claude Code spawns a subagent (a separate Claude instance handling a sub-task), it now computes a `{requestShape, requestNonInteractive}` value describing whether the request is foreground or background. A second new helper scans queued messages for additional context from a `SubagentStart` hook (which runs when a subagent is spawned) and for skill-loading metadata, producing `hookContextCarried` and `carriedPreloads` values used when the agent's skills already have preloaded content or state.

**Why**

This lets context and hook-provided information survive correctly across resumed turns that involve loading skills into a subagent, rather than being dropped or recomputed inconsistently.

- Area: Subagents
- Names: `requestShape`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### New remote-config flag `tagConnectorWrites` adds a Slack/'Claude Tag' write exception to the security monitor prompt

A new flag adds a Slack ('Claude Tag') exception to the security monitor's write-blocking rules

**What

- Area: Slack Integration
- Names: `tagConnectorWrites`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### Artifact fetches now read an `x-ccr-sandbox-egress` relay header and cache a per-artifact network-egress setting

Artifacts now read a sandbox network-egress setting from a relay header and cache it for 10 minutes

**What**

When fetching artifacts, Claude Code now reads a header called `x-ccr-sandbox-egress` from the relay's response, which can be `disabled`, `restricted`, or `unrestricted`. This value is cached per artifact for 10 minutes and used to decide whether that artifact should report its sandbox network access (its ability to reach the network from within its isolated environment) as disabled.

**Why**

This lets the server control and communicate, on a per-artifact basis, whether network access is available, so Claude Code's own display of that state stays in sync with what the relay actually allows.

- Area: Artifacts
- Names: `x-ccr-sandbox-egress`
- Tier: Under the hood
- Useful: 2/5
- Signal: 2/5

### requestShape/requestNonInteractive/workflowPhase threaded through agent telemetry, purpose unclear

Subagent and worktree teardown telemetry now records whether a request ran foreground or background and whether it was non-interactive

**Unclear.** What workflowPhase records and what this telemetry is used for is not stated.

**What**

Internal telemetry sent when a subagent (a Claude Code instance launched to handle a subtask) is launched or torn down now carries three new fields:

- `requestShape`, marked either `foreground` or `background`

- `requestNonInteractive`, a true/false flag

- `workflowPhase`

These are recorded during subagent tool launches and during team/worktree teardown, and are propagated from the context of the tool call unless the caller is an observer.

**Why**

This is internal diagnostic data rather than something that changes what you see or can do in Claude Code. It likely helps Anthropic distinguish how and when subagents were run when investigating issues.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 2/5

### Model switch mid-session now preserves/refreshes rendered client data for artifact frames

Switching models mid-session now preserves rendered artifact-frame data across the switch

**What**

When the model used for the main conversation loop changes mid-session, Claude Code now optionally takes a snapshot of the rendered client-side thread-list data before switching. If that data changed, it's passed along as `renderedClientData` into the bootstrap-refresh step that runs after the switch.

**Why**

This stops the client's displayed state (such as artifact frames) from being lost or reset when you change models in the middle of a session.

- Area: Artifacts
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### wire_ingest_context added to round-trip input-normalization provenance

Session transcripts now record the process state used to normalize tool inputs, like the working directory a `cd` was stripped against

**What**

Claude Code normalizes some tool inputs before running them, for example stripping a leading `cd` command against the current working directory, or stamping a timestamp on a Slack message. A new internal field called `wire_ingest_context` now records exactly what process state was read to do that normalization, and saves it alongside the message.

This lets a replayed session history double-check that a recorded tool input still matches what the normalization would have produced, since the underlying process state (like the working directory) can change between runs.

**Why**

This is internal bookkeeping that helps verify session replay is accurate. It doesn't change what a tool call does, but it makes it possible to detect if a normalized input has drifted from what actually happened.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New per-artifact sandbox egress setting tracked with staleness

Each artifact now tracks its own sandbox network-access setting, which goes stale after a time limit

**What**

Claude Code now records, per artifact, whether its sandbox (an isolated execution environment) has network egress (outbound network access) disabled or not. This setting is cached, but after a set age it's treated as unknown rather than trusted, so it must be re-checked.

**Why**

Caching the setting avoids repeatedly re-checking it, while the staleness cutoff makes sure Claude Code doesn't act on a network-access setting that may no longer be accurate.

- Area: Sandbox
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### React-compiler list/select component gains columnSizingOptions and keysDeferred props

The selectable list component gains column-sizing options and a way to defer keyboard handling elsewhere

**What**

The internal selectable-list UI component now accepts a `columnSizingOptions` setting, used to compute column widths in compact vertical layouts, defaulting to the same list of options being shown. It also accepts a `keysDeferred` setting; when supplied and it signals true, the component's keyboard shortcuts are wrapped so key handling can be deferred to something else instead of being handled directly, and the component is kept active while this is in effect.

**Why**

This is internal UI plumbing that gives list-based menus more control over layout and keyboard handling; it doesn't describe a specific user-facing feature on its own.

- Area: UI Components
- Names: `columnSizingOptions`, `keysDeferred`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Rewind failure reasons switched from free-text strings to stable machine codes

Rewind failure reasons are now stable codes instead of free-text messages

**What**

Rewind (the feature that lets you roll conversation history back to an earlier point) used to report failures as human-readable strings like "commands queued", "target not found", "stale target", or "poll tool_result target". These are now built through a shared helper and expressed as snake_case codes: `commands_queued`, `target_not_found`, `stale_target`, `poll_tool_result_target`.

**Why**

Stable codes are easier to match on programmatically (for logging, telemetry, or tooling) than free-text messages that could change wording. This doesn't change what rewind does, just how its failures are labeled internally.

- Area: Sessions
- Names: `commands_queued`, `target_not_found`, `stale_target`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New rewind-anchor failure taxonomy for prompt/session rewind

Rewind now reports a specific reason when it can't jump back to a point in a session

**What**

'Rewind' (jumping a session or prompt back to an earlier point) now has a defined set of named outcomes for why a rewind couldn't happen: `commands_queued`, `prompt_pending`, `turn_running`, `target_not_found`, `stale_target`, `unseen_later_turn`, `poll_tool_result_target`, `delivered_poll_events_in_range`, `persist_failed`, and `state_changed`. Each maps to a human-readable explanation, and a helper always returns `rewound: false` along with the reason when a rewind fails.

**Why**

This gives clearer, more specific feedback about why a rewind attempt didn't succeed, instead of a generic failure, making it easier to understand what state the session was in that blocked it.

- Area: Sessions
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Plugin-dir watching now covers folders of plugins (collections), not just individual plugin dirs

Claude Code's plugin-directory watcher now also watches folders that contain multiple plugins

**What**

When Claude Code watches plugin directories for changes, it now separately tracks plugin folders (a directory holding several plugins) in addition to individual plugin directories. The watcher resolves both kinds of paths and logs what it's watching for each.

**Why**

This lets Claude Code notice changes across a whole collection of plugins, not just a single plugin folder, so updates to any plugin inside a shared folder are picked up.

- Area: Plugins
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New hook-registration validators for plugin event handlers

New validators catch plugin hooks registered for events or hook types that don't actually exist

**What**

Plugins can register handlers for events (using `on("event")`) and hooks. Two new validators now check this registration at load time: one confirms that a plugin's event patterns actually match a real, known event or method, and the other confirms that hooks the plugin declares were actually found when its hooks module was scanned. If either check fails, Claude Code now throws a descriptive error, such as one saying a pattern 'selects no event' or that a hook 'the scan of its hooks module did not see'.

**Why**

This gives plugin authors clearer, more specific errors when they misconfigure event or hook registrations, instead of the problem failing silently or surfacing as a confusing downstream error.

- Area: Plugins
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Artifact-type-instructions prompt block gained size-scrubbing and page-content helpers

Artifact type-instructions prompts gain new helpers for verifying and trimming embedded page content

**What**

New internal helpers build the guidance text that tells Claude how to write to an Artifact type's declared data store (via `mcp`, `data`, `write_db`, or `run_script`) instead of publishing files directly to it. Related helpers check whether a type's instructions file is verified as belonging to that type and release, and wrap or trim page content using `<...page tag...>` markers, dropping content that would exceed a set byte budget.

**Why**

This keeps Artifact type instructions accurate and within size limits, and steers writes toward the type's proper data store rather than direct file publishing.

- Area: Artifacts
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### MCP tool checkPermissions now consults an SDK-level permission hook first

MCP tool permission checks now first ask an SDK-level permission hook before falling back to normal consent logic

**What**

When Claude Code decides whether an MCP tool is allowed to run, it now first checks whether the SDK layer has already made a decision. If it has, that decision is used directly; otherwise Claude Code falls through to its usual suggestion and consent flow.

**Why**

This lets a higher-level permission decision (for example, one set by an SDK integration) take priority over Claude Code's default prompt-for-consent behavior for MCP tools.

- Area: MCP
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Self-hosted runner session-exit result schema added

New internal schema describes how a self-hosted runner's session ended, with phase, exit code, and signal

**What**

Claude Code now has an internal schema for describing how a self-hosted runner's session process ended. It records a `phase`, either `setup` (the process never started) or `run` (it exited), plus optional `exit_code` and `signal` values.

**Why**

This gives more structured information about how and why a self-hosted runner session terminated, which should help in diagnosing failures that happen before versus after the session actually starts running.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### asLevel / levelConfirmed permission-level plumbing added to artifact API calls

Artifact database calls now pass a permission level and get back confirmation of whether it was honored

**What**

Calls to the artifact database, such as `artifact_db_read`, can now optionally include a permission level (`asLevel`), and the response now includes a `levelConfirmed` flag saying whether that permission level was actually honored by the server.

**Why**

This lets Claude Code check that an artifact request was handled at the permission level it asked for, rather than assuming it was.

- Area: Artifacts
- Names: `asLevel`, `levelConfirmed`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New plugin settings field: payloadSlots

Plugin settings gain a new payloadSlots field alongside shell settings and hooks

**Unclear.** What a plugin "slot" contains or is used for is not stated.

**What**

When Claude Code assembles settings contributed by plugins, it now includes a `payloadSlots` map, built from each plugin's slot entries, alongside the existing `shellSettings`, `envVars`, `sandboxSettings`, and `hooks` fields. A new helper checks whether any slots are non-empty to decide whether a plugin's settings count as meaningful ("non-trivial").

**Why**

The finding does not say what a plugin "slot" holds or what it is used for, only that plugins can now contribute this additional kind of data and that it factors into whether a plugin's settings are considered non-trivial.

- Area: Plugins
- Names: `payloadSlots`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Session resume: hook-message handling reworked to support deferred/abortable hook sets

Session resume now defers and can abort startup hook messages instead of using a single pending flag

**What**

When a session is resumed, Claude Code runs certain startup hooks (automated scripts that fire on events like session start) and needs to insert their output into the conversation at the right point. This mechanism has been rebuilt: instead of tracking a single pending promise and a landed flag, there's now a dedicated `_pendingHookSet` object that can defer hook messages, wait for startup hooks to finish, release the held messages once ready, and abort the process if needed.

The new logic also checks the session id before applying results, so if a session gets replaced while hooks are still running, stale hook output from the old session is discarded instead of being inserted into the new one.

**Why**

This prevents a race where hook output from an old, already-replaced session could leak into a resumed session's transcript, and gives the system a way to cleanly cancel pending hook work instead of leaving it dangling.

- Area: Hooks
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New unified-diff/patch text parser added

Claude Code adds an internal parser for unified-diff/patch text

**What**

Claude Code now includes a self-contained parser for unified-diff format, the common text layout used to represent file changes (with `Index:`, `diff`, `---`, `+++`, and `@@` header lines followed by hunks of added/removed lines). It reads these headers and hunks into a structured form and checks that the number of added and removed lines actually matches what each hunk header claims.

**Why**

Having a dedicated, validating diff parser lets Claude Code reliably interpret patch-formatted text and catch malformed or inconsistent diffs before acting on them.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### SDK query supports waiting for a held OAuth token refresh during shutdown

SDK query can now wait for an in-progress OAuth token refresh before shutting down

**What**

The SDK's query process gains a `waitForHeldOAuthRefresh` step. When shutting down, it now checks whether an OAuth token refresh is currently pending; if so, it extends the shutdown safety timer and waits for the refresh to finish before letting shutdown proceed.

**Why**

This prevents the process from being killed in the middle of refreshing its authentication token, which could otherwise leave the session in a broken authentication state.

- Area: SDK
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### LocalFileJournal gains an explicit restore-in-progress protocol

LocalFileJournal now tracks whether a restore was interrupted, partial, or complete

**What**

LocalFileJournal, the mechanism Claude Code uses to persist session data to disk, now has a `restoreState()` check that reports whether a restore is `"missing"`, `"partial"`, or `"complete"`, by looking for marker records at the start (`{type:"restoring"}`) and end (`{type:"restored"}`) of a restore. A companion `writeRestored()` function wraps a batch of records between these markers and writes them either as an atomic delete-and-append (on the newer v5 storage backend) or as a plain file write otherwise.

**Why**

This gives the journal a reliable way to tell whether a previous restore actually finished, which matters for recovering cleanly if Claude Code was interrupted partway through restoring session data.

- Area: Sessions
- Names: `LocalFileJournal`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New read-baseline lookup for remote-synced project files

Read and Edit tools now check a stored baseline for files synced from a remote host

**What**

New internal helper functions resolve a file path used by the `Read` or `Edit` tool against a remote host's project-sync setting (`two_way` or `upload_only`). If the file falls inside the synced project root or working directory, Claude Code now looks up a previously recorded baseline reading for that file instead of always treating it as never having been read.

**Why**

This avoids unnecessarily treating a synced file as unread when it was already read through the sync connection, which matters for tools like `Edit` that require a file to have been read first.

- Area: Multi-Host Sessions
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New model-selection helper for 'small fast model' vs projects model

A new helper function chooses between the small fast model and a project's configured model

**Unclear.** The finding doesn't say which call sites use this new helper or in what user-visible situations it's invoked.

**What**

A new function picks which model to use in a given situation. When called with a truthy argument, it prefers a session's configured `projectsModel` (after checking it's valid), falling back to a general default-model resolver if not set. When called without that argument, it instead prefers the "small fast model" setting (`useSmallFastModel`) when enabled, otherwise falling back to the same default-model resolver.

**Why**

This centralizes model-selection logic that previously may have been scattered, letting different parts of Claude Code consistently choose between a project-specific model and the small fast model depending on context.

- Area: Models
- Names: `useSmallFastModel`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### MCP tool permission checks now defer to an SDK-registered checker first

MCP tool permission checks now consult an SDK-registered checker before the usual permission logic

**What**

When deciding whether an MCP tool (a tool provided by an external MCP server) is allowed to run, Claude Code now first asks a permission checker registered by the SDK (software development kit), if one is present. Only if that doesn't produce a decision does it fall back to the built-in permission-rule logic and design-consent checks it used before.

**Why**

This lets code built on the Claude Code SDK plug in its own custom permission logic for MCP tools, taking priority over the default rules.

- Area: MCP
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### cgroup CPU accounting rewritten to read cpuacct.usage directly, adds shell CPU tracking

CPU telemetry now reads cgroup usage from a fixed path and adds a new shell CPU time metric

**What**

The telemetry that reports CPU usage broken down by session phase (`tengu_tool_cpu_by_phase`) now reads CPU accounting data from a fixed cgroup path, `/sys/fs/cgroup/cpuacct`, plus a per-tool cgroup's `cpuacct.usage` file. It also adds a new `*_shell_cpu_ms` metric, reported alongside the existing `*_wall_ms`, `*_cli_cpu_ms`, and `*_tools_cpu_ms` metrics when shell cgroup data is available.

**Why**

This gives more precise, directly-read CPU accounting and adds visibility specifically into CPU time spent in shell subprocesses, on top of the existing CLI-versus-tools breakdown.

- Area: Telemetry
- Names: `cpuacct.usage`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### MCP tool calls gain artifact-server arg/result hooks

MCP tool calls to artifact servers now pass through argument-rewriting and result-observing hooks

**What**

When Claude Code calls a tool on an MCP server (a way for Claude Code to talk to external tools and data sources), it now runs the call's arguments through an `argsForCall` step before sending them, and runs the response through an `observeResult` step afterward. A specific handler for the 'artifact' class of MCP servers uses this to rewrite arguments on management calls, and, for `list_artifacts` calls, to record telemetry including a count of shared artifacts.

**Why**

This gives Claude Code a hook point to adjust artifact-related MCP calls and to gather usage data on artifact listings, without changing what the tool call looks like to the server itself.

- Area: MCP
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### New Claude Code state files: device-mcp-consent.json / device-mcp-snapshot.json

Two new state files, device-mcp-consent.json and device-mcp-snapshot.json, are now tracked and copied alongside other Claude config

**What**

Two new per-user state files, `.claude/state/device-mcp-consent.json` and `.claude/state/device-mcp-snapshot.json`, have been added to the set of Claude-managed files that get special handling, alongside existing files like `settings.json` and `unattended-serving-consent.json`. They're also included in the list of paths that get scanned and copied across config directories.

**Why**

This suggests Claude Code is building out a consent and state-tracking system specifically for MCP servers tied to a device, similar to the existing consent mechanism for unattended tool serving, though what specifically populates these files isn't detailed here.

- Area: Elsewhere
- Names: `device-mcp-consent.json`, `device-mcp-snapshot.json`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### `shellToolCommand`: bash executions now default to inserting a 'cc-shell' background-task join marker

Bash commands now default to a 'shell' execution class that inserts a background-task join marker

**Unclear.** What the cc-shell join marker is used for downstream, and whether it's visible to users, isn't shown by the finding.

**What**

Bash command execution now defaults its internal cgroup class (a grouping used to manage resource limits) to `"shell"`. Whenever that class is `"shell"`, a new `shellToolCommand` setting kicks in and causes the command builder to prepend a small marker command, referred to as a `cc-shell` join marker, before running the actual command.

**Why**

This appears to be internal plumbing for tracking or synchronizing background shell tasks; the finding doesn't specify what user-visible behavior depends on this marker.

- Area: Elsewhere
- Names: `cc-shell`
- Tier: Under the hood
- Useful: 2/5
- Signal: 1/5

### Plugin telemetry events now do an async marketplace-catalog lookup before logging

Plugin install/uninstall telemetry now confirms the plugin against the marketplace catalog before logging

**What**

Telemetry events for installing, uninstalling, updating, and disabling plugins now call a new asynchronous helper that tries to confirm the plugin actually exists in the marketplace catalog before logging the event. If that lookup fails, the event falls back to logging the plugin as third-party and redacts its name, rather than logging it directly as before.

**Why**

This avoids telemetry logging plugin names for plugins that can't be verified against the marketplace, reducing the chance of logging inaccurate or unverifiable plugin identities.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact-publish telemetry now separately counts unknown-tool manifest errors

Artifact-publish telemetry now separately counts manifest errors caused by unknown tool names

**What**

The `artifact_publish` telemetry event now tracks a new `unknown_tools_count` bucket, counted separately from `malformed_count`, `opaque_id_count`, and `host_unavailable_count`. `malformed_count` no longer includes the unknown-tool errors that now go into their own bucket.

**Why**

This lets the unknown-tools manifest error (added alongside this change) be measured on its own rather than blending into the general malformed-manifest count.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Agent-proxy relay now tracks per-connection 'bad event' budgets

The agent-proxy relay now tracks a 'bad event' budget for each connection

**Unclear.** What triggers or consumes a connection's bad-event budget, and what happens when it's exhausted, isn't specified.

**What**

The internal state tracked for the agent-proxy relay (which forwards agent traffic) now includes a `badEventBudgets` map, alongside existing counters like `uploadPauses`. This tracks, per connection, some kind of budget related to malformed or invalid events.

**Why**

This appears to be part of tracking and limiting misbehaving connections, though the finding doesn't specify exactly how the budget is enforced.

- Area: Agent Proxy
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP tool-allowlist subset checking (pc) rewritten around a safe array/object reader

The internal check for MCP server tool-allowlist subsets was rewritten to safely handle hostile or malformed data

**What**

The internal logic that checks whether a server's allowed-tools set is a subset of another set (used to enforce MCP tool restrictions) was rewritten around new helper functions that canonicalize and safely read array and object values. The new helpers bound how large a list can be and catch errors from objects with throwing property getters, guarding against malformed or adversarial input.

**Why**

This hardens the tool-allowlist comparison against malformed or maliciously-crafted data, so a bad MCP server response can't crash or bypass the allowlist check.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### policyHelper refresh now reports retry attempt counts on failure

Telemetry for a failed background policyHelper refresh now includes how many attempts were made

**What**

When a background refresh of a `policyHelper` (a script that computes managed settings at startup) fails after its retries are exhausted, the `settings_policy_helper` `refresh_failed` telemetry event now includes an `attempts` field recording how many attempts were made.

**Why**

This gives more detail on failed policy helper refreshes, making it possible to tell whether a failure happened immediately or only after several retries.

- Area: Managed Settings
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Static defaultSettings fallback now tags whether it was armed by remote managed settings, and whether from cache

The static settings fallback log now says whether it came from remote managed settings, and whether it's an unverified cached copy

**What**

When Claude Code falls back to applying a static `defaultSettings` payload, the log message now says whether that payload was armed by remote managed settings, and if so, whether it came from a session cache that hasn't yet been verified this session, versus one that has.

**Why**

This makes it easier to tell, from the logs, exactly which kind of fallback settings payload was applied and whether it's still awaiting verification, which matters when diagnosing unexpected settings behavior.

- Area: Managed Settings
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### copy_from asset-copy tool: new auto-approval short-circuit path

Copying assets between artifacts gains a new auto-approval path that can bypass the older consent check

**Unclear.** The finding does not fully explain how this new branch interacts with the deny/ask permission-rule engine described previously, so the exact practical effect on when a copy is allowed versus prompted is unclear.

**What**

When copying an asset from one artifact to another using `copy_from`, the permission flow now has an additional path: outside of plan-mode consent tracking, it can check a write-permission ruling from the automatic classifier and allow or ask for approval based on that, without going through the older consent-tracking flow for source and destination.

**Why**

This is a further adjustment to how `copy_from` decides whether to allow, ask, or deny a copy, building on the permission-rule checks already added for this action; readers relying on that consent-based flow should be aware another path can now grant or request approval directly.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Recently-read file reconstruction from transcript is now capped and marked

Reconstructing recently-read files from chat history is now capped and marked as coming from history rather than disk

**What**

The logic that reconstructs which files were recently read, by scanning back through the conversation transcript, now walks the transcript from newest to oldest, stops after finding a fixed maximum number of distinct files, and tags each reconstructed file entry with `contentFromTranscript` so later code can tell it was rebuilt from the conversation history rather than freshly read from disk.

**Why**

This limits how much work and memory is spent reconstructing file history from a long conversation, and lets other parts of Claude Code distinguish transcript-derived file content from an up-to-date disk read, which matters if the file has changed since it was last read.

- Area: Transcript
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New start/stop instrumentation around REPL inner tool execution

Claude Code now internally marks the start and end of each tool call for both local and remote execution

**What**

The internal code path that runs a tool call, whether it executes on the local machine or on a remote host, now records a marker just before and just after the actual call.

**Why**

This is internal instrumentation. It does not change what happens when a tool runs, but lays groundwork for measuring or tracking tool execution more precisely.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### DesignSync tool telemetry now validates `dsMethod` against a known method list

DesignSync tool telemetry now checks the method name against a fixed list instead of logging it raw

**What**

When Claude Code records telemetry about which DesignSync tool method was used (things like `list_projects`, `get_project`, `list_files`, `get_file`, `finalize_plan`, `write_files`, `delete_files`, `register_assets`, `unregister_assets`), it now looks the reported method name up against a fixed list of known method names and records the match, instead of logging whatever string was passed in directly. This also applies to the error telemetry recorded when a DesignSync tool call fails.

**Why**

This keeps telemetry data consistent and prevents unexpected or malformed method names from being recorded as-is; it has no effect on what the DesignSync tool actually does.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New internal 'agent worker' event reader plumbing added alongside existing internal event readers

New internal 'agent worker' event reader added alongside the existing internal event reader system

**Unclear.** The finding is too fragmentary to describe a user-facing effect; it only shows new internal plumbing (a parallel event reader filtered by session_agent_id) without saying what feature it supports.

**What

- Area: Background Agents
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Turn-result wall-clock timing fields now gated to the matching user message

Turn-timing fields in the result event now only appear when they match the current turn's user message

**What**

In the final `result` event that Claude Code emits at the end of a turn, two wall-clock timing fields, `request_sent_wall_ms` and `first_stream_post_wall_ms`, are now only included when they belong to the same user message that the current turn is actually reporting on. The other send-echo timing fields are still always included as before.

**Why**

Previously these two timing fields could be attached to a result even when they came from a different user message than the one the result was about, which could make timing data misleading. Restricting them to the matching message keeps the reported timings accurate.

- Area: Telemetry
- Names: `request_sent_wall_ms`, `first_stream_post_wall_ms`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New generic identifier-list validator for telemetry sanitization

A new validator lets comma/plus-separated identifier lists pass through telemetry unredacted

**What**

Claude Code sanitizes telemetry data before sending it, redacting anything that looks like it could contain sensitive information. A new validator has been added that recognizes a specific pattern: one or more alphanumeric identifiers (each starting with a letter, up to 64 characters, allowing underscores), separated by commas or plus signs. Values matching this pattern are now treated as safe and passed through as-is; anything else is redacted as "nonconforming".

**Why**

This lets telemetry preserve useful structured values, like lists of identifiers, without redacting them, while still catching and hiding anything that doesn't fit the expected shape.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Background agent status classifier now receives a project recap flag

Background agent status updates now factor in a project recap when describing what an agent is doing

**Unclear.** What the 'projects recap' flag contains and how it changes the displayed status text is not specified.

**What**

Claude Code periodically classifies what a background agent is doing (working, idle, or blocked) to show a short status description. That classification now also receives a "projects recap" value as input, in addition to what it used before.

**Why**

The finding doesn't say exactly what improves, but feeding in a project recap suggests the status text shown for background agents can now reflect broader project context rather than just the agent's immediate activity.

- Area: Background Agents
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Directory-sync git worker internal rework (basis-memoized index/worktree checks, session-tagged 'kept' ref)

Directory sync's internal git worker was reworked with memoized checks and session-tagged 'kept' refs

**What**

The background worker that handles git operations for directory sync had its internal logic reshuffled. It now uses two new memoized (cached) helper functions to check whether a git "basis" (a known starting point) matches a given commit, or matches a given index and working-tree state, and a new function tags a git ref by session ID as "kept" before falling back to discarding a temporary index.

**Why**

This is an internal restructuring of directory sync's git handling; the finding doesn't indicate a user-visible behavior change beyond how these checks are computed internally.

- Area: Cloud Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### RemoteIO gains a stdinLane constructor option

Remote session IO gains a new 'stdinLane' option alongside its existing stream settings

**Unclear.** What `stdinLane` does and how it affects remote session behavior is not specified in the finding.

**What**

The internal class that drives input/output for a remote (bridge or cloud) session's stream now accepts a new `stdinLane` option when it's constructed, alongside the existing stream URL, initial prompt, session state, and other settings.

**Why**

The finding doesn't say what `stdinLane` controls, so its practical effect for a reader isn't clear from this change alone.

- Area: Sessions
- Names: `stdinLane`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bash command permission checks thread through an extra context value

Bash command permission checks now receive an extra piece of context when deciding whether to allow a command

**Unclear.** What the added argument (`k(o)`) represents and how it changes permission outcomes is not specified.

**What**

The internal functions that match a bash (shell) command against permission rules now take an additional context value alongside the command, working directory, and other options they already received.

**Why**

The finding doesn't specify what the new value carries, so it's not clear what new information now factors into bash permission decisions.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Auto-mode classifier call gains an extra parameter

Auto-mode's classifier call now passes one additional argument alongside the existing transcript and host rules

**Unclear.** What the new argument represents and its effect on auto-mode classification is not specified.

**What**

The function call that invokes the model used to classify auto-mode behavior now passes an extra argument (`xfr(r)`) in addition to the host rules and transcript data it already sent.

**Why**

The finding doesn't specify what this extra value contains or how it changes the classifier's behavior.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Incoming user messages in Projects threads can be stamped with thread state

User messages in Projects threads can now be tagged with the thread's state

**What**

When a message is queued in a Projects thread (as opposed to a peer or overview thread), Claude Code now checks whether the message is a genuine user turn in a real, non-overview Projects thread. If so, the queued message is stamped with `stampThreadState`, marking that it carries the thread's state.

**Why**

This lets Claude Code distinguish messages that need thread-state context attached from other kinds of turns, so downstream handling of Projects threads can rely on that stamp being accurate.

- Area: Projects
- Names: `stampThreadState`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Spinner/glimmer animation gains a 'parked' state that skips the fast 50ms tick

The status-line spinner can now be 'parked' to skip its faster animation speed

**What**

The animated spinner (the little "glimmer" indicator shown while Claude Code is working) now supports a `glimmerParked` flag. Normally, the spinner ticks faster (every 50ms) while a request is in progress. With `glimmerParked` set, that faster speed no longer kicks in even while a request is active - the faster tick only applies when a request is in progress and the spinner is not parked.

**Why**

This gives Claude Code a way to keep the spinner in a slower, calmer animation state even during an active request, for situations where the faster animation isn't wanted.

- Area: Elsewhere
- Names: `glimmerParked`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Slack relay envelope/marker validation tightened

Slack integration tightened its rules for spotting genuine start-of-turn messages vs. injected content

**What**

Claude Code's Slack integration includes text meant to stop malicious prompt injection, where someone tries to sneak fake instructions into a conversation so Claude treats them as legitimate. This defense text has been tightened in two ways:

- File-attachment references must now come immediately before the special marker that opens a genuine user turn; previously, other unrelated '[SendFile: ...]' notes were allowed to sit in between.

- A new rule states that only the harness (Claude Code's own controlling system) can place this opening marker or lead-in at the very first characters of a turn; if it appears after any other text, it is just ordinary content and not to be treated as authoritative.

**Why**

This closes a gap that could let someone disguise injected text as a legitimate system-issued marker by inserting distracting content before it, making the Slack integration harder to trick.

- Area: Slack Integration
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Publish/root path resolution reworked (async allowlist check)

Publish tool now checks the workspace root against an allowlist asynchronously instead of a simple string match

**Unclear.** The finding does not say what practical difference this makes for users, such as which paths are now accepted or rejected differently.

**What**

The publish tool's check for whether a given root directory falls inside the current workspace used to be a simple synchronous comparison of path strings. It now runs an asynchronous allowlist resolution process before deciding whether the root counts as inside the workspace.

**Why**

This changes the internal mechanics of a safety check used when publishing.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Official-marketplace attestation now tracked for synced/skill plugins

Plugin loading now tracks official-marketplace attestation for synced and skill-based plugins

**Unclear.** The finding does not say what effect the attestation has on plugin behavior or trust indicators shown to the user.

**What**

When Claude Code loads a plugin that comes from a local path, it now looks up whether that plugin has an 'official attestation' from a synced marketplace source. After plugins are loaded, Claude Code updates its records of which plugin IDs carry an attested official marketplace.

**Why**

This is part of tracking which plugins can be verified as coming from an official marketplace, though the finding does not say what changes for users as a result of this tracking.

- Area: Marketplace
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### WaitForMcpServers tool refactored to a create()-based factory and drops its explicit auto-allow checkPermissions

Internal tool that waits for MCP servers was rebuilt as a factory function and no longer auto-allows itself

**Unclear.** The `tengu_mcp_pending_call` gate mentioned alongside this change is unread, so nothing can be said about whether it is switched on.

**What**

The internal tool that waits for MCP servers (external tool providers connected via the Model Context Protocol) to become available was restructured from a plain object into a factory function that produces the tool. It also dropped its own explicit permission check that always automatically allowed itself, and now looks up connected servers through a different internal method.

**Why**

This is an internal restructuring of how this tool is built and how it checks for available servers, rather than a change in what it does for users.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Directory sync: 'notSent' can suppress the persistent report line

Directory sync can now skip logging a failure to the persistent report while still updating the live status line

**What**

A function that records failed directory-sync notifications (`notSent`) now takes an option to skip adding the failure to the persistent report log, while still updating the live status line so the current state is visible. The related retry message also now mentions retrying at "the next sync point," in addition to the existing "after every turn" wording.

**Why**

This lets Claude Code show a sync problem in the moment without necessarily cluttering the persistent report with every occurrence, while still being clear about when a retry will happen.

- Area: Cloud Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifacts fetched via an external mode are now flagged 'external'

Artifacts fetched in 'external' mode are now explicitly flagged as external when read or listed

**Unclear.** What consuming code does differently when it sees external: true isn't stated.

**What**

When artifact data comes back with a mode of `external`, the code paths for reading an artifact and for listing its comments now explicitly carry that forward as an `external: true` flag.

**Why**

This makes it clear downstream that a given artifact came from an external source, rather than losing that distinction after the initial fetch.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New scratchpad-directory resolution helpers for tool path handling

New internal helpers resolve and validate a per-session scratchpad directory for tool file paths

**Unclear.** What feature uses this scratchpad directory, and when it's created, isn't stated.

**What**

New internal functions resolve and check a per-session "scratchpad" directory used for tool file operations. They verify it's a real directory (not a symlink), compute its canonical filesystem path, determine whether a given path falls inside the scratchpad or the current working directory, and detect cases where a symlink redirects a path elsewhere.

**Why**

This strengthens path handling for tools that read or write files, making it more reliable to tell whether a file operation is happening inside the intended scratchpad or working directory, including when symlinks are involved.

- Area: File System
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Hook dispatch events gain a 'raise' field

Internal hook dispatch events gained a new 'raise' field, purpose unclear

**Unclear.** What the `raise` field actually controls or affects is not shown by the evidence.

**What**

The internal machinery that dispatches hooks (scripts or commands that run automatically at certain points, such as before or after a tool runs) now passes an extra `raise` value alongside the existing id, event, payload, environments, and origin fields when invoking a hook module's dispatch function.

**Why**

This is an internal plumbing change. The evidence doesn't show what `raise` controls or what a hook author would observe differently.

- Area: Hooks
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Model catalog builder now tracks snapshot timing and stats

Model catalog cache-refresh logic now records how long the snapshot check took

**What**

When Claude Code checks whether its cached model catalog and settings are still current (by comparing against a git snapshot), the code now times that check and returns a `snapshotMs` duration and a `stats` object alongside the usual result of whether anything changed.

**Why**

This looks like internal instrumentation for diagnosing slow catalog refreshes rather than something a user would directly interact with.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Model catalog resolution now takes an explicit provenance argument

Model catalog resolution now passes a provenance value when rebuilding the catalog

**Unclear.** What the provenance value is used for, or what changes for the user, is not shown by the evidence.

**What**

The internal function that reconciles the model picker's catalog state now calls the catalog builder with an object that includes a `provenance` field (tracking where the catalog data came from), instead of just passing the raw catalog value as before.

**Why**

This is an internal refactor to the model catalog machinery. The evidence doesn't show what using provenance changes for a user of the model picker.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact comment thread schema adds degraded-data and scope-filter fields

Artifact comment threads can now report dropped threads and degraded data per thread

**What**

The data format for artifact comment threads (comment discussions attached to shared artifacts) gained several new optional fields:

- `threads_dropped` and `thread_filter`, which indicate when threads were left out and how the results were filtered

- `scoped_dispatch` and `outside_org`, related to scoping the request

- per-thread flags `resolved_degraded`, `activated_degraded`, `anchor_file_degraded`, and `comments_degraded`, marking when specific parts of a thread's data couldn't be fully loaded

- `anchor_region` and `region_inside`, describing the reference location a thread anchors to

**Why**

These fields let the client tell the difference between a thread that's simply empty and one where data was dropped, filtered out of scope, or only partially loaded, which should make it clearer when comment data shown is incomplete rather than genuinely absent.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Tool-use IDs with a reserved prefix are now classified as underivable_excluded

Tool calls with a special reserved ID prefix are now excluded from resume history reconstruction

**Unclear.** What the reserved ID prefix specifically identifies is not shown by the evidence.

**What**

When Claude Code resumes a session and figures out which prior tool calls can be reconstructed, a tool call whose ID starts with a specific reserved prefix is now immediately classified as `"underivable_excluded"`, before the normal checks for whether it was superseded or mismatched even run.

**Why**

This ensures tool calls carrying that reserved ID prefix are never mistakenly reconstructed during resume, treating them as excluded from the start rather than relying on the standard classification logic to catch them.

- Area: Sessions
- Names: `underivable_excluded`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Wire tool input consistency-check telemetry now includes tool name and MCP flag

Tool input consistency-check telemetry now records the tool's name and whether it's an MCP tool

**What**

When Claude Code detects an inconsistency in a tool's recorded input (via the `tether_wire_tool_input` telemetry event), the event now also includes the tool's name (`toolName`) and whether it came from an MCP server (`isMcp`), an external tool provider connected via the Model Context Protocol.

**Why**

This gives more context for diagnosing which specific tool, and whether an MCP-provided one, triggered an inconsistent recorded input, making it easier to track down the source of such issues.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Cloud session 'opened' payload can carry a controlOnly flag

Cloud session 'opened' event can now carry a controlOnly flag

**Unclear.** What effect `controlOnly: true` has on an opened session, or when it is set, is not described in the finding.

**What**

When a cloud session is opened via attach, the event data Claude Code emits can now conditionally include a `controlOnly: true` flag.

**Why**

The finding does not say what consuming this flag changes about the session's behavior.

- Area: Cloud Sessions
- Names: `controlOnly`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact file-read schema adds content/content_scrubbed fields and redaction handling

Artifact file-read data now includes content and a content_scrubbed flag, with redaction before logging

**What**

The artifact schema for files served to Claude gained two new fields: `content` (capped at a fixed length) and `content_scrubbed`, a boolean marking whether the content was redacted. Elsewhere, `file_read` payloads now have their `content` and `content_scrubbed` fields stripped out before being logged. Separately, comment threads that include a `presence` field are no longer treated as automatically cleared.

**Why**

This keeps actual file content out of logs while still tracking whether content was present and whether it was redacted, and it avoids incorrectly marking comment threads as resolved just because they carry presence information.

- Area: Artifacts
- Names: `content_scrubbed`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New MCP-manifest publish failure reasons: opaque_mcp_server_id and unknown_mcp_tool

Artifact publish telemetry gains two new MCP failure reasons: opaque_mcp_server_id and unknown_mcp_tool

**What**

When artifact publishing checks an MCP (Model Context Protocol) server manifest and fails, it now records two additional, more specific failure reasons alongside the existing ones like `host_server_unavailable` and `unresolved_mcp_server`:

- `opaque_mcp_server_id`

- `unknown_mcp_tool`

**Why**

More specific failure reasons make it easier to tell exactly why an artifact's MCP manifest was rejected, building on earlier additions to this same validation chain such as the first-party server name collision check.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### File write/edit stale-read checks now carry remote-call read baseline and host info

Write/Edit stale-read checks over remote calls now carry a read baseline and the serving host's name

**What**

When the Write and Edit tools are used through a remote call, the built-in check that guards against editing a file based on a stale read now also receives `readBaseline` (the state the read was based on) and `servedOn` (the hostname that handled the remote call), in addition to the guard state it already tracked.

**Why**

Carrying this extra context lets the staleness check account for differences between the machine that served a file read and the one performing the write, which matters when remote calls can be served from different hosts.

- Area: Elsewhere
- Names: `readBaseline`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Command-line entrypoint telemetry routed through new normalizer

Command-line entrypoint telemetry now goes through a normalizer instead of reading the raw environment variable

**What**

The `entrypoint` field sent in telemetry now comes from a normalizing function applied to the entrypoint value, falling back to `"other"` if nothing is found. Previously it read the `CLAUDE_CODE_ENTRYPOINT` environment variable directly and fell back to `"cli"`.

**Why**

Routing the value through a normalizer and changing the fallback from `"cli"` to `"other"` likely produces more consistent and accurate entrypoint labels in telemetry, though the finding doesn't specify what the normalizer changes about the value.

- Area: Telemetry
- Names: `CLAUDE_CODE_ENTRYPOINT`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP tool calls now mark session as 'parked on user' while awaiting elicitation

MCP tool calls now flag the session as waiting on the user while an elicitation prompt is pending

**What**

When an MCP (Model Context Protocol) tool other than the configured permission-prompt tool starts waiting for user input, Claude Code now marks the session as 'parked on user' by incrementing an internal counter used for idle detection, and releases it again once the wait ends.

**Why**

This should prevent a session from being wrongly treated as idle while it's actually waiting on the person to respond to an MCP tool's prompt, which matters for any idle-timeout or idle-detection behavior tied to that counter.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin telemetry site map gains command.run and command.describe hooks

Plugin hook telemetry adds command.run and command.describe event types

**What**

The internal dispatch table that instruments plugin hooks for telemetry adds two new event types, `command.run` and `command.describe`, alongside existing ones such as `tool.call` and `prompt.submit`.

**Why**

This extends telemetry coverage to plugin hooks tied to running and describing commands, building on the existing set of hookable events like `tool.call` and `prompt.submit` that plugins built from function hooks can already listen for.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Remote tool-call protocol adds a read_baseline field

Remote tool-call requests can now include a read_baseline field

**Unclear.** What read_baseline is used for or how it affects tool-call approval is not stated in the finding.

**What**

The internal message format used for remote/cloud tool-call requests (part of the remote-control protocol) now accepts a `readBaseline` value, which gets sent out as `read_baseline` in the request, but only when no approval has been given yet.

**Why**

This is an internal protocol addition for how Claude Code communicates with remote or cloud-connected sessions; it does not change anything a user directly interacts with.

- Area: Elsewhere
- Names: `read_baseline`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Agent spawn telemetry records workflow phase and non-interactive request shape

Agent spawn telemetry now records workflow phase and non-interactive request details

**What**

When Claude Code spawns an agent or subagent (a task delegated to run somewhat independently), the internal event it records now optionally includes `workflowPhase`, `requestShape`, and `requestNonInteractive` fields.

**Why**

This is internal telemetry used to understand how agents are being spawned, including whether the request came from a non-interactive (scripted) context and what phase of a workflow it belongs to. It doesn't change user-facing behavior.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Git config reads now report a specific failure cause instead of returning null

Git config read failures now report a specific cause instead of silently returning nothing

**What**

The internal helper that reads a repository's `.git/config` file (used, for example, to figure out the remote repository's identifier) now returns a structured result with `{ok, cause}` when it fails, instead of just returning null. The possible causes are `pointer_file`, `read_failed`, `unsafe_path`, `not_a_file`, and `oversize`.

**Why**

This makes failures to read git configuration easier to diagnose, since the specific reason (such as an unsafe file path or a file that's too large) is now distinguishable instead of being an opaque failure.

- Area: Git
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### dir-sync git-worker turn-end telemetry gains an 'unchanged' outcome and a report toggle

Directory-sync turn-end telemetry adds an 'unchanged' outcome and a way to skip reporting

**What**

The internal function that reports on the directory-sync git worker at the end of a turn now takes a third parameter (defaulting to true) that controls whether the `ccr_dir_sync_git_worker_turn_end` telemetry event fires at all. Its success branch, which previously matched 'shipped' or 'nothing_to_send', now also matches a new 'unchanged' outcome.

**Why**

This is internal telemetry refinement for the directory-sync system, distinguishing a turn where nothing changed from one where changes were sent, and allowing that reporting to be turned off when not needed.

- Area: Cloud Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### dir-sync between-tools publish telemetry now tracks how long the sync was held

Directory-sync publish telemetry now tracks how long a sync was held before sending

**What**

The directory-sync 'between tools' publish logic was rewritten to start a due-check and await a snapshot-taken signal, and now reports a new `held_ms` field, alongside the existing `outcome` and `duration_ms`, in the `tengu_dir_sync_between_tools_publish` telemetry event.

**Why**

`held_ms` shows how long a sync was held before being published, giving a clearer picture of sync timing in the directory-sync system beyond just how long the operation itself took.

- Area: Cloud Sync
- Names: `held_ms`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Growthbook experiment targeting gains a slackTagConnected attribute

Feature-flag targeting can now use whether an account has Slack tagging connected

**What**

Claude Code's feature-flag system (used to test and roll out changes gradually) now includes whether an account has Slack tagging connected as a piece of context. This value is passed into the flag evaluation and is also used as part of the cache key, alongside the account and organization identifiers, so cached flag results can differ based on Slack tag connection status.

**Why**

This extends earlier groundwork for a Slack tagging integration, letting Anthropic target or segment experiments based on whether an account has that connection, rather than only by account or organization identity.

- Area: Internals
- Names: `slackTagConnected`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### late-tool-additions rejection message now also mentions inline-tools fallback

Rejected late-tool-addition warning now also mentions falling back to inline tools

**What**

When Claude Code rejects a late addition of a tool-related beta feature, the warning it logs now also notes that, if there's no ToolSearch feature available, the fallback is to inline tools instead. Previously the message only mentioned falling back to the ToolSearch announcement. The rejection still stays in effect ('sticky') until `/clear` or `/compact` is run.

**Why**

This makes the internal warning more accurate about what actually happens when a late tool addition is rejected, which is useful context for anyone diagnosing why tools behave differently until the conversation is cleared or compacted.

- Area: Tool Search
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Session keepalive heartbeat can now be 'parked on user' and skip sending

Session keepalive heartbeat can now be skipped entirely while 'parked on user'

**What**

Claude Code's session keepalive mechanism (which periodically signals that a session is still active) now checks first whether the session is "parked on user" — a state waiting on the user. If so, it logs a debug event noting the reference count and parked state, and skips the normal heartbeat activity entirely.

**Why**

This avoids sending unnecessary keepalive signals while a session is simply waiting on the user, which should reduce needless background activity in that state.

- Area: Session Management
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### TLS-to-relay warning for the agent proxy is now deduplicated via a gate check

TLS-to-relay warning for the agent proxy is now gated to avoid repeated logging

**What**

When a client sends TLS traffic directly to the agent proxy's relay port (instead of going through the normal path), Claude Code used to log a warning every single time this happened and also increment a telemetry counter. Now, the warning is only logged when an internal gate check (`agent_proxy_request_tls_to_relay`) returns true, and the separate telemetry increment for this case has been removed.

**Why**

This reduces noisy, repeated logging for the same underlying condition, controlling whether and how often this particular warning appears.

- Area: Agent Proxy
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Deferred-tools-pool telemetry gains toolSearchAbsent/resurfacedCount fields tied to a new tool-search-absent mode

Deferred-tool telemetry now tracks resurfaced tools and whether tool search is unavailable

**What**

Claude Code can defer loading some tools until they're needed, pulling them from a pool. The internal event that logs changes to this pool, `tengu_deferred_tools_pool_change`, now records two new fields: `toolSearchAbsent`, which reflects whether tool search itself is unavailable, and `resurfacedCount` (with related `surfacedNames`), which tracks tools that reappear in the pool rather than being newly added. This sits alongside the existing added/removed/pending/failed counters.

**Why**

This is internal telemetry that helps track how the deferred-tools system behaves, including cases where tool search isn't available; it doesn't change what you see or do.

- Area: Tool Search
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Fast-resume worktree reset now logs why it was skipped, and picks filter-driver-aware git args

Fast-resume worktree checks now log a specific reason when they bail out instead of failing silently

**What**

When Claude Code tries to quickly resume an existing git worktree, it first checks the repository's status. If that status check fails or shows uncommitted changes, it now logs a specific diagnostic message, such as `status failed (code N)` or `tree read dirty under filter-driver-off pins`, instead of just quietly giving up. The path also now accounts for filter-driver arguments (git settings that affect how file content is transformed on checkout) when deciding how to proceed.

**Why**

Having a specific logged reason makes it much easier to figure out why a worktree resume was skipped, rather than it just silently falling back to a slower path.

- Area: Worktrees
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### System-init JSON payload gains a workspace_trust_recorded field

Startup system-init data now reports whether workspace trust was recorded

**What**

The system-init data sent when Claude Code starts up now includes a `workspace_trust_recorded` field, alongside existing fields like `current_permission_mode` and `hooks_applied`.

**Why**

This lets Claude Code track whether the decision to trust a workspace (folder) has been recorded, as part of its startup diagnostics.

- Area: Workspace Trust
- Names: `workspace_trust_recorded`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Headless cloud create/attach now support serve-only mode

Headless cloud session creation and attaching now support a serve-only mode

**Unclear.** What `serveOnly` mode actually restricts or enables, and how a user sets it, is not stated in the finding.

**What**

When starting a headless (non-interactive) cloud session, Claude Code now passes a `serveOnly` option through to the attach step, and the create step now goes through a renamed internal function (`runHeadlessCloudCreate`).

**Why**

This lets a headless cloud session run in a mode limited to serving, though the finding doesn't specify what triggers this option or what serve-only mode restricts.

- Area: Cloud Sessions
- Names: `serveOnly`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Startup gate now recognizes 'unwatched' REPL sessions

Claude Code now has an internal check for REPL sessions running unwatched in the background

**Unclear.** What this check is used to change or gate is not stated in the finding.

**What**

A new `isUnwatchedRepl` check was added to Claude Code's startup settings. It's true when a session is running in the background and also has no teammate agent ID attached.

**Why**

The finding doesn't say what behavior this check gates, but its presence suggests Claude Code is starting to distinguish sessions nobody is actively watching from normal interactive ones, likely to change some startup or notification behavior for them.

- Area: Startup
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### MCP telemetry now records negotiated legacy SSE transport

MCP connection telemetry now records when a connection fell back to the older SSE transport

**What**

The `mcp_connect` success telemetry event now includes a field showing whether the connection negotiated the legacy SSE (Server-Sent Events) transport rather than the current one.

**Why**

This gives visibility into how many MCP connections are still using the older transport, which is useful for tracking migration away from it, though it doesn't change connection behavior itself.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### session_activity_parked_leaked warning added for leaked parked-on-user activity

Claude Code now logs a warning if session activity tracking leaks a 'parked on user' count

**What**

Claude Code tracks internally when a session's activity is "parked" waiting on the user. A new warning, `session_activity_parked_leaked`, is now logged if the internal counter that tracks reasons for activity drops to zero while there's still a nonzero count of activity parked on the user. The leaked count is included in the warning, and an internal generation counter is bumped before the stale count is cleared.

**Why**

This is an internal consistency check, not a user-facing feature. It helps catch a bookkeeping bug where the app thinks it's still waiting on you when it shouldn't be, which could otherwise cause confusing hangs or stuck states.

- Area: Session Management
- Names: `session_activity_parked_leaked`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Nested blocked agent chains now release a park callback on unblock

Nested blocked agent chains now properly release their pending callback when unblocked

**What**

When a chain of blocked, nested agents (agents waiting on each other) gets unblocked, Claude Code now runs a stored callback for that chain via a new `releaseNestedChainPark` mechanism, then clears the stored callback (`nestedChainUnparks`) so it isn't run again.

**Why**

This is internal plumbing for how nested agent chains resume after being blocked. It reduces the chance of a leftover callback firing incorrectly or a chain failing to fully resume.

- Area: Background Agents
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Permission-behavior helpers now require strict string/boolean typing

Permission decisions from hooks now require exact string and boolean types instead of loose truthy checks

**What**

Hooks (custom scripts that can intercept and influence Claude Code's actions) can return values that tell Claude Code to allow, ask about, or deny an action. The code that builds these deny/ask/allow decisions now checks values more strictly: it requires `typeof e === "string"`, `typeof n === "string"`, and `r === true` explicitly, rather than accepting any value that happens to be truthy.

**Why**

This tightens how hook output is validated, so a hook returning an unexpected value type (like a number or an object) won't be silently treated as if it meant "allow" or "deny." It makes permission decisions driven by hooks more predictable.

- Area: Hooks
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New `historical` field on session messages for Remote Control replay

Session messages gained a historical flag used by Remote Control when replaying past messages

**What**

Session messages now carry an internal `historical` true/false field. It's set by the Remote Control bridge (the component that lets you control a Claude Code session remotely) on messages it sends up to the session server, and it's also set by the server itself on deliveries it replays.

**Why**

This lets Remote Control and the session server tell apart messages that are being replayed from history versus messages happening live, which matters for correctly reconstructing session state on reconnect or replay.

- Area: Remote Control
- Names: `historical`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Self-edit consent for artifact live replies now tracks explicit allow, not just decline

Consent tracking for live artifact replies now distinguishes an explicit allow from a decline

**What**

When a live artifact session (a shared, interactive Claude Code output) asks for consent to send replies, Claude Code now records an `allowed: true` flag on the pending consent entry when you explicitly grant it. An entry is only moved to `declined` if it wasn't already marked as allowed.

**Why**

This prevents an explicit "allow" from later being incorrectly overwritten or reported as a decline, making consent state for artifact replies more reliable.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Deferred consent payload tracked separately in session verification cache

Session verification now separately stores a payload whose consent was deferred

**Unclear.** What deferredPayload is later used for is not stated.

**What**

Claude Code's session verification cache now has a dedicated `deferredPayload` slot. When a verified payload arrives with `consentDeferred` set, it's stored there in addition to being set as the current verified payload.

**Why**

This keeps a deferred-consent payload available separately from the normally verified one, likely so Claude Code can act on or revisit it once consent is actually given.

- Area: Artifacts
- Names: `consentDeferred`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Agent-proxy bad-event telemetry now rate-limited with suppression counting

Bad agent-proxy events are now rate-limited in telemetry, with a count of how many were suppressed

**What**

A new internal helper groups "bad event" telemetry from the agent proxy by event type and uses a token-bucket rate limiter to avoid logging the same kind of bad event repeatedly. When logging resumes after a period of suppression, it reports a `suppressed_since_last` count of how many were skipped in the meantime.

**Why**

This keeps telemetry from being flooded by repeated identical error events, while still preserving a count of how many were dropped so the scale of the problem isn't lost.

- Area: Agent Proxy
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### cli_teleport_relay_ended replaces generic upgrade_teleport_cache logging for device_tool_requested

Teleport relay reverts caused by a requested device tool now log a dedicated event instead of a generic one

**What**

When a teleport relay (an internal connection-forwarding mechanism) reverts specifically because a `device_tool_requested`, Claude Code now logs a dedicated `cli_teleport_relay_ended` event at info level, instead of the previous generic `upgrade_teleport_cache` telemetry event.

**Why**

This makes it possible to distinguish this specific cause of a relay ending from other, unrelated cache-upgrade events in telemetry, which should make diagnosing relay behavior clearer.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Slack entrypoint detection extended with a second check

Detecting Claude Code running inside Slack now checks a second source in addition to the environment variable

**Unclear.** What the second detection source checks (referred to only as an internal function) is not specified.

**What**

Claude Code already detected when it was running inside Slack by checking whether the `CLAUDE_CODE_ENTRYPOINT` environment variable was set to `claude_in_slack` or `claude-in-slack`. Now a second check has been added that looks at a different source for the same values.

**Why**

This makes the Slack detection more reliable by not depending on a single source, though the finding doesn't specify what the new source is or why the first check alone was insufficient.

- Area: Slack Integration
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Thread-state summary string for async/threaded conversations

A new helper generates a 'Thread state' summary showing when the user last wrote and how many replies followed

**Unclear.** Where this thread-state summary is shown to users or used internally is not stated.

**What**

A new helper builds a human-readable summary for asynchronous or threaded conversations, in the form: "Thread state: the user last wrote {relative time}. Claude has sent {N} replies since then."

**Why**

This gives a quick, plain-language snapshot of where a threaded conversation stands, likely for contexts where a conversation continues across multiple separate messages over time.

- Area: Projects
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### 'dev_intent' recognized as a routine system-message subtype

The 'dev_intent' system message subtype is now filtered as routine, like other benign background messages

**What**

Internal message-filtering and deduplication logic now treats a system message subtype called `dev_intent` the same way it treats other routine, benign subtypes like `files_persisted`, `mirror_error`, and `vcs_state_changed`. This means it gets consistently skipped or filtered rather than being handled as an unrecognized message type.

**Why**

This keeps a new category of routine internal signaling from being surfaced or mishandled as if it were unexpected, consistent with how other background status messages are already treated.

- Area: Elsewhere
- Names: `dev_intent`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### wire_ingest_context telemetry/field added to tool-use messages

Tool-use messages now carry a new wire_ingest_context field alongside existing wire tool inputs

**Unclear.** What wire_ingest_context is used for, or where it's consumed, is not stated.

**What**

When Claude Code serializes assistant messages that use tools, it now includes a new `wire_ingest_context` field (`wireIngestContext` internally) alongside the existing `wire_tool_inputs` data. It's filtered to only include keys that are actually present in the tool's inputs.

**Why**

This looks like additional internal bookkeeping attached to tool calls, though the finding doesn't say what this context is used for.

- Area: Telemetry
- Names: `wire_ingest_context`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### 'muted' field added to sync/upload telemetry event

A new 'muted' field is now included in sync/upload telemetry events

**Unclear.** What the muted field represents or when it is set is not stated.

**What**

A telemetry event related to syncing and uploading files now conditionally includes a `muted` field, alongside existing fields like `first_upload`, `synced_files`, and `other_window`.

**Why**

This is an internal telemetry addition; the finding doesn't specify what condition triggers it or what it's used to measure.

- Area: Cloud Sync
- Names: `muted`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### answeredToolUseIds tracked in session/turn state

Session state now tracks a list of answered tool-use IDs alongside superseded ones

**Unclear.** What functionality reads or depends on answeredToolUseIds is not stated.

**What**

Session and turn state now includes an `answeredToolUseIds` field in several places, alongside the existing `supersededToolUseIds` and `supersededToolNames` fields.

**Why**

This appears to help Claude Code keep track of which tool calls have already received a response, though the finding doesn't describe what specifically relies on this tracking.

- Area: Session Management
- Names: `answeredToolUseIds`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Transcript truncation now tracked with truncatedAtCap flag

Saved conversation transcripts now record whether a tool result was cut off for size with a new truncatedAtCap flag

**What**

When a tool's output is too large and gets shortened before being saved in the conversation transcript, Claude Code now also records a `truncatedAtCap` true/false marker, alongside the existing estimates of how many tokens the original and the saved version amounted to.

**Why**

This makes it easier to tell, when looking back at a transcript, whether a piece of tool output was cut off for being too large versus complete, which matters for understanding what Claude actually saw versus what was recorded.

- Area: Transcript
- Names: `truncatedAtCap`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Shutdown failsafe timer now exposes its fire time

Claude Code now records the exact time its shutdown safety timer is set to fire

**What**

Claude Code has a failsafe timer that forces a session to shut down if it doesn't close normally in time. When this timer is armed, Claude Code now also records the exact timestamp (`failsafeFiresAtMs`) at which it's set to fire, in addition to the timer itself.

**Why**

This is an internal bookkeeping change that makes it possible to know exactly when a pending forced shutdown will occur, which helps with diagnosing shutdown-related issues.

- Area: Session Management
- Names: `failsafeFiresAtMs`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New project_memory_list / project_memory_read permission actions

Two new permission actions, project_memory_list and project_memory_read, added to the project read-access whitelist

**Unclear.** What project memory is and how these actions are triggered in practice is not stated in the evidence.

**What**

The list of project-scoped actions that are treated as read-only for permission purposes now includes `project_memory_list` and `project_memory_read`, alongside the existing `project_info`, `project_read`, and `project_search`.

**Why**

This lets project memory be listed and read under the same permission handling already used for other project read operations.

- Area: Project Memory
- Names: `project_memory_list`, `project_memory_read`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Presence field added to artifact comments/messages

Artifact comments and messages now carry an optional presence field for human authors

**Unclear.** What information the presence field carries or how it is shown to users is not stated.

**What**

Comments and messages attached to artifacts (files Claude creates or edits that you can view and comment on) now include an optional `presence` field. It is only filled in when the comment or message comes from a human, not from Claude.

**Why**

The finding does not say what the field displays or how it is used, only that it exists and is populated for human-authored comments.

- Area: Artifacts
- Names: `presence`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Gateway-forced-login detection simplified/changed condition

The check for whether login is forced through a gateway was simplified

**What**

The internal logic that decides whether login is being forced through a gateway was simplified. It now treats login as gateway-forced whenever `forceLoginMethod` is set to `"gateway"`, or whenever `forceLoginGatewayUrl` is set at all, regardless of what `forceLoginMethod` is set to.

**Why**

Previously, a set `forceLoginGatewayUrl` only forced gateway login when `forceLoginMethod` was left unset; now it forces gateway login even if `forceLoginMethod` names something else, which changes how these two settings interact.

- Area: Auth
- Names: `forceLoginMethod`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### CRI/gateway loopback config validator gains an escape-hatch env var

Gateway loopback check now also covers cri.issuer and cri.policy.webhook.url, not just cri.jwks_url

**What**

The deployment-time check that rejects loopback addresses (like `localhost`) in gateway configuration still requires the `CLAUDE_GATEWAY_ALLOW_LOOPBACK` environment variable to be set before it will allow one through. This check now also applies to `cri.issuer` and `cri.policy.webhook.url`, in addition to `cri.jwks_url`.

**Why**

This widens the same safety net that was already in place for `cri.jwks_url` to two more configuration fields, so pointing any of these three settings at a loopback address without the escape-hatch variable set will still be treated as a fatal misconfiguration.

- Area: Elsewhere
- Names: `CLAUDE_GATEWAY_ALLOW_LOOPBACK`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### "design" removed as a standalone CLI action while design-consent/revoke/login remain

Plain "design" CLI action removed while design-consent, design-revoke and design-login remain

**Unclear.** What the standalone "design" action did, and whether it was actually reachable as a command, is not stated.

**What**

The internal list of CLI command categories no longer includes a standalone `design` entry. The related `design-consent`, `design-revoke`, and `design-login` actions are still present and unaffected.

**Why**

The finding does not explain what the plain `design` action did or why it was dropped, only that it is no longer in the category map while its related subcommands remain.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### "thread_state" added as a recognized prefix-delta/context category

New "thread_state" category joins prefix_delta and diagnostics in context tracking, with a related stampThreadState flag

**Unclear.** What data "thread_state" represents or when stampThreadState is triggered is not stated.

**What**

A new `thread_state` entry has been added to the same category lists that already track `prefix_delta`, `deferred_tools_delta`, and `diagnostics`. A related `stampThreadState` flag is now threaded through the merge logic that combines these events.

**Why**

This extends the existing system for tracking conversation-context updates (like prefix deltas) with a new category for thread state, though the finding doesn't specify what information that state carries or when it's stamped.

- Area: Projects
- Names: `thread_state`, `stampThreadState`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Consent tracking gains dropConsentDeferral()

Consent tracking gains a dropConsentDeferral method to clear deferred consent

**Unclear.** When or why a deferred consent would need to be dropped rather than recorded is not stated.

**What**

The internal state object that tracks consent for design/artifact features gains a new `dropConsentDeferral()` method. It clears any deferred consent payload directly, without going through the normal path used to record consent.

**Why**

The finding does not say when this is called or what problem it addresses, only that a way to discard a pending consent decision now exists separately from recording one.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### writerClass added to cowritten-artifact metadata

Cowritten artifact metadata now includes a writerClass derived from the user's permission role

**What**

Metadata attached to collaboratively-edited artifacts and documents, which already included `cowritten`, `agentDirect`, and `typeLocked`, now also carries a `writerClass` field. It is derived from whether the caller has an `owner` or `writer` permission role, and is used to decide whether a write applies to a single page or to the whole document.

**Why**

This lets the system scope collaborative edits differently depending on the editor's role, so an owner and a writer may not always have the same write scope on a shared artifact.

- Area: Artifacts
- Names: `writerClass`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### git diff for cloud directory sync now treats dirty submodules differently

Cloud directory sync's git diff now reports dirty submodules and short submodule summaries

**What**

When Claude Code syncs a cloud session's directory using `git diff`, it now passes `--ignore-submodules=dirty` instead of `--ignore-submodules=all`, and adds `--submodule=short`.

**Why**

Previously all submodule changes were ignored entirely during this sync. Now submodules that have been modified (dirty) will show up in the diff, with a short summary format, so uncommitted submodule changes are less likely to be silently missed during cloud sync.

- Area: Cloud Sync
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### InstructionsLoaded fallback check via sbe()

Claude Code now checks a fallback source to detect if InstructionsLoaded hooks are configured

**Unclear.** What `sbe` checks or where it sources its answer from is not stated in the finding.

**What**

The `InstructionsLoaded` hook fires when a CLAUDE.md file or a rules file is loaded into context, at session start or later when files are lazily loaded. Claude Code's internal check for whether any `InstructionsLoaded` hooks are registered now falls back to consulting `sbe("InstructionsLoaded")` instead of always assuming none are active when it can't find any.

**Why**

This makes detection of configured `InstructionsLoaded` hooks more reliable, reducing the chance that a hook that's actually set up gets incorrectly treated as absent.

- Area: Hooks
- Names: `InstructionsLoaded`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### "policyGate" made a lazy getter on commands/skills, and getArgumentCompletions wired alongside it

Command and skill registration now computes policyGate lazily, and wires up argument completions

**What**

When Claude Code registers a command or skill, the `policyGate` property (which governs what the command is allowed to do) is now computed lazily via a getter, only when actually accessed, instead of being computed and assigned up front. Alongside this, `getArgumentCompletions` is now passed through during registration.

**Why**

Making `policyGate` lazy avoids unnecessary work when it isn't needed, and passing through `getArgumentCompletions` means commands and skills can supply their own argument autocompletion logic when registered.

- Area: Slash Commands
- Names: `policyGate`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact/document type support extends recognized dialog schemas

Task status data can now carry an optional description and reply field

**Unclear.** What surface uses these new `description` and `reply` fields, and what they display, is not stated in the finding.

**What**

The schema used for task status now includes two new optional fields: `description` and `reply`.

**Why**

The finding doesn't say what feature uses these fields, but adding them to the task status schema suggests task-related dialogs or tools can now carry richer information, such as a written reply, alongside a task's status.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact auto-reply permission probe consolidated into shared helper

Artifact auto-reply permission checks now go through one shared helper instead of inline logic

**What**

When Claude Code automatically reacts to comments on an Artifact (a generated document or file shown in a side panel), it has to check whether it's allowed to reply to or edit that thread. That permission check used to be inlined with ad-hoc try/catch logic; it's now handled by a single extracted helper function that returns a structured result covering whether the check threw an error, was skipped, what was decided, whether it was denied, and the reasoning behind the verdict.

**Why**

This is an internal cleanup that consolidates repeated logic into one place, making the permission outcome easier to reason about consistently; it isn't expected to change what you see when Claude auto-replies to Artifact comments.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Local slash-command execution unified between direct and bridge invocation

Slash commands run the same way whether typed directly or sent through a remote bridge connection

**What**

When you run a slash command (a command starting with `/` that Claude Code handles immediately, like appending its result to the conversation), the underlying code path is now shared between two cases:

- running the command yourself in a normal session

- a command dispatched over a remote/bridge connection

Bridge-originated commands are now internally tagged with a `dispatchedOverBridge` marker so they can still be distinguished from locally typed ones.

**Why**

Unifying the two paths reduces the chance that slash commands behave differently depending on how they were invoked, since both now run through the same logic instead of two separately maintained implementations.

- Area: Slash Commands
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Denial-before-call check wraps tool permission evaluation for headless/classifier flows

New check catches tools denied right before they would have been called, for headless and classifier flows

**What**

A new wrapper runs the normal permission check and then, for flows like headless mode or the auto mode classifier, checks whether a tool looks like it was "denied before call" against a decision that hasn't already been settled. When that's triggered, Claude Code logs "`<tool name>` denied before call:" as a warning, discards the previously recorded decision for that tool, and converts it into the correct denial.

**Why**

This closes a gap where a tool could otherwise be called despite having effectively already been denied, making denial handling more consistent in headless and classifier-driven runs.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin enable telemetry now looks up plugin metadata asynchronously with directory context

Plugin-enable telemetry now looks up plugin metadata asynchronously with added directory context

**Unclear.** Nothing has been read yet about how the `tengu_plugin_enabled_cli` gate affects this on any account.

**What**

The `tengu_plugin_enabled_cli` telemetry event, sent when a plugin is enabled, now gathers its plugin metadata through an asynchronous lookup that also takes directory context into account, replacing the previous synchronous lookup. The enable-failure handler was also updated to receive this same extra context.

**Why**

This should make the telemetry recorded when enabling a plugin more accurate, particularly in cases where plugin metadata depends on directory context that the old synchronous lookup didn't account for.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Workflow run IDs get a dedicated format and telemetry hashing path

Workflow run IDs now use a dedicated ID format with their own telemetry hashing path

**What**

Workflow run IDs now follow a specific recognizable shape (a `wf_` prefix followed by hex characters). Internally, IDs matching this shape are now hashed and redacted differently from other custom identifiers before being included in telemetry data.

**Why**

This is an internal bookkeeping change affecting how workflow run identifiers are anonymized before being sent in telemetry; it doesn't change what you see or do when using workflows.

- Area: Workflows
- Names: `wf_`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New always-on constant changes plan-mode gating for artifact verify/asset-upload

Artifact verify and asset-upload actions now more often need per-action confirmation instead of a session-wide approval

**Unclear.** the finding doesn't fully specify which plan-mode scenarios are newly covered, only that the gating was broadened

**What

A new internal setting, on by default, works together with plan-mode checks to widen the cases where artifact actions like `verify` and `upload_asset` require you to confirm each individual action, rather than relying on a broader session-wide approval. This applies when the conversation may include text from a third party.

**Why

This adds an extra confirmation step in more situations for actions that publish or verify artifact content, guarding against a third party's text in the conversation triggering an artifact action without your explicit per-action say-so.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Abort handling reordered ahead of the 'process committed' guard

Abort-signal checks in tool-permission requests now run before the 'never resolves' hang guard, not only inside it

**What**

In the code paths that send tool-permission requests and control requests, checking whether the operation has been aborted now happens unconditionally and first. Previously, the guard that intentionally hangs forever (by returning a promise that never resolves) when the process is already committed only ran inside a conditional block; now that hang guard runs after the abort check, rather than being nested inside it.

**Why**

Reordering these checks means an abort is more reliably noticed before the code can get stuck in the intentional 'hang forever' branch, which should reduce cases where a permission or control request appears to freeze instead of properly cancelling.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Session stdin handling split by connection lane

Remote session stdin handling now differs by connection type, with non-bridge/BYOC input discarded via a new code path

**What**

Remote sessions no longer route all incoming keyboard/input data (stdin) through a single shared loop. Input for 'bridge' and 'BYOC' (bring-your-own-cloud) connections now goes through a function called `pumpStdinLane`, while other connection types are handled by a new `discardStdinLane` function instead.

**Why**

This separates how input is handled depending on the type of remote connection, so that connection types that shouldn't process stdin now explicitly discard it through dedicated handling rather than sharing logic meant for bridge and BYOC connections.

- Area: Sessions
- Names: `pumpStdinLane`, `discardStdinLane`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New telemetry timing marks added around UDS cross-session inbox startup, unconditionally on

Session startup now records timing marks around cross-session inbox setup, always on

**What**

When a session starts, Claude Code now records timing marks (`setup_uds_start`, `setup_uds_imported`, `setup_uds_end`) around loading and starting the cross-session inbox, a mechanism used for communication between sessions over a local socket (UDS). A new `profileStartup` option is passed in, which in turn enables three more timing marks (`uds_inbox_dir_ready`, `uds_inbox_listening`, `uds_inbox_key_published`) inside the inbox startup itself.

**Why**

These marks give more detailed timing data on how long cross-session inbox setup takes during startup, which can help diagnose slow session startup, though they don't change any user-visible behavior.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Artifact comment threads get stronger prompt-injection framing

Artifact comment threads now carry an explicit warning that comment text is untrusted and can't expand what Claude is allowed to do

**What**

The hidden header text wrapping artifact comment threads now spells out more clearly that:

- comment text is untrusted, since it's written by artifact viewers

- those viewers may be outside your organization

- a request embedded in a comment cannot widen the current task or grant new permissions, such as running commands, following links, touching unrelated files or configuration, or sending data or credentials

**Why**

This strengthens protection against prompt injection: someone leaving a comment on an artifact can't use that comment to trick Claude into doing more than the task actually calls for, even if the comment is phrased as an instruction.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Gateway auth backend: API key check now short-circuits to 'missing' before touching helper/env key

Gateway auth now immediately reports an API key as missing instead of checking apiKeyHelper or environment variables first

**Unclear.** the finding doesn't say what `Ao()` represents, so the exact condition that triggers the short-circuit isn't named

**What**

When using the 'gateway' authentication mode without a configured `Ao()` value, both the API key verification function and its status-check counterpart now immediately report the key as missing (with reason `missing`, as part of the `auth_api_key_verify` check), rather than first falling through to check `apiKeyHelper` (a command you can set to generate an API credential) or environment variables.

**Why**

This skips unnecessary lookup steps in gateway mode when the relevant condition isn't met, reporting the key as missing sooner rather than attempting the normal apiKeyHelper or environment-variable fallback path.

- Area: Auth
- Names: `apiKeyHelper`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Scheduled-task telemetry now anonymizes task IDs

Scheduled-task telemetry now hashes task IDs instead of sending them raw

**What**

When a scheduled (cron) task fires or is reported as missed, the telemetry event sent now runs the task's ID through a hashing step first, instead of including the raw task ID.

**Why**

This avoids sending a scheduled task's plain identifier in telemetry data, obfuscating it before it leaves your machine.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New RemoteSessionManager 'withholdable held send' tracking wired into a UI 'cloud message held' state

Remote sessions now show when a message you sent from the cloud is being held back

**Unclear.** The finding does not say what user-visible message or indicator appears when `cloudMessageHeld` is set, only that the state is threaded through to the message list.

**What**

When you send a message to a remote session (a Claude Code session you're controlling from another device, such as through Remote Control), the app can now hold that message rather than sending it immediately in some cases. A new tracking mechanism inside the remote session's connection logic notices when a send is being withheld, and updates a `cloudMessageHeld` state that the message list can display. This only applies to remote sessions.

**Why**

This gives you visibility into a case that previously had no on-screen indication: a message you sent from a remote device that hasn't actually gone out yet.

- Area: Sessions
- Names: `cloudMessageHeld`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Git working-tree snapshot sync now records detailed timing stats

Git status syncing now records how long the file listing and history read each took

**What**

When Claude Code takes a snapshot of your git working tree's state (used to keep track of file and commit changes), it now records timing details: `listingMs` (time spent listing the working tree), `historyMs` (time spent reading commit history), and `listingEmpty` (whether the listing came back empty).

**Why**

This is internal diagnostic data that helps identify whether slowness in git syncing comes from listing files or reading history, rather than a change you'll notice directly.

- Area: Git
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Cancel/escape handling gains an `isCloudMessageHeld` mode

Cancelling with Escape now behaves differently while a cloud message is being held

**What**

The logic that handles cancelling or interrupting Claude (via Escape or Ctrl-C) now accepts an `isCloudMessageHeld` flag. When this is set and the input box is empty, pressing Escape is treated similarly to cancelling while something is loading externally, and it affects whether the cancel actually goes through.

**Why**

This ties into the new handling for messages held back in remote sessions, making sure that cancelling behaves sensibly while a message you sent is still being withheld rather than sent.

- Area: Sessions
- Names: `isCloudMessageHeld`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Tool dispatch now tracks whether a read baseline was sent

Tool calls now record whether a stored read baseline was used to satisfy the read requirement

**What**

The internal function that dispatches tool calls now has a `noteReadBaselineSent` callback and records a new `readBaselineSent` flag on the outcome of a tool call. This connects to the new lookup that lets Read and Edit use a previously stored baseline reading for files synced from a remote host.

**Why**

This is bookkeeping that supports the new remote-sync read-baseline feature, letting Claude Code track when a file's read requirement was satisfied by a stored baseline rather than a fresh read.

- Area: Multi-Host Sessions
- Names: `readBaselineSent`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plan-mode 'ask before tool call' check now also considers a permission-mode condition

Plan mode's check before refusing a tool call now also looks at the current permission mode

**Unclear.** The finding does not describe what the specific permission-mode condition checks or how it changes outcomes in practice.

**What**

While in plan mode, Claude Code sometimes has to force a late refusal for a tool call that looks read-only but might not be. That check previously only looked at whether the call had been pre-approved. It now also factors in an additional permission-mode condition before deciding whether to refuse.

**Why**

This refines when plan mode blocks a tool call at the last moment, aiming to make the refusal decision line up more accurately with the actual permission mode in effect.

- Area: Plan Mode
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bash path-validation helpers gained an extra passthrough parameter affecting relative-path-after-cd checks

Bash safety checks gained a parameter that can skip the 'ask' prompt for reading a relative path after cd

**Unclear.** The finding doesn't specify which call sites now pass the new parameter as true, so it's unclear which real commands actually skip the ask requirement.

**What**

Several internal functions that check whether a bash command is safe to run were given a new trailing parameter. When set to true, it skips the requirement to ask for permission before reading a relative path that follows a `cd` in a compound command (like `cd some-dir && cat file.txt`), even when a rule is configured to deny that kind of `Read`.

**Why**

This changes when Claude Code will pause to ask before reading a file reached via a directory change in the same command, in cases where a deny rule for `Read` is otherwise in place. The finding does not say which callers now pass true for this new parameter, so it's unclear which specific commands are affected in practice.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Tip-shown telemetry categorization refactored into a shared helper

Tip telemetry now labels plugin-marketplace tips by their actual marketplace instead of a generic bucket

**What**

When Claude Code logs that it showed a tip (a `tengu_tip_shown` telemetry event), it now categorizes the tip using a shared helper function instead of inline logic. The new logic adds a specific case for tips that come from a plugin marketplace: instead of a generic label, these are now tagged with the actual marketplace id, or with `marketplace-plugin:org-marketplace` as a fallback when the specific id isn't available. Other tips are still labeled `org-tip` or `other` as before.

**Why**

This makes internal telemetry about which tips get shown more precise for plugin-marketplace tips specifically, which previously would have been grouped less specifically. It's an internal analytics change and doesn't affect what tips you see.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Local (non-jsx) immediate commands now bypass the dialog/panel host entirely

Local slash commands now run directly without opening a dialog panel; local-jsx commands still do

**What**

When you run a slash command, Claude Code used to route it through a dialog/panel host before executing it. Now, commands of type `local` (as opposed to `local-jsx`) run directly and log the `tengu_immediate_command_executed` event, skipping the panel-opening step entirely. Commands of type `local-jsx` still go through the dialog-host path as before.

**Why**

This should make plain local commands feel snappier since they no longer need to open and tear down a UI panel just to execute. It's an internal execution-path change, not a change to which commands exist.

- Area: Slash Commands
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Session-signal absorption now also updates a per-host aggregate

Session-signal tracking now also updates a per-host aggregate, alongside existing per-session tracking

**Unclear.** The finding doesn't say what this per-host aggregate is used for or what visible effect it has.

**What**

Internal tracking of "session signals" (state like which bash tools or tools have been used) now also updates a shared aggregate tied to the session's host, in addition to the existing tracking that was scoped to just the bash tool, host, and used-tools set. This happens both when signals are absorbed and when they are reset.

**Why**

This is internal bookkeeping that lets related state be tracked at the host level rather than only per individual session, which the finding doesn't further explain the purpose of.

- Area: Session Management
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New artifact-type instruction wording toggle tied to the 'artifact toolset' consolidation

Artifact instructions can now say 'action: read' instead of 'action: describe_type' when a newer artifact toolset is active

**What**

Some internal instructions used to always tell Claude to use `action: "describe_type"` when working with artifacts. Now, when a consolidated "artifact toolset" is active, the same guidance instead says `action: "read"`. Otherwise it keeps saying `action: "describe_type"` as before.

**Why**

This keeps the internal instructions consistent with whichever artifact tool interface is active, so Claude references the correct action name rather than an outdated one.

- Flag `tengu_cobalt_plinth_damson`: Not enough to say (read for one account on one subscription tier against v2.1.265; this account: no value returned, anonymous baseline: off, compiled default: off)
- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Frame unwatch/unsubscribe now reports relay-unavailable distinctly from generic refusal

Unsubscribing from a live artifact frame now reports a relay-unavailable error separately from generic refusals

**What**

When Claude Code stops watching ("unwatches") a live artifact frame and the underlying relay connection is unavailable or not being served, this is now tracked as its own distinct reason, capturing either the HTTP status code or a "relay down" flag. It's reported via a new `unwatch_relay_unavailable` telemetry event, separate from the existing `unwatch_client_policy` event that previously lumped this case in with generic refusals.

**Why**

This gives clearer visibility into why a frame stopped being watched, distinguishing a relay outage from a deliberate policy-based refusal, which should make diagnosing frame-related issues more precise.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Status/plan trigger function now also fires on turn start, not just user text

The status/plan check now also runs at the start of a turn, not only when you type text

**What**

An internal function that checks whether to show a status or plan update used to only run when there was user text to react to. It now also runs when a turn is just starting, even without new user text. When it sets a new status detail, it also clears out any previous `output` value.

**Why**

This means status or plan information can now be refreshed at the start of a turn rather than only in response to something you typed, which should make that information more consistently up to date.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Device-authorization OAuth schema field added

OAuth schema gains optional fields for device-authorization and token endpoints

**Unclear.** The finding only shows the schema definition, not where or how it's consumed, so its practical effect is unclear.

**What**

A new internal schema was added defining two optional fields, `device_authorization_endpoint` and `token_endpoint`, for use in OAuth-related configuration.

**Why**

This lays groundwork for supporting an OAuth device-authorization flow, though the finding doesn't say where this schema is used yet or what feature it enables.

- Area: Auth
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Gateway login force-selection simplified when already in gateway mode

Login is now forced to gateway mode whenever the session is already in gateway auth mode, not just via managed settings

**What**

When Claude Code resolves which login method to force, it now short-circuits straight to `"gateway"` whenever the session is already running in gateway authentication mode. Previously this forcing only happened when the managed setting `forceLoginMethod` was explicitly set to `"gateway"`.

**Why**

This closes a gap where a session already operating under a [cloud gateway](/docs/en/claude-apps-gateway) could otherwise be prompted to log in through a different method. Now the login flow stays consistent with the gateway mode the session is already using, on top of the existing managed-setting-based forcing.

- Area: Auth
- Names: `forceLoginMethod`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Subagent type-matching telemetry now records requested name length; fork override marks parent system prompt

Subagent-type mismatch telemetry now records the length of the requested name; forked teammates flag an inherited system prompt

**What

- Area: Subagents
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bash tool cwd-prefix stripping generalized and persisted as ingest context

The Bash tool's working-directory prefix stripping was generalized and its result is now saved for use across session resumes

**What**

The Bash tool previously stripped a leading `cd <directory> && ` prefix from commands using two separate, hardcoded checks — one for regular paths and one for Windows-style paths. This is now handled by a single shared helper that tries a list of candidate root directories. The directory that gets stripped is now also recorded per tool call in a new `wireIngestContext` map, which is saved and carried over (alongside the existing `wireToolInputs`) when a transcript is persisted or migrated.

**Why**

Saving this context means the working-directory prefix can be reconstructed consistently even after a session is resumed, rather than depending on re-deriving it each time.

- Area: Elsewhere
- Names: `wireIngestContext`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Declared-tool tracking on transcript ingest now distinguishes name-only announcements from full entries

Transcript ingest now separately tracks tool declarations that only announce a name versus full tool entries

**What**

When Claude Code reads in a transcript and processes declared MCP tools, it now keeps two separate records: `nameOnlyAnnouncements`, for declarations that only give a tool's name, and `entries`, for full tool declarations. Previously, only full entries were merged into the tracked state; name-only announcements weren't handled separately.

**Why**

This lets Claude Code distinguish a tool that's merely been announced by name from one that's been fully declared, which likely affects how it decides whether a tool is ready to use.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plugin sync now tracks per-plugin attestation alongside synced dirs

Plugin sync now records an attestation value for each synced plugin directory

**Unclear.** The finding does not say what the attestation value is used to verify or check.

**What**

When Claude Code syncs plugin directories, it now also computes an attestation value for each plugin directory and stores it alongside the list of synced directories, rather than storing just the directory list.

**Why**

This is internal bookkeeping for plugin sync; it gives Claude Code a way to verify or track the state of each synced plugin directory rather than just knowing it was synced.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Bash heredoc/pipe read-restriction check extended to always-deny host-credential rules

Bash heredoc/pipe protections now also account for always-deny host-credential rules

**What**

Claude Code blocks bash commands that use heredocs (multi-line input blocks) or pipes to read files outside your working directories. That check now also looks at the command's "always deny" rules, checking whether any of them target the current session and whether none of the other deny rules (aside from a host-credential rule) apply, before deciding whether to block the read.

**Why**

This tightens the existing protection against commands that try to read sensitive files (like host credentials) from outside the working directory, making the block more consistent with how always-deny rules are otherwise enforced.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New progress-tracking hook for transcripts/tasks (loadingStartTime, responseLength, totalPausedMs)

New internal tracker records loading time, response length estimate, and paused time per conversation

**Unclear.** What surfaces this tracked data to the user is not stated.

**What**

Claude Code now builds a small live tracking object for each conversation or task, recording when a turn or task started loading, an estimated response length (based on token count), and how much total time has been spent paused.

**Why**

The finding doesn't say what feature consumes this new state, but it's the kind of data that could feed a progress indicator or status display for ongoing turns and tasks.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Headless cloud create path now passes serveOnly

Headless cloud session creation now passes through a serveOnly option

**Unclear.** What the `serveOnly` option actually changes about headless cloud behavior is not stated.

**What**

When running Claude Code headlessly (without an interactive terminal) to attach to or create a session on Anthropic's cloud, the dispatch code now threads a `serveOnly` option through to the function that runs the headless cloud attach. The argument order and signature for the create path also changed.

**Why**

This is an internal plumbing change to support a `serveOnly` mode for headless cloud sessions; the finding doesn't say what behavior `serveOnly` triggers.

- Area: Cloud Sessions
- Names: `serveOnly`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### isUnwatchedRepl added to launch-arming policy checks

Unwatched REPL sessions are now checked against launch-refusal policy

**Unclear.** What exactly qualifies a session as an "unwatched REPL" is not detailed beyond the two internal conditions named.

**What**

A new check, `isUnwatchedRepl`, was added to Claude Code's policy checks for arming a session at launch. It's true when certain internal conditions hold, and it's now consulted alongside the existing armed-session check to decide whether an unwatched session should be ended, as if a launch refusal had applied.

**Why**

This extends launch-safety enforcement to cover sessions running unwatched, closing a gap where such a session might otherwise continue running when it should have been refused.

- Area: Startup
- Names: `isUnwatchedRepl`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Session `controlOnly` flag added to session-open options

Sessions can now be opened with a controlOnly flag, off by default

**Unclear.** What controlOnly actually restricts or enables for a session is not shown by the finding.

**What**

Opening a session now accepts a `controlOnly` option, a true/false setting that gets passed down into the low-level code that starts the session. It defaults to being unset, which behaves as false.

**Why**

The finding doesn't say what a control-only session restricts or enables, so it's not yet clear what this changes in practice.

- Area: Session Management
- Names: `controlOnly`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Slack-tag ('Claude Tag') sessions skip syncing remote eval feature flags to disk

Slack-connected ('Claude Tag') sessions now skip writing remote feature flags to disk

**Unclear.** Why Slack-tag sessions specifically need to skip the feature-flag disk sync isn't explained by the finding.

**What**

A new internal flag, `clientSlackTagConnected`, is set based on a `slackTagConnected` user attribute returned during authentication. When it's set, Claude Code now skips its usual step of syncing remote evaluation feature flags to disk entirely.

**Why**

This builds further on the still-largely-inert Slack tagging integration, adding a behavior difference for Slack-connected sessions, though the finding doesn't say why skipping the disk sync specifically matters for that case.

- Area: Slack Integration
- Names: `clientSlackTagConnected`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### New 'prefix lock heal declined' error marker feeds into request-retry classification

Retry logic now remembers when a 'prefix lock' auto-heal was declined, so it won't retry the same way again

**What**

Claude Code can hit a 400-style "prefix lock" error and attempt to automatically heal it. Now, if that auto-heal attempt is declined, the error gets marked with `prefixLockHealDeclined`, and the request-retry logic checks for that marker so it doesn't loop trying the same auto-heal again.

**Why**

This prevents Claude Code from repeatedly retrying an auto-heal that has already been declined, avoiding a wasted retry loop on this specific error condition.

- Area: API Protocol
- Names: `prefixLockHealDeclined`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Cross-session messaging (UDS inbox) startup path has its own telemetry funnel, still gate-checked and skippable

Startup of the cross-session messaging inbox now has its own telemetry steps and logs when it's gated off

**What**

The startup process for a cross-session inbox — a Unix-domain-socket based system that lets separate Claude Code sessions message each other — now has its own sequence of telemetry steps: `setup_uds_messaging`, `setup_uds_import`, `setup_uds_dir`, `setup_uds_listen`, and `setup_uds_publish`. If the underlying feature gate is off, startup logs that it's skipping this setup, noting it can still "late-bind" and turn on if a later GrowthBook (feature-flag) refresh enables it.

**Why**

This gives better visibility into whether and how the cross-session messaging feature starts up, and confirms it can activate later without a restart if the controlling flag flips on mid-session.

- Area: Startup
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### workspaceTrust added as a synced "preference"

The workspaceTrust setting now syncs as a per-user preference instead of being dropped

**What**

In the table that governs how settings propagate (for example to subagents or forked sessions), `workspaceTrust` is now classified as a `"preference"` rather than being dropped. This means the setting is intended to carry over as a per-user preference during settings sync.

**Why**

Previously this setting may have been lost when settings synced elsewhere; classifying it as a preference means a user's workspace trust choice is now preserved rather than reset.

- Area: Workspace Trust
- Names: `workspaceTrust`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### "thread_state" content-block type recognized in message/prefix-delta pipelines

Claude Code's context system now recognizes a new "thread_state" content type alongside prefix_delta and diagnostics

**Unclear.** The finding shows the new "thread_state" type and stampThreadState flag being wired in, but not what information it carries or what a user would see as a result; a related gate, `tengu_projects_thread_state`, has not been read yet, so nothing can be said about whether it's active.

**What**

Claude Code's internal message-building and result-merging code now recognizes a new content type called `thread_state`, joining existing types like `prefix_delta` and `diagnostics` that the conversation-context system already handled. A new `stampThreadState` flag runs through several of the functions that assemble messages and merge results, controlling when this new type gets attached.

**Why**

This is plumbing rather than a visible feature: it lets Claude Code carry an additional piece of state through conversations and workflows. What it actually shows or enables for a project is not yet clear from this change alone.

- Area: Projects
- Names: `thread_state`
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plan-mode third-party-text gate is a build-time constant, currently on

A plan-mode check for third-party text in the artifacts tool is currently wired on at the code level

**Unclear.** The finding shows the underlying constants are hardcoded true, but does not say what user-facing behavior the plan-mode check actually gates.

**What**

A helper used in Claude Code's artifacts tool, referred to internally as `AA(e)`, checks whether Claude Code is in "plan mode" (a read-only planning mode before changes are made) combined with a build-time switch. A related helper, `vU`, adds a second condition: it also triggers when an action is an unattended "ask" with a specific basis, or when plan mode is active under its own build-time switch.

**Why**

Both checks are currently hardcoded to be active in the compiled code, meaning the plan-mode behavior they guard is live rather than dormant, though the finding does not say what user-visible effect these checks produce.

- Area: Plan Mode
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Plan-mode override for the new consent gate is a hardcoded constant, not yet a real toggle

A new plan-mode override for Claude Code's artifact consent prompts is hardcoded on, not yet a real setting

**What**

Claude Code's new Artifact consent system, which decides whether actions like commenting on or reading an artifact need a live confirmation prompt, includes a check for whether Claude Code is in "plan mode" (its read-only planning mode). This check is controlled by a variable, `Cdn`, which is currently just hardcoded to `true` rather than being a real, adjustable toggle. A related variable, `EDe`, is also hardcoded to `true` and gates a similar plan-mode branch elsewhere in this consent logic.

**Why**

Because both values are fixed at `true` in the compiled code rather than driven by a setting, the plan-mode override for artifact consent checks is effectively locked on for now, ahead of whatever configurability is meant to follow.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 1/5

### Tool-search deferred-tools delta now has a fast latch path avoiding full recompute

Checking for newly available tools mid-session now uses a faster cached check first

**What**

The internal logic that decides whether to compute and announce a `deferred_tools_delta` (a signal that new tools have become available partway through a session) now first tries a quick cached check using `toolPoolRefreshes` and `aheadOfRequest`. It only falls back to the previous, more expensive full set of eligibility checks if that quick check doesn't resolve the question.

**Why**

This is a performance change: it avoids redoing full eligibility computation on every check, which should make detecting newly available tools mid-session cheaper without changing what tools end up available.

- Area: Tool Search
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Many tool definitions converted to a create(context) factory pattern

Several built-in tools were internally restructured to build their behavior from shared context instead of per-call

**What**

A batch of built-in tools, including task-killing tools, MCP resource listing and reading, MCP web search, and several self-hosted runner admin tools (pool status, pool sessions, pool secrets, runner list, session requeue), were rewritten internally. They now build their logic once from shared session context rather than receiving that context separately on every call.

**Why**

This is an internal code structure change with no described effect on behavior. It does not change what these tools do for the reader.

- Area: Tooling Architecture
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Publish/serve status now explicitly tagged when handling served vs published payloads

Internal publish/serve status handling now explicitly tags payloads as 'served' or 'published'

**What**

Two internal code paths that process publish and serve status now explicitly pass a status label, either `served` or `published`, when handling that data, instead of relying on a generic shared function without that distinction.

**Why**

This is an internal correctness/clarity change to how Claude Code distinguishes served content from published content internally. The finding does not describe any visible change in behavior.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### MCP control-channel request handlers (mcp_call, mcp_toggle, mcp_authenticate, apply_flag_settings, etc.) — no functional change found

No functional change found in MCP control-channel request handling, only internal variable renaming

**What**

A large section of code handling MCP control-channel requests (things like `mcp_call`, `mcp_toggle`, `mcp_authenticate`, `apply_flag_settings`, and related handlers) was reorganized, but the change appears to be limited to renaming internal variables.

**Why**

No behavior change is described here; this is bookkeeping in the code rather than something a user would notice.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Remote-control bridge control-request handling: no functional change found

No functional change found in remote-control bridge's control-request handling

**What**

The code that handles control requests over Claude Code's remote-control bridge, covering things like setting the model, setting max thinking tokens, setting permission mode, state changes, device hook registration, and announcing remote tools, was reviewed and found to consist almost entirely of variable renaming from minification.

**Why**

No new logic, message, or field was found compared to the previous build, so this doesn't change behavior for anyone using Claude Code.

- Area: Remote Control
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Search-list virtualization gains an onLayout callback

Virtualized search list gains a layout-reporting callback

**Unclear.** What consumes the reported layout information, or what visible effect it has, isn't stated.

**What**

The hook that powers Claude Code's virtualized message list (a list that only renders the visible portion for performance, used for search results) now also returns and uses an `onLayout` callback. A new invisible element is rendered alongside the list specifically to report layout information through this callback.

**Why**

This gives the list rendering logic a way to react to layout changes, though the finding doesn't specify what it's used for beyond that.

- Area: UI Components
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Plugin hook loading diff appears to be a rename-only refactor

Plugin hook loading code was refactored with renamed variables but no behavior change

**What**

The internal logic that registers plugin hooks (including skipping duplicate hook registrations and tracking errors for managed plugins) was refactored with renamed internal variables. No new messages, error codes, or behavior branches were added beyond what already existed.

**Why**

This is a code cleanup with no expected effect on how plugin hooks behave.

- Area: Plugins
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### CLI option class renamed (q -> Y) and error class renamed (Ht -> It); no behavior change

Internal CLI option and error classes were renamed with no change in behavior

**What**

Internally, the class used to build print-mode CLI flags such as `--permission-prompt-tool`, `--system-prompt`, and `--plan-mode-instructions` was renamed, and the class used for invalid-choice errors on those options was also renamed.

**Why**

This is a naming-only change with no effect on how these flags behave or appear to users.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Edit/Write/NotebookEdit-style tools refactored to a per-session `create()` factory

Edit, Write, and Read/PDF tools were refactored internally to build themselves from a per-session factory function

**What**

The internal implementation of tools like `Edit`, `Write`, and the reader that handles files and PDFs was restructured. Previously each tool had flat methods for checking permissions, validating input, and running. Now each tool has a `create()` factory function that builds those methods bound to the specific session and context of the current invocation, giving uniform access to things like permissions, the tool list, remote-call handling, and the active model.

**Why**

This is an internal code reorganization with no described effect on what these tools do from a user's perspective; it standardizes how the tools are built internally.

- Area: Tooling Architecture
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### policyHelper per-OS fallback no longer logs an info message or telemetry event on default-payload fallback

policyHelper default-payload fallback no longer logs an info message or telemetry event

**What**

When `policyHelper` (a program that computes managed settings at startup) has no per-operating-system entry that matches and falls back to a static default settings payload, Claude Code no longer logs an info message or sends a `settings_policy_helpers_per_os` / `fell_back_to_default` telemetry event for it. It now just returns the fallback result silently, with any messaging handled elsewhere in the code.

**Why**

This quiets a code path that previously generated a log line and telemetry event every time the default settings payload was used, though the finding doesn't say why the logging was removed or where, if anywhere, equivalent messaging now happens.

- Area: Managed Settings
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Unix domain socket startup pipeline gains named profiling phases

Startup timing now tracks five detailed phases of the local socket messaging setup

**What**

Claude Code's startup instrumentation for its local inter-process communication socket (a Unix domain socket, used for messaging between local processes) now tracks five distinct named phases: `setup_uds_messaging`, `setup_uds_import`, `setup_uds_dir`, `setup_uds_listen`, and `setup_uds_publish`. These cover the overall messaging setup, module import, directory readiness, socket listening, and publishing the authentication key.

**Why**

This is internal startup profiling that helps diagnose where time is spent during Claude Code's startup, rather than something a user configures or sees directly.

- Area: Startup
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Prompt cache diagnosis telemetry now allowlists diagnosisType values

Prompt-cache diagnosis telemetry now only sends recognized diagnosis types, replacing others with 'other'

**What**

The telemetry event `tengu_prompt_cache_diagnosis_received`, which records diagnostic information about Claude Code's prompt cache, now checks the diagnosis type against a list of recognized values before recording it. If the type isn't on that list, the event now sends the literal value `other` instead of the raw, unrecognized string.

**Why**

This keeps the telemetry data clean and predictable by preventing arbitrary or unexpected diagnosis-type strings from being recorded verbatim.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### WorktreeCreate hook path now conditionally used via Cwt() instead of hX()

The condition for using a WorktreeCreate hook instead of git's default was renamed and restructured

**What

- Area: Worktrees
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Skill-import 'reserved name/oversize/symlink' checks consolidated into a shared helper

Skill import safety checks (reserved names, oversized or symlinked files) are now shared code instead of duplicated

**What**

The checks Claude Code runs when importing a skill (a packaged set of instructions) — rejecting reserved directory names, catching symlinked or oversized `SKILL.md` files, detecting embedded plugin markers, handling multiple `SKILL.md` variants, and guarding against symlinks at the project scope — were previously duplicated for the Codex import path and are now consolidated into one shared function. The copy step was also changed to skip `skill.md` during the raw directory copy, avoiding a race where the file could be written twice.

**Why**

This is an internal cleanup: the same validation now applies consistently wherever skills are imported, and the double-write race fix should make imports slightly more reliable.

- Area: Skills
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Diff panel visibility/toggle logic simplified via Iwt() presentation check

The diff panel's fullscreen-vs-inline display logic was simplified into a single shared check

**What**

The `/diff` slash command's description and its immediate-display behavior now both rely on a single helper function that checks whether the current presentation mode is "fullscreen", replacing three separate condition checks that existed before. A related, unused code branch for rendering the diff panel in fullscreen mode was also removed from an unrelated part of the code.

**Why**

This is an internal cleanup that makes the fullscreen-versus-inline decision for the diff panel consistent in one place; it isn't expected to change what you see when running `/diff`.

- Area: Elsewhere
- Names: `/diff`
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### sandboxed Windows exec refusal error object changed shape

Windows sandbox command refusals now throw a different internal error object

**Unclear.** What practical difference the new error object shape makes, if any, is not stated.

**What**

When Claude Code's sandbox (a restricted execution environment) refuses to run a command on Windows because of policy, it now throws a `cre` error built from the command string, instead of the previous `Vte` error object.

**Why**

This is an internal implementation detail of how the refusal is represented in code. It doesn't change what happens visibly when a Windows sandbox policy blocks a command, but code that inspected the old error shape would need to account for the new one.

- Area: Sandbox
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Marketplace plugin errors: workaround with FA=500 budget constant added

New internal constants including a 500 budget value added near marketplace plugin/session-auth code

**Unclear.** The purpose of these constants and the passthrough usage schema is not stated.

**What**

Several new internal constants (`Oee=80`, `zee=128`, `Zee=5`, `FA=500`) and a passthrough usage schema were added in code related to OTLP telemetry and session authentication.

**Why**

What these constants control is not clear from the change itself, so no practical effect can be described.

- Area: Telemetry
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Image handling switched to Bun's native Image API

Image handling now uses Bun's built-in Image type instead of a custom wrapper object

**What**

A function that previously constructed a custom, frozen wrapper object to represent an image (holding call, signal, event, and origin data) now simply returns `new Bun.Image(...)`, using the image type built into the Bun JavaScript runtime instead.

**Why**

This simplifies image handling by relying on the runtime's native support rather than a hand-built substitute, though the finding doesn't describe any visible behavior change.

- Area: Images
- Names: `Bun.Image`
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### MCP resource metadata fetch de-duplication / discovery-state error type changed

Internal renames in the MCP OAuth login flow's error handling, with no apparent change in behavior

**Unclear.** Whether this is purely a rename or also changes how discovery-state errors are detected in some edge case is not established by the evidence.

**What**

Internal code in the MCP (Model Context Protocol) OAuth login flow was reworked: the check for a discovery-state error now looks for a differently-named error type, and several "persist failed" logging calls were renamed to use a different helper. This happened in both the regular and enterprise variants of the MCP OAuth client.

**Why**

These look like internal renames rather than a behavior change, so there's likely nothing for users to notice here.

- Area: MCP
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Session-list/'served' ordering now sorts by a filter predicate (Nxn) when kind is served

In the served session list view, matching entries are now sorted to the end instead of just being listed as-is

**Unclear.** What the filter specifically matches, and why those entries should sort last, is not stated in the evidence.

**What**

When Claude Code renders a list of sessions in the "served" view, it now sorts the list so that entries matching a particular filter appear last, rather than simply listing them in their original order.

**Why**

This changes the order sessions appear in within that specific list view, grouping matching entries toward the end.

- Area: Session Management
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### "Full output saved to:" persistence marker regex narrowed

The redaction pattern for "saved to:" file paths in truncated tool output now matches more phrasings

**What**

When Claude Code truncates long tool output and saves the full version to a file, it shows a note like "Full output saved to: " and redacts that path in certain places. The pattern used to find and redact that path now matches any phrasing ending in "saved to: ", not just the exact "Full output saved to:" text.

**Why**

This makes the redaction more reliable by catching variant wordings of the same message, reducing the chance a saved-output file path leaks through unredacted.

- Area: Tool Results
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### New file-system helper: statBigint

Claude Code's file-system layer gains a new statBigint helper alongside lstatBigint

**Unclear.** What calls this new method or what problem it fixes is not stated in the finding.

**What**

A new `statBigint` method was added to Claude Code's internal file-system abstraction, next to the existing `lstatBigint`.

**Why**

The finding doesn't specify the exact use, but this looks like an internal helper for getting file stat information with bigint-precision numbers, following a symlink rather than reporting on the symlink itself as `lstatBigint` does.

- Area: File System
- Names: `statBigint`
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Bash command permission dry-run check simplified to a single flag

A bash command permission check during streaming execution now relies on a single flag instead of two conditions

**Unclear.** What behavior difference, if any, this produces for users is not stated in the finding.

**What**

A guard used while checking bash command permissions during streaming execution used to bail out only when both a local flag and a `notRunning()` check agreed; it now bails out based on the local flag alone.

**Why**

The finding doesn't explain the practical effect, but simplifying two conditions into one suggests the `notRunning()` check was found redundant for this particular guard.

- Area: Permissions
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Image tool: budget computation failures now suppressed unless truly unexpected

Image sizing failures now fail silently unless the error is truly unexpected

**What**

When Claude Code works out how much of its image budget (the space limit for images sent to the model) a given image should use, that calculation can occasionally fail. Previously any such failure was always logged as an error. Now the code checks whether the failure is a recognized, expected kind; if so it quietly falls back to a default instead of logging, and only logs at error level when the failure is genuinely unexpected.

**Why**

This cuts down on noisy error logs for routine, already-understood failure cases while still surfacing genuinely surprising problems, making error logs more useful for diagnosing real issues.

- Area: Images
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Tool search unavailability reasons consolidated into one function with a new 'mcp_search_unavailable' case check

Reasons why tool search is unavailable for a model are now computed by one shared function

**What**

Tool search lets Claude look up available tools rather than having them all listed up front. The various checks for why tool search might be unavailable for a given model — such as the model or platform not supporting it, no tools being present in the request, the model not being registered, or MCP (Model Context Protocol) search being unavailable — were scattered across the code. They've now been consolidated into a single function that returns a reason code, used both by the main gating logic and by a new helper that specifically checks for the "MCP search unavailable" case.

**Why**

Consolidating these checks into one place should make it easier to keep the reasons consistent and to add or debug new unavailability cases going forward.

- Area: Tool Search
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Built-in tool classification gets a special-case exception for one built-in name

One built-in tool now gets a special-case exception in the built-in vs MCP classification logic

**Unclear.** The finding doesn't say which specific tool this exception applies to.

**What**

The internal logic that classifies a tool as MCP (Model Context Protocol), built-in, or undefined now takes an extra input and adds a special case: if a tool's name matches one particular built-in tool and none of the extra input matches a specific identifier, it's classified as "built-in" even in a situation where it would otherwise have failed the general built-in check.

**Why**

This fixes a case where that particular tool could be misclassified, ensuring it's consistently recognized as a built-in tool.

- Area: Tooling Architecture
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Git status collection command extracted into a shared constant array

Git status command used for context gathering now built from a shared constant, no behavior change

**What**

The `git status --short` command Claude Code runs internally to gather context now pulls its arguments from a shared named constant instead of an inline list, and an internal truncation-threshold variable (still 2000 characters) was renamed.

**Why**

This is an internal code cleanup with no effect on behavior.

- Area: Git
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Tool-result pairing debug messages now use structured/redacted formatting helpers

Tool-result pairing debug logs now numbered and formatted with redaction helpers

**What**

When Claude Code detects a mismatch between tool-use and tool-result messages (a structural check called `ensureToolResultPairing`), the debug and error messages it logs are now built differently: each message is numbered with an index, and tool-use IDs are formatted through a redaction/formatting helper and joined with a dedicated helper function, instead of being concatenated directly into a plain string.

**Why**

This makes these internal diagnostic logs more structured and consistent, and applies proper redaction formatting to identifiers that appear in them.

- Area: Elsewhere
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Workflow agent detail view fires telemetry on first expand

Expanding a workflow agent's detail view for the first time now sends a telemetry event

**What**

When you expand a workflow agent card's detail view for the first time, Claude Code now records a telemetry event before showing the expanded state.

**Why**

This is a usage-tracking change with no visible effect on how the card behaves; it simply lets Anthropic see when this expand feature is used.

- Area: Workflows
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Workflow agent detail scroll math generalized to arbitrary fold regions

Workflow agent card's expand/collapse scrolling logic was generalized to handle multiple collapsible regions

**What**

The calculation Claude Code uses to keep your scroll position steady when expanding or collapsing a workflow agent card's detail view was rewritten. Previously it handled a single hardcoded case (the collapsed prompt). Now it works with a general list of 'fold regions', each with its own end point and growth amount, so multiple collapsible sections can be accounted for.

**Why**

This is an internal refactor that supports more kinds of collapsible content in the agent card without the scroll position jumping around; it's not expected to change what you see, only to make future card layouts easier to support correctly.

- Area: Workflows
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### propose_skills and DesignSync-style tools refactored to per-call factory pattern

propose_skills and DesignSync tools refactored internally to a per-call factory pattern

**What**

The `propose_skills` tool, along with a nearby DesignSync-related tool, now build their input-validation, permission-check, and call logic inside a `create(r)` method that returns an object, instead of defining those functions directly on the tool's definition.

**Why**

This is an internal code restructuring with no described effect on behavior; it changes how the tool's implementation is organized rather than what the tool does.

- Area: Tooling Architecture
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Composer sidebar gains a `sidebarFill` prop, defaulting to filled (same visual as before)

The composer's side panel now has a toggle for whether its background fill shows

**What**

The layout component behind Claude Code's composer (the box where you type messages) gained a `sidebarFill` setting for its side panel. By default it behaves exactly as before, keeping the panel's background color filled in. When turned off, the background is left transparent instead.

**Why**

This is an internal option, not a user-facing setting, and the default keeps today's appearance unchanged. It gives the interface the ability to show the sidebar without a solid background in places that need it.

- Area: UI Components
- Names: `sidebarFill`
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Agents list screen instance now reused across re-renders

The 'claude agents' list screen now reuses its render object instead of recreating it each frame

**What**

The screen shown by the `claude agents` command now caches and reuses the same underlying screen/render object across re-renders, instead of implicitly building a new one every time the screen redraws.

**Why**

This is an internal efficiency change to how the agents list screen renders; it doesn't change what the screen shows.

- Area: Background Agents
- Names: `claude agents`
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### NotebookEdit tool converted to per-call factory pattern, now requires the originating message

NotebookEdit now requires knowing which message triggered it, matching other tools' internal structure

**What**

The `NotebookEdit` tool's permission-checking, input-validation, and execution logic have been moved into a per-call factory function, matching the pattern already used by other tools that are scoped to a specific agent or session. As part of this, `NotebookEdit`'s execution step now throws an error if it can't find the message that originally issued the call.

**Why**

This is an internal restructuring that brings `NotebookEdit` in line with how other tools are built, and it tightens the tool so it fails loudly if it ever loses track of the message that triggered it, rather than proceeding with missing context.

- Area: Tooling Architecture
- Names: `NotebookEdit`
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Hook lookup API reworked from Map lookups to accessor methods

Internal hook lookups switched from raw map access to dedicated accessor methods

**What**

Internally, code that checks whether a hook applies (for example, hooks that run when a UI component renders) used to look values up directly in maps using `.has(...)` and `.get(...)`. It now goes through dedicated methods, `r.hooks(...)` and `r.matcherFor(...)`, instead.

**Why**

This is an internal code cleanup with no expected effect on how hooks behave; it changes how the lookup is implemented, not what it returns.

- Area: Hooks
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### OAuth token refresh lock telemetry reordered / lock helper renamed

OAuth token refresh lock now reports its "acquired" event later, closer to the actual read check

**What**

When Claude Code refreshes an OAuth (login) token, it briefly locks a file to coordinate with other processes. The `tengu_oauth_token_refresh_lock_acquired` telemetry event that marks this used to fire right after the lock file was acquired; it now fires later, immediately before the strict read-check that follows. The internal helper that acquires the lock was also swapped for a different one.

**Why**

This is an internal reordering of when a telemetry event fires relative to the lock's actual use, which affects how accurately the event reflects the state of the lock at the time it's recorded.

- Area: Auth
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Embedded release-notes text updated for 2.1.265

Built-in release notes text updated for this version

**What**

The changelog text bundled inside Claude Code itself, the text shown by `/release-notes` or on startup when announcing what's new, has been refreshed for this release.

**Why**

This keeps the in-app changelog in sync with the current version so `/release-notes` shows up-to-date information.

- Area: Elsewhere
- Names: `/release-notes`
- Tier: You'll notice
- Useful: 1/5
- Signal: 0/5

### Artifact publish `root` validation reworked to use a new helper pair (Sl/Rl) instead of a manual prefix check

Artifact publish's `root` parameter now uses a dedicated trust-check helper instead of a raw string comparison

**Unclear.** What the new options passed into the file-processing calls actually control is not stated.

**What**

When publishing an artifact with a `root` parameter (used together with `files` to resolve where source files come from), Claude Code used to trust it only if it exactly matched, or started with, the current working directory. That check has been replaced with a call to a new pair of helper functions, and both the general file-copy path and the thumbnail-generation path now pass an extra set of options into their file-processing calls.

**Why**

This replaces a simple path-prefix comparison with a more structured trust check, which likely makes the validation more reliable across different directory setups than a plain string match.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### Artifact tool capability-cache lookup (`Io`) with no obvious external caller beyond internal artifact plumbing

Artifacts gain internal caching of server-declared capabilities, tracking whether they're known-empty or unknown

**Unclear.** What user-facing feature or check this capability cache feeds into is not shown by the finding.

**What**

A new internal function caches an artifact's server-declared capabilities, keyed to the specific tool call that fetched them, and reports whether those capabilities are known to be empty or are still unknown.

**Why**

This appears to be internal plumbing supporting artifact behavior rather than something a reader interacts with directly; the finding doesn't show what feature it enables.

- Area: Artifacts
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

### New `create()` factory form for the memory-read tool with a signal-only call context

The memory-read tool's internal setup was rewritten to a newer factory pattern, likely with no visible change

**What**

The tool that reads memory documents (likely the one behind `project_memory_read`) was restructured internally: instead of a plain method taking a store, path, and an abort controller, it now uses a `create()` factory function that returns an object whose call method takes a cancellation signal directly. This matches a newer coding pattern already used by other tools.

**Why**

This is an internal refactor rather than a behavior change, and it doesn't appear to affect what the tool does when reading memory documents.

- Area: Tooling Architecture
- Tier: Under the hood
- Useful: 1/5
- Signal: 0/5

## Removed

### /plan share (publishing the plan as an artifact) removed from the /plan command

The /plan share subcommand, which published a plan as a claude.ai artifact, has been removed

**What**

The `/plan share` subcommand has been removed entirely. It used to publish your current plan as a claude.ai artifact so it could be viewed outside the terminal. Running `/plan` now only shows `[open|<description>]` as valid arguments, with no `share` option.

Along with the subcommand, the related fallback message that told cloud-workspace users "the plan lives in the cloud workspace, so /plan share can't publish it from this machine yet" is also gone, since there is no longer a share path to fall back from.

**Why**

Anyone who used `/plan share` to hand off a plan as a shareable artifact will need another way to do so; the feature is no longer available from the `/plan` command.

- Area: Plan Mode
- Names: `/plan share`
- Tier: You'll notice
- Useful: 3/5
- Signal: 2/5

### plan-artifact skill/command appears to have been removed as a standalone user-invocable command

The plan-artifact command that published a plan as a shareable Artifact appears removed

**What**

The function that registered a "plan-artifact" skill — user-invocable, with the menu description "Publish a plan as a shareable Artifact" — has been replaced with a plain helper that only builds prompt text internally. No trace of the "plan-artifact" name or its menu entry remains in the bundle.

**Why**

This means the standalone plan-artifact command is no longer available to users to invoke directly, following earlier removals of other artifact-related skills like the spreadsheet and presentation deck ones.

- Area: Artifacts
- Names: `plan-artifact`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5

### Possible removal of the 'design' local command (uncertain, likely diff artifact)

A code diff hints the 'design' slash command may have been removed, but this is uncertain

**Unclear.** Whether the 'design' command was actually removed, or this is just an incidental code-reorganization artifact, is not established.

**What**

A piece of code that defined a `design` slash-command (described as "Grant or revoke Claude agent access to your Design projects") appears to have been replaced by unrelated internal code in the same part of the program. It's not clear whether this means the `design` command was actually removed, or whether this is just an artifact of how the code was reorganized.

**Why**

If you used the `design` command to manage Claude's access to Design projects, it's worth checking whether it still works, since the evidence doesn't confirm one way or the other.

- Area: Design Command
- Names: `/design`
- Tier: You'll notice
- Useful: 2/5
- Signal: 2/5
