Skill: projectsnowwork/proxyops (version 1.0.0)

--- name: proxy description: Local-first proxy inventory, routing planner, and health tracking engine. Use whenever the user needs to organize proxy assets, compare providers, track regions, protocols, auth methods, manage expiry, assign sessions, or decide which proxy best fits a task. Stores all data locally only. --- # Proxy Know what you have. Route with intention. ## Core Philosophy 1. Treat proxies as infrastructure assets, not throwaway strings. 2. Recommendation quality matters more than raw inventory size. 3. Track health, expiry, and fit-for-purpose before choosing a proxy. 4. Keep all proxy metadata local-only. ## Runtime Requirements - Python 3 must be available as `python3` - No external packages required ## Storage All data is stored locally only under: - `~/.openclaw/workspace/memory/proxy/proxies.json` - `~/.openclaw/workspace/memory/proxy/sessions.json` - `~/.openclaw/workspace/memory/proxy/stats.json` No external sync. No cloud storage. No third-party proxy APIs required. ## What This Skill Manages - provider - host and port - protocol - region / country / city - auth type - sticky or rotating behavior - session labels - status and health notes - expiry date - cost and quality metadata ## Key Workflows - **Add Proxy**: `add_proxy.py` to record a proxy and its metadata - **List Inventory**: `list_proxies.py` to view and filter available proxies - **Pick Best Fit**: `pick_proxy.py` to recommend the best proxy for a given use case - **Score Quality**: `score_proxy.py` to update health, reliability, and fit - **Update Metadata**: `update_proxy.py` to change status, expiry, notes, or tags ## Scripts | Script | Purpose | |---|---| | `init_storage.py` | Initialize local storage files | | `add_proxy.py` | Add a proxy asset | | `list_proxies.py` | List and filter proxies | | `score_proxy.py` | Score reliability and quality | | `pick_proxy.py` | Recommend the best proxy for a task | | `update_proxy.py` | Update status, expiry, notes, or tags |

path: references/philosophy.md
content: # Proxy Philosophy

1. Treat proxies as reusable infrastructure assets.
2. Prefer fit-for-purpose selection over random rotation.
3. Health, expiry, and routing clarity matter more than inventory size.
4. Keep all metadata local-only.

This skill exists to help users organize and choose proxy assets intentionally.


path: scripts/add_proxy.py
content: #!/usr/bin/env python3
import argparse
import os
import sys
import uuid
from datetime import datetime

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, SCRIPT_DIR)

from lib.storage import load_proxies, save_proxies, load_stats, save_stats
from lib.scoring import calculate_quality_score

VALID_PROTOCOLS = ["http", "https", "socks5"]
VALID_ROTATION = ["sticky", "rotating"]
VALID_STATUS = ["active", "inactive"]

def parse_csv(value):
    if not value:
        return []
    return [v.strip() for v in value.split(",") if v.strip()]

def recount_stats(proxies):
    total = len(proxies)
    active = 0
    inactive = 0
    expired = 0
    now = datetime.now().date()

    for proxy in proxies.values():
        if proxy.get("status") == "active":
            active += 1
        else:
            inactive += 1

        expires_on = proxy.get("expires_on")
        if expires_on:
            try:
                if datetime.fromisoformat(expires_on).date() < now:
                    expired += 1
            except ValueError:
                pass

    return total, active, inactive, expired

def main():
    parser = argparse.ArgumentParser(description="Add a proxy asset")
    parser.add_argument("--label", required=True)
    parser.add_argument("--provider", required=True)
    parser.add_argument("--protocol", choices=VALID_PROTOCOLS, required=True)
    parser.add_argument("--host", required=True)
    parser.add_argument("--port", required=True, type=int)
    parser.add_argument("--auth_type", default="userpass")
    parser.add_argument("--region", help="Country/region code, e.g. JP")
    parser.add_argument("--city")
    parser.add_argument("--type", default="datacenter", help="datacenter / residential / mobile / isp")
    parser.add_argument("--rotation", choices=VALID_ROTATION, default="sticky")
    parser.add_argument("--session_label")
    parser.add_argument("--status", choices=VALID_STATUS, default="active")
    parser.add_argument("--success_rate", type=float)
    parser.add_argument("--avg_latency_ms", type=int)
    parser.add_argument("--expires_on", help="YYYY-MM-DD")
    parser.add_argument("--cost_monthly", type=float)
    parser.add_argument("--tags")
    parser.add_argument("--notes", default="")

    args = parser.parse_args()

    proxy_id = f"PRX-{str(uuid.uuid4())[:4].upper()}"
    now = datetime.now().isoformat()

    proxy = {
        "id": proxy_id,
        "label": args.label,
        "provider": args.provider,
        "protocol": args.protocol,
        "host": args.host,
        "port": args.port,
        "auth_type": args.auth_type,
        "region": args.region,
        "city": args.city,
        "type": args.type,
        "rotation": args.rotation,
        "session_label": args.session_label,
        "status": args.status,
        "quality_score": 0,
        "success_rate": args.success_rate,
        "avg_latency_ms": args.avg_latency_ms,
        "expires_on": args.expires_on,
        "cost_monthly": args.cost_monthly,
        "tags": parse_csv(args.tags),
        "notes": args.notes,
        "created_at": now,
        "updated_at": now
    }

    proxy["quality_score"] = calculate_quality_score(proxy)

    data = load_proxies()
    data["proxies"][proxy_id] = proxy
    save_proxies(data)

    stats = load_stats()
    total, active, inactive, expired = recount_stats(data["proxies"])
    stats["total_proxies"] = total
    stats["active_proxies"] = active
    stats["inactive_proxies"] = inactive
    stats["expired_proxies"] = expired
    save_stats(stats)

    print(f"✓ Proxy added: {proxy_id}")
    print(f"  {args.label}")
    print(f"  Provider: {args.provider}")
    print(f"  Quality score: {proxy['quality_score']}")

