@kodocagent/cli 0.6.0 → 0.6.1

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/dist/index.js CHANGED
@@ -9948,7 +9948,9 @@ var DOCUMENT_RULES_SECTION = `## \uBB38\uC11C \uADDC\uCE59
9948
9948
  5. \uACBD\uB85C\uB294 \uD604\uC7AC \uC791\uC5C5 \uB514\uB809\uD130\uB9AC\uB97C \uAE30\uC900\uC73C\uB85C \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.
9949
9949
  6. \uC0AC\uC6A9\uC790\uAC00 \uC218\uC815\uC548\uC744 \uAC70\uC808\uD558\uBA74 \uAC19\uC740 \uC81C\uC548\uC744 \uC790\uB3D9\uC73C\uB85C \uBC18\uBCF5\uD558\uC9C0 \uB9D0\uACE0, \uC0AC\uC6A9\uC790\uC758 \uB2E4\uC74C \uC9C0\uC2DC\uB97C \uAE30\uB2E4\uB9AC\uC138\uC694.
9950
9950
  7. \uD070 \uBB38\uC11C\uB294 \uBA3C\uC800 \`outline\`\uC73C\uB85C \uAD6C\uC870\uB97C \uD30C\uC545\uD558\uACE0, \`search\`\uB098 \`pages\`\uB85C \uD544\uC694\uD55C \uBD80\uBD84\uB9CC \uC77D\uC5B4 \uCEE8\uD14D\uC2A4\uD2B8\uB97C \uC544\uB07C\uC138\uC694.
9951
- 8. \uC0AC\uC6A9\uC790\uAC00 \uC9C1\uC804 \uBCC0\uACBD\uC744 \uB418\uB3CC\uB9AC\uAE38 \uC6D0\uD558\uBA74 \`list_backups\`\uB85C \uBC31\uC5C5\uC744 \uD655\uC778\uD558\uACE0 \`restore_backup\`\uC73C\uB85C \uBCF5\uC6D0\uD558\uC138\uC694. \uBCF5\uC6D0\uB3C4 \uC2B9\uC778\uC744 \uAC70\uCE58\uBA70, \uBCF5\uC6D0 \uC804 \uD604\uC7AC \uC0C1\uD0DC\uAC00 \uC790\uB3D9 \uBC31\uC5C5\uB429\uB2C8\uB2E4.`;
9951
+ 8. \uC0AC\uC6A9\uC790\uAC00 \uC9C1\uC804 \uBCC0\uACBD\uC744 \uB418\uB3CC\uB9AC\uAE38 \uC6D0\uD558\uBA74 \`list_backups\`\uB85C \uBC31\uC5C5\uC744 \uD655\uC778\uD558\uACE0 \`restore_backup\`\uC73C\uB85C \uBCF5\uC6D0\uD558\uC138\uC694. \uBCF5\uC6D0\uB3C4 \uC2B9\uC778\uC744 \uAC70\uCE58\uBA70, \uBCF5\uC6D0 \uC804 \uD604\uC7AC \uC0C1\uD0DC\uAC00 \uC790\uB3D9 \uBC31\uC5C5\uB429\uB2C8\uB2E4.
9952
+ 9. \uC218\uC815\xB7\uAD50\uC815\xB7\uBCC0\uACBD \uC694\uCCAD\uC744 \uBC1B\uACE0 \uBB34\uC5C7\uC744 \uBC14\uAFD4\uC57C \uD560\uC9C0 \uBB38\uC11C\uC5D0\uC11C \uC2A4\uC2A4\uB85C \uD310\uB2E8\uD560 \uC218 \uC788\uC73C\uBA74, \uBC1C\uACAC\uD55C \uC624\uB958\xB7\uBCC0\uACBD\uC810\uC744 \uC124\uBA85\xB7\uBAA9\uB85D\uC73C\uB85C\uB9CC \uCD9C\uB825\uD558\uACE0 \uBA48\uCD94\uC9C0 \uB9D0\uACE0 **\uBC18\uB4DC\uC2DC \`propose_*\` \uB3C4\uAD6C\uB85C \uC2E4\uC81C \uC218\uC815\uC548\uC744 \uC81C\uC548**\uD558\uC138\uC694(\uC801\uC6A9\uC740 \uC2B9\uC778 \uD6C4). \uD544\uC694\uD55C \uC815\uBCF4\uAC00 \uC5C6\uC744 \uB54C\uB9CC \uC9C8\uBB38\uD569\uB2C8\uB2E4(\uD3B8\uC9D1 \uC548\uC804 \uADDC\uCE59 8).
9953
+ 10. "\uBAA8\uB450/\uC804\uBD80/\uC77C\uAD04"\uCC98\uB7FC \uC5EC\uB7EC \uD56D\uBAA9\xB7\uD328\uD134\uC744 \uD55C\uAEBC\uBC88\uC5D0 \uBC14\uAFB8\uB294 \uC694\uCCAD\uC740 \uC77C\uBD80\uB9CC \uCC98\uB9AC\uD558\uC9C0 \uB9D0\uACE0 **\uBE60\uC9D0\uC5C6\uC774 \uC804\uBD80** \uCC98\uB9AC\uD558\uACE0, \uC801\uC6A9 \uD6C4 \uB204\uB77D\uB41C \uD56D\uBAA9\uC774 \uC5C6\uB294\uC9C0 \uB2E4\uC2DC \uD655\uC778\uD558\uC138\uC694(\uC608: \uB0A0\uC9DC \uD615\uC2DD\uC774 3\uAC00\uC9C0\uBA74 3\uAC00\uC9C0 \uBAA8\uB450).`;
9952
9954
  var EDIT_SAFETY_SECTION = `## \uD3B8\uC9D1 \uC548\uC804 \uADDC\uCE59
9953
9955
 
9954
9956
  1. \uC694\uCCAD\uBC1B\uC740 \uBD80\uBD84\uB9CC \uC218\uC815\uD558\uACE0, \uC694\uCCAD\uD558\uC9C0 \uC54A\uC740 \uBB38\uC7A5\xB7\uC11C\uC2DD\xB7\uAD6C\uC870\xB7\uD45C\uD604\uC740 \uADF8\uB300\uB85C \uB461\uB2C8\uB2E4. \uBB38\uC11C \uC804\uCCB4\uB97C \uC784\uC758\uB85C \uC7AC\uC791\uC131\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
@@ -9957,7 +9959,8 @@ var EDIT_SAFETY_SECTION = `## \uD3B8\uC9D1 \uC548\uC804 \uADDC\uCE59
9957
9959
  4. \uC804\uBB38 \uC6A9\uC5B4\uB294 \uC784\uC758\uB85C \uB2E4\uB978 \uD45C\uD604\uC73C\uB85C \uBC14\uAFB8\uC9C0 \uC54A\uACE0 \uBB38\uC11C \uC804\uCCB4\uC5D0\uC11C \uC77C\uAD00\uB418\uAC8C \uC720\uC9C0\uD569\uB2C8\uB2E4.
