Communitygithub.com

Rastreador de Adopción de SDK

Dado el nombre de tu SDK o librería, busca en GitHub repositorios públicos que lo importen o requieran, los clasifica por tipo (empresa, desarrollador afiliado, independiente o tutorial), los puntúa según la intensidad de la señal de adopción, detecta nuevos adoptantes por fecha y genera una lista clasificada de quién está construyendo sobre tu SDK con contexto de alcance para cada empresa con alta señal. Útil para encontrar quién usa tu SDK, rastrear su adopción, identificar empresas que construyen sobre tu librería, detectar leads calientes de usuarios existentes o ver qué organizaciones importan tu paquete.

¿Qué es Rastreador de Adopción de SDK?

Este skill automatiza el análisis de adopción de un SDK o librería en GitHub. Dado el nombre de un paquete (como `stripe`, `@clerk/nextjs` o `requests`), realiza una búsqueda en el código de GitHub para encontrar repositorios públicos que lo importen o requieran. Luego, clasifica cada repositorio en categorías como empresa (Organization), desarrollador afiliado (si el perfil del propietario tiene un campo `company`), desarrollador independiente o ruido (tutoriales, ejemplos, demos). A cada repositorio se le asigna una puntuación de adopción basada en la señal de empresa, actividad y ausencia de indicadores de ruido. Los repositorios de alta señal se enriquecen con metadatos del repositorio, información del perfil del propietario (campo `company`) y los principales contribuidores. El resultado final es un informe clasificado con contexto de alcance para cada adoptante empresarial, lo que permite identificar leads cálidos y rastrear la adopción del SDK a lo largo del tiempo. El skill es compatible con los ecosistemas npm, Python y Go, y utiliza la API de búsqueda de código de GitHub con un token de acceso personal.

Compatible con✓Claude Code~Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/Varnan-Tech/opendirectory/tree/main/skills/sdk-adoption-tracker

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

¿Qué hace Rastreador de Adopción de SDK?

Toma un nombre de SDK. Busca en GitHub repositorios públicos que lo importen. Puntúa cada repositorio por señal de empresa, actividad e indicadores de ruido. Enriquece los repositorios de alta señal con datos del propietario y contribuidores. Genera un informe de adopción clasificado con contexto de alcance para los adoptantes empresariales.


Regla crítica: Cada repositorio en la salida debe existir en la respuesta de la API de búsqueda de código de GitHub. Cada nombre de empresa debe provenir del campo company o name de la API de usuario u organización de GitHub. Cada nombre de contribuidor debe provenir de la respuesta de la API de contribuidores de GitHub. Si algún campo está vacío en la API, escribe "no listado" — no infieras, adivines ni extrapoles.


Errores Comunes

El agente querrá...Por qué está mal
Ejecutar la búsqueda de código sin GITHUB_TOKENLa búsqueda de código no autenticada tiene un límite de velocidad secundario de 3 solicitudes/minuto y falla en cualquier análisis significativo. GITHUB_TOKEN es obligatorio. Detente en el Paso 1 con un error claro si falta.
Incluir forks del propio SDKLos repositorios que bifurcan el SDK son contribuidores o espejos, no adoptantes. Filtra los repositorios donde fork == true Y el nombre del repositorio coincide con el nombre del SDK.
Enviar los 500 resultados de búsqueda sin procesar a la IALa búsqueda de código puede devolver hasta 500 resultados, la mayoría de los cuales son ruido. Filtra y puntúa localmente primero. Envía solo los 20 mejores repositorios de alta señal al paso de análisis de la IA.
Reportar repositorios de tutoriales y ejemplos como adoptantesLos repositorios con "example", "tutorial", "demo", "learn", "sample", "playground", "starter" en el nombre o descripción no son usuarios de producción. Márcalos como tutorial_noise y exclúyelos de los informes de leads.
Inventar nombres de empresas o contactosCada nombre de empresa debe provenir del campo company de GitHub o del campo name de la organización. Cada nombre de contribuidor debe provenir de la respuesta de la API de contribuidores. Si un campo está vacío, escribe "no listado".
Usar un único patrón de importación para todos los ecosistemasrequire('sdk') no encontrará usuarios de Python. Detecta automáticamente el ecosistema a partir del nombre del SDK y construye patrones específicos para cada ecosistema. Pregunta al usuario si la detección automática es ambigua.

