# Novel Writing

> Use when user asks to write a novel (소설 써줘).

- Skill: `wcpaka-lgtm/novel-writing` (Agent Skill)
- Install (CLI): `npx skillmds@latest add wcpaka-lgtm/novel-writing`
- Raw SKILL.md: https://api.skillmd.com/api/skills/wcpaka-lgtm/novel-writing/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: wcpaka-lgtm (https://skillmd.com/u/wcpaka-lgtm)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/wcpaka-lgtm/novel-writing

---


# 소설 집필 스킬 (Novel Writing)

## 트리거
사용자가 소설을 써달라고 요청할 때. 장르·스타일은 매번 달라도 됨.

## 저장 위치 & 폴더 구조
- **저장 경로: `G:/내 드라이브/NAS폴더/NASfolder/Novel/<소설제목>/`**
- 폴더명은 소설 제목만 사용 (예: `천강뇌제`, `기억서점`) — 접두사 없음
- 파일 명명:
  - `00_설계도.md` — 전체 기획안 (5권 구성, 권별 줄거리, 주인공 성장곡선, 무공/능력 체계, 갈등 구조, 클라이맥스 배치)
  - `01_1권_<부제>.md`
  - `02_2권_<부제>.md`
  - `03_3권_<부제>.md`
  - `04_4권_<부제>.md`
  - `05_5권_<부제>.md`
  - `<소설제목>.epub` — 최종 EPUB (아이폰 도서 앱용)

## 분량 기준
- **권당 800~1,100줄 / 25~46KB** (웹소설 단행본 1권 ≈ 8~12만 자 분량)
- 5권 합산 약 170KB 내외
- 한 번에 한 권씩 집필 (write_file → 끊기면 patch로 이어서 완성)
- 각 권 12장 구성 (장당 약 70~90줄)

## 집필 포맷 (장르 불변)
```markdown
# <작품명>(<한자>)

## 제N권: <부제>(<한자>)

---

### 제1장 <장제목>(<한자>)

<본문>

---

### 제2장 ...

...

---

*제N권 끝*
```

## 집필 순서
1. `00_설정집.md` 작성 (아래 "설정집 필수 항목" 참고)
2. 1권 → 5권 순서로 집필
3. 각 권 집필 후 read_file로 끝부분 확인 (정상 종료 여부)
4. 5권 완료 후 EPUB 생성

## 설정집 필수 항목 (00_설정집.md)
- **인물 프로필**: 이름, 나이, 외형, 성격(장점/단점/트라우마), 말버릇, 대사 톤
- **인물 관계도**: 누구와 어떤 관계, 감정선, 갈등 축
- **말투 가이드**: 인물별 대사 예시 3~5줄 (집필 시 이 톤 유지)
- **세계관**: 지리, 세력, 규칙
- **무공/능력 체계**: 단계별 설명
- **권별 감정선**: 액션뿐 아니라 인물 내면 변화, 관계 전환점 명시
- **복선 & 회수 계획**: 어디서 깔고 어디서 회수하는지

## 문체 & 몰입 가이드
- **전개 속도**: 한 장(章)에서 시간 점프 최대 1회. 장면 전환은 인물 감정/행동으로 연결
- **서사 개연성**: 인물의 행동 동기를 반드시 본문에서 보여줄 것. "갑자기 강해짐" 금지
- **대화문**: 인물 성격에 맞는 입체적 대사. 딱딱한 설명체 금지. 구어체, 말버릇, 감정 표현 활용
- **내면 독백**: 주인공 시점에서 감정·고민·판단을 보여줄 것
- **조연 서사**: 조연도 자신만의 동기·감정선을 가짐. 도구적 소모 금지
- **긴장-이완 리듬**: 전투 장면 사이 관계 장면·일상 장면 배치
- 인기 웹소설의 전개 속도·사이다 카타르시스 참고하되 표절 금지
- 한국어 자연스러운 문체

