hwpforge 0.2.1

Programmatic control of Korean HWP/HWPX documents — read, write, and convert Hancom 한글 files
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
# HwpForge 🔥

> **Rust로 한글(HWP/HWPX) 문서를 프로그래밍 방식으로 제어**
>
> [Hancom]https://www.hancom.com/ 한글 파일 읽기, 쓰기, 변환

<div align="center">

![CI](https://img.shields.io/github/actions/workflow/status/ai-screams/HwpForge/ci.yml?branch=main\&label=CI\&logo=github)
![codecov](https://img.shields.io/badge/coverage-92.65%25-brightgreen.svg?logo=codecov)
![Tests](https://img.shields.io/badge/tests-1%2C645_passed-success.svg?logo=checkmarx)
![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg?logo=rust)
![Lines of Code](https://img.shields.io/badge/LOC-~54%2C100-informational.svg)

![crates.io](https://img.shields.io/crates/v/hwpforge.svg?logo=rust)
![docs.rs](https://img.shields.io/docsrs/hwpforge?logo=docs.rs)
![crates.io downloads](https://img.shields.io/crates/d/hwpforge.svg?label=downloads\&logo=rust\&color=orange)
![MSRV](https://img.shields.io/badge/MSRV-1.88+-orange.svg?logo=rust)
![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg)

![MCP Ready](https://img.shields.io/badge/MCP-ready-blueviolet.svg?logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTEyIDJMMiA3bDEwIDVMMjIgN3oiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTIgMTdsMTAgNSAxMC01IiBmaWxsPSJ3aGl0ZSIgb3BhY2l0eT0iMC43Ii8+PHBhdGggZD0iTTIgMTJsMTAgNSAxMC01IiBmaWxsPSJ3aGl0ZSIgb3BhY2l0eT0iMC44NSIvPjwvc3ZnPg==)
![GitHub release](https://img.shields.io/github/v/release/ai-screams/HwpForge?logo=github\&color=green)
![GitHub last commit](https://img.shields.io/github/last-commit/ai-screams/HwpForge?logo=github)
![GitHub stars](https://img.shields.io/github/stars/ai-screams/HwpForge?style=social)

![Security Policy](https://img.shields.io/badge/security-policy-blueviolet.svg?logo=githubactions)
![Contributing](https://img.shields.io/badge/contributing-guide-blue.svg?logo=handshake)
![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?logo=github)
![Made in Korea](https://img.shields.io/badge/made_in-Korea_🇰🇷-red.svg)
![Buy Me a Coffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-support-yellow.svg?logo=buy-me-a-coffee\&logoColor=white)

</div>

<div align="center">
<img src="https://raw.githubusercontent.com/ai-screams/HwpForge/main/assets/banner-main.png" alt="HwpForge Banner" width="600">
</div>

---

## HwpForge란?

HwpForge는 HWPX 문서(ZIP + XML, KS X 6101)를 다루기 위한 **오픈소스** 순수 Rust 라이브러리입니다. 한국에서 가장 많이 사용되는 워드프로세서인 [Hancom 한글](https://www.hancom.com)의 최신 포맷을 지원합니다.

### 지원 버전

| 한글 버전         | 포맷         | 읽기 | 쓰기 | 스타일 세트                    |
| ----------------- | ------------ | ---- | ---- | ------------------------------ |
| 한글 2014 \~ 2020 | HWPX (.hwpx) ||| Classic (18 styles)            |
| 한글 2022 \~ 2024 | HWPX (.hwpx) ||| Modern (22 styles, **기본값**) |
| 한글 2025+        | HWPX (.hwpx) ||| Latest (23 styles)             |
| 한글 97 \~ 2010   | HWP5 (.hwp)  ||||

- **HWPX**: OWPML 국가표준 (KS X 6101) 기반, ZIP + XML 컨테이너
- **HWP5**: 구형 바이너리 포맷. 현재는 CLI 중심의 읽기/점검/재출력 경로를 제공합니다 (`convert-hwp5`, `audit-hwp5`, `census-hwp5`)
- 스타일 세트는 `HancomStyleSet` enum으로 선택 가능 (기본: Modern)

**LLM-first 설계** 🔥 — AI 친화적인 Markdown과 공식 한글 문서 포맷(HWPX), 두 세계를 자연스럽게 잇습니다. LLM이 Markdown으로 작성한 내용은 공문서 규격의 HWPX로 컴파일되고 📜, 반대로 기존 HWPX 문서는 AI가 쉽게 읽을 수 있는 구조로 꺼낼 수 있습니다 ⚒️.

- **📄&#x20;**&#x20;[**HWPX 완전 가이드 다운로드**]examples/hwpx_complete_guide.hwpx — HwpForge API로 생성한 4섹션 데모 문서 (한글에서 열어보세요)
- **HWPX Reader for AI** — 기존 한글 문서(.hwpx)를 Markdown으로 변환하여 LLM이 즉시 이해 가능
- **Full HWPX codec** — HWPX 파일을 손실 없이 디코딩/인코딩 (lossless roundtrip)
- **Markdown bridge** — GFM Markdown과 HWPX 간 양방향 변환 (읽기 + 쓰기)
- **YAML style template** — Figma Design Token처럼 재사용 가능한 스타일 정의 (폰트, 크기, 색상)
- **Type-safe API** — branded index, typestate validation, zero unsafe code

## 빠른 시작

### 설치

```
# Cargo.toml에 추가
cargo add hwpforge

# Markdown 지원 포함
cargo add hwpforge --features full
```

또는 `Cargo.toml`에 직접 추가:

```cpp
[dependencies]
hwpforge = "0.1"
```

### 🔨 Hammer — CLI로 시작하기

CLI 도구 `hwpforge`(Hammer)를 설치하면 터미널에서 바로 문서를 생성하고 편집할 수 있습니다.

```cpp
cargo install hwpforge-bindings-cli
```

```bash
# Markdown → HWPX 변환
hwpforge convert report.md -o report.hwpx

# HWPX 구조 확인
hwpforge inspect report.hwpx

# HWPX → Markdown 변환 (AI가 한글 문서 읽기)
hwpforge to-md report.hwpx -o report.md

# HWPX → JSON 추출 (AI 편집용)
hwpforge to-json report.hwpx --section 0 > section0.json

# JSON → HWPX 직접 생성
hwpforge from-json section0.json -o new.hwpx

# JSON으로 섹션 교체
hwpforge patch report.hwpx --section 0 < modified.json -o updated.hwpx

# JSON Schema 출력 (AI agent용)
hwpforge schema document
```

> **AI-first 설계**: CLI는 AI agent(Claude Code 등)가 주 사용자입니다.
> Markdown으로 문서를 생성한 뒤, JSON round-trip으로 기존 스타일을 보존하면서
> section 단위로 정밀하게 편집할 수 있습니다. `--json` 플래그로 모든 명령어가
> machine-readable 출력을 지원합니다.

### ⚙️ Anvil — MCP Server (Beta)로 AI가 직접 한글 문서를 다루다

Claude Code, Codex CLI, Claude, ChatGPT, Cursor, Antigravity 등 [MCP](https://modelcontextprotocol.io/) 지원 AI 도구에서 **한글 문서를 직접 생성하고 편집**할 수 있습니다. 현재 MCP surface는 **베타**이며, HWP5 경로는 MCP가 아니라 CLI workflow를 우선합니다. "보고서 만들어줘"라고 말하면, AI가 알아서 `.hwpx` 파일을 뚝딱 만들어냅니다.

#### AI 도구에 등록

한 줄이면 설치 + 등록이 끝납니다. npm은 `npx -y`가 자동으로 바이너리를 다운로드합니다.

<details>
<summary><strong>Claude Code</strong> (터미널)</summary>

```
# npm (권장 — Rust 툴체인 불필요)
claude mcp add hwpforge -- npx -y @hwpforge/mcp

# Cargo (Rust 개발자용)
cargo install hwpforge-bindings-mcp && claude mcp add hwpforge hwpforge-mcp

# 모든 프로젝트에서 사용 (글로벌)
claude mcp add --global hwpforge -- npx -y @hwpforge/mcp
```

</details>

<details>
<summary><strong>Codex CLI</strong> (터미널)</summary>

`~/.codex/config.toml`에 추가:

```
[mcp_servers.hwpforge]
command = "npx"
args = ["-y", "@hwpforge/mcp"]
```

또는 CLI로:

```
codex mcp add hwpforge -- npx -y @hwpforge/mcp
```

</details>

<details>
<summary><strong>Claude Desktop</strong> (앱)</summary>

설정 파일을 편집합니다:

- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "hwpforge": {
      "command": "npx",
      "args": ["-y", "@hwpforge/mcp"]
    }
  }
}
```

</details>

<details>
<summary><strong>ChatGPT Desktop</strong> (앱)</summary>

Settings → Tools → Add MCP Server에서:

- Name: `hwpforge`
- Command: `npx -y @hwpforge/mcp`

또는 설정 파일을 직접 편집:

```json
{
  "mcpServers": {
    "hwpforge": {
      "command": "npx",
      "args": ["-y", "@hwpforge/mcp"]
    }
  }
}
```

</details>

<details>
<summary><strong>Cursor</strong> (에디터)</summary>

프로젝트 루트에 `.cursor/mcp.json` 생성:

```json
{
  "mcpServers": {
    "hwpforge": {
      "command": "npx",
      "args": ["-y", "@hwpforge/mcp"]
    }
  }
}
```

</details>

<details>
<summary><strong>Antigravity</strong> (에디터)</summary>

`...` 드롭다운 → MCP Store → Manage MCP Servers → View raw config (`mcp_config.json`)에 추가:

```json
{
  "mcpServers": {
    "hwpforge": {
      "command": "npx",
      "args": ["-y", "@hwpforge/mcp"]
    }
  }
}
```

</details>

#### 등록하면 9개 도구를 사용할 수 있습니다

| 도구                 | 하는 일                 | 한마디                               |
| -------------------- | ----------------------- | ------------------------------------ |
| `hwpforge_convert`   | Markdown → HWPX 변환    | "이 마크다운을 한글 파일로!"         |
| `hwpforge_inspect`   | HWPX 구조 확인          | "이 문서 뭐가 들어있어?"             |
| `hwpforge_to_json`   | HWPX → JSON 추출        | "이 섹션 내용 좀 꺼내봐"             |
| `hwpforge_patch`     | JSON으로 섹션 교체      | "이 부분만 바꿔서 다시 저장해"       |
| `hwpforge_templates` | 스타일 프리셋 조회      | "어떤 템플릿 쓸 수 있어?"            |
| `hwpforge_validate`  | HWPX 구조/무결성 검증   | "이 파일 문제 없는지 확인해"         |
| `hwpforge_restyle`   | 스타일 프리셋 일괄 적용 | "이 문서 폰트 바꿔줘"                |
| `hwpforge_from_json` | JSON → HWPX 직접 생성   | "이 JSON으로 한글 파일 만들어"       |
| `hwpforge_to_md`     | HWPX → Markdown 변환    | "이 한글 문서를 Markdown으로 꺼내줘" |

#### 업데이트 / 삭제

npm은 `npx -y`가 항상 최신 버전을 가져오므로 별도 업데이트가 필요 없습니다.

```bash
# Cargo 사용자만 해당
cargo install hwpforge-bindings-mcp --force   # 업데이트
cargo uninstall hwpforge-bindings-mcp          # 삭제
```

> **왜 MCP?** CLI(Hammer)는 AI가 `bash` 명령을 실행해야 하지만, MCP(Anvil)는 AI가 **네이티브 도구**> 직접 호출합니다. 파일 경로 파싱도, stdout 해석도 필요 없습니다.
> JSON-RPC로 요청하면 구조화된 JSON으로 응답 — 깔끔합니다.

### 🔨 문서 생성

```rust
use hwpforge::core::{Document, Draft, Paragraph, Run, Section, PageSettings};
use hwpforge::foundation::{CharShapeIndex, ParaShapeIndex};

let mut doc = Document::<Draft>::new();
doc.add_section(Section::with_paragraphs(
    vec![Paragraph::with_runs(
        vec![Run::text("Hello, 한글!", CharShapeIndex::new(0))],
        ParaShapeIndex::new(0),
    )],
    PageSettings::a4(),
));
```

### ⚒️ HWPX로 인코딩

```rust
use hwpforge::hwpx::{HwpxEncoder, HwpxStyleStore};
use hwpforge::core::ImageStore;

let validated = doc.validate().unwrap();
let style_store = HwpxStyleStore::with_default_fonts("함초롬바탕");
let image_store = ImageStore::new();
let bytes = HwpxEncoder::encode(&validated, &style_store, &image_store).unwrap();
std::fs::write("output.hwpx", &bytes).unwrap();
```

### ⚒️ HWPX 디코딩

```rust
use hwpforge::hwpx::HwpxDecoder;

let result = HwpxDecoder::decode_file("input.hwpx").unwrap();
println!("섹션 수: {}", result.document.sections().len());
```

### ⚒️ HWPX → Markdown 변환 (AI가 한글 문서 읽기)

<div align="center">
<table>
<tr>
<td align="center"><strong>📄 한글 원본 (.hwpx)</strong></td>
<td align="center"><strong>📝 Markdown 변환 결과</strong></td>
</tr>
<tr>
<td><img src="https://raw.githubusercontent.com/ai-screams/HwpForge/main/assets/hwpx-original.png" width="400" alt="한글 원본 문서"></td>
<td><img src="https://raw.githubusercontent.com/ai-screams/HwpForge/main/assets/hwpx-to-md-result.png" width="400" alt="Markdown 변환 결과"></td>
</tr>
</table>
</div>

```rust
use hwpforge::hwpx::HwpxDecoder;
use hwpforge::md::MdEncoder;

let decoded = HwpxDecoder::decode_file("government_report.hwpx").unwrap();
let validated = decoded.document.validate().unwrap();
let markdown = MdEncoder::encode_lossy(&validated).unwrap();
println!("{}", markdown); // LLM이 바로 이해할 수 있는 Markdown
```

기존 .hwpx 파일을 Markdown으로 변환하면 Claude, GPT 등 어떤 LLM이든 한글 공문서를 즉시 읽고 분석할 수 있습니다.

### ⚒️ Markdown → HWPX 변환

```rust
use hwpforge::md::MdDecoder;
use hwpforge::hwpx::{HwpxEncoder, HwpxStyleStore};

let md_doc = MdDecoder::decode_with_default("# 제목\n\nMarkdown에서 변환!").unwrap();
let validated = md_doc.document.validate().unwrap();
let style_store = HwpxStyleStore::from_registry(&md_doc.style_registry);
let image_store = hwpforge::core::ImageStore::new();
let bytes = HwpxEncoder::encode(&validated, &style_store, &image_store).unwrap();
```

## Feature Flags

| Feature | 기본값 | 설명                 |
| ------- | ------ | -------------------- |
| `hwpx`  | Yes    | HWPX encoder/decoder |
| `md`    || Markdown ↔ Core 변환 |
| `full`  || 모든 기능 포함       |

```toml
# Markdown 지원 포함
hwpforge = { version = "0.1", features = ["full"] }
```

## 📜 지원 콘텐츠

| 카테고리      | 요소                                                                 |
| ------------- | -------------------------------------------------------------------- |
| 텍스트        | Run, character shape, paragraph shape, style (22개 한컴 기본 스타일) |
| 구조          | Table (중첩), Image (바이너리 + 경로), TextBox, Caption              |
| 레이아웃      | 다단, 페이지 설정, 가로/세로 방향, 제본 여백, master page            |
| 머리글/바닥글 | Header, Footer, 쪽번호 (autoNum)                                     |
| 각주/미주     | 각주, 미주                                                           |
| 도형          | 선, 타원, 다각형, 호, 곡선, 연결선 (채움, 회전, 화살표 지원)         |
| 수식          | HancomEQN script 형식                                                |
| 차트          | 18종 chart type (OOXML 호환)                                         |
| 참조          | 책갈피, 상호 참조, 필드 (날짜/시간/요약), 메모, 색인                 |
| 덧말/겹침     | 덧말 (dutmal), 글자 겹침                                             |
| Markdown      | GFM decode, lossy + lossless encode, YAML frontmatter                |

## 아키텍처

HwpForge는 `foundation -> core -> blueprint -> smithy-* -> bindings-*` 계층으로 나뉩니다.

- `foundation`: 공통 primitive, unit, index, error
- `core`: 포맷 독립 문서 모델과 validation
- `blueprint`: 스타일 정의와 템플릿 계층
- `smithy-*`: 포맷별 codec과 bridge
- `bindings-*`: CLI/MCP/Python 진입점

### 레이어 구조

```mermaid
%%{init: {'theme': 'base', 'themeVariables': {'fontSize': '14px', 'lineColor': '#BDBDBD'}}}%%
flowchart TB
    F["foundation<br/>primitive types, units, indices, errors"]:::foundation
    C["core<br/>format-agnostic document model<br/>draft / validated DOM"]:::core
    B["blueprint<br/>style registry<br/>template layer"]:::blueprint

    SHX["smithy-hwpx<br/>HWPX encoder / decoder"]:::smithy
    SH5["smithy-hwp5<br/>HWP5 decode<br/>semantic audit<br/>HWPX re-emission support"]:::smithy
    SMD["smithy-md<br/>Markdown bridge"]:::smithy

    CLI["bindings-cli<br/>Hammer CLI"]:::binding
    MCP["bindings-mcp<br/>Anvil MCP Server (Beta)"]:::binding
    PY["bindings-py<br/>stub"]:::binding

    F --> C
    F --> B
    C --> B
    C --> SHX
    C --> SH5
    C --> SMD
    B --> SHX
    B --> SMD
    SHX --> CLI
    SH5 --> CLI
    SMD --> CLI
    SHX --> MCP
    SMD --> MCP
    SHX --> PY

    classDef file     fill:#FFFDE7,stroke:#F9A825,color:#5D4037
    classDef smithy   fill:#FFF3E0,stroke:#FB8C00,color:#E65100
    classDef core     fill:#E3F2FD,stroke:#42A5F5,color:#0D47A1
    classDef blueprint fill:#F3E5F5,stroke:#AB47BC,color:#4A148C
    classDef foundation fill:#FAFAFA,stroke:#BDBDBD,color:#424242
    classDef binding fill:#E8F5E9,stroke:#43A047,color:#1B5E20
```

### 주요 데이터 흐름

```mermaid
%%{init: {'theme': 'base', 'themeVariables': {'fontSize': '14px', 'lineColor': '#BDBDBD'}}}%%
flowchart LR
    HWP5[".hwp"]:::file --> SH5["smithy-hwp5"]:::smithy
    SH5 --> CORE["core document"]:::core
    CORE --> SHX["smithy-hwpx"]:::smithy
    SHX --> HWPX[".hwpx"]:::file

    HWPX <--> SHX
    MD[".md"]:::file <--> SMD["smithy-md"]:::smithy
    SMD <--> CORE

    CLI["CLI"]:::binding --> SH5
    CLI --> SHX
    CLI --> SMD

    MCP["MCP (Beta)"]:::binding --> SHX
    MCP --> SMD

    classDef file fill:#FFFDE7,stroke:#F9A825,color:#5D4037
    classDef smithy fill:#FFF3E0,stroke:#FB8C00,color:#E65100
    classDef core fill:#E3F2FD,stroke:#42A5F5,color:#0D47A1
    classDef binding fill:#E8F5E9,stroke:#43A047,color:#1B5E20
```

**핵심 원칙**: 구조(Structure)와 스타일(Style)의 분리입니다.
`core`는 스타일 *참조*만 가지고, `blueprint`는 스타일 *정의*를 관리합니다.
`smithy-*` 계층이 `core`와 스타일 정보를 각 포맷 surface로 연결합니다.

> HWP5는 현재 CLI 중심 workflow가 강합니다.
> 대표 경로는 `convert-hwp5 -> audit-hwp5 -> inspect --json` 입니다.
> MCP는 현재 HWP5 tool surface를 직접 노출하지 않습니다.

실전에서 가장 자주 쓰는 경로는 다음 셋입니다.

1. Markdown → HWPX
2. HWPX → Markdown / JSON
3. HWP5 → HWPX → audit / inspect

## 프로젝트 현황

| 지표        ||
| ----------- | ----------------------- |
| 총 LOC      | \~54,100                |
| 테스트      | 1,645개 (cargo-nextest) |
| 소스 파일   | 96 .rs                  |
| Crate 수    | 10개 (7개 배포)         |
| 커버리지    | 92.65%                  |
| Clippy 경고 | 0                       |
| Unsafe 코드 | 0                       |

## 개발

### 필수 요구사항

- Rust 1.88+ (MSRV)
- (권장) [cargo-nextest]https://nexte.st/ — 병렬 테스트 실행
- (선택) [pre-commit]https://pre-commit.com/ — git hook 자동화

### MSRV 정책

- 현재 MSRV는 **Rust 1.88**입니다.
- HwpForge는 **stable에서 4 릴리스 뒤처진 버전**을 기본 MSRV 정책으로 유지합니다.
- `Cargo.toml``rust-version`이 단일 진실원이며, CI의 `Verify › MSRV` job이 이 계약을 검증합니다.
- MSRV 상향이 필요하면 PR에서 이유를 명시하고, `Cargo.toml`, CI, CHANGELOG를 함께 갱신합니다.
- 개발용 기본 툴체인은 더 최신일 수 있습니다. 호환성 판단 기준은 최신 stable이 아니라 **MSRV + CI 통과 여부**입니다.

### ⚒️ 명령어

```bash
make ci          # fmt + clippy + test + deny + lint (CI와 동일)
make test        # cargo nextest run
make clippy      # cargo clippy (모든 target, 모든 feature, -D warnings)
make fmt-fix     # rustfmt 자동 포맷
make doc         # rustdoc 생성 (브라우저에서 열림)
make cov         # coverage 리포트 (90% gate)
```

### 프로젝트 구조

```
HwpForge/
├── crates/
│   ├── hwpforge/                 # Umbrella crate (re-exports)
│   ├── hwpforge-foundation/      # 기본 타입 (HwpUnit, Color, Index<T>)
│   ├── hwpforge-core/            # 문서 모델 (스타일 참조만)
│   ├── hwpforge-blueprint/       # YAML 템플릿 (Figma 패턴)
│   ├── hwpforge-smithy-hwpx/     # HWPX codec (ZIP+XML ↔ Core)
│   ├── hwpforge-smithy-md/       # Markdown codec (MD ↔ Core)
│   ├── hwpforge-smithy-hwp5/     # HWP5 decoder (예정)
│   ├── hwpforge-bindings-py/     # Python bindings (예정)
│   ├── hwpforge-bindings-cli/    # CLI 도구 (hwpforge)
│   └── hwpforge-bindings-mcp/    # MCP Server (hwpforge-mcp)
├── tests/                        # 통합 테스트 + golden fixture
└── examples/                     # 📜 사용 예제 + 생성된 HWPX 파일
```

## 기여

버그 수정, 포맷 리서치, 테스트 보강, 문서 개선 모두 환영합니다.

- 시작 전 가이드: [CONTRIBUTING.md]CONTRIBUTING.md
- 특히 확인할 것: release-plz가 쓰는 커밋 prefix (`feat`, `fix`, `perf`, `refactor`)
- 특히 확인할 것: MSRV 정책과 dependency/MSRV 상승 기준
- 특히 확인할 것: 문서 변경 시 `mdbook build`와 markdown lint 검증
- 특히 확인할 것: CI required checks를 깨지 않는 범위에서의 변경 분리

## 로드맵

### 출시 예정

- [ ] HWP5 읽기 — 구형 바이너리 포맷(`.hwp`) 디코더
- [x] MCP 서버 — Claude, Cursor 등 AI 도구가 tool로 직접 HWPX 생성·검증·편집 (8개 도구 + 4 리소스 + 3 프롬프트)
- [x] CLI 도구 — `hwpforge convert doc.md doc.hwpx` 한 줄 변환 (7개 명령어)
- [ ] HWPX 완전 지원 — 양식 컨트롤, 변경 추적, OLE 객체
- [ ] Python 바인딩 — `pip install hwpforge`로 설치, PyPI 배포

## 라이선스

다음 중 하나를 선택할 수 있습니다:

- Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE)
- MIT license ([LICENSE-MIT]LICENSE-MIT)

## Acknowledgements

HwpForge는 거인들의 어깨 위에 서 있습니다.

- [**Hancom**]https://www.hancom.com — HWPX 포맷의 공개 문서와 [KS X 6101 (OWPML)]https://www.kssn.net/ 국가 표준이 없었다면 이 프로젝트는 시작조차 할 수 없었습니다. 포맷을 공개해 주신 Hancom에 감사드립니다.
- [**openhwp**]https://github.com/openhwp/openhwp — Rust로 HWP/HWPX를 다루는 IR 기반 아키텍처 설계에서 큰 영감을 받았습니다. HwpForge의 Core 레이어가 존재할 수 있었던 것은 openhwp이 먼저 그 길을 걸었기 때문입니다.
- [**hwpxlib**]https://github.com/neolord0/hwpxlib — Java로 작성된 가장 성숙한 HWPX 구현체입니다. 스펙과 실제 동작의 차이를 파악하는 데 결정적인 참고가 되었습니다.
- [**hwp.js**]https://github.com/hahnlee/hwp.js — HWP5 포맷의 quirks와 edge case를 꼼꼼히 문서화한 프로젝트입니다. 바이너리 포맷의 어두운 구석을 밝혀 준 덕분에 시행착오를 크게 줄일 수 있었습니다.
- [**hwpx-owpml-model**]https://github.com/hancom-io/hwpx-owpml-model — Hancom이 직접 공개한 C++ OWPML 모델 구현체로, 스키마 해석의 최종 기준으로 삼았습니다.
- **Rust 생태계**[serde]https://serde.rs, [quick-xml]https://github.com/tafia/quick-xml, [pulldown-cmark]https://github.com/pulldown-cmark/pulldown-cmark, [zip]https://github.com/zip-rs/zip2 등 뛰어난 라이브러리들 덕분에 HwpForge 전체를 zero unsafe 순수 Rust로 구현할 수 있었습니다. Rust 커뮤니티와 Ferris 🦀에게 감사드립니다.
- [**Claude**]https://claude.ai&#x20;**&#x20;by&#x20;**&#x20;[**Anthropic**]https://www.anthropic.com — HwpForge의 설계, 구현, 테스트, 문서화 전 과정에서 Claude Code가 개발 파트너로 함께했습니다. LLM-first를 표방하는 프로젝트답게, AI와 사람이 협업하여 만들어낸 결과물입니다.
- [**Codex**]https://openai.com/codex **by** [**OpenAI**]https://openai.com — HwpForge의 구현 검토, 리팩터링, 회귀 점검, 작업 흐름 정리 과정에서 실질적인 개발 파트너로 기여했습니다.

---

<div align="center">
<img src="https://raw.githubusercontent.com/ai-screams/HwpForge/main/assets/mascot-main.png" width="260" alt="쇠부리 Anvilscribe (SoeBuri Anvilscribe)">

쇠부리 Anvilscribe (SoeBuri Anvilscribe)
한컴 문서를 불에 달구어 단단하게 벼려내는 대장장이 오리너구리 🔥

<a href="https://buymeacoffee.com/pignuante">
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me a Coffee" height="50" width="217">
</a>

</div>