Surface Monitor for Windsurf IDE — a performance monitoring and diagnostics tool for Windsurf (Stable, Next, and Insiders).
- Installation
- Quick Start
- Why Use Surfmon?
- Commands
- What It Monitors
- Target Selection
- Exit Codes
- Common Issues
- Development
pip install surfmonOr with uv:
uv tool install surfmonOr run directly without installing:
uvx surfmon check -t stable # Using uvx
pipx run surfmon check -t stable # Using pipxFor development:
git clone https://github.com/detailobsessed/surfmon.git
cd surfmon
uv sync# One-shot health check (--target is required)
surfmon check -t stable
# Verbose output with all process details
surfmon check -t stable -v
# Save reports (auto-named with timestamp, enables verbose output)
surfmon check -t next -s
# Target Windsurf Insiders
surfmon check -t insiders- 🔍 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 and duplicate reports
- 🔧 Troubleshoot Crashes — Detect extension host crashes, language server issues, and PTY leaks
- 📈 Visualize Trends — Generate matplotlib plots showing resource usage over time
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 next -s # Auto-save JSON + Markdown reports (enables verbose)
surfmon check -t stable --json report.json # Save JSON to specific path
surfmon check -t stable --md report.md # Save Markdown to specific path
surfmon check -t stable --json r.json --md r.md # Save both formats with custom namesContinuously 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 directoryAnalyzes 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.pngTerminal Output:
Generated Matplotlib Visualization:
surfmon check -t stable --json before.json
# ... make changes ...
surfmon check -t stable --json after.json
surfmon compare before.json after.jsonDetects 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 confirmationRemoves duplicate/identical JSON reports that accumulate during watch sessions when nothing changes.
surfmon prune reports/watch/20260204-134518/ --dry-run
surfmon prune reports/watch/20260204-134518/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
Issues — Orphaned crash handlers, extension host crashes, update service timeouts, telemetry failures, logs directory in extensions folder
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 InsidersAlternatively, set SURFMON_TARGET in your environment to avoid passing -t every time:
export SURFMON_TARGET=insiders
surfmon checkThe --target flag is required for check, watch, and cleanup. Commands that operate on saved files (compare, prune, analyze) do not require it.
0— No issues detected1— Issues detected (see output)130— Interrupted (Ctrl+C)
| 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 |
src/surfmon/
__init__.py # Version
cli.py # Typer CLI — check, watch, compare, cleanup, prune, 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
compare.py # Report comparison with colored diffs
tests/
conftest.py # Shared fixtures
test_bugfixes.py # Regression tests
test_cli.py # CLI command tests
test_compare.py # Report comparison tests
test_config.py # Configuration and target detection tests
test_monitor.py # Core monitoring logic tests
test_output.py # Display and formatting tests
poe test # Run tests
poe test-cov # Run with coverage
poe lint # Ruff check
poe typecheck # ty check- 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
- Python 3.14+
- macOS (tested), Linux (untested), Windows (untested) though it should work
- Windsurf IDE installed
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




