Skill(スキル):該当する作業のときだけ読み込まれる一連のやり方

Skill:必要なときだけ読む

1依頼する2Skill の説明と照合3該当 Skill だけ読み込む4手順どおりに実行

Skill は .claude/skills/名前/SKILL.md です。description に「何をするか+ユーザーがどう言うか」を書き、Claude はそれを見て本文を読むか判断するので、普段はコンテキストを使いません。ゲストは下の 5 件の Skill の全文を見られます。

.claude/skills/acceptance-criteria/SKILL.md ダウンロード
---
name: acceptance-criteria
description: "要件・機能の「受け入れ条件」(どうなれば完了で正しいか)を書くときに使う。Given-When-Then で要求をテスト可能な Yes/No の条文にし、1グループ約5条まで、正常系+エラー+境界+権限を網羅し、検証方法を明記する。「受け入れ条件」「完了の基準」「テストケースを書いて」「要件を明確に」と言われたときに発動。"
---

# 受け入れ条件の書き方

## 原則
- よい受け入れ条件は、明確・具体的・テスト可能。2人が読んで同じ「合格/不合格」になる。
- Given-When-Then の形式:Given=操作前の状態、When=ユーザーの操作、Then=見えるべき変化。
- どの条文にも「どうテストするか」に答えがあること。テストできないなら書き直す。「速いこと」は「通常の回線で3秒以内に開く」にする。
- 1グループは約5条まで。それ以上は複数機能なので分ける。
- 網羅するもの:正常系、エラー状態、境界、権限ルール。各条文は独立で、Yes/No がはっきりしている。
- 結果はユーザーや業務の視点で書き、実装方法は書かない。

## 補足(踏んだ落とし穴)
1. 各条文の後に「検証方法」を書く:自動テスト/ブラウザ自動化(スマホと PC の幅)/人の目が必要/実機が必要。できないものは正直に「未検証」と書く。
2. 「A に B が見えない/A が B に影響しない」(マルチユーザー、言語の分離)には必ず逆のケースを入れる:実際に B の身分で試す。
3. 数値化できるものは数値化する:横スクロールなし=`scrollWidth <= clientWidth`。公開後は `curl` で 200 を確認。
4. 自動化できるものはテストスクリプトに入れ、変更のたびに実行する。

## ひな形
```
機能:<名前>
受け入れ条件(5条まで):
1. Given <状態> When <操作> Then <結果> 検証:<方法>
2.(エラー)Given … When … Then …
3.(境界)…
4.(権限・分離)Given ユーザー甲と乙 When 乙がログイン Then 甲のデータは見えない 検証:自動テスト(2セッション)
```

## 例:マルチユーザー
1. Given ユーザー甲にお気に入りがある When 乙がログイン Then 乙のお気に入りは空 検証:自動テスト
2. Given 乙が自分の設定を変更した When 甲が再読み込み Then 甲の設定は変わらない 検証:自動テスト
3. Given 未ログイン When 他人のデータ API にアクセス Then 401 が返る 検証:自動テスト
.claude/skills/deploy-verify/SKILL.md ダウンロード
---
name: deploy-verify
description: "Web サイトやサービスの変更を自分のサーバーにデプロイして検証する定型手順:バックアップ→構文チェック→アップロード→再起動→オンラインで curl 確認→ブラウザで実操作→記録。「デプロイ」「公開」「サーバーに反映」「ロールバック」「サービス再起動」と言われたときに使う。迷ったらデプロイせず、先にユーザーに確認する。"
---

# デプロイ+検証の手順(全ステップ実施、飛ばさない)

まずプロジェクトの `CLAUDE.md` に、サーバーのアドレス、デプロイ先ディレクトリ、サービス名、ドメインを書く。なければユーザーに聞く。推測しない。

