From d287216b1380669a8b88ede8786260fc61623da0 Mon Sep 17 00:00:00 2001 From: Jan Karres Date: Wed, 19 Aug 2026 12:18:58 +0200 Subject: [PATCH] fix(agents): keep Claude Code sessions visible in the resume pickers Claude Code records an entrypoint on every transcript record, and both of its resume pickers drop the ones that look machine-driven: /resume in the CLI and the session list in the VS Code extension each filter sdk-cli, sdk-ts and sdk-py. The Agent SDK that the ACP adapter runs on stamps sdk-ts unless the variable is already set, so a session started from the phone is written to ~/.claude/projects like any other and is then invisible at the desk, which is where you would want to pick it up. Set CLAUDE_CODE_ENTRYPOINT=shellular at spawn time, and only when the operator has not set one, the way the SDK itself does it. Baking it into the descriptor would win over an inherited value, since spawnAgentProcess merges the descriptor env over process.env. The value matters: cli is rewritten to sdk-cli when Claude Code runs under the SDK and is filtered again. Anything outside that set works, and shellular also labels the transcript by where it came from. --- .changeset/olive-donkeys-shout.md | 5 +++++ cli/src/agents/claude-code.ts | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 .changeset/olive-donkeys-shout.md diff --git a/.changeset/olive-donkeys-shout.md b/.changeset/olive-donkeys-shout.md new file mode 100644 index 0000000..73f8218 --- /dev/null +++ b/.changeset/olive-donkeys-shout.md @@ -0,0 +1,5 @@ +--- +"shellular": patch +--- + +- fix(agents): set `CLAUDE_CODE_ENTRYPOINT` when spawning the Claude Code adapter, so sessions started from the app appear in `/resume` and in the VS Code session list instead of being filtered out as SDK sessions. An operator who exports their own value keeps it. diff --git a/cli/src/agents/claude-code.ts b/cli/src/agents/claude-code.ts index dbf707a..8934217 100644 --- a/cli/src/agents/claude-code.ts +++ b/cli/src/agents/claude-code.ts @@ -1,8 +1,33 @@ import { BUILTIN_AGENT_DESCRIPTORS } from "./agents"; import { ACP } from "./base"; +/** + * Claude Code records an `entrypoint` on every transcript record, and both of + * its resume pickers hide the ones that look machine-driven: `/resume` in the + * CLI and the session list in the VS Code extension each drop `sdk-cli`, + * `sdk-ts` and `sdk-py`. The Agent SDK that the ACP adapter runs on stamps + * `sdk-ts` unless the variable is already set, so a session started from the + * phone lands in ~/.claude/projects like any other and is then invisible at + * the desk, which is exactly where you want to pick it up. + * + * Any value outside that filtered set fixes it, with one exception: `cli` is + * rewritten to `sdk-cli` when Claude Code runs under the SDK, and is filtered + * again. + */ +const DEFAULT_ENTRYPOINT = "shellular"; + export class ClaudeCode extends ACP { static create() { return new ClaudeCode(BUILTIN_AGENT_DESCRIPTORS["claude-code"]); } + + /** + * Only when the operator has not set one themselves, the way the SDK does + * it. Baking it into the descriptor would win over an inherited value, + * since `spawnAgentProcess` merges the descriptor env over `process.env`. + */ + protected override spawnEnvOverride(): Record | undefined { + if (process.env.CLAUDE_CODE_ENTRYPOINT) return undefined; + return { CLAUDE_CODE_ENTRYPOINT: DEFAULT_ENTRYPOINT }; + } }