关于 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详细介绍
HTML Deck
拿到材料后,先确定一个目标,然后持续修改,直到达成目标。 不要试图一次生成就完成。初稿只是草稿,真正的价值在于反馈循环。
这项技能负责企划、设计、实现、检查和修改的全部工作。 只需要用户进行一次初始访谈,并在最后批准一次。 中途频繁确认细节,会让用户不得不充当评估器。
整体流程
材料を読む → インタビュー(1回・4問) → 情報量の予算を決める → 骨格生成 → デザイン → 全枚実装
↓
ユーザーへ提示 ← 終了判定 ← 批評(Sonnet) ← 決定的検査 ←┘
↓ └──────── 局所修正 ────────────┘
レビューモードで指摘 (#1 #2 … + 自然言語)
↓
局所修正 → 再検査 → resolved に記録 → ## accepted に積む
└────────── ユーザーが納得するまで ──────────┘
从中途开始时
这项技能是按从零开始编写的,但经常会在中途调用。 不要老老实实从步骤 1 开始。 直接跳到适用的步骤。
| 用户的说法 | 前往 |
|---|---|
| 「制作幻灯片」「把这份材料做成幻灯片」 | 从步骤 0 开始(不要跳过访谈) |
| 「给我看一下演示文稿」「让我审阅一下」「我有想修改的地方」 | 步骤 7。启动服务器并等待,然后提供 URL |
| 「阅读意见」「修改我发的东西」 | 步骤 8。处理未读线程 |
| 「修改第 3 页的这里」(在聊天中口头提出) | 只执行步骤 8 的修改部分。不需要指摘 JSON |
| 「文字太小」「内容溢出」 | 从步骤 5 的检查开始 |
如果用户没有说明演示文稿的位置,就查找同时包含 deck.md 和 slides/ 的目录。
如果只有一个,就直接使用。如果有多个,才询问用户。
0. 阅读材料
步骤 0-a. 调查可用技能(首先完成的小任务)
这是一个独立任务。打开材料前先完成,并记下结果
(在步骤 2 中写入 deck.md 的 ## skills)。如果跳过这一步,即使环境中有有用的
技能,也可能直到最后都没发现。只做这一次,开始制作后不要再重新查找。
要做的事:
- 列出技能(同时通过下面两种途径)
- 对照下面的用途表——有符合项就记下来。没有对应用途的,记为「无」
- 仅当设计类技能为 0 项时,用一行告知用户
查看列表的方式因用户环境而异。两种都要看:
- 当前上下文中可用技能的列表——这里始终是主要来源。来自插件或本地的技能(如设计、图表、数据可视化等) 可能只会显示在这里
- 如果可以使用
ListSkills/SearchSkills,也要查询。不过,有些环境只会返回 claude.ai 端的技能,因此不能只看这里就断定「没有」
不要根据名称臆测。 以下列出的是「要寻找的用途」, 并不代表一定存在这些名称的技能。只要有任何匹配项,就积极使用。
| 何时 | 要找的内容(用途) | 过去出现过的名称示例 |
|---|---|---|
| 步骤 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 中的自己和批评子 Agent 都不必再查找「有哪些可用技能」。
不要留空就进入步骤 3。
只要有一项设计类技能,就必须在编写 theme.css 前先阅读。只有确认一项都没有时,
才告知用户这一点,然后仅依据 references/quality-contract.md 中的数值继续(不要默默跳过)。
只记录与此表匹配的技能,以及根据材料和请求判断需要的技能。不要打开无关技能—— 浏览列表不花成本,但阅读内容会占用预算。
不要用于导出。 pptx docx xlsx pdf 用于读取材料,而不是输出。
交付物为 HTML,以及由 html-deck-pdf 生成的固定版 PDF。
阅读材料
完整阅读收到的文件、URL 和对话内容。此时需要在心中确定以下事项: 资料面向谁 / 看完后希望对方做什么 / 最想传达的一句话是什么。 如果材料中没有写明,就根据材料推断出最合理的答案。不要在这里把问题全丢给用户,也不要连珠炮似地提问。带着答案去询问。
这一阶段还要整理另一项内容:材料中「可以转化为图形的关系」
(比较、顺序、包含关系、数量差异)。如果这里是空的,下一步访谈中的选项以及之后故事板的 visual 列都无法填写。
1. 访谈希望达成的状态(唯一必需的确认)
这一步最关键。 资料的质量取决于「制作目的」,而不是制作方法。
调用 1 次 AskUserQuestion,并在其中一次性提出 4 个问题。逐个反复提问只会增加中断,
不会让访谈内容更深入。
要问以下 4 个问题。顺序也不要改变。
| # | 要问的内容 | 为什么需要 |
|---|---|---|
| 1 | 希望对方看完后处于什么状态 | 这将成为后续所有判断的合格标准 |
| 2 | 这份资料如何展示——边讲边展示 / 放置后供人阅读 / 两者兼有 | 每页的信息量预算会因此改变。不问就制作,一定会偏离预期 |
| 3 | 对方是谁,有权做出什么决定 | 这决定了要从什么背景信息开始说明 |
| 4 | 页数和演讲时长 | 这是删减内容时的依据 |
选项要根据材料拟定为具体表述。 罗列泛泛的词语,就算对方回答了,也无法据此做决定。
- × 「传达信息」「加深理解」「进行讨论」
- ○ 「能够决定是否批准将 HTML-first 作为限定范围的试点」 「能够从 7 种传输协议中选出适合自己用途的一种」
最多调用 2 次。只有材料过于单薄,导致故事结构有 2 种以上可能时,才调用第 2 次 (例如:以案例为主,还是解释机制,两种方式会导致页面顺序不同)。除此之外,带着答案继续推进。 反复确认会让用户不得不充当评估器。
根据场景确定信息量预算
将问题 2 的答案直接转换为数值。确定后,仅在第 0 轮时写入 <deck>/gates.json 一次,
并在 deck.md 的 constraints 中说明理由(中途更改属于评估作弊)。
| 场景 | 每页日语字数 | 考量 |
|---|---|---|
| 边讲边展示 | 300 字 | 屏幕内容是演讲的佐证。让观众阅读,就没人听讲了 |
| 放置后供人阅读(分发、异步) | 420~520 字 | 正文是主体。但每页一个信息仍不可破坏 |
| 两者兼有 | 300 字 + 演讲内容放在 deck.md 中 | 不要把所有内容都放到屏幕上 |
这份资料是否真的有必要
阅读材料后,有时会发现只需传达一个决定就够了。这种情况下,应在制作幻灯片前说明。 一个 3 行就能说清的事项,做成 15 页并不周到,只是浪费。 「不做」也可以作为答案提出。 但只通过一轮沟通决定;如果用户表示要做,就继续制作。
将达成一致的内容原样写入 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周ごとに張り直す