Repository navigation
nebula started from inside a Claude Code session no longer passes that session's identity to everything it starts, so Claude agents under it keep their transcripts - #120
Open
DrewBradfordXYZ wants to merge 1 commit into
Conversation
…t session's identity to everything it starts, so Claude agents under it keep their transcripts
A Claude Code session sets CLAUDECODE, CLAUDE_CODE_SESSION_ID,
CLAUDE_CODE_CHILD_SESSION, CLAUDE_PID, its messaging socket and token, and
a few more on the shells it runs tools in. A daemon started from such a
shell (`nebula` typed by an agent) kept them and passed them to every
agent, terminal and `claude` probe it started, so each one believed it was
a sub-process of that other session. Claude Code turns its transcript off
for an inherited CLAUDE_CODE_CHILD_SESSION ("Transcript saving is off —
inherited CLAUDE_CODE_CHILD_SESSION marker"), so those agents wrote no
transcript: --resume found nothing, and a `nebula worktree` relocation came
back as a fresh session. They also talked to the other session's messaging
socket.
`nebula` now drops those variables from its own environment first thing,
for every subcommand, before any thread or child exists, and logs which
ones it dropped. Only session identity goes. User settings that share the
CLAUDE_CODE_ prefix (CLAUDE_CODE_USE_BEDROCK, an OAuth token) stay, and so
does CLAUDE_CODE_SSE_PORT, an IDE terminal's link back to the editor.
Claude Code's own tool-shell overrides, GIT_EDITOR=true (which makes a
bare `git commit` in a nebula terminal abort) and
COREPACK_ENABLE_AUTO_PIN=0, are dropped only at exactly those values and
only beside a session marker, so a user who sets either keeps it.
A daemon already running keeps its environment until it restarts.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What happens
When Claude Code runs a tool, the shell it uses carries variables that name that session:
CLAUDECODE,CLAUDE_CODE_SESSION_ID,CLAUDE_CODE_CHILD_SESSION,CLAUDE_PID, its messaging socket and token, and a few more. Any nebula daemon first started from such a shell keeps them, and every agent, terminal andclaudeprobe it launches inherits them.This doesn't take an unusual setup. Ask Claude, running in an ordinary terminal tab, to
nebula add .a project and nebula's own autostart (spawn_daemon) starts the daemon from Claude's tool shell.spawn_daemondetaches it into a session of its own, but it passes the environment through as it is. The same happens when the daemon is restarted from an agent's shell.docs/how-it-works.mdalready names this source forNO_COLOR— "exported by the agent shell the daemon was first started from" — and the daemon drops that variable before launching agents. The session variables do more damage thanNO_COLOR. Each Claude agent nebula starts believes it is a sub-process of the session that started the daemon, and Claude Code (checked on 2.1.288) turns transcript saving off for an inheritedCLAUDE_CODE_CHILD_SESSION. Its status line says "⚠ Transcript saving is off — inherited CLAUDE_CODE_CHILD_SESSION marker". Claude Code's env-var docs describe the same misclassification for "a background launcher first started by Claude Code's Bash tool". So:.jsonl, and--resumefinds nothing;nebula worktreerelocation does the same;To reproduce: from inside a Claude Code session, with no daemon running, have it run
nebula add <repo>. Then launch a Claude agent in nebula, send it a prompt, and look in~/.claude/projects/*/for its.jsonl. It isn't there. The sameclauderun with those variables removed writes the transcript.The change
Next to the
NO_COLORhandling, at a wider scope:nebuladrops these variables from its own environment first thing inmain(), for every subcommand, before any thread or child exists. So nothing it starts inherits them: the daemon, its agents, terminals and probes, and the TUI's own helpers. Autostart is covered because the daemon re-runsmain(). The daemon and TUI log which variables were dropped.nebula_core::env::HOST_CLAUDE_SESSION_VARS), not the wholeCLAUDE_CODE_prefix. User settings such asCLAUDE_CODE_USE_BEDROCK, an OAuth token andCLAUDE_CODE_SSE_PORT(an IDE terminal's link back to the editor) are kept.GIT_EDITOR=trueandCOREPACK_ENABLE_AUTO_PIN=0on its tool shells. In a nebula terminal,GIT_EDITOR=truemakes a baregit commitabort on an empty message. Both are dropped only at exactly those values, and only when a session marker is also present, so a user who sets them deliberately keeps them.worktree,spawn,open,rename) behave as before.Tests
nebula-core/src/env.rsfor which variables are picked out (pure, no process-env mutation).agents_never_inherit_the_claude_session_the_daemon_started_inintests/e2e_pty.rs, starts a daemon with the session variables set and checks that the agent's environment has none of them whileCLAUDE_CODE_USE_BEDROCKsurvives. With the one call inmain()removed it fails withCLAUDECODE leaked.cargo test --no-fail-fast -p nebula -p nebula-core -p nebula-daemonpasses. The exceptions aretui_drag_past_the_pane_top_autoscrolls_and_copies_the_runandnebula_open_from_inside_a_session_raises_the_file_tabs, which fail the same way on an untouchedmainon my machine.🤖 Generated with Claude Code