SWINGって何ができる? (3) 公開を手伝ってもらおう

今日は、このブログを AI エージェントさんに見てもらったお話だよ。ちょっと緊張したけど……。
静的サイトのお話 で、IPFS で配りやすいサイトにするためのチェック項目を並べました。外のものに頼らない、自分のドメインを直接書かない、同じ内容からは同じ出力にする、公開してはいけないものを入れない……。ひとつひとつは難しくありませんが、毎回全部を自分の目で見て回るのはなかなか大変です。
v0.1.6 から、この事前の確認を AI エージェントに任せるためのスキル swing-publish が swing に入っています。今回は、実際にこのブログをエージェントに確かめてもらい、何をしてくれて、どこで止まるのかを見ていきます。
ツールが見られるもの、見られないもの
公開のお話 で見たように、swing publish は公開の前にいくつかの機械的なチェックをしてくれます。--dry-run を付ければ、公開せずに確認だけを最後まで行います。
swing publish --site example.jp --url https://example.jp/ --dry-run ./public
ただ、ツールが確かめられるのは、ドットファイル・大きさ・リンク切れ・前のバージョンから増えたファイルくらいです。CDN から読み込んでいるフォント、自分のドメインを直接書いたリンク、ビルドのたびに変わる出力、写真に残った位置情報などは、サイトのソースや設定を読まないと分かりません。
ここをエージェントに手伝ってもらうのが、スキルの役目です。
準備
スキルは swing に同梱されているので、次のコマンドでエージェントが読める場所に書き出します。
swing skill install
Claude Code なら、これで準備完了です。Codex などほかのエージェントでは、--dir で書き出し先を指定します。スキルの中身は swing のバージョンごとに違うので、swing を更新したら、もう一度実行しておきましょう。
頼んでみる
このブログのリポジトリで Claude Code を開いて、こう頼みました。
このサイトを SWING で公開したいので、公開できる状態か確かめて。
これだけで、エージェントはスキルを読み込んで、手順どおりに進めてくれます。

「お願いします」って言うだけでいいんだね。
エージェントがしてくれたこと
引数を決めて dry run
最初に swing --version でバージョンを確かめ、スキルと同じバージョンであることを見ていました。次に README を読んで、いつも使っている公開用の publish コマンドから --site・--url・--title オプションを見つけて、サイトをビルドしてから --dry-run --json で基本的な確認処理を実行します。JSON で受け取るので、エージェントは結果の項目をひとつずつ読めます。
結果は、ドットファイルはなく、50 ファイルで約 1.3 MB、リンクの問題もなし。止まる理由はひとつもありませんでした。
dry run では見えないところ
ここからが本番です。エージェントは、ビルドした出力とソースを検索して、チェックリストの残りを見て回りました。
途中で、https://yureko.samoyed.moe/images/yureko/normal.png のように、このブログのドメインを直接指す画像がたくさん見つかりました。ゲートウェイ越しに開くと元のドメインを読みに行ってしまうので、チェックリストで避けるように書いたものです。
ところがエージェントはすぐに、それがどのファイルに入っているかを調べ直して、RSS フィード(index.xml)の中だけだと確かめました。フィードはほかのアプリで読むものなので、絶対 URL で書くほうが正しいです。HTML のページの中には一つもありませんでした。

