@kimdayoun/hwpx-mcp 0.3.0 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +201 -0
- package/README.md +30 -49
- package/dist/HangingIndentCalculator.js +136 -166
- package/dist/HwpxDocument.d.ts +275 -12
- package/dist/HwpxDocument.js +1589 -627
- package/dist/HwpxParser.js +18 -2
- package/dist/XmlWellFormed.d.ts +5 -0
- package/dist/XmlWellFormed.js +52 -0
- package/dist/index.js +117 -62
- package/dist/types.d.ts +5 -0
- package/package.json +10 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
`@kimdayoun/hwpx-mcp` 의 주요 변경 사항을 기록합니다.
|
|
4
|
+
|
|
5
|
+
형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/) 를 따르고,
|
|
6
|
+
버전은 [유의적 버전](https://semver.org/lang/ko/) 을 따릅니다.
|
|
7
|
+
|
|
8
|
+
## [0.3.4] - 2026-09-24
|
|
9
|
+
|
|
10
|
+
0.3.3 을 실제 업무 양식·실문서에 쓴 2차 사용 회신(6건)을 재현해 고쳤습니다.
|
|
11
|
+
같은 시험을 게시된 버전과 로컬 빌드에 돌리는 버전 매트릭스를 만들었고,
|
|
12
|
+
0.3.0 은 3/11, 0.3.3 은 5/11, 이 버전은 11/11 을 통과합니다.
|
|
13
|
+
변경 내역은 [#16](https://github.com/Dayoooun/hwpx-mcp/pull/16) 에 있습니다.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **행을 추가한 파일을 한/글이 열지 못하고 멈추던 문제.** 새 행 아래 행들의
|
|
18
|
+
`rowAddr` 를 다시 매기지 않아 같은 번호가 두 행에 생겼습니다. 사용자 신고는 한/글 2020,
|
|
19
|
+
재현은 한/글 2024 에서 했습니다. 한/글 원본 142건의
|
|
20
|
+
첫 표에서 0.3.3 은 142건 모두 번호가 겹쳤고, 이제 0건입니다. 세로 병합 한가운데에
|
|
21
|
+
넣으면 거부하고, 병합 아래에 넣은 새 행도 모든 열을 덮습니다.
|
|
22
|
+
- **표를 품은 문단을 `update_paragraph_text_preserve_styles` 로 고치면 문서가 깨지던 문제.**
|
|
23
|
+
문단 위치 캐시가 한/글 원본 문단 70,677개 중 16,271개에서 다른 문단을 가리켰고,
|
|
24
|
+
run 을 셀 때 표 칸 안 문단까지 셌습니다. 원본 60건 기준 제대로 바뀐 문단 3 → 55,
|
|
25
|
+
표 칸 글자가 바뀐 경우 44 → 0. 표 요소에 `update_paragraph_text` 를 걸면
|
|
26
|
+
성공이라 답하던 것도 이제 실패로 알려 줍니다.
|
|
27
|
+
- **`save_document(verify_integrity)` 가 깨진 XML 을 통과시키던 문제.** 글자 모양 세 가지만
|
|
28
|
+
보던 검사를 실제 XML 파싱으로 바꿨고, 실패하면 저장하지 않습니다. 한/글 원본 275건
|
|
29
|
+
(XML 2,046개)에서 잘못 거부한 것은 0건입니다.
|
|
30
|
+
- **그림이 든 표 칸에 글을 쓰면 저장본이 깨지던 문제.** 칸 글 정규식이 그림 안
|
|
31
|
+
`<hc:transMatrix>` 를 `<hc:t>` 로 읽었습니다. 한/글 원본 209건 중 18건에서
|
|
32
|
+
재현됐고 이제 0건입니다.
|
|
33
|
+
- **구역이 둘 이상인 문서에서 표 번호가 도구마다 다르던 문제.** `get_table_map` 이
|
|
34
|
+
`table_index_in_section` 도 함께 돌려주고, 도구 설명에 어느 번호를 쓰는지 적었습니다.
|
|
35
|
+
- **`insert_section`·`delete_section` 이 파일에 저장되지 않던 문제.** 두 구역 문서를
|
|
36
|
+
저장하고 다시 열면 1구역만 남았습니다.
|
|
37
|
+
- **열을 추가하면 표가 본문 폭을 넘던 문제.** 원래 표 폭 안에서 칸 폭을 같은 비율로
|
|
38
|
+
다시 나눕니다.
|
|
39
|
+
- **표 편집을 여러 번 한 뒤 저장하면 편집 순서가 뒤바뀌던 문제.** 저장할 때 칸 쓰기,
|
|
40
|
+
병합, 행·열 추가와 삭제를 호출한 순서가 아니라 종류별로 묶어 적용했습니다.
|
|
41
|
+
그래서 새로 넣은 행이나 열에 쓴 글이 빠지거나 다른 칸에 들어갔고, 행을 두 번 넣거나
|
|
42
|
+
지우면 두 번째 위치가 어긋났으며, 행을 넣은 뒤 그 아래를 병합하면 병합이 빠졌습니다.
|
|
43
|
+
0.3.3 에도 있던 문제로, 시험한 여섯 경우 모두 0.3.3 에서 틀리고 이 버전에서 맞습니다.
|
|
44
|
+
열을 지운 뒤 칸에 쓴 글이 빠지던 것(0.3.3 도 같음)과, 행을 지운 뒤 병합 옆에 행을 넣을 때
|
|
45
|
+
병합을 가르는지 한 행 어긋나게 판단하던 것도 함께 고쳤습니다.
|
|
46
|
+
- **병합이 한 행의 칸을 모두 덮으면 한/글이 파일을 변환하지 못하던 문제.** 두 행을 전체 폭으로
|
|
47
|
+
병합하거나 1열 표를 세로로 병합하면 저장본에 칸이 하나도 없는 행이 생겼고, 한/글 2024 는
|
|
48
|
+
이 파일에서 PDF 를 만들지 못했습니다. 한/글 원본 275건에는 칸 없는 행이 한 건도 없습니다.
|
|
49
|
+
이제 이런 병합은 어느 행이 비는지 알려 주고 거부합니다. 0.3.3 에도 있던 문제입니다.
|
|
50
|
+
- **글자 모양이 섞인 문단을 통째로 바꾸면 뒤쪽이 굵게 바뀌던 문제.** run 0 을 바꾸면
|
|
51
|
+
첫 run 의 글자 모양으로 문단 전체를 씁니다.
|
|
52
|
+
- **실패한 호출도 `isError: false` 로 오던 문제.**
|
|
53
|
+
|
|
54
|
+
### 알려진 제한
|
|
55
|
+
|
|
56
|
+
- 표 칸 글 쓰기에서, 칸 안에 문단이 여럿이거나 그림만 있는 칸은 글이 원래 자리에
|
|
57
|
+
들어가지 않을 수 있습니다(한/글 원본 209건 중 67건, 0.3.3 과 같음).
|
|
58
|
+
- 새로 만든 표는 바깥 여백 때문에 한/글에서 오른쪽 여백선을 1.16pt 넘습니다.
|
|
59
|
+
이 버전 이전부터 있던 동작입니다.
|
|
60
|
+
|
|
61
|
+
## [0.3.3] - 2026-09-24
|
|
62
|
+
|
|
63
|
+
0.3.2 는 npm 에 게시하지 않았습니다. 게시 전에 윈도우 한/글로 직접 렌더하다가,
|
|
64
|
+
MCP 응답이 성공이고 `analyze_xml` 도 통과하는데 화면이 틀어진 곳을 찾았습니다.
|
|
65
|
+
0.3.2 의 수정은 모두 이 버전에 포함돼 있습니다.
|
|
66
|
+
|
|
67
|
+
변경 내역은 [#13](https://github.com/Dayoooun/hwpx-mcp/pull/13),
|
|
68
|
+
[#14](https://github.com/Dayoooun/hwpx-mcp/pull/14) 에 있습니다.
|
|
69
|
+
|
|
70
|
+
### Fixed
|
|
71
|
+
|
|
72
|
+
- **문단과 표를 섞어 넣으면 저장본 순서가 뒤집히던 문제.** `[제목, 표, 제목, 표]` 로
|
|
73
|
+
넣었는데 한/글에서는 `[제목, 제목, 표, 표]` 로 보였습니다. 새 문서에서 문단 두 개만
|
|
74
|
+
넣어도 순서가 바뀌었습니다. 위치를 요소 번호 대신 앞 요소의 id 로 기록하고,
|
|
75
|
+
삽입·복제·이동을 호출한 순서대로 저장합니다.
|
|
76
|
+
- **다시 연 문서에서 복제한 문단을 고치면 원본이 바뀌던 문제.** 0.3.2 에서 고친 증상이
|
|
77
|
+
"저장 → 다시 열기 → 복제 → 수정" 경로에는 남아 있었습니다. 수정 대상 문단을
|
|
78
|
+
저장 시점에 다시 찾습니다. 수정한 뒤 다른 문단을 옮기거나 지워도 그 문단이 바뀝니다.
|
|
79
|
+
- **표 뒤에 넣은 문단이 표 첫 칸 안으로 들어가던 문제.**
|
|
80
|
+
- **표 안 글자가 셀 테두리에 붙던 문제.** 새로 만든 표의 셀 안 여백이 0 이었습니다.
|
|
81
|
+
한/글로 쟀을 때 글자가 테두리에서 0pt 떨어져 있었고, 이제 왼쪽 5pt, 위 1.4pt 떨어집니다.
|
|
82
|
+
- **표 안 표가 부모 칸을 뚫고 나가던 문제.** 중첩 표 칸 폭이 부모와 상관없이
|
|
83
|
+
80mm 로 고정돼 있었습니다. 부모 칸 안쪽 폭에 맞추고, 표 위에 생기던 빈 줄도 없앴습니다.
|
|
84
|
+
- **내어쓰기 둘째 줄이 첫 줄 본문보다 오른쪽에서 시작하던 문제.** 마커 폭을 추정식으로
|
|
85
|
+
계산해 한/글보다 평균 4.14pt 넓게 잡았습니다. 마커 35종을 한/글로 그려 잰 폭으로
|
|
86
|
+
바꿨고, 오차는 평균 0.04pt 입니다. 함초롬바탕·함초롬돋움만 실측했습니다.
|
|
87
|
+
- **`insert_table_row` 의 `cell_texts` 가 다른 칸으로 들어가던 문제.** 기준 행에 여러 줄
|
|
88
|
+
칸이 있으면 `['가','나','다']` 가 `['가','나다','']` 로 들어갔고, 새 행이 세 줄 높이가
|
|
89
|
+
됐습니다.
|
|
90
|
+
|
|
91
|
+
### 알려진 제한
|
|
92
|
+
|
|
93
|
+
- run 이 여러 개인 문단을 `update_paragraph_text` 로 고치면 새 글자가 run 사이에
|
|
94
|
+
흩어지거나 사라질 수 있습니다. 미주·수식이 섞인 문단은 수정이 반영되지 않을 수
|
|
95
|
+
있습니다. 이 버전 이전부터 있던 문제입니다.
|
|
96
|
+
|
|
97
|
+
## [0.3.2] - 2026-09-22
|
|
98
|
+
|
|
99
|
+
외부 사용 리뷰에서 보고된 8건을 MCP stdio 클라이언트로 직접 재현한 뒤 수정했습니다.
|
|
100
|
+
리뷰 대응 내역은 [#10](https://github.com/Dayoooun/hwpx-mcp/pull/10) 에 정리돼 있습니다.
|
|
101
|
+
|
|
102
|
+
### Fixed
|
|
103
|
+
|
|
104
|
+
- **표 행·열 삽입이 저장본을 깨뜨리던 문제.** 복제한 행·셀의 본문을 비우는 정규식
|
|
105
|
+
`<(hp|hs):t([^>]*)>` 에 태그명 뒤 경계가 없어 `<hp:tc>` 를 `<hp:t>` 로 삼켰습니다.
|
|
106
|
+
`<hp:subList>` 이하가 통째로 사라지고 닫는 태그만 남아 한/글이 파일을 열지 못했습니다.
|
|
107
|
+
`insert_table_row` · `insert_table_column` 양쪽 해당.
|
|
108
|
+
- **`copy_paragraph` 직후 텍스트를 교체하면 원본까지 바뀌던 문제.** 저장 파이프라인이
|
|
109
|
+
텍스트 갱신을 문단 복제보다 먼저 적용해, 복제 후 인덱스로 지정한 대상이 복제 전 XML 의
|
|
110
|
+
원본 문단으로 해석됐습니다. 복제·이동을 모든 텍스트 갱신 앞으로 옮겼습니다.
|
|
111
|
+
중간에 `save_document` 를 끼우던 우회가 더 이상 필요 없습니다.
|
|
112
|
+
- **`create_document` · `save_document` 의 경로 무시.** 새 문서가 실제 위치 없이
|
|
113
|
+
`new-document.hwpx` 라는 상대 파일명을 들고 있어 저장이 서버 프로세스 cwd 로 갔습니다.
|
|
114
|
+
목적지가 없으면 조용히 cwd 로 가지 않고 명시적으로 실패합니다.
|
|
115
|
+
- **병합으로 덮인 셀에 쓰면 성공이라 답하고 저장 시 사라지던 문제.** HWPX 는 덮인 위치에
|
|
116
|
+
`<hp:tc>` 를 두지 않아 직렬화 대상이 없습니다. 이제 어느 마스터 셀에 써야 하는지
|
|
117
|
+
알려주며 거부합니다.
|
|
118
|
+
- **`get_tool_guide` 의 `topic` 이 무시되던 문제.** 모르는 값에 조용히 전체 참조를
|
|
119
|
+
반환하던 것을 가능한 값 목록을 담은 오류로 바꿨습니다.
|
|
120
|
+
- **복제 문단·행·열의 `linesegarray` 미초기화.** 원본의 고정 줄 배치를 물려받아 긴 글을
|
|
121
|
+
넣으면 글자가 겹쳤습니다. `get_section_xml` → 문자열 치환 → `set_section_xml` 수작업이
|
|
122
|
+
필요 없어집니다.
|
|
123
|
+
|
|
124
|
+
### Changed
|
|
125
|
+
|
|
126
|
+
- **필수 인자 누락 시 원인을 밝힙니다.** `section_index` 를 빠뜨리면
|
|
127
|
+
`Failed to insert paragraph` 가 떠 문서 손상처럼 보였습니다. 스키마의 `required` 를
|
|
128
|
+
디스패처에서 검사해 어떤 인자가 빠졌는지 이름으로 답합니다.
|
|
129
|
+
예: `Missing required arguments for insert_paragraph: section_index, after_index`
|
|
130
|
+
- **`save_document` 응답에 절대경로를 돌려줍니다.** `path` 와 `backup_path` 가 추가됐고,
|
|
131
|
+
`output_path` 외에 `file_path` 도 받습니다.
|
|
132
|
+
- **`batch_fill_table` 이 실패한 셀을 보고하고 나머지를 계속 채웁니다.** 반환값에 `failed`
|
|
133
|
+
목록(좌표·값·이유)이 추가됐습니다. 이전에는 덮인 셀 하나가 배치 전체를 중단시켰습니다.
|
|
134
|
+
|
|
135
|
+
### Added
|
|
136
|
+
|
|
137
|
+
- **`create_document({file_path})`** — 목적지를 미리 지정하면 이후 `save_document` 가
|
|
138
|
+
인자 없이도 그 경로에 씁니다.
|
|
139
|
+
- **`paraPrIDRef` · `charPrIDRef` 노출** — `get_paragraph` · `get_paragraphs` 가 스타일
|
|
140
|
+
값과 함께 원본 숫자 ID 를 돌려줍니다. XML 을 직접 조립할 때 `section0.xml` 을 정규식으로
|
|
141
|
+
파지 않아도 됩니다.
|
|
142
|
+
|
|
143
|
+
### 알려진 제한
|
|
144
|
+
|
|
145
|
+
- `updateTableCell` 은 셀마다 문서 전체를 직렬화해 undo 스택에 쌓습니다. 실측상 100×30 표
|
|
146
|
+
전수 쓰기 1,725ms 중 1,501ms(87%)가 여기서 발생합니다. 구조 변경이라 이 릴리스의 수정
|
|
147
|
+
범위에 포함하지 않았습니다.
|
|
148
|
+
|
|
149
|
+
## [0.3.1] - 2026-09-08
|
|
150
|
+
|
|
151
|
+
- 저장 임시 파일·백업 경로의 링크 공격 방어 및 실패 시 원본 보존
|
|
152
|
+
- 여러 `hp:t`에 분리된 텍스트의 저장 누락 수정 및 특수문자 보존
|
|
153
|
+
- 개인 Windows 문서에 의존하던 테스트를 합성 HWPX 회귀 테스트로 교체
|
|
154
|
+
- 의존성 갱신 및 기존 절대·상대경로 사용법의 호환성 검사 추가
|
|
155
|
+
- 작업 폴더 제한은 추가하지 않았으며, 수식 저장 누락은 이 릴리스의 수정 범위에 포함하지 않음
|
|
156
|
+
|
|
157
|
+
## 0.3.0 - 2026-01-28
|
|
158
|
+
|
|
159
|
+
- **대규모 XML persistence 수정**: 8개 조작에 대한 save-reload 지원 추가
|
|
160
|
+
- `insertTableRow` / `deleteTableRow`
|
|
161
|
+
- `insertTableColumn` / `deleteTableColumn`
|
|
162
|
+
- `copyParagraph` / `moveParagraph` (+ 같은 섹션 인덱스 버그 수정)
|
|
163
|
+
- `setHeader` / `setFooter`
|
|
164
|
+
- **depth-aware element indexing**: 중첩 태그 내부 요소를 무시하는 안전한 파싱
|
|
165
|
+
- **undo/redo 안전성**: pending 배열 초기화로 메모리/XML 비동기화 방지
|
|
166
|
+
- **replaceText 수정**: XML entity 불일치 해결
|
|
167
|
+
- **mergeCells 수정**: indexOf 모호성 해결
|
|
168
|
+
- **테스트**: 24개 E2E 테스트 (16 기본 + 8 persistence)
|
|
169
|
+
|
|
170
|
+
## 0.2.0
|
|
171
|
+
|
|
172
|
+
- **신규 기능**: 테이블 셀 내 내어쓰기(Hanging Indent) 자동 적용
|
|
173
|
+
- `update_table_cell` 시 마커(○, 1., 가., (1) 등) 감지하여 자동 내어쓰기
|
|
174
|
+
- 멀티라인 텍스트의 각 줄에 독립적으로 내어쓰기 적용
|
|
175
|
+
- `set_table_cell_hanging_indent`, `get_table_cell_hanging_indent` 도구 추가
|
|
176
|
+
- **버그 수정**: 병렬 테이블 업데이트 시 XML 손상 문제 해결
|
|
177
|
+
- 문서별 Lock 추가로 병렬 요청 직렬화 (race condition 방지)
|
|
178
|
+
- `findTableCellInXml()` 중첩 테이블 처리 개선 (balanced bracket 매칭)
|
|
179
|
+
- 여러 테이블 동시 수정 후 저장 시 "Broken tag structure" 오류 수정
|
|
180
|
+
- **버그 수정**: 여러 테이블에 내어쓰기 적용 시 stale position 문제 해결
|
|
181
|
+
- 테이블 인덱스 내림차순 처리로 위치 변경 영향 방지
|
|
182
|
+
- 각 테이블 처리 시 위치 정보 재계산
|
|
183
|
+
- **테스트 강화**: Red Team 스트레스 테스트 추가 (238개 테스트)
|
|
184
|
+
- 50~200개 테이블 대량 수정 테스트
|
|
185
|
+
- 중첩 테이블 + 내어쓰기 + 이미지 복합 테스트
|
|
186
|
+
- 병렬 업데이트 시나리오 테스트
|
|
187
|
+
|
|
188
|
+
## 0.1.1
|
|
189
|
+
|
|
190
|
+
- **버그 수정**: `update_table_cell` 후 `save_document` 시 빈 셀 변경사항이 저장되지 않던 문제 수정
|
|
191
|
+
- Self-closing XML run 태그 (`<hp:run ... />`) 처리 지원 추가
|
|
192
|
+
- ID 기반 테이블 매칭으로 정확한 XML 업데이트 구현
|
|
193
|
+
- 원본 XML 구조를 최대한 보존하면서 텍스트만 수정
|
|
194
|
+
|
|
195
|
+
## 0.1.0
|
|
196
|
+
|
|
197
|
+
- 최초 릴리스
|
|
198
|
+
|
|
199
|
+
[0.3.3]: https://github.com/Dayoooun/hwpx-mcp/compare/v0.3.2...v0.3.3
|
|
200
|
+
[0.3.2]: https://github.com/Dayoooun/hwpx-mcp/compare/v0.3.1...v0.3.2
|
|
201
|
+
[0.3.1]: https://github.com/Dayoooun/hwpx-mcp/releases/tag/v0.3.1
|
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# HWPX MCP Server — `@
|
|
1
|
+
# HWPX MCP Server — `@kimdayoun/hwpx-mcp`
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/@kimdayoun/hwpx-mcp)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
[](https://modelcontextprotocol.io/)
|
|
6
6
|
|
|
7
7
|
> **이 저장소가 원본입니다.** 정본: https://github.com/Dayoooun/hwpx-mcp
|
|
8
|
-
> npm 배포본은 **`@
|
|
8
|
+
> npm 배포본은 **`@kimdayoun/hwpx-mcp`** 하나뿐입니다.
|
|
9
9
|
> `hwpx-mcp`, `hwpx-mcp-server` 등 스코프 없는 동명 패키지는 이 프로젝트와 무관한 제3자 배포본입니다.
|
|
10
10
|
|
|
11
11
|
HWP/HWPX 문서를 AI로 읽고 편집할 수 있는 Model Context Protocol (MCP) 서버입니다.
|
|
@@ -21,13 +21,13 @@ HWP/HWPX 문서를 AI로 읽고 편집할 수 있는 Model Context Protocol (MCP
|
|
|
21
21
|
## 설치
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
npm install -g @
|
|
24
|
+
npm install -g @kimdayoun/hwpx-mcp
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
설치 없이 바로 실행하려면:
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
|
-
npx -y @
|
|
30
|
+
npx -y @kimdayoun/hwpx-mcp
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
소스에서 빌드하려면:
|
|
@@ -50,7 +50,7 @@ npm run build
|
|
|
50
50
|
"mcpServers": {
|
|
51
51
|
"hwpx-mcp": {
|
|
52
52
|
"command": "npx",
|
|
53
|
-
"args": ["-y", "@
|
|
53
|
+
"args": ["-y", "@kimdayoun/hwpx-mcp"]
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
}
|
|
@@ -66,7 +66,7 @@ npm run build
|
|
|
66
66
|
"mcpServers": {
|
|
67
67
|
"hwpx-mcp": {
|
|
68
68
|
"command": "npx",
|
|
69
|
-
"args": ["-y", "@
|
|
69
|
+
"args": ["-y", "@kimdayoun/hwpx-mcp"]
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
}
|
|
@@ -79,8 +79,8 @@ npm run build
|
|
|
79
79
|
|------|------|
|
|
80
80
|
| `get_tool_guide` | 도구 가이드 조회 |
|
|
81
81
|
| `open_document` | 문서 열기 (HWPX/HWP) |
|
|
82
|
-
| `create_document` | 새 HWPX 문서
|
|
83
|
-
| `save_document` | 문서
|
|
82
|
+
| `create_document` | 새 HWPX 문서 생성. `file_path`를 주면 이후 `save_document`가 그 경로에 씁니다 |
|
|
83
|
+
| `save_document` | 문서 저장. `output_path`(또는 `file_path`)로 대상 지정, 응답에 절대경로 반환 |
|
|
84
84
|
| `close_document` | 문서 닫기 |
|
|
85
85
|
| `list_open_documents` | 열린 문서 목록 |
|
|
86
86
|
| `get_document_metadata` | 메타데이터 조회 |
|
|
@@ -298,58 +298,39 @@ AI 동작:
|
|
|
298
298
|
|
|
299
299
|
## 테스트
|
|
300
300
|
|
|
301
|
+
테스트는 네 층으로 나뉘고, CI(`.github/workflows/mcp-server-ci.yml`)가 층마다 따로 돌려
|
|
302
|
+
하나라도 실패하면 merge 를 막습니다.
|
|
303
|
+
|
|
301
304
|
```bash
|
|
302
305
|
cd mcp-server
|
|
303
|
-
npm test #
|
|
304
|
-
|
|
305
|
-
|
|
306
|
+
npm test # 모든 층을 한 번에 (vitest)
|
|
307
|
+
npm run test:unit # 단위: src/**/*.test.ts, tests/unit
|
|
308
|
+
npm run test:module # 모듈: 문서 API → 저장 → 다시 열기로 판정
|
|
309
|
+
npm run test:regression # 회귀: 신고 1건당 파일 1개, 신고 문장을 주석으로 붙임
|
|
310
|
+
npm run test:e2e # 종단간: 빌드한 MCP 서버를 stdio 로 띄워 호출
|
|
311
|
+
npm run test:security # 빌드 후 실제 MCP 저장 경로 공격·반복 저장·실패 정리 검사
|
|
312
|
+
npm run test:versions -- 0.3.3 local # 같은 e2e 를 게시된 버전과 로컬 빌드에 돌려 표로 비교
|
|
306
313
|
```
|
|
307
314
|
|
|
315
|
+
e2e 는 `HWPX_MCP_SERVER` 로 대상 서버를 고릅니다. `local`(기본)은 이 저장소의
|
|
316
|
+
`dist/index.js`, `npm:0.3.3` 은 게시된 버전입니다. `local` 서버를 띄울 Node 는
|
|
317
|
+
`HWPX_MCP_NODE` 로 바꿉니다(CI 는 Node 18·22 로 돌립니다).
|
|
318
|
+
|
|
319
|
+
문단 저장 회귀 테스트는 개인 PC의 문서 경로 대신 합성 HWPX를 사용합니다.
|
|
320
|
+
여러 `hp:t`로 나뉜 텍스트·빈 문자열·XML 특수문자·동일한 문단 ID/본문의 대상 선택을 검사하며,
|
|
321
|
+
중첩 표 삭제는 최상위 표 목록과 셀 내부 중첩 표의 보존을 각각 확인합니다.
|
|
322
|
+
|
|
308
323
|
## 알려진 제한사항
|
|
309
324
|
|
|
310
325
|
- **각주/미주/북마크/하이퍼링크 삽입**: 메모리에서만 동작, save 후 XML 미반영 (읽기는 정상)
|
|
311
326
|
- **HWP 파일**: 읽기 전용 (편집 불가)
|
|
312
327
|
- **secPr 문단 스타일**: 첫 번째 특수 문단에서 스타일 reload 제한
|
|
328
|
+
- **파일 접근 범위**: 현재 서버는 작업 폴더 밖의 절대경로·상위경로·디렉터리 심볼릭 링크를 차단하지 않습니다. 신뢰하는 로컬 MCP 클라이언트에서만 사용하고, OS 권한 또는 컨테이너로 접근 범위를 제한하세요. `stdio` 실행을 네트워크 인증·격리로 간주하면 안 됩니다.
|
|
329
|
+
- **저장 안전성**: `save_document`는 목적지와 같은 디렉터리 안에 비공개 임시 디렉터리를 만들고 검증 후 rename합니다. 기존 `.tmp` 파일은 사용하지 않으며, `.bak`이 심볼릭 링크 등 일반 파일이 아니면 저장을 거부합니다. 이 조치는 작업 폴더 밖 접근 제한을 대신하지 않습니다.
|
|
313
330
|
|
|
314
331
|
## 변경 이력
|
|
315
332
|
|
|
316
|
-
|
|
317
|
-
- **대규모 XML persistence 수정**: 8개 조작에 대한 save-reload 지원 추가
|
|
318
|
-
- `insertTableRow` / `deleteTableRow`
|
|
319
|
-
- `insertTableColumn` / `deleteTableColumn`
|
|
320
|
-
- `copyParagraph` / `moveParagraph` (+ 같은 섹션 인덱스 버그 수정)
|
|
321
|
-
- `setHeader` / `setFooter`
|
|
322
|
-
- **depth-aware element indexing**: 중첩 태그 내부 요소를 무시하는 안전한 파싱
|
|
323
|
-
- **undo/redo 안전성**: pending 배열 초기화로 메모리/XML 비동기화 방지
|
|
324
|
-
- **replaceText 수정**: XML entity 불일치 해결
|
|
325
|
-
- **mergeCells 수정**: indexOf 모호성 해결
|
|
326
|
-
- **테스트**: 24개 E2E 테스트 (16 기본 + 8 persistence)
|
|
327
|
-
|
|
328
|
-
### 0.2.0
|
|
329
|
-
- **신규 기능**: 테이블 셀 내 내어쓰기(Hanging Indent) 자동 적용
|
|
330
|
-
- `update_table_cell` 시 마커(○, 1., 가., (1) 등) 감지하여 자동 내어쓰기
|
|
331
|
-
- 멀티라인 텍스트의 각 줄에 독립적으로 내어쓰기 적용
|
|
332
|
-
- `set_table_cell_hanging_indent`, `get_table_cell_hanging_indent` 도구 추가
|
|
333
|
-
- **버그 수정**: 병렬 테이블 업데이트 시 XML 손상 문제 해결
|
|
334
|
-
- 문서별 Lock 추가로 병렬 요청 직렬화 (race condition 방지)
|
|
335
|
-
- `findTableCellInXml()` 중첩 테이블 처리 개선 (balanced bracket 매칭)
|
|
336
|
-
- 여러 테이블 동시 수정 후 저장 시 "Broken tag structure" 오류 수정
|
|
337
|
-
- **버그 수정**: 여러 테이블에 내어쓰기 적용 시 stale position 문제 해결
|
|
338
|
-
- 테이블 인덱스 내림차순 처리로 위치 변경 영향 방지
|
|
339
|
-
- 각 테이블 처리 시 위치 정보 재계산
|
|
340
|
-
- **테스트 강화**: Red Team 스트레스 테스트 추가 (238개 테스트)
|
|
341
|
-
- 50~200개 테이블 대량 수정 테스트
|
|
342
|
-
- 중첩 테이블 + 내어쓰기 + 이미지 복합 테스트
|
|
343
|
-
- 병렬 업데이트 시나리오 테스트
|
|
344
|
-
|
|
345
|
-
### 0.1.1
|
|
346
|
-
- **버그 수정**: `update_table_cell` 후 `save_document` 시 빈 셀 변경사항이 저장되지 않던 문제 수정
|
|
347
|
-
- Self-closing XML run 태그 (`<hp:run ... />`) 처리 지원 추가
|
|
348
|
-
- ID 기반 테이블 매칭으로 정확한 XML 업데이트 구현
|
|
349
|
-
- 원본 XML 구조를 최대한 보존하면서 텍스트만 수정
|
|
350
|
-
|
|
351
|
-
### 0.1.0
|
|
352
|
-
- 최초 릴리스
|
|
333
|
+
버전별 변경 사항은 [CHANGELOG.md](./CHANGELOG.md) 를 참고하세요.
|
|
353
334
|
|
|
354
335
|
## 라이선스
|
|
355
336
|
|