
Claude Code Reference
- 8 installs
- 1 repo stars
- Updated August 2, 2026
- fandhe-ai/agent-cli-skills
Helps with ai & agent building tasks.
About
claude-code-reference is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- claude-code-reference
- AI & Agent Building
- AI-coding skill
Claude Code Reference by the numbers
- 8 all-time installs (skills.sh)
- Ranked #12,339 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/fandhe-ai/agent-cli-skills --skill claude-code-referenceAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 8 |
|---|---|
| repo stars | ★ 1 |
| Last updated | August 2, 2026 |
| Repository | fandhe-ai/agent-cli-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
claude-code-reference
Claude Code 本体の公式仕様を要約した知識ベース。 このリポジトリで skill / agent / rule / hook / settings を著作する際のリファレンスとして使用する。 GitHub 側の仕様は github-docs スキルを参照(重複させない)。
探索手順
1. ユーザーのタスクに最も関連するトピックを下の索引から特定する 2. 該当する reference/<topic>.md を読む 3. 実装の雛形が必要なら sample/ を、実行コマンドが必要なら script/ を参照する 4. 関連トピックがあればリンクを辿る
reference/ の索引
| タスク例 | 参照ファイル |
|---|---|
SKILL.md を書く・frontmatter を設定する・description にトリガー語を入れる | reference/skills.md |
context: fork でサブエージェント実行・allowed-tools の設定 | reference/skills.md |
.claude/agents/ にサブエージェントを定義する・tools/model/permissionMode を指定 | reference/subagents.md |
| subagent_type でサブエージェントを呼び出す | reference/subagents.md |
hooks を設定する・PreToolUse/PostToolUse/SessionStart などのイベント | reference/hooks.md |
| hook の JSON 出力・exit code・stdin 入力フォーマット | reference/hooks.md |
settings.json / settings.local.json を編集する | reference/settings.md |
permissions.allow / permissions.deny を設定する | reference/settings.md |
env で環境変数を設定する・enabledMcpjsonServers を指定 | reference/settings.md |
| スラッシュコマンドを調べる・カスタムコマンドを作る | reference/slash-commands.md |
MCP サーバーを追加・設定する・.mcp.json を書く | reference/mcp.md |
MCP ツール名の命名規則 mcp__server__tool | reference/mcp.md |
CLAUDE.md を書く・メモリ階層を理解する・@import を使う | reference/memory.md |
.claude/rules/ でパス別ルールを設定する | reference/memory.md |
sample/ と script/ の案内
sample/── 動作実例(各機能の最小動作サンプル)script/── 実行可能コマンド集(hook スクリプト・設定生成ユーティリティ等)
更新方法
公式ドキュメントの URL が変更された場合や仕様更新を反映する場合は、 update-reference スキルで各 reference/*.md を再取得・更新する。 各ファイル冒頭の <!-- source: <URL> --> と <!-- 最終確認日: YYYY-MM-DD --> を更新すること。
検証
reference/*.md を追加・更新した後、以下で整合を確認する。
# 索引に記載されたファイルが実在するか確認
ls skills/claude-code-reference/reference/- SKILL.md の索引テーブルの各行に対応する
reference/<topic>.mdが存在すること - 各ファイル先頭に
<!-- source: ... -->と<!-- 最終確認日: ... -->があること - 索引に未掲載のファイルがあれば SKILL.md の索引テーブルに追記すること
<!-- source: https://code.claude.com/docs/en/hooks --> <!-- 最終確認日: 2026-06-06 --> <!-- ✅ 取得済み(WebFetch による公式ドキュメント取得) --> <!-- 取得状況: ✅ 取得済み -->
Hooks リファレンス
概要
Hooks は Claude Code のライフサイクルの特定時点で実行されるシェルコマンド/HTTP リクエスト/MCP ツール呼び出し。ツール実行のブロック・許可・変更、環境変数の注入、外部システムへの通知などに使用する。
重要: CLAUDE.md の指示はソフトガイダンス(Claude が従うかどうかは判断次第)。フックは確定的に実行される。強制が必要な動作にはフックを使う。
---
フックイベント一覧
セッションフック
| イベント | 説明 | ブロック可能 |
|---|---|---|
SessionStart | セッション開始・再開時。matcher: startup/resume/clear/compact | No |
Setup | --init-only/--init/--maintenance フラグ起動時。matcher: init/maintenance | No |
SessionEnd | セッション終了時 | No |
ターンフック
| イベント | 説明 | ブロック可能 |
|---|---|---|
UserPromptSubmit | Claude がプロンプトを処理する前(30秒タイムアウト) | Yes |
UserPromptExpansion | コマンドがプロンプトに展開される時 | Yes |
Stop | Claude が応答を終了した時 | Yes |
StopFailure | API エラーでターン終了 | No |
エージェントループフック
| イベント | 説明 | ブロック可能 |
|---|---|---|
PreToolUse | ツール実行前(ブロック可能) | Yes |
PostToolUse | ツール成功後 | No |
PostToolUseFailure | ツール失敗後 | No |
PostToolBatch | 並列ツール呼び出しの完了後 | Yes |
PermissionRequest | 許可ダイアログ表示時 | Yes |
PermissionDenied | ツール呼び出し拒否時 | No |
非同期イベント(ノンブロッキング)
| イベント | matcher の対象 |
|---|---|
FileChanged | リテラルファイル名(監視ファイル) |
CwdChanged | — |
ConfigChange | user_settings/project_settings/local_settings/policy_settings/skills |
Notification | permission_prompt/auth_success/elicitation_dialog |
MessageDisplay | — |
エージェント・タスクフック
| イベント | matcher の対象 |
|---|---|
SubagentStart | エージェント名(general-purpose/Explore/カスタム名) |
SubagentStop | エージェント名 |
TeammateIdle | — |
TaskCreated | — |
TaskCompleted | — |
命令・ワークスペースフック
| イベント | matcher の対象 |
|---|---|
InstructionsLoaded | session_start/nested_traversal/path_glob_match/include/compact |
PreCompact | manual/auto |
PostCompact | — |
WorktreeCreate | — |
WorktreeRemove | — |
MCP・Elicitation フック
| イベント | matcher の対象 |
|---|---|
Elicitation | MCP サーバー名 |
ElicitationResult | MCP サーバー名 |
---
設定ファイル構造
配置場所と優先度
1. Managed policy settings(組織管理者、最高優先度) 2. Plugin hooks/hooks.json 3. .claude/settings.local.json(プロジェクト、非共有) 4. .claude/settings.json(プロジェクト、共有) 5. ~/.claude/settings.json(ユーザー) 6. スキル/エージェントの frontmatter(コンポーネントスコープ)
すべてのレベルのフックがマージされる(上位が下位を上書きしない)。
基本設定スキーマ
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash|Edit",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/validate.sh",
"timeout": 30,
"statusMessage": "バリデーション中..."
}
]
}
],
"SessionStart": [
{
"matcher": "startup|resume",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/load-context.sh"
}
]
}
]
},
"disableAllHooks": false
}---
matcher パターン
| matcher 値 | 評価方法 | 例 |
|---|---|---|
"*"・""・省略 | 全マッチ | 常に発火 |
文字・数字・_・`\ | ` のみ | 文字列または `\ |
| その他の文字を含む | JavaScript 正規表現 | ^Notebook・mcp__memory__.* |
MCP ツールのパターン: mcp__<server>__<tool>
{"matcher": "mcp__memory__.*"} // memory サーバーの全ツール
{"matcher": "mcp__.*__write.*"} // 全サーバーの write 系ツール---
フックハンドラータイプ
1. Command フック(最も一般的)
{
"type": "command",
"command": "/path/to/script.sh",
"args": ["arg1"],
"timeout": 30,
"statusMessage": "処理中...",
"if": "Bash(rm *)",
"once": false,
"shell": "bash"
}パスプレースホルダー(自動置換):
${CLAUDE_PROJECT_DIR}── プロジェクトルート${CLAUDE_PLUGIN_ROOT}── プラグインインストールディレクトリ${CLAUDE_PLUGIN_DATA}── プラグイン永続データディレクトリ
環境変数(フック内で利用可能):
CLAUDE_PROJECT_DIRCLAUDE_ENV_FILE──SessionStart等で環境変数を永続化するファイルパス(append モード)CLAUDE_EFFORT── effort レベルCLAUDE_CODE_REMOTE── リモート Web の場合"true"
2. HTTP フック
{
"type": "http",
"url": "http://localhost:8080/hooks/validate",
"headers": {"Authorization": "Bearer $API_TOKEN"},
"allowedEnvVars": ["API_TOKEN"],
"timeout": 30
}2xx レスポンスを処理。非 2xx はノンブロッキングエラー(実行継続)。
3. MCP Tool フック
{
"type": "mcp_tool",
"server": "security_server",
"tool": "scan_file",
"input": {"file_path": "${tool_input.file_path}"},
"timeout": 60
}4. Prompt フック
{
"type": "prompt",
"prompt": "このコマンドは安全ですか?引数: $ARGUMENTS",
"model": "claude-opus-4-1",
"timeout": 30
}5. Agent フック(実験的)
{
"type": "agent",
"prompt": "この操作のセキュリティを検証する: $ARGUMENTS",
"timeout": 60
}共通フィールド
| フィールド | 型 | 説明 |
|---|---|---|
type | string | 必須: command/http/mcp_tool/prompt/agent |
if | string | 条件(ツールイベントのみ): Bash(git *)/Edit(*.ts) 等 |
timeout | number | タイムアウト秒数 |
statusMessage | string | スピナーメッセージ |
once | boolean | セッションで一度だけ実行(スキル/エージェント限定) |
---
フック入力フォーマット(stdin / HTTP body)
すべてのフックが受け取る共通フィールド:
{
"session_id": "abc123",
"transcript_path": "/path/to/transcript.jsonl",
"cwd": "/current/working/directory",
"permission_mode": "default",
"hook_event_name": "PreToolUse",
"effort": {"level": "high"},
"agent_id": "subagent-id",
"agent_type": "Explore"
}イベント別の追加フィールド:
// PreToolUse / PostToolUse
{"tool_name": "Bash", "tool_input": {"command": "npm test"}}
// UserPromptSubmit
{"prompt": "ファクトリアルを計算する関数を書いて"}
// SessionStart
{"source": "startup|resume|clear|compact", "model": "claude-sonnet-4-6"}---
exit code と出力
| コード | 意味 | JSON 処理 |
|---|---|---|
0 | 成功 | stdout の JSON を解析 |
2 | ブロッキングエラー | JSON 無視、stderr 表示、アクションをブロック |
| その他 | ノンブロッキングエラー | stderr をトランスクリプトに表示、継続 |
stdout は JSON のみ(周囲のテキスト不可):
{
"continue": true,
"suppressOutput": false,
"systemMessage": "警告: 危険な操作",
"decision": "block",
"reason": "ブロック理由",
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "DB への書き込みは禁止",
"additionalContext": "Claude への追加情報"
}
}PreToolUse での決定コントロール:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow|deny|ask|defer",
"permissionDecisionReason": "監査ログメッセージ",
"updatedInput": {"command": "修正されたコマンド"}
}
}---
最小例
危険なコマンドをブロック
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"if": "Bash(rm *)",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-rm.sh"
}
]
}
]
}
}#!/bin/bash
# block-rm.sh
COMMAND=$(jq -r '.tool_input.command')
if echo "$COMMAND" | grep -q 'rm -rf'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "rm -rf はブロック"
}
}'
else
exit 0
fi書き込み後にリント
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/lint.sh",
"timeout": 30
}
]
}
]
}
}SessionStart で環境変数を永続化
#!/bin/bash
# load-context.sh
BRANCH=$(git branch --show-current)
if [ -n "$CLAUDE_ENV_FILE" ]; then
echo "export CURRENT_BRANCH=$BRANCH" >> "$CLAUDE_ENV_FILE"
fi
jq -nc \
--arg branch "$BRANCH" \
'{
hookSpecificOutput: {
hookEventName: "SessionStart",
additionalContext: "現在のブランチ: \($branch)",
sessionTitle: $branch
}
}'スキル/エージェント frontmatter でのフック定義
---
name: secure-bash
description: セキュリティチェック付き bash 実行
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "./scripts/validate.sh"
timeout: 30
------
よくある落とし穴
1. stdout に JSON 以外が混じる → シェルプロファイルの出力や echo が混入すると JSON パースが失敗する。 2. exit code 2 で意図せずブロック → PostToolUse はブロック不可(既に実行済み)。 3. matcher が効かない → /hooks で設定を確認。文字列リストに使えない文字があると正規表現として解釈される。 4. フックが無効化されている → "disableAllHooks": true が settings に設定されていないか確認。 5. managed フックは上書き不可 → 組織管理者が設定したフックはローカルで無効化できない。
---
このリポでの使い方
.claude/settings.json # プロジェクト共有フック設定
.claude/settings.local.json # 個人用フック設定(gitignore)
~/.claude/settings.json # ユーザー全体のフック設定`.claude/` 配下の編集: dotclaude-via-temp.md ルールに従い _/dotclaude/ 経由で作業する。
デバッグ: セッション内で /hooks を実行すると全フック設定を閲覧できる(読み取り専用)。
<!-- source: https://code.claude.com/docs/en/mcp --> <!-- 最終確認日: 2026-06-06 --> <!-- ✅ 取得済み(WebFetch による公式ドキュメント取得) --> <!-- 取得状況: ✅ 取得済み -->
MCP サーバー連携 リファレンス
概要
MCP(Model Context Protocol)は Claude Code を外部ツール・データソースに接続するオープン標準。MCP サーバーによってツール・データベース・API へのアクセスが可能になる。
---
MCP ツールの命名規則
MCP ツールは以下の形式で参照される:
mcp__<server>__<tool>
mcp__github__create_issue
mcp__memory__search
mcp__sentry__get_errorsフックの matcher でも同様の形式:
{"matcher": "mcp__memory__.*"} // memory サーバーの全ツール
{"matcher": "mcp__.*__write.*"} // 全サーバーの write 系ツール---
インストール方法
Option 1: リモート HTTP サーバー(推奨)
# 基本
claude mcp add --transport http <name> <url>
# 例: Notion
claude mcp add --transport http notion https://mcp.notion.com/mcp
# Bearer トークン付き
claude mcp add --transport http github https://api.githubcopilot.com/mcp/ \
--header "Authorization: Bearer YOUR_GITHUB_PAT"Option 2: ローカル stdio サーバー
# 基本構文(-- で Claude のオプションとサーバーコマンドを分離)
claude mcp add [options] <name> -- <command> [args...]
# 例: Airtable
claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport stdio airtable \
-- npx -y airtable-mcp-serverstdio サーバーでの `--` の役割: -- の前は Claude のオプション(--transport/--env/--scope)、後はサーバーコマンドと引数。
Option 3: SSE サーバー(非推奨、代わりに HTTP を使用)
claude mcp add --transport sse asana https://mcp.asana.com/sseOption 4: WebSocket サーバー
claude mcp add-json events-server \
'{"type":"ws","url":"wss://mcp.example.com/socket","headers":{"Authorization":"Bearer TOKEN"}}'JSON で直接追加
claude mcp add-json weather-api \
'{"type":"http","url":"https://api.weather.com/mcp","headers":{"Authorization":"Bearer token"}}'サーバー管理コマンド
claude mcp list # サーバー一覧
claude mcp get <name> # 詳細表示
claude mcp remove <name> # 削除
/mcp # セッション内でステータス確認---
.mcp.json フォーマット(プロジェクトスコープ)
プロジェクトルートに配置し、git commit して チームと共有する:
{
"mcpServers": {
"shared-server": {
"type": "http",
"url": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer ${API_KEY}"
}
},
"local-tool": {
"command": "${CLAUDE_PROJECT_DIR}/scripts/mcp-server.sh",
"args": ["--config", "${CLAUDE_PROJECT_DIR}/config.json"],
"env": {
"DEBUG": "true"
}
},
"core-tools": {
"type": "http",
"url": "https://mcp.example.com/mcp",
"alwaysLoad": true
}
}
}環境変数展開:
${VAR}── 環境変数 VAR の値${VAR:-default}── VAR が未設定の場合はdefaultを使用
展開可能な場所: command・args・env・url・headers
---
スコープ(--scope フラグ)
| スコープ | 保存先 | 適用範囲 |
|---|---|---|
local(デフォルト) | ~/.claude.json(プロジェクトパス下) | 当該プロジェクトのみ、個人 |
project | .mcp.json(プロジェクトルート) | チーム共有、git 管理 |
user | ~/.claude.json | 全プロジェクト、個人 |
# プロジェクトスコープで追加(チーム共有)
claude mcp add --transport http paypal --scope project https://mcp.paypal.com/mcp
# ユーザースコープで追加(全プロジェクト)
claude mcp add --transport http hubspot --scope user https://mcp.hubspot.com/mcp優先度: local > project > user > plugin > claude.ai connector
---
settings.json での MCP 設定
{
"enableAllProjectMcpServers": false,
"enabledMcpjsonServers": ["github", "sentry"],
"disabledMcpjsonServers": ["experimental"],
"allowedHttpHookUrls": ["http://localhost:*"],
"httpHookAllowedEnvVars": ["API_TOKEN"]
}---
OAuth 認証
# HTTP サーバー追加後に認証
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp
/mcp # ブラウザで OAuth フロー完了固定 OAuth コールバックポート(登録済み redirect URI が必要な場合):
claude mcp add --transport http \
--callback-port 8080 \
my-server https://mcp.example.com/mcp事前設定済み OAuth 認証情報:
claude mcp add --transport http \
--client-id your-client-id --client-secret --callback-port 8080 \
my-server https://mcp.example.com/mcp---
動的ヘッダー(カスタム認証)
{
"mcpServers": {
"internal-api": {
"type": "http",
"url": "https://mcp.internal.example.com",
"headersHelper": "/opt/bin/get-mcp-auth-headers.sh"
}
}
}スクリプトは JSON オブジェクト(文字列キー・値ペア)を stdout に出力する。タイムアウトは 10 秒。
---
Tool Search(コンテキスト最適化)
デフォルトで有効。MCP ツールの定義をオンデマンドでロードし、コンテキスト使用量を削減する。
ENABLE_TOOL_SEARCH=true # 全 MCP ツールを遅延ロード
ENABLE_TOOL_SEARCH=auto # コンテキスト窓の 10% を超えたら遅延ロード
ENABLE_TOOL_SEARCH=false # 全ツールを事前ロード常時ロード(特定サーバーのみ):
{"alwaysLoad": true}---
MCP リソースの参照
@ メンション構文で MCP リソースを参照:
@github:issue://123 を分析して
@docs:file://api/authentication を確認して---
MCP プロンプト(コマンドとして使用)
/mcp__github__list_prs
/mcp__github__pr_review 456
/mcp__jira__create_issue "バグ報告" high---
出力制限
- 警告閾値: 10,000 トークン
- デフォルト最大: 25,000 トークン
MAX_MCP_OUTPUT_TOKENS環境変数で調整可能
export MAX_MCP_OUTPUT_TOKENS=50000
claude---
最小例
PostgreSQL 接続
claude mcp add --transport stdio db -- npx -y @bytebase/dbhub \
--dsn "postgresql://readonly:pass@prod.db.com:5432/analytics"GitHub 接続
claude mcp add --transport http github https://api.githubcopilot.com/mcp/ \
--header "Authorization: Bearer YOUR_GITHUB_PAT"プロジェクト共有(.mcp.json)
{
"mcpServers": {
"api-server": {
"type": "http",
"url": "${API_BASE_URL:-https://api.example.com}/mcp",
"headers": {
"Authorization": "Bearer ${API_KEY}"
}
}
}
}---
よくある落とし穴
1. `--` なしで stdio サーバーを追加 → サーバーのフラグが Claude のオプションとして解釈される。 2. `CLAUDE_PROJECT_DIR` の参照 → .mcp.json の command/args での ${CLAUDE_PROJECT_DIR} はプラグイン以外では ${CLAUDE_PROJECT_DIR:-.} のようにデフォルト値が必要。 3. プロジェクトスコープの承認 → .mcp.json のサーバーは初回使用時に承認が必要(セキュリティ)。 4. `workspace` という名前 → 予約済み。使用不可。 5. claude.ai connectors と重複 → 同じ URL の場合、手動追加サーバーが優先される。 6. WebSocket の使い所 → イベントプッシュが必要な場合のみ。通常は HTTP を使用。
<!-- source: https://code.claude.com/docs/en/memory --> <!-- 最終確認日: 2026-06-06 --> <!-- ✅ 取得済み(WebFetch による公式ドキュメント取得) --> <!-- 取得状況: ✅ 取得済み -->
CLAUDE.md / メモリ リファレンス
概要
Claude Code のセッションはコンテキストウィンドウがリセットされる。セッションをまたいで知識を持続させる仕組みが 2 つある:
1. CLAUDE.md ファイル ── あなたが記述する永続的な指示 2. Auto memory ── Claude が自動的に書き込むメモ
---
CLAUDE.md ファイル
ファイル配置と優先度(ロード順)
| スコープ | ファイルパス | 共有対象 |
|---|---|---|
| Managed policy | /Library/Application Support/ClaudeCode/CLAUDE.md (macOS) / /etc/claude-code/CLAUDE.md (Linux) | 組織全員 |
| ユーザー | ~/.claude/CLAUDE.md | 自分のみ(全プロジェクト) |
| プロジェクト | ./CLAUDE.md または ./.claude/CLAUDE.md | チーム(バージョン管理) |
| ローカル | ./CLAUDE.local.md | 自分のみ(gitignore 推奨) |
ロード動作:
- 現在の作業ディレクトリから上位ディレクトリへ再帰的に探索する。
- 発見したファイルはすべて結合してコンテキストに注入(上書きでなく追記)。
- ルートから下(広いスコープ→狭いスコープ)の順番でコンテキストに入る。
- サブディレクトリの
CLAUDE.mdは Claude がそのディレクトリのファイルを読んだ時にオンデマンドでロード。
@ インポート構文
# CLAUDE.md 内でのインポート
@README
@package.json
@docs/git-instructions.md
@~/.claude/my-project-instructions.md # ホームディレクトリ参照制約:
- 相対パスはインポートするファイルからの相対パスで解決(作業ディレクトリではない)
- 再帰インポート可(最大 4 ホップ)
- 初回外部インポート時に承認ダイアログが表示される
- インポートされたファイルはセッション開始時にコンテキストに展開される(遅延ロードなし)
HTML コメント
<!-- このコメントは Claude のコンテキストに入らない(メンテナー向け) -->コードブロック内のコメントは保持される。
---
.claude/rules/ ディレクトリ
トピック別のルールファイルを分割管理できる:
your-project/
├── .claude/
│ ├── CLAUDE.md # メインプロジェクト指示
│ └── rules/
│ ├── code-style.md # コードスタイル
│ ├── testing.md # テスト規約
│ └── security.md # セキュリティ要件パス別ルール(frontmatter で指定):
---
paths:
- "src/api/**/*.ts"
- "src/**/*.{ts,tsx}"
---
# API 開発ルール
- 全エンドポイントに入力バリデーションを含める
- 標準エラーレスポンスフォーマットを使用paths がないルールはセッション開始時に常時ロード。paths があるルールは、一致するファイルを Claude が開いた時にロード。
シンボリックリンクでプロジェクト間共有:
ln -s ~/shared-claude-rules .claude/rules/shared
ln -s ~/company-standards/security.md .claude/rules/security.mdユーザーレベルルール: ~/.claude/rules/ に配置するとすべてのプロジェクトで有効。プロジェクトルールより低優先。
---
効果的な CLAUDE.md の書き方
目安: 1 ファイルあたり 200 行以内。コンテキスト消費を抑え、指示の遵守率を上げる。
良い例:
- 2 スペースインデントを使用
- `npm test` を実行してからコミット
- API ハンドラーは `src/api/handlers/` に配置悪い例:
- コードを適切にフォーマットする
- 変更をテストする
- ファイルを整理する構造: Markdown ヘッダーと箇条書きを使って関連指示をグループ化。
---
Auto Memory
Claude が自動的に学習内容を記録する仕組み(v2.1.59+)。
ストレージ構造
~/.claude/projects/<project>/memory/
├── MEMORY.md # インデックス(毎セッション最初の 200 行または 25KB をロード)
├── debugging.md # デバッグパターンの詳細メモ
├── api-conventions.md # API 設計決定事項
└── ...<project> パスは git リポジトリから導出(同じリポの全 worktree がメモリを共有)。
ロード動作:
MEMORY.mdの最初の 200 行(または 25KB)が毎セッション開始時にロード- トピックファイルはオンデマンドで読み込まれる
MEMORY.mdを超えた内容はセッション開始時にロードされない
有効/無効の切り替え
// settings.json
{"autoMemoryEnabled": false}# 環境変数で無効化
CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 claudeセッション内では /memory コマンドでトグル可能。
カスタムストレージ場所
{"autoMemoryDirectory": "~/my-custom-memory-dir"}絶対パスまたは ~/ で始まるパスが必要。プロジェクト設定に書いた場合は workspace trust 確認後に有効。
---
/memory コマンド
セッション内で CLAUDE.md・CLAUDE.local.md・rules ファイルの一覧表示、auto memory のトグル、auto memory フォルダへのリンクを提供。
---
AGENTS.md との互換性
他のエージェントツールが AGENTS.md を使っている場合:
<!-- CLAUDE.md -->
@AGENTS.md
## Claude Code 固有の指示
src/billing/ 配下の変更はプランモードを使用。または シンボリックリンク:
ln -s AGENTS.md CLAUDE.md---
大規模リポジトリ・モノレポでの管理
不要な CLAUDE.md を除外
// .claude/settings.local.json
{
"claudeMdExcludes": [
"**/monorepo/CLAUDE.md",
"/home/user/monorepo/other-team/.claude/rules/**"
]
}パターンは絶対パスに対する glob。Managed policy の CLAUDE.md は除外できない。
組織共通 CLAUDE.md のデプロイ
MDM/Group Policy 等で managed policy の場所にデプロイ:
- macOS:
/Library/Application Support/ClaudeCode/CLAUDE.md - Linux:
/etc/claude-code/CLAUDE.md
または managed-settings.json の claudeMd キーに直接埋め込み:
{
"claudeMd": "コミット前は `make lint` を実行すること。\nmain への直接プッシュ禁止。"
}---
/compact 後の生存
| コンテンツ | compact 後 |
|---|---|
| プロジェクトルートの CLAUDE.md | 生存(再読み込み・再注入) |
| サブディレクトリの CLAUDE.md | 次回ファイル読み込み時に再ロード |
| 会話内のみの指示 | 失われる |
| Auto memory (MEMORY.md) | 再ロード |
---
トラブルシューティング
CLAUDE.md が効かない場合: 1. /memory でファイルがリストに表示されるか確認 2. ファイルの配置場所がセッションのパスと一致するか確認 3. 指示をより具体的に書き直す 4. 相矛盾する指示がないか確認
強制実行が必要な場合: CLAUDE.md はソフトガイダンス。確実に実行させるには PreToolUse hook を使う。
---
このリポでの使い方
CLAUDE.md # プロジェクト指示(git 管理、チーム共有)
.claude/rules/ # ルール別管理(git 管理)
CLAUDE.local.md # 個人設定(.gitignore 追加済み)
~/.claude/CLAUDE.md # 全プロジェクト共通の個人設定このリポの CLAUDE.md に含まれている内容:
- スキルの説明・発火トリガー語の規約
- Conventional Commits 形式の要件
- セキュリティレビュー必須事項
- 日本語出力の規約
.claude/操作は_/dotclaude/経由という規則
<!-- source: https://code.claude.com/docs/en/settings --> <!-- 最終確認日: 2026-06-06 --> <!-- ✅ 取得済み(WebFetch による公式ドキュメント取得) --> <!-- 取得状況: ✅ 取得済み -->
settings.json リファレンス
概要
Claude Code の動作を settings.json / settings.local.json で制御する。permissions のルール、モデル・環境変数・フック・MCP サーバー等を設定できる。
---
設定ファイルの種類と優先度
| スコープ | ファイルパス | 共有 | 優先度 |
|---|---|---|---|
| Managed | /etc/claude-code/ (Linux) / /Library/Application Support/ClaudeCode/ (macOS) | 組織全体 | 1(最高) |
| Command Line | CLI 引数 | — | 2 |
| Local | .claude/settings.local.json | No(gitignore 推奨) | 3 |
| Project | .claude/settings.json | Yes(git commit) | 4 |
| User | ~/.claude/settings.json | No | 5(最低) |
マージ動作: 同一キーは高優先度が勝つ。permissions.allow/deny はスコープをまたいでマージされる(上書きでない)。
---
JSON スキーマ参照
オートコンプリートを有効にするには先頭に追加:
{
"$schema": "https://json.schemastore.org/claude-code-settings.json"
}---
主要フィールド
permissions(最重要)
{
"permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run test *)",
"Read(~/.zshrc)",
"Bash(git *)"
],
"deny": [
"Bash(curl *)",
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)"
],
"ask": [
"Bash(*)"
]
}
}ルールの書き方:
Bash(npm run lint)── 完全一致Bash(npm run test *)── ワイルドカードRead(~/.zshrc)── ファイルパスSkill(commit)── スキル名Skill(review-pr *)── プレフィックスマッチToolSearch── ツール名(MCP tool search)
model
{
"model": "claude-sonnet-4-6",
"availableModels": ["claude-sonnet-4-6", "claude-haiku-4-5"],
"effortLevel": "high"
}env(環境変数)
{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"NODE_ENV": "production",
"ENABLE_TOOL_SEARCH": "true"
}
}セッションと全サブプロセスに適用される。
hooks
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/validate.sh"
}
]
}
]
},
"disableAllHooks": false
}フックの詳細は reference/hooks.md を参照。
MCP サーバー関連
{
"enableAllProjectMcpServers": false,
"enabledMcpjsonServers": ["github", "sentry"],
"disabledMcpjsonServers": ["experimental-server"],
"allowedHttpHookUrls": ["http://localhost:*"],
"httpHookAllowedEnvVars": ["API_TOKEN", "GITHUB_TOKEN"]
}.mcp.json のサーバー名で指定する。
Skills 関連
{
"skillListingBudgetFraction": 0.02,
"maxSkillDescriptionChars": 1536,
"skillOverrides": {
"legacy-context": "name-only",
"deploy": "off"
},
"disableSkillShellExecution": false
}skillOverrides の値: "on"/"name-only"/"user-invocable-only"/"off"
メモリ関連
{
"autoMemoryEnabled": true,
"autoMemoryDirectory": "~/.claude/memory",
"claudeMdExcludes": [
"**/monorepo/CLAUDE.md",
"/home/user/monorepo/other-team/.claude/rules/**"
]
}動作・表示
{
"editorMode": "vim",
"viewMode": "default",
"tui": "fullscreen",
"showTurnDuration": true,
"syntaxHighlightingDisabled": false,
"language": "japanese"
}Agents & Workflows
{
"agent": "my-custom-agent",
"disableAgentView": false,
"disableWorkflows": false
}更新・バージョン管理
{
"autoUpdatesChannel": "stable",
"minimumVersion": "2.1.0"
}---
ホットリロード可能な設定
再起動不要:
permissionshooksapiKeyHelper
再起動が必要:
modeloutputStyle(/clearで再構築)
---
最小例
プロジェクト設定(.claude/settings.json)
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git status)",
"Bash(git diff *)",
"Bash(git log *)"
],
"deny": [
"Bash(git push --force *)",
"Read(.env)",
"Read(.env.*)"
]
},
"env": {
"NODE_ENV": "development"
}
}個人設定(.claude/settings.local.json)
{
"permissions": {
"allow": [
"Bash(npm run dev)"
]
},
"hooks": {
"SessionStart": [
{
"matcher": "startup",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/my-context.sh"
}
]
}
]
}
}---
よくある落とし穴
1. `permissions.deny` が `allow` より優先 → deny ルールがあると allow ルールを上書きする。 2. `settings.local.json` を gitignore していない → 個人設定が誤って共有される。プロジェクト初期化時に追加を忘れずに。 3. Managed 設定は上書き不可 → 組織管理者の設定はローカルで変更できない。allowManagedPermissionRulesOnly: true の場合は managed 以外のルールが無効。 4. `env` の変数はインターフェイス色に影響しない → NO_COLOR/FORCE_COLOR は起動前のシェルで設定する必要がある。 5. スキーマが最新に追従しない → $schema の検証警告は最新フィールドでは出ることがある。設定は有効。
---
このリポでの使い方
.claude/settings.json # プロジェクト共有設定(git 管理)
.claude/settings.local.json # 個人設定(.gitignore に追加済み)
~/.claude/settings.json # 全プロジェクト共通の個人設定`.claude/` 配下の編集: dotclaude-via-temp.md ルールに従い _/dotclaude/ 経由で作業し、完了後に mv で移動する。
<!-- source: https://code.claude.com/docs/en/skills --> <!-- 最終確認日: 2026-06-06 --> <!-- ✅ 取得済み(WebFetch による公式ドキュメント取得) --> <!-- 取得状況: ✅ 取得済み -->
Agent Skills リファレンス
概要
Skills は Claude Code の機能を拡張する仕組み。SKILL.md ファイルに手順を記述すると、Claude のツールキットに追加される。Claude が自動的に適用するか、/skill-name で直接呼び出せる。
重要な設計判断:
- CLAUDE.md のコンテンツ(常にコンテキストに入る)とは異なり、スキルの本文は使用時のみロードされるため、長いリファレンス素材のコストが低い。
- カスタムコマンド (
.claude/commands/) はスキルに統合された。両者は同等に動作するが、スキルを推奨。
---
必須項目・構文
ファイル配置
| 場所 | パス | 適用範囲 |
|---|---|---|
| エンタープライズ | managed settings 経由 | 組織全員 |
| 個人 | ~/.claude/skills/<name>/SKILL.md | 全プロジェクト |
| プロジェクト | .claude/skills/<name>/SKILL.md | 当該プロジェクトのみ |
| プラグイン | <plugin>/skills/<name>/SKILL.md | プラグイン有効時 |
コマンド名の決定: ディレクトリ名がコマンド名になる(frontmatter の name フィールドは表示名のみ)。
frontmatter 全フィールド
---
name: my-skill # 表示名(省略可、デフォルト: ディレクトリ名)
description: "スキルの説明。Claude がいつ使うか。トリガー語を含める。"
when_to_use: "追加の発火条件や例" # description に追記される(任意)
argument-hint: "[issue-number]" # 引数のヒント(任意)
arguments: [issue, branch] # 名前付き引数定義(任意)
disable-model-invocation: true # true: ユーザーのみ呼び出し可(任意)
user-invocable: false # false: / メニューに非表示(任意)
allowed-tools: "Read Grep Bash" # このスキル実行中に許可するツール(任意)
disallowed-tools: "Write Edit" # このスキル実行中に禁止するツール(任意)
model: haiku # haiku/sonnet/opus またはフル ID(任意)
effort: high # low/medium/high/xhigh/max(任意)
context: fork # fork: サブエージェントで実行(任意)
agent: Explore # context:fork 時のエージェント種類(任意)
hooks: ... # スキルスコープの hooks(任意)
paths: # このスキルが発火する glob パターン(任意)
- "src/api/**/*.ts"
shell: bash # !`command` に使うシェル(bash/powershell)
---description の注意:
description+when_to_useの合計は 1,536 文字でスキルリスト表示時に打ち切られる。重要なキーワードを先頭に置く。#を含む場合はクォートで囲むこと(YAML コメント扱いを防ぐ)。
# NG: YAML コメントとして # 以降が消える
description: スキル説明 # 詳細は別スキル参照
# OK: クォートで囲む
description: "スキル説明 # 詳細は別スキル参照"参考: コミット e83e1bb(このリポ固有の教訓)
model 選定基準(このリポ規約)
| ユースケース | model |
|---|---|
| 機械的・集計・一覧生成 | haiku |
| 判定・生成・レビュー・複数ファイル読解 | sonnet |
| 複雑な計画立案・アーキテクチャ設計 | opus |
---
文字列置換(変数)
| 変数 | 説明 |
|---|---|
$ARGUMENTS | 呼び出し時に渡された全引数 |
$ARGUMENTS[N] | N 番目の引数(0 始まり) |
$N | $ARGUMENTS[N] の短縮形 |
$name | arguments フィールドで定義した名前付き引数 |
${CLAUDE_SESSION_ID} | 現在のセッション ID |
${CLAUDE_EFFORT} | 現在の effort レベル |
${CLAUDE_SKILL_DIR} | このスキルの SKILL.md があるディレクトリ |
---
最小例
基本スキル
---
name: summarize-changes
description: "コミット前の差分を要約してリスクを指摘。「何が変わった」「コミットメッセージを作って」などで使用。"
---
## 現在の差分
!`git diff HEAD`
## 指示
上記の変更を 2〜3 箇条で要約し、リスク(エラーハンドリング漏れ、ハードコード値、未更新のテスト等)を列挙する。引数を取るスキル
---
name: fix-issue
description: "GitHub Issue を番号で修正する。「Issue #N を直して」などで使用。"
disable-model-invocation: true
argument-hint: "[issue-number]"
---
Issue #$ARGUMENTS を修正する:
1. Issue の内容を読む
2. コードを修正する
3. テストを書く
4. コミットするサブエージェントで実行するスキル
---
name: deep-research
description: "コードベースのトピックを詳しく調査する。「〜について調べて」などで使用。"
context: fork
agent: Explore
---
$ARGUMENTS を徹底的に調査する:
1. Glob と Grep で関連ファイルを探す
2. コードを読んで分析する
3. 具体的なファイル参照付きで結果をまとめる動的コンテキスト注入(! バッククォート)
---
name: pr-summary
description: "PR の変更を要約する。"
context: fork
agent: Explore
allowed-tools: "Bash(gh *)"
---
## PR コンテキスト
- PR diff: !`gh pr diff`
- PR コメント: !`gh pr view --comments`
- 変更ファイル: !`gh pr diff --name-only`
このプルリクエストを要約する...! バッククォートは行頭または空白の直後のみ認識される。複数行は `! ブロックを使用。
---
invocation 制御
| frontmatter | ユーザー呼び出し | Claude 自動呼び出し | コンテキスト投入 |
|---|---|---|---|
| (デフォルト) | Yes | Yes | 説明常時投入、本文は呼び出し時 |
disable-model-invocation: true | Yes | No | 説明なし、本文は呼び出し時 |
user-invocable: false | No | Yes | 説明常時投入、本文は呼び出し時 |
---
よくある落とし穴
1. description の `#` がコメント扱いになる → 必ずクォートで囲む(e83e1bb 参照) 2. スキルが発火しない → description にユーザーが実際に言う言葉(トリガー語)を入れる。/skills でスキル一覧を確認。 3. context: fork を意図しない使い方 → context: fork は明示的なタスク指示がある場合のみ有効。ガイドライン系のコンテンツには不適切。 4. description が長すぎる → description + when_to_use で 1,536 文字上限。重要情報を先頭に。 5. スキル本文が長い → 本文はセッション中コンテキストに残り続ける。500 行以内を推奨。詳細は別ファイルに分離。 6. supporting files の読み込み → SKILL.md から参照しないと Claude は存在を知らない。
---
このリポでの使い方
skills/<name>/SKILL.md # スキル本体
.claude/skills/<name> # シンボリックリンク(skills/<name> → .claude/skills/<name>)シンボリックリンク作成:
ln -s ../../skills/<name> .claude/skills/<name>新スキル追加後:
update-docs スキルを実行して CLAUDE.md のスキル一覧・ツリーを更新する。
.claude/ 配下の編集: dotclaude-via-temp.md ルールに従い _/dotclaude/ を経由する。
<!-- source: https://code.claude.com/docs/en/commands --> <!-- 最終確認日: 2026-06-06 --> <!-- ✅ 取得済み(WebFetch による公式ドキュメント取得) --> <!-- 取得状況: ✅ 取得済み -->
スラッシュコマンド リファレンス
概要
スラッシュコマンドはセッション内から Claude Code を制御する仕組み。メッセージの先頭に / を付けて呼び出す。コマンド名の後に続くテキストは引数として渡される。
カスタムコマンドの追加方法: Skills を使用(詳細は reference/skills.md を参照)。
---
カスタムコマンド(Skills)の作成
.claude/skills/<name>/SKILL.md # スキルディレクトリ形式(推奨)
.claude/commands/<name>.md # 旧コマンドファイル形式(互換性あり)両者は同等に動作するが、スキルディレクトリ形式を推奨(supporting files、frontmatter 等の追加機能あり)。
コマンド名の決定: ディレクトリ名またはファイル名(拡張子なし)が / の後に続くコマンド名になる。
MCP プロンプトコマンド
MCP サーバーが公開するプロンプトは以下の形式でコマンドになる:
/mcp__<server>__<prompt>
/mcp__github__list_prs
/mcp__jira__create_issue "Bug in login flow" high---
ビルトインコマンド一覧
[arg] = 省略可、<arg> = 必須
セットアップ・プロジェクト管理
| コマンド | 説明 |
|---|---|
/init | プロジェクトの CLAUDE.md を生成。CLAUDE_CODE_NEW_INIT=1 で対話フロー |
/memory | CLAUDE.md 編集・auto memory の有効/無効・auto memory エントリ表示 |
/mcp | MCP サーバー接続と OAuth 認証管理 |
/agents | サブエージェント設定管理 |
/permissions | ツール許可・拒否ルール管理(/allowed-tools でも可) |
/add-dir <path> | セッション中にファイルアクセス対象ディレクトリを追加 |
モデル・設定
| コマンド | 説明 |
|---|---|
/model [model] | AI モデルの切り替え・デフォルト設定 |
| `/effort [level\ | auto]` |
/config | 設定インターフェイスを開く(/settings でも可) |
/theme | カラーテーマ変更 |
コンテキスト管理
| コマンド | 説明 |
|---|---|
/compact [instructions] | 会話を圧縮してコンテキストを解放 |
/context [all] | コンテキスト使用量を可視化 |
/clear [name] | 新しい会話を開始(/reset//new でも可) |
/btw <question> | 会話を汚染せずにサイド質問 |
並列実行・エージェント管理
| コマンド | 説明 |
|---|---|
/background [prompt] | 現在のセッションをバックグラウンドエージェントとして切り離し(/bg でも可) |
/tasks | バックグラウンド実行中のタスク管理(/bashes でも可) |
/fork <directive> | 会話をフォークしてバックグラウンドサブエージェントに委任 |
/branch [name] | 会話のブランチを作成 |
/batch <instruction> | Skill コードベース全体に大規模変更を並列適用 |
コードレビュー・品質
| コマンド | 説明 |
|---|---|
/code-review [level] [--fix] [--comment] [target] | Skill 差分をレビュー。--fix で自動修正、ultra でクラウドレビュー |
/simplify [target] | Skill リファクタリング・クリーンアップを適用(バグ修正なし) |
/review [PR] | PR をローカルでレビュー |
/security-review | セキュリティ脆弱性の分析 |
/diff | インタラクティブな差分ビュワー |
セッション履歴・移動
| コマンド | 説明 |
|---|---|
/resume [session] | 以前の会話を再開(/continue でも可) |
/rewind | 会話とコードを以前の時点に巻き戻し(/checkpoint//undo でも可) |
/rename [name] | 現在のセッションに名前を付ける |
/branch [name] | 現在の会話を別方向に分岐 |
スキル・コマンド管理
| コマンド | 説明 |
|---|---|
/skills | 利用可能なスキル一覧。t でトークン数順、Space で可視性切り替え |
/reload-skills | スキルディレクトリを再スキャン(v2.1.152+) |
/reload-plugins [--force] | プラグインをリロード |
/plugin [subcommand] | プラグイン管理 |
診断・デバッグ
| コマンド | 説明 |
|---|---|
/doctor | インストールと設定を診断(f で自動修正) |
/debug [description] | Skill デバッグログを有効化して問題を分析 |
/hooks | フック設定の閲覧(読み取り専用) |
/status | バージョン・モデル・アカウント・接続状況 |
/usage | コスト・使用量・統計(/cost//stats でも可) |
プランモード
| コマンド | 説明 |
|---|---|
/plan [description] | プランモードに入る |
その他
| コマンド | 説明 |
|---|---|
/help | ヘルプと利用可能なコマンドを表示 |
/exit | CLI を終了(/quit でも可) |
/copy [N] | 最後のアシスタントレスポンスをクリップボードにコピー |
/export [filename] | 現在の会話をテキストとしてエクスポート |
/feedback [report] | フィードバック・バグ報告(/bug//share でも可) |
/login | Anthropic アカウントにサインイン |
/logout | サインアウト |
バンドルスキル(Skill マーク)
| コマンド | 説明 |
|---|---|
/run | アプリを起動して変更を実際に確認(v2.1.145+) |
/verify | コード変更が期待通りに動作するか実際のアプリで確認(v2.1.145+) |
/run-skill-generator | /run//verify の起動レシピをプロジェクトスキルとして記録 |
/loop [interval] [prompt] | プロンプトを繰り返し実行(/proactive でも可) |
/deep-research <question> | Workflow Web 検索をファンアウトして調査レポートを生成 |
/claude-api | Claude API リファレンスをロード(SDK import 時に自動発火) |
/code-review | 差分のコードレビュー(上記参照) |
/simplify | リファクタリングのみのレビュー(v2.1.154+) |
/batch | 大規模変更を並列適用 |
/debug | デバッグログ有効化 |
/fewer-permission-prompts | 許可プロンプト削減のための allowlist 設定 |
---
よくある落とし穴
1. コマンドはメッセージの先頭のみ認識 → 文中に /command を書いても発火しない。 2. 可用性はプラットフォーム・プラン依存 → /desktop(macOS/Windows + サブスクリプション必要)等は全ユーザーに表示されない。 3. スキルと MCP プロンプトの競合 → スキルがコマンド名で優先される。 4. `/code-review ultra` はクラウド実行 → 無料枠(3回)を超えると usage credits が必要。
---
このリポでの使い方
このリポのスキルは / コマンドとして呼び出せる(user-invocable: false でない場合)。
/create-commit # コミット作成
/create-pr # PR 作成
/create-plan # 計画立案
/implement-issue # Issue 実装user-invocable: false に設定されたスキル(github-docs・claude-code-reference 等)は / メニューに表示されず、Claude が自動的に呼び出す。
<!-- source: https://code.claude.com/docs/en/sub-agents --> <!-- 最終確認日: 2026-06-06 --> <!-- ✅ 取得済み(WebFetch による公式ドキュメント取得) --> <!-- 取得状況: ✅ 取得済み -->
Subagents リファレンス
概要
Subagents(サブエージェント)は特定タスクに特化した AI アシスタント。サイドタスクが会話のコンテキストを汚染する場合に使用する。各サブエージェントは独自のコンテキストウィンドウ・システムプロンプト・ツールアクセス・権限で動作し、結果のサマリーのみを返す。
サブエージェントのユースケース:
- コンテキストの節約(検索・ログ・ファイル内容を分離)
- ツール制限による制約の強制
- コスト制御(Haiku 等の安価なモデルへのルーティング)
---
必須項目・構文
ファイル配置
| 場所 | パス | 優先度 |
|---|---|---|
| Managed settings | 組織管理者が配置 | 1(最高) |
--agents CLI フラグ | セッション限定 | 2 |
.claude/agents/ | プロジェクトスコープ | 3 |
~/.claude/agents/ | ユーザースコープ(全プロジェクト) | 4 |
Plugin agents/ | プラグインスコープ | 5(最低) |
同名の場合、優先度の高いものが勝つ。.claude/agents/ はサブディレクトリも再帰的にスキャンされる。
サブエージェントファイルの構造
---
name: code-reviewer
description: コードの品質とベストプラクティスをレビューする。コード変更後に使用。
tools: Read, Glob, Grep
model: sonnet
---
あなたはコードレビュアーです。コードを分析し、品質・セキュリティ・ベストプラクティスについて
具体的でアクション可能なフィードバックを提供してください。本文(frontmatter 以降の Markdown)がシステムプロンプトになる。
frontmatter 全フィールド
| フィールド | 必須 | 説明 |
|---|---|---|
name | Yes | 小文字英数字とハイフン。ファイル名と一致する必要はない |
description | Yes | Claude がいつ委譲するかを決定する。明確に記述する |
tools | No | 使用可能なツール。省略時は全ツールを継承 |
disallowedTools | No | 禁止するツール |
model | No | sonnet/opus/haiku またはフル ID。省略時は inherit |
permissionMode | No | default/acceptEdits/auto/dontAsk/bypassPermissions/plan |
maxTurns | No | 最大エージェントターン数 |
skills | No | 起動時にプリロードするスキル(全コンテンツを注入) |
mcpServers | No | このサブエージェントが使える MCP サーバー |
hooks | No | このサブエージェントスコープのフック |
memory | No | 永続メモリスコープ: user/project/local |
background | No | true: 常にバックグラウンドタスクとして実行 |
effort | No | low/medium/high/xhigh/max |
isolation | No | worktree: 独立した git worktree で実行 |
color | No | UI 表示色: red/blue/green/yellow/purple/orange/pink/cyan |
initialPrompt | No | --agent フラグで起動した際の最初のユーザーターン |
プラグインサブエージェントでは `hooks`/`mcpServers`/`permissionMode` は無視される。
model の解決順序
1. CLAUDE_CODE_SUBAGENT_MODEL 環境変数 2. 呼び出し時のパラメータ 3. サブエージェント定義の model frontmatter 4. メイン会話のモデル
利用可能なツール一覧(主要)
Read, Write, Edit, MultiEdit, Bash, Glob, Grep, LS,
WebFetch, WebSearch, TodoRead, TodoWrite,
Task (サブエージェント呼び出し), Skill, AskUserQuestion,
mcp__<server>__<tool>---
ビルトインサブエージェント
| エージェント | モデル | ツール | 目的 |
|---|---|---|---|
| Explore | Haiku | 読み取り専用 | ファイル検索・コードベース探索。CLAUDE.md と git status をスキップ |
| Plan | 継承 | 読み取り専用 | プランモード時のリサーチ。CLAUDE.md と git status をスキップ |
| general-purpose | 継承 | 全ツール | 複雑な複数ステップのタスク |
| statusline-setup | Sonnet | — | /statusline コマンドで使用 |
| claude-code-guide | Haiku | — | Claude Code 機能の質問対応 |
---
最小例
基本的なサブエージェント定義
---
name: security-auditor
description: コードのセキュリティ脆弱性を監査する。新しいコードが追加された後に使用。
tools: Read, Glob, Grep
model: sonnet
---
あなたはセキュリティ専門家です。以下の観点でコードを分析してください:
- OWASP Top 10 の脆弱性
- ハードコードされた認証情報
- 入力バリデーション不足
- XSS・SQLインジェクション・CSRFCLI フラグで定義する例(テスト・自動化向け)
claude --agents '{
"code-reviewer": {
"description": "コードの品質をレビューする。変更後にプロアクティブに使用。",
"prompt": "あなたはシニアコードレビュアーです。品質・セキュリティ・ベストプラクティスに集中してください。",
"tools": ["Read", "Grep", "Glob", "Bash"],
"model": "sonnet"
}
}'スキルをプリロードするサブエージェント
---
name: commit-assistant
description: Conventional Commits 形式でコミットを作成する。
skills:
- create-commit
model: haiku
---
コミットを作成するアシスタントです。---
呼び出し方
Claude はサブエージェントの description を見て自動委譲を決定する。 明示的に指定したい場合は以下のように伝える:
security-auditor エージェントを使ってこのコードを監査してスキルの context: fork + agent: <name> フィールドでも呼び出せる:
---
context: fork
agent: Explore
------
起動時のコンテキストロード
| 内容 | 通常サブエージェント | Explore/Plan |
|---|---|---|
| CLAUDE.md | ロード | スキップ |
| git status | ロード | スキップ |
| サブエージェントのシステムプロンプト | ロード | ロード |
プリロードスキル (skills フィールド) | ロード(全文) | ロード |
---
よくある落とし穴
1. サブエージェントは他のサブエージェントを生成できない(無限ネスト防止)。 2. プラグインサブエージェントの制限 → hooks/mcpServers/permissionMode は無視される。 3. name の重複 → 同一スコープ内で同名が複数あると、どちらかが無警告で破棄される。 4. サブエージェントファイルの変更反映 → ファイルを直接編集した場合はセッション再起動が必要。/agents インターフェイス経由は即時反映。 5. `cd` コマンドが効かない → サブエージェント内の cd は Bash コール間で持続しない。 6. description が曖昧 → Claude が委譲を決定できない。いつ使うかを具体的に記述する。
---
このリポでの使い方
.claude/agents/<name>.md # プロジェクトスコープ(チームで共有)
~/.claude/agents/<name>.md # ユーザースコープ(個人のみ)`.claude/` 配下の編集: dotclaude-via-temp.md ルールに従い _/dotclaude/agents/ で一時作業してから mv で移動する。
このリポの既存エージェント:
.claude/agents/plan-verifier.md── 計画検証エージェント(読み取り専用、Sonnet)
My Agent
このエージェントが何を担当するかの一行説明。
役割
<!-- 委譲される場面・担当スコープを記載する。 -->
- どのスキルから委譲されるか
- どこまでを担当するか(例: 読み取り専用 / ファイル編集まで可)
- 隣接 Agent との責務の境界
対象スコープ
| 区分 | パス |
|---|---|
| 読み書き可 | skills/** |
| 読み取り専用 | .claude/rules/** |
| 変更禁止 | .claude/ 配下(dotclaude-via-temp 経由が必要) |
遵守する規約
<!-- 参照すべきルールファイルを相対パスで列挙する。 -->
../../rules/skill-authoring.md(frontmatter・本文構成)../../rules/dotclaude-via-temp.md(.claude/操作手順)../../rules/security.md(OWASP Top 10・秘密情報混入防止)
手順
Step 1: 状態を把握する
入力パラメータを確認し、対象ファイルを Read で読み込む。
Step 2: メイン処理
<!-- 調査・生成・レビュー等の具体的な手順 -->
Step 3: 報告する
以下フォーマットで日本語レポートを生成する。
完了条件
- 必須ファイルが全て存在する
- frontmatter の必須項目(name / description / model)が揃っている
- セキュリティ自己チェックを実施し問題がない(または報告済み)
報告フォーマット
## My Agent 完了報告
### 対象
- パス: <ファイルパス>
- 操作: 新規作成 / 編集 / 検証
### 結果
- ✅ PASS / ⚠️ WARNING / ❌ FAIL
### 詳細
<問題があれば具体的なファイルパスと修正方法を記載>
### 次のアクション
1. <優先度: 高> <対応が必要な項目>hooks 設定 実例集
settings.json の hooks セクションで定義する自動実行フックの実例。 Claude が特定のアクション(セッション開始・ツール実行後など)を起こしたとき、指定したシェルコマンドを自動実行する。
フックの種類
| hook 名 | 発火タイミング |
|---|---|
SessionStart | Claude Code セッション開始時 |
PostToolUse | ツール実行完了後(Edit / Write / Bash など) |
PreToolUse | ツール実行前(確認・ガード用) |
---
実例 1: SessionStart — 日本語リマインダーを表示する
セッション開始時に規約のリマインダーを echo する。チームの作業規約を毎回表示したい場合に有効。
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "echo '=== Claude Code セッション開始 ==='; echo '重要な規約:'; echo ' - Conventional Commits 形式でコミット (type(scope): subject)'; echo ' - --no-verify は使用禁止'; echo ' - .claude/ 配下は _/dotclaude/ 経由で編集'; echo ' - シークレット (.env 等) を含むファイルはコミット禁止'; echo '================================'"
}
]
}
]
}
}---
実例 2: PostToolUse(Edit) — .md 編集後に通知する
Edit ツールでファイルが更新された後、Markdown ファイルであれば通知を出す。 CLAUDE_TOOL_RESULT 環境変数に Edit ツールの出力 JSON が格納される。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "FILE_PATH=$(echo \"$CLAUDE_TOOL_RESULT\" | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('file_path',''))\" 2>/dev/null || true); if [[ \"$FILE_PATH\" == *.md ]]; then echo \"[hook] Markdown ファイルが更新されました: $FILE_PATH\"; fi"
}
]
}
]
}
}解説
matcher: "Edit"— Edit ツール実行後のみ発火するpython3 -c "import sys,json; ..."— JSON を安全にパースしてfile_pathを取り出す|| true— python3 のエラーを無視してフック自体が失敗しないようにする[[ "$FILE_PATH" == *.md ]]— 変数はダブルクォートで囲む(コマンドインジェクション対策)
---
実例 3: PostToolUse(Bash) — git commit 後にハッシュを記録する
Bash ツールで git commit が実行された後、最新コミットハッシュをログに記録する。
{
"hooks": {
"PostToolUse": [
{
"type": "command",
"matcher": "Bash",
"command": "TOOL_INPUT=$(echo \"$CLAUDE_TOOL_INPUT\" | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('command',''))\" 2>/dev/null || true); if echo \"$TOOL_INPUT\" | grep -q 'git commit'; then HASH=$(git rev-parse --short HEAD 2>/dev/null || true); echo \"[hook] コミット完了: $HASH\"; fi"
}
]
}
}解説
CLAUDE_TOOL_INPUT— ツールへの入力 JSON(コマンド文字列を含む)grep -q 'git commit'— コマンド文字列に git commit が含まれるかを確認git rev-parse --short HEAD— コミット後の最新ハッシュを取得|| true— git コマンド失敗時もフックが止まらないようにする
---
実例 4: PreToolUse(Bash) — rm -rf をガードする
Bash ツールが rm -rf を含むコマンドを実行しようとしたとき、警告を出して中止させる。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "CMD=$(echo \"$CLAUDE_TOOL_INPUT\" | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('command',''))\" 2>/dev/null || true); if echo \"$CMD\" | grep -qE 'rm\\s+-rf\\s+\\.claude'; then echo '[BLOCKED] .claude への rm -rf は禁止されています'; exit 2; fi"
}
]
}
]
}
}解説
exit 2を返すとツール実行をブロックする(exit 1は非ブロッキング)grep -qE 'rm\\s+-rf\\s+\\.claude'—.claudeを対象とした rm -rf のみを検出
---
settings.json への配置場所
| ファイル | 用途 |
|---|---|
.claude/settings.json | プロジェクト共有(チームに適用) |
.claude/settings.local.json | 個人専用(git ignore 推奨) |
permissions の allow / deny と hooks は同一 JSON に併記できる:
{
"permissions": {
"allow": ["Bash(git add:*)"],
"deny": ["Bash(git commit --no-verify:*)"]
},
"hooks": {
"SessionStart": [...]
}
}ルール名(見出し)
<!-- ルールの目的を 1〜2 段落で説明する。 -->
このルールは〇〇を操作する際の規約を定める。
適用範囲
<!-- どのパス・どの操作に適用されるかを明記する。 -->
pathsに列挙されたファイルを編集するすべての Agentapplies_toに列挙されたスキルが参照する
規約内容
基本的なフロー
1. 〇〇をする前に△△を確認する 2. ××の操作は直接行わず、一時ディレクトリを経由する(→ dotclaude-via-temp 参照)
コマンド例
# 安全なコマンド例(変数は必ずクォート)
mv "${TMPDIR}/foo.md" ".claude/rules/foo.md"
# 空ディレクトリのみ削除(rm -rf は禁止)
rmdir "${TMPDIR}" 2>/dev/nullpaths vs applies_to の使い分け
| フィールド | 用途 |
|---|---|
paths | ファイルパス glob で「編集時に自動参照」させる |
applies_to | Agent 名・スキル名で「参照者を明示」する(自動参照は行われない) |
paths を省略すると、Claude は常にこのルールを参照する(グローバルルール)。 特定ファイルにのみ関係するルールは paths で限定することを推奨する。
禁止事項
rm -rfによる一括削除は禁止- 変数をクォートせずにシェルコマンドへ渡すこと(インジェクションリスク)
--no-verifyによるフック回避
関連ルール
./dotclaude-via-temp.md—.claude/配下の操作手順./security.md— OWASP Top 10・秘密情報混入防止
{
"permissions": {
"allow": [
"Bash(git add:*)",
"Bash(git status)",
"Bash(git diff:*)",
"Bash(git log:*)",
"Bash(git commit:*)",
"Bash(git push:*)",
"Bash(git switch:*)",
"Bash(gh pr create:*)",
"Bash(gh issue create:*)",
"Bash(gh issue view:*)",
"Bash(gh api:*)",
"Bash(gh project:*)",
"Bash(ls:*)",
"Bash(find:*)",
"Bash(mkdir -p:*)",
"Bash(mv:*)",
"Bash(ln -s:*)",
"Bash(rmdir:*)",
"Bash(readlink:*)",
"Bash(python3 -c:*)",
"Bash(python3 -m json.tool)",
"WebFetch(domain:docs.github.com)"
],
"deny": [
"Bash(git commit --no-verify:*)",
"Bash(git push --force:*)",
"Bash(rm -rf .claude:*)"
]
},
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "echo '=== Claude Code セッション開始 ==='; echo '重要な規約:'; echo ' - Conventional Commits 形式でコミット (type(scope): subject)'; echo ' - --no-verify は使用禁止'; echo ' - .claude/ 配下は _/dotclaude/ 経由で編集'; echo ' - シークレット (.env 等) を含むファイルはコミット禁止'; echo '================================'"
}
]
}
],
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "FILE_PATH=$(echo \"$CLAUDE_TOOL_RESULT\" | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('file_path',''))\" 2>/dev/null || true); if [[ \"$FILE_PATH\" == *.md ]]; then echo \"[hook] Markdown ファイルが更新されました: $FILE_PATH\"; fi"
}
]
}
]
}
}
my-new-skill
このスキルが何をするかの一文説明。
前提条件
<!-- ツール・権限・認証状態などを列挙する。不要なら削除可。 -->
ghCLI がインストールされ、認証済みであること(gh auth statusで確認)- 対象リポジトリへの書き込み権限があること
フロー
Step 1: 状態を確認する
<!-- 各 Step は「目的 + コマンド例」の構成にする。 -->
git status
git diff --staged説明文。何を確認するのか、結果をどう解釈するかを書く。
Step 2: メイン処理を実行する
gh api \
--method POST \
repos/{owner}/{repo}/issues \
-f title="タイトル" \
-f body="本文"変数は必ずダブルクォートで囲む(コマンドインジェクション対策)。
Step 3: 結果を確認してユーザーに返す
処理結果の URL・番号などをユーザーに提示する。
検証
<!-- 完了確認の方法を記載する。 -->
- 作成されたリソースの URL を確認する
gh issue view <number>等で内容を再確認する
注意事項
<!-- 制約・禁止事項・エッジケース -->
--no-verifyは絶対に使用しない(pre-commit フック回避禁止).envや認証情報ファイルが含まれる場合は警告してコミットを中止する- 破壊的操作(削除等)の前は必ずユーザーの確認を得る
- sandbox 環境での `GIT_SSL_NO_VERIFY=1` 併用:詳細は
docs/sandbox-tls.mdを参照
#!/usr/bin/env bash
# frontmatter-check.sh — 全 SKILL.md / agent / rule の frontmatter 検査と symlink リンク切れ確認
#
# 使い方: ./script/frontmatter-check.sh [--skills | --agents | --rules | --symlinks | --all]
# 元スキル: .claude/agents/quality/frontmatter-linter.md(検証項目 A〜F)
#
# このスクリプトは「読み取り専用」— ファイルの作成・変更・削除は一切行わない。
set -euo pipefail
# このスクリプトは skills/claude-code-reference/script/ 配下にあるため、リポジトリルートは3階層上
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
# ANSI カラー(ターミナル判定付き)
if [[ -t 1 ]]; then
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RESET='\033[0m'
else
RED=''; GREEN=''; YELLOW=''; RESET=''
fi
OK="${GREEN}OK${RESET}"
NG="${RED}NG${RESET}"
WARN="${YELLOW}WARN${RESET}"
TOTAL_NG=0
TOTAL_WARN=0
# ----------------------------------------------------------------
# ヘルパー: YAML frontmatter から指定キーの値を抽出する
# ----------------------------------------------------------------
extract_frontmatter_value() {
local file="$1"
local key="$2"
# --- ... --- の間の行から key: value を取り出す
python3 - "$file" "$key" <<'PYEOF'
import sys, re
filepath, key = sys.argv[1], sys.argv[2]
try:
with open(filepath, encoding='utf-8') as f:
content = f.read()
except Exception:
print('')
sys.exit(0)
# frontmatter ブロックを抽出
m = re.match(r'^---\n(.*?)\n---', content, re.DOTALL)
if not m:
print('')
sys.exit(0)
fm = m.group(1)
for line in fm.splitlines():
if line.startswith(key + ':'):
val = line[len(key)+1:].strip().strip('"\'')
print(val)
sys.exit(0)
print('')
PYEOF
}
# frontmatter ブロックが正しく閉じられているか確認
has_valid_frontmatter() {
local file="$1"
python3 - "$file" <<'PYEOF'
import sys, re
with open(sys.argv[1], encoding='utf-8', errors='replace') as f:
content = f.read()
if re.match(r'^---\n.*?\n---', content, re.DOTALL):
sys.exit(0)
else:
sys.exit(1)
PYEOF
}
# ----------------------------------------------------------------
# A/C: SKILL.md の frontmatter 検査
# ----------------------------------------------------------------
check_skills() {
echo "=== A. SKILL.md frontmatter 検査 ==="
echo ""
local skill_dir="${REPO_ROOT}/skills"
local any_ng=0
for skill_md in "${skill_dir}"/*/SKILL.md; do
local skill_path="${skill_md#${REPO_ROOT}/}"
local dir_name
dir_name=$(basename "$(dirname "$skill_md")")
local fm_ok name_val name_ok kebab_ok desc_ok
# frontmatter ブロックの存在確認
if has_valid_frontmatter "$skill_md" 2>/dev/null; then
fm_ok=true
else
fm_ok=false
fi
name_val=$(extract_frontmatter_value "$skill_md" "name")
desc_val=$(extract_frontmatter_value "$skill_md" "description")
# kebab-case チェック: ^[a-z][a-z0-9-]+$
if [[ -n "$name_val" ]] && echo "$name_val" | grep -qE '^[a-z][a-z0-9-]+$'; then
kebab_ok=true
else
kebab_ok=false
fi
# name とディレクトリ名の一致確認(C)
if [[ "$name_val" == "$dir_name" ]]; then
name_ok=true
else
name_ok=false
fi
# description の存在確認
if [[ -n "$desc_val" ]]; then
desc_ok=true
else
desc_ok=false
fi
local status
if $fm_ok && $name_ok && $kebab_ok && $desc_ok; then
status="$OK"
else
status="$NG"
any_ng=$((any_ng + 1))
TOTAL_NG=$((TOTAL_NG + 1))
fi
printf " [%b] %-40s fm=%s name=%s kebab=%s desc=%s dir-match=%s\n" \
"$status" "$skill_path" \
"$(bool_str $fm_ok)" "$(val_str "$name_val")" "$(bool_str $kebab_ok)" \
"$(bool_str $desc_ok)" "$(bool_str $name_ok)"
done
echo ""
if [[ "$any_ng" -gt 0 ]]; then
echo -e " ${NG}: ${any_ng} 件の問題があります"
else
echo -e " ${OK}: 全 SKILL.md が正常"
fi
echo ""
}
# ----------------------------------------------------------------
# B: Agent frontmatter 検査
# ----------------------------------------------------------------
check_agents() {
echo "=== B. Agent frontmatter 検査 ==="
echo ""
local agents_dir="${REPO_ROOT}/.claude/agents"
local any_ng=0
while read -r agent_md; do
local agent_path="${agent_md#${REPO_ROOT}/}"
local name_val model_val desc_val fm_ok
if has_valid_frontmatter "$agent_md" 2>/dev/null; then
fm_ok=true
else
fm_ok=false
fi
name_val=$(extract_frontmatter_value "$agent_md" "name")
model_val=$(extract_frontmatter_value "$agent_md" "model")
desc_val=$(extract_frontmatter_value "$agent_md" "description")
local model_ok=false
if echo "$model_val" | grep -qE '^(haiku|sonnet|opus|claude-.+)$'; then
model_ok=true
fi
local status
if $fm_ok && [[ -n "$name_val" ]] && [[ -n "$desc_val" ]] && $model_ok; then
status="$OK"
else
status="$NG"
TOTAL_NG=$((TOTAL_NG + 1))
fi
printf " [%b] %-50s model=%s\n" "$status" "$agent_path" "$(val_str "$model_val")"
done < <(find "${agents_dir}" -name "*.md" | sort)
echo ""
}
# ----------------------------------------------------------------
# D: symlink リンク切れ確認
# ----------------------------------------------------------------
check_symlinks() {
echo "=== D. symlink リンク切れ確認 (.claude/skills/*) ==="
echo ""
local dotclaude_skills="${REPO_ROOT}/.claude/skills"
local any_broken=0
if [[ ! -d "$dotclaude_skills" ]]; then
echo " [${WARN}] .claude/skills/ ディレクトリが存在しません"
echo ""
return
fi
for link in "${dotclaude_skills}"/*; do
local link_name
link_name=$(basename "${link}")
local target
target=$(readlink "${link}" 2>/dev/null || echo "(readlink 失敗)")
if [[ -e "${link}" ]]; then
printf " [%b] %-30s -> %s\n" "$OK" "$link_name" "$target"
else
printf " [%b] %-30s -> %s (リンク切れ)\n" "$NG" "$link_name" "$target"
any_broken=$((any_broken + 1))
TOTAL_NG=$((TOTAL_NG + 1))
fi
done
echo ""
if [[ "$any_broken" -gt 0 ]]; then
echo -e " ${NG}: ${any_broken} 件のリンク切れ"
echo " 修正方法: (cd .claude/skills && ln -s ../../skills/<name> <name>)"
else
echo -e " ${OK}: リンク切れなし"
fi
echo ""
}
# ----------------------------------------------------------------
# E: skills-lock.json 整合確認
# ----------------------------------------------------------------
check_skills_lock() {
echo "=== E. skills-lock.json 整合確認 ==="
echo ""
local lock_file="${REPO_ROOT}/skills-lock.json"
if [[ ! -f "$lock_file" ]]; then
echo " [${WARN}] skills-lock.json が見つかりません"
TOTAL_WARN=$((TOTAL_WARN + 1))
echo ""
return
fi
local any_ng=0
while IFS=$'\t' read -r name loc; do
case "$loc" in
skills/)
printf " [%b] %-30s 実在場所: skills/\n" "$OK" "$name"
;;
.agents/skills/)
printf " [%b] %-30s 実在場所: .agents/skills/\n" "$OK" "$name"
;;
MISSING)
printf " [%b] %-30s 実在場所: ❌ MISSING\n" "$NG" "$name"
any_ng=$((any_ng + 1))
TOTAL_NG=$((TOTAL_NG + 1))
;;
esac
done < <(python3 - "${lock_file}" "${REPO_ROOT}" <<'PYEOF'
import json, os, sys
lock_file, repo_root = sys.argv[1], sys.argv[2]
with open(lock_file) as f:
d = json.load(f)
for name in d.get('skills', {}).keys():
in_skills = os.path.isdir(os.path.join(repo_root, f'skills/{name}'))
in_agents = os.path.isdir(os.path.join(repo_root, f'.agents/skills/{name}'))
if in_skills:
loc = 'skills/'
elif in_agents:
loc = '.agents/skills/'
else:
loc = 'MISSING'
print(f'{name}\t{loc}')
PYEOF
)
echo ""
if [[ "$any_ng" -gt 0 ]]; then
echo -e " ${NG}: ${any_ng} 件のエントリが実在しません"
else
echo -e " ${OK}: 全エントリが実在"
fi
echo ""
}
# ----------------------------------------------------------------
# ヘルパー関数
# ----------------------------------------------------------------
bool_str() {
if $1; then echo "✅"; else echo "❌"; fi
}
val_str() {
if [[ -n "$1" ]]; then echo "✅($1)"; else echo "❌(空)"; fi
}
# ----------------------------------------------------------------
# サマリー
# ----------------------------------------------------------------
print_summary() {
echo "=== 総合判定 ==="
echo ""
if [[ "$TOTAL_NG" -gt 0 ]]; then
echo -e " ${NG}: NG ${TOTAL_NG} 件 / WARN ${TOTAL_WARN} 件"
echo " → 詳細を確認して対応してください"
elif [[ "$TOTAL_WARN" -gt 0 ]]; then
echo -e " ${WARN}: NG 0 件 / WARN ${TOTAL_WARN} 件"
echo " → 軽微な警告があります"
else
echo -e " ${OK}: 全チェック通過"
fi
echo ""
}
# ----------------------------------------------------------------
# メイン
# ----------------------------------------------------------------
main() {
local mode="${1:---all}"
echo "Frontmatter & Symlink Checker"
echo "リポジトリ: ${REPO_ROOT}"
echo ""
case "$mode" in
--skills) check_skills ;;
--agents) check_agents ;;
--symlinks) check_symlinks ;;
--lock) check_skills_lock ;;
--all | *)
check_skills
check_agents
check_symlinks
check_skills_lock
;;
esac
print_summary
}
main "$@"
#!/usr/bin/env bash
# gh-issue.sh — gh issue create + sub-issues 紐付けの実例
#
# 使い方: ./script/gh-issue.sh <owner> <repo>
# 元スキル: skills/create-issue/SKILL.md(Step 2〜4)
# skills/project-create-issues/SKILL.md(Step 3: 親 Issue を作成、Step 6: sub-issue 紐付け)
#
# 前提条件:
# - gh CLI がインストールされ認証済みであること
# - 対象リポジトリへの Issues 書き込み権限があること
set -euo pipefail
OWNER="${1:?第1引数 owner が必要です (例: Fandhe-AI)}"
REPO="${2:?第2引数 repo が必要です (例: agent-cli-skills)}"
# ----------------------------------------------------------------
# 親 Issue を作成する
# ----------------------------------------------------------------
# 返り値: 作成された Issue 番号(stdout)
create_parent_issue() {
local title="$1"
local issue_url
issue_url=$(gh issue create \
--repo "${OWNER}/${REPO}" \
--title "${title}" \
--body "$(cat <<'EOF'
## 概要
このトラッキング Issue の目的を記述する。
## 背景
なぜこの作業が必要か。
## 受け入れ条件
- [ ] 条件1
- [ ] 条件2
## 関連
- Figma: (あれば記載)
- 関連 Issue: #(あれば記載)
EOF
)" \
--json url -q '.url')
echo "${issue_url}"
}
# ----------------------------------------------------------------
# 子 Issue を作成する
# ----------------------------------------------------------------
# 返り値: 作成された Issue 番号(stdout)
# 警告: title・body は呼び出し元でサニタイズ済みのリテラルを渡すこと。外部入力を直接渡してはならない。
create_child_issue() {
local title="$1"
local body="$2"
local issue_url
issue_url=$(gh issue create \
--repo "${OWNER}/${REPO}" \
--title "${title}" \
--body "${body}" \
--json url -q '.url')
echo "${issue_url}"
}
# ----------------------------------------------------------------
# Issue のノード ID を取得する(sub_issue_id に必要)
# ----------------------------------------------------------------
get_issue_node_id() {
local issue_number="$1"
gh issue view "${issue_number}" \
--repo "${OWNER}/${REPO}" \
--json id -q '.id'
}
# ----------------------------------------------------------------
# Sub-issue として親 Issue に紐付ける
# ----------------------------------------------------------------
# 元スキル: create-issue/SKILL.md Step 4、project-create-issues/SKILL.md Step 6
add_sub_issue() {
local parent_number="$1"
local child_node_id="$2"
gh api \
--method POST \
"repos/${OWNER}/${REPO}/issues/${parent_number}/sub_issues" \
-f "sub_issue_id=${child_node_id}"
}
# ----------------------------------------------------------------
# Issue 番号を URL から抽出するヘルパー
# ----------------------------------------------------------------
extract_issue_number() {
local issue_url="$1"
# URL 末尾の数字を取り出す(例: .../issues/42 → 42)
echo "${issue_url##*/}"
}
# ----------------------------------------------------------------
# メイン: 親 Issue + 子 Issue 2件 + sub-issues 紐付けのデモ
# ----------------------------------------------------------------
main() {
echo "[INFO] 親 Issue を作成中..."
local parent_url
parent_url=$(create_parent_issue "feat: 認証機能の実装")
local parent_number
parent_number=$(extract_issue_number "${parent_url}")
echo "[INFO] 親 Issue 作成完了: #${parent_number} (${parent_url})"
echo "[INFO] 子 Issue 1 を作成中..."
local child1_url
child1_url=$(create_child_issue \
"feat(auth): ソーシャルログイン実装" \
"OAuth2 を使用した Google/GitHub ログインを実装する。")
local child1_number
child1_number=$(extract_issue_number "${child1_url}")
echo "[INFO] 子 Issue 1 作成完了: #${child1_number}"
echo "[INFO] 子 Issue 2 を作成中..."
local child2_url
child2_url=$(create_child_issue \
"feat(auth): パスワードリセット機能を追加" \
"メール経由のパスワードリセットフローを実装する。")
local child2_number
child2_number=$(extract_issue_number "${child2_url}")
echo "[INFO] 子 Issue 2 作成完了: #${child2_number}"
echo "[INFO] Sub-issue として紐付け中..."
local child1_node_id
child1_node_id=$(get_issue_node_id "${child1_number}")
add_sub_issue "${parent_number}" "${child1_node_id}"
echo "[INFO] #${child1_number} を #${parent_number} の sub-issue として登録"
local child2_node_id
child2_node_id=$(get_issue_node_id "${child2_number}")
add_sub_issue "${parent_number}" "${child2_node_id}"
echo "[INFO] #${child2_number} を #${parent_number} の sub-issue として登録"
echo ""
echo "=== 作成完了 ==="
echo " 親 Issue: #${parent_number} ${parent_url}"
echo " 子 Issue: #${child1_number} ${child1_url}"
echo " 子 Issue: #${child2_number} ${child2_url}"
}
main "$@"
#!/usr/bin/env bash
# gh-pr.sh — gh pr create の実例(body を HEREDOC で安全に渡す)
#
# 使い方: ./script/gh-pr.sh
# 元スキル: skills/create-pr/SKILL.md(Step 5: PR を作成する)
# skills/contribute-skill/SKILL.md(Step 10: push と PR 作成)
#
# 前提条件:
# - gh CLI がインストールされ認証済みであること(gh auth status で確認)
# - 現在のブランチがベースブランチからフォークされていること
# - セキュリティチェック(OWASP Top 10・シークレット確認)を事前に実施済みであること
set -euo pipefail
# ----------------------------------------------------------------
# 変数(呼び出し元で設定するか引数で渡す)
# ----------------------------------------------------------------
BASE_BRANCH="${1:-main}"
PR_TITLE="${2:-feat(scope): subject を記入してください}"
# ----------------------------------------------------------------
# 事前確認
# ----------------------------------------------------------------
preflight_check() {
# gh CLI の認証確認
if ! gh auth status &>/dev/null; then
echo "[ERROR] gh CLI が認証されていません。gh auth login を実行してください。" >&2
exit 1
fi
# ベースブランチとの差分確認
echo "[INFO] ベースブランチ (${BASE_BRANCH}) との差分:"
git log "${BASE_BRANCH}..HEAD" --oneline
echo ""
git diff "${BASE_BRANCH}...HEAD" --stat
echo ""
}
# ----------------------------------------------------------------
# PR 作成(body は HEREDOC で渡す)
# ----------------------------------------------------------------
create_pr() {
local title="$1"
local base="$2"
gh pr create \
--base "${base}" \
--title "${title}" \
--body "$(cat <<'EOF'
## Summary
- 変更内容の箇条書き1
- 変更内容の箇条書き2
## Test plan
- [ ] 動作確認手順1
- [ ] 動作確認手順2
- [ ] エッジケース確認
## Design
- Figma: (あれば記載)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
EOF
)"
}
# ----------------------------------------------------------------
# Draft PR の例(ユーザー確認後に --draft を付ける)
# ----------------------------------------------------------------
create_draft_pr() {
local title="$1"
local base="$2"
gh pr create \
--draft \
--base "${base}" \
--title "${title}" \
--body "$(cat <<'EOF'
## Summary
WIP: 作業中の変更。
## Test plan
- [ ] 未完了
🤖 Generated with [Claude Code](https://claude.com/claude-code)
EOF
)"
}
# ----------------------------------------------------------------
# PR に reviewers / labels を追加する例
# ----------------------------------------------------------------
create_pr_with_options() {
local title="$1"
local base="$2"
local reviewer="${3:-}" # GitHub username(任意)
local label="${4:-}" # ラベル名(任意)
gh pr create \
--base "${base}" \
--title "${title}" \
${reviewer:+--reviewer "${reviewer}"} \
${label:+--label "${label}"} \
--body "$(cat <<'EOF'
## Summary
- ...
## Test plan
- [ ] ...
🤖 Generated with [Claude Code](https://claude.com/claude-code)
EOF
)"
}
# ----------------------------------------------------------------
# メイン
# ----------------------------------------------------------------
main() {
preflight_check
# 通常の PR 作成例
# create_pr "${PR_TITLE}" "${BASE_BRANCH}"
# Draft PR 作成例
# create_draft_pr "${PR_TITLE}" "${BASE_BRANCH}"
# reviewer / label 付き PR 作成例
# create_pr_with_options "${PR_TITLE}" "${BASE_BRANCH}" "<reviewer-username>" "enhancement"
echo "[INFO] PR_TITLE と BASE_BRANCH を設定し、関数呼び出しのコメントを外して実行してください。"
echo " PR_TITLE 例: feat(auth): ソーシャルログイン機能を追加"
}
main "$@"
#!/usr/bin/env bash
# gh-project.sh — GitHub Projects v2 の実コマンド集
#
# 使い方: ./script/gh-project.sh <owner> <project-number>
# 元スキル: skills/project-add-items/SKILL.md(Step 3〜5)
# skills/project-create-issues/SKILL.md(Step 5: item-add, item-edit, item-delete)
# skills/project-update-items/SKILL.md(Step 2〜5)
# skills/project-archive-done/SKILL.md(アーカイブ操作)
#
# 前提条件:
# - gh CLI がインストールされ認証済みであること(project スコープ付き)
# - gh auth status で project スコープがあることを確認
set -euo pipefail
OWNER="${1:?第1引数 owner が必要です (例: Fandhe-AI)}"
PROJECT_NUMBER="${2:?第2引数 project-number が必要です (例: 1)}"
# ----------------------------------------------------------------
# プロジェクト ID を取得する
# ----------------------------------------------------------------
get_project_id() {
gh project view "${PROJECT_NUMBER}" \
--owner "${OWNER}" \
--format json \
-q '.id'
}
# ----------------------------------------------------------------
# フィールド一覧とオプション ID を取得する(jq でパース)
# ----------------------------------------------------------------
# 元スキル: project-add-items/SKILL.md Step 3、project-update-items/SKILL.md Step 2
get_field_list() {
gh project field-list "${PROJECT_NUMBER}" \
--owner "${OWNER}" \
--format json
}
# フィールド名→フィールド ID を解決する例(jq を使用)
# 例: get_field_id_by_name "Status"
get_field_id_by_name() {
local field_name="$1"
local field_json
field_json="$(get_field_list)"
FIELD_NAME="${field_name}" FIELDS_JSON="${field_json}" python3 - <<'PYEOF'
import json, os
data = json.loads(os.environ['FIELDS_JSON'])
fields = data.get('fields', [])
target = os.environ['FIELD_NAME']
for f in fields:
if f.get('name') == target:
print(f['id'])
break
PYEOF
}
# フィールドのオプション名→オプション ID を解決する例
# 例: get_option_id_by_name "Status" "In Progress"
get_option_id_by_name() {
local field_name="$1"
local option_name="$2"
local field_json
field_json="$(get_field_list)"
FIELD_NAME="${field_name}" OPTION_NAME="${option_name}" FIELDS_JSON="${field_json}" python3 - <<'PYEOF'
import json, os
data = json.loads(os.environ['FIELDS_JSON'])
fields = data.get('fields', [])
target_field = os.environ['FIELD_NAME']
target_opt = os.environ['OPTION_NAME']
for f in fields:
if f.get('name') == target_field:
for opt in f.get('options', []):
if opt.get('name') == target_opt:
print(opt['id'])
break
PYEOF
}
# ----------------------------------------------------------------
# アイテム一覧を取得する
# ----------------------------------------------------------------
# 元スキル: project-update-items/SKILL.md Step 3、project-create-issues/SKILL.md Step 1
list_items() {
gh project item-list "${PROJECT_NUMBER}" \
--owner "${OWNER}" \
--format json \
--limit 999
}
# DraftIssue のみを抽出する例
list_draft_items() {
list_items | python3 -c "
import sys, json
data = json.load(sys.stdin)
items = data.get('items', [])
for item in items:
if item.get('type') == 'DraftIssue':
print(json.dumps(item, ensure_ascii=False))
"
}
# ----------------------------------------------------------------
# アイテムを作成する(DraftIssue)
# ----------------------------------------------------------------
# 元スキル: project-add-items/SKILL.md Step 4
create_draft_item() {
local title="$1"
local body="${2:-}"
gh project item-create "${PROJECT_NUMBER}" \
--owner "${OWNER}" \
--title "${title}" \
--body "${body}" \
--format json
}
# ----------------------------------------------------------------
# アイテムにフィールド値を設定する
# ----------------------------------------------------------------
# 元スキル: project-add-items/SKILL.md Step 5、project-update-items/SKILL.md Step 5
# SINGLE_SELECT フィールドの設定例(Status / Priority / Size)
set_single_select_field() {
local item_id="$1"
local project_id="$2"
local field_id="$3"
local option_id="$4"
gh project item-edit \
--id "${item_id}" \
--field-id "${field_id}" \
--project-id "${project_id}" \
--single-select-option-id "${option_id}"
}
# TEXT フィールドの設定例
set_text_field() {
local item_id="$1"
local project_id="$2"
local field_id="$3"
local text_value="$4"
gh project item-edit \
--id "${item_id}" \
--field-id "${field_id}" \
--project-id "${project_id}" \
--text "${text_value}"
}
# NUMBER フィールドの設定例
set_number_field() {
local item_id="$1"
local project_id="$2"
local field_id="$3"
local number_value="$4"
gh project item-edit \
--id "${item_id}" \
--field-id "${field_id}" \
--project-id "${project_id}" \
--number "${number_value}"
}
# DATE フィールドの設定例(YYYY-MM-DD 形式)
set_date_field() {
local item_id="$1"
local project_id="$2"
local field_id="$3"
local date_value="$4" # 例: 2026-06-30
gh project item-edit \
--id "${item_id}" \
--field-id "${field_id}" \
--project-id "${project_id}" \
--date "${date_value}"
}
# ----------------------------------------------------------------
# Issue をプロジェクトに追加する(DraftIssue → 実 Issue 変換後に使用)
# ----------------------------------------------------------------
# 元スキル: project-create-issues/SKILL.md Step 5
add_issue_to_project() {
local issue_url="$1"
gh project item-add "${PROJECT_NUMBER}" \
--owner "${OWNER}" \
--url "${issue_url}" \
--format json
}
# ----------------------------------------------------------------
# DraftIssue アイテムを削除する
# ----------------------------------------------------------------
# 元スキル: project-create-issues/SKILL.md Step 5
delete_draft_item() {
local item_id="$1"
gh project item-delete "${PROJECT_NUMBER}" \
--owner "${OWNER}" \
--id "${item_id}"
}
# ----------------------------------------------------------------
# アイテムをアーカイブする(Done 状態のアイテムをアーカイブ等)
# ----------------------------------------------------------------
# 元スキル: skills/project-archive-done/SKILL.md
archive_item() {
local item_id="$1"
gh project item-archive "${PROJECT_NUMBER}" \
--owner "${OWNER}" \
--id "${item_id}"
}
# ----------------------------------------------------------------
# メイン: 動作確認用のデモ(実際には各関数を用途に合わせて呼び出す)
# ----------------------------------------------------------------
main() {
echo "[INFO] プロジェクト情報を確認中..."
local project_id
project_id=$(get_project_id)
echo "[INFO] プロジェクト ID: ${project_id}"
echo "[INFO] フィールド一覧を取得中..."
get_field_list | python3 -m json.tool | head -40
echo ""
echo "[INFO] アイテム一覧を取得中..."
list_items | python3 -c "
import sys, json
data = json.load(sys.stdin)
items = data.get('items', [])
print(f'合計 {len(items)} 件')
for item in items[:5]:
print(f' - {item.get(\"title\", \"(タイトルなし)\")} [{item.get(\"type\")}]')
"
echo ""
echo "[INFO] 使用例(コメントアウトを外して使用):"
echo " create_draft_item \"feat: 新機能タイトル\" \"本文説明\""
echo " set_single_select_field \"\$item_id\" \"\$project_id\" \"\$status_field_id\" \"\$in_progress_option_id\""
}
main "$@"
#!/usr/bin/env bash
# git-commit.sh — Conventional Commits 形式でのコミット実例
#
# 使い方: ./script/git-commit.sh
# 元スキル: skills/create-commit/SKILL.md(Step 5: コミットを実行する)
# skills/contribute-skill/SKILL.md(Step 9: ブランチ作成・コミット)
# .claude/rules/conventional-commits.md(コミット実行パターン)
#
# 重要:
# - --no-verify は絶対に使用しない(pre-commit フック回避禁止)
# - printf -v で変数にビルドすることで特殊文字・コマンド展開を安全に扱える
# - .env や認証情報ファイルが staged に含まれる場合はコミットを中止する
set -euo pipefail
# ----------------------------------------------------------------
# シークレット混入チェック
# ----------------------------------------------------------------
check_no_secrets() {
local secret_files
secret_files=$(git diff --cached --name-only | grep -E '(\.env|credentials\.json|\.pem|\.key|id_rsa)' || true)
if [[ -n "$secret_files" ]]; then
echo "[ERROR] シークレットが含まれる可能性のあるファイルが staged に含まれています:" >&2
echo "$secret_files" >&2
echo "[ERROR] git restore --staged <ファイル名> でステージングを解除してください。" >&2
exit 1
fi
}
# ----------------------------------------------------------------
# staged 変更の確認
# ----------------------------------------------------------------
check_staged() {
local staged
staged=$(git diff --cached --name-only)
if [[ -z "$staged" ]]; then
echo "[INFO] staged な変更がありません。git add でファイルをステージングしてください。"
git status
exit 1
fi
echo "[INFO] staged ファイル:"
git diff --cached --name-only
echo ""
}
# ----------------------------------------------------------------
# コミット実行(printf -v で変数にビルドし特殊文字を安全に渡す)
# ----------------------------------------------------------------
# 引数: TYPE SCOPE SUBJECT [BODY]
# TYPE: Conventional Commits の type(feat, fix, docs, refactor, test, chore, ...)
# SCOPE: スコープ(省略可。省略する場合は "" を渡す)
# SUBJECT: コミットメッセージの件名(72文字以内、命令形・現在形)
# BODY: コミットメッセージの本文(任意)
do_commit() {
local type="${1:?TYPE が必要です}"
local scope="${2:-}"
local subject="${3:?SUBJECT が必要です}"
local body="${4:-}"
# scope がある場合は括弧付きで結合
local scope_part=""
if [[ -n "$scope" ]]; then
scope_part="(${scope})"
fi
# 件名の長さチェック
local full_subject="${type}${scope_part}: ${subject}"
if [[ ${#full_subject} -gt 72 ]]; then
echo "[WARN] 件名が 72 文字を超えています (${#full_subject} 文字): ${full_subject}" >&2
fi
local full_msg
if [[ -n "$body" ]]; then
printf -v full_msg '%s%s: %s\n\n%s\n\nCo-Authored-By: Claude <noreply@anthropic.com>' \
"${type}" "${scope_part}" "${subject}" "${body}"
else
printf -v full_msg '%s%s: %s\n\nCo-Authored-By: Claude <noreply@anthropic.com>' \
"${type}" "${scope_part}" "${subject}"
fi
git commit -m "$full_msg"
}
# ----------------------------------------------------------------
# 使用例(実際の引数は書き換えて使う)
# ----------------------------------------------------------------
main() {
check_staged
check_no_secrets
# 例 1: feat(auth): ソーシャルログイン機能を追加
# do_commit "feat" "auth" "ソーシャルログイン機能を追加"
# 例 2: fix(api): レスポンスのエラーハンドリングを修正(本文付き)
# do_commit "fix" "api" "レスポンスのエラーハンドリングを修正" "500 エラー時に詳細メッセージを返すよう修正。\nRefs #42"
# 例 3: chore(skills): symlink を作成(scope なし)
# do_commit "chore" "" "symlink を作成"
# 例 4: Breaking Change
# do_commit "feat!" "auth" "認証 API の仕様を変更" "BREAKING CHANGE: レスポンス形式が v1 と互換性なし。移行手順は docs/ 参照。"
echo "[INFO] 使用例をコメントアウトから選択して実行してください。"
echo " 型: feat fix docs refactor test chore style build ci perf"
}
main "$@"
script/ — 実行可能コマンド集
このリポジトリで Claude が実際に使っているコマンドを、動作するシェルスクリプトとして整備したリファレンス集。 各スクリプトは「どのスキルのどのステップが元ネタか」を冒頭コメントに記載している。
スクリプト一覧
| ファイル | 用途 | 元スキル |
|---|---|---|
git-commit.sh | Conventional Commits 形式でのコミット(HEREDOC、シークレット混入チェック) | create-commit, contribute-skill, conventional-commits.md |
gh-pr.sh | gh pr create の実例(body を HEREDOC で渡す、Draft PR、reviewer/label 付き) | create-pr, contribute-skill |
gh-issue.sh | gh issue create + sub-issues 紐付け(gh api .../sub_issues) | create-issue, project-create-issues |
gh-project.sh | gh project item-create / item-edit / item-delete / item-archive など Projects v2 の実コマンド | project-add-items, project-create-issues, project-update-items |
skills-sync.sh | symlink 作成(ln -s ../../skills/<name> .claude/skills/<name>)と skills-lock.json の状態確認 | contribute-skill, sync-skills-lock, skill-authoring.md |
frontmatter-check.sh | 全 SKILL.md / agent / rule の frontmatter 必須項目と symlink リンク切れを検査(読み取り専用) | frontmatter-linter agent |
使い方
# スクリプトに実行権限を付与
chmod +x skills/claude-code-reference/script/*.sh
# コミットのヘルパーを確認
./skills/claude-code-reference/script/git-commit.sh
# PR 作成の確認
./skills/claude-code-reference/script/gh-pr.sh main "feat(auth): ソーシャルログイン機能を追加"
# Issue 作成と sub-issues 紐付け
./skills/claude-code-reference/script/gh-issue.sh <owner> <repo>
# GitHub Projects v2 の操作
./skills/claude-code-reference/script/gh-project.sh <owner> <project-number>
# symlink 作成(新スキル追加後)
./skills/claude-code-reference/script/skills-sync.sh <skill-name>
# 全スキルの状態確認(symlink + symlink 切れ)
./skills/claude-code-reference/script/skills-sync.sh
# frontmatter 全チェック
./skills/claude-code-reference/script/frontmatter-check.sh --all
# SKILL.md のみチェック
./skills/claude-code-reference/script/frontmatter-check.sh --skills設計原則
全スクリプト共通で以下の規約に従っている:
1. 冒頭に `#!/usr/bin/env bash` と `set -euo pipefail` — エラーで即座に停止し、未定義変数・パイプ失敗を検出する 2. 変数は必ずダブルクォートで囲む — コマンドインジェクション対策("$var" 形式) 3. プレースホルダは `<owner>` `<repo>` `<number>` 形式 — 実際の値に置き換えて使用 4. 破壊的操作なし — rm -rf・git push --force・git commit --no-verify は含まない 5. 読み取り専用スクリプトは副作用なし — frontmatter-check.sh はファイルを変更しない
注意事項
- 各スクリプトはデモ用の「使用例」。実際の引数・タイトルは書き換えて使用すること
- GitHub 操作(
ghコマンド)はgh auth statusで認証済みであることを確認してから実行 - sandbox 環境では
GIT_SSL_NO_VERIFY=1の併用が必要な場合がある(docs/sandbox-tls.md参照)
#!/usr/bin/env bash
# skills-sync.sh — スキルの symlink 作成と skills-lock.json 同期の実例
#
# 使い方: ./script/skills-sync.sh [skill-name]
# 元スキル: skills/contribute-skill/SKILL.md(Step 6: upstream clone)
# skills/sync-skills-lock/SKILL.md(Step 3〜7: ハッシュ同期)
# .claude/agents/author/skill-author.md(Step 5: symlink 案内)
# .claude/rules/skill-authoring.md(新スキル追加手順 Step 2)
#
# このスクリプトは以下の2つの用途をカバーする:
# 1. 新スキルの symlink を .claude/skills/ に作成する
# 2. skills-lock.json の computedHash を upstream と同期する(確認のみ)
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
# ----------------------------------------------------------------
# 用途1: スキルの symlink を作成する
# ----------------------------------------------------------------
# 元スキル: skill-authoring.md Step 2
# ln -s ../../skills/<name> .claude/skills/<name>
#
# .claude/skills/<name> → ../../skills/<name>/SKILL.md を辿れるようにする。
# 相対パスで指定することで、リポジトリをどこに clone しても壊れない。
create_symlink() {
local skill_name="${1:?スキル名が必要です}"
local skills_dir="${REPO_ROOT}/skills"
local dotclaude_skills_dir="${REPO_ROOT}/.claude/skills"
# スキルディレクトリの存在確認
if [[ ! -d "${skills_dir}/${skill_name}" ]]; then
echo "[ERROR] skills/${skill_name}/ が存在しません。" >&2
echo "[INFO] 先に skills/${skill_name}/SKILL.md を作成してください。" >&2
exit 1
fi
# .claude/skills/ ディレクトリが存在しなければ作成
mkdir -p "${dotclaude_skills_dir}"
# symlink が既に存在する場合はスキップ
if [[ -e "${dotclaude_skills_dir}/${skill_name}" ]]; then
echo "[INFO] symlink は既に存在します: .claude/skills/${skill_name}"
ls -la "${dotclaude_skills_dir}/${skill_name}"
return 0
fi
# 相対パスで symlink を作成(絶対パスを避けることでポータブルになる)
# ln の -s オプションのみ使用。-f(強制上書き)は使わない(安全のため)
(
cd "${dotclaude_skills_dir}"
ln -s "../../skills/${skill_name}" "${skill_name}"
)
echo "[OK] symlink 作成: .claude/skills/${skill_name} -> ../../skills/${skill_name}"
}
# ----------------------------------------------------------------
# 全スキルの symlink 状態を確認する
# ----------------------------------------------------------------
# 元スキル: .claude/agents/quality/frontmatter-linter.md Step 4
check_symlinks() {
local dotclaude_skills_dir="${REPO_ROOT}/.claude/skills"
echo "[INFO] .claude/skills/ の symlink 状態:"
echo ""
local broken=0
for link in "${dotclaude_skills_dir}"/*; do
local link_name
link_name=$(basename "${link}")
local target
target=$(readlink "${link}" 2>/dev/null || echo "(readlink 失敗)")
if [[ -e "${link}" ]]; then
echo " OK: ${link_name} -> ${target}"
else
echo " BROKEN: ${link_name} -> ${target}"
broken=$((broken + 1))
fi
done
echo ""
if [[ "$broken" -gt 0 ]]; then
echo "[WARN] リンク切れが ${broken} 件あります。"
echo "[INFO] 修正方法: ln -s ../../skills/<name> .claude/skills/<name>"
else
echo "[OK] リンク切れなし"
fi
}
# ----------------------------------------------------------------
# スキル一覧と symlink の対応を確認する
# ----------------------------------------------------------------
check_all_skills_have_symlinks() {
local skills_dir="${REPO_ROOT}/skills"
local dotclaude_skills_dir="${REPO_ROOT}/.claude/skills"
echo "[INFO] skills/ ↔ .claude/skills/ の対応確認:"
echo ""
local missing=0
for skill_dir in "${skills_dir}"/*/; do
local skill_name
skill_name=$(basename "${skill_dir}")
if [[ -e "${dotclaude_skills_dir}/${skill_name}" ]]; then
echo " OK: ${skill_name}"
else
echo " MISSING: ${skill_name} (symlink がありません)"
missing=$((missing + 1))
fi
done
echo ""
if [[ "$missing" -gt 0 ]]; then
echo "[WARN] symlink がないスキルが ${missing} 件あります。"
echo "[INFO] 追加コマンド:"
for skill_dir in "${skills_dir}"/*/; do
local skill_name
skill_name=$(basename "${skill_dir}")
if [[ ! -e "${dotclaude_skills_dir}/${skill_name}" ]]; then
echo " ln -s ../../skills/${skill_name} .claude/skills/${skill_name}"
fi
done
else
echo "[OK] 全スキルに symlink があります"
fi
}
# ----------------------------------------------------------------
# skills-lock.json の computedHash を確認する(読み取り専用)
# ----------------------------------------------------------------
# 元スキル: sync-skills-lock/SKILL.md Step 4〜5
# 実際の更新は sync-skills-lock スキルが行う。このスクリプトは確認のみ。
check_skills_lock() {
local lock_file="${REPO_ROOT}/skills-lock.json"
if [[ ! -f "$lock_file" ]]; then
echo "[INFO] skills-lock.json が見つかりません(スキップ)"
return 0
fi
echo "[INFO] skills-lock.json のスキル一覧:"
LOCK_FILE="${lock_file}" python3 - <<'PYEOF'
import json, os
with open(os.environ['LOCK_FILE']) as f:
d = json.load(f)
skills = d.get('skills', {})
print(f' 合計 {len(skills)} スキル')
for name, info in skills.items():
source = info.get('source', '(source なし)')
h = info.get('computedHash', '(hash なし)')
print(f' - {name}: source={source}, hash={h[:10]}...')
PYEOF
}
# ----------------------------------------------------------------
# メイン
# ----------------------------------------------------------------
main() {
local skill_name="${1:-}"
if [[ -n "$skill_name" ]]; then
echo "[INFO] スキル '${skill_name}' の symlink を作成します..."
create_symlink "${skill_name}"
echo ""
echo "[INFO] 次のステップ:"
echo " 1. update-docs スキルを実行して CLAUDE.md を更新する"
echo " 2. git add .claude/skills/${skill_name} && git commit -m 'chore(skills): ${skill_name} の symlink を追加'"
else
echo "[INFO] 全スキルの状態を確認します..."
echo ""
check_symlinks
echo ""
check_all_skills_have_symlinks
echo ""
check_skills_lock
fi
}
main "$@"