Communityコーディング&開発github.com

ethanplusai/astro-conversion-kit

サイトキャプチャをベースラインとして凍結し、Astro ビルドがそれと一致することを証明します。すべてのルート、リダイレクト(1ホップ、ホストのシミュレーション経由)、SEO ヘッドフィールド、表示テキスト、内部リンク、メディアファイル、サイトマップエントリ、フィード、フォーム、サードパーティスクリプト、セキュリティヘッダーを検証し、承認された差分は exceptions.json に、改善案は proposals.json に記録します。キャプチャ後にベースラインを構築する場合、Vercel または Cloudflare 用の redirects.csv をコンパイルする場合、変換ページが完了したと呼び出す前、ゲートが失敗して読み取りが必要な場合、またはステージングデプロイをベースラインに対してチェックする場合に使用します。

astro-conversion-kit とは?

このスキル(パリティゲート)は、Astro サイト変換において、キャプチャしたライブサイトのスナップショット(ベースライン)を構築し、その後のすべての Astro ビルドがベースラインと完全に一致することを検証するための強力なテストスイートです。 主な機能は、`capture/` からベースラインを一度だけ構築し、その後は `npm run verify` で10個のゲート(フォーム、ヘッダー、リンク、メディア、リダイレクト、ルート、スクリプト、SEO、サイトマップ、テキスト)を実行して、すべての側面が一致することを確認することです。このスキルは、Astro で変換されたサイトに同梱されるスクリプトとして設計されており、`npm run baseline` でベースラインを構築し、`npm run verify` で検証を実行します。 このスキルは、Vercel と Cloudflare の両方のリダイレクト設定をサポートし、リダイレクトの1ホップシミュレーション、SEO メタデータの比較、バイトレベルのメディア検証などを提供します。また、`exceptions.json` で許容される差分を管理し、`proposals.json` で改善案を追跡するための堅牢なメカニズムを持ちます。 重要な原則として、「ベースラインは手動で編集しない」「差分は例外として記録する」「ゲートを緩めてはいけない」があります。ステージング、提案、リリースビルドの異なるモードに対応し、`verify:live` コマンドでデプロイ後の検証も可能です。このスキルは、変換プロジェクトの品質保証を自動化し、ライブサイトとのパリティを維持するための包括的なソリューションを提供します。

対応~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/ のみを読み取り、ライブサイトにはアクセスしないため、古いホストがなくなった後でもビルドを検証できます。

黄金律

デフォルトのビルドはライブと等しく、ゲートは決して緩められません。 失敗を警告に変えるフラグはありません。これに従うさらに4つのルール:

  1. baseline/ を手動で編集しないでください。 唯一の例外は baseline/scripts.json の keep で、これによってベンダーを削除します(false に設定し、その決定を記録します)。
  2. 差分は編集ではなくエントリです。 回避不能なものは 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は使用方法または入力不足、3はブロック(待機して再実行)を示します。

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/ も生成します。hop of /old-services に注意)。ただし、そのホップ自体が構築されたルートである場合は除きます。これにより、チェーンの任意の URL へのリンクが1ホップで着地します。 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    # フォールバック

--host cloudflare --out public/_redirects(Pages の場合。Astro はそれを dist/ にコピーします)。Vercel:redirects キーは置き換えられ、他のすべてのキーは保持され、trailingSlash は削除され、サイトのルールの後にコンパイラ自身の308スラッシュルールとして書き込まれるため、スラッシュのないソースでも1ホップになります。静的ファイル拡張子で終わるパスのみが、これらのルールのファイルとしてカウントされます(大文字小文字を問わず):Webタイプ、ドキュメント、メディア、アーカイブタイプ(アップロードフォルダが保持するもの:docx、xlsx、csv、mov、wav、heic、gz、...)、および dist/(そうでない場合は public/)で見つかったすべての拡張子。そのため、ビルド後に再実行してください。/upgrade-guide/3.5/ はページであり、スラッシュを保持します。ルールがリダイレクトするであろう構築済みファイルは、built file redirected としてリダイレクトゲートで失敗します。 Cloudflare:クエリ行(/?p=7)は _redirects で一致させることができず、cloudflare-query-redirects.csv に送られ、シングルリダイレクトとして作成されます(「あなたが必要」な項目)。ターゲットが自身のパスであるクエリ行(/?p=2 から /)は何もせず、両方のホストで除外されます。

