Community코딩 & 개발github.com

ethanplusai/astro-conversion-kit

사이트 캡처를 baseline/에 고정하고, 모든 Astro 빌드가 이와 일치하는지 검증합니다 — 모든 경로, 리디렉션(호스트 시뮬레이션을 통한 한 번의 홉), SEO head 필드, 표시 텍스트, 내부 링크, 미디어 파일, 사이트맵, 피드, 폼, 서드파티 스크립트 및 보안 헤더를 exceptions.json의 승인된 차이점과 proposals.json의 개선 사항과 함께 검사합니다. 캡처 후 베이스라인을 구축하거나, Vercel 또는 Cloudflare용 redirects.csv를 컴파일하거나, 변환 페이지 완료를 호출하기 전, 게이트 실패 시 진단 목적, 또는 스테이징 배포를 베이스라인과 비교할 때 사용하세요.

astro-conversion-kit란 무엇인가요?

이 스킬은 Astro 사이트 마이그레이션 또는 리빌드 후, 모든 출력이 기존 라이브 사이트와 정확히 일치하는지 자동으로 검증하는 포괄적인 패리티 게이트 시스템입니다. capture/ 디렉토리에서 베이스라인을 한 번 구축한 후, 이후 모든 빌드에서 이 베이스라인을 기준으로 forms, headers, links, media, redirects, routes, scripts, seo, sitemaps, text 등 10개의 게이트를 실행합니다. 각 게이트는 통과/실패 외에도 건너뛰기(skip) 이유를 명확히 보고하며, 예외(exceptions.json)와 개선 제안(proposals.json)을 통해 불가피한 차이점을 관리합니다. Vercel, Cloudflare Pages 등 다양한 호스트를 지원하며, 개발/스테이징/프로덕션 릴리스 환경 모두에서 사용할 수 있습니다. 핵심 원칙은 '기본 빌드는 라이브와 동일해야 하며, 게이트는 절대 약화되지 않는다'입니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ethanplusai/astro-conversion-kit/tree/HEAD/skills/parity-gates

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

패리티 게이트

capture/에서 베이스라인을 한 번 구축한 후, 모든 게이트가 통과할 때까지 모든 빌드를 검증합니다. 게이트는 baseline/만 읽으며, 라이브 사이트는 절대 읽지 않으므로 이전 호스트가 사라진 후에도 빌드를 검증할 수 있습니다.

황금률

기본 빌드는 라이브와 동일하며, 게이트는 절대 약화되지 않습니다. 어떤 플래그도 실패를 경고로 바꾸지 않습니다. 이로부터 파생되는 네 가지 규칙:

  1. baseline/을 수동으로 편집하지 마십시오. 단 한 가지 예외: baseline/scripts.json의 keep 필드로, 벤더를 제거할 때 사용됩니다(false로 설정하고 결정 사항을 기록).
  2. 차이점은 항목(entry)이지, 수정(edit)이 아닙니다. 불가피한 경우: exceptions.json. 개선 사항: proposals.json (PROPOSALS=on일 때만 활성화). 둘 다 references/exceptions.md에 설명되어 있습니다.
  3. 건너뛰기는 통과가 아닙니다. 확인할 수 없는 게이트는 요약 줄에 N skipped (reason)이라고 표시합니다. 모든 건너뛰기를 보고하십시오.
  4. 잘못된 게이트는 키트 버그로 보고하고, 사이트에서 게이트를 절대 변경하지 말며, 베이스라인도 변경하지 마십시오.

스크립트 실행

convert-site로 생성된 사이트는 scripts/ 디렉토리에 스크립트가 있습니다. 사이트 루트에서 아래 npm 스크립트를 실행하고, 옵션은 -- 뒤에 추가합니다. 스캐폴딩된 사이트 외부에서는 각 단계에 표시된 node 형식을 사이트 루트에서 실행하되, <skill-dir>은 npm install이 실행된 키트 복사본 내 이 스킬 폴더의 절대 경로입니다. 모든 스크립트는 --help를 출력하므로, 소스 코드 대신 이를 실행하십시오. 종료 코드: 0 통과, 1 실패한 게이트 또는 드리프트, 2 사용법 오류 또는 입력 누락.

1. 베이스라인 (최초 한 번)

npm run baseline
node <skill-dir>/scripts/build-baseline.mjs --capture capture --out baseline    # 대체 명령

