Skip to main content

Monitor Windsurf and Windsurf Next resource usage and diagnose problems

Project description

Surfmon

surfmon header

ci release documentation pypi version Python 3.14+ coverage

Surface Monitor for Windsurf IDE — a performance monitoring and diagnostics tool for Windsurf (Stable, Next, and Insiders).

Table of Contents

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

# Save reports (auto-named with timestamp, enables verbose output)
surfmon check -t next -s

# Target Windsurf Insiders
surfmon check -t insiders

Basic Check

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 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

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 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 names

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

Watch Dashboard

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:

Analyze Report

Generated Matplotlib Visualization:

Analysis Plot

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

prune — Deduplicate Watch Reports

Removes 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/

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. Use --save to generate JSON + Markdown files suitable for attaching to bug reports.

surfmon pty-snapshot -t next                   # Display snapshot
surfmon pty-snapshot -t stable --save          # Auto-save JSON + Markdown
surfmon pty-snapshot -t next --json snap.json  # Save JSON to specific path
surfmon pty-snapshot -t next --md snap.md      # Save Markdown to specific path

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 (prune, analyze) do not require it.

Exit Codes

  • 0 — No issues detected
  • 1 — Issues detected (see output)
  • 130 — Interrupted (Ctrl+C)

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, 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
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 analyze plots

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

surfmon-0.13.0.tar.gz (44.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

surfmon-0.13.0-py3-none-any.whl (44.5 kB view details)

Uploaded Python 3

File details

Details for the file surfmon-0.13.0.tar.gz.

File metadata

  • Download URL: surfmon-0.13.0.tar.gz
  • Upload date:
  • Size: 44.1 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

Hashes for surfmon-0.13.0.tar.gz
Algorithm Hash digest
SHA256 871ac830c2a5dc897cf369262e26a9a9737b44c86a5c0e6f09adb6685d6ce011
MD5 17fade3bc500626c018a686029b5bb3d
BLAKE2b-256 dfd7a59303fe03b5b467038358008d862470d636a622f04194665653223ff157

See more details on using hashes here.

File details

Details for the file surfmon-0.13.0-py3-none-any.whl.

File metadata

  • Download URL: surfmon-0.13.0-py3-none-any.whl
  • Upload date:
  • Size: 44.5 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

Hashes for surfmon-0.13.0-py3-none-any.whl
Algorithm Hash digest
SHA256 baee9dcd74360a9bac99ac03fa56f65190be78372efca8e60a5792c3ee62b24d
MD5 b9a674f1f3fec2fbe2e0d426bab7d902
BLAKE2b-256 a6bcc3c968691ec43a88bb23cdb1f6786d29b4c0e6305062f2a47301117b7ab4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page