Paso 1: Verificación de Configuración

if [ -z "$GITHUB_TOKEN" ]; then
  echo "ERROR: GITHUB_TOKEN es obligatorio para la búsqueda de código."
  echo "Agrega un token en github.com/settings/tokens (no se necesitan permisos para repositorios públicos)."
  echo "Sin él, la búsqueda de código de GitHub tiene un límite de velocidad secundario de 3 solicitudes/minuto y falla."
  exit 1
fi
echo "GITHUB_TOKEN: establecido"
curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \
     -H "Accept: application/vnd.github+json" \
     "https://api.github.com/rate_limit" | python3 -c "
import json, sys
d = json.load(sys.stdin)
search = d['resources']['search']
core = d['resources']['core']
print(f'Tasa de búsqueda: {search[\"remaining\"]}/{search[\"limit\"]} restantes')
print(f'Tasa principal:   {core[\"remaining\"]}/{core[\"limit\"]} restantes')
"

Si las solicitudes de búsqueda restantes son 0: detente. Indica al usuario la hora de reinicio desde X-RateLimit-Reset.


Paso 2: Recopilar Información

Recopila de la conversación:

  • Nombre del SDK (ej. @company/my-sdk, requests, github.com/org/go-sdk)
  • Opcional: anulación del ecosistema (npm, python, go, gem) — se detecta automáticamente si no se proporciona
  • Opcional: organización/usuario a excluir de los resultados (los repositorios propios del propietario del SDK)
  • Opcional: cadena de contexto del producto (se usa para personalizar mensajes de alcance)

Detectar ecosistema automáticamente:

  • Empieza con @ o contiene -: npm
  • snake_case sin / ni -: python
  • Contiene github.com/: go
  • De lo contrario: pregunta al usuario

Si no se proporciona un nombre de SDK: Pregunta: "¿Qué SDK o librería te gustaría rastrear? Proporciona el nombre del paquete tal como aparece en las declaraciones de importación (ej. stripe, @clerk/nextjs, requests)."

python3 << 'PYEOF'
import json, sys, re

sdk_name = "SDK_NAME_HERE"
ecosystem_override = ""  # déjalo vacío para detección automática
exclude_owner = ""       # opcional: nombre del propietario a excluir (normalmente el publicador del SDK)
product_context = ""     # opcional: qué hace tu producto

# Detectar ecosistema automáticamente
if ecosystem_override:
    ecosystem = ecosystem_override
elif sdk_name.startswith("@") or "-" in sdk_name:
    ecosystem = "npm"
elif re.match(r'^[a-z][a-z0-9_]*$', sdk_name):
    ecosystem = "python"
elif "github.com/" in sdk_name:
    ecosystem = "go"
else:
    ecosystem = "generic"

print(f"SDK: {sdk_name}")
print(f"Ecosistema: {ecosystem}")
print(f"Excluir propietario: {exclude_owner or '(ninguno)'}")

with open("/tmp/sat-input.json", "w") as f:
    json.dump({
        "sdk_name": sdk_name,
        "ecosystem": ecosystem,
        "exclude_owner": exclude_owner,
        "product_context": product_context
    }, f)
PYEOF

Paso 3: Buscar en el Código de GitHub

Primero verifica si existe un script independiente — que maneja los Pasos 3-5 en una sola llamada.

ls scripts/fetch.py 2>/dev/null && echo "script disponible" || echo "script no encontrado"

Si el script está disponible, ejecútalo y salta al Paso 6:

python3 scripts/fetch.py "$(python3 -c "import json; d=json.load(open('/tmp/sat-input.json')); print(d['sdk_name'])")" \
  --ecosystem "$(python3 -c "import json; d=json.load(open('/tmp/sat-input.json')); print(d['ecosystem'])")" \
  --exclude "$(python3 -c "import json; d=json.load(open('/tmp/sat-input.json')); print(d.get('exclude_owner',''))")" \
  --output /tmp/sat-script-out.json

Luego carga los datos en el formato de archivo temporal que esperan los Pasos 6-8:

python3 << 'PYEOF'
import json

out = json.load(open("/tmp/sat-script-out.json"))
json.dump(out["raw_results"], open("/tmp/sat-raw-results.json", "w"), indent=2)
json.dump(out["scored"], open("/tmp/sat-scored.json", "w"), indent=2)
json.dump(out["enriched"], open("/tmp/sat-enriched.json", "w"), indent=2)
print(f"Cargados: {len(out['raw_results'])} sin procesar | {len(out['scored'])} puntuados | {len(out['enriched'])} enriquecidos")
PYEOF

Si el script no está disponible, ejecuta el código integrado a continuación.

Construye patrones de importación y busca en el código de GitHub cada uno:

python3 << 'PYEOF'
import json, urllib.request, ssl, time, os
from datetime import datetime, timezone

ctx = ssl._create_unverified_context()
token = os.environ["GITHUB_TOKEN"]
headers = {
    "Accept": "application/vnd.github+json",
    "Authorization": f"Bearer {token}",
    "User-Agent": "sdk-adoption-tracker/1.0"
}

data = json.load(open("/tmp/sat-input.json"))
sdk_name = data["sdk_name"]
ecosystem = data["ecosystem"]

# Construir patrones de consulta por ecosistema
if ecosystem == "npm":
    # Usar el nombre del SDK sin el prefijo @ para búsquedas simples
    bare = sdk_name.lstrip("@").replace("/", "/")
    queries = [
        f'require("{sdk_name}")',
        f"require('{sdk_name}')",
        f'from "{sdk_name}"',
        f"from '{sdk_name}'",
    ]
elif ecosystem == "python":
    queries = [
        f"import {sdk_name}",
        f"from {sdk_name} import",
        f"from {sdk_name}.",
    ]
elif ecosystem == "go":
    queries = [f'"{sdk_name}"']
else:
    queries = [sdk_name]

print(f"Construyendo consultas para {sdk_name} ({ecosystem}):")
for q in queries:
    print(f"  {q}")

seen_repos = {}  # full_name -> primera coincidencia
search_rate_remaining = 30
flags = []

for i, query in enumerate(queries):
    if search_rate_remaining <= 2:
        flags.append(f"Límite de velocidad de búsqueda bajo ({search_rate_remaining}) -- se saltaron los patrones restantes")
        print(f"  Límite de velocidad bajo ({search_rate_remaining}), deteniendo temprano")
        break

    url = f"https://api.github.com/search/code?q={urllib.parse.quote(query)}&per_page=100"
    req = urllib.request.Request(url, headers=headers)

    try:
        with urllib.request.urlopen(req, timeout=20, context=ctx) as resp:
            search_rate_remaining = int(resp.headers.get("X-RateLimit-Remaining", 10))
            raw = json.loads(resp.read())

        items = raw.get("items", [])
        total = raw.get("total_count", 0)
        print(f"  Patrón '{query}': {total} total, {len(items)} obtenidos | tasa_restante={search_rate_remaining}")

        for item in items:
            repo = item.get("repository", {})
            full_name = repo.get("full_name", "")
            if full_name and full_name not in seen_repos:
                seen_repos[full_name] = {
                    "full_name": full_name,
                    "name": repo.get("name", ""),
                    "owner_login": repo.get("owner", {}).get("login", ""),
                    "owner_type": repo.get("owner", {}).get("type", ""),
                    "file_path": item.get("path", ""),
                    "matched_pattern": query,
                    "html_url": repo.get("html_url", ""),
                    "description": repo.get("description") or "",
                }

    except urllib.error.HTTPError as e:
        if e.code == 403:
            flags.append(f"Límite de velocidad de búsqueda alcanzado en el patrón '{query}'")
            print(f"  Límite de velocidad alcanzado (403) en '{query}'")
            break
        else:
            print(f"  HTTP {e.code} en '{query}'")
    except Exception as e:
        print(f"  Error en '{query}': {e}")

    # Respetar el límite de 10 solicitudes/minuto de búsqueda
    if i < len(queries) - 1:
        time.sleep(6)

