agency-docs-updater について
Agency Docs Updaterは、会議録画の処理と関連動画・ドキュメントの公開更新を自動化するスキルです。設定されたプロジェクトパスと依存関係を使い、文字起こし、動画準備とアップロード、メタデータ、サムネイル、会議ページの更新を調整します。
主な機能
- 01文字起こしと会議レイアウトの検索
- 02ZoomまたはFathom録画のダウンロード
- 03動画のトリミングと準備
- 04YouTube動画のアップロードと確認
- 05要約の生成とメタデータ更新
活用シーン
- 01ラボ会議の録画公開
- 02会議動画とサムネイルの準備
- 03文字起こしに基づく会議要約の作成
- 04YouTube情報と会議ドキュメントの更新
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ glebis/ claude-skills --skill agency-docs-updaterインストール後、Claude Code で/agency-docs-updaterを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.env.examplelabs.json.claude-plugin/plugin.jsonreferences/learnings.mdthumbnail-guide.mdworkflow-conversion-analysis.mdworkflows.mdyoutube-api.mdscripts/cut_spans.pydetect_lesson_start.pylab_layout.pypoll-and-publish.shpreflight.shrebuild_aggregations.pysafe_build.shtrim_leading_silence.shupdate_meeting_doc.py詳細
Agency Docs Updater
すべての手順を順番に自動実行してください。手順が失敗し、復旧できない場合にのみ一時停止してください。開始前に、既知の落とし穴を確認するため references/learnings.md を読んでください。
設定:パスはスキルのルートにある .env から読み込みます(.env.example を参照)。標準的なセットアップではデフォルト値を使用できます。主な環境変数:VAULT_DIR、DOCS_SITE_DIR、YOUTUBE_UPLOADER_DIR、PRESENTATIONS_DIR、SKILLS_REPO_DIR、SKILLS_LOCAL_DIR、ZOOM_CREDENTIALS_DIR、GITHUB_REPO、SITE_DOMAIN。
依存関係(実行前に存在を確認してください):
- zoom — Zoom 録画のダウンロード(
scripts/zoom_meetings.py) - fathom — Fathom 動画のフォールバック(
scripts/download_video.py) - nano-banana — サムネイルへのオーバーレイ生成(
scripts/generate_image.sh) - calendar-sync — ローカル専用、カレンダーイベントの同期(
sync.sh) - youtube-uploader — 動画の処理、アップロード、YouTube API 認証
Step 0: 引数の解析と設定の読み込み
スキルのルートから .env を読み込みます。次に、args を空白で分割します:
- 8 桁のトークン(
YYYYMMDD)→DATE - "yesterday" →
DATE = $(date -v-1d +%Y%m%d) - "today" または指定なし →
DATE = $(date +%Y%m%d) - 2 桁のトークン(
NN)またはlab-NN→LAB_FILTER - slug トークン(例:
ai-design、claude-code)→LAB_SLUG(環境変数の値を上書きします。デフォルトはclaude-code)
以降の手順で使用するパスの環境変数を展開します:
VAULT_DIR="${VAULT_DIR:-$HOME/Brains/brain}"
DOCS_SITE_DIR="${DOCS_SITE_DIR:-$HOME/Sites/agency-docs}"
YOUTUBE_UPLOADER_DIR="${YOUTUBE_UPLOADER_DIR:-$HOME/ai_projects/youtube-uploader}"
SKILLS_REPO_DIR="${SKILLS_REPO_DIR:-$HOME/ai_projects/claude-skills}"
SKILLS_LOCAL_DIR="${SKILLS_LOCAL_DIR:-$HOME/.claude/skills}"
ZOOM_CREDENTIALS_DIR="${ZOOM_CREDENTIALS_DIR:-$HOME/.zoom_credentials}"
PRESENTATIONS_DIR="${PRESENTATIONS_DIR:-$HOME/ai_projects/claude-code-lab}"
GITHUB_REPO="${GITHUB_REPO:-glebis/agency-docs}"
SITE_DOMAIN="${SITE_DOMAIN:-agency-lab.glebkalinin.com}"
LAB_SLUG="${LAB_SLUG:-claude-code}" # e.g. ai-design for the AI Design Lab
LAB_TITLE="${LAB_TITLE:-$(echo $LAB_SLUG | tr '-' ' ' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)}1' | sed 's/^Ai /AI /')}" # "Claude Code", "AI Design"
Step 0a: 事前チェック(推奨)
事前チェック用の doctor を実行して、パイプラインの途中でよく発生する 3 つの失敗(youtube-uploader の Python 依存関係の不足、Playwright/chromium の不足、無効な Groq キー)を事前に検出します:
bash ${SKILLS_LOCAL_DIR}/agency-docs-updater/scripts/preflight.sh
依存関係と Playwright の重大な問題では、修正コマンドを表示してゼロ以外の終了コードで終了します。表示されたコマンドを実行してから、事前チェックを再実行してください。無効な Groq キーは軽度の警告です。LLM メタデータの手順で 401 エラーが発生するため、タイトル、説明、タグを手動で指定する準備をしてください(VideoConfig を作成して upload.py を直接呼び出し、その後サムネイルとプレイリストを個別に設定します)。
Step 1: Fathom のトランスクリプトを探す
LAB_FILTER が設定されている場合:${VAULT_DIR}/${DATE}-${LAB_SLUG}-lab-${LAB_FILTER}.md
未設定の場合:${VAULT_DIR}/${DATE}-${LAB_SLUG}-lab-*.md を glob し、mtime が最も新しいものを選びます。一致するファイルがなく、slug が明示的に指定されていない場合は、${VAULT_DIR}/${DATE}-*-lab-*.md にフォールバックし、一致したファイルから LAB_SLUG を特定します。
ファイルが見つからない場合:${SKILLS_LOCAL_DIR}/calendar-sync/sync.sh を実行して再確認し、それでも見つからなければ停止します。
YAML フロントマターから以下を抽出して保存します:
FATHOM_FILE、SHARE_URL、MEETING_TITLE、DATE、LAB_NUMBERVIDEO_NAME=${DATE}-${LAB_SLUG}-lab-${LAB_NUMBER}TRANSCRIPT_LANG= 最初の約 50 行から自動判定します(キリル文字の割合が 0.3 超の場合はru、それ以外はen)
最初にラボのレイアウトを解決してください — パス、ページ URL、プレイリスト名はラボごとに異なります。手作業で組み立てず、必ずレジストリを使って解決してください:
python3 ${SKILLS_LOCAL_DIR}/agency-docs-updater/scripts/lab_layout.py ${LAB_SLUG} --lab ${LAB_NUMBER} --meeting ${MEETING_NUMBER} --json
# → meetings_dir (relative to DOCS_SITE_DIR), page_url, playlist, lang, thumbnail_style,
# preserve_placeholder_frontmatter, registered
レジストリはスキルのルートにある labs.json です(claude-code のレガシーレイアウト、GDD RU goal-driven-design-ru、GDD EN)。update_meeting_doc.py と rebuild_aggregations.py は自動的にレジストリを使って解決します。未登録の slug は警告を出して、レガシーの {slug}-internal-{lab} 方式にフォールバックします。新しいラボは labs.json に追加し、パスを独自に作らないでください。Step 4b では playlist を使用し(作成前に既存のプレイリスト一覧を確認し、この正確な名前で検索)、Step 4b/8 では page_url を、概要/MDX の言語には lang を使用してください。また、preserve_placeholder_frontmatter を守ってください(GDD のプレースホルダーには調整済みの toolkit: フロントマターがあるため、上書きせずにマージします)。
MEETING_NUMBER を決定します:${DOCS_SITE_DIR}/content/docs/${LAB_SLUG}-internal-${LAB_NUMBER}/meetings/ にある既存の MDX ファイルを確認し、今日の日付のプレースホルダーを探します。見つかった場合は、その番号を使用します。見つからない場合は、ファイルの内容サイズを確認して次の空きスロットを探します。ゼロ埋めした 2 桁の文字列(例:04)として保存します。この変数は Step 3b、4b、5、6、8 で使用します。
ステップ 2:動画をダウンロード
${VAULT_DIR}/${VIDEO_NAME}.mp4 が存在し、サイズが 1 MB を超える場合はスキップします。
注:Zoom の録画は、会議終了後に処理されるまで約 15 分かかることがあります。Zoom API が録画を返さない場合は、Fathom に切り替える前に待ってから再試行してください。
優先 — Zoom:
python3 ${SKILLS_REPO_DIR}/zoom/scripts/zoom_meetings.py recordings \
--start ${DATE:0:4}-${DATE:4:2}-${DATE:6:2} \
--end $(date -j -v+1d -f %Y%m%d ${DATE} +%Y-%m-%d) \
--show-downloads 2>&1
MP4 の URL を見つけてから、次を実行します:
TOK=$(python3 -c "import json,pathlib; print(json.load(open(pathlib.Path('${ZOOM_CREDENTIALS_DIR}')/'oauth_token.json'))['access_token'])")
curl -L -H "Authorization: Bearer ${TOK}" -o ${VAULT_DIR}/${VIDEO_NAME}.mp4 "${MP4_DOWNLOAD_URL}"
代替 — Fathom(Zoom の録画がない場合):
cd ${VAULT_DIR} && python3 ${SKILLS_LOCAL_DIR}/fathom/scripts/download_video.py \
"${SHARE_URL}" --output-name "${VIDEO_NAME}"
ステップ 3:YouTube にアップロード
ステップ 3-pre:冒頭の無音をカット
Zoom の自動録画は会議開始時点から始まるため、冒頭に数分間の無音が含まれることがよくあります。アップロードする前に:
bash ${SKILLS_LOCAL_DIR}/agency-docs-updater/scripts/trim_leading_silence.sh ${VAULT_DIR}/${VIDEO_NAME}.mp4
# If it prints "trim: wrote …trimmed.mp4", upload the trimmed file instead of the original.
このスクリプトは、ファイルの冒頭が 10 秒を超える無音の場合にのみカットし、冒頭の 2 秒を残し、20 分を超えるカットを拒否し、ストリームコピーします(再エンコードなし)。「no leading silence detected」と表示された場合は、元のファイルを使用してください。
トランスクリプトを使ったよりスマートなカット(タイムスタンプ付きトランスクリプトがある場合に推奨 — Fathom JSON または Zoom VTT。ブロック単位のタイムスタンプが粗い、結合済みの公開用 .md は使用しないでください):
python3 ${SKILLS_LOCAL_DIR}/agency-docs-updater/scripts/detect_lesson_start.py <fathom.json|zoom.vtt> --json
# → {"lesson_start_s": 21.0, "lesson_phrase": "всем привет", "presentation_open_s": 915.0, ...}
次の(a)レッスン開始のフレーズ(«всем привет», «добро пожаловать», «давайте начинать», "let's start" など)と、(b)プレゼンテーション開始のタイミング(«открою презентацию», "share my screen" など)を検出します。次のように使用します:
- カット位置:
max(silence_end, lesson_start_s − 5)— あいさつを残し、その前の無音をカットします。無音の検出結果と照らし合わせて妥当性を確認してください。両者が大きく食い違う場合は、カットする前に確認してください。 - 説明欄の YouTube チャプター:
0:00 Начало/MM:SS Презентация(presentation_open_sからカット位置のオフセットを引いた値)。
どちらのフレーズも見つからない場合は、通常の無音カットに切り替えます。
技術的なトラブルの区間。 同じ検出ツールが tech_check_spans も出力します — 画面共有時の手間取り(«видно презентацию?», «меня слышно?», «перешарю», «одну секундочку» と、презентация/экран という語が近くにあるもの)です。これらは候補です。各区間の context 行を先に確認してください。視認性についての実際の質疑応答はカットできますが、説明の途中にある修辞的な «секундочку» はカットできません。承認した区間をカットするには:
python3 ${SKILLS_LOCAL_DIR}/agency-docs-updater/scripts/cut_spans.py video.mp4 \
--remove 1245-1270 --remove 781-821 # seconds, from tech_check_spans
cut_spans.py は再エンコードし(フレーム単位で正確。トーク中心の 1080p ならほぼ実時間)、区間を結合・調整し、動画全体の長さの 15% を超えるカットを拒否します。カットするたびに、その後のすべての位置がずれます — YouTube チャプターのタイムスタンプは、すべてのカットが終わった後に計算してください。30 秒以下の小さな問題が 1 つだけなら、カットを見送ることも検討してください。2 時間の動画全体を再エンコードする価値がない場合があります。
cd ${YOUTUBE_UPLOADER_DIR} && \
python3 process_video.py \
--video ${VAULT_DIR}/${VIDEO_NAME}.mp4 \
--fathom-transcript ${FATHOM_FILE} \
--title "${MEETING_TITLE}" \
--upload
run_in_background: true で実行します(10~30 分)。失敗した場合は、--resume-from upload を指定します。
標準出力(✓ YouTube video: ...)または processed/metadata/${VIDEO_NAME}.json から YOUTUBE_URL を抽出します。
URL から VIDEO_ID を抽出します(?v= の後ろ、または最後のパスセグメント)。
ステップ 3a:アップロードを確認(必須)
VIDEO_ID を抽出したら、次に進む前に動画が実際に YouTube に存在することを確認してください。動画の処理が気付かないうちに失敗したり、YouTube のコンテンツ審査によって自動削除されたりすることがあります。
cd ${YOUTUBE_UPLOADER_DIR} && PYTHONPATH=. python3 -c "
from auth import get_authenticated_service
import sys, time
youtube = get_authenticated_service()
video_id = '${VIDEO_ID}'
# Poll up to 5 minutes for video to become available
for attempt in range(10):
resp = youtube.videos().list(part='status,processingDetails', id=video_id).execute()
if not resp['items']:
if attempt < 9:
print(f'Video not yet available (attempt {attempt+1}/10), waiting 30s...')
time.sleep(30)
continue
print(f'FATAL: Video {video_id} not found after 5 minutes. Upload may have failed.')
sys.exit(1)
status = resp['items'][0]['status']
processing = resp['items'][0].get('processingDetails', {})
upload_status = status.get('uploadStatus', 'unknown')
privacy = status.get('privacyStatus', 'unknown')
rejection = status.get('rejectionReason', None)
print(f'Upload status: {upload_status}, Privacy: {privacy}')
if rejection:
print(f'REJECTED: {rejection}')
sys.exit(1)
if upload_status in ('processed', 'uploaded'):
print(f'✓ Video {video_id} verified OK')
sys.exit(0)
if upload_status == 'failed':
print(f'FATAL: Upload failed — {status.get(\"failureReason\", \"unknown\")}')
sys.exit(1)
print(f'Status: {upload_status}, waiting 30s...')
time.sleep(30)
print('FATAL: Video not ready after 5 minutes')
sys.exit(1)
"
確認に失敗した場合は、失敗した動画のメタデータを削除し(rm processed/metadata/${VIDEO_NAME}.json)、--resume-from upload を指定して再アップロードし、再度確認してください。確認されていない VIDEO_ID を使って、MDX やサムネイルの手順に進まないでください。
ステップ 4 を並行して開始します — 要約は YouTube の URL に依存しません。
ステップ 3b:ラボ形式のサムネイル(必須)
このステップは必ず実行してください。process_video.py が生成する一般的なサムネイルを、ブランド化されたラボテンプレートに置き換えます。一般的なサムネイルは公開用として認められません。
前提条件:VIDEO_ID が判明している必要があります(必要に応じて、ステップ 3 が完了するまで待ってください)。
ワークフロー全体については、references/thumbnail-guide.md に従ってください。
- Nano Banana のオーバーレイ画像を生成します(ガイドのプロンプトパターンを参考に、トピックに合わせたプロンプトを使用)
- 元画像を読み込んで調べ、背景色を確認してから、線の色をオレンジ(#e85d04)に変更します
${YOUTUBE_UPLOADER_DIR}/templates/images/lab-meeting.htmlをベースに、一時的な HTML ファイル(例:/tmp/lab-meeting-${MEETING_NUMBER}.html)を作成します。ミーティング番号、トピックのメインテキスト、箇条書きの説明、日付を更新します。元のテンプレートを直接編集しないでください。- Playwright を使って 1280×720 でレンダリングし、
${YOUTUBE_UPLOADER_DIR}/processed/thumbnails/${VIDEO_NAME}.jpgに出力します - レンダリングしたサムネイルを読み込んで確認し、アップロード前にレイアウトを検証します
- YouTube にアップロードします。ステップ 3 で取得した
VIDEO_IDを使用してください
このステップを省略したり、process_video.py のサムネイルに頼ったりしないでください。
ステップ 4:ファクトチェック済みの概要を作成する
${FATHOM_FILE} を読み込みます。構成された概要を ${TRANSCRIPT_LANG} で作成します。
##見出し、箇条書き、関連する場合はコード例を含めます- 技術用語は英語のままにします(MCP、Skills、Claude Code など)
- 個人的な予定調整の詳細は除外します
- 運用担当者向けのメモやパイプラインに関する記録は除外します:録画ソース、トリミングやカット、無音部分や前置きの削除、リマックスや再エンコード、トランスクリプトの同期、アップロードの再試行、その他の制作上の手順は内部のパイプラインレポートにのみ記載し、公開する概要やミーティングページには含めないでください
- 公開前に、プロジェクトの信頼できる情報源またはユーザーによる明示的な修正内容と照らし合わせて、製品名、企業名、人物名を確認します。固有名詞について、ASR/LLM による表記の正規化を信用しないでください
- MDX をコンパイルできなくなる
<、>、およびそのままの{文字はエスケープします
利用可能な場合は claude-code-guide サブエージェントを使って、Claude Code の機能に関する主張をファクトチェックします(エージェントを利用できない場合は、ファクトチェックを省略します)。修正済みの概要をスクラッチパッドに summary.md として保存します。
ステップ 4b:YouTube のメタデータを更新する
ステップ 3 とステップ 4 の両方が完了した後に実行します。 このステップの前に、VIDEO_ID、MEETING_NUMBER、LAB_NUMBER がすべて確定している必要があります。説明文の形式と API のコードスニペットについては、references/youtube-api.md を読み込んでください。
概要をもとに YouTube の説明文を作成します。言語に応じたテンプレートを使用してください。
TRANSCRIPT_LANG=enの場合:英語のラベル("In this video:", "Course materials and session notes:")TRANSCRIPT_LANG=ruの場合:ロシア語のラベル("В этом видео:", "Материалы и конспект занятия:")
1 つの説明文に複数の言語を混在させないでください。
ミーティングページの URL:https://${SITE_DOMAIN}/${LAB_SLUG}-lab-${LAB_NUMBER}/meetings/${MEETING_NUMBER}
YouTube API を使ってタイトル、説明文、タグを更新し、動画をプレイリスト「${LAB_TITLE} Lab ${LAB_NUMBER}」に追加します(存在しない場合は自動作成されます)。
ステップ 5:MDX を生成する
LAB_SLUG=${LAB_SLUG} python3 ${SKILLS_LOCAL_DIR}/agency-docs-updater/scripts/update_meeting_doc.py \
${FATHOM_FILE} "${YOUTUBE_URL}" ${SCRATCHPAD}/summary.md
実行前:今日の日付のプレースホルダー MDX がすでに存在するか、meetings/ で grep -l を使って確認します。存在する場合は、-n ${MEETING_NUMBER} --update を使って対象にします。
実行後:
- 追加された Marp コンテンツを削除します(要約の閉じる
---からまでのすべて) — MDX は HTML コメント()、エスケープされていない<、および裸の{文字でエラーになります - プレゼンテーションファイルを確認します:
${PRESENTATIONS_DIR}/presentations/lab-${LAB_NUMBER}/(ラボごとにPRESENTATIONS_DIRを設定します。ai-design ラボのデッキは別の場所にあるため、slug に対して未設定の場合はスキップします)と${PRESENTATIONS_DIR}/lesson-generator/で${DATE}に一致するファイルを探します。見つかった場合は${DOCS_SITE_DIR}/public/${DATE}-${LAB_SLUG}-lab-${LAB_NUMBER}.htmlにコピーし、MDX にリンクを追加します - フロントマターのプレースホルダー(
[Название встречи]、[Краткое описание встречи]、[Дата встречи])を置き換えます TRANSCRIPT_LANG=enの場合は、MDX 全体を英語のラベルで書き直します — スクリプトはロシア語をデフォルトとし、翻訳のフォールバックでは言語が混在した不完全な出力になります- 確認します:
bash ${SKILLS_LOCAL_DIR}/agency-docs-updater/scripts/safe_build.sh(npm run buildをラップします。.nextキャッシュが破損している場合、自動的にクリアしてreading 'hash'/ ENOSPC エラー時に一度再試行します) - 生成された MDX 内を検索し、運用者向け/パイプライン関連のメモ(録画の出所、編集/カットの詳細、エンコード、トランスクリプトとの同期、アップロードの仕組み)を公開前に削除します
- MDX、公開トランスクリプト、YouTube メタデータ、サムネイルの文言を検索し、修正済みの固有名詞に対する既知の ASR 表記ゆれを確認します。すべての公開箇所で正規の表記に統一してください
ステップ 6:コミットしてプッシュする
パイプライン関連のファイルのみをステージングします — git add . は絶対に使わないでください:
cd ${DOCS_SITE_DIR}
git fetch origin main
BEHIND=$(git rev-list --count HEAD..origin/main)
if [ "$BEHIND" -gt 0 ]; then
git stash push -m "agency-docs-updater: temp stash"
git pull --rebase origin main
git stash pop || true
fi
git add content/docs/${LAB_SLUG}-internal-${LAB_NUMBER}/meetings/${MEETING_NUMBER}.mdx
# Only stage presentation HTML if it was copied
[ -f public/${DATE}-${LAB_SLUG}-lab-${LAB_NUMBER}.html ] && git add public/${DATE}-${LAB_SLUG}-lab-${LAB_NUMBER}.html
git commit -m "Add ${LAB_TITLE} Lab ${LAB_NUMBER} Meeting ${MEETING_NUMBER}"
git push
ステップ 7 で使用する COMMIT_HASH=$(git rev-parse HEAD) を保存します。
ステップ 7:Vercel のデプロイを待つ
TIMEOUT=300; ELAPSED=0
until [ "$(gh api repos/${GITHUB_REPO}/commits/${COMMIT_HASH}/status --jq '.state' 2>/dev/null || echo 'pending')" != "pending" ]; do
sleep 15; ELAPSED=$((ELAPSED+15))
[ "$ELAPSED" -ge "$TIMEOUT" ] && echo "Deploy timeout after ${TIMEOUT}s" && break
done
DEPLOY_STATE=$(gh api repos/${GITHUB_REPO}/commits/${COMMIT_HASH}/status --jq '.state')
echo "Deploy state: ${DEPLOY_STATE}"
run_in_background: true を指定して実行します。状態が failure または error の場合:Vercel のログ(vercel logs)を確認し、ローカルで修正して再プッシュし、このステップを再実行します。
ステップ 8:ブラウザーで確認する
ブラウザー(chrome automation tools または手動)で https://${SITE_DOMAIN}/${LAB_SLUG}-lab-${LAB_NUMBER}/meetings/${MEETING_NUMBER} を開きます。YouTube 埋め込みが表示されることを確認します。表示されない場合:VIDEO_ID を確認するか、YouTube の処理を待つか、再アップロードします。
ステップ 9:サイト全体の集約データを再生成する
新しいミーティングをコミットした後(ステップ 6)、新しいミーティングが反映されるよう、すべてのミーティングを対象にサイト全体の 3 つの集約データ(データベース(ミーティング索引)、用語集、リンクのグローバルライブラリ)を再生成します。
python3 ${SKILLS_LOCAL_DIR}/agency-docs-updater/scripts/rebuild_aggregations.py
スクリプトは同じ .env のパスを読み取り、以下を書き込みます(パスは AGG_* 環境変数で設定可能です)。
content/docs/database.mdx+public/data/meetings.json— すべてのミーティングの索引content/docs/glossary.mdx(定義は.agency-glossary.jsonに保持されます)content/docs/library.mdx— すべてのミーティングに含まれる重複排除済みの外部リンク
新しい用語集の用語に対応する:スクリプトは、これまで認識していない用語について → N NEW term(s) need definitions と出力します。それぞれについて、${DOCS_SITE_DIR}/.agency-glossary.json に 1 行の定義を記述します(技術用語は英語のままにし、それ以外はページの言語に合わせます)。その後、スクリプトを再実行し、定義を反映した用語集 MDX を再生成します。すでに定義されている用語には手を加えないでください — 保存データが信頼できる情報源です。
次に:bash ${SKILLS_LOCAL_DIR}/agency-docs-updater/scripts/safe_build.sh を実行し、生成された MDX がコンパイルされることを確認します(破損した .next キャッシュから自動復旧します)。変更された集約ファイル(3 つの MDX ページ、public/data/meetings.json、.agency-glossary.json)をステージングし(git add . は絶対に使わないでください)、コミットします:
git add content/docs/database.mdx content/docs/glossary.mdx content/docs/library.mdx \
public/data/meetings.json .agency-glossary.json
git commit -m "Rebuild aggregations after Lab ${LAB_NUMBER} Meeting ${MEETING_NUMBER}"
git push
このコミットは、1 回のプッシュにまとめたい場合はステップ 6 のコミットに含められます。いずれの場合も、ステップ 7 のデプロイ待機を再実行する前にコミットを反映させてください。
パイプラインのレポート
完了後、Fathom のパス、動画のパス、YouTube URL、MDX のパス、コミットハッシュ、デプロイの状態、埋め込みの確認結果、集約データの再生成結果(ミーティング数、新たに定義した用語集の用語があればその内容)を報告します。
関連:ファンアウト型のメンテナンスワークフロー
過去のすべてのミーティングを対象とするリポジトリ全体のジョブ(ページごとに埋め込みの破損や MDX の不具合を監査する、または未完了のミーティングをバックフィル/修復するなど)については、references/workflows.md を参照してください。これらは、オンデマンドで実行するファンアウト型の動的ワークフロー(ミーティングごとに 1 つのエージェント)であり、この単一ミーティングのパイプラインとは別のものです。