$npx -y skills add deancourse/agent-skill-lecture-builder --skill course-page-generator將講稿或非結構化筆記轉換為約定的 Markdown 格式,再透過 build script 產生單一 HTML 課程頁面與 OG 縮圖。Skill 的主要任務是 Markdown 格式轉換,build 與 OG 圖片生成是最後的必要步驟。
| 1 | # Course Page Generator |
| 2 | |
| 3 | 原始講稿 → 結構化 Markdown → `node .agents/skills/course-page-generator/scripts/build.mjs <dir>` → `index.html` → `node .agents/skills/course-page-generator/scripts/generate-og.mjs <dir>` → `assets/og-*.jpg` |
| 4 | |
| 5 | ## 專案結構 |
| 6 | |
| 7 | ``` |
| 8 | .agents/skills/course-page-generator/ |
| 9 | ├── scripts/ |
| 10 | │ ├── build.mjs # 課程頁 build script |
| 11 | │ └── generate-og.mjs # 針對課程頁產出 1200x630 OG 縮圖(依賴 Puppeteer) |
| 12 | └── reference/ # 格式範例與 HTML 模板(含支援 ?og=1 的 base.html) |
| 13 | |
| 14 | <root>/ # 任意根目錄(例如 course/、lectures/、docs/) |
| 15 | ├── config/ |
| 16 | │ ├── global.yaml # 全域設定(講者、社群、頁尾) |
| 17 | │ └── assets/ # 共用圖片(avatar 等) |
| 18 | ├── <course-dir>/ |
| 19 | │ ├── config.yaml # 課程專屬設定(覆蓋 global) |
| 20 | │ ├── content.md # 結構化 Markdown 講稿 |
| 21 | │ ├── index.html # 課程頁(build 生成) |
| 22 | │ └── assets/ |
| 23 | │ └── og-*.jpg # OG 縮圖(generate-og.mjs 產出) |
| 24 | ``` |
| 25 | |
| 26 | ## Workflow |
| 27 | |
| 28 | ### Step 0:偵測輸入類型 |
| 29 | |
| 30 | 在進入轉換流程之前,先判斷使用者提供的是哪種輸入: |
| 31 | |
| 32 | | 情境 | 判斷依據 | 行動 | |
| 33 | |------|----------|------| |
| 34 | | **只有主題** | 只給了一句話主題/標題,無對應資料夾或 Markdown | → 執行「主題生成流程」(見下方) | |
| 35 | | **有講稿內容** | 提供了講稿文字、大綱、或已有 content.md | → 直接進入 Step 1 | |
| 36 | | **有現有目錄** | 指定了已存在的課程資料夾 | → 讀取後進入 Step 1 | |
| 37 | |
| 38 | #### 主題生成流程 |
| 39 | |
| 40 | 當使用者只提供主題(例如「Python 非同步程式設計」): |
| 41 | |
| 42 | 1. **決定課程資料夾位置**:將主題轉為 kebab-case 英文(例如 `python-async`)作為資料夾名稱。 |
| 43 | - 若使用者有指定路徑(例如 `lectures/python-async`),直接使用。 |
| 44 | - 否則,**用 Glob 工具掃描 repo 根目錄**,觀察現有的課程資料夾放在哪一層(例如是否有 `course/`、`lectures/` 等慣例目錄),沿用同層。 |
| 45 | - 若無任何慣例可循,直接建在 **repo 根目錄**下(`<course-dir>/`),不假設子目錄。 |
| 46 | |
| 47 | 2. **建立資料夾結構**: |
| 48 | ``` |
| 49 | <root>/<course-dir>/ |
| 50 | ├── config.yaml # 從主題推導課程設定 |
| 51 | ├── content.md # 根據主題生成骨架 |
| 52 | └── assets/ # 空資料夾(保留圖片用) |
| 53 | ``` |
| 54 | |
| 55 | 3. **生成 `config.yaml`**:根據主題填入基本欄位(`page.title`、`page.hero_title`、`seo.title`、`seo.description`、`quotes.opening`、`quotes.closing`);`seo.image` 與 `seo.url` 依照 Step 2-0 偵測到的 GitHub Pages 前綴填入;若偵測失敗則留空。 |
| 56 | |
| 57 | 4. **生成 `content.md` 骨架**: |
| 58 | - 推導 3–5 個主要章節(`#`),每章節下 1–2 個子章節(`##`)與 2–3 張卡片(`### Emoji Title`) |
| 59 | - 每張卡片留 2–4 個條列式占位點(重點提示,非最終內容) |
| 60 | - 在最後加入 `[summary]` 區塊,列出各章節預期的學習成果 |
| 61 | - 所有占位內容用 `<!-- TODO: ... -->` 或簡短提示標記,讓使用者知道哪裡需要補充 |
| 62 | - 骨架本身應具備足夠結構讓 build 可以成功執行 |
| 63 | |
| 64 | 5. **確認 global config**:檢查是否已有 `config/global.yaml`,若無,在回覆中提示使用者參考 Step 2 建立。 |
| 65 | |
| 66 | 6. **告知使用者**:列出已建立的檔案清單,並說明下一步(補充內容或直接 build)。 |
| 67 | |
| 68 | 7. **完成後繼續 Step 2 以下流程**(確認 config → build → **OG 縮圖**)。Build 成功後**必須**立即執行 `generate-og.mjs`。 |
| 69 | |
| 70 | --- |
| 71 | |
| 72 | ### Step 1:將講稿轉為結構化 Markdown |
| 73 | |
| 74 | 這是 Skill 的核心任務。使用者提供的可能是: |
| 75 | - 非結構化的演講筆記或大綱 |
| 76 | - 已部分格式化的 Markdown |
| 77 | - 課程投影片的文字內容 |
| 78 | |
| 79 | AI 需要根據以下語法規則,將內容轉換為 `content.md`。 |
| 80 | |
| 81 | #### Markdown 語法約定 |
| 82 | |
| 83 | | 語法 | 用途 | 範例 | |
| 84 | |------|------|------| |
| 85 | | `# LABEL:TITLE` | 主章節 | `# 新專案:用 SDD 讓 AI 根據規格建立專案` | |
| 86 | | `> lead text` | 章節引言(緊接 `#` 後) | `> 規格驅動開發(Spec-Driven Development)` | |
| 87 | | `## Title` | 子章節 | `## OpenSpec 初始化` | |
| 88 | | `### Emoji Title` | 卡片標題 | `### 🔧 為什麼需要 OpenSpec?` | |
| 89 | | `` ```prompt [label="..."] `` | 終端機/Prompt 區塊 | 見下方 | |
| 90 | | `> **Bold Title**` | 洞察框(Insight) | `> **AI 正在改變企業決策**` | |
| 91 | | `[flow]...[/flow]` | 流程步驟 | 見下方 | |
| 92 | | `[tags]...[/tags]` | 標籤(必須用此區塊包裹) | `- [green] 正面` | |
| 93 | | `[summary]...[/summary]` | 總結卡片 | `- 🏗️ **標題** \| 描述` | |
| 94 | | `- [x] item` | 勾選清單(僅用於已驗證/已完成的事項) | `- [x] 已完成項目` | |
| 95 | | `` | 獨立圖片 | `` | |
| 96 | | `[image-text]...[/image-text]` | 圖文並排 | 見下方 | |
| 97 | | `[youtube id="..." title="..."]` | YouTube 影片嵌入 | 見下方 | |
| 98 | | `---` | 章節分隔線 | 放在 `#` 章節之間 | |
| 99 | |
| 100 | #### 詳細語法 |
| 101 | |
| 102 | **Prompt Block:** |
| 103 | ~~~markdown |
| 104 | ```prompt [label="安裝指令"] |
| 105 | npm install -g @fission-ai/openspec@latest |
| 106 | ``` |
| 107 | ~~~ |
| 108 | |
| 109 | - Shell 指令開頭(`npm`, `git`, `docker` 等)→ header 顯示 "Terminal" |
| 110 | - 其他內容 → header 顯示 "Prompt" |
| 111 | |
| 112 | **Flow Steps:** |
| 113 | ```markdown |
| 114 | [flow] |
| 115 | 1. proposal.md — 確認目標與範圍 |
| 116 | 2. design.md — 技術選型與風險評估 |
| 117 | [/flow] |
| 118 | ``` |
| 119 | |
| 120 | **Tags:** |
| 121 | ```markdown |
| 122 | [tags] |
| 123 | - [green] 正面標籤 |
| 124 | - [orange] 警告標籤 |
| 125 | - [purple] 中性標籤 |
| 126 | - [blue] 資訊標籤 |
| 127 | [/tags] |
| 128 | ``` |
| 129 | ⚠️ `- [color] text` 必須放在 `[tags]...[/tags]` 內,獨立使用不會套用顏色。 |
| 130 | |
| 131 | **Summary Grid:** |
| 132 | ```markdown |
| 133 | [summary] |
| 134 | - 🏗️ **標題** | 描述文字 |
| 135 | - ⚙️ **標題** | 描述文字 |
| 136 | [/summary] |
| 137 | ``` |
| 138 | |
| 139 | **Insight Box:** |
| 140 | ```markdown |
| 141 | > **洞察標題** |
| 142 | > 第一段落內容。 |
| 143 | > |
| 144 | > 第二段落內容(空行分隔)。 |
| 145 | ``` |
| 146 | |
| 147 | **獨立圖片:** |
| 148 | ```markdown |
| 149 |  |
| 150 | ``` |
| 151 | - 獨立一行 → 置中顯示,alt 文字自動成為圖說 |
| 152 | - 在段落或列表中使用 → 行內圖片 |
| 153 | |
| 154 | **圖文並排(Image-Text):** |
| 155 | ```markdown |
| 156 | [image-text position="left" width="50"] |
| 157 |  |
| 158 | 這是產品的主要介面,提供了 **直覺式操作** 體驗。 |
| 159 | - 支援拖放操作 |
| 160 | - 即時預覽結果 |
| 161 | [/image-text] |
| 162 | ``` |
| 163 | - `position="left"`(預設):圖片在左、文字在右 |
| 164 | - `position="right"`:圖片在右、文字在左 |
| 165 | - `width="N"` 設定圖片佔比百分比(預設 40),例如 `width="30"` 或 `width="60"` |
| 166 | - 文字區域支援段落、粗體、程式碼、連結、列表 |
| 167 | - 響應式:平板(≤ 900px)及手機自動改為上下排列 |
| 168 | |
| 169 | **YouTube 影片嵌入:** |
| 170 | |
| 171 | 單行: |
| 172 | ```markdown |
| 173 | [youtube id="dQw4w9WgXcQ" title="Demo 影片"] |
| 174 | ``` |
| 175 | |
| 176 | 區塊(含說明文字): |
| 177 | ```markdown |
| 178 | [youtube id="dQw4w9WgXcQ"] |
| 179 | 這是一段示範影片的說明 |
| 180 | [/youtube] |
| 181 | ``` |
| 182 | - `id` 為 YouTube 影片 ID(網址中 `v=` 後面的值) |
| 183 | - `title` 為選填標題,顯示在影片下方 |
| 184 | - 影片以 16:9 比例響應式嵌入 |
| 185 | - 列印模式下顯示 YouTube 連結取代 iframe |
| 186 | |
| 187 | 完整元件對照請參考:[components.md](reference/components.md) |
| 188 | Markdown 範例請參考:[content-example.md](reference/content-example.md) |
| 189 | |
| 190 | ### Step 2:確認或建立課程 Config |
| 191 | |
| 192 | #### 2-0:偵測 GitHub Pages 前綴(必須先執行) |
| 193 | |
| 194 | 在撰寫任何 config 之前,先執行以下指令取得 GitHub Page |