9958
9960
  5. \uACC4\uC57D\uC11C\xB7\uC57D\uAD00\xB7\uACF5\uC2DC\xB7\uB17C\uBB38 \uB4F1 \uBC95\uC801\xB7\uACF5\uC2DD \uBB38\uC11C\uB294 \uB2E8\uC5B4 \uD558\uB098\uAC00 \uC758\uBBF8\uB97C \uBC14\uAFC0 \uC218 \uC788\uC73C\uBBC0\uB85C, \uD45C\uD604\uC744 \uC790\uB3D9\uC73C\uB85C \uB2E4\uB4EC\uC9C0 \uB9D0\uACE0 \uC0AC\uC6A9\uC790\uAC00 \uC9C0\uC815\uD55C \uBCC0\uACBD\uB9CC \uC218\uD589\uD569\uB2C8\uB2E4.
9959
9961
  6. \uC758\uBBF8\uAC00 \uBC14\uB014 \uC218 \uC788\uB294 \uC218\uC815\uC740 \uC2E4\uD589 \uC804\uC5D0 \uADF8 \uC0AC\uC2E4\uC744 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC54C\uB9AC\uACE0, \uC218\uC815 \uC81C\uC548\uC758 \uC694\uC57D(summary)\uC5D0\uB294 \uBB34\uC5C7\uC744\xB7\uC65C \uBC14\uAFB8\uB294\uC9C0 \uD568\uAED8 \uC801\uC2B5\uB2C8\uB2E4.
