@kodocagent/cli 0.6.0 → 0.6.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.
package/dist/index.js CHANGED
@@ -9925,6 +9925,7 @@ function buildSystemPrompt(ctx) {
9925
9925
  ROLE_SECTION,
9926
9926
  DOCUMENT_RULES_SECTION,
9927
9927
  EDIT_SAFETY_SECTION,
9928
+ buildCapabilitiesSection(ctx.toolNames),
9928
9929
  LAW_RULES_SECTION
9929
9930
  ].join("\n\n");
9930
9931
  const dynamic = buildDynamicContext(ctx);
@@ -9948,7 +9949,9 @@ var DOCUMENT_RULES_SECTION = `## \uBB38\uC11C \uADDC\uCE59
9948
9949
  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
9950
  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
9951
  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.`;
9952
+ 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.
9953
+ 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).
9954
+ 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
9955
  var EDIT_SAFETY_SECTION = `## \uD3B8\uC9D1 \uC548\uC804 \uADDC\uCE59
9953
9956
 
9954
9957
  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 +9960,17 @@ var EDIT_SAFETY_SECTION = `## \uD3B8\uC9D1 \uC548\uC804 \uADDC\uCE59
9957
9960
  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
9961
  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
9962
  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).`;
9963
+ 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).
9964
+ 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.`;
9965
+ function buildCapabilitiesSection(toolNames) {
9966
+ const docTools = toolNames.filter((n) => !n.startsWith("mcp__"));
9967
+ const available = docTools.length > 0 ? docTools.map((n) => `\`${n}\``).join(", ") : "(\uC5C6\uC74C)";
9968
+ return `## \uB2A5\uB825\xB7\uD55C\uACC4 (\uD604\uC7AC \uB3C4\uAD6C\uB85C \uAC00\uB2A5\uD55C \uAC83\uACFC \uC544\uB2CC \uAC83)
9969
+
9970
+ \uAC00\uB2A5: **\uC544\uB798 \uB4F1\uB85D\uB41C \uB3C4\uAD6C\uAC00 \uB108\uC758 \uB2A5\uB825 \uC804\uBD80\uB2E4**(\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0\uC11C \uC790\uB3D9 \uBC18\uC601) \u2014 ${available}. \uC5F0\uACB0\uB41C MCP \uB3C4\uAD6C\uAC00 \uC788\uC73C\uBA74 \uD568\uAED8 \uC0AC\uC6A9\uD558\uC138\uC694(\uC544\uB798 \uCEE8\uD14D\uC2A4\uD2B8 \uCC38\uC870).
9971
+ \uD604\uC7AC \uBD88\uAC00(\uC694\uCCAD\uBC1B\uC73C\uBA74 \uC194\uC9C1\uD788 \uC54C\uB9B4 \uAC83): \uC704 \uB3C4\uAD6C\uB85C \uCC98\uB9AC\uD560 \uC218 \uC5C6\uB294 \uC791\uC5C5 \u2014 \uAE00\uAF34\xB7\uAD75\uAC8C\xB7\uC904\uAC04\uACA9 \uB4F1 \uBB38\uC790/\uBB38\uB2E8 \uC11C\uC2DD\uACFC \uC81C\uBAA9 \uC2A4\uD0C0\uC77C \uC77C\uAD00\uD654, \uBA38\uB9AC\uB9D0/\uAF2C\uB9AC\uB9D0\xB7\uCABD\uBC88\uD638 \uB808\uC774\uC544\uC6C3/\uC11C\uC2DD, \uAC01\uC8FC \uC0BD\uC785\xB7\uD615\uC2DD, \uBAA9\uCC28\xB7\uAC1C\uC694\uBC88\uD638 \uC790\uB3D9 \uAC31\uC2E0, \uADF8\uB9BC\xB7\uD45C \uBC88\uD638 \uC0C1\uD638\uCC38\uC870, \uC774\uBBF8\uC9C0\xB7\uB3C4\uD615\xB7\uC870\uC9C1\uB3C4 \uD3B8\uC9D1, \uC911\uCCA9(\uBCF5\uD569)\uD45C \uC548\uCABD \uC140 \uC9C0\uC815.
9972
+ \uBCF5\uC7A1\uD558\uAC70\uB098 \uC5EC\uB7EC \uC791\uC5C5\uC774 \uC11E\uC778 \uC694\uCCAD\uC740 \uBA3C\uC800 \uBB34\uC5C7\uC744 \uC5B4\uB5A4 \uB3C4\uAD6C\uB85C \uD560\uC9C0 \uAC04\uB2E8\uD788 \uC815\uB9AC\uD558\uACE0, \uC704 \uB3C4\uAD6C\uB85C \uC548 \uB418\uB294 \uBD80\uBD84\uC774 \uC788\uC73C\uBA74 **\uCD94\uCE21\uD574 \uC5B4\uC124\uD504\uAC8C \uC2DC\uB3C4\uD558\uC9C0 \uB9D0\uACE0 \uADF8 \uC0AC\uC2E4\uC744 \uBA3C\uC800 \uC54C\uB9B0 \uB4A4** \uAC00\uB2A5\uD55C \uBD80\uBD84\uB9CC \uC9C4\uD589\uD558\uAC70\uB098 \uB300\uC548\uC744 \uC548\uB0B4\uD558\uC138\uC694. \uB2E8\uC21C\xB7\uB2E8\uC77C \uC694\uCCAD\uC740 \uACE7\uBC14\uB85C \uC9C4\uD589\uD569\uB2C8\uB2E4.`;
9973
+ }
9961
9974
  var LAW_RULES_SECTION = `## \uBC95\uB839 \uADDC\uCE59
9962
9975
 
9963
9976
  1. \uBC95\uB839 \uC778\uC6A9 \uD615\uC2DD: \u300C\uBC95\uB839\uBA85\u300D \uC81CN\uC870 \uC81CN\uD56D \uC81CN\uD638
@@ -10126,7 +10139,8 @@ var AgentSession = class {
10126
10139
  const system = buildSystemPrompt({
10127
10140
  cwd: this.opts.cwd,
10128
10141
  mcpServers: this.opts.mcpServers ?? [],
10129
- openDocuments: this.openDocuments
10142
+ openDocuments: this.openDocuments,
10143
+ toolNames: tools.toolNames
10130
10144
  });
10131
10145
  const aiSdkTools = tools.toAiSdkTools();
10132
10146
  this.messages = compactMessages(this.messages, config.maxContextTokens);
@@ -10999,6 +11013,20 @@ import { stat as stat7 } from "fs/promises";
10999
11013
  import { extname as extname16 } from "path";
11000
11014
  import ExcelJS2 from "exceljs";
11001
11015
  import { z as z17 } from "zod";
11016
+ var OLE2_MAGIC = [208, 207, 17, 224, 161, 177, 26, 225];
11017
+ var ZIP_MAGIC_0 = 80;
11018
+ var ZIP_MAGIC_1 = 75;
11019
+ function isOle2Binary(bytes) {
11020
+ if (bytes.length < OLE2_MAGIC.length) return false;
11021
+ return OLE2_MAGIC.every((b, i) => bytes[i] === b);
11022
+ }
11023
+ function hwpStructuralGuard(ext, bytes) {
11024
+ const isHwpExt = ext === ".hwp";
11025
+ const isOle2 = isOle2Binary(bytes);
11026
+ if (!isHwpExt && !isOle2) return null;
11027
+ if (!isHwpExt && bytes[0] === ZIP_MAGIC_0 && bytes[1] === ZIP_MAGIC_1) return null;
11028
+ 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.";
11029
+ }
11002
11030
  async function resolveSafePath(cwd, p) {
11003
11031
  const normalizedCwd = normalize(cwd).normalize("NFC");
11004
11032
  const normalizedP = p.normalize("NFC");
@@ -11856,10 +11884,7 @@ var proposeCellEditTool = {
11856
11884
  }) => {
11857
11885
  const safePath = await resolveSafePath(ctx.cwd, input.path);
11858
11886
  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") {
11887
+ if (ext !== ".hwpx" && ext !== ".hwp") {
11863
11888
  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
11889
  }
11865
11890
  let originalBuffer;
@@ -11868,6 +11893,11 @@ var proposeCellEditTool = {
11868
11893
  } catch {
11869
11894
  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
11895
  }
11896
+ const originalBytes = new Uint8Array(originalBuffer.buffer);
11897
+ const structuralGuard = hwpStructuralGuard(ext, originalBytes);
11898
+ if (structuralGuard !== null) {
11899
+ return structuralGuard;
11900
+ }
11871
11901
  if (originalBuffer[0] !== 80 || originalBuffer[1] !== 75) {
11872
11902
  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
11903
  }
@@ -12603,12 +12633,13 @@ async function listFormObjectsFromZip(zip) {
12603
12633
  return { objects, sectionFiles, sectionXmls };
12604
12634
  }
12605
12635
  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") {
12636
+ if (ext !== ".hwpx" && ext !== ".hwp") {
12610
12637
  return `\uC624\uB958: \uC774 \uD234\uC740 .hwpx \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. \uD604\uC7AC \uD30C\uC77C \uD655\uC7A5\uC790: ${ext}`;
12611
12638
  }
12639
+ const structuralGuard = hwpStructuralGuard(ext, buffer);
12640
+ if (structuralGuard !== null) {
12641
+ return structuralGuard;
12642
+ }
12612
12643
  if (buffer[0] !== 80 || buffer[1] !== 75) {
12613
12644
  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
12645
  }
@@ -13379,10 +13410,7 @@ var proposeFindReplaceTool = {
13379
13410
  }) => {
13380
13411
  const safePath = await resolveSafePath(ctx.cwd, input.path);
13381
13412
  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") {
13413
+ if (ext !== ".hwpx" && ext !== ".hwp") {
13386
13414
  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
13415
  }
13388
13416
  let originalBuf;
@@ -13391,14 +13419,18 @@ var proposeFindReplaceTool = {
13391
13419
  } catch {
13392
13420
  return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
13393
13421
  }
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
13422
  const originalBytes = new Uint8Array(
13398
13423
  originalBuf.buffer,
13399
13424
  originalBuf.byteOffset,
13400
13425
  originalBuf.byteLength
13401
13426
  );
13427
+ const structuralGuard = hwpStructuralGuard(ext, originalBytes);
13428
+ if (structuralGuard !== null) {
13429
+ return structuralGuard;
13430
+ }
13431
+ if (originalBuf[0] !== 80 || originalBuf[1] !== 75) {
13432
+ 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.";
13433
+ }
13402
13434
  let newBytes;
13403
13435
  let replacedCount;
13404
13436
  let diffSamples;
@@ -13505,6 +13537,13 @@ var proposeFormFillTool = {
13505
13537
  } catch {
13506
13538
  return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
13507
13539
  }
13540
+ const structuralGuard = hwpStructuralGuard(
13541
+ ext,
13542
+ new Uint8Array(originalBuffer.buffer, originalBuffer.byteOffset, originalBuffer.byteLength)
13543
+ );
13544
+ if (structuralGuard !== null) {
13545
+ return structuralGuard;
13546
+ }
13508
13547
  const parseResult = await parse3(originalBuffer.buffer);
13509
13548
  if (!parseResult.success) {
13510
13549
  const msg = kordocErrorMessage(
@@ -13681,29 +13720,30 @@ var proposeRedactPiiTool = {
13681
13720
  }) => {
13682
13721
  const safePath = await resolveSafePath(ctx.cwd, input.path);
13683
13722
  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") {
13723
+ if (ext !== ".hwpx" && ext !== ".hwp" && ext !== ".md" && ext !== ".txt") {
13688
13724
  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
13725
  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
13726
  }
13691
13727
  const { outputPath, willConvertFormat } = resolveOutputPath(safePath);
13692
- if (ext === ".hwpx") {
13728
+ if (ext === ".hwpx" || ext === ".hwp") {
13693
13729
  let originalBuf;
13694
13730
  try {
13695
13731
  originalBuf = await readFile10(safePath);
13696
13732
  } catch {
13697
13733
  return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}`;
