storymesh は、コンポーネントに対応する Storybook の story ファイルがあるかを検査し、story coverage を報告する Rust 製 CLI です。React、Vue、Angular に対応しています。
次の用途を想定しています。
- story がないコンポーネントを一覧表示する
- story がないコンポーネント用の最小 story を生成する
- Storybook coverage を件数とパーセントで確認する
- CI で story の追加漏れを検知する
| フレームワーク | 主なコンポーネントファイル | --framework |
|---|---|---|
| React | .tsx、.jsx、PascalCase の .ts / .js |
react |
| Vue | .vue |
vue |
| Angular | *.component.ts、@Component(...) を持つ .ts |
angular |
npm を利用する場合は、プロジェクトへの追加または一度だけの実行ができます。
npm install --save-dev storymesh
npx storymesh check src/components --framework reactグローバルにインストールする場合は次のとおりです。
npm install --global storymesh
storymesh --helpAI エージェントに story coverage の確認、missing story の検出、明示依頼時の
story skeleton 生成を行わせる場合は、npx skills で storymesh スキルを導入できます。
npx skills add Inoue416/storymesh --skill storymeshCodex のプロジェクト設定へ確認なしで導入する場合は、次を実行します。
npx skills add Inoue416/storymesh --skill storymesh --agent codex --yes配布・公開の詳細は AI エージェント向けスキルの配布・公開手順 を参照してください。
対応する npm 配布環境は、glibc Linux x64/ARM64、macOS x64/ARM64、Windows x64 です。Node.js 18 以上が必要です。
ソースからビルドする場合は、mise をインストールし、このリポジトリを取得したディレクトリで実行します。
mise install
mise exec -- cargo build --release
./target/release/storymesh --help以降の例ではビルド済みの ./target/release/storymesh を使用します。開発中に直接実行する場合は、代わりに mise exec -- cargo run -- を使用できます。
React プロジェクトの src/components を検査する例です。
./target/release/storymesh check src/components --framework reactstory がないコンポーネントがある場合は、対象ファイルを表示して終了コード 1 を返します。
Missing stories for 1 React component(s):
Card.tsx
すべてのコンポーネントに story がある場合は終了コード 0 です。
All 3 React components have stories.
story がないコンポーネントを一覧表示します。CI で追加漏れを検知する場合に使用します。
./target/release/storymesh check [PATH] [--framework react|vue|angular] [--ignore PATTERN] [--ignore-file PATH] [--generate]--generate を指定すると、missing として検出した各コンポーネントと同じディレクトリに、最小の Component Story Format (CSF) story を生成します。
./target/release/storymesh check src/components --framework react --generateMissing stories for 1 React component(s):
Card.tsx
Generated 1 story skeleton(s):
Card.stories.tsx
--generate 指定時は missing の有無ではなく生成処理の成否を終了コードで示します。すべて生成できた場合(生成対象がない場合を含む)は 0、生成に失敗した場合は 2 です。生成した story を含めて再度 check すると coverage 済みとして扱われます。既存ファイルは上書きしません。
React はコンポーネントと同じ拡張子(例: Button.tsx → Button.stories.tsx)、Vue と Angular は .stories.ts を生成します。React は default export と、ファイル名に対応する一般的な named export を判別します。import 可能な export が見つからない場合は、Storybook 上で編集を始められる render: () => null のプレースホルダーを生成します。Vue は default export、Angular は一般的なクラス名(例: user-card.component.ts → UserCardComponent)を前提とするため、プロジェクトの export が異なる場合は生成後に import を調整してください。
coverage のパーセントと件数を表示します。
./target/release/storymesh coverage src/components --framework vueVue Storybook coverage: 83.3% (5/6 components)
coverage と、story がないコンポーネントの両方を表示します。
./target/release/storymesh report src/app --framework angularAngular Storybook coverage: 83.3% (5/6 components)
Missing: 1
profile.ts
PATH を省略するとカレントディレクトリを検査します。--framework を省略した場合は react です。
検査対象からパスを除外するには、--ignore を繰り返し指定します。パターンは検査ルートからの相対パスとして解釈されます。
./target/release/storymesh check src --ignore 'generated/**' --ignore '**/*.fixture.tsx'検査ルートの .storymeshignore は自動的に読み込みます。.gitignore と同じ形式で、空行・# コメント・! による再包含・* / **・末尾の / を使用できます。
# generated components are not maintained by this repository
generated/
**/*.fixture.tsx
!generated/DocumentedButton.tsx別の ignore ファイルを追加する場合は --ignore-file を繰り返し指定できます。相対パスは検査ルートを基準に解決されます。
開発環境の React、Vue、Angular テストアプリでは、次のコマンドで手動検証できます。
通常の storymesh:check は意図的に未対応の fixture を 1 件報告し、後者の 2 コマンドは
それぞれ --ignore と --ignore-file によって成功します。
cd .storymesh-test-apps/react-app
pnpm storymesh:check
pnpm storymesh:ignore-pattern
pnpm storymesh:ignore-file
cd ../vue-app
pnpm storymesh:check
pnpm storymesh:ignore-pattern
pnpm storymesh:ignore-file
cd ../angular-app
pnpm storymesh:check
pnpm storymesh:ignore-pattern
pnpm storymesh:ignore-file| 終了コード | 意味 |
|---|---|
0 |
正常終了した。通常の check では missing がなく、--generate 指定時は生成に成功した |
1 |
通常の check が story のないコンポーネントを検出した |
2 |
パスの読み取りや出力などでエラーが発生した |
coverage、report、生成に成功した check --generate は missing があっても正常終了します。missing を CI の失敗として扱う場合は --generate を付けない check を使用してください。
- story はコンポーネントと同じディレクトリ、または直下の
stories/__stories__ディレクトリから検索します。 - story の拡張子は
.js、.jsx、.mjs、.cjs、.ts、.tsxに対応します。 .git、.next、.storybook、build、coverage、dist、node_modules、targetディレクトリは走査しません。.storymeshignore、--ignore、--ignore-fileで除外したファイルは、component と story のいずれにも数えません。*.test.*、*.spec.*、story 自身はコンポーネント数に含めません。
.tsx/.jsxをコンポーネントとして扱います。小文字のmain.tsx/main.jsxはエントリポイントとして除外します。.js/.tsは PascalCase のファイル名(例:Button.js)をコンポーネントとして扱います。*.d.tsは除外します。Button.tsxにはButton.stories.tsxのような同名の story を対応付けます。Button/index.tsxとButton/Button.stories.tsxの構成にも対応します。
.vueをコンポーネントとして扱います。Button.vueにはButton.stories.tsのような同名の story を対応付けます。Button/index.vueとButton/Button.stories.tsの構成にも対応します。
*.component.tsをコンポーネントとして扱います。- Angular の新しい命名規則で生成される
app.tsなどは、コメントと文字列を除いたコード上の@Component(...)デコレータから検出します。 button.component.tsにはbutton.stories.tsまたはbutton.component.stories.tsを対応付けます。- suffix-less component の
profile.tsにはprofile.stories.tsを対応付けます。
storymesh はパスとファイル名を中心に判定し、Storybook の CSF や各フレームワークの AST を完全には解析しません。
- コンポーネントと異なる名前の story は対応付けません。
- MDX ドキュメントは coverage に数えません。
- React の非コンポーネント
.jsx/.tsxや、Vue の画面・レイアウトもコンポーネントとして数える場合があります。 - Angular の
Componentを別名 import した suffix-less component は検出しません。
開発用コマンドは mise 経由で実行します。ハーネス検査には jq も必要です。
mise run quick # rustfmt + tests
mise run handoff # 差分に応じた最終ゲート
mise run verify # harness + rustfmt + Clippy + tests
mise run format
mise run lint
mise run test
mise run check
mise run npm-checkCodex 開発ハーネスの運用方法は docs/codex-harness.md を参照してください。 npm 公開を行うメンテナー向けの手順は npm 公開手順 を参照してください。
依存関係の更新 PR は Renovate で管理します。リポジトリ管理者は Renovate GitHub App をこのリポジトリにインストールしてください。 設定は renovate.json にあり、Rust(Cargo)、npm、GitHub Actions の更新を検出します。