Claude Codeプラグイン化の移行手順 — hooks/skills/agentsを移す
既存の.claude/配下のcommands・agents・skills・hooksをプラグイン構造へ移す具体的な手順と、CLAUDE.mdが移行対象に含まれない理由をまとめます。
移す前に決めること: そもそもプラグインにするか
.claude/直下に置いたcommands・agents・skills・hooksは、そのプロジェクトの中だけで使う設定としては十分です。別のプロジェクトやチームへ配ろうとした途端、フォルダを手でコピーするしか方法がなくなります。コピーが古くなっても、それを知らせる仕組みはありません。
プラグインにすると、マーケットプレイス経由の/plugin installで配れます。更新の検知はversionで決まります。plugin.jsonにversionを書くと、その文字列を書き換えるまで、利用側は何コミット進んでも同じコピーのままです。versionを書かなければ、gitでホストされたマーケットプレイス経由なら、コミットのSHAが版の代わりになります。
同じリポジトリの中だけで使うなら、移さずに済む道もあります。<project>/.claude/skills/<名前>/の下に.claude-plugin/plugin.jsonを置くと、Claude Codeはそのフォルダをプラグインとして読みます。その場合はskills-dirプラグインの記事の手順で足ります。この記事は、複数のプロジェクトやチームへ配る前提で、.claude/の中身を別ディレクトリへ移す手順を扱います。
CLAUDE.mdだけは移せない
移せるのは、.claude/commands/・.claude/agents/・.claude/skills/と、設定ファイルのhooksキーの4つです。実際に持っているものだけを移せば足ります。
例外がCLAUDE.mdです。プラグインのルートに置いても、プロジェクトのコンテキストとしては読み込まれません。実際にコピーしてclaude plugin validateにかけると、次の警告が出ます(v2.1.289で実行)。
cp CLAUDE.md my-plugin/
claude plugin validate ./my-pluginValidating plugin: .../my-plugin/CLAUDE.md
⚠ Found 1 warning:
❯ root: CLAUDE.md at the plugin root is not loaded as project context. To ship context with your plugin, use a skill (skills/<name>/SKILL.md) instead.常時読ませたい指示があるなら、スキルとして書き直します。CLAUDE.mdそのものをプラグインにする手順は存在しません。
5つの手順で.claude/をプラグインに移す
次のコマンドは、.claude/があるプロジェクトルートで実行します。cpのパスがルートからの相対になっているためです。
移行の5手順
- 1
雛形を作る
.claude/と同じ階層にプラグインのディレクトリを作ります。マニフェストはmy-plugin/.claude-plugin/plugin.jsonです。必須なのはnameだけで、descriptionとversionは書いておくと配布後に役立ちます。mkdir -p my-plugin/.claude-plugin{ "name": "my-plugin", "description": "Migrated from standalone configuration", "version": "1.0.0" } - 2
commands・agents・skillsをコピーする
持っているディレクトリだけをコピーします。存在しないものは飛ばします。
cp -r .claude/commands my-plugin/ cp -r .claude/agents my-plugin/ cp -r .claude/skills my-plugin/ls -a my-pluginで、コピーしたディレクトリが.claude-pluginと並んでいれば完了です。 - 3
hooksをhooks.jsonへ移す
settings.jsonかsettings.local.jsonのhooksオブジェクトを、my-plugin/hooks/hooks.jsonへそのまま貼ります。形式は同じです。mkdir -p my-plugin/hooks{ "hooks": { "PostToolUse": [ { "matcher": "Write|Edit", "hooks": [{ "type": "command", "command": "jq -r '.tool_input.file_path' | xargs npm run lint:fix" }] } ] } } - 4
--plugin-dirで読み込んで試す
プラグインを1セッションだけ読み込みます。設定ファイルには何も書き込まれません。
claude --plugin-dir ./my-plugin - 5
配る前にvalidateする
マニフェストと、各コンポーネントのフロントマター・hooksを検査します。
claude plugin validate ./my-plugin --strict
hooksのイベント名や設定パターンは、Claude Code Hooks完全ガイドがそのまま流用できます。
移行後の呼び出し名はどう変わるか
プラグイン内のスキル・コマンド・エージェントには、プラグイン名の接頭辞が付きます。公式の例では、/deployだったスキルは/my-plugin:deploy、reviewerだったエージェントはmy-plugin:reviewerとして呼び出します。commands/のフラットな.mdも同じで、commands/about.mdは/my-plugin:aboutになります。
commands/はskills/より古い形式です。新しく書くものはskills/<名前>/SKILL.mdにし、すでにあるファイルを移すときだけcommands/をそのまま使う、という使い分けが公式の案内です。
--plugin-dirで読み込んだ状態は、claude plugin listでも確かめられます。次はフラグを先に付けて実行した出力です(v2.1.289)。
claude --plugin-dir ./my-plugin plugin listSession-only plugins (--plugin-dir / --plugin-url):
❯ my-plugin@inline
Version: 1.0.0
Path: .../my-plugin
Status: ✔ loaded読み込みに失敗したときは、セッション内の/pluginのErrorsタブに原因が出ます。claude plugin list --jsonならerrorsフィールドで読めます。ファイルを直したあとは/reload-pluginsで反映します。反映の詳細は/reload-pluginsの記事にあります。
元の.claude/を消し忘れるとどうなるか
移行が終わっても、元のファイルが.claude/に残っていれば、そちらも読み込まれ続けます。ここで押さえたいのは、コンポーネントごとに結果が違う点です。
消し忘れの結果
skills・agents・commands
接頭辞が付くので衝突しません。/deployと/my-plugin:deployがどちらも動き、Claudeはreviewerとmy-plugin:reviewerを別々のサブエージェントとして見ます。壊れはしませんが、どちらが最新かをチームで取り違えやすくなります。
hooks
hooksには接頭辞がありません。設定ファイルとhooks/hooks.jsonの両方に同じhookが残ると、イベントのたびに2回走ります。
プラグインの動作を確かめ終えたら、.claude/側の元ファイルを削除し、設定ファイルのhooksオブジェクトも消します。
agentの定義は、そのまま移せないフィールドがある
.claude/agents/のMarkdownをコピーしても、フロントマターの一部はプラグイン同梱のagentでは働きません。
プラグイン同梱agentのフロントマター
そのまま使える
name/description/model/effort/maxTurns/tools/disallowedTools/skills/memory/background/omitClaudeMd/isolation(値は"worktree"のみ)/color無視される
permissionMode・hooks・mcpServers・initialPrompt。agentのファイルだけでhooksやMCPサーバーは足せません。プラグインのhooks/hooks.jsonと.mcp.jsonに移します。パースできない
フロントマターが壊れていても、プラグイン同梱のagentは読み込まれます。名前はファイル名から付き、説明は「Agent from my-plugin plugin」になり、残りのフィールドはすべて捨てられます。
3番目の挙動は、元の.claude/agents/と違います。壊れたフロントマターのファイルを2種類のディレクトリで検査すると、次のようになります(v2.1.289)。
元の.claude/側を検査した出力です。
Validating agent: .../proj/.claude/agents/broken.md
✘ Found 1 error:
❯ frontmatter: YAML frontmatter failed to parse: YAML Parse error: Unexpected token. At runtime this agent does not load at all — with no frontmatter name it is treated as a co-located reference document and skipped.コピー先のプラグイン側を検査した出力です。
Validating agent: .../proj/my-plugin/agents/broken.md
✘ Found 1 error:
❯ frontmatter: YAML frontmatter failed to parse: YAML Parse error: Unexpected token. At runtime this agent loads with its name taken from the filename and every other frontmatter field silently dropped.放置していた壊れたagentが、移行後は設定の抜けたまま有効になります。コピーしたら、使い始める前にclaude plugin validateを通しておく価値があります。なお、検査用のreviewer.mdに書いたpermissionMode: planには、検査の警告は出ませんでした。無視されることは警告では分からず、公式のフィールド表で確かめるしかありません。
validateと--strictは何を落とすのか
--strictは、警告をエラー扱いにします。実際に動かすと、境目がはっきり見えます。次の2つを同じプラグインで実行します(v2.1.289)。
claude plugin validate ./my-plugin
claude plugin validate ./my-plugin --strict最初のコマンドは、authorが無いという警告を出したうえで✔ Validation passed with warningsで終わります。2つ目は同じ警告が理由で✘ Validation failed (--strict treats warnings as errors)となり、終了コードが1になります。plugin.jsonにauthorを足すと、どちらも✔ Validation passedです。
警告で済む間違いは、ほかにもあります。hooks.jsonのイベント名をpostToolUseと書いた例では、次の警告が出ました。
⚠ Found 1 warning:
❯ hooks: hooks.postToolUse: unknown hook event; entry ignored at runtimeイベント名は大文字小文字を区別します。警告のまま動き続けるので、--strictなしだと見逃します。移行元のsettings.jsonから貼っただけの状態でも、キー名の取り違えは起こりえます。配る前に--strictを一度通すと、この種のミスが拾えます。
移行後にhooksが動かないときの確認順
hookが発火しないときは、次の順に確認します。
- イベント名の大文字小文字:
PostToolUseであってpostToolUseではない matcherが対象のツール名に合っているか: ファイル操作なら"Write|Edit"typeがcommand/http/mcp_tool/prompt/agentのどれかか- スクリプトを単体で実行して、エラーなく終わるか
- 元の設定ファイルにも同じhookが残っていないか(二重実行の原因になります)
hookのコマンドの中でスクリプトを呼んでいるなら、パスの扱いも見直します。プラグインに同梱したスクリプトは${CLAUDE_PLUGIN_ROOT}/scripts/format.shのように書き、プロジェクト側のファイルを指すときは${CLAUDE_PROJECT_DIR}を使います。.claude/hooks/のスクリプトをプラグインのscripts/へ移したなら、hookのコマンドもその位置に書き換えが要ります。
hooksが発火したかどうかは、デバッグログで確かめます。PostToolUseのhookは0で終了するとトランスクリプトに何も出さないので、ログか、スクリプト自身が変えるものを見ます。
移行後に配る方法
ここまでは、--plugin-dirでローカルに読み込んだだけです。チームや社外へ配るには、marketplace.jsonをgitでホストして/plugin marketplace addしてもらうか、公式のディレクトリへ提出します。配布方法の使い分けはClaude Codeプラグイン(Plugins)完全ガイドにあります。
エージェント定義を見直すならClaude Code Sub-agents完全ガイド、スキルを作り直すならClaude Code Skills完全ガイドが土台になります。
まとめ
.claude/の中身は、コピーとマニフェストの追加でプラグインになります。CLAUDE.mdだけは移せないので、常時読ませたい指示はスキルに書き直します。
移行後に残る事故は、元ファイルの消し忘れによるhookの二重実行と、壊れたagentが静かに有効になることの2つです。二重実行はvalidateでは検出されないので、動作確認のあとに元ファイルを消す作業を忘れないようにします。agentの壊れたフロントマターと、イベント名の綴りミスは、配る前にclaude plugin validate ./my-plugin --strictで拾えます。