9960
- 7. \uAC1C\uC778\uC815\uBCF4(\uC8FC\uBBFC\uB4F1\uB85D\uBC88\uD638\xB7\uC804\uD654\uBC88\uD638\xB7\uC774\uBA54\uC77C\xB7\uACC4\uC88C\xB7\uCE74\uB4DC\uBC88\uD638 \uB4F1) \uCC98\uB9AC: \uC0AC\uC6A9\uC790\uAC00 **\uD655\uC778\xB7\uC810\uAC80\uB9CC** \uC6D0\uD558\uBA74 \`scan_pii\`(\uC77D\uAE30 \uC804\uC6A9)\uB85C \uBCF4\uC5EC\uC8FC\uACE0, **\uAC00\uB9AC\uAE30\xB7\uB9C8\uC2A4\uD0B9\xB7\uBE44\uC2DD\uBCC4\xB7\uAC1C\uC778\uC815\uBCF4 \uC0AD\uC81C**\uB97C \uC6D0\uD558\uBA74 \`scan_pii\`\uC5D0\uC11C \uBA48\uCD94\uC9C0 \uB9D0\uACE0 \`propose_redact_pii\`\uB85C \uBC14\uB85C \uC218\uC815\uC548\uC744 \uC81C\uC548\uD558\uC138\uC694(\uC774 \uB3C4\uAD6C\uB3C4 \uC2B9\uC778\uC744 \uAC70\uCE58\uBBC0\uB85C \uC548\uC804\uD569\uB2C8\uB2E4).`;
9962
+ 7. \uAC1C\uC778\uC815\uBCF4(\uC8FC\uBBFC\uB4F1\uB85D\uBC88\uD638\xB7\uC804\uD654\uBC88\uD638\xB7\uC774\uBA54\uC77C\xB7\uACC4\uC88C\xB7\uCE74\uB4DC\uBC88\uD638 \uB4F1) \uCC98\uB9AC: \uC0AC\uC6A9\uC790\uAC00 **\uD655\uC778\xB7\uC810\uAC80\uB9CC** \uC6D0\uD558\uBA74 \`scan_pii\`(\uC77D\uAE30 \uC804\uC6A9)\uB85C \uBCF4\uC5EC\uC8FC\uACE0, **\uAC00\uB9AC\uAE30\xB7\uB9C8\uC2A4\uD0B9\xB7\uBE44\uC2DD\uBCC4\xB7\uAC1C\uC778\uC815\uBCF4 \uC0AD\uC81C**\uB97C \uC6D0\uD558\uBA74 \`scan_pii\`\uC5D0\uC11C \uBA48\uCD94\uC9C0 \uB9D0\uACE0 \`propose_redact_pii\`\uB85C \uBC14\uB85C \uC218\uC815\uC548\uC744 \uC81C\uC548\uD558\uC138\uC694(\uC774 \uB3C4\uAD6C\uB3C4 \uC2B9\uC778\uC744 \uAC70\uCE58\uBBC0\uB85C \uC548\uC804\uD569\uB2C8\uB2E4).
9963
+ 8. \uC694\uCCAD\uC774 \uBAA8\uB378\uC774 \uD655\uC2E4\uD788 \uC54C \uC218 \uC5C6\uB294 \uC815\uBCF4\uC5D0 \uC758\uC874\uD558\uBA74(\uD559\uC2B5 \uC2DC\uC810 \uC774\uD6C4\uC758 \uCD5C\uC2E0 \uBC95\uB839\xB7\uAE30\uC900\xB7\uACE0\uC2DC\xB7\uD1B5\uACC4 \uB4F1 \uC2DC\uC810 \uC758\uC874 \uC815\uBCF4, \uB610\uB294 \uBB38\uC11C\uC5D0 \uC5C6\uACE0 \uC0AC\uC6A9\uC790\uAC00 \uC8FC\uC9C0 \uC54A\uC740 \uAE30\uAD00\uBA85\xB7\uC870\uC9C1\uAC1C\uD3B8\xB7\uAE08\uC561 \uB4F1) \uCD94\uCE21\uD574 \uC9C4\uD589\uD558\uC9C0 \uB9D0\uACE0 **\uBB34\uC5C7\uC774 \uD544\uC694\uD55C\uC9C0 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBA3C\uC800 \uAD6C\uCCB4\uC801\uC73C\uB85C \uC9C8\uBB38**\uD558\uC138\uC694. \uD604\uD589 \uBC95\uB839\uC740 \`mcp__korean-law__*\`\uB85C, \uADF8 \uC678 \uC124\uC815\uB41C \uAC80\uC0C9 \uB3C4\uAD6C\uAC00 \uC788\uC73C\uBA74 \uADF8 \uB3C4\uAD6C\uB85C \uD655\uC778\uD574 \uCD9C\uCC98\uB97C \uBC1D\uD788\uACE0, \uD655\uC778 \uC218\uB2E8\uC774 \uC5C6\uC73C\uBA74 \uCD94\uC815\uC784\uC744 \uBA85\uC2DC\uD569\uB2C8\uB2E4. \uB418\uBB3C\uC744 \uC218 \uC5C6\uB294 \uBE44\uB300\uD654\uD615(\`-p\`) \uC2E4\uD589\uC5D0\uC120 \uAC00\uC815\uACFC \uBD88\uD655\uC2E4\uC131\uC744 \uACB0\uACFC\uC5D0 \uBA85\uC2DC\uD558\uC138\uC694.`;
9961
9964
  var LAW_RULES_SECTION = `## \uBC95\uB839 \uADDC\uCE59
9962
9965
 
9963
9966
  1. \uBC95\uB839 \uC778\uC6A9 \uD615\uC2DD: \u300C\uBC95\uB839\uBA85\u300D \uC81CN\uC870 \uC81CN\uD56D \uC81CN\uD638
@@ -10999,6 +11002,20 @@ import { stat as stat7 } from "fs/promises";
10999
11002
  import { extname as extname16 } from "path";
11000
11003
  import ExcelJS2 from "exceljs";
11001
11004
  import { z as z17 } from "zod";
11005
+ var OLE2_MAGIC = [208, 207, 17, 224, 161, 177, 26, 225];
11006
+ var ZIP_MAGIC_0 = 80;
11007
+ var ZIP_MAGIC_1 = 75;
11008
+ function isOle2Binary(bytes) {
11009
+ if (bytes.length < OLE2_MAGIC.length) return false;
11010
+ return OLE2_MAGIC.every((b, i) => bytes[i] === b);
11011
+ }
11012
+ function hwpStructuralGuard(ext, bytes) {
11013
+ const isHwpExt = ext === ".hwp";
11014
+ const isOle2 = isOle2Binary(bytes);
11015
+ if (!isHwpExt && !isOle2) return null;
11016
+ if (!isHwpExt && bytes[0] === ZIP_MAGIC_0 && bytes[1] === ZIP_MAGIC_1) return null;
11017
+ return "\uC774 \uC791\uC5C5(\uD45C\xB7\uC140\xB7\uC591\uC2DD\xB7\uCC3E\uAE30\uBC14\uAFB8\uAE30 \uB4F1 \uAD6C\uC870 \uD3B8\uC9D1)\uC740 `.hwpx` \uBB38\uC11C\uC5D0\uC11C \uC9C0\uC6D0\uB429\uB2C8\uB2E4. `.hwp`\uB294 OLE \uBC14\uC774\uB108\uB9AC\uB77C \uAD6C\uC870\uB97C \uBB34\uC190\uC2E4\uB85C \uD328\uCE58\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uD574\uACB0: (1) \uBCF8\uBB38 \uD14D\uC2A4\uD2B8\uB9CC \uACE0\uCE58\uB824\uBA74 `propose_edit`\uC744 \uC0AC\uC6A9\uD558\uC138\uC694(.hwp \uC81C\uC790\uB9AC \uD3B8\uC9D1). (2) \uD45C\xB7\uC140\xB7\uC591\uC2DD \uD3B8\uC9D1\uC774 \uD544\uC694\uD558\uBA74 \uD55C\uAE00\uC5D0\uC11C '\uB2E4\uB978 \uC774\uB984\uC73C\uB85C \uC800\uC7A5 \u2192 HWPX(.hwpx)'\uB85C \uBCC0\uD658\uD55C \uB4A4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.";
11018
+ }
11002
11019
  async function resolveSafePath(cwd, p) {
11003
11020
  const normalizedCwd = normalize(cwd).normalize("NFC");
11004
11021
  const normalizedP = p.normalize("NFC");
@@ -11856,10 +11873,7 @@ var proposeCellEditTool = {
11856
11873
  }) => {
11857
11874
  const safePath = await resolveSafePath(ctx.cwd, input.path);
11858
11875
  const ext = extname3(safePath).toLowerCase();
11859
- if (ext === ".hwp") {
11860
- return "\uC624\uB958: propose_cell_edit\uC740 .hwpx \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. .hwp(\uAD6C\uD615 OLE \uBC14\uC774\uB108\uB9AC)\uB294 \uC9C1\uC811 \uD3B8\uC9D1\uC774 \uBD88\uAC00\uD569\uB2C8\uB2E4. \uD55C\uAE00 \uD504\uB85C\uADF8\uB7A8\uC5D0\uC11C '\uB2E4\uB978 \uC774\uB984\uC73C\uB85C \uC800\uC7A5 \u2192 .hwpx'\uB85C \uC800\uC7A5\uD55C \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694. \uB610\uB294 propose_edit\uC744 \uC0AC\uC6A9\uD560 \uC218 \uC788\uC73C\uB098, \uBCD1\uD569 \uC140\uC774 \uC18C\uC2E4\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4.";
11861
- }
11862
- if (ext !== ".hwpx") {
11876
+ if (ext !== ".hwpx" && ext !== ".hwp") {
11863
11877
  return `\uC624\uB958: propose_cell_edit\uC740 .hwpx \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. \uD604\uC7AC \uD30C\uC77C: ${ext}. \uD45C \uC140 \uC9C1\uC811 \uD3B8\uC9D1\uC740 .hwpx \uD3EC\uB9F7\uC5D0\uC11C\uB9CC \uAC00\uB2A5\uD569\uB2C8\uB2E4.`;
11864
11878
  }
11865
11879
  let originalBuffer;
@@ -11868,6 +11882,11 @@ var proposeCellEditTool = {
11868
11882
  } catch {
11869
11883
  return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uAC70\uB098 read_document\uB85C \uBA3C\uC800 \uD655\uC778\uD558\uC138\uC694.`;
