create-requires-module について
既存の `.plain` モジュールに依存するモジュールを作成するためのスキルです。ビルド順、参照可能な仕様やエクスポート概念、設定の検証方法を案内します。
主な機能
- 01モジュールをビルドチェーンに接続
- 02祖先モジュールの生成コードを再利用
- 03先行する機能仕様を参照
- 04エクスポートで概念の可視性を制御
- 05祖先パスと仕様の競合を検証
活用シーン
- 01既存モジュールを基にモジュールを作成
- 02ビルドチェーンの特定箇所に接続
- 03依存パスの禁止されたダイヤモンド結合を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ plainlang/ plain-forge --skill create-requires-moduleインストール後、Claude Code で/create-requires-moduleを入力して読み込まれたか確認します。
詳細
Requires モジュールの作成
まずルールを読み込んでください。 .plain ファイルを読む、編集する、または書き込む前に、load-plain-reference スキルを実行し、案内されたルールファイルを読んでください。この会話ですでに load-plain-reference が実行されている場合に限り、省略できます。
Requires の機能
requires は、現在のモジュールをプロジェクトのビルドチェーンに接続します。要求されたモジュールは現在のモジュールより先にビルドされ、その生成コード(そのモジュールとすべての祖先の累積出力)が開始点としてコピーされます。現在のモジュールが要求されたモジュールの機能を拡張する必要はありませんが、両者の出力は独立しません。現在のモジュールのコードには、要求されたモジュールのコードが物理的に含まれます。
このモジュールがレンダリングされるとき:
- 要求されたモジュールの生成コード(
plain_modules/<required_module>/code)が開始点としてコピーされます。 - 要求されたモジュールおよびすべての祖先の
***機能仕様***が、以前の機能仕様として表示されます。 - 要求されたモジュールの定義のうち、
exported_conceptsに含まれる概念のみが、それぞれ定義全文とともに表示されます。エクスポートの可視性は推移しません。祖先のエクスポートを参照するには、その祖先もrequiresに記載してください。 - 要求されたモジュールのテスト用 plain ファイルは、そのモジュールに属したままです。新しいモジュールには、そのモジュールが追加する機能ごとに独自のテスト用 plain ファイルが作成されます(
test-plain-files.mdを参照)。
requires で接続されたすべてのモジュールは、共通のルートを持つ単一のツリーを形成します。ダイヤモンド結合は禁止されています。複数の requires エントリーは、1 つのルートから先端までの祖先パス上に並んでいる必要があります。最も深いエントリーが接続点となり、ほかのエントリーはその祖先のエクスポートを可視にするためだけに指定します。
次の場合に requires を使用します:
- 既存モジュールの機能を基盤として構築する場合
- 異なる関心事を扱う場合でも、ビルドチェーンの適切な位置にモジュールを接続する場合
共有の定義と reqs のみが必要で(機能仕様や生成コードは不要で)、あれば、代わりに import を使用してください。create-import-module スキルを参照してください。
ワークフロー
- 接続点を特定します。 ビルドチェーンで、この新しいモジュールをどの既存モジュールの後に接続するかを判断します。そのモジュールはすでに存在し、レンダリング可能でなければなりません。追加のモジュールを指定する場合は、それぞれが接続点の祖先であることを確認してください。ダイヤモンド結合は認められません。
- リポジトリのルートに YAML フロントマターで
requiresフィールドを含む.plainファイルを作成します。 機能仕様を含むモジュールはtemplate/ではなくルートに配置します。 - 祖先チェーン全体の機能仕様を確認します。 それらは以前の要件として扱われます。新しい機能仕様は、そのいずれとも競合してはなりません。
- 指定した各モジュールの
exported_conceptsを確認します。 参照できるのはその概念のみです。祖先のエクスポートを使うには、その祖先を指定する必要があります。 - モジュール固有の内容を追加します。 このモジュールに固有の定義、実装 reqs、テスト reqs、機能仕様を追加します。すべての機能仕様は
add-functional-specまたはadd-functional-specsを使って追加してください。これらのスキルはテスト用 plain ファイルも作成します。 - 競合がないか確認します。 新しい機能仕様と、祖先チェーン内のすべての仕様との競合を確認してください。
形式
requires フィールドは YAML フロントマター内のモジュールパスのリストです。
---
requires:
- base_module
import:
- shared_template
description: Extended module that builds on base_module
---
***definitions***
- :NewFeature: is a feature added by this module.
***functional specs***
# new-feature
:NewFeature: is available.
モジュールでは requires と import を併用できます。requires はルートレベルのほかのモジュールを指定し、import はデフォルトの template/ ディレクトリから解決されます(プレフィックスは不要です)。
複数の requires エントリーを指定できるのは、それらが 1 つの祖先パス上にある場合のみです(例:messaging 自身が auth を要求する場合の requires: [auth, messaging])。最も深いエントリー(messaging)が接続点となり、auth はそのエクスポートを可視にするためだけに指定されます。
エクスポートされた概念
必須モジュールは、exported_concepts を通じて、どの概念を参照できるかを制御します。
> In the required module's frontmatter:
---
exported_concepts: [":StorageClient:", ":BackupResult:"]
---
このモジュールを require するモジュールから利用できるのは、:StorageClient: と :BackupResult: のみで、それぞれ完全な定義テキストが含まれます。必須モジュールのその他の概念はすべて内部扱いです。
requires を使った時系列順序
requires の祖先チェーン全体に含まれる機能仕様は、以前の機能仕様として扱われます。つまり、次のとおりです。
- すでにレンダリングされており、そのコードも存在します。
- 新しい仕様は、それらの後にレンダリングされ、定義済みの内容をすべて把握した状態になります。
- 新しい仕様は、祖先チェーン内のどの仕様とも競合してはなりません。
- レンダラーは、仕様をレンダリングする際に、チェーン内の機能仕様をコンテキストとして参照します。
現在のモジュールは必須モジュールと機能的に関連している場合も、そうでない場合もありますが、いずれの場合も requires によって、蓄積されていくビルドチェーン内の適切な位置に配置されます。
import と requires の違い
| 項目 | import | requires |
|---|---|---|
| 定義を取り込む | はい | いいえ(exported_concepts のみ) |
| 実装要件を取り込む | はい | いいえ |
| テスト要件を取り込む | はい | いいえ |
| 機能仕様を取り込む | いいえ | はい(推移的に、以前の要件として) |
| 生成されたコードをコピーする | いいえ | はい(蓄積された祖先チェーン) |
| 一般的な用途 | テンプレート、共有定義 | モジュールをビルドチェーンに追加する |
検証チェックリスト
- モジュールファイルがリポジトリのルートにある(
template/内ではない) - 必須モジュールが存在し、レンダリング可能である
- すべての
requiresエントリーが1つの祖先パス上にある(ダイヤモンド結合がない) - 最も深い
requiresエントリーが、意図した追加先である - 列挙された各モジュールの
exported_conceptsに、必要な概念が含まれている - 新しい機能仕様が、祖先チェーン内のどの仕様とも競合しない
- モジュールに機能仕様と実装要件がそれぞれ1つ以上ある
- すべての機能仕様に対応するテスト用プレーンファイルがある
-
requiresとimportが正しく使い分けられている(混同されていない) - YAML フロントマターが
---マーカーで正しく囲まれている