Communitygithub.com

Varnan-Tech/opendirectory

npmパッケージのダウンロードデータを分析し、急成長中のパッケージのメンテナー情報を取得、リード生成に役立つブリーフを出力するスキルです。

opendirectory とは?

このスキルは、指定されたnpmパッケージ(自社・競合他社を問わない)の日次ダウンロードデータをnpm APIから12週間分取得し、「ブレイクアウト・ベロシティ」スコアを計算することで、急成長(ホッケースティック成長)しているパッケージを特定します。その後、npmレジストリとGitHub APIからメンテナーのプロフィール(GitHubハンドル、Twitterユーザー名など)を取得し、連絡先シグナルとアウトリーチメッセージを含む、優先順位付けされたリードブリーフを出力します。開発者向けツールのエバンジェリスト発見、競合パッケージの勢い追跡、npmメンテナーのTwitter/GitHubへのマッピングに特に有用です。このスキルは、npm API(認証不要)とGitHub API(GitHubトークン推奨、最大60リクエスト/時間)に依存し、ダウンロード数が週500未満のパッケージや、GitHubレート制限に達した場合でも、グレースフルに動作するよう設計されています。

対応✓Claude Code~Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/Varnan-Tech/opendirectory/tree/main/skills/npm-downloads-to-leads

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

npmダウンロードからリードへ

npmパッケージのリストを取得し、12週間分のダウンロードデータを取得、ブレイクアウト・ベロシティを計算、メンテナーのプロフィールをエンリッチ、連絡先シグナルとアウトリーチメッセージを含むランク付けされたリードブリーフを、ブレイクアウトパッケージごとに出力します。


重要なルール: 出力に含まれるすべてのパッケージダウンロード数は、npm APIのレスポンスから取得する必要があります。すべてのメンテナーのGitHubハンドルまたはTwitterユーザー名は、GitHub APIのレスポンスから取得する必要があります — npmユーザー名から推測してはいけません。GitHub APIがtwitter_usernameフィールドを返さなかった場合は、「GitHubでは見つかりませんでした」と書き、捏造しないでください。


よくある間違い

エージェントがやりがちなことなぜそれが間違いか
リスト内のすべてのパッケージに対してGitHubプロフィールを取得するレート制限はトークンなしで60 req/hrです。安定または減少しているパッケージをエンリッチすると、ブレイクアウトパッケージに到達する前に予算を浪費します。ブレイクアウトおよびウォッチングパッケージに対してのみプロフィールを取得してください。
生の週間ダウンロード数でパッケージをランク付けする生のダウンロード数はReactやlodashを優先し、これらはリードにはなりません。週に1Kから8Kに成長するパッケージの方が、週に50MのReactよりも有望です。ベロシティスコアがシグナルです。
スコープ付きパッケージのURLエンコードをスキップする@org/pkgをエンコードせずに使用すると、npm APIから404が返ります。すべてのスコープ付きパッケージ名について、@を%40に、/を%2Fにエンコードしてください。
GitHubレート制限に達したときにスキルを停止するグレースフルに劣化してください。npmデータからベロシティリーダーボードを提示し、残りのGitHubエンリッチメントをスキップし、data_quality_flagsにフラグを追加してください。処理を中断しないでください。
特定のパッケージを名前指定せずにアウトリーチメッセージを作成する一般的な「あなたのプロジェクトを見ました」というメッセージは無視されます。すべてのアウトリーチメッセージは、パッケージ名、その成長数値、およびユーザーが提供したコンテキストとの具体的な関連性を記載する必要があります。
週間ダウンロード数が500未満のパッケージをリードとして含める週500未満はノイズです。メンテナーにはまだ意味のあるオーディエンスがいません。「時期尚早」としてフラグを立てますが、リードとしては提示しないでください。

ステップ1: セットアップ確認

echo "GITHUB_TOKEN: ${GITHUB_TOKEN:-設定されていません。未認証のレート制限が適用されます(60 req/hr — 約10パッケージ分)}"

GITHUB_TOKENが設定されていない場合: 続行します。ユーザーに「GITHUB_TOKENが設定されていません。GitHubエンリッチメントは、レート制限に達するまで約10パッケージに制限されます。github.com/settings/tokensでトークンを追加してください(スコープは不要です)。」と通知します。

必須キーはありません。npm APIとnpmレジストリは完全にパブリックであり、認証は必要ありません。