if __name__ == "__main__":
    main()


path: scripts/init_storage.py
content: #!/usr/bin/env python3
import json
import os
from datetime import datetime

PROXY_DIR = os.path.expanduser("~/.openclaw/workspace/memory/proxy")
PROXIES_FILE = os.path.join(PROXY_DIR, "proxies.json")
SESSIONS_FILE = os.path.join(PROXY_DIR, "sessions.json")
STATS_FILE = os.path.join(PROXY_DIR, "stats.json")

def write_json_if_missing(path, payload):
    if not os.path.exists(path):
        with open(path, "w", encoding="utf-8") as f:
            json.dump(payload, f, indent=2, ensure_ascii=False)

def main():
    now = datetime.now().isoformat()
    os.makedirs(PROXY_DIR, exist_ok=True)

    write_json_if_missing(PROXIES_FILE, {
        "metadata": {
            "version": "1.0.0",
            "created_at": now,
            "last_updated": now
        },
        "proxies": {}
    })

    write_json_if_missing(SESSIONS_FILE, {
        "metadata": {
            "version": "1.0.0",
            "created_at": now,
            "last_updated": now
        },
        "sessions": {}
    })

    write_json_if_missing(STATS_FILE, {
        "total_proxies": 0,
        "active_proxies": 0,
        "inactive_proxies": 0,
        "expired_proxies": 0,
        "last_scored_at": None
    })

    print("✓ Proxy storage initialized")
    print(f"  {PROXIES_FILE}")
    print(f"  {SESSIONS_FILE}")
    print(f"  {STATS_FILE}")

if __name__ == "__main__":
    main()


path: scripts/lib/scoring.py
content: #!/usr/bin/env python3
from datetime import datetime, date

def days_until(expiry):
    if not expiry:
        return None
    try:
        d = datetime.fromisoformat(expiry).date()
        return (d - date.today()).days
    except ValueError:
        return None

def calculate_quality_score(proxy):
    score = 50

    status = proxy.get("status")
    if status == "active":
        score += 15
    elif status == "inactive":
        score -= 15

    success_rate = proxy.get("success_rate")
    if success_rate is not None:
        try:
            sr = float(success_rate)
            if sr >= 95:
                score += 20
            elif sr >= 85:
                score += 10
            elif sr < 70:
                score -= 15
        except (TypeError, ValueError):
            pass

    latency = proxy.get("avg_latency_ms")
    if latency is not None:
        try:
            lat = int(latency)
            if lat <= 150:
                score += 10
            elif lat <= 300:
                score += 5
            elif lat > 800:
                score -= 10
        except (TypeError, ValueError):
            pass

    expiry = days_until(proxy.get("expires_on"))
    if expiry is not None:
        if expiry < 0:
            score -= 50
        elif expiry <= 3:
            score -= 15
        elif expiry <= 14:
            score -= 5

    if proxy.get("rotation") == "sticky":
        score += 3

    return max(0, min(100, int(score)))

def fit_score(proxy, region=None, protocol=None, rotation=None, max_latency_ms=None):
    score = 0

    if proxy.get("status") != "active":
        return -9999

    expiry = days_until(proxy.get("expires_on"))
    if expiry is not None and expiry < 0:
        return -9999

    if region:
        if (proxy.get("region") or "").lower() == region.lower():
            score += 25
        else:
            score -= 20

    if protocol:
        if (proxy.get("protocol") or "").lower() == protocol.lower():
            score += 20
        else:
            score -= 15

    if rotation:
        if (proxy.get("rotation") or "").lower() == rotation.lower():
            score += 15
        else:
            score -= 10

    latency = proxy.get("avg_latency_ms")
    if max_latency_ms is not None and latency is not None:
        try:
            if int(latency) <= int(max_latency_ms):
                score += 15
            else:
                score -= 20
        except (TypeError, ValueError):
            pass

    score += int(proxy.get("quality_score", 0) / 2)
    return score


