Monitor Windsurf and Windsurf Next resource usage and diagnose problems
Project description
Surfmon
Surface Monitor for Windsurf IDE — a performance monitoring and diagnostics tool for Windsurf (Stable, Next, and Insiders).
Table of Contents
- Installation
- Quick Start
- Why Use Surfmon?
- Commands
- What It Monitors
- Target Selection
- Exit Codes
- Common Issues
- Development
Installation
pip install surfmon
Or with uv:
uv tool install surfmon
Or run directly without installing:
uvx surfmon check -t stable # Using uvx
pipx run surfmon check -t stable # Using pipx
For development:
git clone https://github.com/detailobsessed/surfmon.git
cd surfmon
uv sync
Quick Start
# One-shot health check (--target is required)
surfmon check -t stable
# Verbose output with all process details
surfmon check -t stable -v
# Target Windsurf Insiders
surfmon check -t insiders
Why Use Surfmon?
- 🔍 Debug Performance Issues — Identify memory leaks, CPU spikes, and resource bottlenecks
- 📊 Monitor Over Time — Track resource usage trends with watch sessions and historical analysis
- 🧹 Clean Up Resources — Remove orphaned processes
- 🔧 Troubleshoot Crashes — Detect extension host crashes, language server issues, and PTY leaks
- 📈 Visualize Trends — Generate matplotlib plots showing resource usage over time
Commands
check — Quick Performance Snapshot
The main command. Shows system resources, Windsurf memory/CPU, active workspaces, top processes, and language servers in consistent fixed-width tables.
surfmon check -t stable # Basic check
surfmon check -t stable -v # Verbose (all processes)
surfmon check -t stable --json # Output JSON to stdout (for agent/pipe consumption)
watch — Live Monitoring Dashboard
Continuously monitors Windsurf with a live-updating terminal dashboard. Saves periodic JSON snapshots for historical analysis.
surfmon watch -t stable # Default: 5s interval, save every 5min
surfmon watch -t next -i 10 -s 600 # Check every 10s, save every 10min
surfmon watch -t insiders -i 10 -n 720 # 720 checks = 2 hours
surfmon watch -t stable -o ~/reports # Custom output directory
analyze — Historical Trend Analysis
Analyzes JSON reports from watch sessions (or any directory containing JSON reports) to detect memory leaks, process growth, and performance degradation. Optionally generates a 9-panel matplotlib visualization.
surfmon analyze reports/watch/20260204-134518/
surfmon analyze reports/watch/20260204-134518/ --plot
surfmon analyze reports/watch/20260204-134518/ --plot --output analysis.png
Terminal Output:
Generated Matplotlib Visualization:
cleanup — Remove Orphaned Processes
Detects and kills orphaned chrome_crashpad_handler processes left behind after Windsurf exits. Windsurf must be closed for this command to work.
surfmon cleanup -t stable # Interactive (asks for confirmation)
surfmon cleanup -t next --force # No confirmation
pty-snapshot — PTY Forensic Capture
Captures a detailed PTY ownership snapshot for diagnosing Windsurf's PTY leak. Shows per-PID breakdown, FD-level detail (active vs idle), Windsurf version, and uptime.
surfmon pty-snapshot -t next # Display snapshot
surfmon pty-snapshot -t next --json # Output JSON to stdout (for agent/pipe consumption)
What It Monitors
System — Total/available memory, memory %, swap, CPU cores
Windsurf Processes — Process count, total memory & CPU, top 10 by memory, thread counts
Language Servers — Detects and tracks basedpyright, JDT.LS, Codeium language servers, YAML/JSON servers
MCP Servers — Lists enabled MCP servers from Codeium config
Workspaces — Active workspace paths and load times
PTY Usage — Windsurf PTY allocation vs system limits, per-PID breakdown, FD-level active/idle classification, raw lsof capture for forensic analysis
Issues — Orphaned crash handlers, extension host crashes, update service timeouts, telemetry failures, logs directory in extensions folder
Target Selection
Surfmon requires you to specify which Windsurf installation to monitor. Use --target (-t) with one of stable, next, or insiders:
surfmon check -t stable # Windsurf Stable
surfmon check -t next # Windsurf Next
surfmon check -t insiders # Windsurf Insiders
Alternatively, set SURFMON_TARGET in your environment to avoid passing -t every time:
export SURFMON_TARGET=insiders
surfmon check
The --target flag is required for check, watch, and cleanup. Commands that operate on saved data (analyze) do not require it.
Exit Codes
Diagnostic commands (check, ls-snapshot, pty-snapshot)
0— No issues detected1— Warnings only (non-critical, e.g. extension errors, moderate PTY count)2— Critical issues present (e.g. orphaned workspaces, OOM, PTY exhaustion)130— Interrupted (Ctrl+C)
Data & utility commands (history, trend, analyze, cleanup)
0— Success1— Error (invalid input, operational failure)
Common Issues
| Issue | Cause | Fix |
|---|---|---|
| Orphaned crash handlers | Crash reporters not cleaned up on exit | surfmon cleanup -t stable --force |
logs directory error |
Marimo extension creates logs in wrong place | Move ~/.windsurf/extensions/logs |
| Update service timeouts | DNS or firewall blocking update checks | Check DNS/firewall settings |
| High memory usage | Too many language servers or extensions | Disable unused extensions |
Development
Package Structure
src/surfmon/
__init__.py # Version
cli.py # Typer CLI — check, watch, cleanup, analyze
config.py # Target detection, paths, environment config
monitor.py # Core data collection — processes, language servers, MCP, PTYs
output.py # Rich terminal display and Markdown export
tests/
conftest.py # Shared fixtures
test_bugfixes.py # Regression tests
test_cli.py # CLI command tests
test_config.py # Configuration and target detection tests
test_monitor.py # Core monitoring logic tests
test_output.py # Display and formatting tests
Running Tests
poe test # Run tests
poe test-cov # Run with coverage
poe lint # Ruff check
poe typecheck # ty check
Dependencies
- psutil — Cross-platform process and system monitoring
- typer — CLI framework
- rich — Terminal output with tables and colors
- python-decouple — Environment configuration
- matplotlib — Visualization for
analyzeplots
Requirements
- Python 3.14+
- macOS (tested), Linux (untested), Windows (untested) though it should work
- Windsurf IDE installed
Creating Screenshots
Screenshots in this README were created using:
- Static images (termshot) - Captures terminal output as PNG
- Animated GIF (vhs) - Records terminal sessions as GIF
To recreate the watch GIF:
brew install vhs gifsicle
# Create tape file
cat > watch-demo.tape << 'EOF'
Output docs/screenshots/watch.gif
Set FontSize 13
Set Width 900
Set Height 400
Set Theme "Catppuccin Mocha"
Set BorderRadius 10
Set WindowBar Colorful
Set WindowBarSize 30
Type "uvx surfmon watch --interval 2 --max 15"
Enter
Sleep 32s
EOF
# Generate and optimize
vhs watch-demo.tape
gifsicle -O3 --colors 256 docs/screenshots/watch.gif -o docs/screenshots/watch.gif
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file surfmon-0.20.2.tar.gz.
File metadata
- Download URL: surfmon-0.20.2.tar.gz
- Upload date:
- Size: 45.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2dee9899e21fe44bc38f4df201f4620d502bf3847e1e793d981bcb2aa0a4bada
|
|
| MD5 |
9b43de8414a507f30529796e17566cb2
|
|
| BLAKE2b-256 |
871e627341a939b5237e539f76b8ec97787757c20b727e9ed4a03c53533e2252
|
File details
Details for the file surfmon-0.20.2-py3-none-any.whl.
File metadata
- Download URL: surfmon-0.20.2-py3-none-any.whl
- Upload date:
- Size: 49.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4b5f123e08c89f9cbc6c019efab01505b043ed70543bcb9ae71550bbd0652661
|
|
| MD5 |
b3f269e2e08bda2cfcf63ec35d33d024
|
|
| BLAKE2b-256 |
4e9eecc3e8c61262111693496ac0cb1016b9213db0009903b0ffcb6e997b4fad
|