results = list(seen_repos.values())
json.dump(results, open("/tmp/sat-raw-results.json", "w"), indent=2)
print(f"\nTotal de repositorios únicos encontrados: {len(results)}")
if flags:
    print("Banderas:", flags)

import urllib.parse  # asegurar importación
PYEOF

Si 0 resultados: Indica al usuario: "No se encontraron repositorios que importen {sdk_name}. La indexación de búsqueda de código de GitHub toma de 1 a 4 semanas para paquetes nuevos. Si el SDK está establecido, verifica los patrones de importación en references/import-patterns.md."


Paso 4: Puntuar y Clasificar Repositorios

Sin llamada a la API. Python puro. Filtra ruido, calcula puntuación de adopción, clasifica cada repositorio.

python3 << 'PYEOF'
import json
from datetime import datetime, timezone

data = json.load(open("/tmp/sat-input.json"))
exclude_owner = data.get("exclude_owner", "").lower()
sdk_name = data["sdk_name"].lower().split("/")[-1].replace("@", "")

results = json.load(open("/tmp/sat-raw-results.json"))

TUTORIAL_WORDS = {"example", "tutorial", "demo", "learn", "sample", "starter",
                  "boilerplate", "template", "playground", "test", "course", "workshop"}

scored = []
now = datetime.now(tz=timezone.utc)

for repo in results:
    full_name = repo["full_name"]
    owner_login = repo.get("owner_login", "").lower()
    repo_name = repo.get("name", "").lower()
    description = (repo.get("description") or "").lower()
    owner_type = repo.get("owner_type", "User")

    # Excluir los repositorios propios del propietario del SDK
    if exclude_owner and owner_login == exclude_owner.lower():
        continue

    # Detectar ruido de tutorial
    name_words = set(repo_name.replace("-", " ").replace("_", " ").split())
    desc_words = set(description.split())
    is_tutorial = bool((name_words | desc_words) & TUTORIAL_WORDS)
    # También excluir si el nombre del repositorio ES el nombre del SDK (probablemente un fork)
    if repo_name == sdk_name or repo_name.startswith(sdk_name + "-"):
        is_tutorial = True  # tratar como ruido

    # Nivel de clasificación
    if is_tutorial:
        tier = "tutorial_noise"
    elif owner_type == "Organization":
        tier = "company_org"
    else:
        tier = "solo_dev"  # se actualizará a affiliated_dev en el Paso 5 si el campo company está poblado

    # Puntuación de adopción (rellenada con datos parciales ahora, enriquecida en el Paso 5)
    score = 0
    if owner_type == "Organization": score += 50
    if not is_tutorial:              score += 20
    # estrellas, días_desde_push, es_fork, es_archivado añadidos en el Paso 5

    scored.append({
        **repo,
        "tier": tier,
        "is_tutorial": is_tutorial,
        "adoption_score": score,
        "enriched": False
    })

# Ordenar: company_org primero, luego por nivel
tier_order = {"company_org": 0, "affiliated_dev": 1, "solo_dev": 2, "tutorial_noise": 3}
scored.sort(key=lambda x: (tier_order.get(x["tier"], 9), -x["adoption_score"]))

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

