Communitygithub.com

ethanplusai/astro-conversion-kit

Rastrea un sitio web en vivo, de solo lectura y con ritmo pausado, guardando todo en una carpeta capture/ que se verifica en una reconstrucción: HTML, texto, etiquetas head, redirecciones, enlaces, scripts de terceros, medios, estilos, fuentes, logotipo, iconos, feeds, plantillas y capturas de pantalla en vivo en tres anchos. Úsalo antes de convertir o reconstruir un sitio, cuando te pidan rastrear, capturar, inventariar un sitio, o cuando una captura se detuvo por bloqueos y necesita reanudarse.

¿Qué es astro-conversion-kit?

El kit de conversión Astro es una herramienta profesional para desarrolladores y agentes de IA (como Claude Code, Cursor o Codex) que automatiza la captura completa y respetuosa de sitios web activos. Su objetivo principal es crear una instantánea de solo lectura de un sitio en producción, guardando todo el contenido, estructura y metadatos en una carpeta `capture/` local, para que todas las etapas posteriores (como la conversión a un nuevo framework) trabajen sobre datos locales consistentes y verificables, sin depender del sitio en vivo. Esta habilidad destaca por su diseño ético y robusto: realiza solicitudes HTTP (GET y HEAD) con ritmo controlado (por defecto, 400 ms entre solicitudes, hasta 4 concurrentes), respetando los límites del servidor y ajustándose automáticamente a bloqueos (429, 503) o respuestas lentas. No envía formularios, no inicia sesión ni modifica el sitio original. Incluye pasos especializados como la captura de medios (imágenes, vídeos), plantillas (agrupando páginas por similitud de marcado), metadatos (CSS, fuentes, scripts, logo, favicon) y capturas de pantalla en vivo en tres resoluciones (390, 768, 1440) mediante Chromium headless. Es compatible con los principales sistemas de gestión de contenidos (CMS): detecta automáticamente la plataforma (WordPress, etc.) y utiliza sus API REST, sitemaps y listas de medios para una cobertura exhaustiva. También permite excluir rutas específicas, reanudar capturas interrumpidas, verificar redirecciones históricas (Wayback Machine) y generar informes detallados. Es la herramienta ideal para migraciones, rediseños, auditorías de acceso o cualquier escenario donde se necesite un inventario local completo y fiable de un sitio web, sin riesgo de sobrecargar el servidor original. En resumen, Astro Conversion Kit es un asistente de IA profesional que simplifica el proceso complejo de capturar un sitio web vivo para su posterior conversión o análisis, garantizando la integridad de los datos, la eficiencia en la extracción y el respeto por los recursos del servidor de origen.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ethanplusai/astro-conversion-kit/tree/HEAD/skills/capture-site

Preguntar en tu IA favorita

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

Documentación

capture-site

Guarda todo lo que sirve el sitio en vivo, una vez, para que cada paso posterior funcione a partir de la captura.

La regla de oro

El sitio en vivo es de solo lectura, y la captura es de solo lectura después. Los scripts solo realizan solicitudes GET y HEAD con ritmo pausado; nunca envían un formulario, inician sesión ni obtienen manualmente algo para llenar un vacío. Una vez escritas las notas, nada bajo capture/ se edita: es la evidencia que lee cada puerta.

Cuándo usarlo

Paso 2 de una conversión (convert-site lo ejecuta), o en cualquier momento en que se deba inventariar un sitio en vivo (un sitio de staging o nuevo es trabajo de launch-audit). Una captura que salió con código 3 se reanuda, como se indica a continuación.

Ritmo

