capacitor-plugin-generator について
会話形式の要件または構造化 YAML 契約から、レビュー可能な Capacitor プラグイン候補を生成するスキルです。TypeScript API 契約を基に Web、iOS、Android の各層を作成し、リリース前に人間のレビューを求めます。
主な機能
- 01会話形式または YAML 入力を判別
- 02公式アーキテクチャでプラグインを生成
- 03TypeScript API 契約を実装の基準にする
- 04Web、iOS、Android 層を生成
- 05ドキュメント生成と検証を実行
- 06公開チェックは dry-run に限定
活用シーン
- 01Capacitor プラグインを新規作成
- 02カメラやセンサーなどのネイティブ機能をアプリに接続
- 03移行スキルの YAML 契約からプラグインを生成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ ionic-team/ capacitor-skills --skill capacitor-plugin-generatorインストール後、Claude Code で/capacitor-plugin-generatorを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/android-implementation.mdapi-design.mdarchitecture-patterns.mdconfiguration.mdinput-contract.mdios-implementation.mdpermission-patterns.mdpublishing.mdsample-app.mdscaffolding.mdtesting-strategies.mdtypescript-implementation.mdweb-guide.md詳細
Capacitor プラグインジェネレーター
人が自然言語で指定した要件、または構造化 YAML コントラクトから、レビュー可能な Capacitor プラグインの候補を生成します。出力は Capacitor の公式プラグインアーキテクチャに沿う必要がありますが、初回生成物であり、リリース前に人によるレビューが必要です。
このスキルを使用する場面
✅ 次の場合にこのスキルを使用します:
- Capacitor プラグインを新規作成する。
- Capacitor アプリにネイティブ機能(カメラ、センサー、ストレージなど)を追加する。
- プラグインのアーキテクチャと API コントラクトを設計する。
- iOS(Swift)または Android(Kotlin/Java)向けのネイティブコードを実装する。
- ネイティブ API を JavaScript/TypeScript にブリッジする。
- プラグインの設定とビルドシステムをセットアップする。
cordova-capacitor-plugin-migrationスキルから引き継いだ構造化 YAML コントラクトに基づいてプラグインを生成する。
❌ 次の場合はこのスキルを使用しないでください:
- 標準的な Capacitor アプリを構築する(代わりに Capacitor のドキュメントを使用してください)。
- ネイティブブリッジを必要としない Web 専用の機能を実装する。
- 既存の Capacitor コアプラグインを変更する。
- Cordova プラグインの構造を分析する(先に
cordova-capacitor-plugin-migrationを使用してください。このスキルが、このスキルで使用する入力コントラクトを生成します)。 - 既存のプラグインを新しい Capacitor バージョンにアップグレードする。
- 人によるレビューなしで、本番環境向けのコードを公開する。
前提条件
| 要件 | 用途 |
|---|---|
| Node.js LTS と npm | Capacitor プラグインジェネレーターとパッケージスクリプトを実行します。 |
| Xcode | iOS が対象の場合に、iOS の出力をビルドして検証します。 |
| Android Studio と Android SDK | Android が対象の場合に、Android の出力をビルドして検証します。 |
| CocoaPods と Gradle | 生成されたコードで必要な場合に、ネイティブ依存関係を解決します。 |
| Capacitor プラグインの知識 | 公開前に、生成されたネイティブブリッジコードをレビューします。 |
エージェントの動作
- ユーザーが会話形式の要件を指定したか、構造化 YAML を提供したかを判別します。
- 会話形式の場合、不足しているプラグインの識別情報、メソッド、プラットフォーム、イベント、権限、設定、ネイティブ依存関係のみを確認します。
- 構造化形式の場合、
references/input-contract.mdを解析して聞き取りを省略し、任意の移行ブロックに阻害要因またはティア 3 フックが含まれている場合は停止します。 - 移行メタデータは実装のコンテキストとしてのみ扱います。Cordova ソースの調査や分析は行わないでください。それは移行スキルの担当です。
- Capacitor 公式のプラグインジェネレーターを優先して使用し、生成されたひな形を編集して、要求された API を実装します。
- 生成コードはコントラクトファーストにします。TypeScript 定義を基準として、Web、iOS、Android、ドキュメント、サンプルアプリの動作を決定します。
- インストール済みの
@capacitor/core、@capacitor/android、@capacitor/iosパッケージに存在する Capacitor クラスのみを使用します。ヘルパークラス、ユーティリティ、インポートパスを作り出さないでください。API の存在が不確かな場合は、名前から推測せず、パッケージのソースを確認します。 - 生成する TypeScript コントラクトが既存の公開 API(Capacitor のコア/コミュニティ、Capawesome、内部ライブラリ、またはユーザーが置き換える文書化済み JavaScript API)を反映する場合、実際に通信で使用される文字列リテラル値を調べます。人にわかりやすい名前から値を導き出さないでください。構造化形式では YAML にこれらの値が明記されています。会話形式で生成する場合は、ソースを確認する必要があります。
- ブリッジファイルは薄く保ちます。メソッドが大きな責務混在ブロックになる場合は、ネイティブロジックを実装、マネージャー、権限、設定、マッパーの各ヘルパーに分割します。
- デモでの実装しやすさではなく、意図された製品の動作に基づいてネイティブ API を選択します。要求された動作に権限、特別なアプリ設定、または手動のアプリ設定が必要な場合は、適切な
checkPermissions()/requestPermissions()フローを生成し、手動で必要な設定を文書化します。 - 実行した検証コマンドと、ローカルでの人またはデバイスによる検証が必要な項目を明確に報告します。
- このスキルを使用して実際に公開してはいけません。公開チェックと
npm publish --access public --dry-runのみを実行します。
手順
フェーズ 1:タスクと入力モードを判断する
references/input-contract.md を読みます。入力が plugin、
platforms、api を含む YAML の場合は、構造化モードとして解析し、質問を省略します。
入力が会話形式の場合は、内部で同じ契約の形を作成するために必要な不足項目だけを確認します。
フェーズ 2:ひな形を作成する
references/scaffolding.md を読みます。可能な場合は、非対話型のフラグを指定して、公式の Capacitor プラグインジェネレーターを実行します。名前の一致を徹底します。
registerPlugin() の JavaScript 名、iOS の jsName、Android の
@CapacitorPlugin(name) を一致させます。
フェーズ 3:TypeScript API を設計する
references/api-design.md を読みます。ネイティブ実装の前に src/definitions.ts を定義します。各メソッドにはオプションと結果のインターフェースを使用し、列挙型の代わりに文字列のユニオン型を使用します。イベントのリスナーシグネチャを定義し、すべての項目に @since を含む JSDoc を記述します。
フェーズ 4:Web レイヤーを実装する
references/web-guide.md を読みます。WebPlugin を拡張し、ブラウザー API の使用前に機能を検出します。API が存在しても現在のブラウザーでは利用できない場合は unavailable() を、Web に相当する機能がない場合は unimplemented() をスローします。
Web レイヤーは動的インポートで登録します。
フェーズ 5:メソッドのシグネチャを定義する
references/api-design.md を読みます。各メソッドには、ブリッジの戻り値の型として値、void、コールバックのいずれかを選びます。コールバックの戻り値の型は、ストリームまたは長時間稼働する監視処理にのみ使用します。イベント名は TypeScript、Web、iOS、Android で同一にします。
フェーズ 6:iOS を実装する
references/architecture-patterns.md と references/ios-implementation.md を読みます。デフォルトでは Bridge パターンを使用します。薄い Capacitor プラグインクラスから実装クラスに処理を委譲します。複数のネイティブサブシステム、権限フロー、またはライフサイクルへの対応が必要な複雑なプラグインに限り、Facade を使用します。
フェーズ 7:Android を実装する
references/architecture-patterns.md と references/android-implementation.md を読みます。デフォルトでは Bridge パターンを使用します。薄い Plugin クラスから実装クラスに処理を委譲します。複数のマネージャー、権限フロー、サービス、アクティビティ、またはライフサイクルフックが必要な複雑なプラグインに限り、Facade を使用します。
フェーズ 8:サンプルアプリを生成する
references/sample-app.md を読みます。成功時の処理、想定されるエラー、権限、設定、リスナーを含め、公開プラグイン API 全体を試せるサンプルアプリを作成または更新します。
フェーズ 9:Docgen と検証
references/testing-strategies.md と references/publishing.md を読みます。
npm run docgen で JSDoc から API ドキュメントを生成します。API ドキュメントを手書きしてはいけません。対象プラットフォームに応じた検証コマンドを実行し、環境上の制約で実施できなかった確認事項を記録します。
フェーズ 10:公開前の確認
references/publishing.md を読みます。公開前チェックリストを実行し、ドライランを行います。
npm publish --access public --dry-run。このスキルの範囲外で人による明示的なレビューを受けずに、生成したプラグインを公開してはいけません。
ベストプラクティス
DO
- ✅ コマンドラインフラグを指定して
npm init @capacitor/pluginを実行し、スキャフォルダーが非対話モードで動作するようにします。 - ✅ 質問する前に、入力モード(会話形式か、構造化 YAML か)を判定します。構造化モードでは聞き取りを完全に省略します。
- ✅ まず TypeScript API を設計し(コントラクトファースト)、そのコントラクトに基づいて Web、iOS、Android を実装します。
- ✅ デバイスがなくてもテストできるように Web 層を実装します。大半のメソッドが
unimplemented()をスローする場合でも同様です。 - ✅ 既存 API を再現する場合は、公式プラグインのネイティブ依存関係を調べます。同じ SDK を宣言し、再実装するのではなく薄いアダプターを作成します。
- ✅ すべての公開シンボルに JSDoc と
@sinceを付けてドキュメント化します。 - ✅ コミット前に
npm run fmtを実行し、完了を報告する前にnpm run verifyを実行します。 - ✅ iOS と Android では、テスト可能性を高めるために 2 クラスパターン(ブリッジ+実装)を使用します。
- ✅ 既存 API を再現する場合は、ワイヤーフォーマットの文字列値と数値を正確に一致させます。人にわかりやすい名前から推測せず、公式の
definitions.tsを確認します。 - ✅ TypeScript/Web/iOS/Android 全体でイベント名を統一します。
DON'T
- ❌ 関心事を混在させないでください。プラグインは 1 つの機能に集中させます。
- ❌ エラー処理を省略しないでください。標準の 4 コード分類(
UNAVAILABLE、PERMISSION_DENIED、INVALID_PARAMETER、OPERATION_FAILED)のコードで拒否します。 - ❌ TypeScript の公開 API で Promise の代わりにコールバックを使用しないでください。
- ❌ iOS/Android 専用の機能であっても、Web の実装を忘れないでください。
- ❌ 設定可能にすべき値をハードコードしないでください。
references/configuration.mdのランタイムプラグイン設定を使用します。 - ❌ Capacitor のクラス、ヘルパー、インポートパスをでっち上げないでください。インストール済みの
@capacitor/core、@capacitor/android、@capacitor/iosパッケージで確認します。 - ❌
Pluginサブクラスの外部からnotifyListeners(...)を呼び出さないでください。references/architecture-patterns.mdの「Event Dispatch Locality」を参照してください。 - ❌ このスキルから公開しないでください。
npm publish --access public --dry-runを使ったドライランのみ実行します。 - ❌ Cordova のソースを調査または分析しないでください。これは兄弟関係にある移行スキルの担当です。
Error Handling
| 症状 | 対処方法 |
|---|---|
npm init @capacitor/plugin が Refusing to prompt in non-TTY environment で失敗する | 必須のフラグをすべて指定して、対話なしで実行します。npm init @capacitor/plugin <folder> -- --name "<npm-name>" --package-id "<reverse-dns>" --class-name "<PascalCase>" --description "<one-line>" --author "<name <email>>" --license "<SPDX>" --repo "<url>" --android-lang "<kotlin|java>" を実行してください。references/scaffolding.md を参照してください。 |
npm init @capacitor/plugin が invalid option: --android-lang undefined: Must be either 'kotlin' or 'java' で失敗する | 対話なしで実行する場合、--android-lang フラグが必須です。コマンドに --android-lang "kotlin"(新しいプラグインに推奨)または --android-lang "java" を追加してください。 |
| プラグインの読み込みが何も表示されずに失敗する | registerPlugin() の名前が、iOS の jsName および Android の @CapacitorPlugin(name) と一致するようにします。 |
| JS でイベントを受信できない | イベント名の文字列が、TypeScript、Web、iOS、Android ですべて同一になるようにします。 |
| iOS のメソッドを JS から呼び出せない | メソッドに @objc が付いており、pluginMethods に記載されていることを確認します。 |
| Android のメソッドを JS から呼び出せない | メソッドが public で、@PluginMethod() が付いていることを確認します。 |
npm run verify:ios が失敗する | pod install --repo-update を実行してから、iOS の検証コマンドを再実行します。 |
npm run verify:android が失敗する | Gradle を同期し、Android SDK、コンパイル SDK、依存関係のバージョンを確認します。 |
Android のコンパイルエラー:class X is public, should be declared in a file named X.java | Java では、public クラスをそのクラス名と一致するファイルに配置する必要があります。プラグインごとに複数の Java クラスを生成する場合は、各 public クラスをそれぞれ別のファイルに配置してください。Kotlin にはこのルールはありません。 |
Android のコンパイルエラー:notifyListeners(...) has protected access in Plugin | Plugin の notifyListeners() は protected です。Plugin を継承するクラスの内部からのみ呼び出してください。別のクラスでイベントを発行する必要がある場合は、データをプラグインに返してそこでディスパッチするか、プラグインに notifyListeners() を内部で呼び出す public ラッパーを公開します。 |
Android のコンパイルエラー:com.getcapacitor.* のインポートで cannot find symbol: class … が発生する | インストール済みの @capacitor/android が提供する API に、そのインポートは存在しません。生成前にパッケージのソースでインポートを確認してください。名前から Capacitor クラスを推測しないでください。 |
Android のコンパイルエラー:<method> in <Subclass> cannot override <method> in Plugin; attempting to assign weaker access privileges; was public | Plugin のサブクラスにあるヘルパーが、com.getcapacitor.Plugin にすでに定義されている public メソッド(例:hasPermission、getPermissionState、notifyListeners)と衝突しています。ヘルパーの名前を変更するか、親クラスと同じ public の可視性にしてください。 |
TypeScript のビルドエラー:Cannot find type definition file for '<name>' または Invalid module name in augmentation, module '<name>' cannot be found | 拡張対象のモジュールがインストールされていません。devDependencies に追加してください(トリプルスラッシュ参照を使用する場合は、tsconfig.json の compilerOptions.types にも追加します)。@capacitor/cli だけでなく、あらゆるモジュール拡張に当てはまります。 |
TypeScript のビルドエラー:Interface 'X' incorrectly extends interface 'Y'. Property 'Z' is optional in type 'X' but required in type 'Y'(またはその逆のエラー) | 組み込みの lib 型がすでに提供しているメンバーを再宣言しないでください。lib 型をそのまま使用するか、本当に新しいメンバーのみを declare global { interface Y { newMember?: ... } } で拡張します。機能の有無を確認するには、実行時に 'name' in target のガードを使用します。 |
npm run docgen の出力が空になる | src/definitions.ts に JSDoc を追加します。docgen は TypeScript のコントラクトを読み取ります。 |
| 対象のブラウザーで Web API が利用できない | API が存在するものの、この環境では利用できない場合は unavailable() を使用します。Web に相当する機能が存在しない場合は unimplemented() を使用します。 |
| 構造化 YAML が拒否される | references/input-contract.md に照らして検証し、必須の基本フィールドがそろっていて、ブロッカーが空であることを確認します。 |
| 生成された出力の対象範囲が広すぎる | 関連のない機能を別々のプラグインに分割し、API の範囲を絞って再生成します。 |
| 生成されたネイティブコードが、公式プラグインではネイティブ SDK に委譲しているロジックを再実装している | 公式プラグインの .podspec/Package.swift/android/build.gradle を調べて、ネイティブ SDK への依存関係を確認します。依存関係がある場合は、同じ SDK を宣言して薄いアダプターを作成してください。references/api-design.md の「ネイティブ依存関係の検出」を参照してください。 |
関連スキル
cordova-capacitor-plugin-migration:Cordova プラグインを分析し、このジェネレーター向けの構造化された移行計画を作成します。
参考資料
references/input-contract.md:ジェネレーター入力の構造化 YAML コントラクト。references/scaffolding.md:ジェネレーターの呼び出し、名前の一致、スキャフォールドの検証。references/api-design.md:TypeScript API の設計、JSDoc、イベントシグネチャ、メソッドの戻り値の型。references/web-guide.md:WebPlugin のパターン、動的インポート、機能検出、エラー。references/architecture-patterns.md:ブリッジパターンとファサードパターン、およびイベントの整合性。references/ios-implementation.md:iOS ブリッジ、実装クラス、権限、依存関係、Podspec。references/android-implementation.md:Android ブリッジ、実装クラス、権限、依存関係、Gradle。references/configuration.md:plugins.<PluginJSName>配下の Capacitor 設定キー。references/testing-strategies.md:ローカルリンク、検証コマンド、フック、レビューのワークフロー。references/publishing.md:パッケージのフィールド、docgen、チェックリスト、ドライランでの公開。references/sample-app.md:API 全体を網羅するサンプルアプリの要件。references/permission-patterns.md:権限フローの詳細 — iOS の複数権限に対応する DispatchGroup、位置情報デリゲート、使用前の確認/必要時の確認/コンシューマーへの委任パターン、システム設定を開く方法。references/typescript-implementation.md:TypeScript レイヤーの詳細 — シングルトンプラグインパターン、型付きエラークラス、イベントリスナーハンドルの完全な管理、ヘルパーユーティリティ、Jest のスキャフォールド。