### Install LSP Backends with npm or pip Source: https://github.com/k-dash/typemux-cc/blob/main/README.md Install the required LSP backend for typemux-cc. Pyright is recommended and can be installed globally via npm or pip. Ty and Pyrefly are alternative options installable via pip. ```bash # pyright (default, recommended) npm install -g pyright # ty (by the creators of uv) pip install ty # pyrefly (by Meta) pip install pyrefly ``` -------------------------------- ### Install pyright and typemux-cc Source: https://github.com/k-dash/typemux-cc/blob/main/README.md Follow these steps to install pyright, disable the official plugin, and install typemux-cc from the marketplace. A restart of Claude Code is required after initial installation. ```bash # 1. Install a backend (pyright recommended) npm install -g pyright # 2. Disable the official pyright plugin /plugin disable pyright-lsp@claude-plugins-official # 3. Add marketplace and install /plugin marketplace add K-dash/typemux-cc /plugin install typemux-cc@typemux-cc-marketplace # 4. Restart Claude Code (initial installation only) ``` -------------------------------- ### Configure typemux-cc Backend and Logging Source: https://github.com/k-dash/typemux-cc/blob/main/README.md Configure typemux-cc by creating a configuration file. This example sets the LSP backend to 'pyright' and enables file logging to a specified path. The file uses KEY=VALUE format. ```bash mkdir -p ~/.config/typemux-cc cat > ~/.config/typemux-cc/config << 'EOF' # Select backend (pyright, ty, or pyrefly) TYPEMUX_CC_BACKEND=pyright # Enable file logging TYPEMUX_CC_LOG_FILE=/tmp/typemux-cc.log EOF ``` -------------------------------- ### Install typemux-cc via Claude Code Plugin Marketplace Source: https://context7.com/k-dash/typemux-cc/llms.txt Install the typemux-cc plugin and disable the official pyright plugin to avoid conflicts. Restart Claude Code after initial installation. ```bash # Install a backend (pyright is the default) npm install -g pyright # Disable the official pyright plugin to avoid conflicts /plugin disable pyright-lsp@claude-plugins-official # Add marketplace and install typemux-cc /plugin marketplace add K-dash/typemux-cc /plugin install typemux-cc@typemux-cc-marketplace # Restart Claude Code (required only for initial installation) ``` -------------------------------- ### Verify typemux-cc Installation Source: https://context7.com/k-dash/typemux-cc/llms.txt Verify that the typemux-cc plugin is installed and enabled by checking the Claude settings file. ```bash cat ~/.claude/settings.json | grep typemux ``` -------------------------------- ### Typemux-CC Doctor Output Example Source: https://github.com/k-dash/typemux-cc/blob/main/README.md Example output from the typemux-cc --doctor command, showing configuration, environment, and system details. This output is useful for understanding the current state and identifying potential misconfigurations. ```text typemux-cc v0.2.9 Config file: Path /Users/foo/.config/typemux-cc/config Status loaded Configuration: backend pyright (default) max_backends 8 (default) backend_ttl 1800 (default) warmup_timeout 2 (default) fanout_timeout 5 (default) log_file /tmp/typemux-cc.log (config: /Users/foo/.config/typemux-cc/config) Environment: Backend binary pyright-langserver Path /usr/local/bin/pyright-langserver Version pyright 1.1.350 Git toplevel /Users/foo/project Fallback venv /Users/foo/project/.venv System: OS macos (Darwin 24.0.0) Arch aarch64 ``` -------------------------------- ### Persistent Typemux-cc Configuration File Setup Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Set up a persistent configuration file for typemux-cc in the user's config directory. This method allows for more permanent settings, including backend selection, log file output, and log level. ```bash mkdir -p ~/.config/typemux-cc cat > ~/.config/typemux-cc/config << 'EOF' # Select backend (pyright, ty, or pyrefly) export TYPEMUX_CC_BACKEND="ty" # Enable file output export TYPEMUX_CC_LOG_FILE="/tmp/typemux-cc.log" # Adjust log level (optional) export RUST_LOG="typemux_cc=debug" EOF # Restart Claude Code ``` -------------------------------- ### Add typemux-cc from GitHub Marketplace Source: https://github.com/k-dash/typemux-cc/blob/main/README.md Add the typemux-cc plugin from the GitHub Marketplace. This command uses the GitHub API and curl for installation. ```bash # 1. Add marketplace /plugin marketplace add K-dash/typemux-cc # 2. Install plugin /plugin install typemux-cc@typemux-cc-marketplace # 3. Restart Claude Code (initial installation only) ``` -------------------------------- ### Query Typemux-cc Logs for Session Transitions Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Monitor session transitions in typemux-cc logs, focusing on starting and completed events. This helps in tracking the lifecycle of backend sessions. ```bash grep "session=" /tmp/typemux-cc.log | grep -E "(Starting|completed)" ``` -------------------------------- ### .venv Search Algorithm Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Visual representation of the algorithm used to search for a Python virtual environment (.venv) starting from a file's parent directory. ```mermaid graph TD A[Get file path] --> B{Parent directory exists?} B -->|Yes| C{.venv/pyvenv.cfg exists?} C -->|Yes| D[.venv found] C -->|No| E{Reached git toplevel?} E -->|No| B E -->|Yes| F[No .venv] B -->|No| F style D fill:#d4edda style F fill:#f8d7da ``` -------------------------------- ### Define and Use BackendKind Enum Source: https://context7.com/k-dash/typemux-cc/llms.txt Defines supported LSP backends and provides methods to get their command, display name, and apply virtual environment configurations to a process command. ```rust use typemux_cc::backend::BackendKind; // Available backends let pyright = BackendKind::Pyright; // pyright-langserver --stdio let ty = BackendKind::Ty; // ty server let pyrefly = BackendKind::Pyrefly; // pyrefly lsp // Get command and arguments for spawning assert_eq!(pyright.command(), "pyright-langserver"); assert_eq!(ty.command(), "ty"); assert_eq!(pyrefly.command(), "pyrefly"); // Display name for logging assert_eq!(pyright.display_name(), "pyright"); ``` ```rust use tokio::process::Command; use std::path::Path; let mut cmd = Command::new(pyright.command()); let venv_path = Path::new("/project/.venv"); pyright.apply_env(&mut cmd, venv_path); // Sets VIRTUAL_ENV=/project/.venv // Sets PATH=/project/.venv/bin:$PATH ``` -------------------------------- ### Run Typemux-CC Self-Diagnosis Source: https://github.com/k-dash/typemux-cc/blob/main/README.md Execute the --doctor command to inspect configuration, environment, and system information. This helps in diagnosing issues by providing a snapshot of the current setup. ```bash # Find the binary in the plugin cache, then run --doctor ls ~/.claude/plugins/cache/typemux-cc-marketplace/typemux-cc/ # → 0.2.9 ~/.claude/plugins/cache/typemux-cc-marketplace/typemux-cc/0.2.9/bin/typemux-cc --doctor ``` ```bash ~/.claude/plugins/cache/typemux-cc-marketplace/typemux-cc/0.2.9/bin/typemux-cc --doctor --json ``` -------------------------------- ### Importing Same-Named Classes in Python Source: https://github.com/k-dash/typemux-cc/blob/main/docs/why-lsp.md In monorepos, converter files may import classes with the same name from different modules. This example shows importing a domain entity and an ORM model, both named PaymentNotification, with aliasing for the ORM model to distinguish them. ```python from ...notification import PaymentNotification # domain from project_alpha.models... import PaymentNotification as ...Model # ORM ``` -------------------------------- ### Update and Uninstall typemux-cc Plugin Source: https://github.com/k-dash/typemux-cc/blob/main/README.md Commands to update or uninstall the typemux-cc plugin. Use the update command to get the latest version and uninstall to remove it. ```bash # Update /plugin update typemux-cc@typemux-cc-marketplace # Uninstall /plugin uninstall typemux-cc@typemux-cc-marketplace /plugin marketplace remove typemux-cc-marketplace ``` -------------------------------- ### Initialize and Run LspProxy Source: https://context7.com/k-dash/typemux-cc/llms.txt Initialize an LspProxy with a specified backend kind, maximum number of backends, and backend time-to-live. The proxy then runs its main event loop, handling client and backend messages. ```rust use typemux_cc::backend::BackendKind; use std::time::Duration; // Create a new LSP proxy with pyright backend let backend_kind = BackendKind::Pyright; let max_backends = 8; let backend_ttl = Some(Duration::from_secs(1800)); // 30 minutes let mut proxy = LspProxy::new(backend_kind, max_backends, backend_ttl); // Run the proxy (blocks until exit notification received) proxy.run().await?; // The proxy handles these events via tokio::select!: // 1. Client messages from stdin (JSON-RPC) // 2. Backend messages via mpsc channel // 3. TTL sweep timer (60s interval) // 4. Warmup timeout for new backends // 5. Fan-out timeout for workspace/symbol requests ``` -------------------------------- ### Run All Quality Gates (Format, Lint, Test) Source: https://github.com/k-dash/typemux-cc/blob/main/AGENTS.md Execute all build and quality checks. This command should be run before completing any work. ```bash make all # format + lint + test ``` -------------------------------- ### Startup with Fallback Venv Sequence Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Details the sequence of operations during typemux-cc startup, including pre-spawning a backend with a fallback virtual environment and handling subsequent client requests. ```mermaid sequenceDiagram participant Client as Claude Code participant Proxy as typemux-cc participant Backend as LSP Backend Note over Proxy: Pre-spawn: fallback .venv found Proxy->>Backend: spawn(VIRTUAL_ENV=fallback/.venv) Client->>Proxy: initialize request Proxy->>Backend: initialize request Backend->>Proxy: initialize response Proxy->>Client: initialize response Proxy->>Backend: initialized notification Note over Proxy: Backend in pool (session 1, Warming) Client->>Proxy: didOpen(project-a/main.py) Proxy->>Backend: didOpen (forwarded) Client->>Proxy: textDocument/definition Note over Proxy: Index-dependent + Warming
→ Queued Note over Proxy: 2s timeout expires Note over Proxy: Warming → Ready (fail-open) Proxy->>Backend: textDocument/definition (drained) Backend->>Proxy: definition response Proxy->>Client: definition response ``` -------------------------------- ### Configure typemux-cc Settings Source: https://context7.com/k-dash/typemux-cc/llms.txt Configure typemux-cc by creating a config file in ~/.config/typemux-cc/config. Settings are defined using KEY=VALUE format. Options include backend selection, logging, max backends, and timeouts. ```bash # Create configuration directory and file mkdir -p ~/.config/typemux-cc cat > ~/.config/typemux-cc/config << 'EOF' # Select backend: pyright (default), ty, or pyrefly TYPEMUX_CC_BACKEND=pyright # Enable file logging for debugging TYPEMUX_CC_LOG_FILE=/tmp/typemux-cc.log # Max concurrent backend processes (default: 8) TYPEMUX_CC_MAX_BACKENDS=8 # Backend TTL in seconds, 0 to disable (default: 1800 = 30 min) TYPEMUX_CC_BACKEND_TTL=1800 # Warmup timeout in seconds, 0 to disable (default: 2) TYPEMUX_CC_WARMUP_TIMEOUT=2 # Fan-out timeout for workspace/symbol requests (default: 5) TYPEMUX_CC_FANOUT_TIMEOUT=5 # Log level RUST_LOG=typemux_cc=debug EOF ``` -------------------------------- ### Run All Tests Source: https://github.com/k-dash/typemux-cc/blob/main/AGENTS.md Execute all tests in the project. ```bash cargo test ``` ```bash make test ``` -------------------------------- ### Typemux-cc Development Build and Test Commands Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Execute common development tasks for typemux-cc, including formatting, linting, testing, and building release versions. The `make all` command runs format, lint, and test. ```bash # Format + Lint + Test make all # Individual commands make fmt # Code formatting make lint # Static analysis with clippy make test # Run unit tests make release # Release build # For CI (includes format check) make ci ``` -------------------------------- ### Run Individual Quality Commands Source: https://github.com/k-dash/typemux-cc/blob/main/AGENTS.md Commands to run specific quality checks: formatting, linting, and testing. ```bash make fmt # cargo fmt ``` ```bash make lint # cargo clippy -- -D warnings ``` ```bash make test # cargo test ``` -------------------------------- ### Mermaid Diagram of typemux-cc Architecture Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Illustrates the overall structure of typemux-cc, showing the proxy connecting an LSP client to multiple LSP backends, each associated with a specific virtual environment. ```mermaid graph LR Client[LSP Client
Claude Code] <-->|JSON-RPC| Proxy[typemux-cc] Proxy <-->|VIRTUAL_ENV=project-a/.venv| Backend1[LSP Backend
session 1] Proxy <-->|VIRTUAL_ENV=project-b/.venv| Backend2[LSP Backend
session 2] Proxy <-->|VIRTUAL_ENV=project-c/.venv| Backend3[LSP Backend
session 3] style Proxy fill:#e1f5ff style Backend1 fill:#fff4e1 style Backend2 fill:#fff4e1 style Backend3 fill:#fff4e1 ``` -------------------------------- ### Manage LSP Backend Processes with LspBackend Source: https://context7.com/k-dash/typemux-cc/llms.txt Manages spawning and communicating with LSP backend processes, including sending initialization requests and reading responses. Supports splitting the backend for concurrent read/write operations. ```rust use typemux_cc::backend::{BackendKind, LspBackend}; use typemux_cc::message::{RpcId, RpcMessage}; use std::path::Path; // Spawn a backend with a virtual environment let venv_path = Path::new("/project/.venv"); let mut backend = LspBackend::spawn(BackendKind::Pyright, Some(venv_path)).await?; ``` ```rust // Send an initialize request let init_request = RpcMessage::request( RpcId::Number(1), "initialize", Some(serde_json::json!({ "processId": std::process::id(), "rootUri": "file:///project", "capabilities": {} })) ); backend.send_message(&init_request).await?; ``` ```rust // Read the initialize response let response = backend.read_message().await?; assert!(response.is_response()); ``` ```rust // Split backend for async operations let parts = backend.into_split(); // parts.reader - for spawning reader task // parts.writer - for sending messages // parts.child - process handle // parts.next_id - next request ID counter ``` -------------------------------- ### Query Typemux-cc Logs for Backend Pool Activity Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Analyze typemux-cc logs for backend pool activity, including creation, eviction, and warmup events. This provides insight into backend management. ```bash grep -E "(Creating new backend|Evicting|Backend warmup)" /tmp/typemux-cc.log ``` -------------------------------- ### Run Single Test Source: https://github.com/k-dash/typemux-cc/blob/main/AGENTS.md Execute a specific test case by providing its name. ```bash cargo test test_name ``` -------------------------------- ### Configure Typemux-cc Logging with Environment Variables Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Set the log file path and log level using environment variables for quick configuration. This is useful for temporary logging or debugging. ```bash TYPEMUX_CC_LOG_FILE=/tmp/typemux-cc.log ./target/release/typemux-cc RUST_LOG=debug ./target/release/typemux-cc ``` -------------------------------- ### Build typemux-cc Locally Source: https://github.com/k-dash/typemux-cc/blob/main/README.md Build the typemux-cc plugin from source for development purposes. This requires Rust 1.75 or later and involves cloning the repository, building the release version, and then adding it to the plugin marketplace. ```bash git clone https://github.com/K-dash/typemux-cc.git cd typemux-cc cargo build --release /plugin marketplace add /path/to/typemux-cc /plugin install typemux-cc@typemux-cc-marketplace # Restart Claude Code (initial installation only) ``` -------------------------------- ### Query Typemux-cc Logs for Warmup Transitions Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Filter typemux-cc logs to specifically view 'warmup' related messages. This helps in understanding the backend warmup process. ```bash grep "warmup" /tmp/typemux-cc.log ``` -------------------------------- ### Detecting Virtual Environments with venv module Source: https://context7.com/k-dash/typemux-cc/llms.txt Utilize the venv module to find .venv directories. `get_git_toplevel` helps define search boundaries, `find_venv` searches parent directories, and `find_fallback_venv` checks common startup locations. ```rust use typemux_cc::venv::{find_venv, find_fallback_venv, get_git_toplevel}; use std::path::Path; // Get git repository root (used as search boundary) let cwd = std::env::current_dir()?; let git_toplevel = get_git_toplevel(&cwd).await?; // Returns Some(PathBuf) if in a git repo, None otherwise // Find .venv for a specific file (traverses parent directories) let file_path = Path::new("/project/src/module/main.py"); let venv = find_venv(file_path, git_toplevel.as_deref()).await?; // Searches: /project/src/module/.venv, /project/src/.venv, /project/.venv // Stops at git toplevel or filesystem root // Returns Some(venv_path) if .venv/pyvenv.cfg exists // Find fallback venv at startup (checks git toplevel, then cwd) let fallback = find_fallback_venv(&cwd).await?; // 1. Checks git_toplevel/.venv/pyvenv.cfg // 2. Checks cwd/.venv/pyvenv.cfg // Returns first found, or None ``` -------------------------------- ### Multi-Venv Routing Sequence Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Demonstrates how typemux-cc routes requests to different backends based on the project's virtual environment, including spawning new backends as needed. ```mermaid sequenceDiagram participant Client as Claude Code participant Proxy as typemux-cc participant A as Backend A
(project-a/.venv) participant B as Backend B
(project-b/.venv) Note over Proxy: Backend A already in pool Client->>Proxy: didOpen(project-b/main.py) Proxy->>Proxy: Search .venv → project-b/.venv Note over Proxy: Not in pool → spawn new backend Proxy->>B: spawn(VIRTUAL_ENV=project-b/.venv) Proxy->>B: initialize + initialized Proxy->>B: didOpen (document restoration) Note over Proxy: Both backends in pool Client->>Proxy: hover(project-a/main.py) Proxy->>A: hover request A->>Proxy: hover response Proxy->>Client: hover response Client->>Proxy: hover(project-b/main.py) Proxy->>B: hover request B->>Proxy: hover response Proxy->>Client: hover response ``` -------------------------------- ### Manage Multiple LSP Backends with BackendPool Source: https://context7.com/k-dash/typemux-cc/llms.txt Manages concurrent LSP backend processes with LRU eviction and TTL-based cleanup. Provides methods to check pool status, add/get backends, and identify backends for eviction. ```rust use typemux_cc::backend_pool::{BackendPool, BackendInstance, WarmupState}; use std::time::Duration; use std::path::PathBuf; // Create a pool with max 8 backends and 30-minute TTL let mut pool = BackendPool::new(8, Some(Duration::from_secs(1800))); // Check pool status assert!(pool.is_empty()); assert!(!pool.is_full()); assert_eq!(pool.max_backends(), 8); ``` ```rust // Check if backend exists for a venv let venv = PathBuf::from("/project-a/.venv"); if !pool.contains(&venv) { // Spawn and insert new backend... } ``` ```rust // Get backend for operations if let Some(instance) = pool.get_mut(&venv) { // Update last_used timestamp instance.last_used = tokio::time::Instant::now(); // Check warmup state if instance.is_warming() { // Queue index-dependent requests instance.warmup_queue.push(request); } } ``` ```rust // Find LRU backend for eviction let pending_count = |venv: &PathBuf, session: u64| -> usize { 0 }; if let Some(lru_venv) = pool.lru_venv(pending_count) { // Evict this backend if let Some(instance) = pool.remove(&lru_venv) { shutdown_backend_instance(instance); } } ``` ```rust // Get expired backends for TTL eviction for venv in pool.expired_venvs() { // Evict expired backend... } ``` -------------------------------- ### Monitor typemux-cc Logs Source: https://context7.com/k-dash/typemux-cc/llms.txt Use `tail -f` to continuously monitor the typemux-cc log file for real-time updates. ```bash tail -f /tmp/typemux-cc.log ``` -------------------------------- ### Configuring typemux-cc Logging Source: https://context7.com/k-dash/typemux-cc/llms.txt Enable file logging and set the RUST_LOG level for typemux-cc by modifying the configuration file. This is useful for debugging and troubleshooting. ```bash # Enable file logging via config cat >> ~/.config/typemux-cc/config << 'EOF' TYPEMUX_CC_LOG_FILE=/tmp/typemux-cc.log RUST_LOG=typemux_cc=debug EOF ``` -------------------------------- ### Proxy State Management with ProxyState Source: https://context7.com/k-dash/typemux-cc/llms.txt Manage runtime state for the proxy using the `ProxyState` struct. Track open documents, pending requests, and allocate unique proxy request IDs. ```rust use typemux_cc::state::{ProxyState, PendingRequest, OpenDocument}; use typemux_cc::backend::BackendKind; use typemux_cc::message::RpcId; use std::time::Duration; use std::path::PathBuf; use url::Url; // Create proxy state let mut state = ProxyState::new( BackendKind::Pyright, 8, // max_backends Some(Duration::from_secs(1800)), // backend_ttl ); // Track open documents let uri = Url::parse("file:///project/main.py").unwrap(); state.open_documents.insert(uri.clone(), OpenDocument { language_id: "python".to_string(), version: 1, text: "import os\n".to_string(), venv: Some(PathBuf::from("/project/.venv")), }); // Track pending requests (for routing responses) let request_id = RpcId::Number(42); state.pending_requests.insert(request_id.clone(), PendingRequest { backend_session: 1, venv_path: PathBuf::from("/project/.venv"), }); // Allocate proxy request IDs (negative to avoid collision with client IDs) let proxy_id = state.alloc_proxy_request_id(); // Returns RpcId::Number(-1), then -2, -3, etc. // Get nearest fan-out deadline for timeout handling if let Some(deadline) = state.nearest_fanout_deadline() { // Handle timeout... } ``` -------------------------------- ### Create a New Feature Branch Source: https://github.com/k-dash/typemux-cc/blob/main/AGENTS.md Before making any code changes, create a new feature branch from the main branch. ```bash git checkout -b feat/your-feature-name ``` -------------------------------- ### Run typemux-cc Self-Diagnosis Source: https://context7.com/k-dash/typemux-cc/llms.txt Use the --doctor command to dump configuration, environment, and system information for debugging. The --json flag provides output in JSON format for programmatic use. ```bash # Find and run the doctor command ~/.claude/plugins/cache/typemux-cc-marketplace/typemux-cc/0.2.10/bin/typemux-cc --doctor # Example output: # typemux-cc v0.2.10 # # Config file: # Path /Users/foo/.config/typemux-cc/config # Status loaded # # Configuration: # backend pyright (default) # max_backends 8 (default) # backend_ttl 1800 (default) # warmup_timeout 2 (default) # fanout_timeout 5 (default) # log_file /tmp/typemux-cc.log (config) # # Environment: # Backend binary pyright-langserver # Path /usr/local/bin/pyright-langserver # Version pyright 1.1.350 # Git toplevel /Users/foo/project # Fallback venv /Users/foo/project/.venv # # System: # OS macos (Darwin 24.0.0) # Arch aarch64 # Get JSON output for programmatic use ~/.claude/plugins/cache/typemux-cc-marketplace/typemux-cc/0.2.10/bin/typemux-cc --doctor --json ``` -------------------------------- ### Force Reinstall typemux-cc Plugin Source: https://context7.com/k-dash/typemux-cc/llms.txt Force a reinstall of the typemux-cc plugin, clearing the cache if updates are not taking effect. ```bash rm -rf ~/.claude/plugins/cache/typemux-cc-marketplace/ ``` ```bash /plugin install typemux-cc@typemux-cc-marketplace ``` -------------------------------- ### Define Pending Backend Request Structure Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Stores the original request ID from the backend, the virtual environment path, and the session identifier for pending backend requests. ```rust pub struct PendingBackendRequest { pub original_id: RpcId, // Backend's original ID pub venv_path: PathBuf, pub session: u64, } ``` -------------------------------- ### LSP Framing with LspFrameReader/Writer Source: https://context7.com/k-dash/typemux-cc/llms.txt Use LspFrameReader and LspFrameWriter to handle Content-Length headers for JSON-RPC communication over stdio. Ensure correct imports for reader, writer, and message types. ```rust use typemux_cc::framing::{LspFrameReader, LspFrameWriter}; use typemux_cc::message::{RpcMessage, RpcId}; use tokio::io::{stdin, stdout}; // Create reader/writer for stdio communication let mut reader = LspFrameReader::new(stdin()); let mut writer = LspFrameWriter::new(stdout()); // Read an LSP message (handles Content-Length header parsing) let message = reader.read_message().await?; // Parses: "Content-Length: 46\r\n\r\n{"jsonrpc":"2.0",...}" // Write an LSP message (adds Content-Length header) let response = RpcMessage::request(RpcId::Number(1), "initialize", None); writer.write_message(&response).await?; // Writes: "Content-Length: N\r\n\r\n{...json...}" ``` -------------------------------- ### Represent Backend Warmup State Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Defines the possible warmup states for a backend instance: 'Warming' for queuing index-dependent requests, and 'Ready' for forwarding all requests normally. ```rust pub enum WarmupState { Warming, // Queueing index-dependent requests Ready, // All requests forwarded normally } ``` -------------------------------- ### Rust Struct for Backend Instance Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Defines the `BackendInstance` struct in Rust, which includes a unique session ID and a timestamp for tracking the last usage, essential for LRU eviction and stale message detection. ```rust pub struct BackendInstance { pub session: u64, // Unique session ID pub last_used: Instant, // For LRU tracking // ... } ``` -------------------------------- ### SQLAlchemy Model References in Python Source: https://github.com/k-dash/typemux-cc/blob/main/docs/why-lsp.md These lines demonstrate references to SQLAlchemy models, which can be mistaken for domain entities during text-based code analysis. They are typically found in ORM-related files. ```python query = select(PaymentNotification.id) query = query.where(PaymentNotification.user_id.in_(...)) ``` -------------------------------- ### Typemux-CC Source Code Structure Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md This table outlines the responsibilities of each Rust file within the Typemux-CC project. ```markdown | File | Responsibility | |------|----------------| | `main.rs` | Entry point, CLI argument parsing, logging setup | | `backend.rs` | LSP backend process management (pyright, ty, pyrefly) | | `backend_pool.rs` | Multi-backend pool, LRU/TTL management, warmup state | | `state.rs` | Proxy state: pool, documents, pending requests | | `message.rs` | JSON-RPC message type definitions (RpcMessage, RpcId, RpcError) | | `framing.rs` | JSON-RPC framing (Content-Length header processing) | | `text_edit.rs` | Incremental text edit application for didChange | | `venv.rs` | `.venv` search logic (parent traversal, git toplevel boundary) | | `error.rs` | Error type definitions (ProxyError, BackendError, etc.) | | `proxy/mod.rs` | Main event loop (`tokio::select!` with 5 arms) | | `proxy/client_dispatch.rs` | Client message routing, warmup queueing, cancel handling | | `proxy/backend_dispatch.rs` | Backend message routing, proxy ID rewriting, progress detection | | `proxy/fanout.rs` | Fan-out dispatch, response merging, deduplication, timeout handling | | `proxy/pool_management.rs` | LRU/TTL eviction, crash recovery, warmup expiry | | `proxy/initialization.rs` | Backend initialization handshake, document restoration | | `proxy/document.rs` | Document tracking (didOpen, didChange, didClose) | | `proxy/diagnostics.rs` | Diagnostic message handling, stale diagnostics cleanup | ``` -------------------------------- ### Fan-Out Request Sequence Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Illustrates how typemux-cc fans out a 'workspace/symbol' request to all active backends, collects responses, deduplicates, and merges them before returning to the client. ```mermaid sequenceDiagram participant Client as Claude Code participant Proxy as typemux-cc participant A as Backend A participant B as Backend B Client->>Proxy: workspace/symbol (id: 42) Note over Proxy: Fan-out: dispatch to all backends Proxy->>A: workspace/symbol (id: -1) Proxy->>B: workspace/symbol (id: -2) B->>Proxy: response (id: -2, results: [...]) A->>Proxy: response (id: -1, results: [...]) Note over Proxy: All responses collected
Deduplicate and merge Proxy->>Client: response (id: 42, merged results) ``` -------------------------------- ### Troubleshooting LSP Issues with Typemux-CC Source: https://github.com/k-dash/typemux-cc/blob/main/README.md Commands to quickly diagnose LSP problems with Typemux-CC. This includes running the doctor command, checking plugin settings, and examining log files. ```bash # Quick self-diagnosis (replace version number as needed) ~/.claude/plugins/cache/typemux-cc-marketplace/typemux-cc/0.2.9/bin/typemux-cc --doctor cat ~/.claude/settings.json | grep typemux # Check plugin settings tail -100 /tmp/typemux-cc.log # Check logs (if file logging enabled) ``` -------------------------------- ### Handle JSON-RPC Messages with RpcMessage Source: https://context7.com/k-dash/typemux-cc/llms.txt Represents JSON-RPC 2.0 messages for LSP communication. Supports creating requests, notifications, success responses, error responses, and cancellation responses. ```rust use typemux_cc::message::{RpcMessage, RpcId, RpcError}; use serde_json::json; // Create a request (has id, expects response) let request = RpcMessage::request( RpcId::Number(1), "textDocument/hover", Some(json!({ "textDocument": { "uri": "file:///project/main.py" }, "position": { "line": 10, "character": 5 } })) ); assert!(request.is_request()); assert_eq!(request.method_name(), Some("textDocument/hover")); ``` ```rust // Create a notification (no id, no response expected) let notification = RpcMessage::notification( "textDocument/didOpen", Some(json!({ "textDocument": { "uri": "file:///project/main.py", "languageId": "python", "version": 1, "text": "import os\n" } })) ); assert!(notification.is_notification()); ``` ```rust // Create success response let response = RpcMessage::success_response(&request, json!({ "contents": { "kind": "markdown", "value": "def foo() -> None" } })); assert!(response.is_response()); ``` ```rust // Create error response let error = RpcMessage::error_response(&request, ".venv not found"); assert!(error.error.is_some()); assert_eq!(error.error.unwrap().code, -32603); ``` ```rust // Create cancellation response let cancelled = RpcMessage::cancelled_response( RpcId::Number(1), "Request cancelled" ); assert_eq!(cancelled.error.unwrap().code, -32800); ``` -------------------------------- ### Typemux-CC Event Loop Structure Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Visual representation of the 5 arms within the `tokio::select!` macro used in the main event loop of `proxy/mod.rs`. ```text ┌─────────────────────────────────────────────────────┐ │ tokio::select! │ ├─────────────────────────────────────────────────────┤ │ 1. Client reader │ stdin JSON-RPC messages │ │ 2. Backend reader │ mpsc channel (all backends) │ │ 3. TTL timer │ 60s interval sweep │ │ 4. Warmup timer │ nearest warmup deadline │ │ 5. Fan-out timer │ nearest fan-out deadline │ └─────────────────────────────────────────────────────┘ ``` -------------------------------- ### LRU Eviction Sequence Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Explains the Least Recently Used (LRU) eviction strategy when the backend pool reaches its maximum capacity, including canceling pending requests and spawning a new backend. ```mermaid sequenceDiagram participant Client as Claude Code participant Proxy as typemux-cc Note over Proxy: Pool full (max_backends reached) Client->>Proxy: didOpen(new-project/main.py) Proxy->>Proxy: Search .venv → new-project/.venv Note over Proxy: Not in pool, pool full Proxy->>Proxy: Find LRU backend
(prefer no pending requests) Note over Proxy: Evict LRU backend:
cancel pending, clear diagnostics, shutdown Proxy->>Proxy: Spawn new backend Note over Proxy: Pool size maintained at max ``` -------------------------------- ### Query Typemux-cc Logs for Document Restoration Statistics Source: https://github.com/k-dash/typemux-cc/blob/main/ARCHITECTURE.md Extract and view logs related to document restoration completion. This is useful for verifying that open files are correctly restored. ```bash grep "Document restoration completed" /tmp/typemux-cc.log ``` -------------------------------- ### Push Branch and Create Pull Request Source: https://github.com/k-dash/typemux-cc/blob/main/AGENTS.md After committing changes, push the feature branch to the remote repository and create a pull request. ```bash git push -u origin ``` ```bash gh pr create ``` -------------------------------- ### Filter typemux-cc Log Events Source: https://context7.com/k-dash/typemux-cc/llms.txt Use `grep` to filter the typemux-cc log file for specific events such as warmups, backend spawns, evictions, venv detection, and session tracking. ```bash grep "warmup" /tmp/typemux-cc.log # Warmup transitions ``` ```bash grep "Creating new backend" /tmp/typemux-cc.log # Backend spawns ``` ```bash grep "Evicting" /tmp/typemux-cc.log # Backend evictions ``` ```bash grep ".venv found" /tmp/typemux-cc.log # Venv detection ``` ```bash grep "session=" /tmp/typemux-cc.log # Session tracking ``` -------------------------------- ### Update typemux-cc Plugin Source: https://context7.com/k-dash/typemux-cc/llms.txt Update the typemux-cc Claude Code plugin to the latest version from the marketplace. ```bash /plugin update typemux-cc@typemux-cc-marketplace ``` -------------------------------- ### typemux-cc Enabled Plugins Configuration Source: https://github.com/k-dash/typemux-cc/blob/main/README.md Verify that typemux-cc is enabled and the official pyright plugin is disabled in your Claude Code settings. This JSON snippet shows the expected configuration. ```json { "enabledPlugins": { "pyright-lsp@claude-plugins-official": false, "typemux-cc@typemux-cc-marketplace": true } } ``` -------------------------------- ### Uninstall typemux-cc Plugin Source: https://context7.com/k-dash/typemux-cc/llms.txt Uninstall the typemux-cc Claude Code plugin. This may involve removing it from the marketplace as well. ```bash /plugin uninstall typemux-cc@typemux-cc-marketplace ``` ```bash /plugin marketplace remove typemux-cc-marketplace ``` -------------------------------- ### Manually Clear Typemux-CC Plugin Cache Source: https://github.com/k-dash/typemux-cc/blob/main/README.md Steps to manually clear the Typemux-CC plugin cache and reinstall the plugin. This is a workaround for issues where plugin updates are not taking effect due to a known Claude Code bug. ```bash # 1. Remove cached plugin rm -rf ~/.claude/plugins/cache/typemux-cc-marketplace/ # 2. Reinstall /plugin install typemux-cc@typemux-cc-marketplace # 3. Restart Claude Code ``` -------------------------------- ### Disable Official pyright Plugin Source: https://github.com/k-dash/typemux-cc/blob/main/README.md You must disable the official pyright plugin to avoid conflicts with typemux-cc. This command disables the official plugin. ```bash /plugin disable pyright-lsp@claude-plugins-official ``` -------------------------------- ### Handling ProxyError Types Source: https://context7.com/k-dash/typemux-cc/llms.txt Implement comprehensive error handling for proxy operations using the defined error enums. Match on specific error variants for detailed logging or recovery. ```rust use typemux_cc::error::{ProxyError, BackendError, FramingError, VenvError}; // ProxyError - top-level proxy errors fn handle_proxy_error(err: ProxyError) { match err { ProxyError::Io(e) => eprintln!("IO error: {}", e), ProxyError::Json(e) => eprintln!("JSON parse error: {}", e), ProxyError::InvalidMessage(msg) => eprintln!("Invalid message: {}", msg), ProxyError::Backend(e) => eprintln!("Backend error: {}", e), ProxyError::Framing(e) => eprintln!("Framing error: {}", e), ProxyError::Venv(e) => eprintln!("Venv error: {}", e), } } // BackendError - backend process errors fn handle_backend_error(err: BackendError) { match err { BackendError::SpawnFailed(e) => eprintln!("Failed to spawn: {}", e), BackendError::Communication(e) => eprintln!("Communication error: {}", e), BackendError::InitializeTimeout(secs) => eprintln!("Timeout after {}s", secs), BackendError::InitializeFailed(msg) => eprintln!("Init failed: {}", msg), BackendError::InitializeResponseError(msg) => eprintln!("Response error: {}", msg), } } // FramingError - LSP framing errors fn handle_framing_error(err: FramingError) { match err { FramingError::MissingContentLength => eprintln!("Missing Content-Length"), FramingError::InvalidContentLength => eprintln!("Invalid Content-Length"), FramingError::Io(e) => eprintln!("IO error: {}", e), FramingError::Json(e) => eprintln!("JSON error: {}", e), } } ```