tiers = {}
for r in scored:
    tiers[r["tier"]] = tiers.get(r["tier"], 0) + 1

print(f"Clasificación:")
for tier, count in sorted(tiers.items(), key=lambda x: tier_order.get(x[0], 9)):
    print(f"  {tier}: {count}")
print(f"Total: {len(scored)} repositorios")

non_noise = [r for r in scored if r["tier"] != "tutorial_noise"]
print(f"\nPrincipales repositorios para enriquecer (sin ruido): {len(non_noise)}")
for r in non_noise[:5]:
    print(f"  {r['full_name']} ({r['tier']}) -- {r.get('description','')[:60]}")
PYEOF

Si todos los repositorios son tutorial_noise: Detente. Indica al usuario: "Todos los repositorios encontrados parecen ser tutoriales o ejemplos. No se detectaron adoptantes de producción en GitHub público. El SDK puede ser demasiado nuevo, o el nombre del paquete es lo suficientemente genérico como para que los resultados de búsqueda estén dominados por ejemplos."


Paso 5: Enriquecer Repositorios de Alta Señal

Obtiene metadatos completos del repositorio, perfil del propietario y principales contribuidores para repositorios sin ruido. Omite los repositorios tutorial_noise por completo.

python3 << 'PYEOF'
import json, urllib.request, ssl, os, time
from datetime import datetime, timezone

ctx = ssl._create_unverified_context()
token = os.environ["GITHUB_TOKEN"]
headers = {
    "Accept": "application/vnd.github+json",
    "Authorization": f"Bearer {token}",
    "User-Agent": "sdk-adoption-tracker/1.0"
}

scored = json.load(open("/tmp/sat-scored.json"))
core_remaining = 5000
flags = []

def gh_get(path):
    global core_remaining
    req = urllib.request.Request(f"https://api.github.com{path}", headers=headers)
    try:
        with urllib.request.urlopen(req, timeout=15, context=ctx) as resp:
            remaining = resp.headers.get("X-RateLimit-Remaining")
            if remaining:
                core_remaining = int(remaining)
            return json.loads(resp.read())
    except urllib.error.HTTPError as e:
        if e.code == 404:
            return None
        raise
    except Exception:
        return None

target = [r for r in scored if r["tier"] != "tutorial_noise"]
print(f"Enriqueciendo {len(target)} repositorios (saltando tutorial_noise)...")

enriched = []

for item in target:
    full_name = item["full_name"]
    owner_login = item["owner_login"]
    
    # Obtener metadatos del repositorio
    repo_data = gh_get(f"/repos/{full_name}")
    if repo_data:
        item["stars"] = repo_data.get("stargazers_count", 0)
        item["forks"] = repo_data.get("forks_count", 0)
        item["is_fork"] = repo_data.get("fork", False)
        item["is_archived"] = repo_data.get("archived", False)
        item["pushed_at"] = repo_data.get("pushed_at", "")
        # Actualizar puntuación de adopción
        score = item["adoption_score"]
        if item["stars"] > 0:
            score += min(30, item["stars"])
        if item["is_fork"]:
            score -= 50
        if item["is_archived"]:
            score -= 100
        item["adoption_score"] = max(0, score)
    else:
        item["stars"] = 0
        item["forks"] = 0
        item["is_fork"] = False
        item["is_archived"] = False
        item["pushed_at"] = ""

    # Obtener perfil del propietario
    owner_type = item.get("owner_type", "User")
    if owner_type == "Organization":
        org_data = gh_get(f"/orgs/{owner_login}")
        if org_data:
            item["company_name"] = org_data.get("name") or org_data.get("company") or "no listado"
            item["company_url"] = org_data.get("blog", "") or org_data.get("html_url", "")
        else:
            item["company_name"] = "no listado"
            item["company_url"] = ""
    else:
        user_data = gh_get(f"/users/{owner_login}")
        if user_data:
            item["company_name"] = user_data.get("company") or user_data.get("name") or "no listado"
            item["company_url"] = user_data.get("blog", "") or user_data.get("html_url", "")
            if user_data.get("company"):
                item["tier"] = "affiliated_dev"
        else:
            item["company_name"] = "no listado"
            item["company_url"] = ""

    # Obtener principales contribuidores
    contribs = gh_get(f"/repos/{full_name}/contributors?per_page=5")
    if contribs and isinstance(contribs, list):
        item["top_contributors"] = [c["login"] for c in contribs if c.get("login")]
        item["contributor_count"] = len(contribs)
    else:
        item["top_contributors"] = []
        item["contributor_count"] = 0

    item["enriched"] = True
    enriched.append(item)
    
    if core_remaining < 50:
        flags.append(f"Límite de tasa principal bajo ({core_remaining}) -- enriquecimiento detenido temprano")
        print(f"Límite de tasa principal bajo ({core_remaining}), deteniendo temprano")
        break
    
    time.sleep(0.5)

