Skill: dqhieu/website-flow-monitor (version 1.0.0)

--- name: website-flow-monitor description: Analyze a website URL, discover business-critical user flows to monitor, propose a monitoring plan, and after explicit user confirmation schedule cron health checks. Use when a user asks to monitor a website, check uptime/checkout/onboarding flows, design synthetic checks, or automate recurring website flow checks. --- # Website Flow Monitor Take a user-provided website URL and build a practical monitoring plan. ## Workflow 1. Normalize input URL (ensure `https://`). 2. Discover likely flows by scanning: - homepage - pricing - docs/api - blog/changelog - downloads/signup/login/dashboard if present - robots/sitemaps 3. Categorize checks by impact: - **Revenue**: pricing, checkout, billing links, purchase CTAs - **Onboarding**: signup/login/download/get-started flows - **Product/API**: docs and API endpoints (including expected auth failures like 401) - **Trust**: privacy, terms, contact/support - **SEO/Discovery**: robots.txt and sitemaps - **Content**: blog posts, changelog entries 4. Return a proposed monitoring set with: - URL - expected behavior (200, redirect, 401/403, etc.) - impact category 5. Ask for confirmation before scheduling cron. 6. After confirmation, create/update a cron job with: - `sessionTarget: isolated` - concise agentTurn task that checks all agreed flows - delivery mode announce ## Rules - Do not schedule cron until user confirms the proposed flow list and frequency. - Prefer actionable summaries: failures first, then healthy checks. - Flag as **ALERT** for 4xx/5xx (except expected 401/403 on auth-required API checks), redirect loops, or missing critical links. - If the user requests changes (skip/add endpoint), update the existing cron job instead of creating duplicates. ## Discovery helper Use this script for quick link discovery: ```bash python3 {baseDir}/scripts/discover_flows.py --url https://example.com ``` It returns JSON with discovered internal/external links and suggested flow candidates. ## Cron prompt template (adapt per site) Use this shape in `payload.message`: - mention this is a recurring reminder - list exact URLs and expected behavior - require output format: `OK / WARN / ALERT` - require impact tags: revenue/onboarding/product/trust/seo/support - include "if all healthy, short OK summary" instruction Keep it short and deterministic.

path: scripts/discover_flows.py
content: #!/usr/bin/env python3
import argparse
import json
import re
from urllib.parse import urljoin, urlparse

import requests


def extract_links(html: str):
    hrefs = re.findall(r'href=["\']([^"\']+)["\']', html, flags=re.I)
    out = []
    for h in hrefs:
        h = h.replace('&amp;', '&').strip()
        if not h or h.startswith('#') or h.startswith('mailto:') or h.startswith('tel:'):
            continue
        out.append(h)
    return out


def classify(path: str):
    p = path.lower()
    if p.startswith('/blog') or p.startswith('/changelog'):
        return 'content'
    if any(k in p for k in ['pricing', 'checkout', 'buy', 'billing', 'payment']):
        return 'revenue'
    if any(k in p for k in ['signup', 'sign-up', 'register', 'login', 'dashboard', 'download', 'get-started']):
        return 'onboarding'
    if any(k in p for k in ['api', 'docs', 'reference']):
        return 'product'
    if any(k in p for k in ['privacy', 'terms', 'contact', 'support']):
        return 'trust'
    if any(k in p for k in ['sitemap', 'robots']):
        return 'seo'
    return 'content'


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument('--url', required=True)
    ap.add_argument('--timeout', type=int, default=20)
    args = ap.parse_args()

    base = args.url.strip()
    if not base.startswith('http://') and not base.startswith('https://'):
        base = 'https://' + base

    pages = ['/', '/pricing', '/api', '/docs', '/blog', '/changelog', '/downloads']
    seen = set()
    discovered = []

    for p in pages:
        try:
            r = requests.get(urljoin(base, p), timeout=args.timeout, allow_redirects=True, headers={'User-Agent': 'OpenClawFlowMonitor/1.0'})
            html = r.text or ''
            links = extract_links(html)
            for l in links:
                full = urljoin(r.url, l)
                if full in seen:
                    continue
                seen.add(full)
                pu = urlparse(full)
                discovered.append({
                    'url': full,
                    'host': pu.netloc,
                    'path': pu.path or '/',
                    'category': classify(pu.path or '/'),
                    'source': r.url,
                })
        except Exception:
            continue

    # Add SEO essentials
    for p in ['/robots.txt', '/sitemap.xml']:
        full = urljoin(base, p)
        if full not in seen:
            discovered.append({
                'url': full,
                'host': urlparse(full).netloc,
                'path': p,
                'category': 'seo',
                'source': 'synthetic',
            })

    # Keep high-signal categories first
    order = {'revenue': 0, 'onboarding': 1, 'product': 2, 'trust': 3, 'seo': 4, 'content': 5}
    discovered.sort(key=lambda x: (order.get(x['category'], 9), x['url']))

    print(json.dumps({'base': base, 'candidates': discovered}, indent=2))


if __name__ == '__main__':
    main()


Security scan verdicts — ClawScan: clean | static analysis:  | VirusTotal: clean | SkillSpector: clean (LOW)