ステップ2: 入力の収集

会話から以下を収集します:

  • 1つ以上のnpmパッケージ名(esbuildのような非スコープ、または @hono/honoのようなスコープ付き)
  • オプション: 短いプロダクトコンテキスト文字列(アウトリーチメッセージのパーソナライズに使用)

ユーザーがnpmjs.comのURLを提供した場合は、パッケージ名のみを抽出します。@と組織プレフィックスを含む、完全なスコープ名を保持します。エンコードはステップ3で処理します。

パッケージが提供されなかった場合: 「どのnpmパッケージを分析しますか? 自社、競合他社、またはその混合を提供してください。例: esbuild, @hono/hono, zod, valibot」と質問します。

python3 << 'PYEOF'
import json, sys

packages_raw = "PACKAGES_HERE"  # カンマまたは改行区切り
product_context = "CONTEXT_HERE"  # オプション、空文字列可

packages = [p.strip() for p in packages_raw.replace("\n", ",").split(",") if p.strip()]
if not packages:
    print("ERROR: No packages provided.")
    sys.exit(1)

print(f"Packages to analyze: {len(packages)}")
for p in packages:
    print(f"  {p}")

with open("/tmp/npl-input.json", "w") as f:
    json.dump({"packages": packages, "product_context": product_context}, f)
PYEOF

ステップ3: 12週間分のダウンロードデータを取得

スタンドアロンスクリプトが利用可能な場合はそれを使用してください — 以下のインラインコードブロックを実行する必要はなく、ステップ3、4、5を1回の呼び出しで処理します。

# スクリプトが存在するか確認
ls scripts/fetch.py 2>/dev/null && echo "script available" || echo "script not found"

スクリプトが利用可能な場合、直接実行してステップ6にスキップします:

python3 scripts/fetch.py PACKAGES_HERE --context "CONTEXT_HERE" --output /tmp/npl-script-out.json

次に、出力をステップ6が期待するエンリッチされた形式にロードします:

python3 << 'PYEOF'
import json

out = json.load(open("/tmp/npl-script-out.json"))
# スクリプト出力には結果配列があります — ステップ6-8のためにスコアリング済みとエンリッチ済みに分割
enriched = [r for r in out["results"] if "profile" in r]
scored = out["results"]
json.dump(scored, open("/tmp/npl-scored.json", "w"), indent=2)
json.dump(enriched, open("/tmp/npl-enriched.json", "w"), indent=2)
json.dump({"packages": [r["package"] for r in scored], "product_context": out.get("product_context", "")},
          open("/tmp/npl-input.json", "w"), indent=2)
print(f"Loaded {len(scored)} packages | {out['breakout_count']} breakout | {out['watching_count']} watching")
PYEOF

スクリプトが利用できない場合、以下のインラインコードを実行します。

各パッケージの日次ダウンロードデータをnpm Downloads APIから取得し、週単位に集約します。

python3 << 'PYEOF'
import json, urllib.request, sys, time
from datetime import datetime, timedelta, timezone
from collections import defaultdict
import urllib.parse

data = json.load(open("/tmp/npl-input.json"))
packages = data["packages"]

end_date = datetime.now(tz=timezone.utc)
start_date = end_date - timedelta(weeks=13)  # 部分週のための追加バッファ
start_str = start_date.strftime("%Y-%m-%d")
end_str = end_date.strftime("%Y-%m-%d")

results = []
failed = []