1. **バックアップ**:`ssh <サーバー> "mkdir -p <ディレクトリ>/.bak_<日付> && cp <変更するファイル> <ディレクトリ>/.bak_<日付>/"`。ロールバック=コピーを戻して再起動。
2. **構文チェック**:Node は `node --check <ファイル>`、Python は `python -m py_compile <ファイル>`。フロントエンドの JS を変えたら、ページ内でそれを参照している `?v=` のバージョンを1上げる(キャッシュ回避)。参照している親ファイルも上げる。
3. **アップロード**:該当ディレクトリへ `scp`。nginx を変える前にバックアップし、`nginx -t` が通ってから `systemctl reload nginx`。自分の server/location だけを追加し、他人のものは触らない。
4. **再起動**(バックエンドを変えたときだけ):`systemctl restart <サービス名> && systemctl is-active <サービス名>`。
5. **オンライン検証**:`curl -s -o /dev/null -w "%{http_code}" <URL>` で主要な URL(トップ、API、追加した画像や静的ファイル。1つでも 404 なら同じディレクトリの他のファイルも確認)を調べ、さらにブラウザ自動化で実際に操作する。
6. **報告**:「未テスト」の部分(スマホ実機、同時アクセスなど)を明記する。テストしていないものを「検証済み」と書かない。
7. **記録**:プロジェクトの `CLAUDE.md` に3〜5行(変更内容、バックアップ先、未テストの点)。

## 越えてはいけない線
- 本番データは**自分で作った**テスト用レコードだけを削除する。テーブル全体の DELETE や全消去は禁止。
- 他のプロジェクトの nginx 設定には触れない。
- パスワードやトークンを skill、返信、git に書かない。キーは `secrets/*.env`(`.gitignore` に入れる)に置き、実行時はサーバー上の環境変数が正。
- 重い処理(動画のトランスコード、大きなダウンロード)は一度に1つだけ。先に `free -m` でメモリを見る。
- 迷う、問題がありそうなときは、デプロイせずユーザーに確認する。
.claude/skills/skill-writer/SKILL.md ダウンロード
---
name: skill-writer
description: "新しい skill を書く、または既存の skill を改善する手順:書く価値があるかの判断、分け方(入口 SKILL.md+必要時に読む子ファイル)、description への発動語の書き方、サイズの抑え方。「skill を書いて」「これを skill にして」「skill が発動しない」「skill が大きすぎる」と言われたときに使う。"
---

# skill の書き方

## 0. まず書く価値があるか判断する
価値あり:同じ種類の作業を2回以上やり、手順が固定している。落とし穴をチェックリストにできる。再利用できるスクリプトがある。
価値なし:1回きり。すでに rule やコマンドでカバーされている。リンクの寄せ集めだけ(リンクは検索も発動もできないので、要点は本文に書く)。

## 1. 構造
- 1つの skill=1つのフォルダ。入口は `SKILL.md`、冒頭に `name`(フォルダ名と同じ)と `description`。
- 簡単なものは SKILL.md 1つで足りる。複雑なものは、入口に「ルーティング+重要ルール」だけを置き、詳細は `references/*.md`、固定の動作は `scripts/*.py` に分け、本文に「いつどのファイルを読むか」を書く。
- スクリプトはブラックボックスとして扱う:本文に「まず --help を実行し、ソースは読まない」と書く。

## 2. description が発動するかどうかを決める
- 1段落で「何をするか+ユーザーがどう言うか」を書く。ユーザーが実際に使う言葉を並べる。
- 発動させたくない場面も書く。
- 約600文字以内。

## 3. サイズ
入口の SKILL.md は5KB以下が目標、上限は12KB。超えたら references に分ける。

## 4. 書いたら必ずやること
1. 実際のタスクで一度発動させ、想定どおり動くか確認する。
2. プロジェクトの `CLAUDE.md` に skill 名を1行記録する。
3. キーやパスワードを skill に入れない(パスは書いてよいが、値は書かない)。

## 5. どこに置くか
- 個人用(全プロジェクト共通):`~/.claude/skills/<名前>/SKILL.md`
- 特定のプロジェクトだけ:プロジェクト内の `.claude/skills/<名前>/SKILL.md`
.claude/skills/web-standards/SKILL.md ダウンロード
---
name: web-standards
description: "Web サイト/ページを作る・変更する前に読む:業界で一般的なやり方に従う(アクセシビリティ WCAG、レスポンシブ、フォーム、パフォーマンス、設定ページの慣例)。一般的なやり方から外れる場合は設計書に書く。「ページを作って」「サイトを直して」「見た目がよくない」「スマホの表示がおかしい」「設定はどこに置く」と言われたときに使う。"
---

# Web の一般標準(簡易版)

基本は業界で一般的なやり方に従う。外れるときは、プロジェクトの `DESIGN.md` に「なぜそう設計したか」を書く。