11870
11884
  }
11885
+ const originalBytes = new Uint8Array(originalBuffer.buffer);
11886
+ const structuralGuard = hwpStructuralGuard(ext, originalBytes);
11887
+ if (structuralGuard !== null) {
11888
+ return structuralGuard;
11889
+ }
11871
11890
  if (originalBuffer[0] !== 80 || originalBuffer[1] !== 75) {
11872
11891
  return "\uC624\uB958: \uD30C\uC77C\uC774 \uC720\uD6A8\uD55C .hwpx(ZIP) \uD3EC\uB9F7\uC774 \uC544\uB2D9\uB2C8\uB2E4. \uD30C\uC77C\uC774 \uC190\uC0C1\uB418\uC5C8\uAC70\uB098 \uAD6C\uD615 .hwp(OLE \uBC14\uC774\uB108\uB9AC) \uD3EC\uB9F7\uC785\uB2C8\uB2E4. \uD55C\uAE00 \uD504\uB85C\uADF8\uB7A8\uC5D0\uC11C .hwpx\uB85C \uC800\uC7A5 \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.";
11873
11892
  }
@@ -12603,12 +12622,13 @@ async function listFormObjectsFromZip(zip) {
12603
12622
  return { objects, sectionFiles, sectionXmls };
12604
12623
  }
