| name | hwpforge |
| description | Generate, inspect, edit, and fill Korean HWP/HWPX documents using HwpForge. Use when the user asks to create a Korean government document, proposal, report, or official letter; convert Markdown to HWPX; convert an old HWP5 (.hwp) file to HWPX; fill in a Korean template (e.g. ๊ตญ๊ฐ๊ณผ์ ์ ์์) with content; edit/append content in an existing HWPX; inspect HWPX structure; or convert HWPX back to Markdown. Supports MarkdownโHWPX, HWP5โHWPX, JSON round-trip editing, template filling, and style presets. |
| license | MIT |
| compatibility | claude-code, openai-codex, cursor, windsurf, vscode-copilot |
| metadata | {"author":"ai-screams","version":"0.2.0"} |
| allowed-tools | Bash Read Write |
HwpForge Skill
Overview
HwpForge is a CLI (hwpforge) for the Korean HWPX document format (KS X 6101) used in
government proposals, official reports, and administrative documents. It can:
- Create HWPX from Markdown (with Korean style presets)
- Convert legacy HWP5 (
.hwp) โ HWPX, and HWPX โ Markdown
- Edit existing HWPX via a JSON round-trip (fill placeholders, fix text, add content)
- Inspect structure and emit JSON Schemas
Every command accepts --json for machine-readable output and structured error codes.
There is no .hwp (HWP5) writer. HwpForge reads .hwp but only writes .hwpx.
To work with a .hwp, convert it to .hwpx first (convert-hwp5).
The Algorithm โ pick the right command
Follow this decision flow. Choosing the wrong path is the most common mistake.
What does the user want?
โ
โโ Create a NEW document from text / Markdown
โ โ convert (Markdown โ HWPX, with --preset)
โ
โโ They have a legacy .hwp file
โ โ convert-hwp5 (.hwp โ .hwpx) then treat it as HWPX
โ
โโ EDIT an existing .hwpx โโ ALWAYS `outline` first (nav map), `read` to see targets โโ
โ โ
โ โโ Fill NAMED click-here fields (๋๋ฆํ) โ form-style templates
โ โ โ fields (discover names) โ fill --set name=value [DELTA, cheapest+safest]
โ โ
โ โโ Template has NO ๋๋ฆํ, only prose placeholders (โก, ( ), ๋
์ ์ผ, (์ธ), @)
โ โ โ stamp-plan (discover) โ author spec map โ stamp --map [STAMP, one-time]
โ โ then the stamped output is a form template: use fields/fill above
โ โ
โ โโ Fill a TABLE CELL by position or label (๋ณํฉ์
ํ ์์)
โ โ โ to-json (cells carry addr {row,col}) โ set-cell [GRID, admission-gated]
โ โ --table N --at "r,c" | --right-of LABEL | --below LABEL, --text "" clears
โ โ covered coords resolve to their merge anchor (reported in the result)
โ โ
โ โโ Change only EXISTING text
โ โ (fill a prose placeholder, fix a typo, fill a table cell)
โ โ โ to-json (--section) โ edit the Text โ patch [TEXT-ONLY, safest]
โ โ
โ โโ ADD or REMOVE a top-level paragraph (structural edit, byte-preserving)
โ โ โ outline/read to find the index โ insert-para / delete-para [E4]
โ โ insert-para --section N --anchor I [--before] --text "โฆ" (shape inherited;
โ โ --text ๋ฐ๋ณต = ์ฐ์ ๋ธ๋ก batch ์ฝ์
)
โ โ delete-para --section N --index I [--index J โฆ] (batch)
โ โ IndexMark ๋ ๋ฌธ๋จ ์ญ์ ์ warnings ๋ก ์์ธ ์๋ฉธ advisory (๊ฑฐ๋ถ ์๋)
โ โ fail-closed: refuses deleting a paragraph with a reference
โ โ (bookmark/cross-ref/footnote), a hard page/column break, or the
โ โ section's first paragraph (secPr). Only round-trip-safe inputs.
โ โ verify with `diff base out`. (ํ ํ ์ถ๊ฐ/์ญ์ ๋ ์์ง ๋ฏธ์ง์)
โ โ
โ โโ REBUILD from scratch (structural change beyond paragraphs)
โ โ to-json (full) โ edit โ from-json --base [REBUILD]
โ โ ํ ๊ตฌ์กฐ๋ฅผ ๋ฐ๊ฟจ๋ค๋ฉด(ํ/์ด/์
์ถ๊ฐยท์ญ์ ) ์
์ addr ํ๋๋ฅผ ์ญ์ ํ๊ณ
โ ์ ์ถํ ๊ฒ โ ๋จ๊ฒจ๋๋ฉด stale ์ฃผ์๋ก GRID_ADDR_INVALID ๊ฑฐ๋ถ๋จ
โ (addr ๋ถ์ฌ = ๋ฌด๊ฒ์ฌ, ์กด์ฌ = ์ฌํ์ ๊ฒฉ์์ ๋์กฐ)
โ
โโ Read / export an existing .hwpx โ pick by granularity:
โ โ outline (nav map: headings/tables+dims/fields/bookmarks โ fetch ONCE first)
โ โ read (targeted text: --section N [--paras A..B] | --table N | --field NAME)
โ โ inspect (counts summary only)
โ โ to-md (full lossy flatten, for human reading)
โ โ to-json (whole document JSON, for machine editing ONLY)
โ
โโ Need the JSON shape, or the list of styles
โ schema (JSON Schema for document/section types)
โ templates list (available style presets)
The two edit modes are not interchangeable:
| Mode | Command | Can do | Cannot do |
|---|
| Text-only | patch | change text inside existing paragraphs and table cells; preserves images, styles, tables, layout exactly | add/remove paragraphs (returns PATCH_FAILED: structural change detected) |
| Rebuild | from-json --base | add/remove paragraphs, structural edits; preserves tables; --base inherits images | guarantee byte-perfect fidelity of complex ํ์ปด forms (see Fidelity Warning) |
Commands
Run hwpforge <command> --help for exact flags. Key forms:
hwpforge convert input.md -o out.hwpx [--preset default]
echo "# ์ ๋ชฉ" | hwpforge convert - -o out.hwpx
hwpforge convert-hwp5 old.hwp -o out.hwpx
hwpforge outline doc.hwpx [--json]
hwpforge read doc.hwpx --section 0 --paras 2..5
hwpforge read doc.hwpx --table 3
hwpforge read doc.hwpx --field ๊ณผ์ ๋ช
hwpforge diff base.hwpx edited.hwpx [--json] [-o report.json]
hwpforge inspect doc.hwpx [--styles] [--json]
hwpforge fields doc.hwpx [--json]
hwpforge fill doc.hwpx --set ๊ณผ์ ๋ช
="AI ๋ฌธ์ ์๋ํ" --set ๊ธฐ๊ด๋ช
="AiScream" -o out.hwpx
hwpforge stamp-plan template.hwpx --json
hwpforge stamp template.hwpx --map specs.json -o form.hwpx
hwpforge insert-para doc.hwpx --section 0 --anchor 3 --text "์ถ๊ฐ ๋ฌธ๋จ" -o out.hwpx
hwpforge insert-para doc.hwpx --section 0 --anchor 3 --before --text "์์ ์ถ๊ฐ" -o out.hwpx
hwpforge insert-para doc.hwpx --section 0 --anchor 3 --text "ํ๋" --text "๋" -o out.hwpx
hwpforge delete-para doc.hwpx --section 0 --index 5 -o out.hwpx
hwpforge set-cell form.hwpx --table 0 --at "1,2" --text "ํ๊ธธ๋" -o out.hwpx
hwpforge set-cell form.hwpx --table 0 --right-of "์ฑ๋ช
" --text "ํ๊ธธ๋" -o out.hwpx
hwpforge set-cell form.hwpx --table 0 --below "๋น๊ณ " --text "" -o out.hwpx
hwpforge set-cell form.hwpx --map cells.json -o out.hwpx
hwpforge to-json doc.hwpx -o full.json
hwpforge to-json doc.hwpx --section 0 -o sec.json
hwpforge to-json doc.hwpx --section 0 --no-styles -o sec.json
hwpforge patch doc.hwpx --section 0 sec.json -o doc.hwpx
hwpforge from-json full.json -o doc.hwpx --base doc.hwpx
hwpforge to-md doc.hwpx -o doc.md
hwpforge schema [document|exported-document|exported-section]
hwpforge templates list [--json]
hwpforge templates show default
Diagnostic (parity/QA, not for normal authoring): audit-hwp5, census-hwp5.
Presets
templates list catalogs four: default (ํจ์ด๋กฌ๋์ 10pt), modern (๋ง์ ๊ณ ๋),
classic (๋ฐํ), latest (ํจ์ด๋กฌ๋ฐํ) โ all A4. However, convert --preset currently
resolves only default (others return UNKNOWN_PRESET). Use default for convert; the
catalog entries are inspectable via hwpforge templates show <name>. See
templates.md.
Editing an existing document (JSON round-trip)
The exported section/document JSON is structure + style references (IDs). Full recipes:
editing-workflow.md. Filling a Korean template (e.g. ๊ตญ๊ฐ๊ณผ์
์ ์์): template-fill.md.
Minimal text-only edit (fill placeholders, fix text, fill table cells):
hwpforge inspect doc.hwpx --json
hwpforge to-json doc.hwpx --section 0 -o sec.json
hwpforge patch doc.hwpx --section 0 sec.json -o doc.hwpx
hwpforge inspect doc.hwpx
Add new paragraphs (structural โ rebuild):
hwpforge to-json doc.hwpx -o full.json
hwpforge from-json full.json -o doc.hwpx --base doc.hwpx
hwpforge inspect doc.hwpx
JSON rules (these prevent broken output)
- Reuse existing style IDs. New paragraphs/runs must copy
para_shape_id / char_shape_id
from a neighboring paragraph in the same document. Never invent IDs.
style_id and heading_level are optional per paragraph โ copy them only if the
source paragraph has them; omit otherwise.
patch replaces the whole section, so sec.json must contain ALL existing paragraphs
plus your edits โ it is a read-modify-write of the full section, not a delta.
- Do not edit the
styles registry by hand โ change styles via --preset instead.
- Table cell text lives at
โฆcontent.Table.rows[].cells[].paragraphs[].runs[].content.Text.
Fidelity Warning (government / ํ์ปด-authored templates)
patch (text-only) preserves the original file structure exactly โ prefer it for real
ํ์ปด templates (form fields, master pages, complex tables) where formatting is mandatory.
from-json --base rebuilds the document from HwpForge's internal model. Simple tables and
paragraphs survive, but elements HwpForge does not yet fully model (form controls, master pages,
some advanced formatting) can be lost. Never submit a rebuilt government document without
opening it in ํ์ปด and checking it visually. When in doubt, fill placeholders with patch.
Document Scenarios
Korean Markdown Best Practices
See markdown-guide.md: GFM tables, YAML frontmatter
(title, author, date, preset), image paths, --- as page break, Korean characters.
Agent Behavior Rules
Output: No Raw JSON
Never show raw JSON to the user during round-trip workflows. Summarize as a table, structure
diagram, or short description. Keep intermediate JSON in temp files for internal use only.
Edit: In-Place by Default
When the user asks to modify a specific file, overwrite the original unless they specify a
different output path โ set -o to the input path.
hwpforge patch document.hwpx --section 0 modified.json -o document.hwpx
Always outline before editing, always diff after
Run outline first to learn what is where (use read for the targets you will touch), and
diff base.hwpx edited.hwpx after every edit to confirm ONLY the intended delta landed
before reporting success โ an unexpected entry in the diff report means stop and re-check,
not ship.
Error Handling
With --json, all commands return structured errors:
{ "error": { "code": "PATCH_FAILED", "message": "...", "hint": "..." } }
Common: FILE_NOT_FOUND (bad path), PATCH_FAILED with "structural change detected"
(you added/removed paragraphs in a patch โ use from-json --base instead).
Exit codes: 1 user error (bad input/missing file), 2 internal error (encode/corrupt).
Use --json in all agent workflows to parse errors programmatically.