Stamp CLAUDE_CODE_ENTRYPOINT so phone-started sessions appear in the resume pickers - #108
Stamp CLAUDE_CODE_ENTRYPOINT so phone-started sessions appear in the resume pickers#108jankarres wants to merge 1 commit into
Conversation
|
hey @jankarres. this looks valid today, but i’m hesitant to rely on an undocumented internal variable. bannthropic could start rejecting or filtering unknown values like |
d287216 to
0704871
Compare
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.
0704871 to
4f6fad3
Compare
|
Honestly, that one nagged at me too while I was writing it. So I went and looked at what the current CLI and SDK actually do with the value I changed in this PR. Undocumented: you're right, it is. What settled it for me is that Anthropic's own VS Code extension sets this same variable, to Unknown values: everywhere the CLI reads the entrypoint, it checks for one specific known name and falls through to that default otherwise. Leave the variable unset entirely and it just reports the value as "unknown". Which is also why I'd rather make up a name than borrow a real one. The real ones bring behaviour with them, Auth and billing: token billing only happens if an API credential is configured in the first place, so Stepping back for a moment on why I think this belongs in the CLI at all: the discovery already works in one direction. The session watcher picks up whatever I start at the desk, a terminal session or one from the VS Code extension, and surfaces it in the app. What's missing is the way back, and this variable is the only lever for it, since the pickers hard-code the filter and there's no setting anywhere near it. With this in, both sides finally see each other's sessions instead of one side seeing the other's. If you'd rather not carry it, that's fair, and it stays solvable, just not by default. We ran it exactly that way in our own setup before I opened this PR. The And if you start it by hand instead: Just not |
Sessions started from the app are written to
~/.claude/projectslike any other, and then neither/resumenor the VS Code session list will show them, because the Agent SDK stamps themsdk-tsand both pickers filter that out. This setsCLAUDE_CODE_ENTRYPOINT=shellularwhen the host spawns the Claude Code adapter, which is all it takes. Closes #107.ClaudeCodeoverridesspawnEnvOverride(), the hookACPalready provides for exactly this, and returns the value only when the operator has not exported one of their own. That is deliberate rather than lazy:spawnAgentProcessmerges the descriptor env overprocess.env, so putting it inBUILTIN_AGENT_DESCRIPTORSwould silently beat anyone who sets it themselves. The SDK defaults its own value the same way.The value is not arbitrary.
cliis rewritten tosdk-cliunder the SDK and lands back on the filter list; anything else outsidesdk-cli,sdk-tsandsdk-pyworks, andshellularalso labels the transcript with where the session came from.How I checked it
Built the CLI, pointed it at a local central and relay, paired the app and opened the agent's session list, since that is what makes the host spawn the adapter in the first place. Then read the environment out of
/procrather than trusting the code.With nothing exported, the host process has no
CLAUDE_CODE_ENTRYPOINTand the adapter underneath it comes up withshellular. Restart the same host withCLAUDE_CODE_ENTRYPOINT=operator-choiceand the adapter comes up withoperator-choice, so exporting your own still wins.tsc --noEmitandbiome checkare clean, and there are no tests in the package to add to. CI here only checks thatcli/schema.sqlis in sync; nothing in this change touches a migration, and regenerating it leaves the file untouched.Before you merge
shellularas the value is the part I would expect an opinion on, since it is what ends up in every transcript record. Any string outside the three filtered ones does the job.If anything here should be different, tell me and I will take care of it.