npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

surf-check

v0.2.2

Published

AI agent skill for smart surf forecast alerts with tiered confidence

Readme

🏄 surf-check

A surf forecast decision engine that identifies when conditions are worth paddling out. Evaluates forecasts against configurable thresholds and outputs surfable conditions to stdout — what you do with that output is up to you.

Built as an AI agent skill for OpenClaw, but works with any AI agent framework, automation pipeline, or as a standalone CLI.

What It Does

surf-check evaluates surf forecasts and outputs conditions that meet your criteria. It does not send notifications directly — it's the decision layer, not the delivery layer.

[Forecast Data] → [surf-check] → [stdout] → [Your notification system]

As a standalone CLI: Outputs surfable conditions to stdout. Pipe to any notification system.

As an AI agent skill: Your agent reads the output and handles alerting (see SKILL.md).

Features

  • Tiered decision logic — Requires higher confidence for longer-range forecasts
  • State tracking — No duplicate output for the same forecast
  • Quiet hours — Suppress output during configurable hours (default 10pm-6am)
  • Premium support — Use your Surfline Premium subscription for 16-day forecasts
  • NOAA buoy data — Cross-reference forecasts with real buoy readings
  • Cron-ready — Designed for periodic automated checks

How It Works

Surf forecasts get less accurate the further out you look. surf-check adjusts its confidence threshold accordingly:

| Days Out | Minimum Rating | Rationale | |----------|----------------|-----------| | 4+ days | Fair-Good or better | Forecasts are fuzzy, need high confidence | | 1-3 days | Fair or better | Sweet spot for planning | | Day of | Good or better | Only flag if it's actually firing |

Same-day conditions are suppressed after 8am (dawn patrol has already passed).

Note: These are the default thresholds. All values are fully configurable in src/types.ts to match your preferences and local conditions.

Installation

git clone https://github.com/kevinmcnamee/surf-check.git
cd surf-check
npm install

For Premium Data (Optional)

If you have a Surfline Premium subscription and want 16-day forecasts:

# Install Playwright browsers
npx playwright install chromium

# Log in (opens browser for manual login)
npm run login -- --interactive

Your session cookies are saved locally and reused for authenticated API requests.

Configuration

Create a config file at ~/.surf-check.json (global) or ./surf-check.json (local):

{
  "spots": [
    { "id": "5842041f4e65fad6a7708a01", "name": "Belmar" },
    { "id": "630d04654da1381c5cb8aeb7", "name": "Long Branch" }
  ],
  "waveMin": 2,
  "waveMax": 6,
  "forecastDays": 7,
  "quietHours": {
    "enabled": true,
    "start": 22,
    "end": 6
  }
}

All fields are optional — defaults are used for any missing values.

Finding Spot IDs

Go to your spot on Surfline.com. The URL contains the spot ID:

https://www.surfline.com/surf-report/spot-name/5842041f4e65fad6a7708a01
                                              └── this is the spot ID

Defaults

| Setting | Default | |---------|---------| | spots | Belmar, Long Branch (NJ) | | waveMin | 2 ft | | waveMax | 6 ft | | forecastDays | 7 | | quietHours | 10pm - 6am |

Quiet Hours

Notifications are suppressed during quiet hours (default 10pm-6am). Alerts aren't lost — they're sent on the next check outside quiet hours.

Set "enabled": false to output conditions 24/7.

Usage

Manual Check

# Full forecast with conditions
npm run check

# With debug output (shows why each day did/didn't match)
npm run check:debug

# JSON output
npm run check:json

Example output:

🏄 Checking Surfline forecasts...

📍 Belmar (16th Ave)
----------------------------------------
Wednesday, Feb 18: 3-4ft | Fair | Offshore 7mph
Thursday, Feb 19: 2-3ft | Poor-Fair | Cross-shore 6mph
Saturday, Feb 21: 2-3ft | Fair | Offshore 7mph

========================================
ALERTS
========================================
🏄 **Surf Forecast Summary**

**Belmar (16th Ave)**
• Saturday: 2-3ft (Fair)

Automated Checks (Cron Mode)

npm run check:cron

Cron mode:

  • Only outputs new surfable conditions
  • Updates state file to track what's been output
  • Silent if nothing new (perfect for cron jobs)

State Management

Output history is stored in data/state.json:

{
  "lastCheck": "2026-02-18T20:00:00.000Z",
  "alertsSent": {
    "5842041f4e65fad6a7708a01:2026-02-22": "2026-02-18T20:00:00.000Z"
  }
}

To reset and re-output all conditions:

rm data/state.json

Turning Decisions into Alerts

surf-check outputs to stdout. To receive actual notifications, connect it to your preferred delivery method:

OpenClaw (AI Agent)

The simplest setup. OpenClaw runs surf-check on a schedule and sends output to Telegram, Discord, or any configured channel.

{
  "name": "surf-check",
  "schedule": { "kind": "cron", "expr": "0 */6 * * *", "tz": "America/New_York" },
  "payload": {
    "kind": "systemEvent",
    "text": "Run: cd ~/surf-check && npm run check:cron"
  },
  "sessionTarget": "main"
}

Cron + Webhook

Pipe output to any webhook (Slack, Discord, ntfy, Pushover, etc.):

#!/bin/bash
OUTPUT=$(cd /path/to/surf-check && npm run check:cron 2>/dev/null)
[ -n "$OUTPUT" ] && curl -d "$OUTPUT" https://your-webhook-url

Cron + Email

0 */6 * * * cd /path/to/surf-check && npm run check:cron | mail -s "Surf Alert" [email protected]

Project Structure

surf-check/
├── src/
│   ├── types.ts              # Type definitions, spot configs
│   ├── providers/
│   │   ├── surfline.ts       # Public API client
│   │   ├── surfline-premium.ts # Authenticated API client
│   │   └── noaa.ts           # NOAA buoy data
│   └── services/
│       ├── alerts.ts         # Alert evaluation logic
│       └── state.ts          # State persistence
├── scripts/
│   ├── check-forecast.ts     # Main CLI script
│   └── login-surfline.ts     # Premium login helper
├── data/
│   ├── session/              # Auth cookies (gitignored)
│   └── state.json            # Alert history (gitignored)
└── package.json

Surfline Rating Scale

| Rating | Value | Description | |--------|-------|-------------| | FLAT | 0 | No surf | | VERY_POOR | 0 | Not worth it | | POOR | 1 | Frustrating | | POOR_TO_FAIR | 1-2 | Might get a few | | FAIR | 2 | Fun for most | | FAIR_TO_GOOD | 3 | Worth the drive | | GOOD | 4 | Get out there | | GOOD_TO_EPIC | 5 | Call in sick | | EPIC | 5 | Once a year |

Contributing

PRs welcome! Some ideas:

  • [ ] SMS/email notifications
  • [ ] Tide-aware alerts (prefer incoming tide)
  • [ ] Wind quality scoring
  • [ ] Historical accuracy tracking
  • [ ] Web dashboard
  • [ ] Multi-region support

License

MIT

Disclaimer

This tool uses Surfline's undocumented API. It may break if Surfline changes their API. This project is not affiliated with Surfline.


Built for surfers who'd rather be in the water than checking forecasts.