for pkg in packages:
    # スコープ付きパッケージをURLエンコード: @ -> %40, / -> %2F
    encoded = pkg.replace("@", "%40").replace("/", "%2F")
    url = f"https://api.npmjs.org/downloads/range/{start_str}:{end_str}/{encoded}"

    try:
        req = urllib.request.Request(url, headers={"User-Agent": "npm-downloads-to-leads/1.0"})
        with urllib.request.urlopen(req, timeout=20) as resp:
            raw = json.loads(resp.read())

        # 日次をISO週で週単位に集約
        weekly = defaultdict(int)
        for entry in raw.get("downloads", []):
            day = datetime.strptime(entry["day"], "%Y-%m-%d")
            week_key = day.isocalendar()[:2]  # (year, week_num)
            weekly[week_key] += entry["downloads"]

        weeks = [v for k, v in sorted(weekly.items())]
        # 最後の12週間の完全な週バケットを取得
        weeks = weeks[-12:]

        results.append({
            "package": pkg,
            "weeks": weeks,
            "total_weeks": len(weeks),
            "current_weekly": weeks[-1] if weeks else 0,
            "status": "ok"
        })
        print(f"  {pkg}: {len(weeks)} weeks, latest week {weeks[-1]:,} downloads")

    except urllib.error.HTTPError as e:
        if e.code == 404:
            failed.append(pkg)
            results.append({"package": pkg, "weeks": [], "total_weeks": 0, "current_weekly": 0, "status": "not_found"})
            print(f"  {pkg}: NOT FOUND (404) -- will be skipped")
        else:
            failed.append(pkg)
            results.append({"package": pkg, "weeks": [], "total_weeks": 0, "current_weekly": 0, "status": f"error_{e.code}"})
            print(f"  {pkg}: HTTP {e.code} error")
    except Exception as e:
        failed.append(pkg)
        results.append({"package": pkg, "weeks": [], "total_weeks": 0, "current_weekly": 0, "status": f"error"})
        print(f"  {pkg}: fetch failed ({e})")

    time.sleep(0.2)  # 穏やかなレート制限

json.dump(results, open("/tmp/npl-download-data.json", "w"), indent=2)
print(f"\nFetch complete. OK: {len(results) - len(failed)} | Failed/Not found: {len(failed)}")
if failed:
    print(f"Skipped: {', '.join(failed)}")
PYEOF

すべてのパッケージが404またはエラーを返した場合: 停止します。ユーザーに「ダウンロードデータを取得できませんでした。パッケージ名が正しく、npmjs.comに存在することを確認してください。スコープ付きパッケージは完全な名前(@org/package)を含める必要があります。」と伝えます。


ステップ4: ベロシティスコアを計算

API呼び出しは不要です。純粋なPythonです。各パッケージのベロシティスコア、成長率を計算し、分類します。

python3 << 'PYEOF'
import json

raw_results = json.load(open("/tmp/npl-download-data.json"))
scored = []

for item in raw_results:
    pkg = item["package"]
    weeks = item["weeks"]
    status = item["status"]

    if status != "ok" or len(weeks) < 4:
        scored.append({**item, "velocity_score": 0, "growth_pct": 0, "tier": "insufficient_data",
                       "recent_4_avg": 0, "prior_4_avg": 0})
        continue

    recent_4 = sum(weeks[-4:]) / 4
    prior_4 = sum(weeks[-8:-4]) / max(len(weeks) - 4, 1) if len(weeks) >= 8 else sum(weeks[:4]) / max(len(weeks[:4]), 1)
    recent_2 = sum(weeks[-2:]) / 2
    mid_2 = sum(weeks[-4:-2]) / 2 if len(weeks) >= 4 else recent_2

    growth_ratio = recent_4 / max(prior_4, 1)
    acceleration = recent_2 / max(mid_2, 1)
    growth_pct = round((growth_ratio - 1) * 100, 1)

    # スイートスポット乗数: 500-500K 週間ダウンロード数
    if recent_4 < 500:
        noise_factor = max(recent_4 / 500, 0.1)
    elif recent_4 > 500_000:
        noise_factor = max(500_000 / recent_4, 0.1)
    else:
        noise_factor = 1.0

    velocity_score = round(growth_ratio * acceleration * noise_factor * 100, 1)

    # 分類
    if velocity_score > 80 and 500 < recent_4 < 500_000 and growth_ratio >= 1.5:
        tier = "breakout"
    elif velocity_score > 40 and recent_4 >= 500 and growth_ratio >= 1.2:
        tier = "watching"
    elif recent_4 < 500:
        tier = "too_early"
    elif recent_4 >= 500_000:
        tier = "established"
    else:
        tier = "steady"

    scored.append({
        **item,
        "velocity_score": velocity_score,
        "growth_pct": growth_pct,
        "recent_4_avg": round(recent_4),
        "prior_4_avg": round(prior_4),
        "tier": tier
    })

# ベロシティスコアの降順でソート
scored.sort(key=lambda x: x["velocity_score"], reverse=True)

json.dump(scored, open("/tmp/npl-scored.json", "w"), indent=2)

breakout = [p for p in scored if p["tier"] == "breakout"]
watching = [p for p in scored if p["tier"] == "watching"]
too_early = [p for p in scored if p["tier"] == "too_early"]