capture/inventory.json, media.json (캡처의 media.mjs) 및 templates.json (templates.mjs)이 필요합니다. 누락된 파일이 있으면 해당 단계를 실행하라는 메시지와 함께 종료 코드 2로 종료됩니다. baseline/{routes,seo,redirects,media,forms,scripts,meta,counts}.json, baseline/text/ 및 사이트 루트에 redirects.csv를 작성합니다. 대상이 없는 단축 링크는 제외되고 stderr에 이름이 출력됩니다. 캡처된 체인의 각 중간 홉은 최종 대상까지 직접 연결되는 자체 행을 갖습니다(/old-services → /old-services/ → /services/는 /old-services/,/services/도 생성하며, /old-services의 홉 참고). 단, 해당 홉 자체가 빌드된 경로인 경우는 제외되므로, 체인의 모든 URL에 대한 링크가 한 번의 홉으로 도달합니다. baseline/과 redirects.csv를 함께 커밋하십시오. --check 플래그는 baseline/을 counts.json과 비교하여 재계산합니다(드리프트 시 종료 코드 1). 모든 파일의 구조는 references/contracts.md에 정의되어 있습니다.

2. 리디렉션

redirects.csv (from,to,status,source,note)는 사이트 리디렉션의 단일 소스입니다. source는 캡처의 crawl, sitemap, shortlink 또는 seed이며; 사용자가 추가한 행은 decision이고, note는 결정 ID를 지정합니다. 컴파일된 출력물을 수동으로 편집하지 마십시오. 컴파일은 다음과 같이 실행합니다:

npm run redirects:build
node <skill-dir>/scripts/build-redirects.mjs --csv redirects.csv --host vercel --out vercel.json --trailing-slash always    # 대체 명령

Cloudflare Pages의 경우: --host cloudflare --out public/_redirects (Astro가 이를 dist/로 복사). Vercel: redirects 키는 교체되고, 다른 모든 키는 유지되며, trailingSlash는 제거되고 사이트의 슬래시 규칙 뒤에 컴파일러 자체의 308 슬래시 규칙으로 작성됩니다. 따라서 슬래시가 없는 소스도 한 번의 홉으로 유지됩니다. 정적 파일 확장자로 끝나는 경로만 파일로 간주되며, 대소문자를 구분하지 않습니다: 웹 유형, 문서, 미디어 및 업로드 폴더의 아카이브 유형(docx, xlsx, csv, mov, wav, heic, gz 등), 그리고 dist/(또는 public/)에서 발견된 모든 확장자. 따라서 빌드 후에 다시 실행하십시오. /upgrade-guide/3.5/는 페이지이므로 슬래시를 유지합니다. 규칙이 여전히 리디렉션할 빌드된 파일은 리디렉션 게이트에서 built file redirected로 실패합니다. Cloudflare: 쿼리 행(/?p=7)은 _redirects에서 일치시킬 수 없으며, cloudflare-query-redirects.csv로 이동하여 Single Redirect로 생성해야 합니다("needs you" 항목). 대상이 자체 경로인 쿼리 행(/?p=2 → /)은 무효 작업이므로 두 호스트 모두에서 제외됩니다.