## レイアウトとレスポンシブ
- `<meta name="viewport" content="width=device-width, initial-scale=1">` は必須。
- コンテナに固定ピクセル幅を使わない。flex の子要素には `min-width:0` を付けて飛び出しを防ぐ。長い文は `overflow-wrap:anywhere`。
- 表やコードブロックは横スクロールできる入れ物に入れ、ページ全体に横スクロールバーを出さない。
- 変更後は2つの幅(約390と1400)で `scrollWidth <= innerWidth` を実測する。

## アクセシビリティ(WCAG 2.2 の主な点)
- 本文のコントラスト比は 4.5:1 以上。色だけで状態を表さない。
- クリックできる要素はすべてキーボードで到達でき、フォーカスが見える。ターゲットは 24px 以上(スマホでは 44px 推奨)。
- 画像には alt、フォームの入力には label、エラーメッセージには原因と直し方を書く。
- ダイアログ:Esc で閉じられる。開くときフォーカスが中に入り、閉じたら呼び出し元に戻る。

## フォームと操作
- 1ページに主な操作は1つ。危険な操作(削除)は結果を示した二重確認を入れる。
- ユーザーが入力した内容を消さない。送信時はボタンを無効にして二重送信を防ぐ。

## 設定ページの慣例
- 順序:よく使うもの → 外観・言語 → アカウント・データ → このアプリについて(バージョンと更新)。
- 「このアプリについて」にバージョン番号と更新の入口を置く。

## パフォーマンスとキャッシュ
- 画像は圧縮して遅延読み込み。静的ファイルの URL には `?v=` を付け、変えたら上げる。
- デプロイ後は `curl` で主要なリソースが 200 を返すか確認する。
.claude/skills/webapp-testing/SKILL.md ダウンロード
---
name: webapp-testing
description: "Web のフロントエンド/バックエンドを変更したあと、「オンラインで本当に使える」ことを検証する:2つのビューポート(スマホ約390/PC約1400)での横スクロール、コンソールの JS エラー、主要な流れの実操作、スクリーンショットをプロジェクトのフォルダへ保存。「テストして」「検証して」「スマホの表示がおかしい」「変更後にオンラインを確認」「Playwright」「スクリーンショット」と言われたときに使う。"
---

# Web 検証(オンライン優先)

## 手順
Playwright(`pip install playwright && playwright install chromium`、または Node 版)で**本物の URL**に対して実行する:

1. 2つのビューポートでそれぞれ1回開く:`390×844`(スマホ)と `1400×900`(PC)。
2. ページが落ち着くまで待つ(`wait_for_load_state('networkidle')`)。
3. 横スクロールを測る:`document.documentElement.scrollWidth > innerWidth` ならはみ出し。
4. `console` の error を集め、件数と最初の5件を挙げる。
5. 主要な流れ(ログイン、送信、言語切替など)を一通り操作する。セレクタは id かテキストを優先。
6. スクリーンショットを撮り、**プロジェクト自身のフォルダ**にフルパスで保存する。

最小の例(Python):
```python
from playwright.sync_api import sync_playwright
URL = "https://あなたのURL/"
with sync_playwright() as p:
    b = p.chromium.launch(headless=True)
    for name, w, h in [("phone", 390, 844), ("pc", 1400, 900)]:
        pg = b.new_page(viewport={"width": w, "height": h})
        errs = []
        pg.on("console", lambda m: errs.append(m.text) if m.type == "error" else None)
        pg.goto(URL); pg.wait_for_load_state("networkidle")
        sw = pg.evaluate("document.documentElement.scrollWidth")
        print(name, "scrollWidth", sw, "viewport", w, "overflow" if sw > w else "ok", "errors", len(errs))
        pg.screenshot(path=f"/フル/絶対/パス/{name}.png")
    b.close()
```

## 必ず守ること
1. スクリーンショットはプロジェクトのフォルダにフルパスで保存し、ルートディレクトリに散らかさない。
2. ユーザーの実データを変えない:テストデータは自分で作って自分で消し、テーブル全体の DELETE は禁止。
3. ローカルで通る=オンラインで使えるではない:デプロイ後に本物の URL でもう一度実行する。新しい画像などのバイナリは `curl` で1つずつ 200 を確認する。
4. スマホ実機の操作感、マイク、画面向きのロックはスクリプトでは測れない。報告には「未テスト:…」と書き、「検証済み」と書かない。

ログイン後に追加される Skill