[FEATURE] Mods API: let a nested Claude Code session read its parent's session id and plugin state

Status Open
Reported on v2.1.296
Maintainer reply None cached
Activity 0 comments · opened Oct 11, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

When the model runs claude -p "..." through Bash, the child session starts with empty plugin state. A guard mod in the parent cannot hand its open blocks to the child. The child's copy of the mod cannot learn that it has a parent.

Claude Code 2.1.296 (macOS) describes $.state as "Named values held by the host for the session, each with a version". Its reader has no session parameter:

get: <P extends keyof PluginState & string, K extends keyof PluginState[P] & string>(ref: StateRef<P, K>) => Promise<StateRead<StateValue<P, K>>>;

$.session has id() and no parent.

Proposed Solution

  1. Record the parent session id for every Claude Code process that a session's tools start: the claude CLI, npx-launched Claude Code, and Agent SDK launches. The carrier must not change the child's own behavior (see #67603).
  2. $.session.parent(): Promise<{ sessionId: string } | undefined>.
  3. $.state.get(ref, { session: 'parent' }): read only, own keys, while the parent runs. The engine verifies the parent, so a forged variable cannot read another session's state.

Alternative Solutions

  • The parent mod can export state with $.env.set for the child's $.env.get. Every Bash child and MCP server then sees the blocked paths. A large value risks E2BIG. env -i drops it.
  • The Bash shell carries the undocumented CLAUDE_CODE_SESSION_ID. Inherited CLAUDE_CODE_* variables have broken nested sessions before (#96959).
  • A hidden --parent-session-id flag ("for analytics correlation") reaches teammate panes only. Mods cannot read it.

Priority

Medium - Would be very helpful

Feature Category

Developer tools/SDK

Use Case Example

Arrester (github.com/dot-agi/arrester) blocks detours after a hook, rule or classifier refusal. Its README lists a known limit: a nested claude command "does not inherit the open blocks". With this API, the child's Arrester reads the parent's open blocks at session.start.

Additional Context

Related, narrower: #99920 (id after a fork), #78303 (headless signal), #42656 (/branch parent id).

View original on GitHub ↗