# Combinar repositorios enriquecidos y tutorial_noise
all_enriched = enriched + [r for r in scored if r["tier"] == "tutorial_noise"]

json.dump(all_enriched, open("/tmp/sat-enriched.json", "w"), indent=2)

print(f"\nRepositorios enriquecidos: {len(enriched)}")
print(f"Repositorios tutorial_noise sin cambios: {len([r for r in scored if r['tier'] == 'tutorial_noise'])}")
if flags:
    print("Banderas:", flags)

# Mostrar muestra de alta señal
enriched.sort(key=lambda x: -x["adoption_score"])
print("\nPrincipales repositorios enriquecidos por puntuación:")
for r in enriched[:5]:
    print(f"  {r['full_name']} | Puntuación: {r['adoption_score']} | Empresa: {r.get('company_name','')}")
PYEOF

Paso 6: Análisis de la IA

Proporciona los repositorios enriquecidos a la IA para su análisis. El agente debe:

  1. Leer los repositorios enriquecidos
  2. Identificar los 20 principales repositorios de alta señal (por puntuación de adopción, excluyendo tutorial_noise)
  3. De esos 20, seleccionar los X más prometedores para leads de ventas
  4. Para cada uno, determinar:
    • ¿Es un usuario de producción o un experimento?
    • ¿Qué función del SDK parece estar usando?
    • ¿Podría ser un cliente potencial? (si el producto llena un vacío o mejora su pila actual)
    • Contexto de alcance: ¿cómo contactar o qué valor ofrecer?
  5. Detectar nuevos adoptantes: repositorios creados o con la primera importación en los últimos 30 días

Consejo: Usa el contexto del producto si se proporcionó para personalizar los mensajes de alcance.


Paso 7: Generar Informe

Genera el informe final de adopción del SDK. Incluye:

  • Resumen ejecutivo (total de adoptantes, distribución por niveles, tendencias)
  • Tabla de los 10 principales adoptantes empresariales (compañía, repositorio, puntuación, contribuidores clave)
  • Nuevos adoptantes (últimos 30 días)
  • Notas de contexto de alcance para cada empresa de alta señal

Paso 8: Salida Final

Presenta el informe al usuario en un formato limpio y legible. Incluye:

  • Enlaces directos a cada repositorio
  • La puntuación de adopción
  • El nivel de clasificación
  • El contexto de alcance para leads empresariales
  • Bandera de nuevos adoptantes si corresponde

Referencia: Patrones de Importación por Ecosistema

EcosistemaPatrones
npmrequire('pkg'), import { ... } from 'pkg'
Pythonimport pkg, from pkg import ...
Goimport "host.com/user/repo"
Ruby Gemrequire 'gem_name'
Rust Crateuse crate_name;
PHP Composeruse Vendor\Package;
Java/Mavenimport com.example.package;
.NET/NuGetusing PackageName;

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.

Skills relacionados