claude-code
claude-code copied to clipboard
Support persistent environment variables across Bash calls
Summary
Provide a mechanism for Claude to set environment variables that persist across Bash() tool calls within a session.
Use Case
Multi-step workflows need to maintain state:
# Step 1: Initialize
GIT_INDEX=$(mktemp)
# Step 2 (later Bash call): Use it
git --index-file=$GIT_INDEX ... # GIT_INDEX is gone
Currently each Bash() call is a fresh subprocess with no way to carry state forward except via files.
Current Workaround (Linux-only)
We discovered that appending to the session's shell snapshot file (~/.claude/shell-snapshots/snapshot-*.sh) persists variables, since it's sourced before each Bash() call:
# Find snapshot via SID
sid=$(cut -d' ' -f6 /proc/self/stat)
snapshot=$(ps -o cmd= --sid "$sid" | sed -n 's/.*source \([^ ]*snapshot[^ ]*\.sh\).*/\1/p')
# Append export
echo "export MY_VAR=value" >> "$snapshot"
This works but is fragile and Linux-only.
Suggested Implementation
Either:
-
Parse simple exports: Recognize
export VAR=valuein Bash output and persist it -
Dedicated command:
claude-env set VAR=value - Document the snapshot mechanism: If it's intended to be stable, document it
Option 1 aligns with shell semantics and requires no new syntax.
This startup hook fixes it for me :)
#!/usr/bin/env bash
# Read session JSON from stdin
INPUT=$(cat)
CLAUDE_SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty')
# Detect project context
PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")
PROJECT_NAME=$(basename "$PROJECT_ROOT")
PROJECT_BRANCH=$(git branch --show-current 2>/dev/null || echo "")
if [ -n "$CLAUDE_ENV_FILE" ]; then
# Session identity
echo "export CLAUDE_SESSION_ID=\"$CLAUDE_SESSION_ID\"" >> "$CLAUDE_ENV_FILE"
# Project context
echo "export project_root=\"$PROJECT_ROOT\"" >> "$CLAUDE_ENV_FILE"
echo "export project_name=\"$PROJECT_NAME\"" >> "$CLAUDE_ENV_FILE"
[ -n "$PROJECT_BRANCH" ] && echo "export project_branch=\"$PROJECT_BRANCH\"" >> "$CLAUDE_ENV_FILE"
# Inherit from mycc wrapper if present
[ -n "$myccpid" ] && echo "export myccpid=\"$myccpid\"" >> "$CLAUDE_ENV_FILE"
[ -n "$ai_model" ] && echo "export ai_model=\"$ai_model\"" >> "$CLAUDE_ENV_FILE"
fi
echo "Session ID: $CLAUDE_SESSION_ID"
exit 0