Cada script envía un agente de usuario de Chrome de escritorio. Los scripts de captura (capture, media, assets, fingerprint) comparten un limitador por host: por defecto, los inicios de solicitud están separados por 400 ms con hasta 4 en vuelo (media: 6), por lo que un host que responde rápidamente se lee en minutos. Los pasos de Chromium (shoot, css-coverage, styles) cargan una página a la vez, con 500 ms de separación, y launch-audit y pre-launch mantienen su propio ritmo. El limitador se adapta automáticamente:

  • un 429 o 503 duplica el retraso de ese host (hasta 32 veces) y lo reduce a una solicitud a la vez; después de cada 30 s de respuestas limpias, recupera un paso (mitad del retraso, una más en vuelo) hasta volver a los valores predeterminados;
  • una respuesta que tarda más de 5 s reduce a la mitad las solicitudes en vuelo en ese host (sin repetir mientras esté reducido a la mitad), y se recupera de la misma manera, una más en vuelo por cada 30 s de respuestas limpias;
  • un 403 o un error de red cuenta para la parada de 3 seguidos a continuación, como antes.

--polite es el ritmo anterior: una solicitud a la vez, con 2500 ms de separación (capture, media, assets). Úsalo desde el principio en un hosting compartido con un muro antirrobots (el /.well-known/sgcaptcha/ de SiteGround, hosts que responden 429 o 503 a unas pocas solicitudes rápidas), o cuando una ejecución se detuvo por bloqueos: reanuda con --polite. --delay <ms> y --concurrency <n> anulan los valores predeterminados o --polite. Mantén los valores predeterminados o --polite contra un sitio en vivo (--delay 0 es solo para datos locales de prueba), y nunca cambies --ua para evitar un bloqueo.

  • capture obtiene hasta --concurrency URLs en cola por adelantado y las registra en el orden de la cola, por lo que la captura es igual que un rastreo de uno en uno. Intenta cada URL 3 veces. Una URL aún bloqueada después de eso (403, 429, 503 o un error de red) se registra con su estado y attempts en inventory.json (un sitemap o lista REST en meta.json discoveryErrors) y el rastreo continúa. Se detiene solo después de que 3 URLs diferentes seguidas hayan agotado sus intentos sin éxito entre ellas, estado guardado, esas tres puestas en cola nuevamente con nuevos intentos. Nunca solicita wp-admin, wp-login, xmlrpc.php o búsquedas ?s=.
  • media intenta cada archivo 3 veces: un 429 o 503 persistente lo detiene de inmediato; un 403 o error de red se registra como el estado de ese archivo, y 3 archivos de este tipo seguidos (en el orden en que llegan las respuestas) lo detienen. Los archivos que se están descargando cuando se detiene se dejan terminar. Guarda media.json cada 100 archivos, por lo que una ejecución que se interrumpe se reanuda cerca de donde estaba.
  • fingerprint no reintenta: una página de inicio bloqueada, o una que es un desafío antirrobots, es salida 3. assets y shoot retroceden y se detienen después de 3 respuestas bloqueadas seguidas.

La secuencia de comandos

