html-deck について
html-deckは、資料をHTMLプレゼンテーションにするスキルで、企画、デザイン、実装、検査、修正を扱います。決定的な検査と批評、ユーザーレビューを繰り返して仕上げ、単一HTMLへのバンドルや依頼に応じたPDF出力も行います。
主な機能
- 01目的を聞き取り構成を設計
- 02テーマを決めてHTMLスライドを実装
- 03はみ出し、密度、レイアウトを検査
- 04批評やフィードバックに基づく部分修正
- 05単一HTMLへのバンドルやPDF生成
活用シーン
- 01文書などの資料をプレゼンにまとめる
- 02文字のはみ出しやレイアウトの問題を修正
- 03レビューを重ねてデッキを改善
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ nogikun/ html-deck --skill html-deckインストール後、Claude Code で/html-deckを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/deck-critic.mddeck-fixer.mdslide-critic.mdassets/slide-template.htmlevals/evals.jsonreferences/figures.mdlayout-playbook.mdloop.mdquality-contract.mdreview.mdwhitespace-theory.mdtools/pyproject.tomltools/src/html_deck/__init__.pybundle_deck.pycheck_deck.pydrawio_svg.pyemit_pptx.mjsexport_pdf.pyexport_pptx.pyinit_deck.pyreview_anchor.pyreview_check.pyreview_deck_adapter.pyreview_server.pyreview_thread.pyreview_threads.pytools/src/html_deck/assets/gates.jsonreview.htmlshell.csstheme.css詳細
プロジェクトの README よりHTML Deck
材料を渡されたら、ゴールを1つ決めて、そこに届くまで直し続ける。 1回の生成で完成させようとしない。初期案は下書きで、価値は差し戻しループの側にある。
このスキルが引き受ける範囲は、企画・デザイン・実装・検査・修正の全部。 ユーザーに求めるのは最初のインタビュー1回と、最後の承認1回だけ。 途中で細かく確認を取ると、ユーザーが評価器の代わりをさせられることになる。
全体の流れ
材料を読む → インタビュー(1回・4問) → 情報量の予算を決める → 骨格生成 → デザイン → 全枚実装
↓
ユーザーへ提示 ← 終了判定 ← 批評(Sonnet) ← 決定的検査 ←┘
↓ └──────── 局所修正 ────────────┘
レビューモードで指摘 (#1 #2 … + 自然言語)
↓
局所修正 → 再検査 → resolved に記録 → ## accepted に積む
└────────── ユーザーが納得するまで ──────────┘
入口が途中のとき
このスキルは0から作る前提で書いてあるが、途中から呼ばれることが多い。 手順1から律儀に始めない。 該当する手順へ直接飛ぶ。
| 言われたこと | 行き先 |
|---|---|
| 「スライド作って」「この資料をスライドに」 | 手順0から (インタビューを飛ばさない) |
| 「デッキ見せて」「レビューさせて」「直したいところがある」 | 手順7。サーバと待機を起動して URL を渡す |
| 「指摘読んで」「送ったやつ直して」 | 手順8。未読のスレッドを処理する |
| 「3枚目のここを直して」(チャットで口頭) | 手順8の修正部分だけ。指摘 JSON は要らない |
| 「文字が小さい」「はみ出してる」 | 手順5の検査から |
デッキの場所を言われていないときは、deck.md と slides/ の両方があるディレクトリを探す。
1つなら黙ってそれを使う。複数あるときだけ聞く。
0. 材料を読む
手順0-a. 使えるスキルを調べる(最初にやる小さなタスク)
これは独立したタスク。材料を開く前に済ませ、結果を控えておく
(手順2 で deck.md の ## skills に書く)。ここを飛ばすと、環境に有用な
スキルがあっても最後まで気づかない。やるのはこの1回だけで、作り始めてから
探し直さない。
やること:
- 一覧を出す(下の2経路を両方)
- 下の用途表に当てはめる — 当たるものがあれば控える。無い用途は「なし」と控える
- デザイン系が0件だったときだけ、その旨をユーザーに1行伝える
一覧の見方は、ユーザーの環境によって違う。両方見る:
- 自分のコンテキストにある利用可能スキルの一覧 — 常にここが本体。プラグイン由来や ローカルのスキル (デザイン・図・データ可視化など) はここにしか出ない
ListSkills/SearchSkillsが使えるなら、それも引く。ただし環境によっては claude.ai 側のスキルしか返らないので、これだけを見て「無い」と判断しない
名前で決め打ちしない。 以下は「どういう用途のものを探すか」であって、 この名前のスキルがあるという意味ではない。該当するものが1つでもあれば積極的に使う。
| いつ | 探すもの (用途) | 例として過去にあった名前 |
|---|---|---|
| 手順3 | デザイン・UI・見た目の作り方。色/書体/余白の決め方を扱うもの | frontend-design design artifact-design |
| 手順4 | 図・ダイアグラムの描き方。SVG や作図の指針 | artifact-diagramming (vendor/draw-io は同梱) |
| 手順4 | グラフ・データ可視化。数字を載せる枚があるときだけ | dataviz |
| 手順4・8 | 日本語の文章。claim の言い切りが鈍い・訳文調になったとき | natural-japanese |
| 手順0 | 材料の読み取り。渡された形式を開くため | pptx docx xlsx pdf |
このタスクの成果物は deck.md の ## skills。 手順2 で骨格を作ったら、
そこに調べた結果を書く。書いてあるから、手順3・4 の自分も、批評サブエージェントも、
「何が使えるか」をもう一度探さずに済む。空のまま手順3 に入らない。
デザイン系が1つでもあれば、theme.css を書く前に必ず読む。 1つも無いと
確認できたときだけ、その旨を1行伝えてから references/quality-contract.md の
数値だけで進める (黙って飛ばさない)。
控えるのはこの表に当たるものと、材料・依頼から要ると分かるものだけ。関係ないものまで 開かない — 一覧を眺めるのはタダだが、中身を読むのは予算を食う。
書き出しには使わない。 pptx docx xlsx pdf は材料を読む口であって、
出口ではない。納品物は HTML と、html-deck-pdf が出す固定PDF。
材料を読む
渡されたファイル・URL・会話の内容を全部読む。この時点で次を自分の中で確定させる: 誰に向けた資料か / 見終わった人に何をしてほしいか / 一番言いたい1文は何か。 材料に書いていなければ、材料から一番もっともらしい答えを立てる。ここで ユーザーに丸投げして質問を並べない。答えを持って聞きに行く。
もう1つ、この段で拾っておく。材料の中の「図にできる関係」
(比較・順序・包含・数量の差) を書き出す。次のインタビューの選択肢も、
そのあとのストーリーボードの visual 列も、ここが空だと埋まらない。
1. 目指す状態をインタビューする(唯一の必須確認)
ここが一番効く。 資料の出来は作り方より「何のために作るか」で決まる。
AskUserQuestion を1回呼び、そこに4問まとめて入れる。1問ずつ何度も聞くのは
中断が増えるだけで、インタビューが濃くなるわけではない。
聞くのはこの4つ。順番も変えない。
| # | 聞くこと | なぜ要るか |
|---|---|---|
| 1 | 見終わった人がどういう状態になっていてほしいか | 以降の全ての合否条件になる |
| 2 | どう見せる資料か — 話しながら / 置いて読ませる / 両方 | 1枚の情報量の予算が変わる。聞かずに作ると必ず外す |
| 3 | 相手は誰で、何を決められる人か | 前提の説明をどこから始めるかが決まる |
| 4 | 枚数と持ち時間 | 削る判断の根拠になる |
選択肢は材料から作った具体文にする。 一般語を並べた質問は、答えても何も決まらない。
- × 「情報を伝える」「理解を深める」「検討したい」
- ○ 「HTML-first を限定パイロットとして承認する判断ができる」 「7つの配信プロトコルから自分の用途に合うものを選べる」
呼ぶのは最大2回。2回目を呼ぶのは、材料が薄くて骨格が2通り以上に割れるときだけ (例: 事例中心で行くか、仕組みの説明で行くかで枚の並びが変わる)。それ以外は答えを持って進む。 確認を重ねると、ユーザーが評価器の代わりをさせられる。
場面から情報量の予算を決める
質問2の答えをそのまま数値にする。決めたらラウンド0で1度だけ <deck>/gates.json に反映し、
理由を deck.md の constraints に書く (途中で変えるのは評価ハック)。
| 場面 | 1枚の日本語 | 考え方 |
|---|---|---|
| 話しながら見せる | 300字 | 画面は話の裏付け。読ませると話が聞かれない |
| 置いて読ませる (配布・非同期) | 420〜520字 | 本文が主。ただし1枚1メッセージは崩さない |
| 両方 | 300字 + 話す内容は deck.md 側へ | 画面に全部載せない |
そもそもこの資料が要るか
材料を読んだ結果、1つの判断を伝えるだけで済むことがある。そのときはスライドを 作る前にそう言う。3行で足りる用件に15枚作るのは丁寧ではなく無駄。 「作らない」も答えとして出してよい。 ただし1往復で決め、ユーザーが作ると言えば作る。
合意した内容は deck.md の goal / situation / audience / constraints に
そのまま書く。以降は確認を挟まない。ストーリーボードを作ったら短く見せてから、
止められない限り着工する (承認を待たない)。ユーザーの手を止めないことが、
このスキルのインターフェースの要件。
2. 骨格を作る
uv run --project "<このスキルのディレクトリ>/tools" html-deck-init <出力先> --title "デッキ名"
<このスキルのディレクトリ> は、この SKILL.md が置かれているディレクトリ。
npx skills add nogikun/html-deck で入れたなら .claude/skills/html-deck/ など、
リポジトリから使うなら skills/html-deck/。以降のコマンドも全部ここを起点にする。
パスに空白が入ることがあるので、引用符で囲んで渡す。
出力先の既定は、材料と同じディレクトリの <slug>-deck/。
deck.md / theme.css / index.html(ビューア) / slides/ ができる。
できたらまず deck.md の ## skills を埋める — 手順0-a で調べた結果をここに移す。
これが済むまで次に進まない (手順3 で読むものがここで決まる)。
deck.md の goal / situation / audience / takeaway / storyboard を埋める。
storyboard は1行1枚で、claim(言い切りの見出し) と job(比較/因果/構造/数量/例示/宣言) と
visual(その枚を何の絵で見せるか) と 問い(入)→問い(出) を必ず書く。
claim が名詞句になっている行は、まだ主張になっていない。
storyboard の段階で情報量を割る
実装に入る前に、表を縦に読んで次を確かめる。ここで直すのは1行の書き換えで済むが、 実装後だと1枚まるごと作り直しになる。
visual列が「なし」の行が3つ以上続いていないか。 続いているならどれかを図にする (html-deck-checkがtext_only_streakとして落とす)。デッキ全体で図のある枚が4割以上visualが「箇条書き」の行が並んでいないか。箇条書きは形ではない。job が比較なら 比較の絵、因果なら順序の絵になる (references/layout-playbook.md)- 1行に claim が2つ入っていないか。1枚1メッセージ。 入っていたら2枚に割る
- 手順1で決めた1枚の字数を、
evidenceの量に掛けて総量を見る。総量が持ち時間を 超えるなら、枚を増やすのではなく節を落とす
余白の構図契約を先に決める
余白は要素ごとの気分で足さず、親の構図フレームが一度だけ予算化する。
実装前に各枚を M=80 / frame=composition / axis=row / children=[A, connector, B] / G=40 / align=center のように1行で決める。横方向は 内容幅の合計 + gapの合計 = フレームの内側幅 とし、矢印・線は内容列ではなく56〜80px程度の接続スロットにする。
比較・表・大きな構図は、指定がなければ中央配置。固定幅のフレームには margin-inline:auto を使い、left や transform で後から見た目だけをずらさない。親の gap と隣接子の外側 margin で同じ間隔を二重に作らない。詳細な式・閾値・例外属性は references/whitespace-theory.md に従う。
3. デザインを決めて theme.css に固定する
deck.md の ## skills に挙げたデザイン系を、ここで読む。飛ばさない。
複数あるなら全部読む — 配色の決め方と余白の決め方が別のスキルに分かれていることがある。
1つも無かったなら、その旨を1行伝えたうえで references/quality-contract.md の数値で進める。
読んだうえで、このデッキ固有の方向を決める。
決めるのは4つだけ: 配色4〜6色 / 表示・本文・等幅の3書体 / 文字サイズ段階 / 記憶に残る装置1つ。
決めたら theme.css の TOKENS に書き、deck.md の ## design にも残す。
制約が2つある。守らないと後段で全部やり直しになる。
- 外部フォントは読み込めない (CSP・オフライン配布)。ローカルにある face か、
deck/fonts/に置いた woff2 の相対参照のみ。スタック末尾にsystem-uiを必ず置く - 1600x900 は固定なので px で書き切る。
clamp()もcqhも不要。 実測値と指定値が一致するほど、この後の検査が効く
theme.css を決めたら以降は凍結する。触るのは「2枚以上で同じ指摘が出たとき」だけ
(理由は references/loop.md)。
4. 全枚を実装する
雛形は assets/slide-template.html。各スライドは独立したHTMLで、
theme.css を読み、自分の <style> にそのスライド固有のレイアウトだけを書く。
:root のトークンを再定義しない。 1枚の都合で全枚の色が変わる。
HTMLを1行にまとめない。 要素ごとに改行して書く。1行で吐くと、あとの局所修正 (手順6・8) がファイル全体の書き換えになり、何を直したのか追えなくなる。
レイアウトは job から決める。型を当てはめない。手がかりは references/layout-playbook.md。
数値の初期値と根拠は references/quality-contract.md。迷ったら本文24px・見出し54px・
外周80px・1枚420字 (手順1で場面が「話しながら」なら300字) までから始める。
最初に構図フレームを作り、次に兄弟トラック、最後に子のpaddingと文字・図形を置く。
構図フレームには必要なら data-space-frame="composition"、中央配置には
data-space-align="center"、矢印には data-space-role="connector" を付ける。
center は縦も横もキャンバス中央 (800, 450) を要求する。 見出しの下に置く構図は
縦中央には来ないので、center を付けると横が完璧でも composition_off_center で落ちる。
見出しの下・左右だけ中央に置きたいときは center-x (安全域基準なら safe-center-x) を使う。
横だけを見て縦は不問になる。
明示しなくても、検査は表・比較クラスと幅720px以上の大きなgrid/flexを構図フレームとして推定する。
文字で埋めない。 箇条書きは6項目まで、1項目60字まで。60字を超えたら、それは
箇条書きの形をした段落で読まれない。関係 (比較/順序/包含/数量) が書かれているなら、
文ではなく図にする — それが storyboard の visual 列に書いてあるはず。
図や画像を入れるなら references/figures.md を先に読む。 方式の選び方
(手書きインラインSVG / draw.io / ラスタ)、配置パターン、図の中の数値契約がそこにある。
要点だけ先に: 図は必ずインラインで置く (<img src="*.svg"> にすると中身を測れず、
図に対してだけ検査が無力になる)。図の中の文字は viewBox で縮むので、
指定値ではなく実効サイズが20pxを割らないようにする。
draw.io を使う場合、上流スキルを vendor/draw-io/ にそのまま同梱してある。
枚数が多いときは、実装を並列のサブエージェントに割ってよい。その場合も
theme.css と deck.md は共有の読み取り専用として渡し、書き換えさせない。
5. 決定的検査(批評より先)
uv run --project <このスキルのディレクトリ>/tools html-deck-check <deck-dir>
1600x900 のヘッドレスChromeで全枚を実測し、はみ出し・文字切れ・文字サイズ・
コントラスト・パレット逸脱・外部参照・情報密度・階層比・意味要素の空白構造を出す。
枚ごとの検査に加えて並びの検査も出る (figure_coverage / text_only_streak /
deck_too_dense)。これは1枚ずつ見ても分からない欠陥で、どの1枚も合格のまま
デッキ全体が文字の壁になるのを止めるためにある。1枚ずつ直すのではなく、
どの枚を図に置き換えるか・どこを統合するかで応える。
スクリーンショットとコンタクトシートを .loop/round-N/ に保存し、
index.html のスライド一覧を同期したうえで、ビューア越しに開いても共有CSSが
効いているかまで確かめる (1枚ずつなら正しく、ビューアだと全スタイルが消える、
という事故が実際にあった)。
余白の実測値は report.json の slides[].metrics.space に出る。これは文字の
text_area_ratioとは別の意味要素面積で、背景・装飾を除外した初期ヒューリスティック。
space_edge_tightやweak_group_separationは review、possible_dead_spaceや
spacing_rhythm_noiseは info として扱い、スクリーンショットの人間判断を上書きしない。
一方、metrics.layout の兄弟重なり、中央からの片寄り、子群の片寄り、過大な接続スロット、
gapと子marginの二重所有はDOMの実矩形で再現できるためblockである。これは余白の好みを
自動採点するものではなく、親フレームの配分が壊れていることを止める契約である。
layout_overlap、composition_off_center、layout_child_shift、
connector_track_wide、redundant_gap_owner が1件でも残る間は、批評サブエージェントを
起動しない。修復は親のgrid/flex、幅の再配分、中央配置、間隔の所有者の整理の順で行い、
子の座標を微調整して隠さない。
block が1件でも残っている間は、批評サブエージェントを起動しない。
機械が確実に見つけられる欠陥を自分で潰してから批評に出す。そうしないと
批評の指摘枠が体裁の修正で埋まり、「主張が伝わるか」に枠が回らない。
「ワンショット」は批評を省略するという意味ではない。初回生成時点で構図フレームを 先に割り、決定的検査のlayout blockを0件にしてから批評へ渡す、という順序を意味する。
6. 批評を受けて差し戻す(Sonnetのサブエージェント)
block が 0 になったら、Agent ツールで批評担当を起動する。
実装しているモデルと別の系列を指定する。 既定は model: "sonnet"。
実装しているのはこのセッション自身なので、同じモデルに採点させると自分の癖ごと見落とす。
目的は系列を分けることであって機種名ではない。 指定した系列が使えない環境なら、
使える別系列で回して「批評は <モデル> で回した」と1行伝える。ここで止まらない。
サブエージェントの推論の深さはツール側から指定できないので、プロンプトの冒頭で 「よく考えてから」と明示して思考量を上げる。これは指定の代用であって同義ではない。
枚ごとの批評(未 pass の枚だけ、並列で起動してよい):
subagent_type: "general-purpose", model: "sonnet", run_in_background: false
prompt:
よく考えてから採点してほしい。まず <このスキルのディレクトリ>/agents/slide-critic.md を読み、
そこの指示に完全に従うこと。
- screenshot: <deck>/.loop/round-N/shots/03-evidence.png ← 必ず Read で画像を見る
- slide_contract: <deck.md の該当行をそのまま貼る>
- deck_goal: <合意したゴール>
- metrics: <report.json の該当スライドの metrics>
- accepted: <deck.md の ## accepted をそのまま貼る>
- user_intents: <html-deck-thread <deck> brief --slide 03-evidence の出力を貼る>
- html_path: <deck>/slides/03-evidence.html
返答は指定のJSONのみ。
デッキ全体の批評(毎ラウンド1回):
subagent_type: "general-purpose", model: "sonnet", run_in_background: false
prompt:
よく考えてから判断してほしい。まず <このスキルのディレクトリ>/agents/deck-critic.md を読み、
そこの指示に完全に従うこと。
- contact_sheet: <deck>/.loop/round-N/contact-sheet.png ← 必ず Read で画像を見る
- storyboard / deck_goal / takeaway / audience / accepted: <deck.md から貼る>
- layout_metrics: <report.json の全スライドの metrics.space / metrics.layout>
- user_intents: <html-deck-thread <deck> brief の出力を貼る>
返答は指定のJSONのみ。
返答は .loop/round-N/critique.json に加工せず保存する。要約して保存すると、
次のラウンドで何を直したのか追えなくなる。
user_intents を渡し忘れない。 ユーザーがレビューで確定させた意図は
deck.md の ## accepted にも1行で入っているが、批評担当にはなぜそう決めたかまで
渡したほうが効く。html-deck-thread brief がその形で出す。
返答の user_conflict が空でなかったら、実装で直さない。 そこはユーザーが実物を見て
決めたことなので、批評担当の言い分をそのままユーザーに伝えて判断を仰ぐ
(「03の出典の置き方について、批評担当はこう見ている。どうするか」)。
黙って批評側に寄せると、ユーザーの意思が静かに巻き戻る。
修正は findings 単位の局所修正だけ。ついでに他を整えない。
修正前に現状を .loop/best/ へコピーし、再検査で悪化した枚は戻す。
確定した判断は deck.md の ## accepted に1行ずつ足す。これを次のラウンドの
批評担当に渡さないと、同じ場所を逆方向に指摘され続けて往復する。
7. 終了してユーザーへ返す
終了条件・停滞判定・予算・評価ハックの禁止事項は references/loop.md にまとめてある。
批評担当を起動する前に一度読む。 要点だけ:
- 全軸4以上 +
deck-criticが pass → 完成 - 改善が2ラウンド連続で小さい → 自動で続けない。 現物と残件を出して判断を仰ぐ
- 2ラウンドで打ち切り。 そこで pass していなくても、現物と残件を持ってユーザーへ返す。 3周目以降は自分で決めずに、ユーザーが「続けて」と言ったときだけ回す
返すときは、成果物の場所・ゴールに対する到達度・直せなかった点を明記する。
点数だけ並べない。返す前に自分で index.html を開いて目で見る — 検査が通ったことは
開いて確認しない理由にならない。
渡す形は3つある。用途で選ぶ。
| 形 | 出し方 | 何のため |
|---|---|---|
| デッキ一式 | そのまま | 手直しを続ける。レビューもここから |
| 1枚のHTML | uv run --project <このスキルのディレクトリ>/tools html-deck-bundle <deck> | 人に送る。 外部参照ゼロの1ファイルで、そのまま添付できる |
| 固定PDF | uv run --project <このスキルのディレクトリ>/tools html-deck-pdf <deck> | 見た目を完全に固定する。印刷する。頼まれたときだけ出す |
html-deck-pdf は、theme.css で指定した書体が実際に描画に使われたかを検査して、
代替書体に落ちていたら書き出さない (--mono は対象外。等幅は本文の見た目を支配しないので、
落ちても警告を出すだけで止めない)。生成した環境に書体が無ければ「見た目を固定して
渡した」とは言えないため。承知のうえなら --allow-font-fallback を付ける。
1枚HTML と 固定PDF はレビュー画面のボタンから押せる (サーバ稼働中のみ)。 PPTX ボタンも並んでいるが、これは実験的な経路。 編集可能な .pptx は約束しない (後述)。
渡し方は、Bash を run_in_background: true で2本起動して URL を渡す。
uv run --project <このスキルのディレクトリ>/tools html-deck-review <deck-dir> --open
uv run --project <このスキルのディレクトリ>/tools html-deck-wait <deck-dir> --timeout 1800
2本目を忘れない。 サーバは止めるまで動き続けるので完了通知が飛ばず、 1本目だけだとユーザーが指摘を送ったことに気づけない。待機は指摘が届いた時点で 終了するので、その終了通知が「ユーザーが送信した」の合図になる。
URL を渡したら、E で要素をクリックすると入力欄に #1 のブロックが入ること、
それを主語に書けることを1〜2行で伝える。使い方の全文をチャットに貼らない。
ユーザーは右ペインの凡例を見れば分かる。
ビューアは1本しかない。 index.html とレビュー画面は同じファイルで、
file:// で開くとレビュー機能が自分で畳まれる (親から iframe の中に到達できないため)。
見た目も操作も同じ。デッキを作った時期が古いと index.html だけ昔のままなので、
そのときは入れ替える。
uv run --project <このスキルのディレクトリ>/tools html-deck-init <deck-dir> --refresh-viewer
タイトルとスライド一覧は引き継ぐ。theme.css と slides/ には触らない
(--force は theme.css ごと初期化してしまうので、既存デッキに使わない)。
E で閉じればスライドの上の枠とピンは1本も残らないので、そのまま人に見せられる。
指摘が残っているかはフッタのバッジ (● 3) で分かる。レビュー中に素の見た目を確かめたい
ときは P かそのバッジでピンだけ落とせる。
ブラウザを閉じたあとも見たいだけなら index.html を直接開けばよい
(レビュー機能とボタンは自動で消える。file:// では要素を選べず、書き出しを走らせる
プロセスも無いため)。人に送るなら html-deck-bundle の1枚を渡す。
8. ユーザーの指摘を受けて直す
待機 (html-deck-wait) が終了したら、その標準出力に未読のユーザー発言がそのまま入っている。
スレッドを読み直す必要はない。
指摘1件 = 1本のスレッド = 1つの PR。 会話して、検査結果を見て、ユーザーがマージして
初めて確定する。エージェントは「直した (proposed)」までしか進められない。
待機が終了 (= ユーザーが発言) → スレッドごとにサブエージェント (deck-fixer)
↑ │ context を渡す / 他のスレッドは渡さない
│ ▼
│ 直す → html-deck-recheck --level brief → post --state proposed
│ │
│ ユーザーが読む → 差し戻し または マージ
└──────── 待機を張り直す。ユーザーが終わりと言うまで ────────────┘
メインとサブの分担を崩さない。
- サブ (
agents/deck-fixer.md) はslides/NN.htmlだけ書く。1スレッドだけ見る theme.cssを書けるのはメインだけ。 サブはhtml-deck-thread escalateで上げてくる。 同じkeyが別スライドで2件以上たまったらdecideで一度に直し、関係スレッド全部に書き戻す- メインが受け取るのはマージの結果だけ。スレッドの会話をメインに持ち込まない
処理が終わったら待機を張り直す。 張らないと次の指摘に気づけず、ユーザーは 送ったのに反応がない状態で待つことになる。ただし待機がタイムアウトで戻ってきたときは 黙って張り直さない。 一度「まだ見ていますか」と声をかける。無言で待ち続けると、 ユーザーからはセッションが固まったように見える。
受け取り方・直し方・閉じ方は references/review.md に全部ある。着手前に読む。 要点:
- 優先度は user > block > critic。 ユーザーが待っているのに批評の指摘を先に潰さない
- 位置は
file_lineを第一候補にするが、anchor_confidenceを必ず見る。 1件直すたびに行番号はずれるので、2件目以降はtext_excerptで取り直す - 直したら必ず検査して、結果を添えて返す (
html-deck-recheck --thread <id> --level brief)。block > 0のままではユーザーがマージできない (サーバが 409 で止める) - ユーザーの指示でも
gates.jsonは割らない。溢れるならdeferredにして理由と代案を返す - マージはユーザーが押す。 そのとき
deck.mdの## acceptedに確定した意図が積まれる。 積まれないと次のラウンドで批評担当が逆方向に指摘し、ユーザーの意思が静かに巻き戻る
返すときは、マージされた件数だけでなく確認待ち (proposed) のまま残っているものと
却下・保留したものとその理由を必ず言う。proposed が残っている間は完成と言わない。
編集可能な .pptx は約束しない。HTML → PPTX の忠実な変換は検証していない。
PPTX が必須なら最初から pptx スキルで作る。
同梱物
| パス | 中身 | 読むタイミング |
|---|---|---|
references/quality-contract.md | 文字サイズ・密度・余白・色の数値とその根拠 | 実装前 |
references/layout-playbook.md | job からレイアウトを決める手がかり | 実装前 |
references/whitespace-theory.md | 余白の一所有者原則・構図フレーム・layout blockの閾値 | 実装前・実装中 |
references/figures.md | 図の方式選択・配置パターン・図中の数値契約 | 図や画像を入れる前 |
vendor/draw-io/ | draw.io スキル本体 (MIT / little-hands、改変なし) | draw.io で図を作るとき |
tools/src/html_deck/drawio_svg.py | .drawio → 貼れるSVGへ変換 | 同上 |
references/loop.md | ループ制御・終了条件・評価ハック禁止 | 批評を起動する前 |
references/review.md | ユーザーの指摘の受け取り方・直し方・閉じ方 | レビューを回す前 |
agents/slide-critic.md | 1枚採点のサブエージェント指示 | サブエージェントが読む |
agents/deck-critic.md | デッキ全体採点のサブエージェント指示 | サブエージェントが読む |
agents/deck-fixer.md | レビュー1スレッドを担当するサブエージェント指示 | サブエージェントが読む |
tools/src/html_deck/assets/gates.json | しきい値の実体 (ラウンド0でのみ変更可。場面に応じた字数もここ) | 検査結果を解釈するとき |
tools/src/html_deck/assets/theme.css | 共有トークンの骨格 | init_deck が配置 |
tools/src/html_deck/assets/shell.css | ビューアの共通の殻 (配置・配信時に埋め込まれる) | 見た目を直すとき |
assets/slide-template.html | 1枚の骨格 | 実装時 |
tools/src/html_deck/init_deck.py | 骨格生成 | 手順2 |
tools/src/html_deck/check_deck.py | 決定的検査 + スクショ + ビューア同期 | 毎ラウンド |
tools/tests/test_space_metrics.py | 余白union・群化比・最大空白・DOM構図契約の自己チェック (ブラウザ不要) | 余白計測を触ったとき |
tools/src/html_deck/export_pdf.py | 16:9 の固定PDF出力 (指定書体が使われたかを検査する) | 納品時 |
tools/src/html_deck/export_pptx.py + emit_pptx.mjs | 編集可能PPTXの実験的出力 (Chromeの実測座標を PptxGenJS へ写す) | 実験 |
tools/src/html_deck/setup_export_runtime.py | pptxgenjs をプロジェクト内に用意する (Python 側は uv run が持つ) | PPTX の初回 |
tools/src/html_deck/bundle_deck.py | デッキ一式を1枚のHTMLに畳む | 渡すとき |
tools/src/html_deck/review_server.py | デッキを配信し、DOM 指定を JSON に落とす | 手順7・8 |
tools/src/html_deck/review_wait.py | 指摘が届くまで待つ (終了通知が送信の合図) | 手順7・8 |
tools/src/html_deck/review_threads.py | スレッドの読み書き・状態遷移・マージ処理 (サーバと CLI が共有) | ライブラリ |
tools/src/html_deck/review_thread.py | スレッドの CLI。list / context / post / escalate / decide / brief | 手順8 |
tools/src/html_deck/review_check.py | 検査の濃淡ラッパ (brief / full / deck) | 手順8 |
tools/tests/test_review_flow.py | レビュー経路の自己チェック (ブラウザ不要) | レビュー機構を触ったとき |
tools/tests/test_export_pdf.py | PDFのフォント照合の自己チェック (ブラウザ不要) | html-deck-pdf を触ったとき |
tools/tests/test_skill_layout.py | SKILL.md や references/ が指すパス・コマンドが実在するかの検査 | 構成を動かしたとき必ず |
tools/tests/test_bundle_deck.py | バンドルがデッキ外を畳まないことの検査 (ブラウザ不要) | html-deck-bundle を触ったとき |
tools/pyproject.toml + tools/uv.lock | Python 依存とコマンド名の唯一の記述 | 依存やコマンドを変えるとき |
tools/src/html_deck/assets/review.html | 唯一のビューア。 配信時はレビュー付き、file:// では自分で畳んでただのビューアになる | サーバ配信 / init_deck が配置 |
コードは tools/ の uv プロジェクト (html_deck パッケージ) で、
すべて uv run --project <このスキルのディレクトリ>/tools から叩く。
Python 本体 (3.14) と Playwright / pypdf は tools/uv.lock で固定してあり、
初回の呼び出しで tools/.venv に入る。以降は解決も再ビルドも走らない。
pptxgenjs だけは uv の管轄外なので、PPTX 書き出しの初回に
<プロジェクト>/.html-deck-runtime/node/ へ入る。
利用者に uv sync も npm install も叩かせない。 初回だけネットワークを使う。
Playwright はシステムの Chrome を使うのでブラウザの追加ダウンロードは無い。
uv / Node.js / Chrome が無い場合だけ名指しのエラーになる。
コードは配布物に同梱される。npx skills add nogikun/html-deck はスキルディレクトリを
丸ごとコピーするので、入れた先に tools/ がそのまま届く。取り寄せる手順は要らない。
呼び口は uv run --project だけ。uvx は使わない。 ビルド結果を uv のキャッシュに
固定するので、tools/ の src を書き換えても、pyproject.toml に依存を足しても、
古いまま動く (依存を足した直後に「pypdf が無い」で落ちた。実測)。
このスキルが避けようとしている失敗
作る前に頭に入れておく。全部、1枚ずつ自由に作らせると必ず起きる。
- 各スライドが凝った見た目を競い、デッキの声が割れる → theme.css 凍結 +
palette_drift検査 - 1枚ずつは美しいが、全体の話が進まない →
deck-criticが cut/merge/reorder を判断 - 見た目を優先して出典や数字が雑になる → 出典は主張と1対1、未出典の数値は禁止
- はみ出しを
overflow:hiddenで隠す →clipped_textとして block - 批評が往復して収束しない →
acceptedに確定判断を積む - 点を上げること自体が目的になる → しきい値はラウンド0で固定、途中変更は結果を無効
- ユーザーが直させた箇所を、次のラウンドで批評担当が元に戻す → マージが
## acceptedに[user]行を積み、以降の批評担当に必ず渡す - ユーザーが指摘を送ったのに気づかず放置する → 手順7で
html-deck-waitを必ず一緒に張り、 1周ごとに張り直す