print(f"Velocity scoring complete:")
print(f"  BREAKOUT: {len(breakout)}")
print(f"  WATCHING: {len(watching)}")
print(f"  STEADY/ESTABLISHED: {len([p for p in scored if p['tier'] in ('steady','established')])}")
print(f"  TOO EARLY (<500/week): {len(too_early)}")
print()
for p in scored[:10]:
    print(f"  {p['tier'].upper():12} {p['package']:30} score={p['velocity_score']:6.1f}  "
          f"{p['recent_4_avg']:>8,}/wk  growth={p['growth_pct']:+.0f}%")

# 分析する価値がない場合は停止
if not breakout and not watching:
    all_too_early = all(p["tier"] in ("too_early", "insufficient_data") for p in scored)
    if all_too_early:
        print("\nERROR: All packages are below the 500 weekly downloads threshold for reliable velocity analysis.")
        print("Try packages with more community adoption.")
        import sys; sys.exit(1)
PYEOF

すべてのパッケージが週500未満の場合: 上記のメッセージで停止します。


ステップ5: メンテナープロフィールを取得

ブレイクアウトおよびウォッチングパッケージのみ。npmレジストリメタデータを取得し、次にGitHubユーザープロフィールを取得します。

python3 << 'PYEOF'
import json, urllib.request, re, os, time

scored = json.load(open("/tmp/npl-scored.json"))
token = os.environ.get("GITHUB_TOKEN", "")

gh_headers = {"Accept": "application/vnd.github+json", "User-Agent": "npm-downloads-to-leads/1.0"}
if token:
    gh_headers["Authorization"] = f"Bearer {token}"

target_packages = [p for p in scored if p["tier"] in ("breakout", "watching")]
print(f"Fetching profiles for {len(target_packages)} packages (breakout + watching)...")

gh_rate_remaining = 999
enriched = []