13698
13734
  }
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
13735
  const originalBytes = new Uint8Array(
13703
13736
  originalBuf.buffer,
13704
13737
  originalBuf.byteOffset,
13705
13738
  originalBuf.byteLength
13706
13739
  );
13740
+ const structuralGuard = hwpStructuralGuard(ext, originalBytes);
13741
+ if (structuralGuard !== null) {
13742
+ return structuralGuard;
13743
+ }
13744
+ if (originalBuf[0] !== 80 || originalBuf[1] !== 75) {
13745
+ 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.";
13746
+ }
13707
13747
  let patchResult;
13708
13748
  try {
13709
13749
  patchResult = await applyRedactToHwpx(originalBytes);
@@ -14609,10 +14649,7 @@ var proposeTableStructureTool = {
14609
14649
  }) => {
14610
14650
  const safePath = await resolveSafePath(ctx.cwd, input.path);
14611
14651
  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") {
14652
+ if (ext !== ".hwpx" && ext !== ".hwp") {
14616
14653
  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
14654
  }
14618
14655
  let originalBuf;
@@ -14621,14 +14658,18 @@ var proposeTableStructureTool = {
14621
14658
  } catch {
14622
14659
  return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
14623
14660
  }
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
14661
  const originalBytes = new Uint8Array(
14628
14662
  originalBuf.buffer,
14629
14663
  originalBuf.byteOffset,
14630
14664
  originalBuf.byteLength
14631
14665
  );
14666
+ const structuralGuard = hwpStructuralGuard(ext, originalBytes);
14667
+ if (structuralGuard !== null) {
14668
+ return structuralGuard;
14669
+ }
14670
+ if (originalBuf[0] !== 80 || originalBuf[1] !== 75) {
14671
+ 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.";
14672
+ }
14632
14673
  let originalBlocks = null;
14633
14674
  try {
14634
14675
  const origResult = await parse4(originalBuf.buffer);