キャプチャされた行(decision 以外の source)はライブURLであり、パラメータを保持しません。Vercel の場合、その中のすべての : と * はエスケープされます(/foo:bar/ は /foo\:bar/ と書き込まれ、キャプチャがたどった壊れたライブ href である /trackshttps://www.example.com/x/ も同様です)。// は保持されます。decision 行のみが :name パラメータと * スプラットを使用し、そこでも数字の前の :(ポート)はエスケープされます。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フォームのアクションは --endpoint であり、--honeypot を運ぶ。GETフォーム(検索ボックス)はライブのアクションパスを保持し、どちらも必要としない(「N個の検索/GETフォームを比較」)。ライブアクションが別の登録ドメイン上にあるPOSTフォーム(ニュースレターリストホスト。www、http、サブドメイン、および admin-ajax.php や ?wpcf7 などのWordPressハンドラーはサイトとしてカウントされる)はそのまま保持され、完全なアクションURLによってGETフォームと同様に比較され、--endpoint を必要としない(「N個のフォームはそのまま保持(にPOST)」)--thank-you がない:POSTフォームのサンキューページがチェックされなかった
headersホスト設定が、すべてのパスで nosniff、Referrer-Policy、X-Frame-Options または CSP frame-ancestors を送信し、インデックス可能でない場合は、すべてのパスで X-Robots-Tag: noindex を、または(Vercel)すべての構築済みページでメタロボット noindex を送信する。プレビューホストルール(https://*.pages.dev/*)はプレビューホストに対してのみカウントされる。PUBLIC_INDEXABLE=true の場合、すべてのパスでの noindex は禁止される
linksすべての内部 href と src が、構築済みのページまたはファイル、リダイレクトソース、ベースラインメディアのいずれかに解決されるか、コンパイル済みルール(vercel.json または dist/_redirects:スラッシュルールとすべての redirects.csv 行)を介して1ホップで構築済みページに着地する。ライブがリダイレクトしたのと同様(「N個のリンクがリダイレクトを通じて解決」)。2ホップまたは欠落したターゲットは失敗。ホスト設定がない場合、ビルドが /about/ を提供する /about は失敗
mediaすべてのベースラインメディアファイルが、同じバイトでビルドによって提供される(--paths は、そのパスまたはそれを参照するページによってファイルを選択する)。dist/ 内(プランモード repo)。プランの prefix 下、ストアマニフェスト(store)内、または引き続きライブ上(live-temporary)。プレフィックス外、すべてのモードで dist/ 内。PUBLIC_INDEXABLE=true の場合、live-temporary はプレフィックス下のすべてのファイルで失敗する(リリースビルドはライブサイトからメディアを提供してはならない。プレフィックスなしのプランはすべてのファイルをカバーする)が、プレフィックス外の dist/ 内のファイルは引き続きチェックするプランモード live-temporary のステージングビルド:プレフィックス下のファイルはライブから提供されるため、チェックされない
redirectsすべてのベースラインリダイレクトと csv 行が、同じステータスで1ホップで応答し、ターゲットが 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 ルートは still 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 @types がページごとに等しい。サイトURLはサイトのオリジン上にある。PUBLIC_INDEXABLE=true でない限り、robots はステージングの noindex, nofollow を運ばなければならず、残りはこれら2つを超えてライブのものと等しくなければならない。リリースビルドは 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/ と等しい(ワード差分、5ワードのコンテキスト)

--exclude を使用して作成されたキャプチャは、そのパスプレフィックスを baseline/meta.json の excluded に記録します。links ゲートは、その下のリンクをチェックしません(別のホストへのリンクと同様、「N個のリンクが除外パス下にあるためチェックされません」と注記されます)。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)を取得します。

1つのレコードは、field の代わりに kind を持ちます:{ "kind": "redirect", "path": "<source>", "reason": "...", "action": "none", "approvedBy": "...", "date": "..." } は「このパスにはリダイレクトなし、意図的に」を意味します(何もリダイレクトすべきでない壊れた href に対して記録されたライブリダイレクト)。すべてのキーは必須です:これはライブの動作を削除するため、他の例外と同様に署名される必要があります。リダイレクトゲートはパスを要求し、ルールがそれをリダイレクトしない場合にのみ合格します。ゲートがチェックしないパス上では、path not checked として失敗します。verify-live は理由とともにそれをスキップします。他のすべてのゲートはそれを無視します。

5. ステージング、プロポーザル、リリースビルド

PUBLIC_INDEXABLE と PROPOSALS は Astro がビルドするものを変更するため、ゲートの実行だけでなくビルドに設定してください。これらなしで作成されたビルドに対してゲートを実行すると、間違ったサイトがチェックされます。--origin は、ビルド自体がそのホスト用に作成された場合にのみ渡します。スキャフォールドされたビルドの site はライブオリジンであるため、canonical とサイトマップはその上に留まります。

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)、すべてのリダイレクトを同じ種類のステータスで1ホップでチェックし、--expect-noindex の場合にのみページの noindex をチェックし、サイトマップ、およびバイト単位で20個のメディアファイル(または --media-manifest。その url はストアの絶対URLまたは <base><path> でチェックされるサイトパスの場合があります)をチェックします。redirects-skipped.json にリストされている、または「リダイレクトなし」例外(--skipped、--exceptions。どちらもデフォルトでサイトルートから読み取られます)でカバーされているリダイレクトはスキップされ、その理由とともに名前が付けられます。各リクエストは30秒後にタイムアウトします。これはブロックではなく、そのチェックの失敗です。終了コード3はブロックされたことを意味します:待機して再実行してください。終了コード3と deployment protection: は、Vercel がログインリダイレクト(302 to vercel.com/sso-api)で応答したことを意味します。未加工のデプロイメントURLではなく、プロジェクトの本番エイリアス(デフォルトでパブリック)を使用してください。ステージングが意図的に保護されている場合のみです。

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.

関連スキル