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
- check — Quick Performance Snapshot
- watch — Live Monitoring Dashboard
- analyze — Historical Trend Analysis
- cleanup — Remove Orphaned Processes
- pty-snapshot — PTY Forensic Capture
- What It Monitors
- Target Selection
- Exit Codes
- Common Issues
- Development
- Package Structure
- Running Tests
- Dependencies
- Requirements
- Creating Screenshots
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