bunshin について
Web サイトや Web アプリの初版を作るための設計・開発スキルです。主担当が方向性を定め、サブエージェントが調査、ページの並行構築、レビューを行い、根拠の確認と人間による承認を組み込みます。
主な機能
- 01サブエージェントによる並行調査と構築
- 02ページごとのファイル分担
- 03独立したレビュー、テスト、検証
- 04方向性の承認とラウンド上限
- 05不足情報の記録
活用シーン
- 01顧客資料からサイトの初版を作成
- 02複数ページを並行して開発・レビュー
- 03キャプチャとテスト結果に基づく Web アプリの改良
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ athevon/ genjutsu --skill bunshinインストール後、Claude Code で/bunshinを入力して読み込まれたか確認します。
詳細
Bunshin - The Shadow Clones
アートディレクターは一人、クローンは大勢。ビジョンはあなたが保ち、クローンが制作の幅を担います。 これは genjutsu で最も負荷の高いパイプラインです。目的はただ一つ、クライアントの実際の素材を使って、 サイト全体の初版を作ることです。
あなたが指揮します。方向性を定める契約を書き、基盤と特徴となる画面を自分で作り、レビューの意味を判断します。クローン(サブエージェント)は調査を行い、互いに重ならないファイルでページを並行して構築し、独立した視点でレビューし、計画を適用します。インストールされている場合、Impeccable がプロダクトインタビューを主導し、ビジュアルの方向性を描きます。genjutsu のモジュールは、モーション、プラットフォームの原則、特徴、監査を担います。人間に判断を求めるのは二度、召喚時と方向性を選ぶ時です。その後は、ティアのラウンド上限を超える場合にのみ、再度求めます。
口調
このスキルでは、二つの口調を使います。
実行中 - 軽い忍者風の演出を交え、短くします。
- 「調査のため、クローンを四人召喚します。」
- 「クローンが戻りました。ページは六つ、ビルドは五つ成功です。」
- 「第2ラウンドを封印します。」
レポート、要約、ゲートメッセージ - 平易で事実に基づき、開発者に読みやすくします。何を構築したか、何をどのように検証したか、何をしていないか、費用はいくらか、クライアントがまだ提供する必要のあるものは何かを伝えます。神秘的な表現は使いません。ゲートメッセージも平易にします。誰かが、そこにお金を使うか判断するためです。
bunshin、paint、cast
/genjutsu:cast | /genjutsu:paint | /genjutsu:bunshin | |
|---|---|---|---|
| 対象 | 一つのエフェクト、コンポーネント、またはセクション | 一つのビジュアルアイデンティティ、一つのページまたはプロダクト | サイト全体またはウェブアプリの初版 |
| 作業する人 | あなた | あなた | あなたとクローンチーム |
| 方向性 | インタラクションの方針 | ビジュアルとインタラクションの方針、MASTER.md | Impeccable が描く方向性(インストールされている場合)と genjutsu のインタラクション方針を、一つの契約にまとめたもの |
| 成果の確認 | 簡易監査 | 完全な監査 | 全ページのキャプチャ、スクリプト化されたテスト、独立した視点からのレビュー、判定、第三者による客観的な確認 |
| 人間による確認ゲート | 方針、バリエーション | ブレインストーミング、方針、デザインシステム、ページ | 二つ:召喚、方向性 |
| コスト | 1セッション | 長時間のセッション | 数百万トークン、数時間(「召喚」参照) |
絶対ルール
- 最初に召喚します。 ティアが決まるまでは、クローンを実行してはならず、読み取りより負荷の高い作業もしてはなりません。誰も回答しない場合は、「誰も回答しない場合」を参照してください。
- 2回尋ねてから、根拠をもとに判断します。 召喚と方向性はユーザーが決めます。それ以外の判断はすべて、資料、調査、レビューをもとにあなたが行い、レポートに記載します。
- アートディレクターは1人です。 方向性の契約、基盤、特徴的なサーフェスはあなたが作成します。クローンは契約の範囲内で構築し、契約を再定義してはなりません。
- 検証済みのテーゼなしにコードを書いてはなりません。 方向性ゲートでは、
Allowed patterns:の行とともに、ビジュアルとインタラクションのテーゼを検証します。 - 所有範囲を明確に分けます。 各クローンは、宣言したファイル一覧を所有し、それ以外のすべてのファイルは読み取り専用です。共有の要望は依頼として伝え、編集してはなりません。
- 開発サーバーも共有ブラウザーも使いません。 クローンはそれぞれ専用のヘッドレスブラウザーでキャプチャし、フレームワークのバイナリを使ってコピー上で構築します。
- 証拠がなければ、実施したことにはなりません。 すべての指摘にはキャプチャの領域または
file:lineを記載します。「完了」とするには終了コード 0 が表示されたビルドが必要であり、すべての挙動には測定値が必要です。 - 何も捏造しません。 事実は資料と回答から得ます。不足している情報はページ上では汎用的な内容にとどめ、コンテンツファイルに明記し、レポートにも記載します。
- ループはルールに従って終了します。 最終レビュアーが軽微な修正のみと判断したとき、ティアのラウンド上限に達したとき、または修正がなかったラウンドで終了します。終わりのない反復は禁止です。確認を求めずに上限を超えてはなりません。
- 許可なく依存関係をインストールしてはなりません。 Impeccable とブラウザーツールも対象です。召喚で許可される唯一のインストールは、指定されたスキャフォールドです(SUMMON を参照)。誰も回答しない場合は、それ以外をインストールしてはなりません。
- 許可なくマシンの外に何も出してはなりません。 コミット、プッシュ、デプロイ、公開は禁止です。
- 現時点では Web のみです。 Compose または SwiftUI の場合は、bunshin はまだネイティブスタックに対応していないと伝え、
paintに切り替えてください。
対象外の場合は切り替える
bunshin は、サイト全体より小規模な作業には適していません。READ の段階で対象外と判断したら、何かに着手する前に、その旨を1行で伝えてください。
| 依頼内容 | 切り替え先 |
|---|---|
| 1つのコンポーネント、1つのエフェクト、1つのセクション | cast |
| 1ページ、1つのランディングページ、またはサイトを伴わないビジュアルアイデンティティ | paint |
| サイト全体だが、ホストがサブエージェントを起動できない | paint。bunshin にはサブエージェントを起動できるホストが必要だと1行で伝えます |
| ネイティブの Compose または SwiftUI アプリ | paint |
「これはランディングページ1つなので、適切なパイプラインは bunshin ではなく paint です。paint を実行します。」
切り替えるには、ホストに genjutsu:paint または genjutsu:cast が表示されている場合はスキルとして呼び出してください。表示されていない場合は、このファイルの隣にあるエントリーファイル、つまり $GENJUTSU_SKILL_DIR/../paint/(または ../cast/)の直下にある Markdown ファイルを読み、最初のステップから従ってください。ユーザーは切り替えを覆すことができます。その場合、bunshin を実行し、作業範囲が大きすぎると判断した理由を伝えてください。
このホストが召喚できるもの
READ 時に一度確認してください。能力で判断し、製品名では判断しません。このセッションで実際に公開されているツールが決め手です。角括弧内の名前は、Claude Code がそれらをどう呼ぶかを示すだけです。
- サブエージェントを起動するツール。直接(Agent)、またはワークフロースクリプト経由(Workflow)で起動します。 どちらもなければクローンは作れません。次の段階に進んでください。ワークフローツールがある場合は、テンプレートどおりに実行されます。サブエージェントツールしかない場合は、テンプレートを計画として使い、同じクローンを手動で起動します。
- 構造化された質問ツール(AskUserQuestion)。2つのゲートで使います。なければ、各ゲートでメッセージを1つずつ送ります。
- セッションから操作できるブラウザー。ソーシャルプロフィールの情報収集と、ページを自分で確認するために使います。クローンは使用しません。
- 権限。クローンは
rsync、ln、find、node、フレームワークのバイナリ、ヘッドレス Chrome を、毎回新しいパスを使って並行実行します。このセッションがコマンドごとに確認を求める場合は、召喚時にその旨を伝え、実行に必要な許可ルールを列挙してください(例:Bash(rsync:*)、Bash(find:*)、Bash(node:*)、Bash(./node_modules/.bin/astro:*))。設定ファイルに自分で書き込まないでください。
次に、1回のシェル呼び出しで実行します。
for d in .claude/skills/impeccable .agents/skills/impeccable "$HOME/.claude/skills/impeccable" "$HOME/.agents/skills/impeccable"; do
# The entry file's name is assembled from parts: the bundle rewrites it when spelled out.
e="$d/SKILL"
if [ -f "$e.md" ]; then echo "impeccable: $d ($(sed -n 's/^version: //p' "$e.md" | head -1))"; break; fi
done
node -e 'process.exit(typeof WebSocket === "function" ? 0 : 1)' 2>/dev/null && echo "node: 22+ (shoot.mjs runs)" || echo "node: missing or older than 22 (shoot.mjs cannot run)"
for c in "${CHROME_PATH:-}" "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" "/Applications/Chromium.app/Contents/MacOS/Chromium" \
"$(command -v google-chrome google-chrome-stable chromium chromium-browser chrome 2>/dev/null | head -1)"; do
[ -n "$c" ] && [ -x "$c" ] && { echo "chrome: $c"; break; }
done
command -v magick >/dev/null 2>&1 && echo "imagemagick: yes" || echo "imagemagick: no"
python3 -c 'import PIL, numpy' 2>/dev/null && echo "python PIL + numpy: yes" || echo "python PIL + numpy: no"
不足している要素ごとの代償は、フェーズ 8 で初めて気づくのではなく、召喚時に伝えてください。
| 不足しているもの | 影響 |
|---|---|
| サブエージェントツールとワークフローツールの両方 | bunshin は実行されません。paint に進んでください。 |
| ワークフローツール(サブエージェントツールはある) | フェーズは同じですが、scripts/brief.mjs が出力するプロンプトを使ってクローンを手動で起動するため、時間がかかります。 |
| Impeccable | 方向性は bunshin 独自のラウンド(references/impeccable.md、"Without Impeccable")で描かれるため、質が下がります。npx impeccable install --project -y を一度だけ提案してください。実行中にインストールした場合、そのエージェントが利用できるようになるのはホストが再読み込みした後です。それまでは、仕上げレビューは機能が低下した役割ファイルから実行されます。 |
| セッションから操作できるブラウザー | スクリプトで投稿を一覧表示するソーシャルプロフィールの情報収集はできません。画像とテキストをファイルとして渡してもらうか、現在のサイトのアドレスを尋ねてください。 |
| Node 22 または Chrome | キャプチャはできません。レビュー担当者はコードだけを読み、レビューループの価値の大部分が失われます。その旨を伝えてください。何もインストールしないでください。 |
| ImageMagick、Pillow、numpy | コンタクトシートも切り抜きもできず、素材の手順は手作業での切り抜きだけになります。 |
召喚 - ティアとコスト
実測した1回の実行では、プロフェッショナルのソーシャルプロフィールをもとに、2言語対応の7ページのサイトを構築し、人が2回手を加えました。6~8時間でサブエージェントのトークンを約10.5M消費し、レビュー1回、改善ラウンド3回(レビューによるものが1回、決定ファイルによるものが2回)、判定2回を実施しました。メインセッション自体のトークン数は計測していません。以下のティアはこの実行をもとにした推定値で、ページ数に応じて変動します。提示するたびに、その旨を伝えてください。
| ティア | 改善ラウンド | 観点 | 初見レビュー | 推定値、サブエージェントのトークン |
|---|---|---|---|---|
| lean | 1 | 3:仕上がり、モバイル、真偽・技術 | なし | 約6M、3~4時間 |
| standard(推奨) | 最大2 | 5 | 第1ラウンドの判定に含まれ、第2ラウンドでその決定を適用 | 約8~9M、4~6時間 |
| full | 最大4 | 5 | すべての判定 | 約12~13M、6~10時間 |
推定値を算出するために、実測した実行で各単位にかかった量は次のとおりです。調査は約0.6M、ページのクローン1つあたり約0.4M(6ページで2.3M)、計画を含む5観点レビューは約1.6M、計画に基づく改善ラウンドは担当者8人で約1.6M、決定ファイルを適用する改善ラウンドは約1.75M、初見レビューを含む判定は約0.35M、ドキュメント作成は約0.2Mです。2つの単位は計測しておらず、これらをもとに推定しています。計画を含む3観点レビューは約1.1M、初見レビューを含まない判定は、含む場合のおよそ半分です。
作業内容の提示 - プレビューゲート
このパイプラインの一部のゲートは、承認する前にユーザーが何かを見られるように設けられています。インタラクションの設計方針、バリエーション、ビジュアルアイデンティティ、デザインシステムなどです。モーションや色は、文章で説明しても伝わりません。目に見えないイージングカーブを承認するのは、承認ではなく推測です。
そのため、最初にこの種のゲートに入る前に、どのように見たいかを尋ねます。その後は二度と尋ねません。
メニュー - 最初のビジュアルゲートで一度だけ提示し、推奨するデフォルトに印を付けます。
これをお見せする前に、どのように見たいか教えてください。
A. レンダリングされたページ - ライブ HTML ページです。実際のイージングカーブ、実際の時間、実際にモーションする要素を確認できます。 B. ライブプレビュー - プロジェクト内に一時的なルートを用意します。実際のスタックと実際のトークンを使います。ネイティブの場合は、
@Preview/#Previewのスクラッチファイルです。 C. インライン - 会話内に文章で記載します。
推奨するデフォルト - メニューに明記し、黙って適用しないでください。
| 状況 | デフォルト |
|---|---|
| 範囲が小さい(ホバー、1つのトランジションなど) | C - インライン |
| 範囲が中規模または全体で、Web スタックの場合 | A - レンダリングされたページ |
| 範囲が中規模または全体で、Compose / SwiftUI の場合 | B - ライブプレビュー。次点は A |
| ビジュアルアイデンティティ全体またはデザインシステムを検討している場合 | A - レンダリングされたページ |
| 開発サーバーがない場合、またはリポジトリに書き込んではならない場合 | A - レンダリングされたページ |
| ホストが Cowork で、書き込み可能なプロジェクトのチェックアウトがない場合 | A - レンダリングされたページ。B は利用できません |
選択したモードはセッション全体で固定されます。 以降の各ゲートでは、モードを1行で伝えて(「レンダリングされたページでバリエーションを表示します。」)、そのまま進めます。メニューを再度表示しないでください。ユーザーが「それをテキストで見せて」「ページに載せて」「口頭で教えて」などと伝えた場合に、すぐに従ってください。新しいモードが以降のセッションのデフォルトになります。
このホストはどれですか? ゲートは LOAD の前に実行されるため、$SKILL_BASE はまだ存在せず、以下の判定は単独で機能します。一度だけ簡単に検出し、それに応じて対応します。
if [ -d /mnt/skills/plugins ] || [ -d /mnt/skills/user ]; then
GENJUTSU_HOST=claude-ai
elif [ -d /mnt/.claude/skills ] \
|| [ -n "$(find /sessions -maxdepth 6 -type d -path '*/.claude/skills' 2>/dev/null | head -1)" ]; then
GENJUTSU_HOST=cowork
elif [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] || [ -d "$HOME/.claude/plugins" ]; then
GENJUTSU_HOST=claude-code
else
GENJUTSU_HOST=unknown
fi
echo "genjutsu host: $GENJUTSU_HOST"
Cowork を Claude Code より先に判定するのは意図的です。どちらも ~/.claude ツリーを持つ場合がありますが、セッションをルートとするスキルのマウントがあるのは Cowork だけなので、より具体的なシグナルを優先する必要があります。
プレビューの作成 - ホストを特定し、機能を縮退させても、決して失敗させないでください。
| ホスト | A - レンダリングされたページ | C - インライン |
|---|---|---|
| claude.ai | アーティファクトとしてネイティブにレンダリングされます。そのまま作成してください。 | 会話内に文章で記載します。 |
| Cowork | ホストの永続アーティファクトです。ターンが終わっても残ります。デザインシステムには、ユーザーが後から戻ってこられることが重要です。 | ホストのインラインウィジェットを、その場でレンダリングします。短いタスクに適したデフォルトです。 |
| Claude Code | セッションにある場合は Artifact ツールを使い、それ以外の場合は以下の機能ルールに従います。 | 会話内に文章で記載します。 |
| 不明(その他のホスト) | 以下の機能ルールに従います。 | 会話内に文章で記載します。 |
A は機能に応じて選択します。 モード A には次のいずれかが必要です。以下の順に試してください。ユーザー向けに HTML をレンダリングする、このセッションで利用可能なツール(Claude ホストではアーティファクト)。それがない場合は、セッションが操作できるブラウザーがあれば、一時パスに書き込んだ自己完結型の使い捨て HTML ファイルを開きます。それもない場合は、同じファイルを作成し、開き方を1行添えて、そのパスをユーザーに渡します。名前から判断せず、セッションで実際に利用できるツールを確認してください。どの方法も使えない場合は、ゲートを失敗させずに C に切り替えてください。インラインプレビューのほうが、中断するより常に優れています。
B - ライブプレビューには、書き込み先のプロジェクトが必要です。 Cowork ではプロジェクトがないことが多いため、A と C を提示し、機能しない選択肢を並べるのではなく、B が選べない理由を1行で説明してください。
プレビューに含めるもの。 文章を見栄えのよいフォントで書き直しただけのプレビューには、価値がありません。文章では伝えられないものを表現してください。
| ゲート | プレビューに表示するもの |
|---|---|
| インタラクションの方針 | SVG でプロットしたイージングカーブとその正確な値、リプレイボタンで実際にインタラクションを実行する要素、数値のみの設定(デュレーション、遅延、スタガー、スプリングのパラメーター)、および動きを減らす設定を有効にした場合の簡略版を表示するトグル。 |
| バリアントのセット | バリアントごとに同じカードを横並びで表示し、すべてを同時に実行するグローバルトリガーで比較できるようにするほか、バリアントごとのリプレイも用意します。 |
| ビジュアルアイデンティティ | 背景とのコントラスト比を添えた16進数表記のスウォッチ、実際のスケール段階での書体見本、スペーシングバー、角丸とシャドウのサンプル、実際のボタン1つとカード1つ。 |
| デザインシステム | すべてのトークンカテゴリ、各基本コンポーネントの5つの状態(デフォルト、ホバー、フォーカス、アクティブ、無効)、およびライトとダークの両方がある場合はそれらを横並びで表示します。 |
プレビューが守るルール:
- プレビューを含むメッセージでは、方針を平易なテキストで明示します。 モードに関係なく、最初に方針を1文で示し、
Interaction thesis:またはVisual thesis:とラベルを付けます。続けてAllowed patterns:の行を記載し、このページは提案であり実装ではないことを1行で伝え、最後に検証の質問を記載します。 実装は含めません。コードを書くのは、承認を得た後の次のターンからです。AまたはBを選んだ人が、方針をどこで確認できるのか探すことがあってはなりません。 - プレビューは使い捨てです。実装に転用することはありません。 検証済みの方針と読み込まれたサブスキルをもとに、本物を一から作ります。プレビューのマークアップを移植してはいけません。Compose / SwiftUI では特に重要です。HTMLが近似するのはタイミングとカーブのみであり、描画ではないことをページ上で伝えてください。
- 検証後、ユーザーが残すよう求めない限り、ライブプレビューのルートを削除します。
- プレビューの作成に依存関係をインストールしてはいけません。
- ユーザーに確認せず開発サーバーを起動してはいけません。
- 方針に含まれる値のみを表示します。方針にない数値をプレビューに含めてはいけません。そうしないと、プレビューが2つ目の方針になり、その方針は誰にも検証されていません。
- プレビューがこのセッション中に読み込めないウェブフォントも、固有の名前で表示し、フォールバックスタックを設定したうえで
not rendered in this sessionとラベル付けします。セッション中に描画できるフォントに置き換えてはいけません。サンドボックスが取得できるものと、サイトが実際に配信するものは同じではありません。
bunshin がプレビューゲートを使う方法。 唯一のビジュアルゲートは方向性であり、質問も2つのゲートに関するものだけなので、メニューは表示しません。Impeccable がある場合は、判断ページがプレビューになります。ない場合は、方向性カードをレンダリング済みページ(モードA)として表示し、そのことを1行で伝えます。ユーザーは、希望を伝えればモードを切り替えられます。
誰も応答しない場合
エバリュエーションハーネス、CI ジョブ、このスキルを操作する別のエージェントなど、人間が応答しないセッションもあります。リクエストやホストがそのことを示した場合(非対話型の実行、「質問しないでください」という指示、ゲートへの回答があらかじめ含まれたプロンプトなど)に限ってそう判断します。1つの質問にしばらく回答がなかったからといって、そう判断してはいけません。リクエストにゲートへの回答があらかじめ含まれている場合、その回答は有効です。ゲートは回答済みであり、スキップされたのではありません。
このようなセッションでも、各ゲートは必ず出力を生成します。変わるのは、誰もその内容を検証しないことです。
- 調査とブレインストーミングの質問: 質問しないでください。概要とスキャン結果に基づいてそれぞれに回答し、すべての回答を論旨の中で仮定として明示します。
- プレビューゲート: この範囲とスタックに対してメニューが推奨するデフォルトを選び、1行で伝えてから先に進みます。
- 論旨ゲート: 提案するはずだった論旨を採用し、未検証であることを1行で伝えてから先に進みます。最終レポートには、未検証と明記して掲載します。
- 依存関係: インストールしてはいけません。論旨で求められるライブラリがプロジェクトにない場合は、スタックのネイティブ API を使い、最終レポートで不足している依存関係を明記します。
それ以外はすべて変わりません。コードを書く前に論旨を作成し、モジュールを読み込み、監査では根拠を報告します。ヘッドレス実行で省略するのは待機であり、作業ではありません。
誰も応答しない場合の bunshin の動作。 ティアは予算ですが、誰も予算に合意していません。ヘッドレス実行が READ を超えて進むのは、リクエストでティアが指定されている場合に限られ、その回答は有効です。指定がなければ READ の後で停止し、召喚メッセージを最終レポートとして出力し、何も起動しません。実行する場合、スキャナーが検出したスタックを使います。ただし、リクエストでスタックが指定され、インストールが許可されている場合はそのスタックを使います(上記の共通ルールにより、その他のインストールは禁止されています)。それ以外の場合は、インストールせずにプレーンな静的 HTML と CSS を使います(FOUNDATION、「プレーンな HTML と CSS の場合」)。方向性は、決定ページを提示せずにドローで割り当てられたカードを採用します。Impeccable がない場合は、3つの世界のうち最初のものを引き継ぎます。インストールされていない Impeccable は、インストールされていないままにします。すべてのゲートへの回答には、レポート内で未検証と明記します。
サブスキルのパス検出
このスキルがどこにあるかをブロックに知らせてください。 ブロックの最初の行は GENJUTSU_SKILL_DIR です。Claude Code では自動的に設定されます。それ以外のホストでは、このファイルを読み込んだディレクトリを指定する1行を、同じシェル呼び出しでブロックの前に置いてください。
GENJUTSU_SKILL_DIR='/absolute/path/to/bunshin'。genjutsu ルーターが GENJUTSU_SKILL_DIR= の行を出力した場合は、その値をそのまま使ってください。
このブロックはシェルの状態を定義しますが、その状態はシェル呼び出しをまたいで保持されません。 $SKILL_BASE、load_skill、load_ref は、このブロックを実行した単一のシェル呼び出し内でのみ使えます。後続のフェーズはどれも、ユーザー検証ゲートの後に続くすべてのフェーズも、後のフェーズにあたるため、状態が何もないところから始まります。したがって、これから実行する load_skill の行と同じシェル呼び出しで、このブロック全体を再出力してください。 $SKILL_BASE を定義していない呼び出しで cat "$SKILL_BASE/..." を実行してはいけません。パスが /<name>/... に解決され、cat が失敗して、モジュールが失われます。
ブロックが could not find the genjutsu modules と出力した場合は、パイプラインを停止してください。 インストールコマンドも含めてメッセージをユーザーに表示し、それ以外の操作は行わないでください。後続のすべての手順はモジュールに依存しており、モジュールなしで実行すると、このスキルが防ごうとしている一般的な出力がそのまま生成されます。
GENJUTSU_SKILL_DIR="${GENJUTSU_SKILL_DIR:-${CLAUDE_SKILL_DIR}}"
# Resolution order, first hit wins:
# 0. claude.ai, /mnt/skills/plugins (or the older /mnt/skills/user): the
# genjutsu bundle.
# 1. This skill's own directory: its _jutsu, or the _jutsu next to it.
# 2. ${CLAUDE_PLUGIN_ROOT}/skills/_jutsu, when Claude Code substituted it.
# 3. Bounded probes: .claude/skills and .agents/skills from $PWD upward, then
# the skills directories installers write to, then /sessions (Cowork).
# 4. The Claude Code plugin cache, newest version. Last on purpose: an old
# plugin install must never win over a newer bundle.
# Resolved from scratch every time. A cache was tried here and removed: after a
# plugin update the old version directory is still on disk, so a cached path
# passes an "is it a directory" check and serves the previous release.
# No function below names a positional parameter (a dollar sign followed by a
# digit, or the whole argument list). Claude Code replaces those tokens in a
# skill's text with the words typed after the slash command, before the model
# reads this block: after "/genjutsu:cast make the cards feel physical", a path
# built from a function's first parameter would read "the/motion-principles/...",
# the second word typed. Each function reads its arguments with a bare
# `for name; do`, which walks the positional parameters without writing any out.
# A _jutsu directory counts only if it holds motion-principles. The shared
# skills directory of npx serves about 80 agents, so a directory name proves
# nothing. The entry file is named SKILL or GUIDE depending on the artifact
# (the bundle renames it at packaging time), so the name is assembled from
# parts: spelled out in full, the packaging step would rewrite it too.
genjutsu_is_jutsu() { # <candidate _jutsu directory>
for jutsu_dir; do
for d in SKILL GUIDE; do
[ -f "$jutsu_dir/motion-principles/$d.md" ] && return 0
done
done
return 1
}
# Print the first genjutsu _jutsu among the candidate paths read on stdin.
genjutsu_first_jutsu() {
while read -r jutsu_c; do
genjutsu_is_jutsu "$jutsu_c" && { printf '%s\n' "$jutsu_c"; return 0; }
done
return 1
}
SKILL_BASE=""
# 0. claude.ai mounts uploaded skills under /mnt/skills/plugins/<name>/ (seen on
# 2026-09-28), next to the user's other skills; /mnt/skills/user before that.
# GENJUTSU_CLAUDE_AI_ROOT stands in for /mnt/skills in the test suite only.
# Only a _jutsu holding motion-principles counts: a mount without genjutsu in it
# must never pass for a resolved base.
genjutsu_claude_ai="${GENJUTSU_CLAUDE_AI_ROOT:-/mnt/skills}"
for claude_root in "$genjutsu_claude_ai/plugins" "$genjutsu_claude_ai/user"; do
[ -z "$SKILL_BASE" ] && [ -d "$claude_root" ] || continue
SKILL_BASE="$(find -L "$claude_root" -maxdepth 2 -type d -name _jutsu 2>/dev/null | genjutsu_first_jutsu)"
done
# 1. This skill's own directory. Empty means unknown: never probe "/_jutsu".
if [ -z "$SKILL_BASE" ] && [ -n "$GENJUTSU_SKILL_DIR" ]; then
SKILL_BASE="$(printf '%s\n' "$GENJUTSU_SKILL_DIR/_jutsu" "$GENJUTSU_SKILL_DIR/../_jutsu" | genjutsu_first_jutsu)"
fi
# 2. Claude Code plugin root.
if [ -z "$SKILL_BASE" ] && [ -n "${CLAUDE_PLUGIN_ROOT}" ]; then
SKILL_BASE="$(printf '%s\n' "${CLAUDE_PLUGIN_ROOT}/skills/_jutsu" | genjutsu_first_jutsu)"
fi
# 3. Bounded probes, following symlinks (npx links .claude/skills/<name> to
# .agents/skills/<name>). The case guard stops the walk at "/", "." or "".
probe_dir="${PWD:-$(pwd)}"
probe_n=0
while [ -z "$SKILL_BASE" ] && [ "$probe_n" -lt 24 ]; do
probe_n=$((probe_n + 1))
SKILL_BASE="$(find -L "$probe_dir/.claude/skills" "$probe_dir/.agents/skills" -maxdepth 2 -type d -name _jutsu 2>/dev/null | genjutsu_first_jutsu)"
case "$probe_dir" in /|.|"") break ;; esac
probe_dir="$(dirname "$probe_dir")"
done
for probe_root in "$HOME/.agents/skills" "$HOME/.claude/skills" "$HOME/.codex/skills" \
"$HOME/.cursor/skills" /mnt/.claude/skills; do
[ -z "$SKILL_BASE" ] && [ -d "$probe_root" ] || continue
SKILL_BASE="$(find -L "$probe_root" -maxdepth 2 -type d -name _jutsu 2>/dev/null | genjutsu_first_jutsu)"
done
if [ -z "$SKILL_BASE" ] && [ -d /sessions ]; then
SKILL_BASE="$(find -L /sessions -maxdepth 8 -type d -path '*/.claude/skills/*/_jutsu' 2>/dev/null | genjutsu_first_jutsu)"
fi
# 4. Claude Code plugin cache, newest version first. Numeric version
# directories only, so a bare marketplace clone never wins.
if [ -z "$SKILL_BASE" ] && [ -d "$HOME/.claude/plugins/cache" ]; then
SKILL_BASE="$(find "$HOME/.claude/plugins/cache" -maxdepth 6 -type d -path '*/genjutsu/[0-9]*/skills/_jutsu' 2>/dev/null | sort -V -r | genjutsu_first_jutsu)"
fi
[ -n "$SKILL_BASE" ] && SKILL_BASE="$(cd "$SKILL_BASE" 2>/dev/null && pwd -P)"
# Stop instead of running the pipeline without its modules. Name every root that
# was tried, so a new layout can be reported instead of guessed.
if [ -z "$SKILL_BASE" ]; then
echo "genjutsu: could not find the genjutsu modules (a _jutsu directory holding motion-principles)." >&2
echo " genjutsu's pipelines do not work without them. Install the full bundle:" >&2
echo " any agent npx skills add https://genjutsu.athevon.dev -g" >&2
echo " Claude Code /plugin marketplace add AThevon/genjutsu, then /plugin install genjutsu" >&2
echo " claude.ai upload genjutsu.zip in Customize > Skills" >&2
echo " npx skills add AThevon/genjutsu installs the pipelines without their modules." >&2
echo " Tried: /mnt/skills/plugins, /mnt/skills/user, GENJUTSU_SKILL_DIR (${GENJUTSU_SKILL_DIR:-empty}) and its parent," >&2
echo " \$CLAUDE_PLUGIN_ROOT, .claude/skills and .agents/skills from \$PWD upward," >&2
echo " ~/.agents/skills, ~/.claude/skills, ~/.codex/skills, ~/.cursor/skills," >&2
echo " /mnt/.claude/skills, /sessions, ~/.claude/plugins/cache." >&2
echo "genjutsu: stop the pipeline here and show this message to the user." >&2
return 1 2>/dev/null || exit 1
fi
echo "genjutsu: modules from $SKILL_BASE" >&2
# Print a module's entry file. A missing module does not stop the pipeline (a
# partial claude.ai upload is legitimate), but it is announced, and the final
# report lists it: shell state does not survive, so the model keeps the list.
load_skill() { # <module>
skill_name=""
for skill_arg; do skill_name="$skill_arg"; break; done
for d in SKILL GUIDE; do
if [ -n "$skill_name" ] && [ -f "$SKILL_BASE/$skill_name/$d.md" ]; then
cat "$SKILL_BASE/$skill_name/$d.md"
return 0
fi
done
echo "genjutsu: sub-skill '$skill_name' NOT LOADED - not found under $SKILL_BASE. Carry on, and list it under 'Modules not loaded' in the final report." >&2
return 1
}
# Print one reference file of a module: load_ref <module> <path inside it>.
load_ref() { # <module> <path inside it>
ref_module=""; ref_path=""; ref_n=0
for ref_arg; do
ref_n=$((ref_n + 1))
case "$ref_n" in
1) ref_module="$ref_arg" ;;
2) ref_path="$ref_arg"; break ;;
esac
done
if [ -n "$ref_module" ] && [ -n "$ref_path" ] && [ -f "$SKILL_BASE/$ref_module/$ref_path" ]; then
cat "$SKILL_BASE/$ref_module/$ref_path"
return 0
fi
echo "genjutsu: reference '$ref_module/$ref_path' NOT LOADED - not found under $SKILL_BASE. Carry on, and say so in the final report." >&2
return 1
}
bunshin では、シェルの外でも絶対パスの $SKILL_BASE が必要です。ワークフローテンプレートにはパスが渡され、各クローン向けの指示書には、クローンが読み込む必要のあるモジュールが記載されます。ブロックが初回に出力するパス(genjutsu: modules from ...)を控え、ティア、機能、Impeccable のディレクトリとともに .bunshin/run.json に記入してください。オーナーマップは FOUNDATION で .bunshin/owners.json に記入します。シェルの状態は引き続き保持されません。何かを読み込む場合やスクリプトを実行する場合は、呼び出しのたびにブロックを再出力してください。
オーケストレーションモジュールは、最初のクローンを開始する前の SUMMON で読み込みます。
# (skill-base block re-emitted above this line)
load_skill orchestration
参照ファイルは該当するフェーズで、シェル呼び出しごとに1つずつ読み込みます。
load_ref orchestration references/material.md(HARVEST、MATERIAL)、
references/impeccable.md(Impeccable がある場合は READ、DIRECTION、SEAL)、
references/evidence.md(FOUNDATION、PROVE)。
テンプレートに渡すすべてのパスは絶対パスです。以下の <root> はプロジェクトの絶対パスで、スクラッチディレクトリは呼び出し前に解決します(ホストが指定するセッションのスクラッチディレクトリがあればそれを使い、なければ printf '%s\n' "${TMPDIR:-/tmp}/bunshin-<project>" の値を使います)。テンプレートでは渡された値が引用されるため、パスとして渡されたシェル式は展開されません。
パイプライン
12のフェーズがあります。サイト以外で実行時に書き込まれるものは、すべて <root>/.bunshin/ に格納します。SUMMON で .gitignore に次の項目を追加してください。run.json、owners.json、harvest/、research/、direction/(選択されたカードのボードとヒーロー、および Impeccable がない場合の direction.md)、captures/round-N/(round 1:レビューの証拠、round N+1:refine の round N 後の証拠)、reviews/round-N.json とその横に置くレンズファイル、reviews/round-N-refine.json、reviews/round-N-verdict.json、decisions/round-N.md、report.md。.bunshin/ 内のものは、サイトに取り込まれることはありません。分離されたコピーから除外されます。
0. 読む — プロジェクト、ブリーフ、ホスト
# 1. Web (existing)
cat package.json 2>/dev/null | grep -E '"(gsap|motion|framer-motion|three|@react-three/fiber|@react-three/drei|animejs|popmotion|lenis|locomotive-scroll)"'
cat package.json 2>/dev/null | grep -E '"(react|react-dom|vue|svelte|next|nuxt|astro|solid-js|qwik)"'
cat package.json 2>/dev/null | grep -E '"(tailwindcss|styled-components|@emotion|sass|less|vanilla-extract|panda)"'
# 2. Android / Compose
ls build.gradle.kts build.gradle settings.gradle.kts settings.gradle 2>/dev/null
grep -rE 'androidx\.compose|implementation\("androidx\.compose' build.gradle* settings.gradle* 2>/dev/null
# 3. Compose Multiplatform / KMP
grep -rE 'org\.jetbrains\.compose|kotlin\("multiplatform"\)|id\("org\.jetbrains\.kotlin\.multiplatform"\)' build.gradle* settings.gradle* 2>/dev/null
# 4. Apple / SwiftUI
ls *.xcodeproj *.xcworkspace Package.swift 2>/dev/null
grep -lE 'import SwiftUI|@main.*App' --include="*.swift" -r . 2>/dev/null | head -1
# 5. Apple platform sub-detection (iOS vs macOS)
grep -E '\.iOS\(|\.macOS\(' Package.swift 2>/dev/null
grep -E 'SDKROOT = (iphoneos|macosx)' *.xcodeproj/project.pbxproj 2>/dev/null
# 6. Mobile web indicators
grep -rE 'viewport.*width=device-width|@media.*pointer:\s*coarse|@media.*max-width' --include='*.html' --include='*.css' --include='*.scss' . 2>/dev/null | head -3
ls public/manifest.json public/sw.js 2>/dev/null
# 7. Legacy bridge indicators (mention in DISCOVER, do not auto-load)
ls -- *.xib *.storyboard 2>/dev/null
find . -path '*/res/layout/*.xml' 2>/dev/null | head -1
grep -rE 'setContentView\(R\.layout' --include='*.kt' --include='*.java' . 2>/dev/null | head -1
結果を整理します:
- アニメーションライブラリ:gsap、
motion、framer-motion、three/@react-three、anime.js、またはなし。motionとframer-motionは、名前が異なる同じライブラリです。 Framer MotionはMotionに改名されました。現在のパッケージはmotionで、framer-motionはレガシーパッケージですが、今も広くインストールされ、公開されています。どちらがpackage.jsonにあるかを記録してください。インポートパスが異なるため、サブスキルが把握する必要があります。両方ある場合、プロジェクトは移行中です。その旨を伝え、編集するファイルですでにインポートされている方に従ってください。 - フレームワーク:React、Vue、Svelte、Next.js、Nuxt、Astro、vanilla
- CSS:Tailwind、styled-components、CSS modules、vanilla CSS
- 何も検出されない場合:ゼロから始めるため、すべて利用可能です
- ネイティブ Android:gradleの依存関係からComposeを検出します。
- ネイティブ Apple:Package.swift/xcodeprojとSwiftファイルからSwiftUIを検出します。Package.swiftのplatformsまたはpbxprojのSDKROOTを使って、iOSとmacOSを区別します。
- Compose Multiplatform:kotlin-multiplatformプラグインとjetbrains.composeプラグイン。
- モバイルのコンテキスト:viewport、manifest、モバイル専用のメディアクエリ、またはネイティブのiOS/Android。
- デスクトップのコンテキスト:macOSをターゲットにしている、またはWebでモバイルを示す要素がない場合。
- レガシーの混在:
.xib、.storyboard、レイアウトXML、setContentView(R.layout.*)の存在。言及のみとし、自動ロードはしません。
次に、ブリーフを読み、そこに記載されたすべてのソース(プロフィール、現在のサイト、ドキュメント)にざっと目を通します。まだ情報は収集しません。上記の機能チェックを実行します。作業の規模を見積もります。ページまたは画面、言語、対象ユーザー、主要チャネルを確認します。bunshinが適切なパイプラインか判断します(「Step down」を参照)。Impeccableを使う場合は、今すぐload_ref orchestration references/impeccable.mdを実行し、Impeccable自身のreference/init.md(Step 3にインタビューの質問、Step 4にPRODUCT.mdの形式があります)と、reference/new-work.mdのセクション2(描画前に尋ねる質問)を読んで、召喚時にそれらを引き継げるようにします。
召喚する前に、castやpaintと同じように、読み取った内容を1行で宣言してください:「ここまでの読み取り:<何を>、<誰のために>、<方向性>を目指し、<スタック>を使用します。」埋められない項目は不明として述べ、ゲートで質問します。
1. SUMMON - 最初のゲート
1 つのメッセージに続けて、ホストにツールがある場合は、構造化された質問を 1 回呼び出します。
bunshin 対象:<内容>、<言語>で ページ、ソースは <ソース>。 計画:素材を収集し、4 つのクローンと統合で調査します。あなたが方向性を選び、私が 基盤と特徴的な表層を作成し、 ページ分のクローンが残りを構築します。その後、細かな 問題だけになるか、ティアの上限に達するまで、改善ラウンドと判定を繰り返します。 このホスト:<ワークフロー経由でクローンを並列実行 | クローンを 1 つずつ実行 | 呼び出し不可>。 Impeccable:<バージョン、方向性の決定を支援 | 未インストール:方向性を決めるラウンドの効果が弱まります。
npx impeccable install --project -yで解決します>。キャプチャ:<はい | いいえ。その場合の影響も記載>。 スタック:<フレームワークとアダプターは導入済み | プロジェクトはまだありません:以下のスタックに関する質問の各選択肢に、正確なスキャフォールドコマンドとパッケージを記載し、型チェック用のものも含めます>。 ティアとスタックに関する回答で対象となるのは、その 1 回のインストールだけです。それ以外は含まれません。 コスト:実行 1 回分を測定済みです。7 ページのバイリンガルサイトで、サブエージェントのトークン消費量は約 10.5M、所要時間は 6~8 時間でした。 これを基にした推定値:軽量は約 6M、標準は約 8~9M、フルは約 12~13M で、このセッション自体のトークンは別途必要です。消費量はページ数に応じて増減します。 <権限:このセッションが各コマンドの実行前に確認を求める場合に、実行に必要な許可ルール。>
同じ呼び出しで、質問は最大 4 つです。最初は ティア(標準を推奨として明記)、続いて作業内容への影響が大きいプロダクトに関する質問を、推奨する選択肢から順に提示します。Impeccable がある場合は、その init のステップ 3 で尋ねる質問と、作成前に new-work が尋ねる質問が対象で、最大 3 つです。スキャフォールドがない場合は、スタックに関する質問を最初にします。これでインタビューは完了し、どちらも再度尋ねることはありません。Impeccable がない場合は、paint のブレインストーミング対象領域を尋ねます。4 つの質問で決まらないことはすべて仮定として扱い、PRODUCT.md とレポートに記載します。
回答を待ちます。その後、.bunshin/ を .gitignore に追加し、.bunshin/run.json を書き込み、オーケストレーションモジュールを読み込みます。Impeccable がある場合は、プロジェクトのルートから <dir>/scripts/impeccable context を 1 回実行します(<dir> は機能チェックの出力どおりです。プロジェクトへのインストールでは、PATH には何も追加されません)。
2. HARVEST - 実際の素材
load_ref orchestration references/material.md を読み込み、その手順に従います。クライアント自身が所有する画像をフル解像度で収集し、テキスト、実際に読んだコンタクトシート、主要な画像から抽出したパレット、出典付きの事実、足りないもののリストをそろえます。収集するのは、クライアントが所有するものだけです。すべて .bunshin/harvest/ に格納します。
3. RESEARCH - 4 つのクローン、続いて統合
ブリーフ(事実とゲートでの回答のみ)を渡して research.js を実行し、out を
<root>/.bunshin/research/synthesis.md に設定します。統合内容を読みます。続いて PRODUCT.md を作成します。Impeccable がある場合は、その init ステップ 4 の形式に従います。ない場合は、同じ見出しを使用します。確認済みの事実のみを記載し、決して創作してはならないもの(価格、レビュー、クライアント、数値)をまとめたセクション、手元にある根拠、原則を含めます。
4. DIRECTION - 第二のゲート
references/impeccable.mdのDirectionラウンドを実行します。抽選前に並べる7つの世界、抽選、挑戦者とその引き上げ、決定ページ、そしてページを実行できない場合、または回答されないまま閉じられた場合に限る構造化質問のフォールバックを含みます。各カードにはインタラクションの論旨(タイミングの範囲、ホバー、スクロール、禁止パターン)と、そのAllowed patterns:行を含めます。どちらもページに実際に表示されるフィールド内に置き、1つの選択で両方の論旨を検証できるようにします。bunshinは常にコード主導で構築します。Impeccableがない場合は、レンダリングされたページ上で、そのリファレンスに記載されたラウンドを実行します。
推測可能性のテストは、すべてのカードに適用されます。製品カテゴリーだけから書ける方向性は、そのカテゴリーの既定値であり、方向性ではありません。
ユーザーが選択したら、コントラクトを作成します(surface-brief writeまたは.bunshin/direction.md)。THESIS、OWN-WORLD、STORY、FIRST VIEWPORT、FORM、FINISH、インタラクションの論旨、許可されたパターンを記載します。このファイルを基準として、すべてのクローンとレビュアーが作業を評価します。Impeccableを使う場合は、選択したカードのボードとヒーロー画像を.bunshin/direction/に保存します(仕上がりのレビュアーはQUALITY BARカードとして読み込みます)。その後、独立したシェル呼び出しでスキルベースブロックを再出力し、Webリファレンスとともにtellsを読み込みます(load_skill tellsの後にload_ref tells references/web.md)。次にMATERIALでタイプを確定し、tellsで排除すべき反射的なパターンを特定します。選択したカードのAllowed patterns:行をカタログと照らし合わせ、許可するカタログ記載の反射的パターンを、次のメッセージの1行(質問ではありません)とレポートの前提条件に明記します。
5. MATERIAL - 反射ではなく、証拠に基づいて
references/material.mdに従い、レイアウトを実際に小さく再現したものにタイプ見本をレンダリングし、キャプチャを比較します。写真はトリミングとクロップを行います。切り抜きはオブジェクト自体のエッジに合わせ、明るい背景と暗い背景の両方で確認します。粒子模様はタイルとして扱います。すべてのラスター画像に出典情報を付けます。タイプの選択とその理由をコントラクトに記録します。サイトが配信するすべてのラスター画像は、プロジェクト独自のアセットフォルダー(例:src/assets/)に書き込み、sharedが所有します。また、ビルドパケットで指定するインデックス(ファイル、対象、使用可能なページ)を用意します。
6. FOUNDATION - クローンのものではなく、自分のもの
必ず読み込みます(上記で定義したload_skill <name>を使用します。不足しているモジュールはNOT LOADEDと表示され、パイプラインは続行するため、最終レポート用に一覧を保持してください)。
load_skill motion-principles- 基盤
シェル呼び出しごとに1つのモジュールを読み込みます。 約30,000文字を超えるシェル呼び出しの出力はインラインで表示されず、2,000文字のプレビューとファイルパスが返されます。読めなかったモジュールは読み込んでいないのと同じです。そのため、各読み込み呼び出しではスキルベースブロックを再出力して1つのモジュールを読み込み、出力を25,000文字未満に保ちます。モジュールのエントリーファイルはすべてこの上限以下であり、validate-skills.pyによってその状態が維持されます。読み込み状況を記録してください。load_skillは不足しているモジュールに対してNOT LOADEDと表示して続行し、最終レポートには両方を記載します。各モジュールを全体として読み込みます。上記のバッチ処理ルールによって各呼び出しはすでに上限未満に収まるため、load_skillやload_refをhead、tail、sed、grepにパイプで渡してはいけません。途中で切り詰められたモジュールは、読み込んでいないのと同じです。
コンテキストレイヤー(該当する場合に読み込みます)。
| 検出条件 | 読み込み |
|---|---|
| Webスタックで、スコープがmediumまたはfull | load_skill tells(専用の呼び出しで、references/web.mdとともに読み込みます。下記参照) |
| モバイルのコンテキスト(Webモバイル、またはネイティブのiOS/Android) | load_skill mobile-principles |
| デスクトップのコンテキスト(macOS、またはモバイルを示す要素のないWebデスクトップ) | load_skill desktop-principles |
| 監査が明示的に要求された場合、またはscope=full | load_skill design-audit |
| 高度なUI/UXに関する質問 | load_skill ui-ux-pro-max |
tells は単独のシェル呼び出しを取得します。 Web リファレンスを含めると約 20,000 文字になり、シェル呼び出しの出力がインラインで届かなくなる閾値に近すぎるため、他のモジュールと 1 回の呼び出しを共有することはできません。その呼び出しで skill-base ブロックを再度出力してから、次を実行します: |
# (skill-base block re-emitted above this line)
load_skill tells
load_ref tells references/web.md
これは thesis ゲートの後に、視覚的な選択が確定する前に読み込まれます。検証済みの thesis はどのパターンが求められているかを示し、tells は誰も求めていない反射を名指しします。Compose や SwiftUI のスタックでは決して使用せず、light scope でも決して使用しません。paint ではこの行はすでに満たされています。Phase 3 はデザインシステムのクエリの前に tells を読み込みます。
スタック固有 (SCAN で読み込み):
| 検出されたスタック | 読み込むサブスキル |
|---|---|
| gsap | load_skill gsap |
motion または framer-motion (同じライブラリ、2 つのパッケージ名) | load_skill framer-motion |
| Pure CSS / Tailwind / ライブラリなし | load_skill css-native |
| three / @react-three | load_skill threejs-r3f |
| Canvas / ジェネラティブ | load_skill canvas-generative |
| Android Compose | load_skill compose-motion (常に) + load_skill compose-graphics (scope=full または thesis が advanced の場合 — 以下を参照) |
| Compose Multiplatform | load_skill compose-motion + load_skill compose-multiplatform (常に); iOS ターゲットが検出され、SwiftUI 相互運用が必要な場合は load_skill swiftui-motion; advanced の場合は load_skill compose-graphics |
| SwiftUI iOS または macOS | load_skill swiftui-motion (常に) + load_skill swiftui-graphics (scope=full または thesis が advanced の場合) |
compose-graphics / swiftui-graphics の「advanced thesis」トリガー:
thesis に以下の用語のいずれかが含まれている場合、その thesis は「advanced」です (そして graphics サブスキルの読み込みをトリガーします):
shader、Metal、AGSL、RuntimeShader、MSLliquid-glass、glassEffect、morphing transitionM3 Expressive、MotionScheme、expressive motioncolorEffect、distortionEffect、layerEffectCanvas(ジェネラティブ / パーティクル / フローフィールドのコンテキストを伴う場合)holographic、CRT、displacement、ripple
それ以外の場合は、基本の motion サブスキルにとどめてください。
bunshin はサイト全体を構築するため、そのスコープは常に full です。tells (すでに direction の後に読み込まれています)、mobile-principles、desktop-principles、design-audit がすべて適用され、それぞれが独自の呼び出しで、foundation の最初の行の前に実行されます。Impeccable の場合、最初の UI 編集の直前にその reference/craft-floor.md を読んでください。
次に、ご自身で構築します:
- スキャフォールド、プロジェクトが存在しない場合。ルートにはすでに
.claude/、.bunshin/、 PRODUCT.md、.gitignoreがあり、スキャフォールダーは空でないフォルダを拒否、リダイレクト、 または空にすることを提案します。召喚が指定したコマンドを、そのインストール手順を除いて<scratch>/scaffoldで実行し、次にrsync -a --ignore-existing '<scratch>/scaffold/' '<root>/'を実行し、 スキャフォールドの.gitignoreの行をルートのものに追記し、指定されたパッケージを パッケージマネージャーでルートにインストールし(それが実行される唯一の場所です)、 何よりも先に終了コード 0 を出力するビルドを 1 回実行します。 - トークン: インク、トーンロール(フィールド全体の背景、テキスト、ボタン、フォーカスを設定する クラス)、流動的なタイプスケール、スペーシング、4 つか 5 つの duration、名前付きイージング。
- コンテンツモデル: すべての可視テキストを、すべての言語で、型付きコンテンツファイルに、 実務的な事実(連絡先、法務、エリア)の単一のソースとともに。ビューにコピーはありません。 それが、クライアントが後で AI を使ってサイトを編集できるようにするものです。
- 共有コンポーネント: レイアウト(メタデータ、代替、構造化データ、フォント)、ヘッダー、 フッター、モバイルのコールトゥアクションバー、リビール付きのレスポンシブ画像、 すべての内部ページが再利用するページヘッダー。
- すべてのルート、ファンアウトの前に: すべての言語のすべてのページのルートファイル。 それぞれが空のコンテンツファイルでそのページのビューをレンダリングし、すべてのページが ヘッダーからリンクされるようにします。これにより、各クローンのルートが最初の実行から ビルドおよびキャプチャできるようになります。
- シグネチャサーフェス: ホームページと 1 つのシグネチャインタラクション、すべてを決める
サーフェス。それをキャプチャし(
references/evidence.md)、キャプチャが示すものを修正し、 再度キャプチャします。2 パスで、次に進みます。
プレーンな HTML と CSS について(ビルドステップなし): build.cmd: 'true'、build.static: '.'、
build.link: [] を渡します。各ページの HTML ファイルがそのビューであり、そのコピーを保持するため、
コンテンツモデルのルールは適用できず、レポートはそのように述べます。ヘッダーとフッターを
ホームページに 1 回書き、ファンアウトの前にすべてのルートファイルにそのままコピーします。
それらへの変更は、すべてのページに適用する共有変更リクエストです。
.bunshin/owners.json を書き、すべてのオーナーを含めます。1 ページにつき 1 オーナー
(そのビュー、そのコンテンツファイル、そのコンポーネントフォルダ)、複数のページで使用される
すべてのものには shared、ルートファイルも含め、ホームページのオーナーはファンアウトが
終わるまではあなたです。そのすべてを review.js と verdict.js に渡します。build.js には
自分でビルドしなかったページオーナーのみを、それぞれのミッションとともに渡します。
refine.js には修正があるオーナーのみ、またはそのファイルに触れる決定ファイルのルールを渡します。
7. CLONES - ページ、並列で
build.js を root、パケット(絶対パスで最初に読むもの: PRODUCT.md、コントラクト、
品質フロア、デザインシステム、あなたがビルドしたホームページ。規約。テーゼのルール。
ボイス。アセットフォルダとそのインデックス)、ミッション付きのページオーナー、そして
build とともに実行します。build は次のとおりです。
フレームワークのバイナリを cmd として(型チェックがある場合は check も)、解決された絶対
scratch、静的出力フォルダを static として、shoot.mjs の絶対パスを shoot として、
そして各オーナーのルート。これにより、すべてのクローンが自身のコピーから自身のページを
キャプチャし、戻る前にそれを確認します。優れたブリーフの解剖はオーケストレーションモジュールに
あります。クローンは自分のブリーフが言うことだけを知っています。
クローンが戻ったら: すべての shared_change_requests エントリを読み、成立するものを適用し
(この時点で共有ファイルはあなたが所有します)、クライアント向けの未解決の質問を記録します。
8. PROVE - レビューの前に
load_ref orchestration references/evidence.md。次の順に実行します。
- ビルドと型チェックをそれぞれ実行し、終了コード 0 が出力されることを確認します。Impeccable がインストールされている場合は、
<dir>/scripts/impeccable detect --json <source folders>を実行します。続いて、tells 監査を実行します(1 回のシェル呼び出しで、skill-base ブロックを再出力してから、python3 "$SKILL_BASE/design-audit/scripts/audit.py" . --group tellsを実行します)。また、thesis で許可されていない場合は、U+2014 の grep を実行します。 shoot.mjsで、すべてのページと言語を撮影します。標準の撮影リストを使い、ページと言語ごとに撮影ファイルを 1 つ用意して 1 回ずつ呼び出し、.bunshin/captures/round-1/に保存します。Impeccable がある場合は、finish reviewer が必要とする 2 枚の撮影も追加し、分割せず、それぞれ指定のファイルに直接保存します。{ "path": "/", "w": 1440, "h": 900, "full": true, "out": "<root>/.impeccable/review/desktop.png" }同じ設定でサイズを 390x664 にしてmobile.pngに保存し、すべての PROVE で同じrevealを使います。判定時に、verdict がこれらの正確なパスを再び読み込むためです。最初の画面は自分でも確認します。- 成果につながる経路(メニュー、スティッキーバー、フォームへの選択内容の反映、フォームの各ステップ、エンドポイントの失敗と成功)に対する機能テストを実施し、それぞれ測定値を報告します。
レビュー前に問題を修正します。ビルドが壊れた状態で 5 つのレンズを使っても、その 5 つは無駄になります。合格した項目は、すでに検証済みとしてパケットに記載します。
9. REVIEW - 独立したレンズ
エビデンスパケット、ラウンド、ティアのレンズ、モジュールディレクトリ($SKILL_BASE/mobile-principles、desktop-principles、motion-principles。いずれも絶対パス)、owners.json に記載されたすべての担当者を指定して review.js を実行します。planOut は <root>/.bunshin/reviews/round-<N>.json に設定します。N はこのレビューが開始するラウンドです(初回は 1、再ビルド後は次のラウンド)。Impeccable があり、ホストがそのエージェントタイプを一覧表示している場合は、finishAgent にホストが Impeccable の finish reviewer に付けた名前を設定します(Claude Code の場合は impeccable-finish-reviewer)。Impeccable の指示どおり、エージェントは新規に起動します。定義をプロンプトに貼り付けてはいけません。Impeccable がインストールされていても、ホストがそのエージェントタイプを一覧表示していない場合は、代わりに finishRole に reference/degraded/finish-reviewer.md の絶対パスを設定し、その旨をレポートに記載します。
最初に finish disposition を確認します。recapture の場合は、問題はビルドではなくエビデンスにあります。recapture リストに記載されたものを再撮影してからレビューを再実行します。このラウンドはカウントしません。disposition がない場合(finish reviewer が 2 回続けて何も返さなかった場合)も、同じ扱いとします。rebuild の場合は、指定された領域を自分で再ビルドしてから、レビューをもう一度、最初から実施します。このラウンドは、ティアの refine ラウンドの 1 つとしてカウントします。fix または ship の場合は、プランと却下リストを確認します(検証済みの方針に反する却下はプラン側で判断し、実際の不具合を却下している場合は自分で覆します)。そのうえで、refine の前に orchestrator の修正を自分で適用します。
10. REFINE - ループ
各ラウンドでは、ラウンド 1 から次の手順を実行します。
refine.jsを実行します。引数はroot、パケット(PRODUCT.md、契約、品質の最低基準。絶対パスを指定)、planPath(ラウンド 1:レビューの計画ファイル。以降のラウンド:直前の判定が書き出した計画)、decisions(ラウンド 2 以降:直前の決定ファイル)、修正または決定を適用するオーナー、内容がある場合はshared(最初に単独で実行されます)、フェーズ 7 と同じbuildです。結果は.bunshin/reviews/round-N-refine.jsonに書き込みます。- もう一度検証します:チェックを実行し、新しいキャプチャを
.bunshin/captures/round-<N+1>/に保存して、.impeccable/review/の 2 つのキャプチャも同じファイルで撮り直します。 - 新しいパケット、
history(ラウンドの計画ファイル、そのラウンドの修正結果、決定ファイル)、round、すべてのオーナー、<root>/.bunshin/reviews/round-<N+1>.jsonを設定したplanOut、レビューと同じfinishAgent、およびティアの指定に応じたfreshEyes: trueを指定してverdict.jsを実行します。さらに、対象者がサイトとどのように出会うかを一文で説明するシナリオを添えます。残っている指摘をもとに、最終レビュー担当者が次のラウンドの計画を書き出します。残件がなければ、修正リストは空になります。結果は.bunshin/reviews/round-N-verdict.jsonに書き込みます。 - 判定が新鮮な目で行われ、ループを続ける場合は、そのメモを自分で決定事項に変換します(停止ルールによってループを終了する場合は、メモをレポートに記載します)。保存先は
.bunshin/decisions/round-N.mdです。次のラウンドで全体に適用するルールを記述します(各ヒーロー画像の役割、彩度の高い色を使ってよい場所、文字の役割、コントロールの形状、変更する共有契約など)。メモをクローンにタスクリストとして渡してはいけません。計画にあるorchestratorの修正は自分で適用します。 - 停止ルール(オーケストレーションモジュール)を適用します。まず処置を確認します:
recaptureは再撮影して判定を再実行し、rebuildはレビューに戻ります。その後、minor を超える指摘が残っていなければ納品し、ティアのラウンド上限に達したら停止し、ラウンドで何も修正されなかった場合も停止します。それ以外の場合は、次のラウンドを手順 1 から開始します。
ティアの上限を超えるには、残件の一覧をユーザーに提示したうえで、ユーザーの許可を得る必要があります。
11. SEAL - ドキュメント作成、監査、レポート
- DESIGN.md:ホストが指定するエージェントタイプで Impeccable のドキュメント作成担当を起動し(Claude Code の場合は
impeccable-documenter)、プロジェクトルート、成果物のパス(ソースフォルダーとビルド済み出力)、方向性の契約、PRODUCT.md、Impeccable のreference/document.mdの絶対パス、書き込み範囲(プロジェクトルート)を渡します。納品済みコードをもとに DESIGN.md と.impeccable/design.jsonを作成します。Impeccable を使わない場合は、意図ではなく納品済みコードをもとに、自分で DESIGN.md を作成します。 - AGENTS.md(参照先として
CLAUDE.mdを用意):サイトを保守する AI 向けに、クライアントの言語で作成します。変更の種類ごとに手を加える場所、デザインルール、文章作成ルール、コマンド、プッシュ前に確認する項目を記載します。 - ローンチガード:不足している事実(連絡先、法的情報、ドメイン)をすべて列挙するビルド時の警告を設け、厳格モードでは本番ビルドを失敗させます。
- 以下に記載する監査を、プロジェクト全体に対して実行します。
- 以下に記載するレポートを
.bunshin/report.mdにも書き込みます。
このパイプラインの締めくくりの手順は、以前は 25 個のチェック項目で構成されており、そのいくつかはエージェントが実行できないツールを指定していました。Chrome を開かずに「Chrome DevTools で 60fps を確認済み」にチェックを付けると、「確認していない」が「確認した結果、問題なし」にすり替わります。何も書かないより、かえって悪い結果です。
そのため、チェック項目を 2 つのグループに分けます。最初のグループは、使用した証拠とともに報告してください。2 つ目のグループには一切チェックを付けず、引き継ぎます。
ここで証拠を添えて確認
各項目は チェック項目 - 判定 - 証拠 の形式で報告します。証拠には、実行した grep、計算した値、または確認した file:line を記載します。証拠のない判定は所見とは見なされません。確認できなかった項目は、合格ではなく未確認として報告します。
- コードに対する主張。 まず、以下のすべてのチェックでは、検証対象となった主張がコードに記されていることを前提としています。検証された主張が実際に掲げている約束(時間、イージング、スプリング、カラーパレット、タイポグラフィ、レイアウトの種類)ごとに、その根拠となる
file:line、または「見つからない」を示してください。カラーパレットやタイポグラフィについて約束していない主張、つまりインタラクションだけに関する主張には、カラーパレットやタイポグラフィの行は不要です。file:lineのない約束は合格ではなく、発見された問題です。正直な格下げ:約束したモーションを動作する形でリリースできない場合は、静的なバージョンをリリースし、その旨をここに記し、取り下げた約束を明記してください。これは発見された問題として扱います。書面上の約束を守るために、半端に壊れたモーションをリリースしてはいけません。 証拠:約束ごとに1行。例:hover 180ms ease-out - src/Card.tsx:42。 - モーションの軽減に対応。 Web:アニメーションを実際に軽減する
prefers-reduced-motionブロックがあること。空のブロックでは不十分です。SwiftUI:accessibilityReduceMotion。Compose:ValueAnimator.areAnimatorsEnabled()/Settings.Global.ANIMATOR_DURATION_SCALEによるヘルパー。 証拠:ガードがあるファイルと行、および軽減後の動作。 - 終了アニメーション:アンマウントされる箇所すべてにあること。 証拠:条件付きレンダーとその終了経路、または終了アニメーションがないアンマウント箇所の一覧。
- レイアウトプロパティをアニメーションしない。
width、height、top、left、margin、paddingをアニメーションするものがないこと。代わりに transform、opacity、またはgraphicsLayerを使用します。 証拠:grep の結果と該当箇所、または該当なしの結果。 - すべてのインタラクティブ要素でフォーカスが見えること、また代替手段のない
outline: noneがないこと。 証拠:grep の結果。 - インタラクティブ要素に5つすべての状態があること: デフォルト、ホバーまたは押下、フォーカス、アクティブ、無効。 証拠:コンポーネントごとに見つかった状態と、欠けている状態。
- マジックナンバーではなくトークンを使う。 色とスペーシングは、プロジェクトのデザイントークン(存在する場合は MASTER.md)から取得します。
証拠:該当する値と
file:line。 - コントラスト比:本文テキストは4.5:1以上、大きなテキストとUIの境界は3:1以上。
計算してください。 出力したトークン値から計算し、色見本を目視で判断してはいけません。
証拠:色の組み合わせと計算した比率。例:
#831843 on #FDF2F8 = 9.4:1。 - セマンティクス。 Web:ロールのないクリック可能な
divがないこと。装飾的なモーションにはaria-hiddenを設定すること。Compose:カスタムのインタラクティブコンポーネントにModifier.semanticsを設定すること。SwiftUI:テキストのないコントロールには.accessibilityLabelを設定すること。 証拠:grep の結果。 - Web のみ。 条件付きレンダーは
AnimatePresenceまたはフレームワークの同等機能でラップすること。will-changeは必要最小限に使い、アニメーション後に削除すること。 証拠:grep の結果。 - 主張と照らし合わせて指摘事項を確認。
tellsが読み込まれている場合のみ実施します。1回のシェル呼び出しで、スキルベースのブロックを再出力し、design-auditが読み込まれているかどうかにかかわらず、python3 "$SKILL_BASE/design-audit/scripts/audit.py" . --group tellsを実行します。 証拠:各指摘について、問題として残した場合はそのfile:line、または主張のAllowed patterns:行で該当項目を示します。残した指摘は発見された問題として数えます。許可されたものは「主張により許可」と記載し、該当項目を引用します。これは問題として数えません。tellsリストを手作業で確認した結果(div 内の偽の商品、繰り返されるレイアウトの種類、隅に浮かぶ段落、コピーの文体、JavaScript のデータ内に置かれたコピー)も、同じ方法で報告します。 各指摘の結果は、必ず次の3種類のいずれかです。4つ目はありません。主張により許可:該当するAllowed patterns:の項目を引用します。この指摘には該当しない:検出内容が項目自体のマーカーと矛盾する場合に限ります(ループが実際のローディング状態を示している、ぼかしがモーダルの背景である、該当行が表示テキストではないなど)。それを証明するfile:lineを示し、好みの問題には決して使いません。または 問題。報告する前に修正します。ただし、この実行で加えた変更のみが対象です。この実行で記述した行にある問題(プロジェクトにgit diffがある場合はそれを確認してください)は削除または書き換え、その後このチェックを再実行します。最大2回まで実施し、それでも残る問題はfile:lineとともに報告します。プロジェクトに以前から存在し、この実行で記述していない行にある指摘は、ここでは変更しません。ユーザー向けに一覧として記載します。既存プロジェクトの保護対象リスト(公開トークン名、URL、ナビゲーションラベル、フォームフィールド名、ロゴ、法的な記載事項)は、この手順で変更しません。
ここにある項目は必ず実行してください — この環境では未検証です
エージェントはプロファイラーを開いたり、デバイスに接続したり、ポインターを動かしたりできません。これらは、正確な実行方法を含む引き継ぎブロックとして報告し、UNVERIFIED と明記します。チェックを付けたり、表現を和らげたり、ほかの項目に問題がなかったからといってこのセクションを省略したりしないでください。
| 対象 | 実行内容 | 合格条件 |
|---|---|---|
| Web | Chrome DevTools > Performance で、操作をまたいで記録する | 16.7ms を超えるフレームがない |
| Web | 375 / 768 / 1024 / 1440 でページを表示する | 横スクロールがなく、コンテンツが切れていない |
| Web | OS の「視差効果を減らす」設定をオンにしてページを表示する | 劣化時のパスが実際に実行される |
| Web | このセッションで Web フォントが描画されなかった場合に、オンラインでページを表示する | フォールバックではなくフォントが読み込まれ、論旨が依拠する数値とウェイトが適用される |
| Compose | Layout Inspector > Component Tree > View Options > Show Recomposition Counts | スクロール中もカウントが安定している |
| Compose | ミドルレンジのデバイスで androidx.benchmark.macro Macrobenchmark を実行する | 60fps でフレーム時間が 16.67ms 未満、120fps で 8.33ms 未満 |
| SwiftUI | Instruments > Animation Hitches | トランジション中にヒッチが発生しない |
| SwiftUI | 「視差効果を減らす」をオンにし、Dynamic Type を 200% にする | コンテンツが切れず、動きだけに依存する要素もない |
| macOS | すべてのインタラクティブ要素にポインターを重ね、ビュー全体をキーボードで操作する | ホバー状態が動作し、フォーカスリングが表示され、ショートカットが割り当てられている |
プレビューまたは開発サーバーがすでに起動していて、ユーザーの同意がある場合は、ブラウザーを操作して Web の項目を確認するほうが、ユーザーに引き継ぐより望ましいです。監査のためだけに起動してはいけません。また、そのために何かをインストールしてはいけません。
2 つのグループは、件数を添えて別々に報告してください。「11 件を確認、2 件の問題を発見、8 件を引き継ぎ」は正直な監査報告です。チェック項目を 1 つのリストにまとめるのは適切ではありません。
レポートは必ずモジュールの記載で締めくくり、以下のようにそれぞれ独立した 2 行にしてください。
Modules loaded: motion-principles, framer-motion, design-audit
Modules not loaded: none
Modules not loaded には、load_skill の呼び出しで NOT LOADED と報告されたすべてのモジュールと、ロード表で指定されていたのに一度も要求されなかったすべてのモジュールを記載します。両方とも空の場合に限り、none と記載してください。呼び出しの間でシェルの状態は保持されないため、最初のロードから最後のロードまで、この一覧は自分で記録しておいてください。シェルは記憶していません。
最終レポート
簡潔に、次の順序で記載してください。
- 構築内容:言語ごとのルートと、デザインシステムおよび契約が置かれている場所。
- 検証結果と証拠:ビルド、型チェック、検出器、所見、キャプチャ(場所)、測定値を伴う各機能テスト、最後の判定とその対応。
- 未検証項目:監査で引き継いだ項目に UNVERIFIED と明記し、レンズで確認できなかった項目も記載。
- 残件:最後の確認後に残った軽微な点をページごとに記載。
- クライアント向け:
missing.mdとコンテンツファイルにある未確認の事実すべてと、クローンの作成で浮かび上がった未解決の質問。 - コスト:ティア、実施したラウンド数、ワークフローごとのエージェント数、ホストから報告された場合はトークン数。
- 前提。ヘッドレス実行では、
UNVALIDATEDとマークされたすべてのゲート回答も記載。 - 監査に基づく 2 行のモジュール情報。
ユーザーから依頼されるまで、コミット、プッシュ、デプロイは行いません。
危険信号 - このスキルのルールに違反しようとしています
| 考え | 実際 |
|---|---|
| 「ユーザーが全力を尽くせと言ったから、召喚は省略しよう」 | ティアは毎回尋ねます。全力を尽くすのもティアの一つで、代償があります。 |
| 「まず調査しよう。そうすれば質問の質が上がる」 | ティアを尋ねる前に、読み込み以上のことはしません。READ の段階でソースに目を通せば、適切な質問をするには十分です。 |
| 「方向性をどう見せるか聞いてみよう」 | 質問は2つまでで、3つ目はありません。判断ページか、1行で告知したレンダリング済みページのどちらかです。 |
| 「ホームページもクローンに任せよう」 | 代表的な画面はあなたの担当です。すべてのクローンが手本にするものです。 |
| 「2つのクローンでスタイルシートを共有してもいい。各自が1行ずつ書けば済む」 | ファイルごとに担当者は1人です。共有が必要なら依頼します。 |
| 「プロジェクトフォルダーでビルドが成功した。これで十分」 | クローンはコピー上でビルドします。共有ツリーでのビルド成功は、何の証明にもなりません。 |
| 「レンズはコードを見て判断できる。キャプチャには時間がかかる」 | 判断の対象はレンダリング結果です。キャプチャを撮り、最初の画面を読んでからレビューします。 |
| 「仕上げのレビュアーに再キャプチャを指示されたが、計画どおり進めよう」 | 無効な証拠は何も裏付けません。まず再キャプチャします。 |
| 「冷静な目で8つのタスクが挙がった。割り当てよう」 | それらを決定事項ファイルのルールにします。この工程はアートディレクションであり、あなたの担当です。 |
| 「もう1回やれば、残りの小さな点も改善できる」 | 停止ルールに従います。小さな改善点はレポートに記載します。 |
| 「サブエージェントツールがない。自分でクローンを演じよう」 | それでは独立したレビューが行われません。ペイントに切り替えます。 |
| 「Impeccable がインストールされていない。無料だからインストールしよう」 | 許可を尋ねます。断られたら、それに従います。 |
| 「準備ができた。見てもらえるようにプッシュしよう」 | 許可を得ずに、このマシンから何かを外に出してはいけません。 |
クイック判断ツリー
Whole-site request received
|
+- READ: stack, brief, sources, host capabilities, size
| |
| +- smaller than a site, native stack, or no subagents? -> step down (cast / paint)
|
+- SUMMON (gate 1): read, plan, host, Impeccable, stack, cost; tier + product questions
|
+- HARVEST -> RESEARCH (four clones, a synthesis) -> PRODUCT.md
|
+- DIRECTION (gate 2): seven worlds, the draw, cards with both theses; contract; tells
|
+- MATERIAL -> FOUNDATION (yours: scaffold, tokens, content model, shared, routes, signature)
|
+- CLONES: one per page, disjoint files, isolated builds, each capturing its own page
|
+- PROVE -> REVIEW (lenses + plan; recapture? rebuild? read the disposition first)
|
+- REFINE -> PROVE -> VERDICT (+ cold eyes) -> decisions, next plan
| |
| +- stop rule: minor only, round cap, or nothing fixed? -> SEAL
| +- else -> next round
|
+- SEAL: DESIGN.md, AGENTS.md, launch guard, audit, report