캡처된 행(source가 decision이 아닌 모든 경우)은 라이브 URL이며 매개변수를 포함하지 않습니다. Vercel의 경우 :와 *가 이스케이프됩니다(/foo:bar/는 /foo\:bar/로 작성되며, /trackshttps://www.example.com/x/도 마찬가지이며, 캡처가 따라간 손상된 라이브 href입니다). //는 유지됩니다. decision 행만 :name 매개변수와 * splat을 사용하며, 숫자 앞의 :(포트)는 이스케이프됩니다. Vercel은 베어 :을 거부하며, 게이트의 시뮬레이션도 마찬가지입니다. 유효한 형식이 없는 소스(선행 / 없음, 공백, 제어 문자; Cloudflare의 경우 캡처된 :<name> 또는 *도 포함하며, _redirects가 이스케이프할 수 없음)는 삭제되고, stderr에 이름이 출력되며, redirects-skipped.json에 { source, reason }으로 나열됩니다. 이 파일은 redirects.csv 옆(사이트 루트)에 위치하며, public/ 아래에는 절대 위치하지 않으므로 배포되지 않습니다. 리디렉션 게이트와 verify-live는 나열된 행을 건너뛴 것으로 간주하며, 통과로 간주하지 않습니다. 경로에 단순히 리디렉션이 없어야 하는 경우, 대신 "리디렉션 없음" 예외를 기록하십시오(섹션 4): { "kind": "redirect", "path": "<source>", "reason": "...", "action": "none", "approvedBy": "...", "date": "..." }.

3. 검증

npm run build
npm run verify -- --endpoint https://forms.example.com/f/abc --thank-you /thank-you/
node <skill-dir>/scripts/verify/run-all.mjs --endpoint https://forms.example.com/f/abc --thank-you /thank-you/    # 대체 명령

run-all은 10개의 게이트를 알파벳 순서로 실행하며, 각 게이트에 허용된 옵션만 전달하고 첫 번째 실패 시 중단합니다. 공통 옵션: --paths (쉼표 목록, *는 모든 항목과 일치), --json, --origin (링크, SEO, 사이트맵: 빌드 대상 호스트), --allow-extra (경로), --endpoint, --honeypot, --thank-you (폼; 베이스라인에 POST 폼이 있는 경우 --endpoint는 필수), --host, --config (리디렉션, 링크), --csv (리디렉션), --media-plan (미디어). 첫 번째 실패를 수정하고, 다시 빌드한 후, 다시 실행하십시오. 단일 게이트 실행: node <skill-dir>/scripts/verify/<gate>.mjs.

게이트통과 조건건너뛰기의 의미
forms각 라이브 폼이 해당 페이지에 동일한 필드 이름, 순서, 메서드로 존재합니다. POST 폼의 action은 --endpoint이며 --honeypot을 포함합니다. GET 폼(검색 상자)은 라이브의 action 경로를 유지하며 둘 다 필요하지 않습니다("N search/GET forms compared"). POST 폼의 라이브 action이 다른 등록 가능한 도메인(뉴스레터 목록 호스트, www, http, 서브도메인 및 admin-ajax.php 또는 ?wpcf7와 같은 WordPress 핸들러는 사이트로 간주)에 있는 경우 그대로 유지되며, 전체 action URL로 GET 폼처럼 비교되고 --endpoint가 필요하지 않습니다("N forms kept as is (posts to )")--thank-you 없음: POST 폼의 감사 페이지가 확인되지 않음
headers호스트 구성이 모든 경로에 nosniff, Referrer-Policy, X-Frame-Options 또는 CSP frame-ancestors를 전송하고, 인덱싱 불가능한 경우 모든 경로에 X-Robots-Tag: noindex를 전송하거나 (Vercel) 모든 빌드된 페이지에 메타 robots noindex를 전송합니다. 미리보기 호스트 규칙(https://*.pages.dev/*)은 미리보기 호스트에만 적용됩니다. PUBLIC_INDEXABLE=true인 경우 모든 경로에 noindex가 금지됩니다.
links모든 내부 href와 src가 빌드된 페이지, 파일, 리디렉션 소스 또는 베이스라인 미디어로 확인되거나, 컴파일된 규칙(vercel.json 또는 dist/_redirects: 슬래시 규칙 및 모든 redirects.csv 행)을 통해 한 번의 홉으로 빌드된 페이지에 도달하며, 라이브가 리디렉션한 대로 작동합니다("N links resolved through redirects"). 두 번의 홉 또는 누락된 대상은 실패합니다. 호스트 구성이 없으면, /about이 빌드에서 /about/을 제공하는 경우 실패합니다.
media모든 베이스라인 미디어 파일이 빌드에 의해 동일한 바이트로 제공됩니다(--paths는 경로 또는 해당 파일을 참조하는 페이지로 파일을 선택). dist/ 내: 계획 모드 repo; 계획의 prefix 아래, 저장소 매니페스트(store) 또는 라이브(live-temporary)에 있음; 접두사 외부, 모든 모드에서 dist/ 내. PUBLIC_INDEXABLE=true인 경우, live-temporary는 접두사 아래의 모든 파일을 실패시킵니다(릴리스 빌드는 라이브 사이트에서 미디어를 제공하지 않을 수 있음; 접두사가 없는 계획은 모든 파일을 포함). dist/의 접두사 외부 파일은 계속 확인합니다.스테이징 빌드의 계획 모드 live-temporary: 접두사 아래의 파일이 라이브에서 제공되며, 확인되지 않음
redirects모든 베이스라인 리디렉션과 csv 행이 동일한 상태로 한 번의 홉으로 응답하며, 대상이 dist/에서 200을 반환합니다(또는 외부이거나 베이스라인 meta.json excluded의 접두사 아래에 있는 경우: 첫 번째 홉만 확인). 어떤 소스도 빌드된 파일이 아닙니다. 어떤 빌드된 페이지나 파일도 자체 URL에서 리디렉션되지 않습니다(built page redirected by rule <rule>; 예외가 이를 포함하지 않으면 규칙을 수정). "리디렉션 없음" 예외(kind: "redirect", action: "none")가 있는 경로는 전혀 리디렉션되지 않습니다.무효 쿼리 행, Cloudflare의 모든 쿼리 행, 또는 redirects-skipped.json에 이유(not compiled)와 함께 나열된 유효한 형식이 없는 소스
routes모든 페이지, 게시물, 아카이브 및 피드가 200으로 빌드되고, noindex 경로는 여전히 noindex를 말하며, 추가 항목이 빌드되지 않습니다(캡처의 자체 스크립트 baseline/js.json 및 스타일시트 baseline/css.json의 라이브 경로, 라이브 사이트맵 이름 baseline/sitemaps.json, 실행 아이콘 세트는 추가 항목이 아님). 200, 3xx, 404 또는 410 이외의 상태로 캡처된 경로는 routes 예외가 해당 경로를 건너뛰거나 빌드된 대체 이름을 지정하지 않는 한 not captured: <status>로 실패합니다.to: "skip"인 routes 예외: 해당 경로가 캡처되지 않음
scripts각 유지된 벤더가 정확히 해당 라이브 페이지에 동일한 ID로 존재합니다. 삭제된 벤더는 어떤 페이지에도 없습니다. 새 벤더가 없습니다.
seo제목, 설명, canonical, robots, lang, h1, h2, og 및 JSON-LD @type이 페이지별로 동일합니다. 사이트 URL은 사이트의 오리진에 있습니다. PUBLIC_INDEXABLE=true가 아닌 경우, robots는 스테이징 noindex, nofollow를 포함해야 하며, 나머지는 이 두 값 이후 라이브와 동일합니다. 릴리스 빌드는 robots를 정확히 비교합니다.
sitemapsdist/의 모든 최상위 사이트맵(Astro의 sitemap-index.xml 또는 baseline/sitemaps.json의 라이브 이름(예: wp-sitemap.xml 또는 sitemap_index.xml))이 오리진의 인덱싱 가능한 200 페이지를 정확히 나열합니다(퍼센트 이스케이프는 대소문자를 구분하지 않고 비교: %c3는 %C3와 동일). 모든 robots.txt Sitemap: 줄은 오리진에 있으며 dist/의 파일을 지정하거나, 라이브 robots.txt(capture/robots.txt)가 그대로 가지고 있던 줄입니다. 모든 피드는 동일한 항목 수로 빌드됩니다.
text각 페이지의 표시 텍스트가 baseline/text/와 동일합니다(단어 diff, 5단어 컨텍스트).

--exclude로 만든 캡처는 경로 접두사를 baseline/meta.json excluded에 기록합니다. links 게이트는 해당 접두사 아래의 링크를 확인하지 않으며(다른 호스트의 링크처럼, "N links under excluded paths ... not checked"로 기록), sitemaps 게이트는 라이브 robots.txt가 그대로 가지고 있던 경우 접두사 아래의 robots.txt Sitemap: 줄을 수락합니다(동일 호스트의 멀티사이트 하위 사이트 사이트맵).

4. 차이점 및 결정

빌드가 라이브와 일치할 수 없거나 일치하지 않아야 하는 경우, references/exceptions.md를 읽으십시오. 간단히 말해: 항목은 { path, field, from, to, reason, approvedBy, date }입니다. from: ""은 빌드가 추가한 값을 기록하고, to: ""은 제거한 값을 기록합니다. 더 이상 일치하지 않거나 게이트가 확인하지 않는 경로를 지정하는 예외는 게이트를 실패시킵니다. 라이브 사이트의 모든 이상 현상(누락된 H1, 죽은 태그, 깨진 링크)은 기본적으로 재현되며, 결정 행(id, topic, choice, default, reason, cost if wrong)을 통해 이를 명시하고 수정 사항이 무엇인지 설명합니다.

하나의 레코드는 field 대신 kind를 갖습니다: { "kind": "redirect", "path": "<source>", "reason": "...", "action": "none", "approvedBy": "...", "date": "..." }는 "이 경로에 대한 리디렉션 없음, 의도적으로"를 의미합니다(리디렉션하지 않아야 하는 깨진 href에 대해 기록된 라이브 리디렉션). 모든 키는 필수입니다. 이는 라이브 동작을 제거하므로 다른 예외와 마찬가지로 서명이 필요합니다. 리디렉션 게이트는 경로를 요청하고 규칙이 이를 리디렉션하지 않는 경우에만 통과시킵니다. 게이트가 확인하지 않는 경로에서는 path not checked로 실패합니다. verify-live는 이유와 함께 이를 건너뜁니다. 다른 모든 게이트는 이를 무시합니다.

5. 스테이징, 제안 및 릴리스 빌드

PUBLIC_INDEXABLE과 PROPOSALS는 Astro가 빌드하는 내용을 변경하므로, 게이트 실행뿐만 아니라 빌드에도 설정하십시오. 이 설정 없이 만든 빌드에서 게이트를 실행하면 잘못된 사이트를 확인합니다. --origin은 빌드 자체가 해당 호스트용으로 만들어진 경우에만 전달하십시오. 스캐폴딩된 빌드의 site는 라이브 오리진이므로, canonicals 및 사이트맵이 그대로 유지됩니다.

npm run build && npm run verify -- --endpoint ... --thank-you ...                                       # 스테이징
PROPOSALS=on npm run build && npm run verify:proposals -- --endpoint ... --thank-you ...                 # 제안
PUBLIC_INDEXABLE=true npm run build && npm run verify:release -- --endpoint ... --thank-you ...          # 릴리스

스테이징 배포 후, HTTP를 통해 베이스라인과 비교하여 확인합니다. 릴리스 배포는 --expect-noindex 없이 동일한 방식으로 확인합니다:

npm run verify:live -- --base https://my-site.vercel.app --expect-noindex
node <skill-dir>/scripts/verify-live.mjs --base https://my-site.vercel.app --expect-noindex    # 대체 명령

--bypass "$VERCEL_AUTOMATION_BYPASS_SECRET"은 스테이징이 의도적으로 보호된 경우에만 적용됩니다(환경 변수에서 가져온 값이며, 채팅에 붙여넣지 않음). 공개 스테이징 별칭은 필요하지 않습니다.

모든 베이스라인 경로를 200으로 확인하고(또는 --sample), 모든 리디렉션을 동일한 상태 유형으로 한 번의 홉으로 확인하며, --expect-noindex가 있는 경우에만 페이지에 noindex를 확인하고, 사이트맵을 확인하며, 20개의 미디어 파일을 바이트 단위로 확인합니다(또는 --media-manifest, 해당 url은 저장소의 절대 URL이거나 <base><path>에서 확인되는 사이트 경로일 수 있음). redirects-skipped.json에 나열되거나 "리디렉션 없음" 예외(--skipped, --exceptions, 둘 다 기본적으로 사이트 루트에서 읽음)로 포함된 리디렉션은 건너뛰고 이유와 함께 이름이 표시됩니다. 모든 요청은 30초 후에 타임아웃되며, 차단보다는 해당 검사의 실패로 처리됩니다. 종료 코드 3은 차단되었음을 의미합니다: 기다렸다가 다시 실행하십시오. deployment protection:과 함께 종료 코드 3은 Vercel이 로그인 리디렉션(302 to vercel.com/sso-api)으로 응답했음을 의미합니다: 원시 배포 URL 대신 프로젝트의 프로덕션 별칭(기본적으로 공개)을 사용하십시오. 스테이징이 의도적으로 보호된 경우에만...

(참고: 원문 SKILL.md가 잘린 부분이 있으므로, 이 번역도 해당 지점에서 중단됩니다.)

Individual skills in this repo

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

ethanplusai/astro-conversion-kit

Crawl a live website, read-only and paced, into a capture/ folder that a rebuild is checked against — every page's HTML, text and head tags, redirects with every hop, links, third-party scripts, the media set, stylesheets, fonts, logo and icons, feeds, templates, and live screenshots at three widths. Use before converting or rebuilding a site, when asked to crawl, capture, snapshot or inventory a site, or when a capture stopped on blocks and needs resuming.

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

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.

관련 스킬