[FEATURE] Persistent shell context (CWD, env vars) across Bash tool calls
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
Shell state (working directory, environment variables, virtualenv activation) does not persist between Bash tool calls. Every call resets to the project root. This creates a constant operational tax for any workflow that requires positional state.
Concrete impacts:
- Every Bash call must re-establish position: Commands that should be a single line become
cd /path && source venv/bin/activate && <actual command>. This adds noise to every invocation and wastes tokens on boilerplate.
- Git operations are unsafe: The CWD reset can silently change which branch is active when using git worktrees. A commit intended for a feature branch can land on
mainwith no warning. We maintain a dedicated rule file that mandates: "verify branch in the SAME command chain as git add and git commit" solely because of this behavior.
- Git stash is hazardous:
git stashdoes not save untracked files, andstash popafter a state reset can destroy work. Another safety rule exists solely for this.
- Virtualenv activation is lost between every call: Projects using Python virtualenvs require redundant
source venv/bin/activate &&prefixes on every Bash invocation. This is especially painful for multi-environment workflows.
- Environment variables set in one call are invisible to the next: Any
exportdone in a Bash call is gone by the next call, making iterative shell workflows impossible without chaining everything into a single invocation.
Proposed Solution
Any of these would significantly improve the experience, listed from highest to lowest impact:
- Persistent CWD across Bash calls (highest impact). After
cd /some/path, subsequent Bash calls should start in/some/pathinstead of resetting to the project root. This single change would eliminate the most common workaround pattern.
- Persistent env vars / virtualenv state. Environment variables set via
exportand virtualenv activations (which are just env var changes) should survive across Bash tool calls.
- Named shell sessions. Allow creating a named shell session that maintains full state between invocations. Example:
{"session": "my-project", "command": "pytest"}would run in whatever statemy-projectsession has accumulated.
- Configurable anchor directory. A setting (e.g.,
CLAUDE_BASH_ANCHOR_DIR) that auto-restores a specific directory after each call, rather than always resetting to the project root.
Alternative Solutions
We have built the following workarounds, all of which add complexity and cognitive load:
- A
git-branch-safetyrule that auto-loads every session, enforcing branch verification in the same command chain as git operations - A
git stashsafety rule requiringgit addof untracked files before any stash, because state loss makes stash dangerous - Convention of chaining all related commands with
&&in a single Bash call to maintain state within one invocation - Absolute paths everywhere to avoid CWD ambiguity
- System prompt instructions telling the model to never use
cdalone and to always use absolute paths
These workarounds consume token budget on every invocation and add fragility to every shell interaction.
Note: CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR exists but its behavior is the opposite of what is needed here -- it forces CWD back to the project root, rather than allowing CWD to persist.
Also see #26652 which proposes a per-call workingDirectory parameter. That is complementary to this request: per-call overrides are useful, but persistent state across calls eliminates the need to specify the directory at all after the first cd.
Priority
High - Significant impact on productivity
Feature Category
CLI commands and flags
Use Case Example
Scenario: Multi-agent orchestrator with specialist subagents
Our system runs 10+ specialist subagents, each operating in different directories and virtualenvs on the same machine:
- Agent A needs to work in
/root/projects/project-alphawith its virtualenv - Agent B needs to work in
/root/projects/project-betawith a different virtualenv - Each agent makes 20-50 Bash calls per task
Current behavior (every single call):
cd /root/projects/project-alpha && source venv/bin/activate && pytest tests/
cd /root/projects/project-alpha && source venv/bin/activate && python -m mymodule
cd /root/projects/project-alpha && source venv/bin/activate && pip install -e ".[dev]"
With persistent shell context:
# First call establishes state
cd /root/projects/project-alpha && source venv/bin/activate
# All subsequent calls just run the actual command
pytest tests/
python -m mymodule
pip install -e ".[dev]"
Across 10 agents making 50 calls each, that is 500 redundant cd && source prefixes per session. The token cost and error surface are substantial.
Additional Context
- Related: #27907 (CWD reset after context compaction -- a special case of this broader issue)
- Related: #16361 (CWD not persisting on Windows -- filed as bug, auto-closed)
- Related: #26652 (proposes per-call
workingDirectoryparameter -- complementary approach) - Platform: Linux (primary), but the issue affects all platforms
- The Bash tool documentation itself acknowledges this behavior: "Working directory persists between commands; shell state (everything else) does not." -- but in practice, CWD persistence is unreliable (see #27907, #16361)
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