claude-code-hwp-mcp 0.5.1 → 0.5.2
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.
|
@@ -151,6 +151,9 @@ export function registerAnalysisTools(server, bridge, toolset = 'standard') {
|
|
|
151
151
|
// HWPX → XML 직접 검색 시도. EBUSY 시 COM 폴백.
|
|
152
152
|
if (bridge.getCurrentDocumentFormat() === 'HWPX') {
|
|
153
153
|
try {
|
|
154
|
+
// COM 메모리 변경사항을 파일에 반영 (XML 엔진이 최신 내용을 읽도록)
|
|
155
|
+
await bridge.ensureRunning();
|
|
156
|
+
await bridge.send('save_document', {});
|
|
154
157
|
const doc = await readHwpxXml(filePath, 'Contents/section0.xml');
|
|
155
158
|
const result = searchTextInSection(doc, search);
|
|
156
159
|
const limited = max_results ? result.results.slice(0, max_results) : result.results.slice(0, 50);
|
|
@@ -135,6 +135,9 @@ export function registerEditingTools(server, bridge, toolset = 'standard') {
|
|
|
135
135
|
// HWPX → XML 직접 치환 시도 (COM 우회). EBUSY 시 COM 폴백.
|
|
136
136
|
if (bridge.getCurrentDocumentFormat() === 'HWPX' && !use_regex) {
|
|
137
137
|
try {
|
|
138
|
+
// COM 메모리 변경사항을 파일에 반영 (XML 엔진이 최신 내용을 읽도록)
|
|
139
|
+
await bridge.ensureRunning();
|
|
140
|
+
await bridge.send('save_document', {});
|
|
138
141
|
const doc = await readHwpxXml(filePath, 'Contents/section0.xml');
|
|
139
142
|
const count = replaceTextInSection(doc, find, replace);
|
|
140
143
|
await writeHwpxXml(filePath, filePath, 'Contents/section0.xml', doc);
|
|
@@ -183,6 +186,9 @@ export function registerEditingTools(server, bridge, toolset = 'standard') {
|
|
|
183
186
|
// HWPX → XML 직접 다건 치환 시도. EBUSY 시 COM 폴백.
|
|
184
187
|
if (bridge.getCurrentDocumentFormat() === 'HWPX' && !use_regex) {
|
|
185
188
|
try {
|
|
189
|
+
// COM 메모리 변경사항을 파일에 반영
|
|
190
|
+
await bridge.ensureRunning();
|
|
191
|
+
await bridge.send('save_document', {});
|
|
186
192
|
const doc = await readHwpxXml(filePath, 'Contents/section0.xml');
|
|
187
193
|
const results = [];
|
|
188
194
|
let totalCount = 0;
|
|
@@ -235,6 +241,8 @@ export function registerEditingTools(server, bridge, toolset = 'standard') {
|
|
|
235
241
|
// HWPX → XML 직접 조작 시도. EBUSY 시 COM 폴백.
|
|
236
242
|
if (bridge.getCurrentDocumentFormat() === 'HWPX' && !color) {
|
|
237
243
|
try {
|
|
244
|
+
await bridge.ensureRunning();
|
|
245
|
+
await bridge.send('save_document', {});
|
|
238
246
|
const doc = await readHwpxXml(filePath, 'Contents/section0.xml');
|
|
239
247
|
const found = findAndAppendInSection(doc, find, append_text);
|
|
240
248
|
if (!found) {
|
|
@@ -418,6 +426,8 @@ export function registerEditingTools(server, bridge, toolset = 'standard') {
|
|
|
418
426
|
// HWPX → XML 직접 N번째 치환 시도. EBUSY 시 COM 폴백.
|
|
419
427
|
if (bridge.getCurrentDocumentFormat() === 'HWPX') {
|
|
420
428
|
try {
|
|
429
|
+
await bridge.ensureRunning();
|
|
430
|
+
await bridge.send('save_document', {});
|
|
421
431
|
const doc = await readHwpxXml(filePath, 'Contents/section0.xml');
|
|
422
432
|
const replaced = replaceTextNthInSection(doc, find, replace, nth);
|
|
423
433
|
if (replaced) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-code-hwp-mcp",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "MCP server for HWP (한글) document automation via pyhwpx COM API. 94 tools for document editing, analysis, table formatting, and AI-powered filling.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
package/python/hwp_service.py
CHANGED
|
@@ -201,6 +201,12 @@ def dispatch(hwp, method, params):
|
|
|
201
201
|
validate_params(params, ["path"], method)
|
|
202
202
|
save_path = validate_file_path(params["path"], must_exist=False)
|
|
203
203
|
fmt = params.get("format", "HWP").upper() # pyhwpx는 대문자 포맷 필요 (HWP, HWPX, PDF 등)
|
|
204
|
+
# 내보내기 전 현재 문서 저장 (COM 메모리 → 파일 반영, 빈 PDF 방지)
|
|
205
|
+
if _current_doc_path and fmt in ("PDF", "DOCX", "HTML"):
|
|
206
|
+
try:
|
|
207
|
+
hwp.save()
|
|
208
|
+
except Exception:
|
|
209
|
+
pass
|
|
204
210
|
hwp.save_as(save_path, fmt)
|
|
205
211
|
# 파일 실제 생성 확인
|
|
206
212
|
if not os.path.exists(save_path):
|
|
@@ -654,6 +660,21 @@ def dispatch(hwp, method, params):
|
|
|
654
660
|
validate_params(params, ["path", "format"], method)
|
|
655
661
|
save_path = validate_file_path(params["path"], must_exist=False)
|
|
656
662
|
fmt = params["format"].upper() # HWP, HWPX, PDF, HTML, TXT 등
|
|
663
|
+
# DOCX/HTML은 HWP COM에서 미지원 — 타임아웃 방지
|
|
664
|
+
if fmt in ("DOCX", "DOC"):
|
|
665
|
+
return {"status": "not_supported",
|
|
666
|
+
"message": "DOCX 직접 내보내기는 한/글 COM에서 지원되지 않습니다. PDF로 내보내기를 권장합니다.",
|
|
667
|
+
"alternative": "hwp_export_pdf"}
|
|
668
|
+
if fmt == "HTML":
|
|
669
|
+
return {"status": "not_supported",
|
|
670
|
+
"message": "HTML 직접 내보내기는 한/글 COM에서 지원되지 않습니다. hwp_get_as_markdown으로 마크다운 변환 후 HTML로 변환하세요.",
|
|
671
|
+
"alternative": "hwp_get_as_markdown"}
|
|
672
|
+
# PDF/내보내기 전 현재 문서 저장 (COM 메모리 → 파일 반영, 빈 PDF 방지)
|
|
673
|
+
if _current_doc_path:
|
|
674
|
+
try:
|
|
675
|
+
hwp.save()
|
|
676
|
+
except Exception:
|
|
677
|
+
pass
|
|
657
678
|
result = hwp.save_as(save_path, fmt)
|
|
658
679
|
# 파일 실제 생성 확인
|
|
659
680
|
file_exists = os.path.exists(save_path)
|
|
@@ -665,6 +686,12 @@ def dispatch(hwp, method, params):
|
|
|
665
686
|
if method == "verify_layout":
|
|
666
687
|
# PDF로 내보내고 PNG 이미지로 변환 → Claude Code의 Read로 시각적 검증
|
|
667
688
|
import tempfile
|
|
689
|
+
# 먼저 현재 문서 저장 (COM 메모리 → 파일 반영, 빈 PDF 방지)
|
|
690
|
+
if _current_doc_path:
|
|
691
|
+
try:
|
|
692
|
+
hwp.save()
|
|
693
|
+
except Exception:
|
|
694
|
+
pass
|
|
668
695
|
tmp_pdf = os.path.join(tempfile.gettempdir(), "hwp_verify_layout.pdf")
|
|
669
696
|
try:
|
|
670
697
|
hwp.save_as(tmp_pdf, "PDF")
|