## EPUB 생성 (아이폰 도서 앱용)
5권 완료 후 아래 Python 스크립트로 EPUB 생성:

```python
# pip install ebooklib (없으면 uv pip install ebooklib)
import ebooklib
from ebooklib import epub
import os, re, glob

def create_epub(novel_dir, title, author="Hermes"):
    book = epub.EpubBook()
    book.set_identifier(f"novel-{title}")
    book.set_title(title)
    book.set_language("ko")
    book.add_author(author)
    
    style = '''
    body { font-family: "Apple SD Gothic Neo", "Noto Sans KR", sans-serif; line-height: 1.8; }
    h1 { text-align: center; margin-top: 3em; }
    h2 { text-align: center; color: #333; }
    h3 { margin-top: 2em; border-bottom: 1px solid #ccc; padding-bottom: 0.3em; }
    p { text-indent: 1em; margin: 0.5em 0; }
    hr { border: none; border-top: 1px solid #ddd; margin: 2em 0; }
    '''
    css = epub.EpubItem(uid="style", file_name="style/default.css",
                        media_type="text/css", content=style.encode("utf-8"))
    book.add_item(css)
    
    chapters = []
    toc = []
    md_files = sorted(glob.glob(os.path.join(novel_dir, "0[1-5]_*.md")))
    
    for md_file in md_files:
        with open(md_file, "r", encoding="utf-8") as f:
            content = f.read()
        
        vol_match = re.search(r'^## (.+)$', content, re.MULTILINE)
        vol_title = vol_match.group(1).strip() if vol_match else os.path.basename(md_file)
        
        html_content = f"<h1>{vol_title}</h1>\n"
        sections = re.split(r'^### ', content, flags=re.MULTILINE)
        
        for section in sections[1:]:
            lines = section.strip().split('\n')
            ch_title = lines[0].strip()
            body = '\n'.join(lines[1:])
            body = re.sub(r'^---$', '<hr/>', body, flags=re.MULTILINE)
            body = re.sub(r'^\*(.+)\*$', r'<p><em>\1</em></p>', body, flags=re.MULTILINE)
            paragraphs = []
            for line in body.split('\n'):
                line = line.strip()
                if not line:
                    continue
                if line.startswith('<'):
                    paragraphs.append(line)
                else:
                    paragraphs.append(f"<p>{line}</p>")
            ch_html = f"<h3>{ch_title}</h3>\n" + '\n'.join(paragraphs)
            html_content += ch_html
        
        ch_file = epub.EpubHtml(
            title=vol_title,
            file_name=os.path.basename(md_file).replace('.md', '.xhtml'),
            lang="ko"
        )
        ch_file.content = html_content.encode("utf-8")
        ch_file.add_item(css)
        book.add_item(ch_file)
        chapters.append(ch_file)
        toc.append(ch_file)
    
    book.toc = toc
    book.add_item(epub.EpubNcx())
    book.add_item(epub.EpubNav())
    book.spine = ["nav"] + chapters
    
    output_path = os.path.join(novel_dir, f"{title}.epub")
    epub.write_epub(output_path, book)
    return output_path
```

- 출력: `G:/내 드라이브/NAS폴더/NASfolder/Novel/<제목>/<제목>.epub`
- 아이폰 전송: NAS 폴더를 iCloud Drive에 동기화하거나, iTunes/Finder 도서 동기화

## 피트폴
- write_file이 15KB 근처에서 끊길 수 있음 → 반드시 read_file로 끝 확인, patch로 이어서 작성
- search_files로 한글 폴더명 검색 안 될 수 있음 → terminal `ls` 사용
- ebooklib 미설치 시: `uv pip install ebooklib` 또는 `pip install ebooklib`
- EPUB 생성 후 파일 존재 여부 반드시 확인

## 검증
- [ ] 5개 md 파일 모두 `*제N권 끝*`으로 종료
- [ ] EPUB 파일 생성됨
- [ ] EPUB 파일 크기 > 0