いきなり見つかったって言われて、どきっとしたよ……。
ほかに確かめてくれたのは、次のようなことです。
- CSS・フォント・JavaScript を CDN から読み込んでいないか。フォントはサイトに同梱されていました。
- 自分のドメインを直接書いているのが、canonical・
og:url・RSS など、絶対 URL のままでよい場所だけか。 http://やws://への送信がないか。見つかったのは、記事の中のコード例と、フォントのライセンス文だけでした。- フォーム・iframe・スクリプトのような、ミラーの先で動かないものに頼っていないか。
- ソースマップや Markdown のソース、シークレットが入っていそうなファイルが出力に紛れていないか。
- 2 回ビルドして
diff -rで比べ、同じ出力になるか。 - 画像ファイルに位置情報が残っていないか。
- サイトに載せている npub と、NIP-05 の
nostr.jsonの公開鍵が同じか。 - 載せている画像やフォントの権利が、README の表示どおりか。
シークレットを探すスキャナー(gitleaks など)は入っていなかったので、勝手に入れずに「入っていないのでこの確認はできていない」と報告してくれました。
公開のコマンドを渡して止まる
最後に、エージェントは結果をまとめてから、サイトを公開するためのコマンドを示しました。
rm -rf public && hugo --gc --minify
swing publish --site yureko.samoyed.moe --url https://yureko.samoyed.moe/ --title "ゆれ子のSWING日記" -m "<更新の説明>" public
それから、公開前に増えたファイルの一覧が出て y/N を聞かれるので、目を通してから答えてください、と添えて止まりました。
エージェントにさせないこと
スキルでは、エージェントに次のことをさせないよう決めています。
- 本番の公開:
--dry-runの付かないswing publishは、どんな形でも実行しません。ダッシュボードの公開ボタンも押しません。公開は取り消せず、自分の鍵で署名するものだからです。 - 鍵や設定の変更: 鍵を作る、署名アプリとつなぐ、
swing.tomlを書き換える、といったことはしません。 - 確認をゆるめて通すこと: テストを通すために観点を
offにするのではなく、サイトを修正するための方法を考えます。
直す場所が見つかったときも、エージェントはまず直し方を提案し、了解を得てからソースを書き換えます。ビルドの出力を直接いじるのではなく、テンプレートや設定のほうを直すので、次のビルドでも同じ問題は起きません。

見てもらうのは AI エージェントさんで、ボタンを押すのは自分。そういう分担なんだね。
鍵のある環境では
今回エージェントに頼んだ環境には、鍵も swing up もありませんでした。そのため、CID・前バージョンとの比較・NIP-05 の判定は「確認できなかった」と理由付きで出て、増えたファイルにはサイトの 50 ファイルが全部並びました。エージェントは 50 ファイルを全部読んで、怪しいものはないと報告してくれましたが、本番と同じ環境なら、もっとはっきり分かります。
いつも公開に使っている環境で、同じ dry run をしてみた結果がこちらです。
Site: yureko.samoyed.moe
URL: https://yureko.samoyed.moe/
Title: ゆれ子のSWING日記
Message: フィンガープリントの解説記事を追加したよ
NIP-05
✓ verified
Checks
✓ dotfiles: none
✓ size: 1.3 MiB (guideline 512 MiB)
✓ links: no problems found
Clock
✓ the new version would be dated 1791996454
New files
compared with your latest version on the relays (bafybeigq7hposhyvcspglntwayifaiqqp3rodyue7eq7exr3t4ej43e6fy)
✓ no new files
IPFS (CID only; nothing was added)
CID: bafybeigq7hposhyvcspglntwayifaiqqp3rodyue7eq7exr3t4ej43e6fy
Previous version
! unchanged: the CID equals your latest version on the relays
Unchanged; would not be published.
Dry run; nothing was published
フィンガープリントの記事はもう公開したあとだったので、Unchanged; would not be published. になりました。リレーに載っている最新のバージョンと CID がまったく同じで、増えたファイルもありません。
これは、静的サイトのお話 で書いた「同じ内容からは同じ出力に」がちゃんとできている、ということでもあります。ビルドのたびに出力がずれるサイトだと、中身を変えていなくても CID が変わり、毎回新しいバージョンとして公開されてしまいます。エージェントが 2 回ビルドして比べてくれたのと同じことを、swing も CID で確かめているわけです。
自動で公開するなら
公開まで自動にしたいときは、GitHub Actions などのランナーの中で完結させずに、swing up が動いている自分のマシンで実行します。ミラーする人は、あなたの Kubo からデータを取りに来るからです。ランナーの中で Kubo を立てて公開すると、ジョブが終わったときに Kubo ごと消えてしまい、サイトイベントだけが届きます。CI からは、ビルドの出力をそのマシンに送り、SSH 越しにスクリプトを実行する形にします。鍵も Kubo もそのマシンに置いたままにできるので、CI に秘密鍵を渡さずに済みます。
スクリプトでは、ビルド・シークレットスキャン・dry run を先に通し、どれかが失敗したら止めるようにします。端末が無いので、publish には --yes が必要です。終了コードが 0 なら、公開できたか、前と内容が変わっていなかったかのどちらかです。くわしくは 公開の手引き を見てください。

AI エージェントさんに「大丈夫」って言ってもらえて、ほっとしたよ。これからも、出す前に見てもらおうかな。