for item in target_packages:
    pkg = item["package"]
    profile = {"package": pkg, "npm_maintainers": [], "description": "", "keywords": [],
               "github_owner": None, "github_repo": None, "github_users": [], "npm_homepage": ""}

    # --- npm registry ---
    encoded = pkg.replace("@", "%40").replace("/", "%2F")
    reg_url = f"https://registry.npmjs.org/{encoded}"
    try:
        req = urllib.request.Request(reg_url, headers={"User-Agent": "npm-downloads-to-leads/1.0"})
        with urllib.request.urlopen(req, timeout=20) as resp:
            reg = json.loads(resp.read())

        profile["description"] = reg.get("description", "")
        profile["keywords"] = (reg.get("keywords") or [])[:6]
        profile["npm_homepage"] = reg.get("homepage", "")
        profile["npm_maintainers"] = [m.get("name", "") for m in reg.get("maintainers", []) if m.get("name")]

        # リポジトリURLからGitHubオーナーを抽出
        repo_field = reg.get("repository") or {}
        if isinstance(repo_field, dict):
            repo_url = repo_field.get("url", "")
        else:
            repo_url = str(repo_field)
        gh_match = re.search(r"github\.com[/:]([^/]+)/([^/.]+)", repo_url)
        if gh_match:
            profile["github_owner"] = gh_match.group(1)
            profile["github_repo"] = gh_match.group(2).rstrip(".git")

        print(f"  {pkg}: registry OK | maintainers={profile['npm_maintainers'][:3]} | "
              f"github_owner={profile['github_owner']}")
    except Exception as e:
        print(f"  {pkg}: registry fetch failed ({e})")

    time.sleep(0.1)

    # --- GitHub user profiles ---
    candidates = []
    if profile["github_owner"]:
        candidates.append(profile["github_owner"])
    # npmメンテナーのユーザー名も試す(多くの場合GitHubと一致)
    for m in profile["npm_maintainers"][:2]:
        if m and m not in candidates:
            candidates.append(m)

    for username in candidates[:3]:
        if gh_rate_remaining <= 5:
            print(f"  GitHub rate limit low ({gh_rate_remaining} remaining) -- skipping {username}")
            break

        gh_url = f"https://api.github.com/users/{username}"
        req = urllib.request.Request(gh_url, headers=gh_headers)
        try:
            with urllib.request.urlopen(req, timeout=15) as resp:
                gh_rate_remaining = int(resp.headers.ge

…

[truncated for translation]

重要な注記: このコードブロックは長いため途中で切れています。完全版は元のSKILL.mdに記載されています。


ステップ6: リードブリーフを構築

スコアリング済みデータとエンリッチ済みプロフィールを組み合わせて、ランク付けされたリードブリーフを生成します。

python3 << 'PYEOF'
import json

scored = json.load(open("/tmp/npl-scored.json"))
# enriched が存在する場合のみロード
try:
    enriched = json.load(open("/tmp/npl-enriched.json"))
except FileNotFoundError:
    enriched = []

# データ品質フラグ
data_quality_flags = []
if not enriched:
    data_quality_flags.append("GitHubプロフィールエンリッチメントが完了していません。レート制限またはエラーが発生した可能性があります。")

# ブレイクアウトとウォッチングのパッケージをブリーフにまとめる
brief = []
for item in scored:
    if item["tier"] not in ("breakout", "watching"):
        continue
    pkg_name = item["package"]
    # 対応するプロフィールを見つける
    prof = next((e for e in enriched if e["package"] == pkg_name), {})
    
    brief_entry = {
        "package": pkg_name,
        "tier": item["tier"],
        "velocity_score": item["velocity_score"],
        "growth_pct": item["growth_pct"],
        "current_weekly": item["current_weekly"],
        "recent_4_avg": item["recent_4_avg"],
        "prior_4_avg": item["prior_4_avg"],
        "description": prof.get("description", ""),
        "keywords": prof.get("keywords", []),
        "npm_homepage": prof.get("npm_homepage", ""),
        "maintainers": prof.get("npm_maintainers", []),
        "github_owner": prof.get("github_owner"),
        "github_repo": prof.get("github_repo"),
        "github_users": prof.get("github_users", []),
        "data_quality_flags": data_quality_flags
    }
    brief.append(brief_entry)

# 出力
print(f"\n{'='*60}")
print(f"NPM DOWNLOADS TO LEADS - BRIEF")
print(f"{'='*60}")
print(f"\nTotal packages analyzed: {len(scored)}")
print(f"Breakout: {len([p for p in scored if p['tier']=='breakout'])}")
print(f"Watching: {len([p for p in scored if p['tier']=='watching'])}")
print(f"Too early/Steady/Established: {len([p for p in scored if p['tier'] in ('too_early','steady','established')])}")

if data_quality_flags:
    print(f"\n⚠️ Data quality warnings:")
    for flag in data_quality_flags:
        print(f"  - {flag}")

print(f"\n{'='*60}")
print(f"TOP LEADS")
print(f"{'='*60}")

for i, entry in enumerate(brief[:10]):  # トップ10
    print(f"\n{i+1}. {entry['package']} ({entry['tier'].upper()})")
    print(f"   Score: {entry['velocity_score']:.1f} | Growth: {entry['growth_pct']:+.0f}%")
    print(f"   Current weekly: {entry['current_weekly']:,} | Recent 4wk avg: {entry['recent_4_avg']:,}")
    print(f"   Description: {entry['description'][:100]}..." if len(entry['description']) > 100 else f"   Description: {entry['description']}")
    print(f"   Keywords: {', '.join(entry['keywords'][:5])}" if entry['keywords'] else "   Keywords: (none)")
    if entry['maintainers']:
        print(f"   Maintainers: {', '.join(entry['maintainers'][:3])}")
    if entry['github_users']:
        print(f"   GitHub users: {', '.join([u.get('login','') for u in entry['github_users'][:3]])}")

json.dump({"brief": brief, "data_quality_flags": data_quality_flags}, open("/tmp/npl-brief.json", "w"), indent=2)
print(f"\nBrief saved to /tmp/npl-brief.json with {len(brief)} entries.")
PYEOF

ステップ7: アウトリーチメッセージを生成(任意)

各リードに対してパーソナライズされたアウトリーチメッセージを生成します。

python3 << 'PYEOF'
import json

brief = json.load(open("/tmp/npl-brief.json"))
product_context = json.load(open("/tmp/npl-input.json")).get("product_context", "")

print(f"\n{'='*60}")
print(f"OUTREACH MESSAGES")
print(f"{'='*60}")

for entry in brief["brief"][:5]:  # トップ5
    pkg = entry["package"]
    growth_pct = entry["growth_pct"]
    current_weekly = entry["current_weekly"]
    description = entry["description"]
    maintainers = entry["maintainers"]
    github_users = entry["github_users"]
    
    # メッセージテンプレート
    print(f"\n--- {pkg} ---")
    print(f"Subject: Exciting growth with {pkg}")
    print(f"")
    print(f"Hi {' or '.join([u.get('name','') or u.get('login','') for u in github_users[:2]]) if github_users else (maintainers[0] if maintainers else 'there')},")
    print(f"")
    print(f"I've been following the momentum behind {pkg} — {growth_pct:+.0f}% growth in downloads per week is remarkable.")
    if description:
        print(f"The fact that it {description[:120].lower()}... really aligns with what we're building at {product_context or 'our company'}.")
    print(f"")
    if product_context:
        print(f"At {product_context}, we're [specific connection to the package or its problem space]. I'd love to explore how we might collaborate.")
    else:
        print(f"I'd love to explore how we might collaborate or support the continued growth of {pkg}.")
    print(f"")
    print(f"Would you be open to a 15-min chat next week?")
    print(f"")
    print(f"Best,")
    print(f"[Your Name]")

print(f"\n{'='*60}")
print(f"Note: Replace [Your Name] and [specific connection] with your details.")
print(f"{'='*60}")
PYEOF

ステップ8: 最終出力の提示

最終的な出力は以下を含める必要があります:

  1. 実行の概要(分析したパッケージ数、ブレイクアウト、ウォッチング)
  2. データ品質フラグ(もしあれば)
  3. ランク付けされたリードブリーフの表(各リードのスコア、成長率、メンテナー情報を含む)
  4. オプションのアウトリーチメッセージ(または参照先)

トラブルシューティング

問題解決策
スコープ付きパッケージから404が返る@ を %40 に、/ を %2F にエンコードする
GitHubレート制限の問題GITHUB_TOKEN 環境変数を設定する(スコープ不要)
すべてのパッケージが「時期尚早」になるより多くのダウンロード数があるパッケージを試す(週500+)
出力に予想より少ないパッケージが含まれるレート制限により一部のGitHubエンリッチメントがスキップされた可能性があります。data_quality_flags を確認

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

Varnan-Tech/opendirectory

Use when the user asks to generate a blog cover image, thumbnail, or article header. Automatically uses modern typography, brand logos, and Google Search grounding to create beautiful 16:9 images with Gemini 3.1 Flash Image Preview.

Varnan-Tech/opendirectory

World-class brand strategist and naming expert. Uses an interrogation-led discovery phase to extract your brand's DNA, then applies scientific naming frameworks (Phonosemantics) and automated multi-TLD domain checking.

Varnan-Tech/opendirectory

Use when the user asks to generate or update a project's CLAUDE or AGENTS context file from a codebase scan. Writes a focused file under 100 lines containing only the non-obvious build commands, conventions, and gotchas Claude Code needs.

Varnan-Tech/opendirectory

Use when the user wants to verify cold emails, enrich a lead list, or autonomously guess email addresses from a CSV using ValidEmail.co or the open-source Reacher engine.

Varnan-Tech/opendirectory

Competitive intelligence orchestrator tracking companies across 8+ platforms (GitHub, Twitter, Reddit, HN, PH, YC Jobs) with heat scores and AI briefings.

Varnan-Tech/opendirectory

Give it your product URL or description. It finds your top 5 competitors, runs three-track PR research across all of them (editorial, podcasts, communities), identifies which channels appear most frequently, looks up the journalist or host for each, and returns a tiered outreach list with story angles and ready-to-send cold pitch drafts tailored to your product. Use when asked to find PR opportunities, discover where competitors got featured, build a media outreach list, find which journalists cover my space, or get pitch templates for press coverage.

Varnan-Tech/opendirectory

Generate high-converting, deep-dive growth case studies in MDX format. Use this skill when asked to write a case study or blog post about a company's growth, tech stack, or product-led strategy. It handles the full pipeline (researching the company via Tavily, generating a 16:9 cover image, quality checking the draft, uploading assets to cloud storage, and pushing directly to the target repository).

Varnan-Tech/opendirectory

Scans your project for outdated npm, pip, Cargo, Go, or Ruby packages. Runs a CVE security audit. Fetches changelogs, summarizes breaking changes with Gemini, and opens one PR per risk group (patch, minor, major). Includes Diagnosis Mode for install conflicts. Use when asked to update dependencies, check for outdated packages, open dependency PRs, scan for package updates, audit for CVEs, or flag breaking changes in upgrades. Trigger when a user says "check for outdated packages", "update my dependencies", "open PRs for dependency updates", "scan for CVEs", or "which packages need upgrading".

Varnan-Tech/opendirectory

Generates and updates README.md and API reference docs by reading your codebase's functions, routes, types, schemas, and architecture. Uses graphify to build a knowledge graph first, then writes accurate docs from it. Use when asked to write docs, generate a README, document an API, update stale docs, create an API reference from code, add an architecture section, or document a project in any language. Trigger when a user says their docs are missing, outdated, or wants to document their codebase without writing it manually.

Varnan-Tech/opendirectory

Evaluates expired domain candidates against a target niche, scores them by topical relevance, historical activity level, and history cleanliness, then outputs a ranked shortlist with explainable reasoning and risk flags.

Varnan-Tech/opendirectory

Brutally honest developer-experience audit for a GitHub repo. Scores 10 DX dimensions (time-to-first-success, README clarity, visual proof, install, quick-start, docs, examples, community, trust, marketing), writes a shareable roast in the requested tone (brutal/honest/kind), produces a prioritized action plan ranked by impact × effort, and sketches an ideal README. Trigger when user says "roast my repo", "audit my README", "dx audit", "developer experience review", "score my GitHub project", "before launch checklist", or "make my repo shareable".

Varnan-Tech/opendirectory

Drafts and designs a complete HTML email newsletter from a topic or content brief. Outputs paste-ready HTML for Loops, Mailchimp, Beehiiv, Resend, or any standard email platform. Includes subject line options and plain-text fallback. Trigger when a user says "write a newsletter", "draft an email newsletter", "create an HTML email", "design an email for my subscribers", or "write a newsletter about [topic]".

Varnan-Tech/opendirectory

Takes a GitHub PR URL or the current branch and writes a plain-English explanation of what it does and why, then posts it as a PR comment. Use when asked to explain a PR, summarize a pull request, write a plain-English description of a PR, add a summary comment to a PR, or understand what a PR changes. Trigger when a user says "explain this PR", "summarize this pull request", "what does this PR do", "add a comment explaining the PR", or shares a GitHub PR URL and asks what it does.

Varnan-Tech/opendirectory

Audit how often LLMs recommend your brand vs competitors and generate a GEO action plan.

Varnan-Tech/opendirectory

Takes a competitor's public GitHub repo URL, fetches their open issues via the GitHub REST API, filters noise locally, clusters issues into 6 demand categories, computes a demand score per issue and per cluster, and outputs a ranked demand gap report with a GTM messaging brief. Use when asked to scan a competitor's GitHub issues, find what their users are begging for, turn GitHub complaints into product positioning, identify competitor feature gaps, or generate messaging from real user demand. Trigger when a user says "scan competitor issues", "what are users asking for on X repo", "find demand gaps in Y", "turn GitHub issues into messaging", or "what should I build based on competitor complaints".

Varnan-Tech/opendirectory

Find recurring confusion in your repo's GitHub Discussions, rank it by urgency, and draft the actual docs fixes and content angles — with verbatim community quotes and source links as evidence.

Varnan-Tech/opendirectory

SEO keyword research workflow for blog generation using Google Trends data. Use when writing blog posts, planning content calendars, or optimizing articles for search engines. Finds breakout keywords, builds content structure, and generates SEO-optimized blog outlines targeting tech and developer audiences.

Varnan-Tech/opendirectory

Generates a professionally designed case study PDF for B2B SaaS sales and marketing. Supports 7 page layouts, 9 style presets, 1-4 page output. Trigger when user says "create a case study", "write a customer story", "make a case study PDF", "design a success story", "turn this customer win into a PDF".

Varnan-Tech/opendirectory

Generates data visualization charts (bar, line, area, pie, doughnut, scatter, radar, treemap) as PNG using Apache ECharts v6. 1080×1080px default, 5 style presets, highlight annotations. Trigger when user says "create a chart", "visualize data", "make a bar chart", "line graph", "pie chart", "data visualization", "chart this data", "plot", "graph", or "visualize these numbers".

Varnan-Tech/opendirectory

Fetches low-star App Store and Google Play reviews, clusters them into broken-promise patterns, and generates a ranked copy brief with positioning opportunities.

関連スキル