# Ebook

> สร้าง ebook เชิงลึกภาษาไทยแบบครบวงจร จากหัวข้อเดียว — research → master brief + โครงบท → เขียนบทขนานด้วย writer subagents → เจนปก+ภาพประกอบการ์ตูนผ่าน chatgpt-bridge → บีบภาพ → build เป็น PDF+EPUB+HTML (pandoc + ฟอนต์ Sarabun + Chromium print) → ตรวจด้วยภาพหน้าจอ → ส่งออกพร้อมอัปขึ้นร้าน/เว็บของคุณเอง. Trigger เมื่อผู้ใช้พิมพ์ /ebook หรือขอ "ทำ ebook / เขียนหนังสือ / สร้าง ebook / ปั้นหนังสือขาย / คู่มือ PDF เล่มยาว".

- Skill: `ksmaster03/ebook` (Agent Skill, multi-file: 10 files)
- Install (CLI): `npx skillmds@latest add ksmaster03/ebook`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ksmaster03/ebook/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: ksmaster03 (https://skillmd.com/u/ksmaster03)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/ksmaster03/ebook

---


# /ebook — โรงงานปั้น ebook (ไทย, เชิงลึก, ครบตั้งแต่เขียนยันขึ้นเว็บ)

Pipeline ที่พิสูจน์แล้วหลายเล่ม — ล่าสุด **"สแกนแล้วจบ"** (14 บท, `$WORK/warehouse-handheld-ebook`, 2026-07-28) และ **"หยุดนิ้ว"** (12 บท, `$WORK/shortform-ebook`) ทำงานบน T14 ของ <your-github-user>

คุย/เคาะ **ชื่อเล่ม + ขอบเขต + ปลายทางอัปโหลด** เป็นภาษาไทยก่อนเสมอ; autonomous ได้หลังเคาะโครง

## ถามผู้ใช้ก่อนเริ่ม (ใช้ AskUserQuestion รวบเป็นชุดเดียว)
1. **ขอบเขต/ความหนา** — จำนวนบท (ดีฟอลต์ 12; 14 ถ้าต้องครอบคลุมผู้อ่าน 2 กลุ่ม), ภาษา (ดีฟอลต์ไทยล้วน)
2. **กลุ่มเป้าหมาย** — ถ้ามี 2 กลุ่ม (เช่น dev + ผู้บริหาร) ต้องบังคับให้ทุกบทมีหัวข้อ `### มุม<กลุ่มที่สอง>` ไม่งั้นเล่มจะเอียงไปทางเดียว
3. **ปลายทาง** — ไฟล์เฉย ๆ หรืออัปขึ้นร้าน/เว็บของคุณเอง (ดูหัวข้อ Upload ท้ายไฟล์)
3.5 **เครดิตผู้เขียน** — ถามชื่อผู้เขียน/แบรนด์ที่จะขึ้นบนเล่ม → ไปลง `CREDIT` ใน build-book.mjs ซึ่งโผล่ 4 จุดตามหัวข้อ "เครดิตผู้เขียน" ด้านล่าง
4. ถ้าเป็นหนังสือเทคนิคที่มีหลาย stack — **เลือกข้างหรือวางคู่กันทุกบท** (คำตอบนี้เปลี่ยนโครงบททั้งเล่ม)

## โครงโปรเจกต์
```
$WORK/<slug>-ebook/
  BRIEF.md            # แหล่งความจริงเดียว: ตัวตนเล่ม + โทน + คลังข้อเท็จจริง + โครงบทละเอียด
  raw/chNN.md         # หนึ่งไฟล์ต่อบท (บรรทัดแรก = "# ชื่อบท")
  images/cover.png + chNN.png   # ผลจาก chatgpt-bridge
  images/*.jpg        # เวอร์ชันบีบแล้ว (build ใช้ตัวนี้ก่อน)
  prompts.json        # [{ "id":"cover|chNN", "prompt":"..." }]
  fonts/Sarabun-*.ttf # ฟอนต์หนังสือไทย
  build-book.mjs      # ประกอบ → dist/*.html/.pdf/.epub
  dist/               # ผลลัพธ์ 3 ฟอร์แมต
  UPLOAD.md           # คู่มืออัปขึ้นร้านของเล่มนี้
```

## 8 ขั้น

### 1. Research
WebSearch (TH+EN) 8–12 คิวรีแบบขนาน (ยิงทีละ 4 ใน message เดียว) + ดึงจาก memory/skill ที่เกี่ยว
เก็บทุกอย่างลง "คลังข้อเท็จจริง" ของ BRIEF พร้อม **ชื่อแหล่ง** — **ห้ามแต่งสถิติ**
ถ้าตัวเลขจากหลายแหล่งขัดกัน (เช่น อัตราความแม่นของ barcode) → บันทึกเป็น *ช่วง* + สั่ง writer ให้เขียนว่า "ตัวเลขฝั่งผู้ขายต่างกันมาก" แทนการฟันธง

### 2. เขียน BRIEF.md
คัดโครงจาก `templates/BRIEF_TEMPLATE.md` ต้องมีครบ:
- ตัวตนเล่ม (ชื่อ/ชื่อรอง/กลุ่มเป้าหมาย/สัญญาของหนังสือ)
- **กฎโทน** + ความยาวต่อบท + องค์ประกอบบังคับ (`### มุม...`, ❌/✅, `> **จำ 3 ข้อ**`)
- **รูปแบบไฟล์** (บรรทัดแรก = ชื่อบท, ห้ามใส่ภาพเอง, code fence ระบุภาษา, UTF-8)
- **คลังข้อเท็จจริง** แยกหมวด A/B/C… ให้ writer อ้างได้ตรง ๆ
- **หมวด "ข้อความที่ห้ามผิด"** — ดักความเข้าใจผิดเฉพาะโดเมน (เช่น "SE4710/SE55 เป็น imager ไม่ใช่เลเซอร์", "ห้ามใส่ราคาเครื่อง")
- **โครงบทละเอียด** ระบุต่อบทว่าต้องมีอะไร + บทไหนหนาพิเศษ
- ถ้าเล่มมีหัวข้อ "แหล่งอ้างอิง" ท้ายเล่ม → ใส่รายการเต็มไว้ใน BRIEF แล้วสั่ง writer บทสุดท้ายให้ **คัดลอกมาทั้งหมด ห้ามเพิ่ม/ตัด**

### 3. เขียนบทขนานด้วย writer subagents
- `general-purpose`, `model: sonnet`, รันพร้อมกันใน message เดียว
- **≤3 บทต่อ agent** — เกินกว่านั้นมักโดน watchdog ตัดที่ 600s (ดู Gotcha 3)
- ทุก prompt สั่ง: อ่าน `BRIEF.md` ให้จบก่อน → **Write ลง `raw/chNN.md` โดยตรง** → ตอบกลับสั้น ๆ แค่จำนวนคำ **ห้าม paste เนื้อหากลับ**
- ย้ำกฎบังคับซ้ำใน prompt ทุกข้อ (อย่าอ้างว่า "ตาม BRIEF" อย่างเดียว) — โดยเฉพาะ "ห้ามแต่งสถิติ/URL"

### 4. QC บทด้วยสคริปต์ (ก่อนเสียเวลา build)
```bash
bash ~/.claude/skills/ebook/scripts/qc-chapters.sh <proj>
```
เช็ก: บรรทัดแรกเป็น `# `, มี code fence ทั้งสอง stack, มีหัวข้อ `### มุม`, มี `จำ 3 ข้อ`, ไม่มี `![`, ไม่มีราคาเงิน, ไม่มี URL แปลกปลอมนอกบทอ้างอิง
บทไหนขาด → SendMessage กลับไปที่ agent เดิม หรือ spawn ตัวใหม่เฉพาะบทนั้น

### 4.5 ปรับภาษาให้เป็นมนุษย์ (ห้ามข้าม — นี่คือสิ่งที่แยกเล่มที่ขายได้ออกจากเล่มที่ "อ่านรู้เลยว่า AI เขียน")
อ่าน **`references/human-voice-th.md`** แล้วรันตามนั้น สาระสำคัญ:
- ปัญหาไม่ใช่คำศัพท์ แต่คือ **จังหวะสม่ำเสมอเกินไป** — ย่อหน้ายาวเท่ากันหมด ทุกหัวข้อมีสามข้อย่อย ทุกย่อหน้าขึ้นด้วยประโยคใจความ
- ใส่ตัวเชื่อมภาษาพูด 15–29 จุด/บท (เกิน 30 = เลี่ยน) **สามคำที่ให้ผลเร็วที่สุดคือ `ดังนั้น` `แบบนี้` `หรือเปล่า`** ตามด้วย `จริง ๆ แล้ว` `คือว่า` `ทีนี้` `เอาจริง ๆ` `พูดง่าย ๆ ก็คือ` (สลับกัน อย่าใช้ตัวเดียวรัว)
- `เอ่อ` / `เอิ่ม` ใช้ได้แต่ **ไม่เกิน 1–2 ครั้งต่อบท** เกินกว่านั้นอ่านเหมือนถอดเทป
- **⚠ ขีดยาว ` — ` ห้ามเกิน 10 จุด/บท (บทยาว 40KB+ ไม่เกิน 12)** — นี่คือกับดักที่พลาดมาแล้ว 2 รอบ: บอกให้ "แทรกความคิดด้วยขีดยาว" แล้ว agent ใส่จนได้ 31–76 จุด/บท กลายเป็นลายเซ็น AI ที่ชัดกว่าคำศัพท์ใด ๆ **วิธีแทนที่ดีที่สุดคือตัดเป็นสองประโยค** รองลงมาคือ `ดังนั้น` `เพราะว่า` `ก็คือ` `นั่นคือ` `ซึ่ง` หรือวงเล็บ (ดู `references/human-voice-th.md` ข้อ 3.5)
- **รูปทรงย่อหน้า** — ย่อหน้าปกติ 2–6 บรรทัด · ประโยคห้วนที่ยืนเป็นย่อหน้าเดี่ยวได้ **ไม่เกิน 2 จุด/บท** ที่เหลือกลืนเข้าย่อหน้าก่อนหน้า · ห้ามให้หัวข้อตามด้วยย่อหน้า 1 บรรทัดแล้วขึ้นหัวข้อใหม่ (ข้อ 3.6)
- สลับความยาวประโยค + ถามผู้อ่าน (10–20 จุด/บท ปิดด้วย `หรือเปล่า` บ้าง) + เล่าฉากสมมติสั้น ๆ
- ล่าลายเซ็น AI ให้หมด: `สิ่งสำคัญคือ` `โดยสรุปแล้ว` `ไม่ว่าจะเป็น...หรือ...` `ในยุคที่` `อย่างไรก็ตาม` ทุกย่อหน้า
- **ห้ามแตะ:** ตัวเลข ข้อเท็จจริง ชื่อแหล่ง ตาราง บล็อกโค้ด prompt template บรรทัดแรก `# ชื่อบท` และรายการอ้างอิงท้ายเล่ม (ขีดยาวในสามอย่างหลังไม่ต้องนับและห้ามแก้)
- **1 บท = 1 subagent** (3 บทชนกำแพง 600 วิ) · สั่งว่า **ห้ามลดความยาว** · หลังรันต้อง**เทียบขนาดไฟล์ก่อน/หลัง** แล้วรัน `qc-chapters.sh` ซ้ำ (agent เผลอตัดตารางบ่อย)
- **วัดผลด้วย `scripts/check-voice.sh <proj>`** — นับตัวเชื่อม 21 คำ + `เอ่อ/เอิ่ม` + คำถาม + ขีดยาว ต่อบท แล้วบอกว่าบทไหนตก (ตกได้ทั้งจาก "ตัวเชื่อมน้อยไป" และ **"ขีดยาวเยอะไป"**)
- **บทเรียนสำคัญ: สั่งเป็นยอดรวมอย่างเดียวไม่พอ** — จากรอบจริงมีแค่ 1 ใน 3 บทที่ถึงเป้า agent ที่เหลือตีความว่า "แตะเบา ๆ" ต้องสั่งเป็น **จำนวนขั้นต่ำรายคำ** (`จริง ๆ แล้ว` ≥4, `ดังนั้น` ≥4, `แบบนี้/แบบนั้น` ≥4, `หรือเปล่า` ≥3, `คือว่า` ≥3, `ทีนี้` ≥3, `เอาจริง ๆ` ≥2, `เอ่อ/เอิ่ม` ≥1) **บวกเพดานขีดยาวเป็นตัวเลขชัด ๆ** และ**ให้ agent รัน `check-voice.sh` เองก่อนส่งงาน** ถ้ายังไม่ผ่านให้แก้แล้ววัดซ้ำ
- **ทำขั้นนี้ให้ครบทั้ง 3 อย่างในรอบเดียว** (ตัวเชื่อม + ลดขีดยาว + รูปทรงย่อหน้า) อย่าแยกเป็นสองรอบ เพราะรอบสองต้องอ่านไฟล์ใหม่ทั้งไฟล์อีกครั้ง เสียเวลาเป็นเท่าตัว

### 5. ภาพ (chatgpt-bridge)
เขียน `prompts.json`: `cover` (แนวตั้ง เว้นที่หัว-ท้ายไว้ใส่ชื่อเรื่อง) + `chNN` (แนวนอน)
ทุก prompt ขึ้นด้วย **style prefix เดียวกันทั้งเล่ม** และปิดท้ายด้วย
`NO text, no words, no letters, no numbers, no logos, no brand marks`
```bash
cd /d/Project/chatgpt-bridge
node chatgpt-batch.mjs <proj>/prompts.json <proj>/images
```
~1–2 นาที/รูป (รูปแรกนานกว่าเพราะเปิด browser + เช็ก session) → 15 รูป ≈ 20–30 นาที รันเป็น background task
**ล้มบางรูปเป็นเรื่องปกติ** → รันซ้ำเฉพาะที่ขาด:
```bash
node ~/.claude/skills/ebook/scripts/missing-images.mjs <proj>   # เขียน prompts-missing.json
cd /d/Project/chatgpt-bridge && node chatgpt-batch.mjs <proj>/prompts-missing.json <proj>/images
```
วนจนครบ (เล่มล่าสุดใช้ 3 รอบ)

### 6. บีบภาพ (ขั้นที่ห้ามข้าม)
PNG จาก chatgpt-bridge ~1.5–2.3MB/รูป → PDF บวมเป็น **43MB**
```bash
python ~/.claude/skills/ebook/scripts/optimize-images.py <proj>
```
แปลงเป็น JPEG (กว้างสุด 1500px ภาพบท / 1200px ปก, quality 82) → **PDF เหลือ ~4MB** โดยตาแทบไม่เห็นต่าง
`build-book.mjs` เลือก `.jpg` ก่อน `.png` อัตโนมัติ

### 7. Build
```bash
cd <proj> && node build-book.mjs
```
→ `dist/<slug>.html` (self-contained) · `.pdf` (Chromium) · `.epub` (pandoc)
build ทนไฟล์หาย — บทที่ยังไม่มีจะข้าม ภาพที่ยังไม่มีก็ข้าม → **build ทดสอบได้ตั้งแต่ยังเขียนไม่ครบ** (แนะนำให้ build ครั้งหนึ่งทันทีที่ pipeline พร้อม เพื่อจับปัญหา pandoc/Chromium แต่เนิ่น ๆ)

### 7.5 ใส่ชื่อเรื่องลงบนปก (ทำก่อนอัปขึ้นร้าน)
ปกที่เจนมาไม่มีตัวอักษร (สั่ง "NO text" ไว้) — การ์ดในร้านจะดูจืดกว่าเล่มที่มีชื่อเรื่องบนปก
**ห้ามให้โมเดลภาพเขียนไทย** ให้เอาชื่อเรื่องมาทับทีหลังด้วย Chromium (shape ไทยถูกต้อง เหตุผลเดียวกับ PDF):
```bash
cp ~/.claude/skills/ebook/scripts/cover-title.mjs /d/Project/chatgpt-bridge/
cd /d/Project/chatgpt-bridge && node cover-title.mjs <covers.json>
```
`covers.json` = array ของ `{image, out, fontsDir, kicker, title[], subtitle, footer, accent, scrim}` (ดูหัวไฟล์สคริปต์)
เคล็ด: ชื่อบนปกต้อง **สั้นกว่าชื่อเต็มในร้าน** (2 บรรทัด) + kicker `E-BOOK 2026 · N บท` + คำโปรย + แถบล่างบอก stack
**ปกในร้านควรเป็น JPEG ~200–300KB** — PNG 1.8MB ทำให้หน้า /ebooks โหลดช้า

### 8. ตรวจด้วยตา + ส่งมอบ
```bash
cp ~/.claude/skills/ebook/scripts/shot-book.mjs /d/Project/chatgpt-bridge/
cd /d/Project/chatgpt-bridge
node shot-book.mjs "file:///$WORK/<proj>/dist/<slug>.html" <out>.png [scrollY]
```
ดูอย่างน้อย 3 จุด: ปก, สารบัญ+หัวบทแรก, บทที่มีตาราง/โค้ดเยอะ
นับหน้า PDF: `python -c "import re;d=open('dist/x.pdf','rb').read();print(len(re.findall(rb'/Type\s*/Page[^s]',d)))"`
แล้วเขียน `UPLOAD.md` ของเล่มนั้น + สรุปให้ผู้ใช้พร้อม path

## Build รายละเอียด (templates/build-book.mjs)
- ฝังฟอนต์ Sarabun (Regular/Medium/SemiBold/Bold/ExtraBold) เป็น base64 `@font-face` → ไทยคมทุกเครื่อง; ฝังภาพ base64 → ไฟล์เดียวจบ
- HTML: แถบเครดิต `.bookbar` ด้านบน + ปก gradient + สารบัญ + บททั้งหมด (แต่ละบทขึ้นหน้าใหม่ตอนพิมพ์) + `.bookfoot` ปิดท้าย, รองรับ light/dark
- PDF: render HTML เดียวกันด้วย Chromium (`page.pdf` A4, `@media print` คุม page-break, **header + footer เป็นเครดิตในขอบกระดาษ**) — **Chromium shape ไทยดีสุดบน Windows** (ไม่ต้อง xelatex/wkhtmltopdf)
- EPUB: `pandoc book.md --toc --epub-embed-font --epub-cover-image` — **cover ต้องเลือกด้วย `pickImg('cover')` ไม่ใช่ hardcode `cover.png`** ไม่งั้นพอลบ PNG ทิ้งแล้ว EPUB จะไม่มีปก
- แก้ค่าคงที่หัวไฟล์ให้ครบทุกครั้ง: `DIR / SLUG / TITLE / SUB1 / SUB2 / AUTHOR / CREDIT / CHAPTERS.length` + สีใน `:root`

### เครดิตผู้เขียน (ถามผู้ใช้ตอนเริ่ม แล้วใส่ให้ครบ 4 จุด)
ค่าคงที่ `CREDIT` (ตั้งจากคำตอบของผู้ใช้) ต้องโผล่ที่:
1. **แถบบนของ HTML** — `.bookbar` แบบ sticky (ซ่อนตอนพิมพ์ด้วย `.bookbar{display:none}` ใน `@media print`)
2. **footer ปิดเล่มของ HTML** — `.bookfoot`
3. **header ของทุกหน้า PDF** — ส่งเป็นอาร์กิวเมนต์ที่ 4 ของ `print_pdf.mjs`
4. **footer ของทุกหน้า PDF** — อาร์กิวเมนต์ที่ 3
```js
await pexec('node', ['$CHATGPT_BRIDGE/print_pdf.mjs', fileUrl, pdfOut,
  `${TITLE} · ${CREDIT}`, CREDIT]);
```
`print_pdf.mjs` รับ header เป็นอาร์กิวเมนต์ที่ 4 (ไม่ใส่ = ไม่มี header เหมือนเดิม)

### คุมย่อหน้าไม่ให้ตกหน้า (ต้องมีทุกเล่ม)
ใน `@media print`:
```css
p,li{orphans:3;widows:3;}
h2,h3{page-break-after:avoid;}
pre,table,blockquote,.chapimg{page-break-inside:avoid;}
```
- **ต้องมี**: pandoc ใน PATH, playwright + chromium ที่ `$CHATGPT_BRIDGE`
- โหลดฟอนต์ครั้งแรก: `curl -sL -o fonts/Sarabun-<W>.ttf https://github.com/google/fonts/raw/main/ofl/sarabun/Sarabun-<W>.ttf` (W = Regular/Medium/SemiBold/Bold/ExtraBold) — เก็บสำเนาไว้ reuse ข้ามเล่มได้

## Upload → ร้าน/เว็บของคุณ

สกิลนี้จบที่ **ไฟล์** (`dist/<slug>.pdf` + `.epub` + `.html`) — ขั้นอัปขึ้นร้านขึ้นกับระบบของแต่ละคน จึงไม่ผูกไว้ในสกิล

สิ่งที่ควรเตรียมไว้ ไม่ว่าจะใช้ร้านไหน:
- **ปกแยกไฟล์** — `images/cover.jpg` (มีตัวอักษรแล้ว) ใช้เป็น thumbnail
- **ไฟล์เดียวต่อเล่ม** — ถ้าจะแจกทั้ง PDF+EPUB ให้ zip รวมก่อน (ร้านส่วนใหญ่ผูกได้ไฟล์เดียว)
- **ไฟล์ private + presigned URL** — อย่าวาง PDF ไว้บน public bucket ถ้าตั้งใจจะขาย
- **สคริปต์อัปซ้ำได้** — ทำเป็น `upload-to-store.sh` ของโปรเจกต์ แล้วแก้แค่ SLUG/TITLE/DESC/PRICE ต่อเล่ม

⚠️ ถ้าปลายทางคือ production: **ต้องมีคำสั่งเป็นข้อความจากผู้ใช้ก่อนเขียน production** — คำตอบใน AskUserQuestion ไม่นับ (classifier อ่านเฉพาะ user text turn) และ **ห้ามใส่คำสั่งเขียน prod ไว้ใน prompt ของ subagent** (โดนบล็อก) ให้เขียนสคริปต์ก่อน แล้วสั่ง subagent ว่า "รันสคริปต์นี้แล้วตรวจผล"

## Gotchas (จ่ายด้วยเลือดมาแล้ว)
1. **ฟอนต์ไทยใน PDF** — อย่าใช้ pandoc→LaTeX (ไม่มี xelatex + ไทยพัง) ใช้ Chromium print จาก HTML ที่ฝัง Sarabun
2. **writer subagent ต้องเขียนลงไฟล์เอง** ไม่ paste กลับ ไม่งั้น context main พัง
3. **watchdog 600s** — agent ที่เขียน 4 บทรวดมักถูกตัดกลางทางพร้อมสถานะ failed **แต่ไฟล์ที่เขียนไปแล้วยังอยู่ครบ** → อย่าตกใจ ให้ `ls raw/` แล้ว spawn ตัวใหม่เฉพาะบทที่ขาด (1–2 บท/agent)
4. **`npx playwright install chromium`** — เครื่องนี้เคยอัปเดต playwright แล้ว browser หาย ทำให้ทั้งการเจนภาพ **และการพิมพ์ PDF** ล้มพร้อมกัน เช็กก่อนเริ่ม: `ls ~/AppData/Local/ms-playwright/`
5. **chatgpt-batch ล้มเป็นชุดเมื่อเน็ตสะดุด** (`ERR_NAME_NOT_RESOLVED`, `Navigation ... interrupted`) — session ยังดีอยู่ แค่รันซ้ำเฉพาะที่ขาด อย่าเพิ่งเปลี่ยนไป fallback
6. **PNG → PDF บวม 10 เท่า** — ต้องบีบเป็น JPEG ก่อน build เสมอ (ขั้น 6)
7. **ภาพสั่ง "NO text"** เสมอ + style prefix เดียวกันทุกภาพให้ดูเป็นเล่มเดียว (โมเดลเขียนไทยเพี้ยนทุกครั้ง)
8. **อย่าไล่ `sleep` ใน Bash เพื่อ poll** — โดนบล็อก ให้ใช้ `run_in_background` แล้วรอ notification
9. **สคริปต์ที่ `import playwright` ต้องวางในโฟลเดอร์ `$CHATGPT_BRIDGE`** (node_modules อยู่ที่นั่น) รันจาก `/tmp` จะ `ERR_MODULE_NOT_FOUND`
10. **pandoc fence** — ใช้ `-f markdown-tex_math_dollars` กันสูตร `$...$` กินเนื้อหา; `--no-highlight` แล้วจัดสีเองด้วย CSS
11. build อ่านชื่อบทจาก **บรรทัดแรก** ของ chNN.md → บรรทัดแรกต้องเป็นชื่อบทจริง
12. ไฟล์ .md ต้อง UTF-8; slug ต้อง unique ในร้าน ตรวจก่อนสร้าง (`curl -s .../ebooks | grep -o '/ebooks/[a-z0-9-]*' | sort -u`)
16. **`optimize-images.py` จะเขียนทับปกที่ใส่ชื่อเรื่องแล้ว** ถ้ายังมี `images/cover.png` อยู่ (มันแปลง PNG → JPG ทับ) → **หลังทำขั้น 7.5 เสร็จ ให้ `rm images/cover.png` ทิ้ง** และถ้าเผลอรันทับไปแล้วก็แค่รัน `cover-title.mjs` ซ้ำ (ต้นฉบับเปล่าถูกสำรองไว้ที่ `cover-plain.jpg` อัตโนมัติ)
17. **กล่อง `> **จำ 3 ข้อ**` ต้องมีบรรทัด `>` ว่างคั่นก่อน `> 1.`** ไม่งั้น pandoc มองเป็น lazy continuation แล้วเรนเดอร์สามข้อรวมเป็นย่อหน้าเดียว ไม่ใช่ ordered list
    **ตรวจก่อนว่าต้องซ่อมจริงไหม** (ถ้า BRIEF สั่งรูปแบบไว้ตั้งแต่แรก writer มักทำถูกอยู่แล้ว):
    ```bash
    grep -A1 'จำ 3 ข้อ' raw/ch*.md | grep -c '^\S*-> *1\.'   # 0 = ไม่ต้องซ่อม
    ```
    ถ้าต้องซ่อมจริง ใช้สคริปต์นี้เท่านั้น:
    ```bash
    python - <<'PY'
    import io, re, glob
    pat = re.compile(r'(>\s*\*\*จำ 3 ข้อ\*\*[^\n]*)\n(>\s*1\.)')
    for p in glob.glob('raw/ch*.md'):
        s = io.open(p, encoding='utf-8').read()
        if not s.strip():          # กันเขียนทับไฟล์ที่อ่านไม่ได้/ว่าง
            print('SKIP empty', p); continue
        new = pat.sub(r'\1\n>\n\2', s)
        if new != s:
            io.open(p, 'w', encoding='utf-8').write(new); print('FIXED', p)
    PY
    ```
    ‼ **ห้ามใช้ one-liner แบบ `io.open(p,'w',...).write(io.open(p).read())` เด็ดขาด** — Python evaluate `io.open(p,'w')` **ก่อน** อาร์กิวเมนต์ ไฟล์จึงถูก truncate เป็น 0 ไบต์ แล้วอ่านได้ค่าว่าง สุดท้ายเขียนค่าว่างทับ **เคสจริง: ล้างเนื้อหาทั้ง 16 บทหายเกลี้ยงหลังเขียนเสร็จแล้ว กู้ไม่ได้** กฎเดียวกันนี้ใช้กับ one-liner อ่าน-เขียนไฟล์เดิมทุกอัน ให้อ่านให้จบก่อนเสมอ แล้วค่อยเปิดเขียน
19. **สำรอง `raw/` ก่อนรันสคริปต์ใด ๆ ที่เขียนทับบททั้งชุด** ต้นทุนแค่วินาทีเดียว แต่กันงานทั้งวันหาย:
    ```bash
    cp -r raw raw.bak && echo ok
    ```
18. **ห้ามมี backtick ในบรรทัดแรกของบท** — build เอาบรรทัดแรกไปทำสารบัญแบบ plain text จะเห็น `` ` `` ติดมาโต้ง ๆ
13. **ตรวจปกในร้านด้วย GET ไม่ใช่ HEAD** — `/api/ebooks/<id>/cover` ตอบ 307 ไป presigned S3 ที่เซ็นไว้เฉพาะ GET, `curl -I` จะได้ 403 ทั้งที่รูปปกติ
15. **ขั้นปรับภาษา (4.5) ทำไฟล์หดได้** — agent ที่สั่งให้ "เขียนใหม่ให้เป็นธรรมชาติ" มักย่อเนื้อหาไปด้วยโดยไม่ตั้งใจ (เจอเคสหด 30%) ต้องสั่งห้ามลดความยาวให้ชัด แล้ว**เทียบขนาดไฟล์ก่อน/หลังทุกบท** ถ้าหดเกิน 5% ให้สั่งเขียนใหม่เฉพาะบทนั้น
14. **agent นับ "จำนวนคำ" ภาษาไทยไม่ได้** (รายงาน 662 คำ ทั้งที่ไฟล์ 33KB) — ตัดสินความยาวจาก **ขนาดไฟล์ ~20–35KB/บท**

## ปรับที่ผู้ใช้ขอบ่อย
เพิ่ม/ลดบท (แก้ BRIEF + `CHAPTERS.length`), เปลี่ยนสไตล์ภาพ (prefix ใน prompts.json), เปลี่ยนสี/ฟอนต์ปก (`:root` + `.cover` ใน build-book.mjs), ทำ .docx ด้วย (pandoc + reference.docx สไตล์ `$WORK/notebooklm-bridge/ebook`)

## ไฟล์ในสกิลนี้
| ไฟล์ | ใช้ทำอะไร |
|---|---|
| `references/human-voice-th.md` | เทคนิคปรับภาษาไทยให้เหมือนคนเขียน + คลังตัวเชื่อม + โควตาต่อบท + ลายเซ็น AI ที่ต้องล่า (ขั้น 4.5) |
| `scripts/check-voice.sh` | วัดความเป็นมนุษย์ต่อบท (ตัวเชื่อม/เอ่อ/คำถาม/ขีดยาว) → ชี้บทที่ต้องรอบสอง (ขั้น 4.5) |
| `templates/BRIEF_TEMPLATE.md` | โครง BRIEF |
| `templates/build-book.mjs` | ตัว build (คัดลอกไปโปรเจกต์แล้วแก้ค่าคงที่หัวไฟล์) |
| `scripts/qc-chapters.sh` | ตรวจโครงสร้างบททุกบท (ขั้น 4) |
| `scripts/missing-images.mjs` | สร้าง prompts-missing.json จากภาพที่ยังไม่มี (ขั้น 5) |
| `scripts/optimize-images.py` | PNG → JPEG บีบขนาด (ขั้น 6) |
| `scripts/cover-title.mjs` | วางชื่อเรื่องไทยลงบนปกด้วย Chromium (ขั้น 7.5) |
| `scripts/shot-book.mjs` | screenshot HTML ที่ build แล้ว (ขั้น 8) |

เกี่ยวข้อง: (เล่มล่าสุด), (ร้าน),, vidcraft

