agent-html について
agent-html は、レポートやダッシュボード、レビュー画面を作る AI エージェント向けの、単体 HTML のデザインシステムとコンポーネント仕様です。テンプレート、チャートや操作の規則、納品前の検証を定め、外部依存を避ける設計です。
主な機能
- 01内容に応じた HTML と Markdown の選択
- 027 種類のページレイアウトテンプレート
- 03ネイティブ SVG チャートと操作の規則
- 04外部依存のない単一ファイル生成
- 05検証スクリプトによる成果物チェック
活用シーン
- 01データダッシュボードやレポートの作成
- 02ログまたはコードレビュー画面の構築
- 03並列比較ページの作成
- 04絞り込みと結果エクスポートが可能な画面の作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ qingyuna/ agent-html --skill agent-htmlインストール後、Claude Code で/agent-htmlを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/templates/en/compare.htmldashboard.htmlinspector.htmlkanban.htmlreport.htmlreview.htmltimeline.htmlassets/templates/zh/compare.htmldashboard.htmlinspector.htmlkanban.htmlreport.htmlreview.htmltimeline.htmlevals/evals.jsonREADME.mdreferences/components.mdfailures.mdscripts/smoke.mjsvalidate.mjs詳細
エージェント向け HTML デザインシステムとコンポーネント化規範
この規範では、AI エージェントが高い情報密度、工業製品のような質感、外部依存ゼロ、ダブルクリックですぐに開ける単一ファイルの HTML を生成する方法を説明します。
ゼロ、価値判断の基準:HTML を使うとき、使わないとき (Judgment Rules)
黄金律:Markdown は事実の情報源(Source of Truth)、HTML は人間が判断・レビューするための表面(Human Review Surface)です。
すべての出力を HTML にする必要はありません。作業を始める前に、AI エージェントはまず価値を判断しなければなりません。
1. HTML を優先して使う場面(次のいずれかに当てはまる場合):
- 空間性と多次元性 (Spatial):ワイド画面のデータダッシュボード、左右二列のログレビューアー、指標統計グリッド、高密度のステータスダッシュボード。
- 並列と比較 (Parallel / A-B):ベンチマーク vs チャレンジャー、バージョン差分、モデル評価、案のトレードオフを比較するマトリックス。
- インタラクティブ性と即時フィルター (Interactive / Filterable):数十件の記録をミリ秒単位で検索する必要がある、多数のタブを切り替える、アコーディオンを開閉する。
- 人間による正式な判断・アーカイブ用 (Human Review Surface):正式なアーキテクチャレビュー、面接採用レポート、技術振り返りのホワイトペーパー、リリースログ。
2. HTML を使わない場面(ターミナルの Markdown で十分です):
- 直線的な内容:通常の質疑応答、短い説明、単一のコードブロックの説明(200 字未満)。
- 純粋なターミナルコマンド/スクリプト:ユーザーがすぐにターミナルへコピーして実行する必要があるシェルコマンド。
- 空間構造のない情報:表も比較も次元もない、時系列に並べただけのテキスト。無理に HTML を出力すると、ユーザーのターミナルでの作業の流れを中断し、トークンを無駄にします。
3. HTML を使うと決めたら、次に粒度を決める (Output Granularity)
これは二つ目の問いであり、一つ目と同じくらい重要です。粒度を誤ると、ユーザーは期待を大きく上回る、または下回る成果物を受け取ることになります。
| 粒度 | 成果物 | 使う場面 |
|---|---|---|
| 断片 | 単一のコンポーネントカード/図/表 | 単一の結論や比較で、ユーザーが一目で確認したい場合 |
| エビデンスページ | 1 ページ:KPI 概要 + 図表 + 主要な詳細表 | 独立した結論が 2~3 個あり、証拠を提示する必要はあるものの、完全なストーリーは不要な場合 |
| ページ全体のテンプレート | 7 種類の汎用テンプレートのいずれか(「汎用レイアウトテンプレート」の節を参照) | レポート、振り返り、レビュー、ホワイトペーパーなど、完全なストーリーをまとめて提供する場合 |
デフォルトの粒度は「エビデンスページ」であり、「ページ全体のテンプレート」ではありません。 ユーザーが「このデータを分析して」「このダッシュボードを作って」と言っていても、レポート/ホワイトペーパー/年次報告書/振り返り/レビューとは言っていない場合:
- まずエビデンスページ(KPI + 最も有力な図を 1~2 点 + 主要な詳細)を提供し、返信で「完全なレポートが必要であれば、さらに展開できます」と一言伝える必要があります。
- 「データが豊富」「結論が多い」「ユーザーが分析と言った」という理由だけで、独断でページ全体のテンプレートに格上げしてはいけません。
- 反対に、ユーザーが明確に「レポート/ホワイトペーパー」を求めている場合、図を 1 点だけ提供して済ませてはいけません。
判断に迷ったら、より細かい粒度を選んでください。カードを 1 枚多く提供すれば、ユーザーは自分で「さらに展開して」と言えます。6 章構成のレポートを丸ごと渡すと、ユーザーは情報に圧倒されたと感じるだけです。
一、アンチパターン回避リスト (Anti-Patterns to Avoid)
HTML を生成する際は、次によくある AI のアンチパターンを絶対に避けてください。エンジニアリングと成果物の提供に関するもの(1~10。多くは scripts/validate.mjs で機械的に判定可能)と、データと意味に関するもの(11~17。多くは人の目による確認が必要)の 2 グループに分かれます。
1. エンジニアリングと成果物の提供に関するもの(1~10)
- HTML の外套を着せた普通の Markdown (Markdown in an HTML Trenchcoat):段落を何段も
<p>と<h1>で囲むだけで、カード、グリッド、ステータスバッジ、コールアウトをまったく活用していない。 - 外部 CDN/リモートフォントの持ち込み:Tailwind CDN、Google Fonts、CDN スクリプトを導入する。オフライン環境や社内ネットワークのサーバールームでは、画面が真っ白になって動作しなくなります。
- 操作の行き止まり (Dead-end UI / No Copy-back):ユーザーがページ上でフィルター、チェック、手動レビューを行っても、「結果をコピー」や「Markdown にエクスポート」ボタンがなく、操作結果をターミナルに戻してエージェントに渡せない。
- 高さの固定によるコンテンツの切り捨て (Fixed-height Truncation):
height: 400px; overflow: hidden;を設定し、システムやフォントサイズの違いによって内容がそのまま切れてしまう。 - ダークモードに対応しているかのように見せかける:一部の要素に
#ffffffや#000000をハードコードし、ダークモードで文字や背景が溶け込んで見えなくなる。 - モバイル/小画面向けのレスポンシブ対応不足:
<meta name="viewport">を追加していない、または@mediaのブレークポイントがないため、分割表示の小さなウィンドウで横スクロールバーが大量に発生する。 - 空状態への対応不足 (Empty State):検索結果がないとき、表やリストが何も表示されず、「一致する記録はありません」という案内もない。
- 印刷スタイルの欠如 (@media print):レポートページで
@media printのスタイルを最適化しておらず、PDF にエクスポートするとボタンがあちこちに表示される。 - グラフに重いサードパーティライブラリを導入する:単純な折れ線グラフを描くために Chart.js/ECharts を導入する(ネットワークが切断されると画面が真っ白になるリスクがあります)。必ず純粋なネイティブのベクター SVG を使ってください。
- 重要なメタデータとデータ精度の喪失:レイアウトを美しくすることにこだわりすぎて、重要なエラーコード、タイムスタンプ、元の ID、トレースを失い、エンジニアリング上の検証価値がなくなる。
2. データと意味に関するもの(11~17)
このグループは**「ページを壊す」のではなく「グラフを誤って描く」ものです。ページでエラーが起きることも、画面が真っ白になることもなく、バリデーターでも検出できません。しかし、読み手に誤った結論を導かせます**。気づきにくいため、技術的なバグより危険です。
- 面積/半径のエンコーディングで平方根を取らない:値を半径や点の大きさで表す場合、必ず
Math.sqrt(v)を使ってください。値をそのまま半径にすると、面積が値の二乗に比例して増加します。2 倍の差が 4 倍に描かれ、差を系統的に誇張します。 - 棒グラフの軸を切る:棒グラフの約束は長さ ∝ 値です。Y 軸を切るのは約束を破ることになります。極端な値がある場合に正しく対処する方法は 3 つだけです。① 極端な値をそのまま突出させる(最も誠実)② メインチャート + 拡大鏡の小さな図 ③ 棒を切って軸は切らない(描ききれないことを明記する)。
- 集計値を元の記録に見せかける:「37%」を 37 個の点で表すことはできますが、副題または注記に
1 点 = 1 パーセントポイントと明記する必要があります。密度を出すために、存在しない個別の記録を捏造してはいけません。 - 端数処理の説明不足:割合を丸めた結果、合計が 100 に満たない場合(例:49+27+14+5+3 = 98)は、注記に「残りの 2% は四捨五入によって失われています」と明記してください。偽のデータを足して 100 に合わせてはいけません。
- 色にデータ上の意味がない:「5 色をすべての要素に均等に振り分ける」ことは禁止です。色は実際の次元と結びつけなければなりません。順序尺度には数値の段階、カテゴリにはカテゴリ色、強調色は唯一の主役だけに使い、注記で色が何を表すかを明記してください。色を取り除いても、グラフの構造が読み取れる必要があります。
- 不確定なデモデータ:デモ/プレースホルダーデータでは
Math.random()を使わず、決定論的な疑似乱数を使ってください。2 回更新しても見た目が同じでなければなりません。そうでないと、スクリーンショット、画面録画、回帰比較がすべて役に立たなくなります。 - 実際の記録がない要素へのインタラクション追加:純粋な装飾要素にホバーやクリックを追加するのはユーザーを欺く行為です。インタラクションを追加する前に、「この要素の背後に実際の記録はあるか?」と問いかけてください。詳しい判定手順は「インタラクション」節の3 つの問いを参照してください。
📕 失敗の記録:上記アンチパターンの原因、実例、再確認方法は
references/failures.md(12 項目)を参照してください。新しいコンポーネントを書く前に、まず一読してください。規範は何をすべきかを教え、失敗の記録は同じ過ちを繰り返さないために役立ちます。この文書の末尾には索引表があり、どの教訓がすでに機械的な制約になっていて、どれがまだ人の確認に頼っているのかを正直に記しています。
二、なぜこのように設計するのか? (Design Principles & The "Why")
-
純粋な単一ファイルと外部依存ゼロをなぜ徹底するのか(Zero-Dependency Standalone)?
- 可視化レポートやユースケースレビュー用ツールの多くは、社内ネットワークのサーバールーム、パブリックインターネットに接続できない隔離環境(Air-gapped)、またはローカルのオフラインアーカイブで開かれるためです。
- Tailwind CDN (
cdn.tailwindcss.com) やサードパーティのフォントライブラリを導入すると、ネットワークが不安定な環境では画面が真っ白になる(FOUC)ほか、CDN ノードの停止による障害や、企業の CSP ポリシーによるブロックが発生します。そのため、精選した CSS 変数と最小限のスクリプトを直接埋め込む必要があります。
-
なぜ shadcn/ui の Zinc/Slate ニュートラルカラー体系を厳密に採用するのか?
- LLM は自由に生成させると、「AI らしい美的感覚の逸脱」が起きやすく、大きすぎる角丸、目に刺さる広範囲なグラデーション、意味のない余白の多用が生じます。
- shadcn の核心は、**冷たいグレーのニュートラルな背景、精密な 1px の繊細な淡色ボーダー、高い情報密度、意味を持つステータスドット(Green/Amber/Red)**です。このレイアウトなら、どんなデータレポートも、経験豊富なフロントエンドエンジニアが数日かけて丁寧に調整したような、プロフェッショナルなエンタープライズ製品に見えます。
-
なぜネイティブのダークモード(Light / Dark Theme)が必須なのか?
- エンジニアや運用担当者の多くは、ダークモードの IDE/ターミナル環境で作業しています。CSS 変数を使ってネイティブにマッピングすれば、ネイティブの JS を 5 行使うだけで滑らかに切り替えられます。ビルドコストはゼロでありながら、使い勝手を大幅に向上できます。
三、7 種汎用レイアウトテンプレートと段階的開示(Progressive Disclosure)
ページ全体をゼロから手書きしないでください。要件を受け取ったら、まず以下の7種類の汎用レイアウトテンプレートから、最も近い骨組みを選びます。ユーザーの入力言語に合わせて選べるよう、英語と中国語のテンプレート体系を用意しています。
- 英語のケース:
assets/templates/en/<name>.htmlを参照します - 中国語のケース:
assets/templates/zh/<name>.htmlを参照します
🗂 このリポジトリのアセットは3層に分かれています。混同しないでください。
層 場所 内容 使い方 骨組み(テンプレート) `assets/templates/zh en/*.html` ページ全体のレイアウトの正式版 パーツ(コンポーネント辞書) references/components.mdボタン/カード/グラフなどのスニペットの正式版 必要に応じて個々のスニペットを使います 完成品(サンプル) examples/(リポジトリ内のみ)実データで全工程を経て、すべてのゲートを通過した成果物 納品物のイメージがつかめない場合は、まずこちらを確認します ユーザーに納品するのは、常に単一ファイルの完成品であり、テンプレートまたはコンポーネントを組み合わせて作成します。 各アセットの正式版は1つだけです。 同じコードを2か所に保存してはいけません。手作業で複製した2つのファイルは必ず乖離します(
references/failures.mdF-014を参照)。重複を見つけた場合は一方を残し、もう一方は参照に置き換えます。examples/README.mdには、各サンプルがどのような忘れやすいルールを示しているかが記録されています。そこには、ゲートでは検出できず、人の目でしか気づけないグラフの目盛りの誤り(F-015)も含まれています。📌 このファイル内の相対パスはすべて、このSkillのルートディレクトリ(つまり
SKILL.mdがあるディレクトリ)を基準とします。現在の作業ディレクトリを基準とするものではありません。~/.agents/skills/agent-htmlにインストールした場合、scripts/validate.mjsは~/.agents/skills/agent-html/scripts/validate.mjsを指します。
| レイアウトパターン | 読者の所要時間 | 情報密度 | 主なインタラクション | 中国語テンプレートのパス | 英語テンプレートのパス | 適した要件と主要な構造 |
|---|---|---|---|---|---|---|
| Report レポート (Document / Report) | 30s+ | 中 | フローティング目次 ScrollSpy、折りたたみ式アコーディオン | assets/templates/zh/report.html | assets/templates/en/report.html | 技術選定、アーキテクチャレビュー、障害の振り返り、面接レポート、要件説明、リリースノート。 構造:幅広のレスポンシブコンテナ(デフォルトは1200px~1280px。幅広画面では最大96%まで拡張し、テーブルが押しつぶされるのを防ぎます)、フローティング目次(Sticky TOC with ScrollSpy)、要点を示すCallout、KPI概要バー、複数セクションの <details>折りたたみ式アコーディオン、Markdownへのワンクリックコピー。 |
| Dashboard ダッシュボード (Dashboard & Data Grid) | <10s | 高 | リアルタイムの二重フィルター、テーブルのコピー | assets/templates/zh/dashboard.html | assets/templates/en/dashboard.html | リソース監視、利用状況ダッシュボード、勤怠/代休管理、注文/タスクフロー管理。 構造:幅広画面向けのグリッド、上部操作バー、レスポンシブな4列のKPI統計カード、ネイティブSVGの折れ線グラフと棒グラフ、リアルタイムの二重フィルターテーブル、テーブル(MD)のワンクリックコピー。 |
| Inspector インスペクターワークベンチ (Master-Detail Workbench) | 1項目ずつ読む | 高 | Master-Detail連動、手動判定 | assets/templates/zh/inspector.html | assets/templates/en/inspector.html | ログ/Traceのレビュー、プロンプトデバッガー、JSONLエディター、構成管理。 構造:ビューポート全体を使用(100vh)、左側で項目リストをフィルタリングし、右側で選択項目の詳細を動的に連動表示、手動レビューの判定バー(Pass/Fix/Reject)、レビュー結果をコピーしてAgentに返信。 |
| Compare 比較 (Side-by-Side Comparison) | ~30s | 中 | 並列比較、Delta判定 | assets/templates/zh/compare.html | assets/templates/en/compare.html | モデルのA/Bテスト、プロンプトの改訂前後の比較、アーキテクチャバージョンのdiff、製品プラン/機能マトリックス。 構造:左右に並ぶ2列のカード(基準 vs 挑戦者)、主要な判定を示すCallout、定量的な差分比較テーブル(Deltaの勝敗判定ラベル)、Markdownへのワンクリックエクスポート。 |
| Timeline タイムライン (Timeline & Postmortem) | 30s+ | 中 | 診断ログの折りたたみ | assets/templates/zh/timeline.html | assets/templates/en/timeline.html | リリースロードマップ(Roadmap)、変更履歴(Changelog)、インシデントの振り返り(Postmortem)。 構造:左側に縦方向の単線タイムライン、状態を示す小さなノード、正確なタイムスタンプと担当者Tag、展開可能な診断ログ、タイムラインをMarkdownとしてワンクリックコピー。 |
| Kanban カンバンボード (Triage & Agile Kanban) | <10s | 中 | ネイティブHTML5のドラッグ&ドロップによる並べ替え | assets/templates/zh/kanban.html | assets/templates/en/kanban.html | バグの分類、要件の優先順位付け、タスクの状態遷移。 構造:4列のアジャイルカンバン(Backlog、In Progress、Blocked、Done)、依存関係ゼロのネイティブHTML5ドラッグ&ドロップによる並べ替え、分類結果をコピーしてAgentに返信するワンクリックのフィードバックループ。 |
| Review コードレビュー (Diff Review) | 1項目ずつ読む | 高 | 行単位の指摘、ファイルごとの判定 | assets/templates/zh/review.html | assets/templates/en/review.html | PR/ブランチのコードレビュー、パッチレビュー、リファクタリング前後の差分説明。 構造: git diffを<script type="text/plain" id="diffSource">にそのまま貼り付けると、統一diffとして自動解析されます。指摘事項は「新バージョンの行番号」を基準にアンカーされ、行内コメント(blocker / major / minor + 修正案)として表示されます。各ファイルには個別の単一選択判定(承認/コメント/修正依頼)があり、ファイルツリーのフィルターと空状態表示も備えています。Tabsでdiffと指摘事項の一覧を切り替え、レビュー結果をコピーしてAgentに返信できます。 |
「読者の所要時間」と「情報密度」を基準に選び、業界用語だけで選ばないでください。 テンプレート名にある「レポート」「カンバンボード」「振り返り」はレイアウトの性格を表すものであり、利用シーンを限定するものではありません。「タイムライン」は個人の生活データにも、「比較」は2つの案のトレードオフにも使えます。選ぶ際に確認するのは、読者が何秒かけて読むか、情報がどれほど密集しているか、特定のインタラクションが必要かどうかです。
⚠️ 中国語と英語のテンプレートは、構造を一致させる必要があります。 zhとenは同じ骨組みの2つの言語版であり、別々に管理するテンプレートではありません。一方を変更したら、もう一方も必ず同期してください。
scripts/validate.mjsの[ZH_EN_PARITY]は、「中国語にはあるが英語にはない<nav>/<aside>/<details>」をブロッキングエラーとして扱います。
💡 コンポーネント辞書の参照:ボタンのバリエーション、ピル型バッジ、32個のベクターアイコン、ネイティブの純粋なSVGグラフ、Tabs、フォームコントロール、インタラクションスクリプトの完全なコードは、すべて
references/components.mdにあります。コンポーネントコードの正式版はここだけです。このファイルでは、コンポーネントコードを重複して記載しません。
四、Micro-CSSコア基盤(Micro-CSS Base)
HTMLを生成するときは、以下の約75行のCSS基盤を必ず<head><style>に含めてください。これは、すべてのコンポーネントの質感を統一するための基礎です。
:root {
--bg: #fafafa;
--card: #ffffff;
--card-fg: #09090b;
--popover: #ffffff;
--popover-fg: #09090b;
--primary: #18181b;
--primary-fg: #fafafa;
--primary-hover: #27272a;
--secondary: #f4f4f5;
--secondary-fg: #18181b;
--secondary-hover: #e4e4e7;
--accent: #f4f4f5;
--accent-fg: #18181b;
--destructive: #dc2626;
--destructive-fg: #fafafa;
--muted: #f4f4f5;
--muted-fg: #71717a;
--border: #e4e4e7;
--input: #e4e4e7;
--ring: #18181b;
--radius: 8px;
--radius-sm: 6px;
--radius-lg: 12px;
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
--shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
--ok: #16a34a; --ok-bg: #f0fdf4; --ok-border: #bbf7d0;
--warn: #d97706; --warn-bg: #fffbeb; --warn-border: #fde68a;
--err: #dc2626; --err-bg: #fef2f2; --err-border: #fecaca;
--info: #2563eb; --info-bg: #eff6ff; --info-border: #bfdbfe;
/* 图表专用色(Tremor 风格)。语义固定,不可当作装饰色随机分配:
每个色相各承担一种数据含义,见「轻量原生图表规范」一节。 */
--chart-indigo: #6366f1; /* 主指标时序走势 */
--chart-emerald: #10b981; /* 正常 / 健康 / 增长 / 放行 */
--chart-amber: #f59e0b; /* 警戒 / 抖动 / 温和上升 */
--chart-rose: #f43f5e; /* 异常瓶颈 / 错误峰值 / 降级 */
--chart-violet: #8b5cf6; /* P95 / P99 峰值高亮 */
--chart-cyan: #06b6d4; /* 辅助对比时序 / 出向流量 */
--chart-slate: #64748b; /* 低优对比柱 / 中性刻度 */
}
[data-theme="dark"] {
--bg: #09090b;
--card: #121215;
--card-fg: #fafafa;
--popover: #121215;
--popover-fg: #fafafa;
--primary: #fafafa;
--primary-fg: #18181b;
--primary-hover: #e4e4e7;
--secondary: #27272a;
--secondary-fg: #fafafa;
--secondary-hover: #3f3f46;
--accent: #27272a;
--accent-fg: #fafafa;
--destructive: #ef4444;
--destructive-fg: #fafafa;
--muted: #18181b;
--muted-fg: #a1a1aa;
--border: #27272a;
--input: #27272a;
--ring: #d4d4d8;
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.5);
--shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.5);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.5);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5);
--ok: #4ade80; --ok-bg: #052e1680; --ok-border: #166534;
--warn: #fbbf24; --warn-bg: #451a0380; --warn-border: #854d0e;
--err: #f87171; --err-bg: #450a0a80; --err-border: #991b1b;
--info: #60a5fa; --info-bg: #17255480; --info-border: #1e40af;
--chart-indigo: #818cf8;
--chart-emerald: #34d399;
--chart-amber: #fbbf24;
--chart-rose: #fb7185;
--chart-violet: #a78bfa;
--chart-cyan: #22d3ee;
--chart-slate: #94a3b8;
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background-color: var(--bg);
color: var(--card-fg);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
}
.card {
background: var(--card);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow-sm);
overflow: hidden;
}
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
font-size: 13px;
font-weight: 500;
height: 34px;
padding: 0 12px;
border-radius: var(--radius-sm);
border: 1px solid var(--border);
background: var(--card);
color: var(--card-fg);
cursor: pointer;
text-decoration: none;
transition: all 0.15s ease;
}
.btn:hover { background: var(--secondary); }
.btn-primary { background: var(--primary); color: var(--primary-fg); border-color: var(--primary); }
.btn-primary:hover { background: var(--primary-hover); opacity: 0.95; }
.btn-destructive { background: var(--err); color: #fff; border-color: var(--err); }
.btn-sm { height: 28px; padding: 0 8px; font-size: 12px; }
.badge {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 12px;
font-weight: 500;
height: 20px;
padding: 0 7px;
border-radius: 9999px;
border: 1px solid var(--border);
background: var(--secondary);
color: var(--secondary-fg);
}
.badge-dot { width: 5px; height: 5px; border-radius: 9999px; background: currentColor; }
.badge-success { background: var(--ok-bg); color: var(--ok); border-color: var(--ok-border); }
.badge-warning { background: var(--warn-bg); color: var(--warn); border-color: var(--warn-border); }
.badge-danger { background: var(--err-bg); color: var(--err); border-color: var(--err-border); }
.badge-info { background: var(--info-bg); color: var(--info); border-color: var(--info-border); }
五、コンポーネント索引とチャートの契約 (Components & Chart Contract)
コンポーネントコードの正本は references/components.md のみです。必要に応じて該当する節を読み、記憶に頼って書かないでください。 次の表で参照先を確認してください。
| 必要なもの | components.md の参照先 |
|---|---|
| ボタン、ステータスバッジ | §1 ボタン · §2 バッジ |
| KPI 指標カード、ミニトレンド | §3 指標カード |
| 主要な結論/リスク提示バー | §4 Callout |
| 検索可能なテーブル(空の状態を含む) | §5 インタラクティブデータテーブル |
| トレンド/分布/割合/比較/ランキング/水位/構成/クロス分布 | §6 チャート A–H(面積折れ線、棒グラフ、ドーナツ、二重線、ランキング、ゲージ、積み上げ棒グラフ、ヒートマップ) |
| チャートのホバー値 | §6-I ホバーツールチップ(全ページで共通のものを一つ使い、チャート要素に data-tip を追加) |
| アイコン | §7(32 個、stroke="currentColor" でダークモードに自動対応) |
| ダイアログ、折りたたみ、タブ | §8 Dialog / Details / Tabs |
| 人が入力して Agent に返すもの | §9 フォームコントロール(入力欄、ドロップダウン、チェックボックス、スイッチ、セグメント選択、検証エラー状態) |
| テーマ切り替え、テーブルのフィルタリング、Markdown のコピー、裁定の返却、ScrollSpy、フッターのクレジット印、ドラッグ&ドロップ | §10 インタラクションスクリプト |
軽量なネイティブチャートの規約 (Zero-CDN Pure SVG Charts)
データダッシュボードやレポートを生成する際は、Chart.js / ECharts / Recharts などの外部 CDN ライブラリを絶対に導入しないでください。 チャートはすべて、純粋なネイティブのベクター SVG で実装します。
- ネットワーク依存ゼロ:オフラインや社内ネットワークの機器でも 100% すぐに表示でき、CDN の停止や画面が真っ白になるリスクがありません。
- ダークモードに自動対応:テーマ変数(「ミニマル CSS コア基盤」で定義されている
--chart-*チャート用セマンティックカラーを含む)を直接使用するため、再描画を監視する追加の JS は不要です。 - ビューポートに自動対応:
viewBoxとstyle="width: 100%; height: auto;"を統一して使用することで、Retina ディスプレイでも印刷でも忠実に表示できます。
📖 8 種類の完全なコードは
references/components.md§6 にあります(面積折れ線/縦棒グラフ/複合ドーナツ/二重線時系列/横型ランキング/半円ゲージ/積み上げ棒グラフ/ヒートマップ)。ホバーツールチップは §6-I を参照してください。 コードはあちらに、契約はここにあります。コードを変更する前に、この節を読んでください。
チャートの必須 4 要素(1 つでも欠けたら差し戻し)
各チャートには、次の 4 つの要素を順番どおりにすべて含めてください。
- 結論を示すタイトル —— チャートの種類ではなく、判断を書きます。
ピークは 16:00 のバッチ処理時間帯は可、24 時間のスループット推移は不可です。 - 単位の契約を示すサブタイトル ——
1 X = 1 Yの形式で、視覚上の単位が実際の数量のいくつに相当するかを明示し、さらに·で凡例と期間を追加します。これはデータの誠実さの核心であり、装飾ではありません。1 マス = 1 パーセントポイント · 中空 = 週末 · 直近 30 日1 tick = 1 日 · 5 日ごとに 1 目盛り- 集計値の内訳を示す場合は、必ず集計方法を明記します(アンチパターン 13 を参照)。丸めた合計が 100 に満たない場合も、その旨を明示します(アンチパターン 14 を参照)。
- チャート本体 —— データレイヤーの誠実さを保ちます。密度は装飾ではなく、単位によって表します。
- 最下部のすべて大文字のコード説明行 ——
font-size: 10px; letter-spacing: .08em; color: var(--muted-fg)とし、色と目盛りが何を表しているかを説明します。オレンジ = 今回の主役(今回最も時間がかかった処理)グレーの濃淡 = 数値の大きさ、濃いほど大きい
控えめな装飾要素(チャートを寂しく見せず、shadcn の表現を保つ)
データと基準線だけの小さなチャートはどうしても寂しくなります。以下の 4 つを追加してください。これらはデータを持たず、読み取りの手がかりだけを提供します。
| 装飾要素 | 方法 |
|---|---|
| 基準線を強調 | 下部に 1px の実線(var(--border))を引き、上部の stroke-dasharray="3 3" の参照用破線と区別します |
| リム目盛り | 基準線に沿って 5 または 10 単位ごとに目盛りを置き、数字を一つずつ見なくても読み取れるようにします |
| 参照ガイド | Y 軸の整数値に合わせて、水平の破線を 2~3 本引きます |
| ピークの引き出し線 | ピークの吹き出しからデータポイントまで 1px の折れ線を引き、吹き出しが宙に浮かないようにします |
⚠️ 編集的なナラティブ表現(Lupi 系)の装飾をそのまま持ち込まないでください:髪の毛のような細線で面積を表現する、横線で棒を構成する、カードの枠線や影をなくす——それは別のデザイン言語の特徴であり、取り入れると両方のアイデンティティが損なわれます。 agent-html のチャート表現は shadcn の企業向けダッシュボードです。白いカード +
1pxの枠線 + セマンティックなステータスカラー。この表現を保ってください。
六、インタラクション:3 つの問いを先に考え、その後でスクリプトを選ぶ (Interaction)
「インタラクションを追加すれば、より高度になる」と決めつけないでください。 内容のない要素に動作を与えるのは欺瞞です。一目で読める内容に動作を加えるのはノイズです。インタラクションを追加する前に、次の 3 つの問いに順番に答えてください。
- この要素の背後に実際の記録がありますか? ない(区切り線、装飾的な図形、背景のアクセントなど、純粋なテクスチャ装飾)→ インタラクションの追加は禁止です。内容のない要素にホバーやクリックを加えると、表示できる何かがあると誤解させます。
- 記録がある場合、クリックしなくても読み取れますか? 読み取れる(要素が約 50 個未満で、両端または重要な箇所にラベルがある)→ 静的表示で十分です。ホバーはあれば便利なだけで、必須ではありません。
- 要素が約 50 個を超えるか、複数の経路がありますか? → 読者が雰囲気しか見えず、個別に確認できないため、ホバー/ピン留めを必ず用意してください。
3 つの問いに答えてから、次のどのスクリプトを使うかを決めます。逆に言えば、3 つの問いの答えが「インタラクションは不要」なら、「テンプレートにこの機能があるから」と無理に追加しないでください。
スクリプトのコードはすべて references/components.md §10 にあります(テーマ切り替え、テーブルのフィルタリング、Markdown としてコピー、裁定の返却、ScrollSpy、フッターのクレジット印、ダッシュボードのドラッグ&ドロップ)。確認不要の基本ルールが 3 つあります。
- 各ページの右上にテーマ切り替えボタンを配置し、暗色テーマのユーザーに明色の画面が一瞬表示されないよう、
<head>内であらかじめdata-themeを設定します。 - ページにフィルター、チェック、裁定、フォーム入力のいずれかがある場合は、必ず「結果をコピー」できる手段を用意します(アンチパターン 3)。
- 各成果物の下部に、Colophon フッターのクレジット印(生成日時、データソース、基準バージョン)を付けます。
七、成果物の自己検証と品質ゲート (Self-Verification Gate)
提出前に 2 つのことを行ってください。品質ゲートを実行できるなら実行します。実行できない場合は、チェックリストを一つずつ手作業で確認し、「品質ゲート未実行」であることを正直に伝えます。
1 · まず環境を確認する(Node があると決めつけない)
品質ゲートのスクリプトは Node で書かれています。Agent の実行環境には Node がない場合や、Chrome がない場合も多くあります——これはエラーではありませんが、まず環境を確認してから進め方を決める必要があります。実行できないからといって、成果物に問題がないと決めつけてはいけません。
command -v node >/dev/null 2>&1 && echo "有 node" || echo "无 node"
| 環境 | 進め方 |
|---|---|
node がある | 静的品質ゲートを実行します(下の第 2 節)。必須です。最も速く、確実な確認方法です |
node があり、Chrome/Chromium もある | さらにレンダリングのスモークテストを実行します(第 3 節)。任意ですが、強く推奨します |
node がない | スクリプトをスキップし、第 4 節の手動セルフチェックリストを実施します。提出時の説明には「この環境には Node がないため、品質ゲートは未実行です。手動チェックリストに従って一項目ずつ確認しました」と明記します |
node はあるが Chrome がない | スモークテストのみスキップします。スモークテストの終了コード 2 は環境が条件を満たしていないことを示し、成果物の欠陥ではありません。これを根拠に成果物を不合格と判定しないでください |
見栄より透明性を優先してください。「品質ゲート未実行」と正直に伝えるほうが、「検証済みです」と虚偽の報告をするよりはるかに有用です。後者では、ユーザーが未検証の成果物を意思決定に使うことになります。
2 · 静的ゲート(Node がある場合は必ず実行)
パスはこの Skill のルートディレクトリからの相対パスです(作業ディレクトリではありません)。
node <skill>/scripts/validate.mjs <generated_file.html> # 校验单个产物
node <skill>/scripts/validate.mjs --all # 校验技能全部产物
node <skill>/scripts/validate.mjs --all --json # 机器可读输出
このスクリプトはネットワーク通信ゼロ、Token 消費ゼロ、Node の組み込みモジュールのみで、19 個のルール+2 件のファイル間チェックを実行します。
ブロッキングルール 10 個(違反した場合は必ず修正が必要です):
[ZERO_CDN]外部 script / link /@importによる CDN 参照やリモートフォントが含まれていないか;[THEME_TOKENS]CSS 変数の基盤一式(--bg--card--primary--border)を宣言し、ダークモードをサポートしているか;[VIEWPORT]モバイルの小さな画面に対応するレスポンシブ viewport があるか;[TAG_HYGIENE]svg / details / dialog / table / nav / aside などの重要なタグが対称に閉じられているか;[DUP_ID]同じファイル内でidが一意か(そうでない場合、JS が取得する要素が不確定になります);[SCRIPT_SYNTAX]各インライン<script>がコンパイルできるか——「エラーが出ない」≠「実行できる」;[DARK_MODE_LEAK]token ブロックの外に#fff/#000/white/blackがハードコードされていないか(見せかけのダークモード);[WIDTH_HYGIENE]表を含む場合、overflow-xのスクロールコンテナーが用意されているか、メインコンテナーの幅がハードコードで狭くなっていないか;[DOC_FENCES]仕様ドキュメントの Markdown コードフェンスが対応しているか(閉じ忘れると後続の全文がコードブロックになり、Agent が仕様を読み違えます);[CSS_VAR_DEFINED]var(--x)で参照する変数が同じファイル内で定義されているか。単一ファイルで依存関係ゼロの場合、外部スタイルシートで補うことはできません。また、fallback のないvar()の失敗は全体の失敗であり、フォールバックにはなりません——strokeはnoneになり、色が違うのではなく図形そのものが消えます。
8 番目の一般的な修正方法:
.containerの基本幅にはmax-width: 1280px(またはwidth: 100%; max-width: 1380px)を使い、表の外側を<div class="table-wrap" style="overflow-x: auto; width: 100%;">で囲みます。メインコンテナーの幅を 800–860px にハードコードすることは厳禁です。
警告ルール 9 個(人による確認を推奨します):
[NO_RANDOM]デモ/グラフのデータにMath.random()を使用していないか(決定論的である必要があります);[CHART_TOKEN_ONLY]SVG のfill/strokeに色の値がハードコードされていないか(テーマに追従するよう CSS 変数を使う必要があります);[FIXED_HEIGHT]固定ピクセル高とoverflow:hiddenの併用で内容が切れていないか;[PRINT_STYLE]ドキュメント型のテンプレートに@media printが用意されているか;[EMPTY_STATE]フィルター/検索を実装している場合、空の状態も実装しているか;[AFFORDANCE]コピー/エクスポートの手段があるか(操作不能な行き止まりを防ぎます);[COLOPHON]フッターに出典を示すアーカイブ印が含まれているか;[DOC_SECTIONS]章番号が重複したり、飛んだりしていないか;[MIN_FONT]SVG 内の文字サイズが 9px 未満になっていないか(収まらない場合は hover で表示するように変更し、文字を縮小して無理に詰め込んではいけません)。
ファイル間チェック 2 件:
[ZH_EN_PARITY]:zh テンプレートにあり、en にない構造要素(nav / aside / details / table / dialog / section)はブロッキングと判定します。同じ機能のエクスポートボタンの id が中英版で異なる場合は警告と判定します。[DOC_TOKEN_COVERAGE]:仕様ドキュメント内の```htmlコード例が Micro-CSS 基盤にない CSS 変数を参照している場合、ブロッキングと判定します。このチェックは「ドキュメントどおりに作るとかえって壊れる」ことを防ぎます——基盤とサンプルは別々に手作業で複製したものであり、このチェックがないとそれぞれが乖離していきます(references/failures.mdF-014 を参照)。
3 · レンダリングスモークテスト(静的 lint ではカバーできない領域。Chrome がある場合は実行を推奨)
静的 lint で証明できるのは「コードにエラーがない」ことであり、「ページが実際に描画される」ことは証明できません。納品前にレンダリングスモークテストも実行してください:
node <skill>/scripts/smoke.mjs # 技能全部产物
node <skill>/scripts/smoke.mjs <file.html> # 单个产物
生成物を一時ディレクトリにコピーし(リポジトリ内のファイルは変更しません)、プローブスクリプトを注入してから headless Chrome で --dump-dom を使い、レンダリング後の DOM を出力し、実行時の事実を検証します:
- インラインスクリプトに実行時エラーがないか(構文が正しくても実行できるとは限りません。この点は静的 lint では決してテストできません);
SVGが実際に図形を描画しているか(コンテナーだけがあり、内容が空の「空の殻」になっていないか);#themeToggleのクリック前後で--bgが実際に変化するか(見せかけのダークモード);overflow:hiddenによって切り取られている内容がないか;- 狭いビューポートで横方向にはみ出していないか。
ローカル環境に Chrome/Chromium が必要です(CHROME_PATH で指定でき、一般的な macOS / Linux のパスに対応しています)。ブラウザーが見つからない場合は終了コード 2 でスキップし、言語上も環境の問題であって生成物の不具合ではないことを明示します。 node <skill>/scripts/smoke.mjs --selftest は不具合を注入し、プローブ自体が実際に失敗することを確認します。
4 · 免除の仕組み(ルールより先にホワイトリストを適用)
誤検知はゲートへの信頼を損ないます。そのため、コンテナーの token 定義ブロック(:root / [data-theme] / prefers-color-scheme)と @media print ブロック内の色のリテラルは常に許可され、免除は不要です。
本当に免除が必要な場合は、該当行の直前の行に次のように記述します:
/* @lint-allow: DARK_MODE_LEAK — 该按钮悬浮在恒为深色的代码块表面上,不随主题反转 */
.copy-btn:hover { background: #3f3f46; color: #fff; }
- 免除の適用範囲は「コメントの行+次の行」のみです。同じファイル内の別の箇所にある実際の違反を隠すことはありません(この制約は F-003 をきっかけに導入されました。初期実装ではファイル単位の免除だったため、ある箇所を許可すると別の箇所も隠れてしまいました);
- 理由を必ず明記してください(4 文字以上)。理由のない免除は機能しません(F-004);
- 典型的な免除対象:常に暗色のコードブロック/ターミナルの表面上にあるボタン(F-005)。本当のダークモードの不具合を隠すために使わないでください。
ホワイトリストをルールより先に適用する理由や、免除を一行のみに適用する理由については、
references/failures.mdF-002 / F-003 / F-004 を参照してください。
5 · ゲート自体の有効性(メンテナー向け)
リポジトリの開発時には、npm test(静的 lint +ルールのミューテーションテスト)と npm run test:smoke(レンダリングスモークテスト)を実行してください。ルールを変更した後は、必ずミューテーションテストを再実行してください——「何でも通る」バリデーターは、バリデーターがないのと同じです。
6 · 人によるセルフチェックリスト(Node がない場合、これが唯一の検証方法です)
バリデーターとスモークテストを合わせても、「図が正しく描画されているか」はテストできません。次の 6 項目は静的には判定できず、スクリプトがすべて成功しても問題がないとは限りません——Agent は納品前に「アンチパターン回避リスト」のデータと意味の各項目を照合し、必ずセルフチェックしてください:
- 棒グラフに断軸がないか?(Y 軸の切り詰めは信頼を損ないます。Y 軸の意味を理解する必要があります)
- 面積/半径のエンコーディングに平方根を適用しているか?(ある
rが数値と面積のどちらに対応しているかを把握する必要があります) - 色が実際のデータ次元と対応しており、脚注に何をエンコードしているか明記されているか?(意味の判断が必要です)
- カードのタイトルがグラフの種類ではなく結論を示しているか?(「Revenue by plan」はよいですが、「棒グラフ」は不適切です)
- グラフの種類とデータの形状が一致しているか?(意味の判断が必要です)
- デモデータが決定論的か?(2 回更新しても同じ見た目である必要があります)
また、静的に検出できるものの、コストが高く見落としやすい項目を 2 つ、納品前に念のため確認してください:
- 言語の統一性:中国語テンプレートと英語テンプレートが混在しておらず、1 回の納品には 1 つの言語のみを使っているか;
- 粒度が適切か:「価値判断基準」第 3 条に沿って判定されているか——「分析して」がページ全体のレポートになっていたり、「レポートを作成して」が 1 枚のグラフになっていたりしないか。
このチェックリストは補足説明ではなく、ゲートの適用範囲を示すものであり、Node がない場合の唯一の検証方法でもあります。 ゲートがすべて成功していても、「エンジニアリング上の問題がない」ことを示すだけで、「グラフに誤りがない」ことは証明しません——F-015 は、18 個のルール、14 個の生成物スモークテスト、28 個のミューテーションケースがすべて成功したにもかかわらず、グラフが誤って描画された事例です。