Skip to content

#2065 を実装する(スプリント s2065) - #2069

Merged
takemi-ohama merged 13 commits into
sprint/s2065from
feat/issue-2065-s2065
Oct 17, 2026
Merged

takemi-ohama merged 13 commits into
sprint/s2065from
feat/issue-2065-s2065

Conversation

@takemi-ohama

Copy link
Copy Markdown
Contributor

スライドの作成を、Node の生成スクリプトで pptx を作る経路に一本化しました(#2065)。あわせて、ページの枠組み・トーン&マナー・台本からのノート・尺の計算を備えた汎用テンプレートと、Google Slides の全ページのサムネイルを取るスクリプトを ndf の release Skill に加えました。発表資料「独自スキルプラグイン開発の薦め」もこの経路で作っています。

利用者向けの変化

  • ndf の release Skill に、スライドの汎用テンプレートが入りました。ページの枠組みに沿って生成スクリプトから pptx を作り、トーン&マナーを差し替えられます。台本はノートになり、台本から発表の尺を計算できます
  • スライドの生成は生成スクリプトの 1 経路です。構成メモと台本を用意し、生成スクリプトで作ります
  • Google Slides の全ページのサムネイルを取るスクリプトで、変換後の体裁を画像で確かめられます。pptx の変換と差し替えに使う gws のコマンドは対応表から引けます
  • 既知の失敗に、pptx で差し替えた Google スライドの書体が Arial になる場合と、その確かめ方を載せています

移行の手順

  • 無し

変更の要点

  • 汎用テンプレートを plugins/ndf/skills/release/assets/slides/ に追加しました。lib/deck-frame.js がページの枠組み、lib/script-time.js が台本からの尺の計算、build-deck.js が生成の入口です。script.md は台本の雛形です
  • references/form-slide.md を、生成スクリプトの方式に合わせて書き直しました。汎用テンプレート、構成メモと台本、変換とサムネイルの確認は、規約から辿れます。比較の語は外しています
  • docs/presentations から Marp の手順と build.sh を外し、生成スクリプトの方式へ書き換えました。要求の写しには、Marp と python-pptx を外す決定 12・13 を足しています
  • gws のスクリプトについて、出力の末尾と stopped の結果を共有の部品へ寄せました。サムネイルの画像は curl で取ります
  • 発表資料「独自スキルプラグイン開発の薦め」の台本・構成メモ・生成スクリプトを追加しました。サムネイルでの体裁レビューで見つかった点も直しています(流れ図の矢印、箱の文字の余白、1 文字だけの行、下の空白の偏り)
  • 確定仕様のスライドの生成経路と、google-workspace が扱う範囲を、生成スクリプトとサムネイルの取得に合わせて更新しました。layout-review と official-skills-autoloader の SKILL.md も、これに合わせて直しています

テスト

  • テストを追加しました
    • test_slide_template.py: テンプレートの生成、枠組みの座標、トーン&マナーの差し替え、台本と尺
    • test_slides_thumbnails.py: サムネイルのスクリプト
    • tests/test_presentation_decks.py: 発表資料の生成
  • supervise.py の run の結果は次のとおりです
    • base-sync・format・sync・lint-limited・design-specs は通りました
    • test-limited は exit 0 です。落ちたテストはフレーキーと既存の失敗だけでした(441.3 秒)
    • design-tests は exit 1(stopped)で止まっています。対象は設計文書 2 件(issues/issue-2065-design-decisions.md ほか)です。中身はレビューで確認が要ります

設計と違う点

設計の箇所 違い 理由
issues/issue-2065-design-decisions.md の決定 11(と設計の「非機能の実現方式」のシステム環境) CI の pytest のジョブは actions/setup-node の 22 だけを足し、汎用テンプレートと発表資料の npm ci はジョブで打たず、生成のテスト(plugins/ndf/skills/release/tests/slide_deck_support.py)がロックを取って自分で打つ 手元と CI で同じ経路にし、npm ci を打ち忘れた手元の実行でも生成のテストが読み飛ばされないため。前提のコマンド(node・npm)の確認は根の conftest.py が行う
issues/issue-2065-design.md の「入出力の契約」の slides-thumbnails.py の終了コード 設計の 0 / 1 / 2 / 11 に加え、gws の応答が JSON でない・ページの ID や contentUrl が無いときは 2(読めない)、gws か curl が無いときは 3(前提が無い)を返す。画像の取得は curl で行い、curl の失敗は 1 共有の終了コードの規約(plugins/ndf/scripts/lib/step_result.py の EXIT_UNREADABLE・EXIT_PRECONDITION)に揃え、応答を読めない失敗を「gws の失敗」と区別するため
issues/issue-2065-design.md の「構成要素」のテストのパス(release/tests/test_slide_template.py・google-workspace/tests/test_slides_thumbnails.py) テストは plugins/ndf/skills/ の下(plugins/ndf/skills/release/tests/test_slide_template.py・plugins/ndf/skills/google-workspace/tests/test_slides_thumbnails.py)にあり、design-match の「無い」は設計の表が plugins/ndf/skills/ を省いた書き方による。作らなかったテストは無い 構成要素の表は他の行も Skill の名前から書く形で、実体は同じファイルである

体裁レビュー(代替: 手元の描画。gws 未認証のときに行った。正式な記録は下の「体裁レビュー(Google Slides のサムネイル)」)

  • 描画の手段: LibreOffice(soffice --headless --convert-to pdf)→ pdftoppm -r 80。書体は Noto Sans CJK JP で描画された
  • 見た範囲: 全 23 ページ(docs/presentations/2026-10-17-skill-plugin-development、2026-10-18 JST)
  • 機械で測った項目: ページ数 23(台本 23・構成メモ 23 行)/ 全ページにスピーカーノート(台本と一致、pytest)/ 書体 Noto Sans JP のみ / 色は theme の値のみ
  • 人が見た結果(1 回目):
    • 2・7・10・11 ページ: 区画の下が空く → 生成へ差し戻し(区画の高さを詰めた)
    • 8 ページ: 「ドキュメントの再構成」「クロスリファクタリング」が語の途中で折れる → 生成へ差し戻し(改行の位置を指定)
    • 9・13〜16・20〜22 ページ: 本文の文字が小さく区画が空く → 生成へ差し戻し(本文を 11〜12.5pt に)
    • 20 ページ: 前提の違い 3 つが同じ段に並ぶ → 生成へ差し戻し(1 段下げた)
  • 人が見た結果(直した後): 文字あふれ 0 件・図の重なり 0 件
  • 画像: 作業ディレクトリの deck-01.png〜deck-23.png(コミットしない)

gws の変換とサムネイル(未達。代替の記録。2026-10-18 08 時台に下で達成)

  • python3 plugins/ndf/skills/google-workspace/scripts/gws-check.py は authenticated(exit 0)を返したが、gws auth status は auth_method: none・credential_source: client_secret.json で、トークンが無い
  • gws drive files export --params '{"fileId":"<台本のID>","mimeType":"text/markdown"}' → exit 1 error[auth]: Access denied. No credentials provided.
  • そのため台本は手元の写し script-v7.md を使い、正本との突き合わせ・Google Slides への変換・サムネイルの取得はできていない。利用者が ! gws auth login を打った後に、form-slide.md の「変換と確認」の順で打つ
  • 要求の形だけは --dry-run で確かめた(gws-dry-run.md)

gws の dry-run(代替。2026-10-18 02:51 JST)

presentations get: GET https://slides.googleapis.com/v1/presentations/PRES
exit=0
getThumbnail: GET https://slides.googleapis.com/v1/presentations/PRES/pages/p1/thumbnail
files copy: POST https://www.googleapis.com/drive/v3/files/FILE/copy
files update --upload: PATCH https://www.googleapis.com/upload/drive/v3/files/FILE
+upload: POST https://www.googleapis.com/upload/drive/v3/files

台本の正本との突き合わせ(2026-10-18 08 時台 JST)

  • 認証: gws auth status → auth_method: oauth2
  • 書き出し: gws drive files export --params '{"fileId":"<台本の正本の ID>","mimeType":"text/markdown"}' --output canon.md → exit 0(17695 bytes)。text/plain でも exit 0(17528 bytes)
  • 比べ方: 正本の Markdown のエスケープ(1\. など)・行末の空白・空行・表の区切り行の形を正規化し、script.md と行単位で diff
  • 結果: 差分 0 行(両方 61 行)。script.md・生成スクリプト・テスト・構成メモの尺は直していない
  • 尺: node slides/lib/script-time.js script.md --limit 35 → 合計 5317 字・911.5 秒(15分12秒)。notes.md の「尺」と一致
  • 正本の書き出しは work/gws/ に置き、コミットしない

Google Slides への変換(gws の実際の実行結果)

手 コマンド(form-slide.md の「変換と確認」・system-gdrive.md・google-workspace の対応表のまま) 結果
生成 node slides/build-deck.js work/gws/skill-plugin-development.pptx exit 0、23 ページ
上げる gws drive +upload skill-plugin-development.pptx(pptx のあるディレクトリで) exit 0、mimeType は pptx
変換 gws drive files copy --params '{"fileId":"<上げた pptx の ID>"}' --json '{"name":"独自スキルプラグイン開発の薦め","mimeType":"application/vnd.google-apps.presentation"}' exit 0、mimeType: application/vnd.google-apps.presentation
サムネイル python3 plugins/ndf/skills/google-workspace/scripts/slides-thumbnails.py <ID> work/thumbs-r1 --size LARGE exit 0、status: ok・23 ページ・約 30 秒
差し替え(4 回) gws drive files update --params '{"fileId":"<Google Slides の ID>"}' --upload skill-plugin-development.pptx --upload-content-type application/vnd.openxmlformats-officedocument.presentationml.presentation(pptx のあるディレクトリで) 4 回とも exit 0。ID と URL は変わらない
  • 手順どおりに打てなかったコマンド: なし(規約側の直しは不要だった。受け入れ条件 8 の確認)
  • 見つけた失敗: 3 回目の差し替えの後、本文 1304 か所の書体が Arial になった(pptx の指定は Noto Sans JP のまま)。同じ pptx でもう一度差し替えると Noto Sans JP に戻った(空白だけの文字列 323 か所は Calibri)。system-gdrive.md の「既知の失敗」に事象と確かめ方を足した(6fc928d98)

体裁レビュー(Google Slides のサムネイル)

  • 描画の手段: Google Slides のサムネイル(slides-thumbnails.py、LARGE=横 1600px)。書体は Noto Sans JP で描画された(最終版を gws slides presentations get の fontFamily で確認)
  • 見た範囲: 全 23 ページ(1 回目は 23 ページすべてを Read で 1 ページずつ見た。直した後は直した 6 ページを見て、直していない 17 ページは 1 回目と画像のハッシュが一致することを確かめた)
  • 機械で測った項目: ページ数 23 / 全ページのスピーカーノートが台本と一致(pytest)/ 直していない 17 ページの画像が 1 回目とバイト一致
  • 人が見た結果(1 回目):
    • 1〜7・10・11・13〜17・19・21・23 ページ: 文字あふれ・重なり・切れ 0 件
    • 8 ページ: 段の続きの下向きの矢印が 4 列目(「ドキュメントの再構成」→「クロスレビュー」)の間にあり、箱どうしの流れに読める。「テストファーストの実装」「完了判定(証跡)」「リリース後テスト」の文字が箱の端に迫る → 生成へ差し戻し(矢印を見出しの列へ移し、箱の文字を 9→8.5pt)
    • 9 ページ: 区画の下から注記の上まで本文の領域の約 4 分の 1 が空く → 生成へ差し戻し(区画の高さ 2.6→2.75。本文を 12pt にすると「語・」の「・」が行頭へ来たので 11.5pt のまま)
    • 12 ページ: 「claude・codex・kiro」が箱の幅いっぱい → 生成へ差し戻し(9.5→9pt)
    • 18 ページ: 表の下が本文の領域の約 4 分の 1 空く → 生成へ差し戻し(行の高さと文字を 11→12pt)
    • 20 ページ: 左の区画と右の表の下が大きく空く → 生成へ差し戻し(区画の高さ 2.3→2.6・本文 12pt、表の行 0.42→0.5・12pt)
    • 22 ページ: 「自分のリポジトリからインストールする」の「る」だけが次の行へ落ちる → 生成へ差し戻し(「自分のリポジトリからインストール」)
  • 人が見た結果(直した後・最終版): 文字あふれ 0 件・重なり 0 件・切れ 0 件。2・3・10・13・14・22 ページの区画の中の下側の空きは、横に並ぶ区画の高さをそろえたためで残した
  • 直した生成スクリプト: 4747d5b
  • 画像: /home/ubuntu/.local/state/ndf/sv/s2065/5-impl-2065-state/work/thumbs-r1/(1 回目)、thumbs-r2/・thumbs-r3/(途中)、thumbs-final/(最終版)。コミットしない

モード: standard / 通した工程: 実装 → 完了判定 → Pull Request

🤖 Generated with Claude Code

takemi-ohama and others added 13 commits October 17, 2026 17:45
…2065)

2026-08-06 の資料の md・html・pdf は発表日時点の記録として残す。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8 ページ目の段の続きの矢印を見出しの列へ移し(工程の箱の間にあると箱どうしの流れに読める)、
箱の文字を 8.5pt にした。12 ページ目の箱の文字を 9pt、22 ページ目の「る」だけの行を解消した。
9・18・20 ページ目は本文の領域の下に偏った空白を、区画と表の高さで埋めた。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant