Claude CodeでStream Deckプラグインを作る — manifest検証と再読込の回し方
Stream Deckプラグインは、manifest.jsonの検証とstreamdeck restartでの再読込を回せば、Claude Codeに編集を任せやすくなります。PostToolUse hookと権限の設定例を示します。
Stream Deckのプラグインは、manifest.json の検証と streamdeck restart での再読込を、Claude Codeの作業ループに入れると任せやすくなります。コードを書く部分はTypeScriptの普通のNode.jsプロジェクトです。つまずきやすいのは、manifestの書式と、Stream Deck本体に変更を反映する手順のほうです。
この記事では、足場作りはウィザードに任せ、その後の編集・検証・再読込をClaude Codeに回させる設定を組みます。
先に揃える前提と、人が触る範囲
Getting Startedが挙げる前提は次のとおりです。
| 必要なもの | 条件 |
|---|---|
| Node.js | 条件24以上 |
| Stream Deckアプリ | 条件7.1以上 |
| デバイス | 条件Stream Deck本体(持っていなければStream Deck Mobileを無料で試せる) |
| ターミナル | 条件Stream Deck CLIを使うため |
Stream Deck CLIは npm install -g @elgato/cli で入ります。Windowsで .ps1 の実行ポリシーに引っかかるときは、Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser を案内しています。
ここで線を引いておきます。キーを押したときの見た目や挙動は、Stream Deckアプリの画面とデバイスの上にしか現れません。Claude Codeが確かめられるのは、ビルドが通るか、manifestが検証を通るか、プラグインが再起動できるか、までです。押した結果の確認は人の仕事として残ります。
足場は streamdeck create に任せる
プラグインの雛形は、Claude Codeに一から書かせず streamdeck create で作ります。ウィザードは、作者名・プラグイン名・プラグインUUID・説明の4つを聞きます。完了するとプラグインはStream Deckに自動でインストールされ、すぐ動かせる状態になります。
npm install -g @elgato/cli
streamdeck createプラグインUUIDはリバースDNS形式の文字列で、小文字の英数字(a-z, 0-9)、ハイフン、ピリオドだけを使えます。Marketplaceに公開したあとは変更できません。ウィザードの入力は人が決め、Claude Codeには決まったUUIDを渡します。
生成されるディレクトリは次の構成です。
.
├── *.sdPlugin/
│ ├── bin/
│ ├── imgs/
│ ├── logs/
│ ├── ui/
│ └── manifest.json
├── src/
│ ├── actions/
│ └── plugin.ts
├── package.json
├── rollup.config.mjs
└── tsconfig.json*.sdPlugin がビルド済みのプラグイン本体で、src がソースです。bin は src のコンパイル結果なので、Claude Codeに直接編集させないほうが安全です。
編集から再読込までの1周を決める
変更をStream Deckに反映する方法は2つあります。
変更をStream Deckに反映する2つの方法
build + restart
npm run build のあと streamdeck restart <UUID> を実行します。Claude Codeに1周ずつ回させたいときはこちらです。
npm run watch
rollup -c -w が変更を監視し、ビルド終了のたびに streamdeck restart を呼びます。manifest.json と src の変更が自動で反映されます。
streamdeck restart は、プラグインを止めて起動し直します。起動していなければ起動します。manifestを含むプラグインの全リソースが読み直されます。manifestを直したら、restartが必須ということです。
npm run watch はClaude Codeの外のターミナルで人が走らせておく形が扱いやすいです。Claude Codeは編集と検証だけをして、反映は監視側に任せられます。止めるときは Ctrl + C です。
そこにmanifestの検証を足すと、1周は次の順になります。
Claude Codeに回させる1周
- 1
編集
src/またはmanifest.jsonを編集します。 - 2
manifestの検証
streamdeck validateが、プラグインの検証結果を出力します。 - 3
ビルド
npm run buildでbin/に出力します。 - 4
再読込
streamdeck restart <UUID>で、Stream Deckがプラグインを読み直します。 - 5
人が確認
デバイスまたはアプリ上でキーを押し、挙動を見ます。
権限は検証と再読込だけ先に通す
毎周の確認ダイアログを減らすため、周回に使う3つのコマンドを許可します。Bash(npm run *) のような * 付きのパターンは、permissionsの書式です。
{
"permissions": {
"allow": [
"Bash(npm run build)",
"Bash(streamdeck validate *)",
"Bash(streamdeck restart *)",
"Bash(streamdeck pack --dry-run)"
]
}
}streamdeck pack は --dry-run のときだけ許可しています。--dry-run はパッケージを作らずにレポートだけを出します。.streamDeckPlugin ファイルを書き出す通常の pack と、streamdeck link や streamdeck dev のようにStream Deckへの登録や開発者モードを変えるコマンドは、あえて許可に入れません。
権限の書き方そのものはClaude Codeのpermissionsコマンドで、検証コマンドだけを通す設計の別例はuvプロジェクトの権限設計で扱っています。
manifest.jsonの検証をPostToolUse hookに入れる
streamdeck validate を毎回思い出して打たせるより、manifestを編集した直後にhookで走らせるほうが確実です。PostToolUse hookは、ツール実行後に動きます。hooksの表では、PostToolUseで終了コード2のときstderrがClaudeに表示されます。ツールはすでに実行済みなので、編集を取り消すのではなく、直すべき内容をClaudeに伝える使い方になります。hookの全体像はClaude Code Hooks完全ガイドに、PostToolUseでLintを回す別の例はPostToolUse hookのLint自動修正にあります。
.claude/settings.json に登録します。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/validate-sd-manifest.sh"
}
]
}
]
}
}スクリプトは、編集されたファイルが *.sdPlugin/manifest.json のときだけ検証します。
#!/bin/bash
# .claude/hooks/validate-sd-manifest.sh
input=$(cat)
file=$(jq -r '.tool_input.file_path // empty' <<<"$input")
case "$file" in
*.sdPlugin/manifest.json) ;;
*) exit 0 ;;
esac
if ! out=$(streamdeck validate "$(dirname "$file")" --no-update-check 2>&1); then
echo "$out" >&2
exit 2
fi作ったら chmod +x で実行権限を付けます。ポイントは3つです。
- 入力のJSONはstdinに届くので、
jqでtool_input.file_pathを取り出しています --no-update-checkは検証ルールの更新確認を止めるオプションです。ビルドパイプラインで使うことが推奨されています。付けなければ、更新確認は1日に1回走ります- 検証が失敗したときに終了コードが非ゼロになるかどうかは、validateのページに記載がありません。わざと壊したmanifestで、hookが実際にエラーを返すかを一度試してください
CLAUDE.mdに書いておく運用ルール
hookは編集のたびに働きますが、周回の順番や触らない場所は文章で渡します。
# Stream Deckプラグイン
- プラグインUUID: com.example.my-plugin(変更しない)
- 編集してよいのは `src/` と `com.example.my-plugin.sdPlugin/manifest.json`。`bin/` は触らない
- 変更後は `npm run build` → `streamdeck validate com.example.my-plugin.sdPlugin` → `streamdeck restart com.example.my-plugin` の順
- manifestのVersionは `{major}.{minor}.{patch}.{build}` の4桁
- 実機のキー操作は人が確認する。確認が要る箇所を最後に列挙するvalidate や restart に渡すUUIDとディレクトリ名は、ここに書いた値と一致させます。streamdeck link の説明では、ディレクトリ名がプラグインのUUIDに .sdPlugin を付けた名前でなければならないとされています。
Claudeがmanifestで踏みやすい箇所
manifestのリファレンスから、書き間違えると検証や読み込みで引っかかりやすい項目を抜き出します。
| 項目 | 定義 |
|---|---|
Version | 定義{major}.{minor}.{patch}.{build} の形式 |
SDKVersion | 定義2 または 3(3を推奨) |
Nodejs.Version | 定義"20"、"24"、"26" のいずれか |
CodePath | 定義プラグインの入口。必須。拡張子を含める(例: bin/plugin.js) |
Icon / State.Image | 定義拡張子を省いて書く |
Actionの UUID | 定義プラグインのUUIDを接頭辞にする |
画像は、GIF・PNG・SVGのいずれかで、72 × 72 pxと144 × 144 px(@2x)の2サイズを用意する決まりです。Claude Codeに画像パスを足させるときは、拡張子を書かないこと、2サイズ揃えることを指示に入れておくと、手戻りが減ります。
Nodejs.Version と、前提の「Node.js 24以上」は別の話です。前者はプラグインが動く実行環境の指定で、後者は開発環境の要件です。manifestの例にある "20" をそのまま写させず、使うバージョンを指定します。
配布前に確かめること
配布用の .streamDeckPlugin は streamdeck pack で作ります。パッケージ化の前に、プラグインが検証を通る必要があります。Claude Codeには次の形で確認させます。
streamdeck pack com.example.my-plugin.sdPlugin --dry-run.git・.env*・*.log・*.js.map はパッケージに含まれません。ほかに除外したいファイルは、manifestと同じ階層の .sdignore に .gitignore の書式で書きます。
もう1点、DRM保護にはClaude Codeが生成するコードに関わる条件があります。DRMを有効にする条件は、SDKVersion を3、Software.MinimumVersion を "6.9" 以上にし、Node.jsプラグインでは @elgato/streamdeck v2以上を使うことです。そのうえで、配布物のファイルは変更できず、manifestは実行時に読めません。実行時に manifest.json を読むコードをClaude Codeが書くと、DRMを有効にした配布物では動かなくなります。必要な情報は別のJSONに分けるか、コードに埋め込みます。
新しいアクションを足すときの注意
雛形のアクションは src/actions/increment-counter.ts にあり、SingletonAction を継承したクラスに @action({ UUID: "..." }) を付ける形です。onWillAppear はアクションがキャンバスに現れたとき、onKeyDown はキーを押したときに呼ばれます。ほかにも onWillDisappear や、ダイヤルを回したときの onDialRotate などを受けられます。
アクションを増やす依頼では、2か所を同じ変更で直させます。
manifest.jsonのActionsに、名前・アイコン・States・UUIDを足すsrc/actions/に、同じUUIDを指定したクラスを足す
アクションのUUIDは、プラグインのUUIDを接頭辞にした、リバースDNS形式の文字列にします。Stream Deckはイベントを送るとき、このUUIDでどのアクションが発生元かを伝えます。片方だけ直すとイベントが対応づかないため、先に挙げたhookの検証に加えて、依頼文に「manifestとクラスの両方」と書いておきます。
キー(Keypad)だけでなく、Stream Deck +のダイヤル(Encoder)にも対応するアクションは、Controllers に "Keypad" と "Encoder" を並べます。Stream Deck Neoの情報バーを指す "Neo" もあり、こちらはStream Deck 7.6から使えます。Software.MinimumVersion が7.6より低いままだと、Neoを指定したmanifestは前提とずれるので、最低バージョンも同時に見直させます。
デバッグは開発者モードを入れてから
動作がおかしいときのために、streamdeck dev で開発者モードを有効にします。有効な間は、デバッガ(VS Codeなど)をNode.jsプラグインにつなげられ、プロパティインスペクタ(アクションの設定UI)を http://localhost:23654/ で確認できます。解除は streamdeck dev --disable です。
manifestの Nodejs.Debug に "enabled" を指定すると、プラグインは --inspect 付きで起動します。"break" なら --inspect-brk で、最初の行で停止します。どちらもポートはStream Deckが空きを割り当てます。デバッガをつなぐ作業は画面の操作を伴うので、Claude Codeには「ログを読んで原因を絞る」までを任せ、ブレークポイントを置く作業は人が受け持つ分担が現実的です。
つまずいたとき
プラグインがStream Deckに表示されないときは、アプリが管理者権限で動いている場合があります。新規インストールやアップデートの直後に起きうる症状で、アプリを再起動すると直るとされています。
ビルドが通ってもキーの反応がおかしいときは、プラグインのログを見ます。*.sdPlugin/logs には、ロガーが出したログが入ります。Claude Codeにはこのファイルを読ませ、再現手順は人が伝える分担が効きます。
まとめ
Stream DeckプラグインをClaude Codeに任せるときは、足場作りと実機確認を人が持ち、編集・検証・ビルド・再読込の1周をClaude Codeに渡します。1周を回す部品は、manifestを検証するhook、周回コマンドだけを通す権限、順番を書いたCLAUDE.mdの3つです。最初に壊れたmanifestでhookの動きを一度確かめておけば、以降の編集は検証付きで進みます。