path: scripts/lib/storage.py
content: #!/usr/bin/env python3
import json
import os
from datetime import datetime

PROXY_DIR = os.path.expanduser("~/.openclaw/workspace/memory/proxy")
PROXIES_FILE = os.path.join(PROXY_DIR, "proxies.json")
SESSIONS_FILE = os.path.join(PROXY_DIR, "sessions.json")
STATS_FILE = os.path.join(PROXY_DIR, "stats.json")

def ensure_dir():
    os.makedirs(PROXY_DIR, exist_ok=True)

def _safe_load(path, default):
    ensure_dir()
    if not os.path.exists(path):
        return default
    try:
        with open(path, "r", encoding="utf-8") as f:
            return json.load(f)
    except (json.JSONDecodeError, OSError):
        return default

def _atomic_save(path, data):
    ensure_dir()
    tmp = path + ".tmp"
    with open(tmp, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=2, ensure_ascii=False)
    os.replace(tmp, path)

def load_proxies():
    now = datetime.now().isoformat()
    return _safe_load(PROXIES_FILE, {
        "metadata": {
            "version": "1.0.0",
            "created_at": now,
            "last_updated": now
        },
        "proxies": {}
    })

def save_proxies(data):
    data.setdefault("metadata", {})
    data["metadata"]["last_updated"] = datetime.now().isoformat()
    _atomic_save(PROXIES_FILE, data)

def load_sessions():
    now = datetime.now().isoformat()
    return _safe_load(SESSIONS_FILE, {
        "metadata": {
            "version": "1.0.0",
            "created_at": now,
            "last_updated": now
        },
        "sessions": {}
    })

def save_sessions(data):
    data.setdefault("metadata", {})
    data["metadata"]["last_updated"] = datetime.now().isoformat()
    _atomic_save(SESSIONS_FILE, data)

def load_stats():
    return _safe_load(STATS_FILE, {
        "total_proxies": 0,
        "active_proxies": 0,
        "inactive_proxies": 0,
        "expired_proxies": 0,
        "last_scored_at": None
    })

def save_stats(data):
    _atomic_save(STATS_FILE, data)


path: scripts/list_proxies.py
content: #!/usr/bin/env python3
import argparse
import os
import sys

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, SCRIPT_DIR)

from lib.storage import load_proxies

def main():
    parser = argparse.ArgumentParser(description="List proxies")
    parser.add_argument("--region")
    parser.add_argument("--protocol")
    parser.add_argument("--status")
    parser.add_argument("--provider")
    args = parser.parse_args()

    data = load_proxies()
    proxies = list(data.get("proxies", {}).values())

    filtered = []
    for proxy in proxies:
        if args.region and (proxy.get("region") or "").lower() != args.region.lower():
            continue
        if args.protocol and (proxy.get("protocol") or "").lower() != args.protocol.lower():
            continue
        if args.status and (proxy.get("status") or "").lower() != args.status.lower():
            continue
        if args.provider and (proxy.get("provider") or "").lower() != args.provider.lower():
            continue
        filtered.append(proxy)

    if not filtered:
        print("No proxies found.")
        return

    filtered.sort(key=lambda x: x.get("quality_score", 0), reverse=True)

    for proxy in filtered:
        print(f"{proxy['id']} | {proxy['label']}")
        print(
            f"  provider={proxy.get('provider')} "
            f"protocol={proxy.get('protocol')} "
            f"region={proxy.get('region')} "
            f"rotation={proxy.get('rotation')} "
            f"status={proxy.get('status')} "
            f"score={proxy.get('quality_score')}"
        )

if __name__ == "__main__":
    main()


path: scripts/pick_proxy.py
content: #!/usr/bin/env python3
import argparse
import os
import sys

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, SCRIPT_DIR)

from lib.storage import load_proxies
from lib.scoring import fit_score

def reason_for(proxy, region=None, protocol=None, rotation=None):
    reasons = []

    if region and (proxy.get("region") or "").lower() == region.lower():
        reasons.append("region matches")
    if protocol and (proxy.get("protocol") or "").lower() == protocol.lower():
        reasons.append("protocol matches")
    if rotation and (proxy.get("rotation") or "").lower() == rotation.lower():
        reasons.append("rotation matches")

    score = proxy.get("quality_score")
    if score is not None:
        reasons.append(f"quality score {score}")

    latency = proxy.get("avg_latency_ms")
    if latency is not None:
        reasons.append(f"latency {latency}ms")

    return ", ".join(reasons) if reasons else "best available fit"

