Investigación en GitHub
Encuentra cada repositorio relevante y componente extraíble para el tema o pregunta del usuario: $ARGUMENTS (Claude Code lo completa; en otros agentes es la solicitud del usuario)
La búsqueda literal de palabras clave falla en temas especializados: los desarrolladores nombran los repositorios según la cosa que tocan (un sitio web, una API, una organización, una biblioteca), no según el concepto. Busca los artefactos que cualquier implementación debe contener, desde varias direcciones (código, repositorios, commits, issues, otros sitios, la web), verifica cada resultado y desglosa los candidatos en piezas reutilizables para combinarlas en nuestra solución objetivo.
La familia rotless
Parte de rotless, y completamente usable por sí sola. Cuando la investigación es un antecedente para una habilidad, quien llama nombra un archivo y su forma (prior-art.md, definido por rotless-skill-modernizer): escribe el informe allí con esa forma. Quienes llaman: rotless-skill-creator (paso 0, antes de construir), rotless-skill-modernizer (fix para una herramienta reemplazada, refresh para todo el panorama) y rotless-skill-refiner (una lección de "mejor manera" se verifica contra lo que existe antes de adoptarla).
Caja de herramientas
Los ayudantes residen en la carpeta scripts/ de esta habilidad. Establece S en la ruta absoluta de esa carpeta una vez, desde el directorio base de esta habilidad (la carpeta que contiene este SKILL.md; Claude Code lo imprime como "Directorio base para esta habilidad: …" cuando la habilidad se carga), y siempre llama a los ayudantes a través de $S (el directorio de trabajo actual es el proyecto del usuario); -h lista las banderas; python3, o python en Windows. Los endpoints fuera de GitHub están en references/sources.md (misma carpeta). Prefiere un shell POSIX (bash; Git Bash en Windows) sobre PowerShell (comillas de -, !, jq). Los ejemplos de sarkari/UPSC son solo ilustrativos.
| Herramienta | Qué busca | Mejor para |
|---|---|---|
grepapp.py (= herramienta searchGitHub si grep MCP está instalado) | contenidos de archivos, ~1M repos populares, regex, sin autenticación | dominios hardcodeados, líneas de importación, claves de configuración |
gh api -X GET search/code -f q='…' | contenidos de archivos, índice legacy de GitHub (más repos, sin regex) | segunda fuente de código; firmas path:/filename: |
ghsweep.py | nombre/descripción/readme/topics del repo, muchas consultas, deduplicado | amplitud; conteos totales, topics comunes, etiquetas [noise?] |
gh search commits … | mensajes de commit | repos cuyo nombre/README no dicen nada |
gh search issues … --include-prs | texto de issues/PR | repos + puntos débiles del mundo real (necesita frases específicas; palabras genéricas se ahogan en issues de bots) |
ghverify.py | lote GraphQL, 25 repos/llamada | existencia, renombres, actividad real, estado, evidencia, banderas de advertencia |
gh repo read-dir / read-file, gh api …/contents | archivos de un repo, sin clonar | confirmación de código real |
srcsweep.py | 21 fuentes no-GitHub en paralelo: npm, crates, Packagist, Hex, NuGet, Maven, RubyGems, Hackage, Docker Hub, ArtifactHub, AUR, Open VSX, GitLab, Codeberg, MCP Registry, skills.sh, Hugging Face (modelos/datasets/spaces/papers, con el repo de código al que enlaza un paper), Hacker News | antecedentes fuera de GitHub; termina con un registro de fuentes buscadas / no alcanzadas; --repos canaliza repos de GitHub a ghverify.py - |
references/sources.md | notas de endpoint + fuentes sin API de búsqueda (PyPI, Homebrew, pkg.go.dev, Product Hunt, Reddit) | seguimientos manuales |
Reglas de gh search que importan (probadas; ignorarlas devuelve silenciosamente [] o resultados incorrectos)
- Comillas:
gh search <kind> "two words"= frase exacta. Para Y pasa palabras sin comillas;Ofunciona sin comillas. - Para cualquier cosa no trivial usa la API cruda (sintaxis completa +
total_count):gh api -X GET search/{repositories|code|commits|issues} -f q='<query>' -f per_page=100 --cache 1h - Todas las palabras deben coincidir en la búsqueda de repos, así que mantén cada consulta de 2 a 3 palabras y varía la redacción en lugar de acumular términos en una consulta. Si un barrido devuelve < 5 repos, acorta las consultas.
- Exclusión: palabras con
NOT palabra; calificadores con-calificador:valor.-palabradevuelve 0. Engh searchpon las exclusiones después de--. - Búsqueda de código vía API = motor legacy: sin regex;
O/NO,path:,filename:,extension:,language:funcionan. Solo rama por defecto; omite archivos grandes. Usa grep.app para regex. - Límite de resultados 1000 por consulta. Divide conjuntos grandes:
created:A..B,pushed:>FECHA, bandas de estrellasstars:0..24,stars:25..99,stars:100..499(también saca gemas de baja visibilidad),language:. - Límites de tasa: búsqueda 30/min; búsqueda de código 10/min (
gh skill searchlo comparte); GraphQL 5000 pts/hora. Verifica:gh api rate_limit --jq '.resources | {search: .search.remaining, code: .code_search.remaining, graphql: .graphql.remaining}'. Usa--cache 1hen llamadas repetidas; cuando la búsqueda de código se agote, cambia de vector en lugar de dormir. - Privacidad: la búsqueda autenticada devuelve repos privados que la cuenta puede ver. Nunca los reportes: añade
select(.repository.private == false)(código) /select(.private == false)(repos) a jq;ghsweep.pylos filtra. Nunca pongas nombres privados/internos del usuario en las consultas de búsqueda. gh repo read-file/read-dir/gh discussion/gh skillnecesitan un gh reciente (probado 2.103). Si es más antiguo, usa los fallbacks degh apien el Paso 3 o sugierewinget upgrade GitHub.cli/brew upgrade gh.
Paso 0 — Resumen (un bloque corto, sin ida y vuelta a menos que sea genuinamente ambiguo)
Escribe: Objetivo · Desglose de la solución objetivo (subproblemas modulares: ej. autenticación/sesión, scraper/parser, normalización/esquema, almacenamiento, API/interfaz — para identificar qué se puede aprovechar de dónde) · Imprescindibles · Deseables · Anti-patrones (ej. envoltorio fino, abandonado, necesita API de pago, solo GPU) · Restricciones (lenguaje, offline…: estas son comprobaciones de aprobado/suspenso, no términos de búsqueda) · Fecha de corte como fecha absoluta ("reciente" → pushed:>2025-10-24) · Esfuerzo: pase rápido (elección barata y reversible: ~10 consultas, top 5) o método completo (predeterminado para antecedentes / construir-vs-comprar / combinar).
Si la solicitud es "alternativa a X / como X / clon de X", resuelve X a su repositorio primero y siembra desde él (sus topics, README, dependientes).
Verifica localmente primero (gratis, 10 segundos): lo que ya está instalado puede responderla: las carpetas de habilidades que carga tu agente (nivel de proyecto y de usuario: .agents/skills/, .claude/skills/, ~/.codex/skills/…), su lista de servidores MCP (ej. claude mcp list), gh extension list. Reporta un acierto antes de buscar en el mundo.
Paso 1 — Identificar el tema
Escribe de 15 a 30 términos de búsqueda concretos:
- Puntos de contacto — dominios, URLs, endpoints de API, nombres de host, rutas RSS, IDs de aplicación que cualquier implementación debe alcanzar.
- Firmas de código — líneas de importación, nombres de clases/funciones de SDK, variables de entorno, claves de configuración, selectores CSS, constantes distintivas.
- Vocabulario desde varios puntos de vista — constructor, usuario final, académico, infraestructura, y la disciplina vecina que probablemente lo resolvió primero; términos regionales/no ingleses, abreviaturas, errores ortográficos. Las palabras ambiguas necesitan un término acompañante (
agent+llm, noagentsolo). - Formas — bot, scraper, API, CLI, librería, extensión, servidor MCP, habilidad de agente, conjunto de datos, modelo, Acción de GitHub; y sus firmas de archivo (
.github/workflowscron,manifest.json,SKILL.md,.claude-plugin/marketplace.json). Las habilidades de agente y plugins a menudo viven dentro de repos más grandes (unskills/x/SKILL.mden un monorepo de 80k★), invisibles para la búsqueda de repos: encuéntralos con búsqueda de códigofilename:SKILL.md "<frase de su descripción>"(ruidoso: cientos a miles de resultados, así que usa 2 frases distintivas y escanea 2–3 páginas) y skills.sh (srcsweep.py --sources skills; semántico, funciona mejor con el nombre de la habilidad que con su propósito). La recuperación de habilidades es el vector más débil: si una habilidad ancla nunca aparece, busca su nombre directamente y dilo en la nota de cobertura. - Anclas — los 3 a 10 proyectos/productos conocidos que esperarías que cualquier buena respuesta incluya. Se usan en el Paso 2 como verificación de recuperación.
- Párrafo de README ideal — dos oraciones que describan el repositorio perfecto, escritas como lo haría su autor; extráele términos de búsqueda.
Paso 2 — Buscar en cada vector
Ejecuta vectores en paralelo. Registra qué consultas encontraron cada repo (found_by: más consultas = mayor relevancia).
A. Búsqueda de código (la señal más alta). Muchas consultas estrechas, una por punto de contacto/firma:
S="<directorio base de esta habilidad>/scripts" # ej. S="$HOME/.agents/skills/rotless-github-research/scripts" (o ~/.claude/skills/… en Claude Code)
python "$S/grepapp.py" "sarkariresult.com" --repos-only
python "$S/grepapp.py" "(sarkariresult|freejobalert)\.com" --regex --lang Python --lang JavaScript --repos-only
python "$S/grepapp.py" "upsc.gov.in" --path .github/workflows/ --repos-only # bots programados
gh api -X GET search/code -f q='sarkariresult OR freejobalert language:python' -f per_page=100 \
--jq '"total \(.total_count)", (.items[] | select(.repository.private == false) | "\(.repository.full_name)\t\(.path)")'
grep.app devuelve ~10 archivos/consulta y da 504 en regex amplios: ancla en un literal raro, añade --lang/--path. Elimina ruido: conjuntos de datos de URLs rastreadas, listas de bloqueo de anuncios, monorepos donde el término aparece una vez.
B. Búsqueda de repos (amplitud + tamaño del panorama).
python "$S/ghsweep.py" --pushed ">2024-01-01" --order hits "sarkari OR naukri NOT resume" "freejobalert" "topic:government-jobs"
python "$S/ghsweep.py" --sort stars "topic:sarkari-result" # principales cuyas descripciones omiten palabras genéricas
python "$S/ghsweep.py" --sort updated "sarkari scraper" # trabajo fresco enterrado por mejor coincidencia
python "$S/ghsweep.py" --must "scrap|crawl|alert|job" --exclude "resume|linkedin" "sarkari OR naukri" # filtro de relevancia; los homónimos ("prior art" = patentes) inundan los resultados
gh api -X GET search/topics -f q=sarkari --jq '.items[].name' # descubre slugs de topics
ghsweep.py imprime conteos totales (qué tan concurrido está el espacio), los topics más comunes (→ próximas consultas; también prueba pares de topics compartidos por ≥2 de los mejores resultados: topic:a topic:b), y etiquetas [noise?] (tutorial/template/demo/dotfiles/awesome: degrada, no elimines automáticamente). Elimina --pushed para antecedentes independientemente de la antigüedad.
C. Búsqueda de commits: gh search commits sarkariresult --limit 50 --json repository,commit --jq '.[] | "\(.repository.fullName)\t\(.commit.message | split("\n")[0])"'
D. Búsqueda de issues/PR: gh search issues "freejobalert" --include-prs --limit 50 --json repository,title,url (solo frases específicas).
E. Bola de nieve desde los mejores resultados (top 3–5):
- Sigue la dependencia envuelta: si un resultado "envuelve", "está construido sobre" o "usa" X, investiga X también: a menudo es el verdadero titular. El lugar más común para detenerse demasiado pronto.
- Listas awesome:
python "$S/ghsweep.py" --sort stars "awesome <kw> in:name"; toma listasawesome-*con ≥200★, extrae sus enlaces de repos (gh repo read-file README.md --repo o/awesome-x | grep -oE 'github\.com/[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+' | sort -u) y canalízalos aghverify.py -. Estar listado es una señal de calidad suave. - Repos similares: topics + idioma de un resultado top →
topic:a topic:b language:x, prefiere un nivel de estrellas similar. - Secciones de README "Alternativas / Similar / Inspirado por / Créditos"; cadenas de código distintivas → grep.app (encuentra copias y ports); otros repos del autor (
gh repo list <owner> --limit 100); forks con trabajo propio (gh api "repos/o/r/forks?per_page=100" --jq '.[] | select(.pushed_at > .created_at) | .full_name'); página de dependientes de la librería a través de tu herramienta de fetch web ocurl(github.com/o/r/network/dependents).
F. Fuera de GitHub: un comando, varias redacciones (1–3 palabras cada una; registros Y los términos):
python "$S/srcsweep.py" "repository discovery" --limit 4 # 21 fuentes, ~10s, termina con un registro de buscado / NO ALCANZADO
python "$S/srcsweep.py" "sarkari" --repos | python "$S/ghverify.py" - # Repos de GitHub enlazados desde los resultados, verificados
Luego usa búsqueda web para lo que no tiene API de búsqueda (PyPI site:pypi.org, Homebrew, pkg.go.dev, Product Hunt, Reddit, blogs, awesome <topic>). Para investigación de antecedentes/competencia también enumera productos comerciales notables. Los resultados que no son de GitHub (GitLab, Codeberg, solo registro) no pueden pasar por ghverify.py: revísalos manualmente y marca la evidencia como Documentada/Metadatos.
Parada y recuperación. Detente cuando las nuevas consultas devuelvan principalmente repos conocidos, pero tres consultas que devuelvan el mismo repo es un mínimo local, no cobertura. Verifica las anclas del Paso 1: cualquier ancla no descubierta por tus búsquedas significa una brecha de vocabulario: descubre qué palabras usa y búscalas. Cero resultados significa "esta ruta no puede verlo", no "no existe": reformula o cambia de ruta una vez antes de concluir.
Paso 3 — Verificar y evaluar
Cada candidato pasa por ghverify.py (los nombres inventados aparecen como NO ENCONTRADO; los renombrados muestran el nombre actual):
python "$S/ghverify.py" owner/repo https://github.com/o2/r2 ... # o: ... | python "$S/ghverify.py" -
Lee sus columnas: último commit sustancial (ignora bump/chore/deps/merge/typo/docs) no pushedAt; % de resolución de issues; PRs fusionados; personas; org/usuario; lanzamientos/año; evidencia (tests, ci, manifest, security.md; NINGUNA = solo README, verifica duro); banderas !velocity (>100★/día: viral o comprado, necesita contexto), !lowfork (≥1000★, forks/stars < 0.005), new (<14 días), stale Ny (sin commit sustancial por 2+ años: marcado, nunca degradado: una herramienta abandonada aún prueba que la idea se construyó), noise?.
Luego confirma el código real para cada repo que reportarás (los README mienten en ambos sentidos). Fija la evidencia a un commit:
sha=$(gh api repos/o/r/commits/HEAD --jq .sha)
gh repo read-dir src --repo o/r --ref $sha # JSON: --json name,type --jq '.entries[]'
gh repo read-file path/to/main.py --repo o/r --ref $sha # fallback: gh api "repos/o/r/contents/PATH?ref=$sha" -H "Accept: application/vnd.github.raw"
gh api "repos/o/r/git/trees/$sha?recursive=1" --jq '"\(.tree|length) files", (.tree[:80][] | .path)'
Cita enlaces permanentes https://github.com/o/r/blob/<sha>/<path>#L10-L40, no enlaces de rama.
- Ajuste y Extraíble: fuerte / parcial / débil / fuera_de_objetivo, listando