Search Algorithm
typemux-cc searches for.venv by traversing parent directories upward from the opened file, stopping at the git repository root.
Search Flow
Implementation Details
Code reference:src/venv.rs:34-96
Search Rules
1
Starting point
Parent directory of opened file (not the file itself)
2
Verification
Check existence of
.venv/pyvenv.cfg (not just .venv directory)3
Boundary
Git repository root (obtained at startup via
git rev-parse --show-toplevel)4
Direction
Traverse upward through parent directories until boundary or
.venv foundExample Traversal
- Monorepo Structure
- Nested Projects
- No venv
project-a/src/main.py:- Check
project-a/src/.venv/pyvenv.cfg→ ❌ - Check
project-a/.venv/pyvenv.cfg→ ❌ - Check
monorepo/.venv/pyvenv.cfg→ ✅ Found
Git Toplevel Boundary
Why Git Toplevel?
The git repository root provides a natural boundary for venv search:- Prevents escaping workspace: Stops search from going into parent directories outside the project
- Performance: Limits search depth in deeply nested directory structures
- Semantic boundary: Git repo typically == project boundary
Fallback When Not in Git Repo
Ifgit rev-parse --show-toplevel fails (not in a git repo), search continues up to filesystem root (/ on Unix, drive root on Windows).
Code reference: src/venv.rs:9-32
Fallback .venv Search Order
At startup (before any files are opened), typemux-cc attempts to pre-spawn a backend with a fallback venv.Search Order
1
1. Git toplevel
Check
.venv at $(git rev-parse --show-toplevel)/.venv2
2. Current working directory
Check
.venv at $PWD/.venv3
3. No fallback
Start without pre-spawned backend (backends created on-demand)
src/venv.rs:98-155
Fallback Behavior Examples
- Monorepo (git toplevel .venv)
- Nested project (cwd .venv)
- No fallback
Cache Behavior and Limitations
Document Cache
When a file is opened viatextDocument/didOpen, typemux-cc caches:
- URI:
file:///path/to/file.py - Language ID:
python - Version: LSP document version number
- Text: Full file contents
- Venv: Resolved
.venvpath (orNoneif not found)
src/state.rs:30-37
When Venv is Re-searched
Always Re-search
textDocument/didOpen(explicit file open)- Cache miss on URI-bearing request (file not in cache)
Never Re-search
textDocument/didChange(uses cached venv)textDocument/hoveron cached file (uses cached venv)- Any request for a file already in cache
Cache Limitations
Example Problem Scenario
1
User opens file without .venv
2
User creates .venv
3
Cached venv still None
textDocument/hover on a cached file does not trigger venv re-search.4
Workaround: Reopen file
Workarounds for Stale Cache
Option 1: Restart Claude Code (Full Reset)
Option 1: Restart Claude Code (Full Reset)
Cleanest solution — clears all cached state.Pros: Guaranteed to work
Cons: Loses all open tabs, window state, etc.
Cons: Loses all open tabs, window state, etc.
Option 2: Close and Reopen File
Option 2: Close and Reopen File
Lightweight — only clears cache for specific file.In Claude Code:
Cons: Must repeat for each open file
- Close the file tab
- Reopen the file from file explorer
textDocument/didClose→ cache entry removedtextDocument/didOpen→ fresh venv search
Cons: Must repeat for each open file
Option 3: Create .venv Before Opening Files
Option 3: Create .venv Before Opening Files
Best practice — avoids the problem entirely.Pros: No cache staleness
Cons: Requires discipline
Cons: Requires discipline
Debugging Venv Detection
Enable Detailed Logging
Useful Log Queries
Manual Verification
To manually check if typemux-cc will find your.venv:
- From Project Root
- From Subdirectory
Why pyvenv.cfg?
typemux-cc checks for.venv/pyvenv.cfg (not just .venv directory) because:
- Standard marker: All virtualenvs created by
python -m venv,virtualenv, oruv venvcontainpyvenv.cfg - Avoids false positives: Prevents detecting unrelated
.venvdirectories (e.g., manually created folders) - Contains metadata:
pyvenv.cfgincludeshomepath to base Python interpreter
If your virtual environment doesn’t have
pyvenv.cfg, it’s likely not a standard virtualenv. typemux-cc only supports standard .venv environments (see Architecture: Non-Goals).Performance Characteristics
- Search time: O(depth) — typically 1-5 directory checks
- Cache lookup: O(1) — hash map lookup by URI
- Git toplevel: Cached on first call (single
gitsubprocess at startup)