12605
12624
  function validateHwpxBuffer(ext, buffer) {
12606
- if (ext === ".hwp") {
12607
- return "\uC624\uB958: \uC774 \uD234\uC740 .hwpx \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. .hwp(\uAD6C\uD615 OLE \uBC14\uC774\uB108\uB9AC)\uB294 \uC9C1\uC811 \uD3B8\uC9D1\uC774 \uBD88\uAC00\uD569\uB2C8\uB2E4. \uD55C\uAE00 \uD504\uB85C\uADF8\uB7A8\uC5D0\uC11C '\uB2E4\uB978 \uC774\uB984\uC73C\uB85C \uC800\uC7A5 \u2192 .hwpx'\uB85C \uC800\uC7A5\uD55C \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.";
12608
- }
12609
- if (ext !== ".hwpx") {
12625
+ if (ext !== ".hwpx" && ext !== ".hwp") {
12610
12626
  return `\uC624\uB958: \uC774 \uD234\uC740 .hwpx \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. \uD604\uC7AC \uD30C\uC77C \uD655\uC7A5\uC790: ${ext}`;
12611
12627
  }
12628
+ const structuralGuard = hwpStructuralGuard(ext, buffer);
12629
+ if (structuralGuard !== null) {
12630
+ return structuralGuard;
12631
+ }
12612
12632
  if (buffer[0] !== 80 || buffer[1] !== 75) {
12613
12633
  return "\uC624\uB958: \uD30C\uC77C\uC774 \uC720\uD6A8\uD55C .hwpx(ZIP) \uD3EC\uB9F7\uC774 \uC544\uB2D9\uB2C8\uB2E4. \uD30C\uC77C\uC774 \uC190\uC0C1\uB418\uC5C8\uAC70\uB098 \uAD6C\uD615 .hwp(OLE \uBC14\uC774\uB108\uB9AC) \uD3EC\uB9F7\uC785\uB2C8\uB2E4.";
12614
12634
  }
@@ -13379,10 +13399,7 @@ var proposeFindReplaceTool = {
13379
13399
  }) => {
13380
13400
  const safePath = await resolveSafePath(ctx.cwd, input.path);
13381
13401
  const ext = extname8(safePath).toLowerCase();
13382
- if (ext === ".hwp") {
13383
- return "\uC624\uB958: propose_find_replace\uB294 .hwpx \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. .hwp(\uAD6C\uD615 OLE \uBC14\uC774\uB108\uB9AC)\uB294 XML \uC9C1\uC811 \uD3B8\uC9D1\uC774 \uBD88\uAC00\uD569\uB2C8\uB2E4. \uD55C\uAE00 \uD504\uB85C\uADF8\uB7A8\uC5D0\uC11C '\uB2E4\uB978 \uC774\uB984\uC73C\uB85C \uC800\uC7A5 \u2192 .hwpx'\uB85C \uC800\uC7A5\uD55C \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.";
13384
- }
13385
- if (ext !== ".hwpx") {
13402
+ if (ext !== ".hwpx" && ext !== ".hwp") {
13386
13403
  return `\uC624\uB958: propose_find_replace\uB294 .hwpx \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. \uD604\uC7AC \uD30C\uC77C \uD655\uC7A5\uC790: ${ext}. .hwpx \uD30C\uC77C\uC744 \uC9C0\uC815\uD558\uC138\uC694.`;
13387
13404
  }
13388
13405
  let originalBuf;
@@ -13391,14 +13408,18 @@ var proposeFindReplaceTool = {
13391
13408
  } catch {
13392
13409
  return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
13393
13410
  }
13394
- if (originalBuf[0] !== 80 || originalBuf[1] !== 75) {
13395
- return "\uC624\uB958: \uD30C\uC77C\uC774 \uC720\uD6A8\uD55C .hwpx(ZIP) \uD3EC\uB9F7\uC774 \uC544\uB2D9\uB2C8\uB2E4. \uD30C\uC77C\uC774 \uC190\uC0C1\uB418\uC5C8\uAC70\uB098 \uAD6C\uD615 .hwp(OLE \uBC14\uC774\uB108\uB9AC) \uD3EC\uB9F7\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4. \uD55C\uAE00 \uD504\uB85C\uADF8\uB7A8\uC5D0\uC11C .hwpx\uB85C \uC800\uC7A5 \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.";
13396
- }
13397
13411
  const originalBytes = new Uint8Array(
13398
13412
  originalBuf.buffer,
13399
13413
  originalBuf.byteOffset,
13400
13414
  originalBuf.byteLength
13401
13415
  );
13416
+ const structuralGuard = hwpStructuralGuard(ext, originalBytes);
13417
+ if (structuralGuard !== null) {
13418
+ return structuralGuard;
13419
+ }
13420
+ if (originalBuf[0] !== 80 || originalBuf[1] !== 75) {
13421
+ return "\uC624\uB958: \uD30C\uC77C\uC774 \uC720\uD6A8\uD55C .hwpx(ZIP) \uD3EC\uB9F7\uC774 \uC544\uB2D9\uB2C8\uB2E4. \uD30C\uC77C\uC774 \uC190\uC0C1\uB418\uC5C8\uAC70\uB098 \uAD6C\uD615 .hwp(OLE \uBC14\uC774\uB108\uB9AC) \uD3EC\uB9F7\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4. \uD55C\uAE00 \uD504\uB85C\uADF8\uB7A8\uC5D0\uC11C .hwpx\uB85C \uC800\uC7A5 \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.";
13422
+ }
13402
13423
  let newBytes;
13403
13424
  let replacedCount;
13404
13425
  let diffSamples;
@@ -13505,6 +13526,13 @@ var proposeFormFillTool = {
13505
13526
  } catch {
13506
13527
  return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
13507
13528
  }
13529
+ const structuralGuard = hwpStructuralGuard(
13530
+ ext,
13531
+ new Uint8Array(originalBuffer.buffer, originalBuffer.byteOffset, originalBuffer.byteLength)
13532
+ );
13533
+ if (structuralGuard !== null) {
13534
+ return structuralGuard;
13535
+ }
13508
13536
  const parseResult = await parse3(originalBuffer.buffer);
13509
13537
  if (!parseResult.success) {
13510
13538
  const msg = kordocErrorMessage(
@@ -13681,29 +13709,30 @@ var proposeRedactPiiTool = {
13681
13709
  }) => {
13682
13710
  const safePath = await resolveSafePath(ctx.cwd, input.path);
13683
13711
  const ext = extname10(safePath).toLowerCase();
13684
- if (ext === ".hwp") {
13685
- return "\uC624\uB958: propose_redact_pii\uB294 .hwpx \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. .hwp(\uAD6C\uD615 OLE \uBC14\uC774\uB108\uB9AC)\uB294 XML \uC9C1\uC811 \uD3B8\uC9D1\uC774 \uBD88\uAC00\uD569\uB2C8\uB2E4. \uD55C\uAE00 \uD504\uB85C\uADF8\uB7A8\uC5D0\uC11C '\uB2E4\uB978 \uC774\uB984\uC73C\uB85C \uC800\uC7A5 \u2192 .hwpx'\uB85C \uC800\uC7A5\uD55C \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.";
13686
- }
13687
- if (ext !== ".hwpx" && ext !== ".md" && ext !== ".txt") {
13712
+ if (ext !== ".hwpx" && ext !== ".hwp" && ext !== ".md" && ext !== ".txt") {
13688
13713
  const hint = ext === ".docx" || ext === ".xlsx" ? " .hwpx/.md/.txt\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4." : " .hwpx/.md/.txt\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4.";
13689
13714
  return `\uC624\uB958: propose_redact_pii\uB294 .hwpx/.md/.txt \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. \uD604\uC7AC \uD30C\uC77C \uD655\uC7A5\uC790: ${ext}.${hint}`;
13690
13715
  }
13691
13716
  const { outputPath, willConvertFormat } = resolveOutputPath(safePath);
13692
- if (ext === ".hwpx") {
13717
+ if (ext === ".hwpx" || ext === ".hwp") {
13693
13718
  let originalBuf;
13694
13719
  try {
13695
13720
  originalBuf = await readFile10(safePath);
13696
13721
  } catch {
13697
13722
  return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}`;
13698
13723
  }
13699
- if (originalBuf[0] !== 80 || originalBuf[1] !== 75) {
13700
- return "\uC624\uB958: \uD30C\uC77C\uC774 \uC720\uD6A8\uD55C .hwpx(ZIP) \uD3EC\uB9F7\uC774 \uC544\uB2D9\uB2C8\uB2E4. \uD30C\uC77C\uC774 \uC190\uC0C1\uB418\uC5C8\uAC70\uB098 \uAD6C\uD615 .hwp(OLE \uBC14\uC774\uB108\uB9AC) \uD3EC\uB9F7\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4.";
13701
- }
13702
13724
  const originalBytes = new Uint8Array(
13703
13725
  originalBuf.buffer,
13704
13726
  originalBuf.byteOffset,
13705
13727
  originalBuf.byteLength
13706
13728
  );
13729
+ const structuralGuard = hwpStructuralGuard(ext, originalBytes);
13730
+ if (structuralGuard !== null) {
13731
+ return structuralGuard;
13732
+ }
13733
+ if (originalBuf[0] !== 80 || originalBuf[1] !== 75) {
13734
+ return "\uC624\uB958: \uD30C\uC77C\uC774 \uC720\uD6A8\uD55C .hwpx(ZIP) \uD3EC\uB9F7\uC774 \uC544\uB2D9\uB2C8\uB2E4. \uD30C\uC77C\uC774 \uC190\uC0C1\uB418\uC5C8\uAC70\uB098 \uAD6C\uD615 .hwp(OLE \uBC14\uC774\uB108\uB9AC) \uD3EC\uB9F7\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4.";
13735
+ }
13707
13736
  let patchResult;
13708
13737
  try {
13709
13738
  patchResult = await applyRedactToHwpx(originalBytes);
@@ -14609,10 +14638,7 @@ var proposeTableStructureTool = {
14609
14638
  }) => {
14610
14639
  const safePath = await resolveSafePath(ctx.cwd, input.path);
14611
14640
  const ext = extname12(safePath).toLowerCase();
14612
- if (ext === ".hwp") {
14613
- return "\uC624\uB958: propose_table_structure\uB294 .hwpx \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. .hwp(\uAD6C\uD615 OLE \uBC14\uC774\uB108\uB9AC)\uB294 XML \uC9C1\uC811 \uD3B8\uC9D1\uC774 \uBD88\uAC00\uD569\uB2C8\uB2E4. \uD55C\uAE00 \uD504\uB85C\uADF8\uB7A8\uC5D0\uC11C '\uB2E4\uB978 \uC774\uB984\uC73C\uB85C \uC800\uC7A5 \u2192 .hwpx'\uB85C \uC800\uC7A5\uD55C \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.";
14614
- }
14615
- if (ext !== ".hwpx") {
14641
+ if (ext !== ".hwpx" && ext !== ".hwp") {
14616
14642
  return `\uC624\uB958: propose_table_structure\uB294 .hwpx \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. \uD604\uC7AC \uD30C\uC77C \uD655\uC7A5\uC790: ${ext}. .hwpx \uD30C\uC77C\uC744 \uC9C0\uC815\uD558\uC138\uC694.`;
14617
14643
  }
14618
14644
  let originalBuf;
@@ -14621,14 +14647,18 @@ var proposeTableStructureTool = {
14621
14647
  } catch {
14622
14648
  return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
14623
14649
  }
14624
- if (originalBuf[0] !== 80 || originalBuf[1] !== 75) {
14625
- return "\uC624\uB958: \uD30C\uC77C\uC774 \uC720\uD6A8\uD55C .hwpx(ZIP) \uD3EC\uB9F7\uC774 \uC544\uB2D9\uB2C8\uB2E4. \uD30C\uC77C\uC774 \uC190\uC0C1\uB418\uC5C8\uAC70\uB098 \uAD6C\uD615 .hwp(OLE \uBC14\uC774\uB108\uB9AC) \uD3EC\uB9F7\uC785\uB2C8\uB2E4. \uD55C\uAE00 \uD504\uB85C\uADF8\uB7A8\uC5D0\uC11C .hwpx\uB85C \uC800\uC7A5 \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.";
14626
- }
14627
14650
  const originalBytes = new Uint8Array(
14628
14651
  originalBuf.buffer,
14629
14652
  originalBuf.byteOffset,
14630
14653
  originalBuf.byteLength
14631
14654
  );
14655
+ const structuralGuard = hwpStructuralGuard(ext, originalBytes);
14656
+ if (structuralGuard !== null) {
14657
+ return structuralGuard;
14658
+ }
14659
+ if (originalBuf[0] !== 80 || originalBuf[1] !== 75) {
14660
+ return "\uC624\uB958: \uD30C\uC77C\uC774 \uC720\uD6A8\uD55C .hwpx(ZIP) \uD3EC\uB9F7\uC774 \uC544\uB2D9\uB2C8\uB2E4. \uD30C\uC77C\uC774 \uC190\uC0C1\uB418\uC5C8\uAC70\uB098 \uAD6C\uD615 .hwp(OLE \uBC14\uC774\uB108\uB9AC) \uD3EC\uB9F7\uC785\uB2C8\uB2E4. \uD55C\uAE00 \uD504\uB85C\uADF8\uB7A8\uC5D0\uC11C .hwpx\uB85C \uC800\uC7A5 \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.";
14661
+ }
14632
14662
  let originalBlocks = null;
14633
14663
  try {
14634
14664
  const origResult = await parse4(originalBuf.buffer);