@kodocagent/cli 0.4.1 → 0.4.3
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 +467 -166
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -318,7 +318,7 @@ var require_BufferList = __commonJS({
|
|
|
318
318
|
this.head = this.tail = null;
|
|
319
319
|
this.length = 0;
|
|
320
320
|
};
|
|
321
|
-
BufferList.prototype.join = function
|
|
321
|
+
BufferList.prototype.join = function join5(s) {
|
|
322
322
|
if (this.length === 0) return "";
|
|
323
323
|
var p = this.head;
|
|
324
324
|
var ret = "" + p.data;
|
|
@@ -9890,7 +9890,8 @@ var DOCUMENT_RULES_SECTION = `## \uBB38\uC11C \uADDC\uCE59
|
|
|
9890
9890
|
4. \`.hwp\` \uD30C\uC77C\uC744 \uD3B8\uC9D1\uD55C \uACB0\uACFC\uB294 \`.hwpx\` \uD615\uC2DD\uC73C\uB85C \uC800\uC7A5\uB429\uB2C8\uB2E4. \uC774 \uBCC0\uD658 \uC0AC\uC2E4\uC744 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBBF8\uB9AC \uC548\uB0B4\uD558\uC138\uC694.
|
|
9891
9891
|
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.
|
|
9892
9892
|
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.
|
|
9893
|
-
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
|
|
9893
|
+
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.
|
|
9894
|
+
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.`;
|
|
9894
9895
|
var LAW_RULES_SECTION = `## \uBC95\uB839 \uADDC\uCE59
|
|
9895
9896
|
|
|
9896
9897
|
1. \uBC95\uB839 \uC778\uC6A9 \uD615\uC2DD: \u300C\uBC95\uB839\uBA85\u300D \uC81CN\uC870 \uC81CN\uD56D \uC81CN\uD638
|
|
@@ -10009,6 +10010,13 @@ var AgentSession = class {
|
|
|
10009
10010
|
opts;
|
|
10010
10011
|
messages = [];
|
|
10011
10012
|
openDocuments = [];
|
|
10013
|
+
/** 열람한 문서 경로를 중복 없이 기록한다 (방어적: 비문자열/오류는 무시). */
|
|
10014
|
+
recordOpenDocument(p) {
|
|
10015
|
+
if (typeof p !== "string" || p.trim() === "") return;
|
|
10016
|
+
if (!this.openDocuments.includes(p)) {
|
|
10017
|
+
this.openDocuments.push(p);
|
|
10018
|
+
}
|
|
10019
|
+
}
|
|
10012
10020
|
/** approval-required 이벤트를 run() 스트림에 전달하기 위한 큐 */
|
|
10013
10021
|
pendingApprovalEvents = [];
|
|
10014
10022
|
/**
|
|
@@ -10064,6 +10072,18 @@ var AgentSession = class {
|
|
|
10064
10072
|
args: part.input,
|
|
10065
10073
|
callId: part.toolCallId
|
|
10066
10074
|
};
|
|
10075
|
+
try {
|
|
10076
|
+
const inp = part.input;
|
|
10077
|
+
if (part.toolName === "read_document") {
|
|
10078
|
+
this.recordOpenDocument(inp.path);
|
|
10079
|
+
} else if (part.toolName === "compare_documents") {
|
|
10080
|
+
this.recordOpenDocument(inp.pathA);
|
|
10081
|
+
this.recordOpenDocument(inp.pathB);
|
|
10082
|
+
} else if (part.toolName === "write_new_document") {
|
|
10083
|
+
this.recordOpenDocument(inp.path);
|
|
10084
|
+
}
|
|
10085
|
+
} catch {
|
|
10086
|
+
}
|
|
10067
10087
|
break;
|
|
10068
10088
|
}
|
|
10069
10089
|
case "tool-result": {
|
|
@@ -10775,7 +10795,12 @@ var ToolRegistry = class {
|
|
|
10775
10795
|
return `\uC0AC\uC6A9\uC790\uAC00 \uBCC0\uACBD\uC744 \uAC70\uC808\uD558\uC5EC \uC800\uC7A5\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4${reasonPart}. \uAC19\uC740 \uC218\uC815\uC548\uC744 \uC790\uB3D9\uC73C\uB85C \uB2E4\uC2DC \uC81C\uC548\uD558\uC9C0 \uB9D0\uACE0, \uC0AC\uC6A9\uC790\uC758 \uB2E4\uC74C \uC9C0\uC2DC\uB97C \uAE30\uB2E4\uB9AC\uC138\uC694.`;
|
|
10776
10796
|
}
|
|
10777
10797
|
try {
|
|
10778
|
-
|
|
10798
|
+
const commitMsg = await commit();
|
|
10799
|
+
if (proposal.warnings && proposal.warnings.length > 0) {
|
|
10800
|
+
return `${commitMsg}
|
|
10801
|
+
[\uACBD\uACE0] ${proposal.warnings.join("\n[\uACBD\uACE0] ")}`;
|
|
10802
|
+
}
|
|
10803
|
+
return commitMsg;
|
|
10779
10804
|
} catch (err) {
|
|
10780
10805
|
const msg = err instanceof Error ? err.message : String(err);
|
|
10781
10806
|
return `\uC800\uC7A5 \uC624\uB958: ${msg}`;
|
|
@@ -10801,26 +10826,29 @@ import { realpath } from "fs/promises";
|
|
|
10801
10826
|
import { basename, dirname as dirname2, isAbsolute, join as join3, normalize, relative, resolve } from "path";
|
|
10802
10827
|
import { copyFile, mkdir as mkdir3, readdir as readdir2, readFile as readFile3, rename, rm, stat as stat2, writeFile as writeFile2 } from "fs/promises";
|
|
10803
10828
|
import { basename as basename2, dirname as dirname22, extname, join as join22 } from "path";
|
|
10829
|
+
import { createTwoFilesPatch } from "diff";
|
|
10830
|
+
import { readdir as readdir22, readFile as readFile22, stat as stat22 } from "fs/promises";
|
|
10831
|
+
import { basename as basename3, extname as extname2, join as join32 } from "path";
|
|
10804
10832
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
10805
10833
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
10806
10834
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
10807
|
-
import { createTwoFilesPatch } from "diff";
|
|
10808
|
-
import { readFile as readFile22 } from "fs/promises";
|
|
10809
|
-
import { blocksToMarkdown, compare } from "@clazic/kordoc";
|
|
10810
10835
|
import { z as z3 } from "zod";
|
|
10811
10836
|
import { readFile as readFile32 } from "fs/promises";
|
|
10812
|
-
import {
|
|
10837
|
+
import { blocksToMarkdown, compare } from "@clazic/kordoc";
|
|
10813
10838
|
import { z as z22 } from "zod";
|
|
10814
|
-
import { readdir as readdir22, stat as stat22 } from "fs/promises";
|
|
10815
|
-
import { extname as extname3, join as join32, relative as relative2 } from "path";
|
|
10816
|
-
import { z as z32 } from "zod";
|
|
10817
10839
|
import { readFile as readFile4 } from "fs/promises";
|
|
10818
|
-
import { extname as
|
|
10840
|
+
import { extname as extname3 } from "path";
|
|
10841
|
+
import { z as z32 } from "zod";
|
|
10842
|
+
import { readdir as readdir3, stat as stat3 } from "fs/promises";
|
|
10843
|
+
import { extname as extname4, join as join4, relative as relative2 } from "path";
|
|
10819
10844
|
import { z as z4 } from "zod";
|
|
10820
10845
|
import { readFile as readFile5 } from "fs/promises";
|
|
10821
10846
|
import { extname as extname5 } from "path";
|
|
10822
|
-
import { compare as compare2, markdownToHwpx, parse } from "@clazic/kordoc";
|
|
10823
10847
|
import { z as z5 } from "zod";
|
|
10848
|
+
import { readFile as readFile6 } from "fs/promises";
|
|
10849
|
+
import { extname as extname6 } from "path";
|
|
10850
|
+
import { compare as compare2, markdownToHwpx, parse } from "@clazic/kordoc";
|
|
10851
|
+
import { z as z6 } from "zod";
|
|
10824
10852
|
import {
|
|
10825
10853
|
Document,
|
|
10826
10854
|
HeadingLevel,
|
|
@@ -10832,37 +10860,37 @@ import {
|
|
|
10832
10860
|
TextRun,
|
|
10833
10861
|
WidthType
|
|
10834
10862
|
} from "docx";
|
|
10835
|
-
import { readFile as readFile6 } from "fs/promises";
|
|
10836
|
-
import { extname as extname6 } from "path";
|
|
10837
|
-
import { parse as parse2 } from "@clazic/kordoc";
|
|
10838
|
-
import { z as z6 } from "zod";
|
|
10839
10863
|
import { readFile as readFile7 } from "fs/promises";
|
|
10840
10864
|
import { extname as extname7 } from "path";
|
|
10841
|
-
import {
|
|
10842
|
-
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
10865
|
+
import { parse as parse2 } from "@clazic/kordoc";
|
|
10843
10866
|
import { z as z7 } from "zod";
|
|
10844
10867
|
import { readFile as readFile8 } from "fs/promises";
|
|
10845
10868
|
import { extname as extname8 } from "path";
|
|
10846
|
-
import
|
|
10869
|
+
import { extractFormFields, markdownToHwpx as markdownToHwpx2, parse as parse3 } from "@clazic/kordoc";
|
|
10870
|
+
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
10847
10871
|
import { z as z8 } from "zod";
|
|
10848
10872
|
import { readFile as readFile9 } from "fs/promises";
|
|
10849
10873
|
import { extname as extname9 } from "path";
|
|
10850
|
-
import
|
|
10874
|
+
import ExcelJS from "exceljs";
|
|
10851
10875
|
import { z as z9 } from "zod";
|
|
10852
|
-
import { readFile as readFile10
|
|
10876
|
+
import { readFile as readFile10 } from "fs/promises";
|
|
10853
10877
|
import { extname as extname10 } from "path";
|
|
10854
|
-
import { parse as
|
|
10878
|
+
import { parse as parse4 } from "@clazic/kordoc";
|
|
10855
10879
|
import { z as z10 } from "zod";
|
|
10856
|
-
import { readFile as
|
|
10857
|
-
import { z as z11 } from "zod";
|
|
10858
|
-
import { stat as stat5 } from "fs/promises";
|
|
10880
|
+
import { readFile as readFile11, stat as stat4 } from "fs/promises";
|
|
10859
10881
|
import { extname as extname11 } from "path";
|
|
10860
|
-
import {
|
|
10882
|
+
import { parse as parse5 } from "@clazic/kordoc";
|
|
10883
|
+
import { z as z11 } from "zod";
|
|
10884
|
+
import { readFile as fsReadFile, stat as stat5 } from "fs/promises";
|
|
10861
10885
|
import { z as z12 } from "zod";
|
|
10862
10886
|
import { stat as stat6 } from "fs/promises";
|
|
10863
10887
|
import { extname as extname12 } from "path";
|
|
10864
|
-
import
|
|
10888
|
+
import { markdownToHwpx as markdownToHwpx3 } from "@clazic/kordoc";
|
|
10865
10889
|
import { z as z13 } from "zod";
|
|
10890
|
+
import { stat as stat7 } from "fs/promises";
|
|
10891
|
+
import { extname as extname13 } from "path";
|
|
10892
|
+
import ExcelJS2 from "exceljs";
|
|
10893
|
+
import { z as z14 } from "zod";
|
|
10866
10894
|
async function resolveSafePath(cwd, p) {
|
|
10867
10895
|
const normalizedCwd = normalize(cwd).normalize("NFC");
|
|
10868
10896
|
const normalizedP = p.normalize("NFC");
|
|
@@ -10999,11 +11027,220 @@ function resolveOutputPath(targetPath) {
|
|
|
10999
11027
|
}
|
|
11000
11028
|
return { outputPath: targetPath, willConvertFormat: void 0 };
|
|
11001
11029
|
}
|
|
11030
|
+
function parseBackupFilename(filename) {
|
|
11031
|
+
const m = filename.match(/^(\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d{3}Z)-(.+)$/);
|
|
11032
|
+
if (!m) return null;
|
|
11033
|
+
return { tsToken: m[1], origBasename: m[2] };
|
|
11034
|
+
}
|
|
11035
|
+
function formatTimestamp(tsToken) {
|
|
11036
|
+
const restored = tsToken.replace(
|
|
11037
|
+
/^(\d{4}-\d{2}-\d{2})T(\d{2})-(\d{2})-(\d{2})-(\d{3})Z$/,
|
|
11038
|
+
"$1T$2:$3:$4.$5Z"
|
|
11039
|
+
);
|
|
11040
|
+
try {
|
|
11041
|
+
const d = new Date(restored);
|
|
11042
|
+
if (Number.isNaN(d.getTime())) return tsToken;
|
|
11043
|
+
return d.toISOString().replace("T", " ").slice(0, 19);
|
|
11044
|
+
} catch {
|
|
11045
|
+
return tsToken;
|
|
11046
|
+
}
|
|
11047
|
+
}
|
|
11048
|
+
var MAX_BACKUP_LIST = 50;
|
|
11049
|
+
var listBackupsSchema = z3.object({
|
|
11050
|
+
path: z3.string().optional().describe("\uD2B9\uC815 \uD30C\uC77C\uC758 \uBC31\uC5C5\uB9CC \uBCF4\uB824\uBA74 \uADF8 \uD30C\uC77C \uACBD\uB85C (\uBBF8\uC9C0\uC815 \uC2DC \uC804\uCCB4 \uBC31\uC5C5)")
|
|
11051
|
+
});
|
|
11052
|
+
var listBackupsTool = {
|
|
11053
|
+
name: "list_backups",
|
|
11054
|
+
description: "\uBC31\uC5C5 \uB514\uB809\uD130\uB9AC\uC758 \uBC31\uC5C5 \uBAA9\uB85D\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4. path\uB97C \uC9C0\uC815\uD558\uBA74 \uD574\uB2F9 \uD30C\uC77C\uC758 \uBC31\uC5C5\uB9CC, \uBBF8\uC9C0\uC815 \uC2DC \uC804\uCCB4 \uBC31\uC5C5\uC744 \uD45C\uC2DC\uD569\uB2C8\uB2E4. \uCD5C\uB300 50\uAC74, \uCD5C\uC2E0\uC21C \uC815\uB82C.",
|
|
11055
|
+
inputSchema: listBackupsSchema,
|
|
11056
|
+
requiresApproval: false,
|
|
11057
|
+
execute: async ({
|
|
11058
|
+
input
|
|
11059
|
+
}) => {
|
|
11060
|
+
const backupsDir = KODOC_PATHS.backups;
|
|
11061
|
+
let allEntries;
|
|
11062
|
+
try {
|
|
11063
|
+
allEntries = await readdir22(backupsDir);
|
|
11064
|
+
} catch {
|
|
11065
|
+
return "\uBC31\uC5C5\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.";
|
|
11066
|
+
}
|
|
11067
|
+
if (allEntries.length === 0) {
|
|
11068
|
+
return "\uBC31\uC5C5\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.";
|
|
11069
|
+
}
|
|
11070
|
+
const parsed = [];
|
|
11071
|
+
for (const filename of allEntries) {
|
|
11072
|
+
const info = parseBackupFilename(filename);
|
|
11073
|
+
if (!info) continue;
|
|
11074
|
+
const fullPath = join32(backupsDir, filename);
|
|
11075
|
+
let mtimeMs = 0;
|
|
11076
|
+
try {
|
|
11077
|
+
const s = await stat22(fullPath);
|
|
11078
|
+
mtimeMs = s.mtimeMs;
|
|
11079
|
+
} catch {
|
|
11080
|
+
mtimeMs = 0;
|
|
11081
|
+
}
|
|
11082
|
+
parsed.push({ filename, fullPath, ...info, mtimeMs });
|
|
11083
|
+
}
|
|
11084
|
+
let filtered = parsed;
|
|
11085
|
+
if (input.path) {
|
|
11086
|
+
const targetBase = basename3(input.path);
|
|
11087
|
+
filtered = parsed.filter((e) => e.origBasename === targetBase);
|
|
11088
|
+
}
|
|
11089
|
+
if (filtered.length === 0) {
|
|
11090
|
+
if (input.path) {
|
|
11091
|
+
return `\uD574\uB2F9 \uD30C\uC77C\uC758 \uBC31\uC5C5\uC774 \uC5C6\uC2B5\uB2C8\uB2E4: ${basename3(input.path)}`;
|
|
11092
|
+
}
|
|
11093
|
+
return "\uBC31\uC5C5\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.";
|
|
11094
|
+
}
|
|
11095
|
+
filtered.sort((a, b) => {
|
|
11096
|
+
if (b.mtimeMs !== a.mtimeMs) return b.mtimeMs - a.mtimeMs;
|
|
11097
|
+
return b.tsToken.localeCompare(a.tsToken);
|
|
11098
|
+
});
|
|
11099
|
+
const total = filtered.length;
|
|
11100
|
+
const truncated = filtered.length > MAX_BACKUP_LIST;
|
|
11101
|
+
const display = filtered.slice(0, MAX_BACKUP_LIST);
|
|
11102
|
+
const lines = display.map(
|
|
11103
|
+
(e, i) => `${i + 1}. ${e.origBasename} [${formatTimestamp(e.tsToken)}] ${e.fullPath}`
|
|
11104
|
+
);
|
|
11105
|
+
const notice = truncated ? `
|
|
11106
|
+
(\uCD1D ${total}\uAC74 \uC911 \uCD5C\uC2E0 ${MAX_BACKUP_LIST}\uAC74\uB9CC \uD45C\uC2DC\uB429\uB2C8\uB2E4.)` : "";
|
|
11107
|
+
return lines.join("\n") + notice;
|
|
11108
|
+
}
|
|
11109
|
+
};
|
|
11110
|
+
var restoreBackupSchema = z3.object({
|
|
11111
|
+
path: z3.string().describe("\uBCF5\uC6D0\uD560 \uB300\uC0C1 \uD30C\uC77C \uACBD\uB85C"),
|
|
11112
|
+
backup: z3.string().optional().describe("\uBCF5\uC6D0\uD560 \uD2B9\uC815 \uBC31\uC5C5 \uD30C\uC77C\uBA85 (list_backups \uACB0\uACFC\uC758 \uD30C\uC77C\uBA85; \uBBF8\uC9C0\uC815 \uC2DC \uAC00\uC7A5 \uCD5C\uADFC \uBC31\uC5C5)"),
|
|
11113
|
+
summary: z3.string().optional().describe("\uBCF5\uC6D0 \uC0AC\uC720/\uC694\uC57D")
|
|
11114
|
+
});
|
|
11115
|
+
var restoreBackupTool = {
|
|
11116
|
+
name: "restore_backup",
|
|
11117
|
+
description: "\uBC31\uC5C5 \uD30C\uC77C\uB85C \uB300\uC0C1 \uD30C\uC77C\uC744 \uBCF5\uC6D0\uD569\uB2C8\uB2E4. backup\uC744 \uBBF8\uC9C0\uC815 \uC2DC \uAC00\uC7A5 \uCD5C\uADFC \uBC31\uC5C5\uC744 \uC0AC\uC6A9\uD569\uB2C8\uB2E4. \uBCF5\uC6D0 \uC804 \uD604\uC7AC \uD30C\uC77C\uB3C4 \uC790\uB3D9 \uBC31\uC5C5\uB429\uB2C8\uB2E4(\uBCF5\uC6D0\uB3C4 \uB418\uB3CC\uB9B4 \uC218 \uC788\uC74C). \uC0AC\uC6A9\uC790 \uC2B9\uC778\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
|
|
11118
|
+
inputSchema: restoreBackupSchema,
|
|
11119
|
+
requiresApproval: true,
|
|
11120
|
+
propose: async ({
|
|
11121
|
+
input,
|
|
11122
|
+
ctx
|
|
11123
|
+
}) => {
|
|
11124
|
+
let safePath;
|
|
11125
|
+
try {
|
|
11126
|
+
safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
11127
|
+
} catch (e) {
|
|
11128
|
+
return `\uACBD\uB85C \uC624\uB958: ${e instanceof Error ? e.message : String(e)}`;
|
|
11129
|
+
}
|
|
11130
|
+
const targetBase = basename3(safePath);
|
|
11131
|
+
const backupsDir = KODOC_PATHS.backups;
|
|
11132
|
+
let allEntries;
|
|
11133
|
+
try {
|
|
11134
|
+
allEntries = await readdir22(backupsDir);
|
|
11135
|
+
} catch {
|
|
11136
|
+
return `\uBC31\uC5C5\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${targetBase}. list_backups\uB85C \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uBC31\uC5C5\uC744 \uBA3C\uC800 \uD655\uC778\uD558\uC138\uC694.`;
|
|
11137
|
+
}
|
|
11138
|
+
const candidates = [];
|
|
11139
|
+
for (const filename of allEntries) {
|
|
11140
|
+
const info = parseBackupFilename(filename);
|
|
11141
|
+
if (!info) continue;
|
|
11142
|
+
if (info.origBasename !== targetBase) continue;
|
|
11143
|
+
const fullPath = join32(backupsDir, filename);
|
|
11144
|
+
let mtimeMs = 0;
|
|
11145
|
+
try {
|
|
11146
|
+
const s = await stat22(fullPath);
|
|
11147
|
+
mtimeMs = s.mtimeMs;
|
|
11148
|
+
} catch {
|
|
11149
|
+
mtimeMs = 0;
|
|
11150
|
+
}
|
|
11151
|
+
candidates.push({ filename, fullPath, tsToken: info.tsToken, mtimeMs });
|
|
11152
|
+
}
|
|
11153
|
+
if (candidates.length === 0) {
|
|
11154
|
+
return `\uBC31\uC5C5\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${targetBase}. list_backups\uB85C \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uBC31\uC5C5\uC744 \uBA3C\uC800 \uD655\uC778\uD558\uC138\uC694.`;
|
|
11155
|
+
}
|
|
11156
|
+
let chosen;
|
|
11157
|
+
if (input.backup) {
|
|
11158
|
+
const found = candidates.find(
|
|
11159
|
+
(c) => c.filename === input.backup || c.fullPath.endsWith(input.backup)
|
|
11160
|
+
);
|
|
11161
|
+
if (!found) {
|
|
11162
|
+
return `\uC9C0\uC815\uD55C \uBC31\uC5C5\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.backup}. list_backups\uB85C \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uBC31\uC5C5\uC744 \uBA3C\uC800 \uD655\uC778\uD558\uC138\uC694.`;
|
|
11163
|
+
}
|
|
11164
|
+
chosen = found;
|
|
11165
|
+
} else {
|
|
11166
|
+
candidates.sort(
|
|
11167
|
+
(a, b) => b.mtimeMs !== a.mtimeMs ? b.mtimeMs - a.mtimeMs : b.tsToken.localeCompare(a.tsToken)
|
|
11168
|
+
);
|
|
11169
|
+
chosen = candidates[0];
|
|
11170
|
+
}
|
|
11171
|
+
let backupBytes;
|
|
11172
|
+
try {
|
|
11173
|
+
backupBytes = await readFile22(chosen.fullPath);
|
|
11174
|
+
} catch {
|
|
11175
|
+
return `\uBC31\uC5C5 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${chosen.fullPath}`;
|
|
11176
|
+
}
|
|
11177
|
+
const stagedPath = await stageFile(ctx.sessionId, targetBase, backupBytes);
|
|
11178
|
+
const ext = extname2(targetBase).toLowerCase();
|
|
11179
|
+
const isText = ext === ".md" || ext === ".txt";
|
|
11180
|
+
let diff;
|
|
11181
|
+
if (isText) {
|
|
11182
|
+
let currentText = "";
|
|
11183
|
+
try {
|
|
11184
|
+
currentText = await readFile22(safePath, "utf-8");
|
|
11185
|
+
} catch {
|
|
11186
|
+
currentText = "";
|
|
11187
|
+
}
|
|
11188
|
+
const backupText = backupBytes.toString("utf-8");
|
|
11189
|
+
diff = markdownDiff(currentText, backupText, targetBase);
|
|
11190
|
+
} else {
|
|
11191
|
+
let currentSize = "\uD30C\uC77C \uC5C6\uC74C";
|
|
11192
|
+
try {
|
|
11193
|
+
const s = await stat22(safePath);
|
|
11194
|
+
currentSize = `${s.size} bytes`;
|
|
11195
|
+
} catch {
|
|
11196
|
+
currentSize = "\uD30C\uC77C \uC5C6\uC74C";
|
|
11197
|
+
}
|
|
11198
|
+
const backupSize = `${backupBytes.length} bytes`;
|
|
11199
|
+
diff = [
|
|
11200
|
+
`\uBCF5\uC6D0 \uB300\uC0C1: ${safePath}`,
|
|
11201
|
+
`\uD604\uC7AC \uD30C\uC77C: ${currentSize}`,
|
|
11202
|
+
`\uBC31\uC5C5 \uD30C\uC77C: ${chosen.fullPath}`,
|
|
11203
|
+
`\uBC31\uC5C5 \uC2DC\uAC01: ${formatTimestamp(chosen.tsToken)}`,
|
|
11204
|
+
`\uBC31\uC5C5 \uD06C\uAE30: ${backupSize}`,
|
|
11205
|
+
`\u2192 \uD604\uC7AC \uD30C\uC77C\uC744 \uC704 \uBC31\uC5C5\uC73C\uB85C \uB418\uB3CC\uB9BD\uB2C8\uB2E4.`
|
|
11206
|
+
].join("\n");
|
|
11207
|
+
}
|
|
11208
|
+
const warnings = [];
|
|
11209
|
+
const autoSelected = !input.backup && candidates.length > 1;
|
|
11210
|
+
if (autoSelected) {
|
|
11211
|
+
warnings.push(
|
|
11212
|
+
`\uBC31\uC5C5\uC744 \uC9C0\uC815\uD558\uC9C0 \uC54A\uC544 \uAC00\uC7A5 \uCD5C\uADFC \uBC31\uC5C5(${formatTimestamp(chosen.tsToken)})\uC744 \uC790\uB3D9\uC73C\uB85C \uC120\uD0DD\uD588\uC2B5\uB2C8\uB2E4. \uB2E4\uB978 \uBC31\uC5C5\uC744 \uC6D0\uD558\uBA74 list_backups\uB85C \uD655\uC778 \uD6C4 backup \uD30C\uB77C\uBBF8\uD130\uB97C \uC9C0\uC815\uD558\uC138\uC694.`
|
|
11213
|
+
);
|
|
11214
|
+
}
|
|
11215
|
+
warnings.push(
|
|
11216
|
+
"\uBCF5\uC6D0\uC744 \uC2E4\uD589\uD558\uBA74 \uD604\uC7AC \uD30C\uC77C\uB3C4 \uBC31\uC5C5\uB41C \uB4A4 \uB36E\uC5B4\uC4F0\uC5EC\uC9D1\uB2C8\uB2E4(\uBCF5\uC6D0 \uC790\uCCB4\uB3C4 \uB418\uB3CC\uB9B4 \uC218 \uC788\uC74C)."
|
|
11217
|
+
);
|
|
11218
|
+
const summary = input.summary ?? `\uBC31\uC5C5\uC73C\uB85C \uB418\uB3CC\uB9AC\uAE30: ${targetBase}`;
|
|
11219
|
+
const chosenBackupPath = chosen.fullPath;
|
|
11220
|
+
return {
|
|
11221
|
+
proposal: {
|
|
11222
|
+
id: crypto.randomUUID(),
|
|
11223
|
+
kind: "restore",
|
|
11224
|
+
targetPath: safePath,
|
|
11225
|
+
stagedPath,
|
|
11226
|
+
summary,
|
|
11227
|
+
diff,
|
|
11228
|
+
warnings
|
|
11229
|
+
},
|
|
11230
|
+
commit: async () => {
|
|
11231
|
+
const safetyBackup = await backupFile(safePath);
|
|
11232
|
+
await commitStaged(stagedPath, safePath);
|
|
11233
|
+
const safetyNote = safetyBackup ? ` (\uBCF5\uC6D0 \uC804 \uD604\uC7AC \uC0C1\uD0DC \uBC31\uC5C5: ${safetyBackup})` : "";
|
|
11234
|
+
return `\uBCF5\uC6D0 \uC644\uB8CC: ${safePath} \u2190 ${chosenBackupPath}${safetyNote}`;
|
|
11235
|
+
}
|
|
11236
|
+
};
|
|
11237
|
+
}
|
|
11238
|
+
};
|
|
11002
11239
|
var MAX_MARKDOWN_LENGTH = 8e4;
|
|
11003
11240
|
var MAX_BLOCK_TEXT_LENGTH = 200;
|
|
11004
|
-
var compareDocumentsSchema =
|
|
11005
|
-
pathA:
|
|
11006
|
-
pathB:
|
|
11241
|
+
var compareDocumentsSchema = z22.object({
|
|
11242
|
+
pathA: z22.string().describe("\uBE44\uAD50\uD560 \uCCAB \uBC88\uC9F8 \uBB38\uC11C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)"),
|
|
11243
|
+
pathB: z22.string().describe("\uBE44\uAD50\uD560 \uB450 \uBC88\uC9F8 \uBB38\uC11C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)")
|
|
11007
11244
|
});
|
|
11008
11245
|
function bufferToArrayBuffer(buf) {
|
|
11009
11246
|
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
|
@@ -11041,13 +11278,13 @@ var compareDocumentsTool = {
|
|
|
11041
11278
|
let bufA;
|
|
11042
11279
|
let bufB;
|
|
11043
11280
|
try {
|
|
11044
|
-
bufA = await
|
|
11281
|
+
bufA = await readFile32(safePathA);
|
|
11045
11282
|
} catch (e) {
|
|
11046
11283
|
const msg = e instanceof Error ? e.message : String(e);
|
|
11047
11284
|
return `\uC624\uB958: \uCCAB \uBC88\uC9F8 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (${input.pathA}): ${msg}`;
|
|
11048
11285
|
}
|
|
11049
11286
|
try {
|
|
11050
|
-
bufB = await
|
|
11287
|
+
bufB = await readFile32(safePathB);
|
|
11051
11288
|
} catch (e) {
|
|
11052
11289
|
const msg = e instanceof Error ? e.message : String(e);
|
|
11053
11290
|
return `\uC624\uB958: \uB450 \uBC88\uC9F8 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (${input.pathB}): ${msg}`;
|
|
@@ -11495,14 +11732,14 @@ function validateHwpxBuffer(ext, buffer) {
|
|
|
11495
11732
|
}
|
|
11496
11733
|
return null;
|
|
11497
11734
|
}
|
|
11498
|
-
var listFormObjectsSchema =
|
|
11499
|
-
path:
|
|
11735
|
+
var listFormObjectsSchema = z32.object({
|
|
11736
|
+
path: z32.string().describe("\uC77D\uC744 .hwpx \uD30C\uC77C \uACBD\uB85C")
|
|
11500
11737
|
});
|
|
11501
|
-
var formEditSetSchema =
|
|
11502
|
-
caption:
|
|
11503
|
-
checked:
|
|
11504
|
-
selected:
|
|
11505
|
-
text:
|
|
11738
|
+
var formEditSetSchema = z32.object({
|
|
11739
|
+
caption: z32.string().optional().describe("PushButton \uCEA1\uC158 \uD14D\uC2A4\uD2B8"),
|
|
11740
|
+
checked: z32.boolean().optional().describe("CheckBox/RadioButton \uCCB4\uD06C \uC0C1\uD0DC (true=CHECKED)"),
|
|
11741
|
+
selected: z32.string().optional().describe("ComboBox \uC120\uD0DD \uAC12 (listItem \uC911 \uD558\uB098\uC5EC\uC57C \uD568)"),
|
|
11742
|
+
text: z32.string().optional().describe("Edit \uD14D\uC2A4\uD2B8 \uB0B4\uC6A9")
|
|
11506
11743
|
}).refine(
|
|
11507
11744
|
(v) => {
|
|
11508
11745
|
const keys = ["caption", "checked", "selected", "text"].filter(
|
|
@@ -11512,24 +11749,24 @@ var formEditSetSchema = z22.object({
|
|
|
11512
11749
|
},
|
|
11513
11750
|
{ message: "set \uD544\uB4DC\uB294 caption/checked/selected/text \uC911 \uC815\uD655\uD788 \uD558\uB098\uB9CC \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4." }
|
|
11514
11751
|
);
|
|
11515
|
-
var formEditExpectedSchema =
|
|
11516
|
-
caption:
|
|
11517
|
-
checked:
|
|
11518
|
-
selected:
|
|
11519
|
-
text:
|
|
11752
|
+
var formEditExpectedSchema = z32.object({
|
|
11753
|
+
caption: z32.string().optional(),
|
|
11754
|
+
checked: z32.boolean().optional(),
|
|
11755
|
+
selected: z32.string().optional(),
|
|
11756
|
+
text: z32.string().optional()
|
|
11520
11757
|
}).optional();
|
|
11521
|
-
var formEditItemSchema =
|
|
11522
|
-
name:
|
|
11523
|
-
index:
|
|
11758
|
+
var formEditItemSchema = z32.object({
|
|
11759
|
+
name: z32.string().describe("\uC591\uC2DD \uAC1C\uCCB4\uC758 name \uC18D\uC131 \uAC12"),
|
|
11760
|
+
index: z32.number().int().nonnegative().optional().describe("\uB3D9\uC77C name\uC774 \uC5EC\uB7FF\uC778 \uACBD\uC6B0 \uBB38\uC11C \uC804\uCCB4 0-based \uC778\uB371\uC2A4\uB85C \uAD6C\uBD84"),
|
|
11524
11761
|
set: formEditSetSchema.describe("\uBCC0\uACBD\uD560 \uAC12 (caption/checked/selected/text \uC911 \uD558\uB098)"),
|
|
11525
11762
|
expected: formEditExpectedSchema.describe(
|
|
11526
11763
|
"\uD604\uC7AC \uAC12 \uC0AC\uC804 \uAC80\uC99D (\uC548\uC804 \uC635\uC158). \uC2E4\uC81C \uAC12\uC774 \uB2E4\uB974\uBA74 \uC774 \uD3B8\uC9D1\uC744 \uCDE8\uC18C\uD558\uACE0 \uC624\uB958 \uBC18\uD658."
|
|
11527
11764
|
)
|
|
11528
11765
|
});
|
|
11529
|
-
var proposeFormObjectSchema =
|
|
11530
|
-
path:
|
|
11531
|
-
edits:
|
|
11532
|
-
summary:
|
|
11766
|
+
var proposeFormObjectSchema = z32.object({
|
|
11767
|
+
path: z32.string().describe("\uC218\uC815\uD560 .hwpx \uD30C\uC77C \uACBD\uB85C"),
|
|
11768
|
+
edits: z32.array(formEditItemSchema).min(1).describe("\uC591\uC2DD \uAC1C\uCCB4 \uD3B8\uC9D1 \uBAA9\uB85D"),
|
|
11769
|
+
summary: z32.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
11533
11770
|
});
|
|
11534
11771
|
var listFormObjectsTool = {
|
|
11535
11772
|
name: "list_form_objects",
|
|
@@ -11541,10 +11778,10 @@ var listFormObjectsTool = {
|
|
|
11541
11778
|
ctx
|
|
11542
11779
|
}) => {
|
|
11543
11780
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
11544
|
-
const ext =
|
|
11781
|
+
const ext = extname3(safePath).toLowerCase();
|
|
11545
11782
|
let buffer;
|
|
11546
11783
|
try {
|
|
11547
|
-
buffer = await
|
|
11784
|
+
buffer = await readFile4(safePath);
|
|
11548
11785
|
} catch {
|
|
11549
11786
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}`;
|
|
11550
11787
|
}
|
|
@@ -11596,10 +11833,10 @@ var proposeFormObjectTool = {
|
|
|
11596
11833
|
ctx
|
|
11597
11834
|
}) => {
|
|
11598
11835
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
11599
|
-
const ext =
|
|
11836
|
+
const ext = extname3(safePath).toLowerCase();
|
|
11600
11837
|
let originalBuffer;
|
|
11601
11838
|
try {
|
|
11602
|
-
originalBuffer = await
|
|
11839
|
+
originalBuffer = await readFile4(safePath);
|
|
11603
11840
|
} catch {
|
|
11604
11841
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}`;
|
|
11605
11842
|
}
|
|
@@ -11786,14 +12023,14 @@ var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
|
11786
12023
|
]);
|
|
11787
12024
|
var MAX_DEPTH = 4;
|
|
11788
12025
|
var MAX_FILES = 500;
|
|
11789
|
-
var listFilesSchema =
|
|
11790
|
-
dir:
|
|
12026
|
+
var listFilesSchema = z4.object({
|
|
12027
|
+
dir: z4.string().optional().describe("\uBAA9\uB85D\uC744 \uC870\uD68C\uD560 \uB514\uB809\uD130\uB9AC (\uBBF8\uC9C0\uC815 \uC2DC cwd \uC804\uCCB4)")
|
|
11791
12028
|
});
|
|
11792
12029
|
async function collectFiles(dir, cwd, depth, entries) {
|
|
11793
12030
|
if (depth > MAX_DEPTH || entries.length >= MAX_FILES) return;
|
|
11794
12031
|
let items;
|
|
11795
12032
|
try {
|
|
11796
|
-
items = await
|
|
12033
|
+
items = await readdir3(dir);
|
|
11797
12034
|
} catch {
|
|
11798
12035
|
return;
|
|
11799
12036
|
}
|
|
@@ -11801,15 +12038,15 @@ async function collectFiles(dir, cwd, depth, entries) {
|
|
|
11801
12038
|
if (entries.length >= MAX_FILES) break;
|
|
11802
12039
|
if (item.startsWith(".")) continue;
|
|
11803
12040
|
if (SKIP_DIRS.has(item)) continue;
|
|
11804
|
-
const fullPath =
|
|
12041
|
+
const fullPath = join4(dir, item);
|
|
11805
12042
|
let info;
|
|
11806
12043
|
try {
|
|
11807
|
-
info = await
|
|
12044
|
+
info = await stat3(fullPath);
|
|
11808
12045
|
} catch {
|
|
11809
12046
|
continue;
|
|
11810
12047
|
}
|
|
11811
12048
|
const relPath = relative2(cwd, fullPath);
|
|
11812
|
-
const ext =
|
|
12049
|
+
const ext = extname4(item).toLowerCase();
|
|
11813
12050
|
const isDoc = DOC_EXTENSIONS.has(ext);
|
|
11814
12051
|
if (info.isDirectory()) {
|
|
11815
12052
|
entries.push({ path: relPath + "/", isDir: true, isDoc: false });
|
|
@@ -11847,29 +12084,29 @@ var listFilesTool = {
|
|
|
11847
12084
|
return lines.join("\n") + truncateNotice;
|
|
11848
12085
|
}
|
|
11849
12086
|
};
|
|
11850
|
-
var cellEditItemSchema =
|
|
11851
|
-
tableIndex:
|
|
12087
|
+
var cellEditItemSchema = z5.object({
|
|
12088
|
+
tableIndex: z5.number().int().nonnegative().optional().describe(
|
|
11852
12089
|
"\uC88C\uD45C \uBAA8\uB4DC: 0-based \uD45C \uC778\uB371\uC2A4(read_document\uC758 kordoc \uBE14\uB85D \uC21C\uC11C, \uC911\uCCA9\uD45C \uC81C\uC678). \uB808\uC774\uBE14 \uBAA8\uB4DC\uC5D0\uC120 \uD0D0\uC0C9 \uBC94\uC704 \uC81C\uD55C\uC6A9(\uC120\uD0DD)."
|
|
11853
12090
|
),
|
|
11854
|
-
row:
|
|
11855
|
-
col:
|
|
11856
|
-
label:
|
|
12091
|
+
row: z5.number().int().nonnegative().optional().describe("\uC88C\uD45C \uBAA8\uB4DC: \uC140\uC758 rowAddr (0-based)"),
|
|
12092
|
+
col: z5.number().int().nonnegative().optional().describe("\uC88C\uD45C \uBAA8\uB4DC: \uC140\uC758 colAddr (0-based)"),
|
|
12093
|
+
label: z5.string().optional().describe(
|
|
11857
12094
|
"\uB808\uC774\uBE14 \uBAA8\uB4DC: \uAE30\uC900 \uC140 \uD14D\uC2A4\uD2B8(\uD2B8\uB9BC \uBE44\uAD50). \uC774 \uC140\uC758 direction \uBC29\uD5A5 \uC778\uC811 \uC140\uC5D0 newText\uB97C \uAE30\uB85D. \uC88C\uD45C \uBAA8\uB4DC\uBA74 \uC0DD\uB7B5."
|
|
11858
12095
|
),
|
|
11859
|
-
direction:
|
|
11860
|
-
newText:
|
|
11861
|
-
expectedText:
|
|
12096
|
+
direction: z5.enum(["right", "below"]).optional().describe("\uB808\uC774\uBE14 \uBAA8\uB4DC \uBC29\uD5A5. \uAE30\uBCF8 right(\uC624\uB978\uCABD \uC140), below(\uC544\uB798 \uC140). \uBCD1\uD569 span \uACE0\uB824."),
|
|
12097
|
+
newText: z5.string().describe("\uC140\uC5D0 \uC4F8 \uC0C8 \uD14D\uC2A4\uD2B8"),
|
|
12098
|
+
expectedText: z5.string().optional().describe(
|
|
11862
12099
|
"\uD604\uC7AC \uC140 \uD14D\uC2A4\uD2B8(\uC548\uC804 \uAC80\uC99D\uC6A9). \uBD88\uC77C\uCE58 \uC2DC \uC218\uC815\uD558\uC9C0 \uC54A\uC74C. \uC798\uBABB\uB41C \uC140 \uC218\uC815 \uBC29\uC9C0\uB97C \uC704\uD574 \uAD8C\uC7A5."
|
|
11863
12100
|
)
|
|
11864
12101
|
}).describe(
|
|
11865
12102
|
"\uD3B8\uC9D1 \uD56D\uBAA9. \uC88C\uD45C \uBAA8\uB4DC(tableIndex+row+col) \uB610\uB294 \uB808\uC774\uBE14 \uBAA8\uB4DC(label[+direction]) \uC911 \uD558\uB098\uB97C \uC0AC\uC6A9\uD558\uC138\uC694. \uB458 \uB2E4 \uC9C0\uC815\uD558\uAC70\uB098 \uB458 \uB2E4 \uC0DD\uB7B5\uD558\uBA74 \uC624\uB958\uC785\uB2C8\uB2E4."
|
|
11866
12103
|
);
|
|
11867
|
-
var proposeCellEditSchema =
|
|
11868
|
-
path:
|
|
11869
|
-
edits:
|
|
12104
|
+
var proposeCellEditSchema = z5.object({
|
|
12105
|
+
path: z5.string().describe("\uC218\uC815\uD560 .hwpx \uD30C\uC77C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)"),
|
|
12106
|
+
edits: z5.array(cellEditItemSchema).min(1).describe(
|
|
11870
12107
|
"\uD3B8\uC9D1 \uBAA9\uB85D. \uAC01 \uD56D\uBAA9\uC740 \uC88C\uD45C \uBAA8\uB4DC(tableIndex+row+col) \uB610\uB294 \uB808\uC774\uBE14 \uBAA8\uB4DC(label+direction) \uC911 \uD558\uB098"
|
|
11871
12108
|
),
|
|
11872
|
-
summary:
|
|
12109
|
+
summary: z5.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
11873
12110
|
});
|
|
11874
12111
|
function tokenizeHwpxXml(xml) {
|
|
11875
12112
|
const tokens = [];
|
|
@@ -12204,7 +12441,7 @@ var proposeCellEditTool = {
|
|
|
12204
12441
|
ctx
|
|
12205
12442
|
}) => {
|
|
12206
12443
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
12207
|
-
const ext =
|
|
12444
|
+
const ext = extname5(safePath).toLowerCase();
|
|
12208
12445
|
if (ext === ".hwp") {
|
|
12209
12446
|
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.";
|
|
12210
12447
|
}
|
|
@@ -12213,7 +12450,7 @@ var proposeCellEditTool = {
|
|
|
12213
12450
|
}
|
|
12214
12451
|
let originalBuffer;
|
|
12215
12452
|
try {
|
|
12216
|
-
originalBuffer = await
|
|
12453
|
+
originalBuffer = await readFile5(safePath);
|
|
12217
12454
|
} catch {
|
|
12218
12455
|
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.`;
|
|
12219
12456
|
}
|
|
@@ -12542,10 +12779,10 @@ async function markdownToDocx(markdown) {
|
|
|
12542
12779
|
});
|
|
12543
12780
|
return Packer.toBuffer(doc);
|
|
12544
12781
|
}
|
|
12545
|
-
var proposeEditSchema =
|
|
12546
|
-
path:
|
|
12547
|
-
newMarkdown:
|
|
12548
|
-
summary:
|
|
12782
|
+
var proposeEditSchema = z6.object({
|
|
12783
|
+
path: z6.string().describe("\uC218\uC815\uD560 \uBB38\uC11C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)"),
|
|
12784
|
+
newMarkdown: z6.string().describe("\uC0C8 \uBB38\uC11C \uB0B4\uC6A9 (\uB9C8\uD06C\uB2E4\uC6B4 \uD615\uC2DD). read_document\uB85C \uC6D0\uBCF8\uC744 \uBA3C\uC800 \uC77D\uC5B4\uC57C \uD568"),
|
|
12785
|
+
summary: z6.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
12549
12786
|
});
|
|
12550
12787
|
var proposeEditTool = {
|
|
12551
12788
|
name: "propose_edit",
|
|
@@ -12557,10 +12794,10 @@ var proposeEditTool = {
|
|
|
12557
12794
|
ctx
|
|
12558
12795
|
}) => {
|
|
12559
12796
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
12560
|
-
const ext =
|
|
12797
|
+
const ext = extname6(safePath).toLowerCase();
|
|
12561
12798
|
let originalBuffer;
|
|
12562
12799
|
try {
|
|
12563
|
-
originalBuffer = await
|
|
12800
|
+
originalBuffer = await readFile6(safePath);
|
|
12564
12801
|
} catch {
|
|
12565
12802
|
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.`;
|
|
12566
12803
|
}
|
|
@@ -12631,17 +12868,48 @@ ${diff}`;
|
|
|
12631
12868
|
};
|
|
12632
12869
|
}
|
|
12633
12870
|
};
|
|
12634
|
-
var proposeFindReplaceSchema =
|
|
12635
|
-
path:
|
|
12636
|
-
find:
|
|
12637
|
-
replace:
|
|
12638
|
-
caseSensitive:
|
|
12639
|
-
all:
|
|
12640
|
-
summary:
|
|
12871
|
+
var proposeFindReplaceSchema = z7.object({
|
|
12872
|
+
path: z7.string().describe("\uC218\uC815\uD560 .hwpx \uD30C\uC77C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)"),
|
|
12873
|
+
find: z7.string().min(1).describe("\uCC3E\uC744 \uD14D\uC2A4\uD2B8"),
|
|
12874
|
+
replace: z7.string().describe("\uBC14\uAFC0 \uD14D\uC2A4\uD2B8"),
|
|
12875
|
+
caseSensitive: z7.boolean().optional().default(false).describe("\uB300\uC18C\uBB38\uC790 \uAD6C\uBD84 (\uAE30\uBCF8\uAC12: false)"),
|
|
12876
|
+
all: z7.boolean().optional().default(true).describe("\uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uAD50\uCCB4\uD560\uC9C0 \uC5EC\uBD80 (\uAE30\uBCF8\uAC12: true). false\uC774\uBA74 \uCCAB \uBC88\uC9F8 \uB9E4\uCE58\uB9CC \uAD50\uCCB4"),
|
|
12877
|
+
summary: z7.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
12641
12878
|
});
|
|
12879
|
+
var MAX_DIFF_SAMPLES = 20;
|
|
12642
12880
|
function escapeXml3(text3) {
|
|
12643
12881
|
return text3.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
12644
12882
|
}
|
|
12883
|
+
function unescapeXml(text3) {
|
|
12884
|
+
return text3.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&");
|
|
12885
|
+
}
|
|
12886
|
+
function makeChangeSnippet(before, after, ctx = 24) {
|
|
12887
|
+
let p = 0;
|
|
12888
|
+
while (p < before.length && p < after.length && before[p] === after[p]) p++;
|
|
12889
|
+
const maxSuffix = Math.min(before.length - p, after.length - p);
|
|
12890
|
+
let s = 0;
|
|
12891
|
+
while (s < maxSuffix && before[before.length - 1 - s] === after[after.length - 1 - s]) s++;
|
|
12892
|
+
const slice = (str) => {
|
|
12893
|
+
const start = Math.max(0, p - ctx);
|
|
12894
|
+
const end = Math.min(str.length, str.length - s + ctx);
|
|
12895
|
+
return (start > 0 ? "\u2026" : "") + str.slice(start, end) + (end < str.length ? "\u2026" : "");
|
|
12896
|
+
};
|
|
12897
|
+
return { before: slice(before), after: slice(after) };
|
|
12898
|
+
}
|
|
12899
|
+
function collectChangedSnippets(beforeXml, afterXml, maxSamples) {
|
|
12900
|
+
const re = /<hp:t>([\s\S]*?)<\/hp:t>/g;
|
|
12901
|
+
const beforeNodes = [...beforeXml.matchAll(re)].map((m) => m[1] ?? "");
|
|
12902
|
+
const afterNodes = [...afterXml.matchAll(re)].map((m) => m[1] ?? "");
|
|
12903
|
+
const out = [];
|
|
12904
|
+
const n = Math.min(beforeNodes.length, afterNodes.length);
|
|
12905
|
+
for (let i = 0; i < n && out.length < maxSamples; i++) {
|
|
12906
|
+
if (beforeNodes[i] !== afterNodes[i]) {
|
|
12907
|
+
const snip = makeChangeSnippet(unescapeXml(beforeNodes[i]), unescapeXml(afterNodes[i]));
|
|
12908
|
+
out.push(snip);
|
|
12909
|
+
}
|
|
12910
|
+
}
|
|
12911
|
+
return out;
|
|
12912
|
+
}
|
|
12645
12913
|
function replaceInSectionXml(xml, find, replace, caseSensitive, replaceAll, alreadyReplaced) {
|
|
12646
12914
|
if (!replaceAll && alreadyReplaced > 0) {
|
|
12647
12915
|
return { xml, count: 0 };
|
|
@@ -12749,7 +13017,19 @@ async function applyFindReplaceToHwpx(hwpxBuffer, find, replace, caseSensitive,
|
|
|
12749
13017
|
}
|
|
12750
13018
|
}
|
|
12751
13019
|
if (totalCount === 0) {
|
|
12752
|
-
return { buffer: hwpxBuffer, count: 0 };
|
|
13020
|
+
return { buffer: hwpxBuffer, count: 0, samples: [] };
|
|
13021
|
+
}
|
|
13022
|
+
const samples = [];
|
|
13023
|
+
for (let si = 0; si < sectionFiles.length && samples.length < MAX_DIFF_SAMPLES; si++) {
|
|
13024
|
+
const remaining = MAX_DIFF_SAMPLES - samples.length;
|
|
13025
|
+
const snippets = collectChangedSnippets(
|
|
13026
|
+
sectionXmls[si] ?? "",
|
|
13027
|
+
newSectionXmls[si] ?? "",
|
|
13028
|
+
remaining
|
|
13029
|
+
);
|
|
13030
|
+
for (const snip of snippets) {
|
|
13031
|
+
samples.push(snip);
|
|
13032
|
+
}
|
|
12753
13033
|
}
|
|
12754
13034
|
const out = new import_jszip3.default();
|
|
12755
13035
|
const mimetypeEntry = zip.file("mimetype");
|
|
@@ -12768,7 +13048,8 @@ async function applyFindReplaceToHwpx(hwpxBuffer, find, replace, caseSensitive,
|
|
|
12768
13048
|
const buf = await out.generateAsync({ type: "nodebuffer", compression: "DEFLATE" });
|
|
12769
13049
|
return {
|
|
12770
13050
|
buffer: new Uint8Array(buf),
|
|
12771
|
-
count: totalCount
|
|
13051
|
+
count: totalCount,
|
|
13052
|
+
samples
|
|
12772
13053
|
};
|
|
12773
13054
|
}
|
|
12774
13055
|
var proposeFindReplaceTool = {
|
|
@@ -12781,7 +13062,7 @@ var proposeFindReplaceTool = {
|
|
|
12781
13062
|
ctx
|
|
12782
13063
|
}) => {
|
|
12783
13064
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
12784
|
-
const ext =
|
|
13065
|
+
const ext = extname7(safePath).toLowerCase();
|
|
12785
13066
|
if (ext === ".hwp") {
|
|
12786
13067
|
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.";
|
|
12787
13068
|
}
|
|
@@ -12790,7 +13071,7 @@ var proposeFindReplaceTool = {
|
|
|
12790
13071
|
}
|
|
12791
13072
|
let originalBuf;
|
|
12792
13073
|
try {
|
|
12793
|
-
originalBuf = await
|
|
13074
|
+
originalBuf = await readFile7(safePath);
|
|
12794
13075
|
} catch {
|
|
12795
13076
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
|
|
12796
13077
|
}
|
|
@@ -12804,6 +13085,7 @@ var proposeFindReplaceTool = {
|
|
|
12804
13085
|
);
|
|
12805
13086
|
let newBytes;
|
|
12806
13087
|
let replacedCount;
|
|
13088
|
+
let diffSamples;
|
|
12807
13089
|
try {
|
|
12808
13090
|
const result = await applyFindReplaceToHwpx(
|
|
12809
13091
|
originalBytes,
|
|
@@ -12814,6 +13096,7 @@ var proposeFindReplaceTool = {
|
|
|
12814
13096
|
);
|
|
12815
13097
|
newBytes = result.buffer;
|
|
12816
13098
|
replacedCount = result.count;
|
|
13099
|
+
diffSamples = result.samples;
|
|
12817
13100
|
} catch (e) {
|
|
12818
13101
|
return `\uC624\uB958: \uCE58\uD658 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. ${String(e)}`;
|
|
12819
13102
|
}
|
|
@@ -12842,7 +13125,23 @@ var proposeFindReplaceTool = {
|
|
|
12842
13125
|
}
|
|
12843
13126
|
const { outputPath, willConvertFormat } = resolveOutputPath(safePath);
|
|
12844
13127
|
const allLabel = input.all ?? true ? `${replacedCount}\uACF3` : "\uCCAB \uBC88\uC9F8 1\uACF3";
|
|
12845
|
-
|
|
13128
|
+
let diff;
|
|
13129
|
+
if (diffSamples.length === 0) {
|
|
13130
|
+
diff = `\uCC3E\uAE30: "${input.find}" \u2192 \uBC14\uAFB8\uAE30: "${input.replace}" (${allLabel} \uAD50\uCCB4\uB428)`;
|
|
13131
|
+
} else {
|
|
13132
|
+
const lines = [`${replacedCount}\uACF3 \uAD50\uCCB4: "${input.find}" \u2192 "${input.replace}"`];
|
|
13133
|
+
for (let i = 0; i < diffSamples.length; i++) {
|
|
13134
|
+
const sample = diffSamples[i];
|
|
13135
|
+
lines.push(` ${i + 1}. - ${sample.before}`);
|
|
13136
|
+
lines.push(` + ${sample.after}`);
|
|
13137
|
+
}
|
|
13138
|
+
if (replacedCount > diffSamples.length) {
|
|
13139
|
+
lines.push(
|
|
13140
|
+
` \u2026 \uC678 ${replacedCount - diffSamples.length}\uACF3 (\uBBF8\uB9AC\uBCF4\uAE30\uB294 \uCD5C\uB300 ${MAX_DIFF_SAMPLES}\uACF3)`
|
|
13141
|
+
);
|
|
13142
|
+
}
|
|
13143
|
+
diff = lines.join("\n");
|
|
13144
|
+
}
|
|
12846
13145
|
const stagedPath = await stageFile(ctx.sessionId, outputPath, newBytes);
|
|
12847
13146
|
const proposalId = crypto.randomUUID();
|
|
12848
13147
|
return {
|
|
@@ -12865,10 +13164,10 @@ var proposeFindReplaceTool = {
|
|
|
12865
13164
|
};
|
|
12866
13165
|
}
|
|
12867
13166
|
};
|
|
12868
|
-
var proposeFormFillSchema =
|
|
12869
|
-
path:
|
|
12870
|
-
fields:
|
|
12871
|
-
summary:
|
|
13167
|
+
var proposeFormFillSchema = z8.object({
|
|
13168
|
+
path: z8.string().describe("\uC591\uC2DD \uBB38\uC11C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)"),
|
|
13169
|
+
fields: z8.record(z8.string(), z8.string()).describe("\uCC44\uC6B8 \uD544\uB4DC \uB9E4\uD551: { \uB77C\uBCA8: \uAC12 }. read_document\uB85C \uBA3C\uC800 \uD544\uB4DC \uBAA9\uB85D\uC744 \uD655\uC778\uD558\uC138\uC694"),
|
|
13170
|
+
summary: z8.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
12872
13171
|
});
|
|
12873
13172
|
var proposeFormFillTool = {
|
|
12874
13173
|
name: "propose_form_fill",
|
|
@@ -12880,13 +13179,13 @@ var proposeFormFillTool = {
|
|
|
12880
13179
|
ctx
|
|
12881
13180
|
}) => {
|
|
12882
13181
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
12883
|
-
const ext =
|
|
13182
|
+
const ext = extname8(safePath).toLowerCase();
|
|
12884
13183
|
if (ext !== ".hwpx" && ext !== ".hwp") {
|
|
12885
13184
|
return `\uC624\uB958: propose_form_fill\uC740 .hwp/.hwpx \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. \uD604\uC7AC \uD30C\uC77C: ${ext}. .docx \uD30C\uC77C\uC740 propose_edit\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.`;
|
|
12886
13185
|
}
|
|
12887
13186
|
let originalBuffer;
|
|
12888
13187
|
try {
|
|
12889
|
-
originalBuffer = await
|
|
13188
|
+
originalBuffer = await readFile8(safePath);
|
|
12890
13189
|
} catch {
|
|
12891
13190
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
|
|
12892
13191
|
}
|
|
@@ -12954,16 +13253,16 @@ var proposeFormFillTool = {
|
|
|
12954
13253
|
};
|
|
12955
13254
|
}
|
|
12956
13255
|
};
|
|
12957
|
-
var proposeSheetEditSchema =
|
|
12958
|
-
path:
|
|
12959
|
-
updates:
|
|
12960
|
-
|
|
12961
|
-
sheet:
|
|
12962
|
-
cell:
|
|
12963
|
-
value:
|
|
13256
|
+
var proposeSheetEditSchema = z9.object({
|
|
13257
|
+
path: z9.string().describe("\uC218\uC815\uD560 XLSX \uD30C\uC77C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)"),
|
|
13258
|
+
updates: z9.array(
|
|
13259
|
+
z9.object({
|
|
13260
|
+
sheet: z9.string().describe("\uC2DC\uD2B8 \uC774\uB984"),
|
|
13261
|
+
cell: z9.string().describe("\uC140 \uC8FC\uC18C (\uC608: A1, B3)"),
|
|
13262
|
+
value: z9.union([z9.string(), z9.number()]).describe("\uC0C8 \uAC12")
|
|
12964
13263
|
})
|
|
12965
13264
|
).min(1).describe("\uC218\uC815\uD560 \uC140 \uBAA9\uB85D. read_document\uB85C \uC6D0\uBCF8 \uC2DC\uD2B8 \uAD6C\uC870\uB97C \uBA3C\uC800 \uD655\uC778\uD558\uC138\uC694"),
|
|
12966
|
-
summary:
|
|
13265
|
+
summary: z9.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
12967
13266
|
});
|
|
12968
13267
|
var proposeSheetEditTool = {
|
|
12969
13268
|
name: "propose_sheet_edit",
|
|
@@ -12975,13 +13274,13 @@ var proposeSheetEditTool = {
|
|
|
12975
13274
|
ctx
|
|
12976
13275
|
}) => {
|
|
12977
13276
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
12978
|
-
const ext =
|
|
13277
|
+
const ext = extname9(safePath).toLowerCase();
|
|
12979
13278
|
if (ext !== ".xlsx" && ext !== ".xls") {
|
|
12980
13279
|
return `\uC624\uB958: propose_sheet_edit\uC740 .xlsx/.xls \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. \uD604\uC7AC \uD30C\uC77C: ${ext}.`;
|
|
12981
13280
|
}
|
|
12982
13281
|
let originalBuffer;
|
|
12983
13282
|
try {
|
|
12984
|
-
originalBuffer = await
|
|
13283
|
+
originalBuffer = await readFile9(safePath);
|
|
12985
13284
|
} catch {
|
|
12986
13285
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
|
|
12987
13286
|
}
|
|
@@ -13072,47 +13371,47 @@ function detectStructuralLoss(beforeBlocks, afterBlocks) {
|
|
|
13072
13371
|
}
|
|
13073
13372
|
return { lost: false, detail: "" };
|
|
13074
13373
|
}
|
|
13075
|
-
var insertRowOpSchema =
|
|
13076
|
-
type:
|
|
13077
|
-
row:
|
|
13078
|
-
position:
|
|
13374
|
+
var insertRowOpSchema = z10.object({
|
|
13375
|
+
type: z10.literal("insertRow"),
|
|
13376
|
+
row: z10.number().int().nonnegative().describe("\uAE30\uC900 \uD589 \uC778\uB371\uC2A4 (0-based)"),
|
|
13377
|
+
position: z10.enum(["above", "below"]).describe("\uC0BD\uC785 \uC704\uCE58: above=row \uC704\uC5D0, below=row \uC544\uB798\uC5D0")
|
|
13079
13378
|
});
|
|
13080
|
-
var deleteRowOpSchema =
|
|
13081
|
-
type:
|
|
13082
|
-
row:
|
|
13379
|
+
var deleteRowOpSchema = z10.object({
|
|
13380
|
+
type: z10.literal("deleteRow"),
|
|
13381
|
+
row: z10.number().int().nonnegative().describe("\uC0AD\uC81C\uD560 \uD589 \uC778\uB371\uC2A4 (0-based)")
|
|
13083
13382
|
});
|
|
13084
|
-
var insertColumnOpSchema =
|
|
13085
|
-
type:
|
|
13086
|
-
col:
|
|
13087
|
-
position:
|
|
13383
|
+
var insertColumnOpSchema = z10.object({
|
|
13384
|
+
type: z10.literal("insertColumn"),
|
|
13385
|
+
col: z10.number().int().nonnegative().describe("\uAE30\uC900 \uC5F4 \uC778\uB371\uC2A4 (0-based)"),
|
|
13386
|
+
position: z10.enum(["left", "right"]).describe("\uC0BD\uC785 \uC704\uCE58: left=col \uC67C\uCABD\uC5D0, right=col \uC624\uB978\uCABD\uC5D0")
|
|
13088
13387
|
});
|
|
13089
|
-
var deleteColumnOpSchema =
|
|
13090
|
-
type:
|
|
13091
|
-
col:
|
|
13388
|
+
var deleteColumnOpSchema = z10.object({
|
|
13389
|
+
type: z10.literal("deleteColumn"),
|
|
13390
|
+
col: z10.number().int().nonnegative().describe("\uC0AD\uC81C\uD560 \uC5F4 \uC778\uB371\uC2A4 (0-based)")
|
|
13092
13391
|
});
|
|
13093
|
-
var mergeCellsOpSchema =
|
|
13094
|
-
type:
|
|
13095
|
-
startRow:
|
|
13096
|
-
startCol:
|
|
13097
|
-
endRow:
|
|
13098
|
-
endCol:
|
|
13392
|
+
var mergeCellsOpSchema = z10.object({
|
|
13393
|
+
type: z10.literal("mergeCells"),
|
|
13394
|
+
startRow: z10.number().int().nonnegative().describe("\uBCD1\uD569 \uC2DC\uC791 \uD589 (0-based)"),
|
|
13395
|
+
startCol: z10.number().int().nonnegative().describe("\uBCD1\uD569 \uC2DC\uC791 \uC5F4 (0-based)"),
|
|
13396
|
+
endRow: z10.number().int().nonnegative().describe("\uBCD1\uD569 \uB05D \uD589 (0-based, \uD3EC\uD568)"),
|
|
13397
|
+
endCol: z10.number().int().nonnegative().describe("\uBCD1\uD569 \uB05D \uC5F4 (0-based, \uD3EC\uD568)")
|
|
13099
13398
|
});
|
|
13100
|
-
var operationSchema =
|
|
13399
|
+
var operationSchema = z10.discriminatedUnion("type", [
|
|
13101
13400
|
insertRowOpSchema,
|
|
13102
13401
|
deleteRowOpSchema,
|
|
13103
13402
|
insertColumnOpSchema,
|
|
13104
13403
|
deleteColumnOpSchema,
|
|
13105
13404
|
mergeCellsOpSchema
|
|
13106
13405
|
]).describe("\uD45C \uAD6C\uC870 \uC5F0\uC0B0. \uB098\uC911 \uC5F0\uC0B0\uC758 row/col \uC778\uB371\uC2A4\uB294 \uC55E \uC5F0\uC0B0 \uC801\uC6A9 \uD6C4 \uC0C1\uD0DC\uB97C \uAE30\uC900\uC73C\uB85C \uD55C\uB2E4.");
|
|
13107
|
-
var proposeTableStructureSchema =
|
|
13108
|
-
path:
|
|
13109
|
-
anchor:
|
|
13406
|
+
var proposeTableStructureSchema = z10.object({
|
|
13407
|
+
path: z10.string().describe("\uC218\uC815\uD560 .hwpx \uD30C\uC77C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)"),
|
|
13408
|
+
anchor: z10.string().min(1).describe(
|
|
13110
13409
|
"\uB300\uC0C1 \uD45C\uB97C \uC2DD\uBCC4\uD558\uB294 \uC575\uCEE4 \uD14D\uC2A4\uD2B8. \uD45C \uC548\uC5D0\uB9CC \uC788\uB294 \uB3C5\uD2B9\uD55C \uC140 \uD14D\uC2A4\uD2B8\uB97C \uC9C0\uC815\uD558\uC138\uC694. (\uBD80\uBD84 \uC77C\uCE58, \uACF5\uBC31 \uD2B8\uB9BC) \u2014 read_document\uB85C \uD655\uC778 \uD6C4 \uC0AC\uC6A9 \uAD8C\uC7A5."
|
|
13111
13410
|
),
|
|
13112
|
-
operations:
|
|
13411
|
+
operations: z10.array(operationSchema).min(1).describe(
|
|
13113
13412
|
"\uC801\uC6A9\uD560 \uD45C \uAD6C\uC870 \uC5F0\uC0B0 \uBAA9\uB85D (\uC21C\uC11C\uB300\uB85C \uC2E4\uD589). \uAC01 \uC5F0\uC0B0\uC740 \uC774\uC804 \uC5F0\uC0B0\uC774 \uC801\uC6A9\uB41C \uD6C4\uC758 \uD45C \uC0C1\uD0DC \uAE30\uC900\uC73C\uB85C row/col\uC744 \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4."
|
|
13114
13413
|
),
|
|
13115
|
-
summary:
|
|
13414
|
+
summary: z10.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
13116
13415
|
});
|
|
13117
13416
|
function tokenizeHwpxXml2(xml) {
|
|
13118
13417
|
const tokens = [];
|
|
@@ -13787,7 +14086,7 @@ var proposeTableStructureTool = {
|
|
|
13787
14086
|
ctx
|
|
13788
14087
|
}) => {
|
|
13789
14088
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
13790
|
-
const ext =
|
|
14089
|
+
const ext = extname10(safePath).toLowerCase();
|
|
13791
14090
|
if (ext === ".hwp") {
|
|
13792
14091
|
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.";
|
|
13793
14092
|
}
|
|
@@ -13796,7 +14095,7 @@ var proposeTableStructureTool = {
|
|
|
13796
14095
|
}
|
|
13797
14096
|
let originalBuf;
|
|
13798
14097
|
try {
|
|
13799
|
-
originalBuf = await
|
|
14098
|
+
originalBuf = await readFile10(safePath);
|
|
13800
14099
|
} catch {
|
|
13801
14100
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
|
|
13802
14101
|
}
|
|
@@ -13992,11 +14291,11 @@ function searchExcerpts(markdown, query) {
|
|
|
13992
14291
|
}
|
|
13993
14292
|
return result;
|
|
13994
14293
|
}
|
|
13995
|
-
var readDocumentSchema =
|
|
13996
|
-
path:
|
|
13997
|
-
pages:
|
|
13998
|
-
outline:
|
|
13999
|
-
search:
|
|
14294
|
+
var readDocumentSchema = z11.object({
|
|
14295
|
+
path: z11.string().describe("\uC77D\uC744 \uBB38\uC11C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)"),
|
|
14296
|
+
pages: z11.string().optional().describe('\uC77D\uC744 \uD398\uC774\uC9C0 \uBC94\uC704 (\uC608: "1-3", "1,3,5") \u2014 \uBBF8\uC9C0\uC815 \uC2DC \uC804\uCCB4'),
|
|
14297
|
+
outline: z11.boolean().optional().describe("\uD5E4\uB529(\uC81C\uBAA9) \uAD6C\uC870\uB9CC \uBC18\uD658\uD574 \uBB38\uC11C \uAC1C\uC694 \uD30C\uC545 (\uB300\uD615 \uBB38\uC11C \uD0D0\uC0C9\uC6A9)"),
|
|
14298
|
+
search: z11.string().optional().describe("\uD0A4\uC6CC\uB4DC\uAC00 \uD3EC\uD568\uB41C \uBD80\uBD84\uACFC \uC8FC\uBCC0 \uB9E5\uB77D\uB9CC \uBC18\uD658 (\uB300\uD615 \uBB38\uC11C\uC5D0\uC11C \uD544\uC694\uD55C \uBD80\uBD84\uB9CC \uC77D\uAE30)")
|
|
14000
14299
|
});
|
|
14001
14300
|
function applyReadMode(body, outline, search) {
|
|
14002
14301
|
if (outline === true) {
|
|
@@ -14018,18 +14317,18 @@ var readDocumentTool = {
|
|
|
14018
14317
|
}) => {
|
|
14019
14318
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
14020
14319
|
try {
|
|
14021
|
-
const fileStat = await
|
|
14320
|
+
const fileStat = await stat4(safePath);
|
|
14022
14321
|
const guardMsg = fileSizeGuardMessage(fileStat.size, MAX_FILE_SIZE_BYTES);
|
|
14023
14322
|
if (guardMsg !== null) return guardMsg;
|
|
14024
14323
|
} catch (e) {
|
|
14025
14324
|
const msg = e instanceof Error ? e.message : String(e);
|
|
14026
14325
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${msg}`;
|
|
14027
14326
|
}
|
|
14028
|
-
const ext =
|
|
14327
|
+
const ext = extname11(safePath).toLowerCase();
|
|
14029
14328
|
if (PLAIN_TEXT_EXTS.has(ext)) {
|
|
14030
14329
|
let raw;
|
|
14031
14330
|
try {
|
|
14032
|
-
raw = await
|
|
14331
|
+
raw = await readFile11(safePath, "utf-8");
|
|
14033
14332
|
} catch (e) {
|
|
14034
14333
|
const msg = e instanceof Error ? e.message : String(e);
|
|
14035
14334
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${msg}`;
|
|
@@ -14129,8 +14428,8 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
14129
14428
|
".csv",
|
|
14130
14429
|
".log"
|
|
14131
14430
|
]);
|
|
14132
|
-
var readFileSchema =
|
|
14133
|
-
path:
|
|
14431
|
+
var readFileSchema = z12.object({
|
|
14432
|
+
path: z12.string().describe("\uC77D\uC744 \uD30C\uC77C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)")
|
|
14134
14433
|
});
|
|
14135
14434
|
var readFileTool = {
|
|
14136
14435
|
name: "read_file",
|
|
@@ -14144,7 +14443,7 @@ var readFileTool = {
|
|
|
14144
14443
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
14145
14444
|
let info;
|
|
14146
14445
|
try {
|
|
14147
|
-
info = await
|
|
14446
|
+
info = await stat5(safePath);
|
|
14148
14447
|
} catch {
|
|
14149
14448
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}`;
|
|
14150
14449
|
}
|
|
@@ -14154,8 +14453,8 @@ var readFileTool = {
|
|
|
14154
14453
|
if (info.size > MAX_SIZE) {
|
|
14155
14454
|
return `\uC624\uB958: \uD30C\uC77C\uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${Math.round(info.size / 1024)}KB). \uCD5C\uB300 256KB\uAE4C\uC9C0 \uC77D\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4.`;
|
|
14156
14455
|
}
|
|
14157
|
-
const { extname:
|
|
14158
|
-
const ext =
|
|
14456
|
+
const { extname: extname14 } = await import("path");
|
|
14457
|
+
const ext = extname14(safePath).toLowerCase();
|
|
14159
14458
|
if (!TEXT_EXTENSIONS.has(ext) && ext !== "") {
|
|
14160
14459
|
return `\uC624\uB958: '${ext}' \uD615\uC2DD\uC740 \uD14D\uC2A4\uD2B8 \uD30C\uC77C\uB85C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uBB38\uC11C \uD30C\uC77C\uC774\uB77C\uBA74 read_document \uD234\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.`;
|
|
14161
14460
|
}
|
|
@@ -14170,9 +14469,9 @@ var readFileTool = {
|
|
|
14170
14469
|
}
|
|
14171
14470
|
};
|
|
14172
14471
|
var MAX_PREVIEW_CHARS = 1e4;
|
|
14173
|
-
var writeNewDocumentSchema =
|
|
14174
|
-
path:
|
|
14175
|
-
markdown:
|
|
14472
|
+
var writeNewDocumentSchema = z13.object({
|
|
14473
|
+
path: z13.string().describe("\uC0DD\uC131\uD560 \uBB38\uC11C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)"),
|
|
14474
|
+
markdown: z13.string().describe("\uC0C8 \uBB38\uC11C \uB0B4\uC6A9 (\uB9C8\uD06C\uB2E4\uC6B4 \uD615\uC2DD)")
|
|
14176
14475
|
});
|
|
14177
14476
|
var writeNewDocumentTool = {
|
|
14178
14477
|
name: "write_new_document",
|
|
@@ -14184,9 +14483,9 @@ var writeNewDocumentTool = {
|
|
|
14184
14483
|
ctx
|
|
14185
14484
|
}) => {
|
|
14186
14485
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
14187
|
-
const ext =
|
|
14486
|
+
const ext = extname12(safePath).toLowerCase();
|
|
14188
14487
|
try {
|
|
14189
|
-
await
|
|
14488
|
+
await stat6(safePath);
|
|
14190
14489
|
return `\uC624\uB958: \uD30C\uC77C\uC774 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4: ${input.path}. \uAE30\uC874 \uD30C\uC77C\uC744 \uC218\uC815\uD558\uB824\uBA74 propose_edit\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.`;
|
|
14191
14490
|
} catch {
|
|
14192
14491
|
}
|
|
@@ -14234,12 +14533,12 @@ ${preview}`,
|
|
|
14234
14533
|
};
|
|
14235
14534
|
}
|
|
14236
14535
|
};
|
|
14237
|
-
var writeNewSpreadsheetSchema =
|
|
14238
|
-
path:
|
|
14239
|
-
sheets:
|
|
14240
|
-
|
|
14241
|
-
name:
|
|
14242
|
-
rows:
|
|
14536
|
+
var writeNewSpreadsheetSchema = z14.object({
|
|
14537
|
+
path: z14.string().describe("\uC0DD\uC131\uD560 XLSX \uD30C\uC77C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)"),
|
|
14538
|
+
sheets: z14.array(
|
|
14539
|
+
z14.object({
|
|
14540
|
+
name: z14.string().describe("\uC2DC\uD2B8 \uC774\uB984"),
|
|
14541
|
+
rows: z14.array(z14.array(z14.string())).describe("\uD589 \uB370\uC774\uD130 \uBC30\uC5F4 (\uAC01 \uD589\uC740 \uC140 \uAC12 \uBC30\uC5F4)")
|
|
14243
14542
|
})
|
|
14244
14543
|
).min(1).describe("\uC0DD\uC131\uD560 \uC2DC\uD2B8 \uBAA9\uB85D")
|
|
14245
14544
|
});
|
|
@@ -14253,12 +14552,12 @@ var writeNewSpreadsheetTool = {
|
|
|
14253
14552
|
ctx
|
|
14254
14553
|
}) => {
|
|
14255
14554
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
14256
|
-
const ext =
|
|
14555
|
+
const ext = extname13(safePath).toLowerCase();
|
|
14257
14556
|
if (ext !== ".xlsx") {
|
|
14258
14557
|
return `\uC624\uB958: write_new_spreadsheet\uC740 .xlsx \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. \uD604\uC7AC \uD655\uC7A5\uC790: ${ext}.`;
|
|
14259
14558
|
}
|
|
14260
14559
|
try {
|
|
14261
|
-
await
|
|
14560
|
+
await stat7(safePath);
|
|
14262
14561
|
return `\uC624\uB958: \uD30C\uC77C\uC774 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4: ${input.path}. \uAE30\uC874 \uD30C\uC77C \uC140 \uC218\uC815\uC740 propose_sheet_edit\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.`;
|
|
14263
14562
|
} catch {
|
|
14264
14563
|
}
|
|
@@ -14311,6 +14610,7 @@ function createDocTools(_ctx) {
|
|
|
14311
14610
|
readDocumentTool,
|
|
14312
14611
|
compareDocumentsTool,
|
|
14313
14612
|
listFilesTool,
|
|
14613
|
+
listBackupsTool,
|
|
14314
14614
|
readFileTool,
|
|
14315
14615
|
proposeEditTool,
|
|
14316
14616
|
proposeFormFillTool,
|
|
@@ -14321,7 +14621,8 @@ function createDocTools(_ctx) {
|
|
|
14321
14621
|
listFormObjectsTool,
|
|
14322
14622
|
proposeFormObjectTool,
|
|
14323
14623
|
writeNewDocumentTool,
|
|
14324
|
-
writeNewSpreadsheetTool
|
|
14624
|
+
writeNewSpreadsheetTool,
|
|
14625
|
+
restoreBackupTool
|
|
14325
14626
|
];
|
|
14326
14627
|
}
|
|
14327
14628
|
|
|
@@ -15125,7 +15426,7 @@ async function runOnboarding() {
|
|
|
15125
15426
|
|
|
15126
15427
|
// src/update.ts
|
|
15127
15428
|
import { spawn } from "child_process";
|
|
15128
|
-
import { mkdir as mkdir4, readFile as
|
|
15429
|
+
import { mkdir as mkdir4, readFile as readFile12, writeFile as writeFile3 } from "fs/promises";
|
|
15129
15430
|
import { dirname as dirname3 } from "path";
|
|
15130
15431
|
function compareSemver(a, b) {
|
|
15131
15432
|
const parse6 = (v) => {
|
|
@@ -15146,7 +15447,7 @@ function compareSemver(a, b) {
|
|
|
15146
15447
|
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
15147
15448
|
async function readCache(cachePath) {
|
|
15148
15449
|
try {
|
|
15149
|
-
const raw = await
|
|
15450
|
+
const raw = await readFile12(cachePath, "utf-8");
|
|
15150
15451
|
const parsed = JSON.parse(raw);
|
|
15151
15452
|
if (parsed !== null && typeof parsed === "object" && "checkedAt" in parsed && "latest" in parsed && typeof parsed.checkedAt === "string" && typeof parsed.latest === "string") {
|
|
15152
15453
|
return parsed;
|