hook-creator について
hook-creatorは、Claude Codeのマルチエージェント・オーケストレーションフレームワークでHookを作成、検証、登録するスキルです。安全性、メモリ、ルーティング、セッション管理を扱い、テスト、文書、システムへの登録も必須とします。
主な機能
- 01安全性、メモリ、ルーティング、セッション用Hookの作成
- 02トリガー種別に応じた配置先の選択
- 03各Hookのテスト作成
- 04Hook登録と文書更新
活用シーン
- 01コマンド実行前の操作検証やブロック
- 02タスク完了後の記録やメモリ更新
- 03プロンプト送信やセッション開始・終了時の処理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ oimiragieo/ agent-studio --skill hook-creatorインストール後、Claude Code で/hook-creatorを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
commands/hook-creator.mdhooks/post-execute.cjspre-execute.cjsreferences/research-requirements.mdrules/hook-creator.mdschemas/input.schema.jsonoutput.schema.jsonscripts/main.cjstemplates/implementation-template.md詳細
フック作成スキル
マルチエージェントオーケストレーションフレームワーク用のフックを作成、検証、登録します。
ルーターの更新が必須です(重要 — 必ず実施してください)
フックを作成した後は、必ずドキュメントを更新してください。
1. Add to .claude/hooks/README.md under appropriate category
2. Register in config.yaml or settings.json if required
3. Update learnings.md with hook summary
検証:
grep "<hook-name>" .claude/hooks/README.md || echo "ERROR: hooks/README.md NOT UPDATED!"
理由:ドキュメントに記載されていないフックは、認識されず、保守もできません。
概要
このスキルでは、Claude Code フレームワーク用のフックを作成します。
- ツール実行前 — コマンド実行前の安全性を検証します
- ツール実行後 — ログ記録、メモリ更新、テレメトリを行います
- セッションのライフサイクル — コンテキストを初期化し、終了時にクリーンアップします
- メモリ管理 — 学びを自動抽出し、メモリファイルを整形します
- ルーティングの適用 — Router-First プロトコルへの準拠を確保します
フックの種類
| 種類 | 場所 | 目的 | 起動タイミング |
|---|---|---|---|
| 安全性 | .claude/hooks/safety/ | コマンドを検証し、危険な操作をブロックする | Bash/Write/Edit の前 |
| メモリ | .claude/hooks/memory/ | 学びを自動更新し、洞察を抽出する | タスク完了後 |
| ルーティング | .claude/hooks/routing/ | ルーターファーストプロトコルを適用する | UserPromptSubmit 時 |
| セッション | .claude/hooks/session/ | セッションを初期化/クリーンアップする | セッション開始/終了時 |
フックとエージェントのアーキタイプの参照
フックを作成する際は、新しいフックの適用対象となるエージェントのアーキタイプを特定してください。.claude/docs/@HOOK_AGENT_MAP.md を参照してください。
- セクション 1:フックとエージェントの完全な対応表
- セクション 2:アーキタイプごとのフックセット(Router、Implementer、Reviewer、Documenter、Orchestrator、Researcher)
フックを作成した後は、必ず対応表に追加し、影響を受けるエージェントの ## Enforcement Hooks セクションも更新してください。
Claude Code のフックの種類
| フックイベント | 起動タイミング | 用途 |
|---|---|---|
PreToolUse | ツールの実行前 | 検証、ブロック、権限チェック |
PostToolUse | ツールの完了後 | ログ記録、クリーンアップ、通知 |
UserPromptSubmit | モデルがメッセージを見る前 | ルーティング、意図分析、フィルタリング |
ワークフローの手順
ステップ 0:存在確認とアップデーターへの委任(必須 — 最初に実施)
フックファイルを作成する前に、すでに存在しているか確認してください。
-
フックがすでに存在するか確認します。
test -f .claude/hooks/<category>/<hook-name>.cjs && echo "EXISTS" || echo "NEW" -
フックが存在する場合:
-
作成を続行しないでください
-
代わりに artifact-updater ワークフローを実行します。
Skill({ skill: 'artifact-updater', args: '--type hook --path .claude/hooks/<category>/<hook-name>.cjs --changes "<description of requested changes>"', }); -
アップデーターの結果を返し、そこで終了します
-
-
フックが新規の場合:
- 以下のステップ 0.5 に進みます
ステップ 0.1:重複のスマート検出(必須)
作成を進める前に、3 層の重複チェックを実行してください。
const { checkDuplicate } = require('.claude/lib/creation/duplicate-detector.cjs');
const result = checkDuplicate({
artifactType: 'hook',
name: proposedName,
description: proposedDescription,
keywords: proposedKeywords || [],
});
結果への対応:
EXACT_MATCH:作成を中止します。代わりにhook-updaterスキルに引き継ぎます:Skill({ skill: 'hook-updater' })REGISTRY_MATCH:ユーザーに警告します。成果物は登録されていますが、ファイルが存在しない可能性があります。作成する前に調査し、ユーザーに確認してください。SIMILAR_FOUND:候補をスコアとともに表示します。ユーザーに「類似する成果物が見つかりました。新規作成を続けるか、既存のものを更新しますか?」と尋ねます。NO_MATCH:ステップ 0.5(関連ファイルの確認)に進みます。
例外:ユーザーが --force を明示的に指定した場合、このチェックを完全に省略します。
Step 0.5: コンパニオンの確認
作成に進む前に、エコシステムのコンパニオン確認を実行します。
.claude/lib/creators/companion-check.cjsのcompanion-check.cjsを使用しますcheckCompanions("hook", "{hook-name}")を呼び出して、コンパニオン成果物を特定します- コンパニオンチェックリストを確認し、不足している必須/推奨コンパニオンを記録します
- この成果物の完成後に、不足しているコンパニオンを作成または確認する計画を立てます
- 作成後の統合メモに、コンパニオンの確認結果を含めます
この手順は情報提供のみ(作成を妨げるものではありません)ですが、成果物のエコシステム全体を確実に考慮できます。
参照フック
正式なルーティングの参照先として .claude/lib/routing/routing-table.cjs を使用してください。
フックを確定する前に、ルーティングテーブルの構造と照合します。
- 適切な CommonJS エクスポート(module.exports)がある
- フックの種類に必要な関数(validate、main など)をエクスポートしている
- 適切なテストファイル(.test.cjs)がある
- 適切なエラー処理(try/catch、フォールバック処理)がある
- フックの種類に応じた正しい応答形式を返す
Step 1: フックの要件を収集する
フックを作成する前に、以下を収集します。
- 目的:このフックは何をするものですか?
- トリガー:いつ実行しますか?(ツール実行前、ツール実行後、セッションイベント)
- 対象ツール:どのツールに適用しますか?(Bash、Write、Edit、Read)
- 動作:操作をブロックしますか、それとも警告のみですか?
- 終了コード:何を成功/失敗として示しますか?
// Example requirements gathering
{
purpose: "Validate git push commands to prevent force push",
trigger: "pre-tool (Bash)",
target_tools: ["Bash"],
behavior: "block if force push detected",
exit_codes: { 0: "allow", 1: "block" }
}
Step 2: フックの種類と配置場所を決める
| フックの処理内容 | 種類 | 配置場所 |
|---|---|---|
| コマンドを検証する | Safety | .claude/hooks/safety/ |
| ルーティングを変更する | Routing | .claude/hooks/routing/ |
| メモリを更新する | Memory | .claude/hooks/memory/ |
| セッションの初期化/クリーンアップ | Session | .claude/hooks/session/ |
命名規則: <action>-<target>.cjs
例:
validate-git-force-push.cjsenforce-tdd-workflow.cjsextract-workflow-learnings.cjsmemory-reminder.cjs
Step 3: フックのコードを生成する(CJS 形式)
すべてのフックは CommonJS 形式を使用し、以下のテンプレートに従います。
'use strict';
/**
* {Hook Name}
*
* Type: {pre|post}-{tool} | session-{start|end} | user-prompt
* Purpose: {One line description}
* Trigger: {When this hook runs}
*
* Exit codes:
* - 0: Allow operation (with optional warning)
* - 1: Block operation (when in blocking mode)
*
* Environment:
* {HOOK_NAME}_MODE=block|warn|off (default: warn unless explicitly required)
*/
const fs = require('fs');
const path = require('path');
// Find project root by looking for .claude directory
function findProjectRoot() {
let dir = __dirname;
while (dir !== path.parse(dir).root) {
if (fs.existsSync(path.join(dir, '.claude'))) {
return dir;
}
dir = path.dirname(dir);
}
return process.cwd();
}
const PROJECT_ROOT = findProjectRoot();
const ENFORCEMENT_MODE = process.env.HOOK_NAME_MODE || 'warn';
/**
* Parse hook input from Claude Code
* Claude Code passes JSON via process.argv[2] for hooks
* @returns {Object|null} Parsed hook input or null
*/
function parseHookInput() {
try {
if (process.argv[2]) {
return JSON.parse(process.argv[2]);
}
} catch (e) {
// Fallback for testing or invalid input
}
return null;
}
/**
* Validate hook - called by Claude Code or programmatically
* @param {Object} context - Hook context with tool info
* @param {string} context.tool - Tool name (Bash, Write, Edit, Read)
* @param {Object} context.parameters - Tool parameters
* @returns {Object} Validation result with valid (boolean), error (string), and optional warning (string)
*/
function validate(context) {
const { tool, parameters } = context;
// YOUR VALIDATION LOGIC HERE
// Return validation result
return { valid: true, error: '' };
}
/**
* Main execution for CLI hook usage
*/
function main() {
// Skip if enforcement is off
if (ENFORCEMENT_MODE === 'off') {
process.exit(0);
}
const hookInput = parseHookInput();
if (!hookInput) {
process.exit(0);
}
// Get tool name and input
const toolName = hookInput.tool_name || hookInput.tool;
const toolInput = hookInput.tool_input || hookInput.input || {};
// Run validation
const result = validate({ tool: toolName, parameters: toolInput });
if (!result.valid) {
if (ENFORCEMENT_MODE === 'block') {
console.error(`BLOCKED: ${result.error}`);
process.exit(1);
} else {
console.warn(`WARNING: ${result.error}`);
process.exit(0);
}
}
if (result.warning) {
console.warn(`WARNING: ${result.warning}`);
}
process.exit(0);
}
// Run main if executed directly
if (require.main === module) {
main();
}
// Export for programmatic use and testing
module.exports = {
validate,
findProjectRoot,
PROJECT_ROOT,
};
Step 4: テストファイルを作成する
すべてのフックには、対応するテストファイルが必須です。
'use strict';
const { validate } = require('./hook-name.cjs');
describe('Hook Name', () => {
test('allows valid operations', () => {
const result = validate({
tool: 'Bash',
parameters: { command: 'git status' },
});
expect(result.valid).toBe(true);
expect(result.error).toBe('');
});
test('blocks dangerous operations', () => {
const result = validate({
tool: 'Bash',
parameters: { command: 'git push --force' },
});
expect(result.valid).toBe(false);
expect(result.error).toContain('force push');
});
test('handles missing parameters gracefully', () => {
const result = validate({
tool: 'Bash',
parameters: {},
});
expect(result.valid).toBe(true);
});
});
Step 5: フックを登録する(必要な場合)
設定ファイルへの登録が必要なフックもあります。
ツール実行前/実行後のフックの場合(settings.json):
{
"hooks": {
"pre-tool": [".claude/hooks/safety/hook-name.cjs"],
"post-tool": [".claude/hooks/memory/hook-name.cjs"]
}
}
イベントフックの場合(config.yaml):
hooks:
UserPromptSubmit:
- path: .claude/hooks/routing/hook-name.cjs
type: command
SessionStart:
- path: .claude/hooks/session/hook-name.cjs
type: command
Step 6: ドキュメントを更新する(必須・ブロッキング)
フックを作成した後、.claude/hooks/README.md を更新します。
#### {Hook Name} (`hook-name.cjs`)
{Description of what the hook does}
**When it runs:** {Trigger condition}
**What it checks/does:** {Detailed behavior}
以下を実行して確認します。
grep "hook-name" .claude/hooks/README.md || echo "ERROR: Not documented!"
Step 7: システムへの影響を分析する(必須)
この分析は必須です。これを行わずにフックを作成しても、作成は完了していません。
フックを作成した後、以下を実施します。
-
設定への登録(ブロッキング)
- .claude/settings.json の PreToolUse/PostToolUse などに追加します
grep "hook-name" .claude/settings.jsonで確認します
-
テストカバレッジ(ブロッキング)
- 最低10件のテストケースを含む .test.cjs ファイルを作成します
- テストを実行します:
node .claude/hooks/<category>/<name>.test.cjs
-
ドキュメント
- フックが新しい機能を追加する場合は、.claude/docs/ を更新します
- 使用例を追加します
-
関連フック
- 同じトリガーカテゴリに属する他のフックに影響するか確認します
- 相互作用のパターンを記録します
完全なチェックリスト:
[HOOK-CREATOR] System Impact Analysis for: <hook-name>
1. HOOK FILE CREATED
[ ] Created at .claude/hooks/<type>/<hook-name>.cjs
[ ] Follows CJS format with validate() export
[ ] Has main() function for CLI execution
[ ] Handles graceful degradation (warn by default)
2. TEST FILE CREATED (minimum 10 test cases)
[ ] Created at .claude/hooks/<type>/<hook-name>.test.cjs
[ ] Tests valid operations (3+ cases)
[ ] Tests blocked operations (3+ cases)
[ ] Tests edge cases (3+ cases)
[ ] Tests error handling (1+ cases)
3. DOCUMENTATION UPDATED
[ ] Added to .claude/hooks/README.md
[ ] Documented trigger conditions
[ ] Documented exit codes
4. REGISTRATION (BLOCKING)
[ ] Added to settings.json (pre/post-tool hooks)
[ ] Added to config.yaml (event hooks)
[ ] Verified: grep "<hook-name>" .claude/settings.json
5. MEMORY UPDATED
[ ] Added to learnings.md with hook summary
6. HOOK-AGENT MAP UPDATED (MANDATORY)
[ ] Added new hook to @HOOK_AGENT_MAP.md Section 1 matrix
[ ] Determined which agent archetypes are affected (based on hook trigger/tool target)
[ ] Updated affected agents' `## Enforcement Hooks` sections
[ ] Verified: `grep "<hook-name>" .claude/docs/@HOOK_AGENT_MAP.md || echo "ERROR: Hook not in agent map!"`
ブロッキング:上記に1つでも不足がある場合、フックの作成は完了していません。
ステップ 8:作成後のフック登録(フェーズ 1 統合)
このステップは非常に重要です。 フックのアーティファクトを作成したら、フック検出システムに必ず登録してください。
フェーズ 1 の背景: フェーズ 1 では、ツールとフックの検証および検出を担当します。登録されていないフックはシステムから認識されず、起動時に読み込まれません。
フックファイルの作成とテストが完了したら、次の手順を実行します。
-
適切な場所にフックレジストリエントリを作成または更新します。
レジストリが存在しない場合は、
.claude/context/artifacts/hook-registry.jsonを作成します。{ "hooks": [ { "name": "{hook-name}", "id": "{hook-name}", "description": "{Brief description from hook}", "category": "{safety|routing|memory|session|validation|audit}", "type": "{pre-tool|post-tool|user-prompt|session-start|session-end}", "version": "1.0.0", "targetTools": ["{Tool1}", "{Tool2}"], "enforcementMode": "{block|warn|off}", "defaultEnabled": true, "filePath": ".claude/hooks/{category}/{hook-name}.cjs", "testFilePath": ".claude/hooks/{category}/{hook-name}.test.cjs", "environmentVariable": "{HOOK_NAME}_MODE" } ] } -
スキーマに対してフックを検証します。
フックが
.claude/schemas/hook-schema.json(存在する場合)に対して有効であることを確認します。# Validate hook structure node -e " const hook = require('./.claude/hooks/{category}/{hook-name}.cjs'); if (hook.validate) console.log('✓ Has validate() export'); if (hook.PROJECT_ROOT) console.log('✓ Has PROJECT_ROOT'); if (hook.findProjectRoot) console.log('✓ Has findProjectRoot()'); " -
ローダーにフックを登録します。
新しいフックを含めるため、
.claude/lib/hooks/hook-loader.cjs(存在する場合)を更新します。const HOOKS_MANIFEST = { '{hook-name}': { path: './.claude/hooks/{category}/{hook-name}.cjs', type: '{pre-tool|post-tool}', matcher: '{Bash|Write|Edit|Read}', // Optional enabled: true, enforcementMode: process.env.{HOOK_NAME}_MODE || 'warn' } }; -
設定にフックを登録します。
ツールの前後に実行するフックの場合 -
.claude/settings.jsonを更新します。{ "hooks": { "pre-tool": ["./.claude/hooks/safety/{hook-name}.cjs"], "post-tool": ["./.claude/hooks/memory/{hook-name}.cjs"] } }イベントフックの場合 -
.claude/config.yamlを更新します。hooks: UserPromptSubmit: - path: ./.claude/hooks/routing/{hook-name}.cjs type: command SessionStart: - path: ./.claude/hooks/session/{hook-name}.cjs type: command -
.claude/hooks/README.mdに記載します。適切なカテゴリの下にエントリを追加します。
#### {Hook Name} (`{hook-name}.cjs`) {Detailed description of what the hook does.} **When it runs:** {Trigger condition - e.g., "Before every Bash command", "After task completion"} **What it checks/does:** - {Check/action 1} - {Check/action 2} - {Check/action 3} **Enforcement mode:** `process.env.{HOOK_NAME}_MODE` (default: `warn`) **Test file:** `.claude/hooks/{category}/{hook-name}.test.cjs` **Related hooks:** {List any hooks that interact with this one} -
メモリを更新します。
.claude/context/memory/learnings.mdに追記します。## Hook: {hook-name} - **Type:** {pre-tool|post-tool|event} - **Category:** {safety|routing|memory|session|validation} - **Purpose:** {Detailed purpose} - **Trigger:** {When it runs} - **Enforcement:** {Block/warn/off by default} - **Integration Notes:** {Any special considerations}
これが重要な理由: フックを登録しないと、次のようになります。
- 起動時にフックが読み込まれません
- フックの検証が実行されません
- システムが利用可能なフックを検出できません
- 安全性バリデーターを迂回できます
- 「不可視のアーティファクト」パターンが発生します
フェーズ 1 との統合: フックレジストリはフェーズ 1 の検出機構です。これにより、システムはスキーマに対してフックを検証し、起動時に読み込み、一貫して安全ルールを適用できます。
ステップ 9:統合の検証(必須 - 省略禁止)
このステップでは、アーティファクトがエコシステムに正しく統合されていることを確認します。
TaskUpdate({ status: "completed" }) を呼び出す前に、必ず作成後の検証ワークフローを実行してください。
-
10 項目の統合チェックリストを実行します。
node .claude/tools/cli/validate-integration.cjs .claude/hooks/<category>/<hook-name>.cjs -
終了コードが 0 であることを確認します(すべてのチェックに合格)。
-
終了コードが 1 の場合(1 つ以上のチェックに失敗):
- エラー出力を読み、具体的な失敗箇所を確認します
- 各失敗を修正します。
- フックレジストリがない場合 -> レジストリエントリを作成します(ステップ 8)
- settings.json のエントリがない場合 -> フックを登録します(ステップ 8)
- ドキュメントがない場合 -> hooks/README.md に追加します
- メモリの更新がない場合 -> learnings.md を更新します
- テストファイルがない場合 -> .test.cjs ファイルを作成します
- 終了コードが 0 になるまで検証を再実行します
-
検証に合格してから次に進みます。
このステップは必須です。 検証に合格するまで、タスクを完了としてマークしないでください。
これが重要な理由: Party Mode のインシデントでは、完全に実装されたアーティファクトでも、統合手順を省略すると Router から認識されなくなることが示されました。この検証により、「不可視のアーティファクト」パターンを防ぎます。
参照: .claude/workflows/core/post-creation-validation.md
CLI リファレンス
# Create hook using CLI tool
node .claude/tools/hook-creator/create-hook.mjs \
--name "hook-name" \
--type "PreToolUse|PostToolUse|UserPromptSubmit" \
--purpose "Description of what the hook does" \
--category "safety|routing|memory|audit|security|validation|custom" \
--matcher "Edit|Write|Bash" # Optional: tool matcher regex
# List all hooks
node .claude/tools/hook-creator/create-hook.mjs --list
# Validate hook structure
node .claude/tools/hook-creator/create-hook.mjs --validate "<path>"
# Assign to agents
node .claude/tools/hook-creator/create-hook.mjs --assign "name" --agents "agent1,agent2"
# Unregister hook
node .claude/tools/hook-creator/create-hook.mjs --unregister "<path>"
# Test with sample input
echo '{"tool_name":"Edit","tool_input":{"file_path":"test.js"} }' | node .claude/hooks/<category>/<hook-name>.cjs
フックパターンのリファレンス
パターン 1:安全性バリデーター(ツール実行前)
実行前にコマンドを検証する場合:
'use strict';
/**
* Validate Git Force Push
* Prevents accidental force pushes to protected branches
*/
const PROTECTED_BRANCHES = ['main', 'master', 'production'];
function validate(context) {
const { tool, parameters } = context;
if (tool !== 'Bash') {
return { valid: true, error: '' };
}
const command = parameters?.command || '';
// Check for force push
if (command.includes('git push') && (command.includes('--force') || command.includes('-f'))) {
// Check if pushing to protected branch
for (const branch of PROTECTED_BRANCHES) {
if (command.includes(branch)) {
return {
valid: false,
error: `Force push to ${branch} blocked. Use --force-with-lease instead.`,
};
}
}
return {
valid: true,
error: '',
warning: 'Force push detected. Ensure you know what you are doing.',
};
}
return { valid: true, error: '' };
}
module.exports = { validate };
パターン 2:メモリ抽出ツール(ツール実行後)
タスク完了後に学びを抽出する場合:
'use strict';
/**
* Extract Workflow Learnings
* Automatically captures patterns from completed workflows
*/
const fs = require('fs');
const path = require('path');
function findProjectRoot() {
let dir = __dirname;
while (dir !== path.parse(dir).root) {
if (fs.existsSync(path.join(dir, '.claude'))) return dir;
dir = path.dirname(dir);
}
return process.cwd();
}
const LEARNINGS_PATH = path.join(findProjectRoot(), '.claude/context/memory/learnings.md');
function extractLearnings(context) {
const { tool, parameters, result } = context;
// Only process completed tasks
if (!result || result.status !== 'completed') {
return { extracted: false };
}
// Extract patterns from result
const learnings = [];
if (result.patterns) {
learnings.push(...result.patterns);
}
if (result.decisions) {
learnings.push(...result.decisions);
}
if (learnings.length === 0) {
return { extracted: false };
}
// Append to learnings file
const entry = `\n## [${new Date().toISOString().split('T')[0]}] ${context.taskName || 'Task'}\n\n`;
const content = learnings.map(l => `- ${l}`).join('\n');
fs.appendFileSync(LEARNINGS_PATH, entry + content + '\n');
return { extracted: true, count: learnings.length };
}
module.exports = { extractLearnings };
パターン 3:ルーティング適用ツール(ユーザープロンプト)
ルーティングプロトコルを適用する場合:
'use strict';
/**
* Router First Enforcer
* Ensures all requests go through the Router agent
*/
function validate(context) {
const { prompt, currentAgent } = context;
// Skip if already routed
if (currentAgent === 'router') {
return { valid: true, error: '' };
}
// Skip slash commands (handled by skill system)
if (prompt && prompt.trim().startsWith('/')) {
return { valid: true, error: '' };
}
// Suggest routing
return {
valid: true,
error: '',
warning: 'Consider using Router to spawn appropriate agent via Task tool.',
};
}
module.exports = { validate };
パターン 4:セッション初期化ツール
セッションのライフサイクルを管理する場合:
'use strict';
/**
* Session Memory Initializer
* Reminds agents to read memory files at session start
*/
const fs = require('fs');
const path = require('path');
function findProjectRoot() {
let dir = __dirname;
while (dir !== path.parse(dir).root) {
if (fs.existsSync(path.join(dir, '.claude'))) return dir;
dir = path.dirname(dir);
}
return process.cwd();
}
const MEMORY_FILES = [
'.claude/context/memory/learnings.md',
'.claude/context/memory/issues.md',
'.claude/context/memory/decisions.md',
];
function initialize() {
const root = findProjectRoot();
console.log('\n' + '='.repeat(50));
console.log(' SESSION MEMORY REMINDER');
console.log('='.repeat(50));
console.log('\n Before starting work, read these memory files:');
for (const file of MEMORY_FILES) {
const fullPath = path.join(root, file);
if (fs.existsSync(fullPath)) {
const stats = fs.statSync(fullPath);
const modified = stats.mtime.toISOString().split('T')[0];
console.log(` - ${file} (updated: ${modified})`);
}
}
console.log('\n' + '='.repeat(50) + '\n');
return { initialized: true };
}
// Run on direct execution
if (require.main === module) {
initialize();
}
module.exports = { initialize };
例
セキュリティ検証フック
node .claude/tools/hook-creator/create-hook.mjs \
--name "secret-detector" \
--type "PreToolUse" \
--purpose "Blocks commits containing secrets or credentials" \
--category "security" \
--matcher "Bash"
監査ログ記録フック
node .claude/tools/hook-creator/create-hook.mjs \
--name "operation-logger" \
--type "PostToolUse" \
--purpose "Logs all file modifications to audit trail" \
--category "audit"
意図分析フック
node .claude/tools/hook-creator/create-hook.mjs \
--name "intent-classifier" \
--type "UserPromptSubmit" \
--purpose "Classifies user intent for intelligent routing" \
--category "routing"
ワークフロー統合
このスキルは、統合されたアーティファクトのライフサイクルの一部です。マルチエージェントオーケストレーションの全容については、以下を参照してください。
ルーターの判断: .claude/workflows/core/router-decision.md
- ルーターがこのスキルのアーティファクトを検出して呼び出す方法
アーティファクトのライフサイクル: .claude/workflows/core/skill-lifecycle.md
- 検出、作成、更新、非推奨化の各フェーズ
- バージョン管理とレジストリの更新
- CLAUDE.md の統合要件
外部統合: .claude/workflows/core/external-integration.md
- 外部アーティファクトの安全な統合
- セキュリティレビューと検証の各フェーズ
相互参照:クリエーターエコシステム
このスキルはクリエーターエコシステムの一部です。フックを作成した後、関連するアーティファクトが必要かどうかを検討してください。
| 発見されたギャップ | 必要なアーティファクト | 呼び出すクリエーター | タイミング |
|---|---|---|---|
| ドメイン知識に再利用可能なスキルが必要 | スキル | Skill({ skill: 'skill-creator' }) | ギャップが完全なスキルドメインである場合 |
| 既存のスキルの対象範囲が不十分 | スキルの更新 | Skill({ skill: 'skill-updater' }) | 該当するスキルはあるが、対象範囲が不十分な場合 |
| 機能に専用のエージェントが必要 | エージェント | Skill({ skill: 'agent-creator' }) | エージェントに機能を担わせる場合 |
| 既存のエージェントに機能の更新が必要 | エージェントの更新 | Skill({ skill: 'agent-updater' }) | 該当するエージェントはあるが、対象範囲が不十分な場合 |
| ドメインにコード/プロジェクトのスキャフォールディングが必要 | テンプレート | Skill({ skill: 'template-creator' }) | 再利用可能なコードパターンが必要な場合 |
| 振る舞いに実行前後のガードが必要 | フック | Skill({ skill: 'hook-creator' }) | 振る舞いの適用が必要な場合 |
| プロセスに複数フェーズのオーケストレーションが必要 | ワークフロー | Skill({ skill: 'workflow-creator' }) | 複数ステップの調整が必要な場合 |
| アーティファクトに構造化された I/O 検証が必要 | スキーマ | Skill({ skill: 'schema-creator' }) | アーティファクトの I/O 用 JSON スキーマが必要な場合 |
| ユーザーとのやり取りにスラッシュコマンドが必要 | コマンド | Skill({ skill: 'command-creator' }) | ユーザー向けのショートカットが必要な場合 |
| 繰り返し使うロジックに再利用可能な CLI ツールが必要 | ツール | Skill({ skill: 'tool-creator' }) | CLI ユーティリティが必要な場合 |
| 限定的/単一アーティファクトのみの機能 | インライン | このアーティファクト内にのみ記述 | 汎用化するには具体的すぎる場合 |
統合ワークフロー
追加の機能が必要なフックを作成した後:
// 1. Hook created but needs dedicated skill
Skill({ skill: 'skill-creator' });
// Create skill that encapsulates hook logic
// 2. Hook needs to be assigned to agent
// Update agent's workflow to include hook awareness
// 3. Hook needs workflow for testing
// Create workflow in .claude/workflows/<hook-name>-test-workflow.md
エコシステム統合の作成後チェックリスト
フックの作成と検証が完了した後:
[ ] Does hook need a skill wrapper? -> Use skill-creator
[ ] Does hook need dedicated agent? -> Use agent-creator
[ ] Does hook need testing workflow? -> Create workflow
[ ] Should hook be enabled by default? -> Update config.yaml
[ ] Does hook interact with other hooks? -> Document in README.md
[ ] Run post-creation validation -> node .claude/tools/cli/validate-integration.cjs .claude/hooks/<category>/<hook-name>.cjs
フック作成における鉄の掟
これらのルールは絶対に遵守してください。違反すると、検知されない障害が発生します。
1. NO HOOK WITHOUT validate() EXPORT
- Every hook MUST export validate() function
- Hooks without validate() cannot be called programmatically
2. NO HOOK WITHOUT main() FOR CLI
- Every hook MUST have main() for CLI execution
- Run only when require.main === module
3. NO HOOK WITHOUT ENFORCEMENT CONTROLS
- Support 'block|warn|off' via environment variable
- Default to 'warn' unless explicitly required to block
- Never crash on malformed input
4. NO HOOK WITHOUT ERROR HANDLING
- Wrap JSON.parse in try/catch
- Handle missing parameters gracefully
- Return valid: true when unsure (fail open, not closed)
5. NO HOOK WITHOUT TEST FILE
- Every hook needs <hook-name>.test.cjs
- Test valid, invalid, and edge cases
6. NO HOOK WITHOUT DOCUMENTATION
- Add to .claude/hooks/README.md
- Document trigger, behavior, exit codes
7. CROSS-PLATFORM PATHS
- Use path.join() not string concatenation
- Handle both / and \ path separators
- Use path.normalize() for comparison
8. NO CREATION WITHOUT SYSTEM IMPACT ANALYSIS
- Check if hook requires settings.json registration
- Check if hook requires config.yaml registration
- Update @HOOK_AGENT_MAP.md with new hook row (MANDATORY)
- Update affected agents' Enforcement Hooks sections (MANDATORY)
- Check if related hooks need updating
- Document all system changes made
9. IRON LAW I: PRE-TOOL HOOKS MUST VALIDATE AGAINST JSON SCHEMA
- PreToolUse hooks MUST compile and validate input against the companion
schemas/input.schema.json using AJV or equivalent before allowing execution
- Pattern: compile(schema) → validate(input) → exit 2 on schema failure
- Never block (exit 2) on schema-load errors — fail open, not closed
- Search: site:github.com "preToolUse" "ajv" "validate" filetype:cjs
10. IRON LAW III: POST-TOOL HOOKS MUST EMIT OBSERVABILITY EVENTS
- PostToolUse hooks MUST append a structured JSON line to
.claude/context/runtime/tool-events.jsonl via the centralized emitter:
const { sendEvent } = require('.claude/tools/observability/send-event.cjs')
- Required fields: tool_name, agent_id, session_id, outcome, timestamp
- Never crash on emit failure (try/catch, fail open)
- Inspect events: node .claude/tools/observability/send-event.cjs --tail 20
統合ポイント
- エコシステム評価者:フッククリエーターは、逆引き参照のためにエコシステム評価と連携します
- エージェントクリエーター:エージェントは frontmatter でフックを参照できます
- スキルクリエーター:スキルは hooks/ ディレクトリでフックを定義できます
- Settings.json:フックは適切なトリガーとマッチャーを設定して自動登録されます
- Config.yaml:UserPromptSubmit、SessionStart などのイベントフックが登録されます
アーキテクチャへの準拠
ファイルの配置(ADR-076)
- フック:
.claude/hooks/{category}/(safety、routing、memory、session、validation、audit) - フックのテスト:
.claude/hooks/{category}/{name}.test.cjs(フックと同じ場所に配置) - テスト:
tests/(フックの統合テスト) - 関連ドキュメント:
.claude/docs/ - フックレジストリ:
.claude/hooks/README.md
ドキュメントの参照(CLAUDE.md v3.1.0)
- 参照ファイルには @ 記法を使用します:@ENFORCEMENT_HOOKS.md、@TOOL_REFERENCE.md
- 配置場所:
.claude/docs/@*.md - 参照先:CLAUDE.md のセクション 1.3(ENFORCEMENT HOOKS の参照)
シェルセキュリティ(ADR-077)
- 新しい安全性フック: bash-cwd-validator.cjs、shell-injection-validator.cjs、variable-quoting-validator.cjs(ADR-077 フェーズ 2)
- フェーズ 3 のフック: shellcheck-validator.cjs、command-allowlist-validator.cjs(参照実装)
- フックのテストでは、シェルセキュリティのパターンを必ず検証してください
- 参照先:.claude/docs/SHELL-SECURITY-GUIDE.md
- 適用対象:すべての安全性フック、ツール実行前フック、検証フック
最近の ADR
- ADR-075:ルーターの設定に応じたモデル選択
- ADR-076:ファイル配置アーキテクチャの再設計
- ADR-077:シェルコマンドセキュリティアーキテクチャ
ファイル配置と標準
出力場所のルール
このスキルの出力先:.claude/hooks/<category>/
カテゴリ:
safety/- 安全性バリデーター(コマンド検証、セキュリティチェック、シェルセキュリティ)routing/- ルーターの適用フックmemory/- メモリ管理フックsession/- セッションのライフサイクルフックvalidation/- 入出力の検証フック
必須の参照資料
- ファイル配置:
.claude/docs/FILE_PLACEMENT_RULES.mdを参照 - 開発者ワークフロー:
.claude/docs/DEVELOPER_WORKFLOW.mdを参照 - アーティファクトの命名:
.claude/docs/ARTIFACT_NAMING.mdを参照
適用
ファイル配置は file-placement-guard.cjs フックによって適用されます。
無効な配置は本番モードでブロックされます。
メモリプロトコル(必須)
フックを作成する前に:
cat .claude/context/memory/learnings.md
以下を確認します:
- 以前に作成されたフック
- 既知のフックパターン
- フックの動作に関するユーザーの希望
完了後:
- 新しいフックを作成した場合 →
.claude/context/memory/learnings.mdに追記 - フックに関する問題があった場合 →
.claude/context/memory/issues.mdに追記 - フックの設計を決定した場合 →
.claude/context/memory/decisions.mdに追記
中断を想定してください。コンテキストがリセットされることがあります。メモリに記録されていなければ、実施されていないものとみなします。
エコシステム連携契約(必須)
このクリエイタースキルは、連携するクリエイターエコシステムの一部です。ここで作成するアーティファクトは、関連するクリエイターと連携し、検証される必要があります。
- 所有権と実行経路については
agent-creator - 機能のパッケージ化と割り当てについては
skill-creator - 実行可能な自動化の仕組みについては
tool-creator - 適用とガードレールについては
hook-creator - ポリシーと静的チェックについては
rule-creatorおよびsemgrep-rule-creator - 標準化されたひな形については
template-creator - オーケストレーションとフェーズ管理については
workflow-creator - ユーザー/オペレーター向けのコマンド UX については
command-creator
クリエイター間の連携確認(必須)
完了前に、関連するすべての連携を確認してください。
.claude/CLAUDE.mdおよび関連するルーティングドキュメントに、アーティファクトのルートが存在する。- ディスカバリー/レジストリの項目(該当するカタログ/インデックス/レジストリ)が更新されている。
- 関連アーティファクトが作成されているか、理由を明記して明示的に適用対象外とされている。
- 作成したアーティファクトに対して
validate-integration.cjsが成功する。 - スキルのメタデータを変更した場合は、スキルインデックスが再生成されている。
調査ゲート(Exa + arXiv — どちらも必須)
新しいパターン、テンプレート、ワークフローについては、調査が必須です。
- 実装およびエコシステムのパターンを Exa で調査します。
mcp__Exa__web_search_exa({ query: '<topic> 2025 best practices' })mcp__Exa__get_code_context_exa({ query: '<topic> implementation examples' })
- 学術研究を arXiv で検索します(AI/ML、エージェント、評価、オーケストレーション、メモリ/RAG、セキュリティに関する場合は必須)。
- Exa 経由:
mcp__Exa__web_search_exa({ query: 'site:arxiv.org <topic> 2024 2025' }) - 直接 API:
WebFetch({ url: 'https://arxiv.org/search/?query=<topic>&searchtype=all&start=0' })
- Exa 経由:
- 決定事項、制約、対象外事項を、アーティファクトの参照資料/ドキュメントに記録します。
- 更新は最小限にとどめ、過度な設計を避けます。
対象に次のトピックが含まれる場合、arXiv の調査は代替ではなく必須です: AI エージェント、LLM の評価、オーケストレーション、メモリ/RAG、セキュリティ、静的解析、または新たな方法論。
リグレッションを防ぐデリバリー
- 振る舞いを変更する場合は、厳格に RED -> GREEN -> REFACTOR に従ってください。
- 変更したモジュールを対象にテストを実行してください。
- 変更したファイルに対してリンター/フォーマッターを実行してください。
- コミットは関心事ごと(ロジック/ドキュメント/生成されたアーティファクト)に分けてください。
オプション:評価品質ゲート
共有の評価フレームワークを実行して、フックの品質を検証します。
node .claude/skills/skill-creator/scripts/eval-runner.cjs --skill hook-creator
フックアーティファクトに対するグレーダーのアサーション:
- 終了コードが正しい:フックは
0(許可)または2(ブロック)のみで終了します。終了コード1は使用しません(SE-03 に従い、ブロックではなくエラーとして扱われます)。 - 100ms のパフォーマンス予算:フック本体は 100ms 未満で完了します。ホットパスでは、ネットワーク呼び出し、ブロッキング I/O、長時間の計算を行いません。
- フェイルオープンとフェイルクローズのポリシー:セキュリティフック(routing、creator、write)はフェイルクローズです(エラー時は
process.exit(2))。アドバイザリーフックと PostToolUse フックはフェイルオープンです(エラー時はprocess.exit(0))。 - 適切なエラー処理:フック本体は
try/catchで囲みます。予期しないエラーが発生した場合は、重要度に応じて0(非クリティカル)または2(セキュリティ上クリティカル)で終了します。終了コードを指定せずにクラッシュすることはありません。 - 登録が完了している:フックは
.claude/settings.jsonに登録され、@ENFORCEMENT_HOOKS.mdに記載されています。
評価プロトコルとグレーダー/アナライザーエージェントの使用方法の詳細は .claude/skills/skill-creator/EVAL_WORKFLOW.md を参照してください。