design-compliance について
design-complianceは、Hexagone Web開発者向けのデザインシステム監査スキルです。ページやコンポーネントのコードを調べ、開発サーバーが利用できる場合はライト・ダーク表示も確認し、違反を修正してレポートを作成します。
主な機能
- 01URL、ページ名、コンポーネント名を解決
- 02ローカルコンポーネントツリーを再帰的に分析
- 03デザイントークンとフレームワーク規約を確認
- 04可能な場合にライト・ダークモードを検査
- 05違反コードを修正しレポートを作成
活用シーン
- 01Hexagoneのページをデザインシステムに照らして監査
- 02古いPrimeVueコンポーネントをPrimeVue 4の規約に更新
- 03ハードコード色やトークン違反を発見して修正
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dedalus-erp-pas/ foundation-skills --skill design-complianceインストール後、Claude Code で/design-complianceを入力して読み込まれたか確認します。
詳細
デザイン準拠性
Hexagone Web アプリケーションのページまたはコンポーネントに対して、完全自律型のデザインシステム準拠性監査を実行します。このスキルは、ソースファイルを特定し、コンポーネントツリー全体を再帰的に分析して、レンダリングされたページを(ライトモードとダークモードの両方で)視覚的に検査し、Hexagone デザインシステムのルールに対するすべての違反を検出し、違反をすべてその場で自動修正して、構造化レポートを出力します。これらすべてを、ユーザーに確認を求めることなく実行します。
このスキルを使用するタイミング
次のような場合に有効にします。
- ユーザーが URL、コンポーネント名、またはページ名に続けて「design-compliance」と言う
- ページまたはコンポーネントのデザインシステム準拠性を監査または確認するよう依頼する
- 既存のコードに PrimeVue/Tailwind/Hexagone のトークン規約を適用したい
- Hexagone のコードについて「デザインを確認して」「UI を監査して」「デザインレビュー」と言う
基本原則
1. 完全な自律性
- 実行中に質問することなく、パイプライン全体を実行します
- 引数が指定されていない場合は、確認対象をユーザーに尋ねてから、自律的に実行します
- ファイルは確認を求めずにその場で編集します
- 変更はコミットしません。開発者が差分を確認します
2. 単一の標準(MF ごとの例外なし)
- Composition API と
<script setup lang="ts">を常に使用します - Tailwind CSS 4 を常に使用します
- 状態管理には Pinia を常に使用します
- PrimeVue 4 ネイティブコンポーネントを常に使用します(新規コードおよび変更コードでは hexa-compat を使用しません)
- スコープ付きトークンのオーバーライドには
dtを常に使用します(視覚的なスタイリングにptは使用しません)
3. Hexagone 固有
このスキルは、Hexagone Web モノレポのスタックに合わせて調整されています。
hexagone-preset.js(Aura を拡張)を使用する PrimeVue 4.3- Tailwind CSS 4
- 3 層のトークンシステム:
--p-*(PrimeVue)、--hexa-*(shell のみ)、beta-scss(レガシー、禁止) - TypeScript を使用する Vue.js 3.5
4. すべてを修正
このスキルは、機械的な違反(インポート名の変更、クラスの置き換え)と構造的な違反(コンポーネントの置き換え、テンプレートの書き換え)の両方を含む、すべての違反を自動修正します。レポートのみのモードはありません。編集前に確認を求めることもありません。
情報源(優先順位順)
このスキルは、次の情報源を記載順に確認してルールセットを構築します。
-
明示的なルールファイル(存在する場合はすべてに優先):
design-system.mdまたはdocs/design-system/design-rules.mdCLAUDE.md(ルートおよび MF ごと).github/copilot-instructions.mdまたは.github/instructions/*.md
-
フレームワークの設定:
hexagone-preset.js— PrimeVue プリセット(トークン、カラースキーム)shell-tokens.scss— Shell のクロームトークン(--hexa-*)tailwind.config.*— Tailwind の設定package.json— PrimeVue のバージョン、依存関係
-
コードベースのパターン:
- 既存の「良好な」コンポーネントを暗黙の規約として使用
- ルーターの設定を使用してルートとコンポーネントを対応付け
入力モード
このスキルは、3 種類の入力を受け付けます。どの入力も最終的には同じパイプラインに進みます。
URL モード
/design-compliance http://localhost:5173/hexagone-etab/vue/patients
- 視覚的な検査に URL を直接使用します
- URL のパスからルーター設定内のルートを逆引きします
- そのルートのコンポーネントファイルを特定します
- すべてのローカルインポートを再帰的に解決します
コンポーネント名モード
/design-compliance PatientDashboard
- 一致するファイルを glob で検索します:
**/PatientDashboard.vue、**/patient-dashboard.vue、**/PatientDashboard/** - 複数見つかった場合は、すべてを確認します
- 一致した各コンポーネントについて、視覚的な検査のために属するルートがあれば特定します
- すべてのローカルインポートを再帰的に解決します
ページ名モード
/design-compliance Patients
- ルーター設定ファイルで、「Patients」という名前、またはパスが
/patientsのルートを検索します - そのルートに割り当てられているコンポーネントを特定します
- 視覚的な検査に使用する URL を構成します
- すべてのローカルインポートを再帰的に解決します
引数なし
/design-compliance
確認対象をユーザーに尋ねます。推測しないでください。
ワークフロー
ステップ 1:信頼できる情報源を特定する
-
明示的なルールファイルを読み込む(プロジェクト内に存在する場合):
**/CLAUDE.md、**/design-system.md、**/design-rules.mdを Glob で検索する.github/copilot-instructions.md、.github/instructions/*.mdを Glob で検索する- デザインシステムのルール、アンチパターン、トークンの規約を抽出する
-
フレームワークの設定を読み込む:
- PrimeVue のプリセットファイルを検索して読み込む(通常は
**/hexagone-preset.jsまたは**/theme/*.js) - シェルトークンを検索して読み込む(通常は
**/shell-tokens.scss) package.jsonを読み込んで PrimeVue のバージョンと依存関係を確認する- Tailwind の設定があれば読み込む
- PrimeVue のプリセットファイルを検索して読み込む(通常は
-
統合ルールセットを作成する — すべての情報源を、適用するルールのチェックリストにまとめる
ステップ 2:対象ファイルを解決する
入力モードに基づいて、次の手順を実行します。
-
ユーザーの入力を解析してモード(URL、コンポーネント名、ページ名)を特定する
-
エントリーポイントのファイルを検索する:
- URL → パスを解析し、ルーターのファイル(
**/router/**/*.{js,ts}、**/router.{js,ts})で一致するルートを検索して、コンポーネントを取得する - コンポーネント名 →
**/<name>.vue、**/<name-kebab>.vue、**/<Name>/**を Glob で検索する - ページ名 → ルーター設定でルート名またはパスの一致を検索する
- URL → パスを解析し、ルーターのファイル(
-
コンポーネントツリーを再帰的に解決する:
- 各
.vueファイルを読み込む - すべてのローカルインポートを抽出する(
primevue/*、vue、vue-router、pinia、node_modulesは除外) - 各インポートをファイルまでたどり、新しいローカルコンポーネントが見つからなくなるまで繰り返す
- レビュー対象となる完全なファイル一覧を作成する
- 各
-
見つかったツリーをユーザーに報告する:
Found 12 files in component tree for PatientDashboard: - frontend/gap-mf/src/views/PatientDashboard.vue (entry) - frontend/gap-mf/src/components/PatientHeader.vue - frontend/gap-mf/src/components/PatientTimeline.vue - ...
ステップ 3:静的コード解析
コンポーネントツリー内の各ファイルについて、すべての違反カテゴリを確認します。
カテゴリ 1:不適切なコンポーネント
- PrimeVue に同等のコンポーネントがある場合の生の
<button>、<input>、<select>、<textarea>、<table> <btn>、<alert>、<card>、<action>、<spinner>(hexa-compat)— PrimeVue ネイティブのコンポーネントを使用する必要があります- すべての hexa-components(
<datepicker>、<data-table>、<modal>など)— PrimeVue ネイティブのコンポーネントを使用する必要があります - **修正:**適切な PrimeVue コンポーネントに置き換え、インポートを更新し、props/スロットを調整する
カテゴリ 2:不適切なトークンレイヤー
- ハードコードされた色:
<style>またはインラインスタイル内の#xxx、rgb(...)、hsl(...) - テンプレート内の beta-scss クラス:
text:teal、bg:grey-lightest、flex:6/12など - シェルコンポーネント(Header、Sidebar、Navigation)以外で使用されている
--hexa-*トークン - Tailwind の任意の値:
text-[#ff0000]、bg-[rgb(...)]、p-[17px] - 修正:
var(--p-*)トークン、Tailwind のテーマクラス、またはdt()のオーバーライドに置き換える
カテゴリ 3:pt の誤用
- 視覚的なスタイル設定に
ptprop を使用している:border、shadow、padding、margin、background、color、font-size、border-radius - **修正:**視覚的なオーバーライドを
dtprop、またはトークンを使った<style scoped>に移す
カテゴリ 4:インポート違反
- 大文字の PrimeVue インポート:
primevue/InputText→primevue/inputtext - v3 のコンポーネント名:
Dropdown→Select、Calendar→DatePicker、InputSwitch→ToggleSwitch、OverlayPanel→Popover、TabView/TabPanel→Tabs/TabList/Tab/TabPanels/TabPanel、Chips→InputChips primevueのバレルからの名前付きインポート:import { InputText } from "primevue"→ デフォルトインポート- **修正:**インポート文を書き換え、コンポーネントの登録とテンプレートでの使用箇所を更新する
カテゴリ 5:ダークモード違反
<style scoped>内にネストされた:global(.p-dark)— スコープなしの別の<style>ブロックを使用する必要があります- ダークモード用のバリエーションがない、ライトモード専用のハードコードされた色
- **修正:**ダークモードのスタイルを別の
<style>ブロックに移し、自動的に切り替わるトークンを使用する
カテゴリ 6:i18n 違反
- テンプレート内のハードコードされたテキスト文字列(ラベル、プレースホルダー、タイトル、メッセージ、エラーテキスト)
- 例外:単一文字(
/、|、:、-)、数値、CSS クラス名、ユーザーに表示されない prop の値 - **修正:**ロケールファイルに抽出し、
t('key')(Composition API)または$t('key')(Options API)に置き換える
カテゴリ 7:アクセシビリティ
<button>またはアイコンのみでaria-labelが設定されていない PrimeVueButton- 関連付けられた
<label>がないフォームフィールド(for/idの組み合わせがない、FloatLabelラッパーがない) - コンテキストメニュー(右クリックハンドラー)— アプリはタブレットでも動作する必要があります
- ホバーのみの操作(クリックによる代替手段がない
@mouseenter/@mouseleave) <img>タグにaltがない- 修正方法:
aria-labelを追加し、FloatLabelで囲み、ホバー操作をクリック操作に置き換え、altテキストを追加します
カテゴリ 8:フレームワークの規約
<script setup lang="ts">ではなく Options API(export default { data(), methods, computed })を使用している<script setup>にlang="ts"がない- Pinia ではなく Vuex/pathify を使用している
- Pinia の
useXxxStore()ではなくthis.$store/mapState/mapGetters/mapActionsを使用している - Tailwind クラスまたはトークンを使ったスコープ付き CSS ではなく、インラインスタイル(
style="...")を使用している - 新しいコードに
!importantがある(beta-scss のレガシーな競合を解消する場合に限り許容されます) - 修正方法:
<script setup lang="ts">を使った Composition API に書き換え、状態を Pinia に移行し、インラインスタイルを置き換えます
ステップ 4:視覚的な検査
前提条件: 一般的なポート(5173、5174、3000、8080)を確認し、開発サーバーが実行中かどうかを調べます。
開発サーバーが検出されない場合は、視覚的な検査を完全にスキップし、コードのみの結果をもってステップ 5 に進みます。
開発サーバーが実行中の場合:
4a. ページに移動する
-
URL を特定します:
- ユーザーが URL を指定した場合は、その URL をそのまま使用します
- コンポーネント名/ページ名が指定された場合は、ルート設定から URL を組み立てます
- ルートを特定できない場合は、視覚的な検査をスキップします
-
ヘッドレスブラウザー(Playwright)でページを開きます
-
認証を処理します:
- ログインページが検出された場合(ログインフォーム、
/loginへのリダイレクトを確認)、認証します:- ユーザー名:
apvhn - パスワード:
apvhn
- ユーザー名:
- ログイン後、対象ページに移動します
- ログインページが検出された場合(ログインフォーム、
4b. ライトモードの検査
- ページ全体のスクリーンショットを撮ります
- 主な要素の算出済みスタイルを分析します:
--p-*トークンの値に一致しないハードコードされた色がないか確認します- Tailwind の間隔スケールに沿わない値など、標準外の間隔がないか確認します
- 兄弟要素間で角丸が一貫しているか確認します
- 視覚的なヒューリスティック:
- 要素のずれ(兄弟要素間でパディング/マージンに一貫性がない)
- レスポンシブ動作の破損または不整合
- 要素がコンテナーからはみ出している
- 同じコンテキスト内でフォントサイズに一貫性がない
4c. ダークモードの検査
- ダークモードを切り替えます。ブラウザーで
document.documentElement.classList.add('p-dark')を実行します - ページ全体のスクリーンショットをもう一度撮ります
- 以下を確認します:
- 適応しないハードコードされた明るい色(白い背景、暗い背景上の暗い文字)を持つ要素
--hexa-*トークンが正しく切り替わらない- コントラストの問題(背景に対して文字が読みにくい)
- トークンベースではないスタイルによる視覚的な乱れ
4d. 結果を記録する
すべての視覚的な問題を以下の項目とともにまとめます:
- 要素セレクターまたは説明
- 問題の説明
- 重大度(P1:動作しない/判読できない、P2:一貫性がない、P3:軽微な仕上げ)
ステップ 5:すべての違反を自動修正する
見つかった違反(コードおよび視覚面)ごとに、以下を行います:
- 修正の優先順位を決めます: P1(動作しない)→ P2(一貫性がない)→ P3(仕上げ)
- Edit ツールを使ってファイルを直接編集します
- 既存のパターンに従います: 修正時は周囲のコードのスタイルに合わせます
- 連鎖する修正に対応します: コンポーネントの置き換えによって API(props、slots、events)が変わる場合は、テンプレート内のすべての使用箇所を更新します
- インポートを更新します: PrimeVue のインポートを追加し、未使用のものを削除します
- コミットしないでください — 開発者が確認できるよう、変更はステージングしないでください
ステップ 6:レポートを作成する
構造化されたレポートをターミナルに出力します:
## Design Compliance Report
**Target:** [component/page name or URL]
**Files analyzed:** [count]
**Violations found:** [count]
**Violations fixed:** [count]
**Visual inspection:** [performed (light + dark) / skipped (no dev server)]
### Files in Component Tree
| # | File | Violations |
|---|------|------------|
| 1 | `frontend/gap-mf/src/views/PatientDashboard.vue` | 5 |
| 2 | `frontend/gap-mf/src/components/PatientHeader.vue` | 2 |
| ... | ... | ... |
### Violations Fixed
#### Category 1: Wrong Component ([count])
| File | Line | Before | After |
|------|------|--------|-------|
| `PatientDashboard.vue` | 42 | `<button @click="save">` | `<Button @click="save" label="..." />` |
#### Category 2: Wrong Token Layer ([count])
| File | Line | Before | After |
|------|------|--------|-------|
| `PatientHeader.vue` | 15 | `color: #006875` | `color: var(--p-primary-500)` |
#### Category 3: pt Misuse ([count])
...
#### Category 4: Import Violations ([count])
...
#### Category 5: Dark Mode Violations ([count])
...
#### Category 6: i18n Violations ([count])
...
#### Category 7: Accessibility ([count])
...
#### Category 8: Framework Conventions ([count])
...
### Visual Inspection Results
[If performed]
#### Light Mode
- [Issue 1: description — severity]
- [Issue 2: description — severity]
#### Dark Mode
- [Issue 1: description — severity]
- [Issue 2: description — severity]
### Summary
- **Total violations:** [count]
- **Auto-fixed:** [count]
- **Remaining (manual review needed):** [count, if any]
違反のリファレンス
PrimeVue v3 → v4 のコンポーネント名変更
| v3(使用禁止) | v4(正しい名前) | インポートパス |
|---|---|---|
Dropdown | Select | primevue/select |
Calendar | DatePicker | primevue/datepicker |
InputSwitch | ToggleSwitch | primevue/toggleswitch |
OverlayPanel | Popover | primevue/popover |
TabView / TabPanel | Tabs / TabList / Tab / TabPanels / TabPanel | primevue/tabs, etc. |
Chips | InputChips | primevue/inputchips |
HTML → PrimeVue の対応表
| 生の HTML | PrimeVue での置き換え |
|---|---|
<button> | primevue/button の <Button> |
<input type="text"> | primevue/inputtext の <InputText> |
<input type="checkbox"> | primevue/checkbox の <Checkbox :binary="true"> |
<input type="radio"> | primevue/radiobutton の <RadioButton> |
<select> | primevue/select の <Select> |
<textarea> | primevue/textarea の <Textarea> |
<table> | primevue/datatable、primevue/column の <DataTable> + <Column> |
<dialog> | primevue/dialog の <Dialog> |
<progress> | primevue/progressbar の <ProgressBar> |
hexa-compat → PrimeVue の対応表
| hexa-compat | PrimeVue ネイティブ |
|---|---|
<btn severity="..."> | primevue/button の <Button severity="..."> |
<alert color="red"> | primevue/message の <Message severity="error"> |
<card> | primevue/card の <Card> |
<action @click> | primevue/button の <Button link @click> |
<spinner> | primevue/progressspinner の <ProgressSpinner> |
<modal> | primevue/dialog の <Dialog> |
トークンレイヤーのルール
| コンテキスト | 使用可能 | 使用禁止 |
|---|---|---|
| ビジネスページ(ビュー、コンポーネント) | var(--p-*)、Tailwind クラス、dt() | var(--hexa-*)、beta-scss クラス、ハードコードされた色 |
| シェルコンポーネント(Header、Sidebar、Nav) | var(--hexa-*)、var(--p-*) | beta-scss クラス、ハードコードされた色 |
| 新しいコード(すべて) | Tailwind CSS 4 クラス、var(--p-*) トークン | beta-scss クラス、インラインスタイル、!important |
beta-scss → 最新の代替表現
| beta-scss クラス | Tailwind / トークンでの置き換え |
|---|---|
text:teal | text-primary-500 または var(--p-primary-500) |
bg:grey-lightest | bg-surface-50 または var(--p-surface-50) |
bg:teal-dark | var(--hexa-chrome-bg-accent)(シェルのみ) |
bg:orange | var(--hexa-nav-bg)(シェルのみ) |
flex:X/12 | Tailwind グリッドまたは w-{fraction} |
p:1, m:1, pt:1 | Tailwind の p-4、m-4、pt-4 |
text:bold | font-bold |
text:center | text-center |
border | border |
rounded:1/2 | rounded-md または var(--p-content-border-radius) |
w:full | w-full |
例外ケース
ファイルが見つからない場合
glob/検索で一致するファイルが見つからない場合:
- ユーザーに伝えます:"No files found matching '[input]'. Try a URL, a .vue component name, or a route path."
- 停止します
開発サーバーが起動していない場合
- ビジュアル検査を完全にスキップします
- コードのみの分析と自動修正を実行します
- レポートに記載します:"Visual inspection skipped — no dev server detected on ports 5173, 5174, 3000, 8080"
認証に失敗した場合
apvhn/apvhnでのログインに失敗した場合、ビジュアル検査をスキップします- レポートに記載します:"Visual inspection skipped — authentication failed"
- コードのみの分析を続行します
コンポーネントツリーが大きい場合(20 ファイル以上)
- すべてのファイルを処理します。スキップや抜き取りはしません
- 読みやすいように、ファイルごとにレポートを整理します
- ツリーが 10 ファイルを超える場合は、並列サブエージェントを使用します(5 ファイルごとに 1 つのサブエージェント)
複数の MF ファイルが混在する場合
コンポーネントツリーが複数のマイクロフロントエンドにまたがる場合(例:共有パッケージのインポート):
- すべてのファイルに同じ単一の基準を適用します
- 各ファイルが属する MF をレポートに記載します
ファイルがすでに準拠している場合
ファイルに違反が 1 つもない場合:
- ファイル一覧に "0 violations" と記載して含めます
- 編集しません
重要な注意事項
- このスキルはファイルを変更します。 違反を修正するため、
.vueファイルを直接編集します。変更はコミットされません。 - 開発者が差分を確認します。 スキルの実行後、開発者は
git diffを実行してすべての変更を確認してください。 - i18n キー: ハードコードされたテキストを抽出する際は、コンポーネント名とコンテキストに合った説明的なドット記法のキーを使用してください(例:
patientDashboard.title、patientHeader.saveButton)。 - PrimeVue のドキュメント: コンポーネントの API の詳細については、
https://primevue.org/<component>.mdを取得してください。 - 再帰的な解決を停止する対象:
primevue/*、vue、vue-router、pinia、@vueuse/*、node_modules、@hexagone/shared(共有パッケージはライブラリ境界として扱います)。 - シェルコンポーネント(Header、Sidebar、Navigation、Breadcrumbs)では
--hexa-*トークンを使用できます。これらは違反として報告しないでください。