def main():
    parser = argparse.ArgumentParser(description="Pick the best-fit proxy")
    parser.add_argument("--region")
    parser.add_argument("--protocol", choices=["http", "https", "socks5"])
    parser.add_argument("--rotation", choices=["sticky", "rotating"])
    parser.add_argument("--max_latency_ms", type=int)
    args = parser.parse_args()

    data = load_proxies()
    proxies = list(data.get("proxies", {}).values())

    ranked = []
    for proxy in proxies:
        ranked.append((
            fit_score(
                proxy,
                region=args.region,
                protocol=args.protocol,
                rotation=args.rotation,
                max_latency_ms=args.max_latency_ms
            ),
            proxy
        ))

    ranked.sort(key=lambda x: x[0], reverse=True)
    picks = [proxy for score, proxy in ranked if score > 0][:3]

    if not picks:
        print("No strong proxy match found.")
        return

    labels = ["Top Pick", "Backup", "Backup"]
    for idx, proxy in enumerate(picks):
        print(f"{labels[idx]} — {proxy['id']} | {proxy['label']}")
        print(f"  {reason_for(proxy, region=args.region, protocol=args.protocol, rotation=args.rotation)}")

if __name__ == "__main__":
    main()


path: scripts/score_proxy.py
content: #!/usr/bin/env python3
import argparse
import os
import sys
from datetime import datetime

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, SCRIPT_DIR)

from lib.storage import load_proxies, save_proxies, load_stats, save_stats
from lib.scoring import calculate_quality_score

def main():
    parser = argparse.ArgumentParser(description="Update scoring fields for a proxy")
    parser.add_argument("--id", required=True)
    parser.add_argument("--success_rate", type=float)
    parser.add_argument("--avg_latency_ms", type=int)
    parser.add_argument("--status", choices=["active", "inactive"])
    args = parser.parse_args()

    data = load_proxies()
    proxies = data.get("proxies", {})

    if args.id not in proxies:
        print(f"Proxy not found: {args.id}")
        sys.exit(1)

    proxy = proxies[args.id]

    if args.success_rate is not None:
        proxy["success_rate"] = args.success_rate
    if args.avg_latency_ms is not None:
        proxy["avg_latency_ms"] = args.avg_latency_ms
    if args.status is not None:
        proxy["status"] = args.status

    proxy["quality_score"] = calculate_quality_score(proxy)
    proxy["updated_at"] = datetime.now().isoformat()
    save_proxies(data)

    stats = load_stats()
    stats["last_scored_at"] = datetime.now().isoformat()
    save_stats(stats)

    print(f"✓ Scored {args.id}")
    print(f"  Quality score: {proxy['quality_score']}")

if __name__ == "__main__":
    main()


path: scripts/update_proxy.py
content: #!/usr/bin/env python3
import argparse
import os
import sys
from datetime import datetime

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, SCRIPT_DIR)

from lib.storage import load_proxies, save_proxies
from lib.scoring import calculate_quality_score

def parse_csv(value):
    if not value:
        return None
    return [v.strip() for v in value.split(",") if v.strip()]

def main():
    parser = argparse.ArgumentParser(description="Update proxy metadata")
    parser.add_argument("--id", required=True)
    parser.add_argument("--status", choices=["active", "inactive"])
    parser.add_argument("--expires_on")
    parser.add_argument("--notes")
    parser.add_argument("--tags")
    parser.add_argument("--session_label")
    args = parser.parse_args()

    data = load_proxies()
    proxies = data.get("proxies", {})

    if args.id not in proxies:
        print(f"Proxy not found: {args.id}")
        sys.exit(1)

    proxy = proxies[args.id]

    if args.status is not None:
        proxy["status"] = args.status
    if args.expires_on is not None:
        proxy["expires_on"] = args.expires_on
    if args.notes is not None:
        proxy["notes"] = args.notes
    if args.tags is not None:
        proxy["tags"] = parse_csv(args.tags) or []
    if args.session_label is not None:
        proxy["session_label"] = args.session_label

    proxy["quality_score"] = calculate_quality_score(proxy)
    proxy["updated_at"] = datetime.now().isoformat()
    save_proxies(data)

    print(f"✓ Updated {args.id}")
    print(f"  Quality score: {proxy['quality_score']}")

if __name__ == "__main__":
    main()


path: skill.json
content: {
  "name": "proxy",
  "version": "1.0.0",
  "description": "Local-first proxy inventory, routing planner, and health tracking engine.",
  "entrypoints": [],
  "files": [
    "SKILL.md",
    "skill.json",
    "scripts/init_storage.py",
    "scripts/add_proxy.py",
    "scripts/list_proxies.py",
    "scripts/score_proxy.py",
    "scripts/pick_proxy.py",
    "scripts/update_proxy.py",
    "scripts/lib/storage.py",
    "scripts/lib/scoring.py",
    "references/philosophy.md"
  ]
}


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