Ejecutar desde la carpeta que contendrá capture/ (la raíz del repositorio del sitio). <skill-dir> es la ruta absoluta de la carpeta de esta habilidad, en una copia del kit donde se ha ejecutado npm install (los scripts importan sus paquetes). Cada script imprime --help; ejecútalo en lugar de leer el código fuente. Ejecuta cada paso como su propio comando, en este orden:

  1. Fingerprint (huella digital), luego lee la referencia de la plataforma para lo que nombra (tabla a continuación):

    node <skill-dir>/scripts/fingerprint.mjs https://www.example.com
    
  2. Captura. El descubrimiento son los sitemaps (cada línea Sitemap: en robots.txt, más el índice predeterminado de la plataforma), las listas REST (WordPress, cuando la huella encuentra REST; --no-rest omite), el rastreo de enlaces, y --seed <path> o --seed-file <file> (una ruta o URL por línea, comentarios #) para rutas que el rastreo no puede alcanzar (URL antiguas, un .htaccess antiguo). Después del rastreo, las rutas de Wayback que no encontró van a wayback-unverified.txt (--no-wayback omite; un listado que falla se solicita una vez más 10 s después antes de que meta.json wayback registre failed). Los enlaces cortos ?p= se registran sin verificar y nunca se obtienen a menos que pases --verify-shortlinks. Después del rastreo, solicita una ruta que no puede existir (/<32 hex>/) una vez, por lo que la página 404 del sitio se guarda como pages/404.html (meta.json notFound; un sitio que responde 200 o redirige allí se registra sin página), y solicita /favicon.ico y /apple-touch-icon.png una vez cada uno, siguiendo redirecciones (meta.json icons: ruta a { status, file, contentType, bytes }); uno que responde 200 se guarda byte por byte como assets/root-favicon.ico o assets/root-apple-touch-icon.png (una respuesta HTML no se guarda y tiene un note; uno de más de 5 MB es estado "too-large"), y assets.mjs lo enumera en assets/index.json como tipo "root-icon" con su path, por lo que la compilación lo envía allí. Las URLs se codifican con escapes de porcentaje en mayúsculas (%c3%a9 y %C3%A9 son una URL), por lo que una página enlazada con ambas ortografías se captura una vez. Un sitemap que robots.txt nombra y que responde 404 (o cualquier no 200) se enumera en sitemaps/index.json con su estado y en meta.json discoveryErrors. Un sitemap en otro host (robots.txt que nombra uno de un sitio hermano, o un índice que enumera uno; www y dominio raíz cuentan como un host) se enumera allí como { url, host, skipped: "other host" } y nunca se obtiene, por lo que ninguna de sus URLs ingresa al rastreo. Dos URLs de sitemap con el mismo nombre de archivo nunca se sobrescriben entre sí: el segundo se guarda con un sufijo de su ruta de directorio (page-sitemap-es.xml). --exclude <prefix>[,<prefix>...] deja partes del host fuera (los subsitios de un WordPress multisitio como /president/, o una sección que el propietario mantiene): una URL cuya ruta comienza con uno nunca se solicita, ya sea que un sitemap, las listas REST, un enlace o una redirección conduzcan allí. Un sitemap bajo uno se enumera en sitemaps/index.json como { url, skipped: "excluded" }; una redirección hacia uno se registra con ese destino, sin solicitar; los enlaces a uno permanecen en el HTML guardado y se enumeran en links.json excluded, no internal; meta.json excluded nombra los prefijos y la línea base los incluye. Los prefijos y rutas se comparan en una forma, por lo que /présidence/, /pr%c3%a9sidence/ y /pr%C3%A9sidence/ son el mismo prefijo. Una hoja de estilo o icono raíz que redirige bajo uno no se sigue allí (la hoja se enumera con estado "excluded"). --resume los mantiene; un prefijo agregado en --resume elimina lo que ya se capturó bajo él (sus páginas con sus archivos pages/ y text/, redirecciones de él, feeds y sitemaps bajo él, y hojas de estilo y scripts que solo esas páginas usaron) e imprime lo que eliminó. media.mjs y assets.mjs también omiten archivos bajo ellos.

    node <skill-dir>/scripts/capture.mjs https://www.example.com --out capture
    

    Luego, la segunda pasada de Wayback, cuando wayback-unverified.txt no está vacío: solicita cada ruta archivada una vez, por lo que las que aún redirigen terminan en capture/redirects.json con fuente seed (las redirecciones de la línea base las recogen) y el resto se registra con su estado en inventory.json. --seed, --seed-file y --include-query se aplican todos en --resume, y no se vuelve a preguntar a Wayback Machine:

    node <skill-dir>/scripts/capture.mjs https://www.example.com --out capture --resume --seed-file capture/wayback-unverified.txt
    
  3. Medios. Enumera cada archivo multimedia en capture/media.json y lo guarda en .conversion/media-cache/, el directorio de trabajo de la conversión, que permanece fuera de git:

    node <skill-dir>/scripts/media.mjs --capture capture --download .conversion/media-cache
    

    Descarga seis archivos a la vez. Por defecto (--sizes referenced) obtiene los originales y cada tamaño que usa el sitio: aquel al que apuntan una página, hoja de estilo, srcset, etiqueta og o sitemap, o cuyo nombre de archivo aparece en cualquier parte de las páginas, hojas de estilo o scripts capturados (data-thumb, data-bg, configuraciones JSON, scripts de slider). Un tamaño de WordPress que solo nombra la lista de medios REST se enumera con downloaded: false, reason: "unreferenced size" y no se solicita. Imprime el desglose, p. ej., 920 originals + referenced sizes (downloaded), 4,520 unreferenced sizes (listed only): repite esa línea a la persona. Usa --sizes all cuando el propietario dice que correos electrónicos antiguos u otros sitios pueden enlazar a esos tamaños.

    Los hosts que cambian el tamaño mediante una cadena de consulta (WordPress VIP, Jetpack Photon: photo.jpg?w=1024, ?resize=300,200) sirven todos los tamaños en la misma ruta. El original es la ruta desnuda, por lo que eso es lo que se solicita y guarda; cada cadena de consulta vista se enumera bajo variants (no solicitada; --sizes all los guarda como <path>%3F<query> bajo una carpeta hermana, .conversion/media-cache-variants/, por lo que la caché de medios que se carga o copia en el repositorio contiene solo rutas desnudas). Cuando la ruta desnuda responde con un error (4xx o 5xx; una redirección se registra con su ubicación, y un archivo demasiado grande se solicita nuevamente una vez que se aumenta el límite), se guarda una variante en su lugar y la entrada downloadedFrom es la URL de la que proviene. Una consulta de invalidación de caché (sin parámetro w, h, resize, crop, fit, quality, format o s, p. ej., ?ver=3) es el mismo archivo, por lo que se prefiere y no se marca nada más; de lo contrario, se guarda la variante más ancha y la entrada también dice resized: true. La ejecución imprime una línea por archivo y un recuento (2 originals unavailable (resized: true) ...), baseline/media.json mantiene ambos campos, y la puerta de medios repite el recuento como N resized (original unavailable on live) sin fallar, ya que compara con los bytes realmente guardados. Repite ese recuento a la persona y enumera esos archivos en el plan y el runbook como originales que el sitio en vivo ya no sirve.

  4. Plantillas. Agrupa las páginas que respondieron 200 en capture/templates.json. En WordPress, las páginas se agrupan primero por clase de cuerpo de plantilla (home, page, single-post, archive, clases de plantilla) y una página cuyo marcado es claramente diferente (Jaccard por debajo de 0.5) se separa como page-2; otras plataformas se fusionan por marcado en Jaccard 0.6, como template-<n>:

    node <skill-dir>/scripts/templates.mjs --capture capture
    
  5. Activos. Logotipo, favicon, apple-touch-icon, el manifiesto web <link rel=manifest> y cada fuente @font-face en capture/assets/, más el /favicon.ico y /apple-touch-icon.png raíz (root-favicon.*, root-apple-touch-icon.*) cuando meta.json icons los registró en 200:

    node <skill-dir>/scripts/assets.mjs --capture capture
    

    El logotipo se busca en la página de inicio dentro de <header> primero, luego dentro de cualquier otro elemento cuya clase o id nombre un logotipo (.logo, .site-logo, #logo-wrap). En cada uno: un <img> cuyo src, alt, class o id tenga la palabra "logo" (no "logout"), luego un <svg> en línea con "logo" en su clase, id, aria-label o <title> (guardado como logo.svg, url: null en assets/index.json; su nota lo dice cuando solo <use> un símbolo definido en otra parte de la página, que se renderiza vacío por sí solo), luego la primera <img> en un enlace a la página de inicio, luego la primera <img>. Verifica assets/logo.* visualmente: un avatar de cuenta o una marca de patrocinador aún puede ganar en un encabezado inusual. El favicon y apple-touch-icon se guardan tal como se sirven desde su href <link>, incluida la cadena de consulta, por lo que uno que apunta a un cambio de tamaño (?w=32, ?w=180) de un archivo de uploads difiere en bytes de la entrada de ese archivo en media.json: mantén el icono guardado, no el original.

  6. Capturas de pantalla en vivo, una por plantilla a 390, 768 y 1440, con el shooter de revisión visual:

    node <skill-dir>/../visual-review/scripts/shoot.mjs --base https://www.example.com --routes capture/templates.json --widths 390,768,1440 --out capture/screens/live
    
  7. Lighthouse (opcional). Solo cuando npx --no-install lighthouse --version responda; nunca lo instales sin preguntar; si falta, dila en las notas (un salto, no un pase). Ejecuta mkdir -p capture/lighthouse-live, luego una ejecución por cada representative en templates.json, por turno:

    npx --no-install lighthouse https://www.example.com/ --quiet --chrome-flags="--headless=new" --output json --output html --output-path capture/lighthouse-live/home
    
  8. README. Resume la captura en capture/README.md; su ## Notes comienza con líneas generadas, reescritas en cada ejecución (cuántas rutas de Wayback verificó la segunda pasada y qué respondió cada una: estado, destino de redirección; un listado de Wayback que falló o fue rechazado por tamaño; cada URL que aún falla después de sus reintentos). Ejecútalo al final, y después de cualquier re-ejecución:

    node <skill-dir>/scripts/readme.mjs --capture capture
    
ScriptSalida
fingerprint0 terminado, 2 uso o inalcanzable, 3 bloqueo o desafío antirrobots
capture0 terminado, 2 uso, 3 detenido por bloqueos, inalcanzable, desafío antirrobots (todo reanudable), o ninguna página respondió 200
media0 terminado (archivos faltantes incluidos), 2 uso, sin captura o sin página que respondiera 200, 3 detenido por bloqueos
assets0 terminado (archivos faltantes incluidos), 2 uso o sin captura, 3 detenido por bloqueos
templates0 terminado, 2 uso, sin inventory.json, o "sin páginas capturadas" (ninguna respondió 200)
readme0 terminado, 2 uso o sin inventory.json
shoot0 todas disparadas, 1 una ruta falló, 2 uso, 3 detenido por bloqueos

En caso de salida 3

El sitio está bloqueando solicitudes o no se puede acceder a él. Espera (minutos, no segundos), luego:

  • fingerprint: ejecútalo de nuevo.
  • capture: ejecuta el mismo comando con --resume. Las URLs aún en cola se reintentan

…

[truncado para traducción]

Individual skills in this repo

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

ethanplusai/astro-conversion-kit

Convert a live website (WordPress first; Drupal, Webflow, Squarespace, Wix and static sites too) into a static Astro site with the same URLs, content, head tags, media, redirects and look, proven by parity gates and a pixel-level visual review, ending in one pull request, a noindexed staging deploy and a launch runbook. Use when asked to convert, rebuild, migrate or clone a site to Astro, when handed a site URL with this kit's link, to resume a conversion from .conversion/state.json, or with --apply <id> to apply one suggestion as a proposal.

ethanplusai/astro-conversion-kit

Audit a live or staging website and report what would go wrong at launch — crawl and inventory, indexability, redirects for a domain cutover, links, images, forms, accessibility, performance, analytics, content sanity, and full-page screenshots for a visual pass. Use before or right after a site launch, when asked to QA, audit, or review a website, when a site is moving to a new domain, or when somebody asks whether a site is ready to go live. Read-only: it never submits a form, clicks a control, or edits anything.

ethanplusai/astro-conversion-kit

Freeze a site capture into baseline/ and prove an Astro build matches it — every route, redirect (one hop, through a simulation of the host), SEO head field, visible text, internal link, media file, sitemap entry, feed, form, third-party script and security header — with approved differences in exceptions.json and improvements in proposals.json. Use after a capture to build the baseline, when compiling redirects.csv for Vercel or Cloudflare, before calling any conversion page done, when a gate fails and needs reading, or to check a staging deploy against the baseline.

ethanplusai/astro-conversion-kit

The moment DNS moves and for the thirty days after — verifies the cutover (DNS propagation, certificate, http and www redirects, the noindex, robots and sitemap on the live host, every redirect the audit mapped, forms, analytics, the staging copy, the old host, security headers), diffs production against the pre-launch baseline, and schedules the watch. Use when asked did the launch work, is the site live, what should I check after launch, the domain just switched, or when a site went live in the last month and something looks wrong. It is read-only and exits 0 whatever it finds.

Skills relacionados