@kodocagent/cli 0.4.2 → 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 +461 -165
- 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": {
|
|
@@ -10806,26 +10826,29 @@ import { realpath } from "fs/promises";
|
|
|
10806
10826
|
import { basename, dirname as dirname2, isAbsolute, join as join3, normalize, relative, resolve } from "path";
|
|
10807
10827
|
import { copyFile, mkdir as mkdir3, readdir as readdir2, readFile as readFile3, rename, rm, stat as stat2, writeFile as writeFile2 } from "fs/promises";
|
|
10808
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";
|
|
10809
10832
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
10810
10833
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
10811
10834
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
10812
|
-
import { createTwoFilesPatch } from "diff";
|
|
10813
|
-
import { readFile as readFile22 } from "fs/promises";
|
|
10814
|
-
import { blocksToMarkdown, compare } from "@clazic/kordoc";
|
|
10815
10835
|
import { z as z3 } from "zod";
|
|
10816
10836
|
import { readFile as readFile32 } from "fs/promises";
|
|
10817
|
-
import {
|
|
10837
|
+
import { blocksToMarkdown, compare } from "@clazic/kordoc";
|
|
10818
10838
|
import { z as z22 } from "zod";
|
|
10819
|
-
import { readdir as readdir22, stat as stat22 } from "fs/promises";
|
|
10820
|
-
import { extname as extname3, join as join32, relative as relative2 } from "path";
|
|
10821
|
-
import { z as z32 } from "zod";
|
|
10822
10839
|
import { readFile as readFile4 } from "fs/promises";
|
|
10823
|
-
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";
|
|
10824
10844
|
import { z as z4 } from "zod";
|
|
10825
10845
|
import { readFile as readFile5 } from "fs/promises";
|
|
10826
10846
|
import { extname as extname5 } from "path";
|
|
10827
|
-
import { compare as compare2, markdownToHwpx, parse } from "@clazic/kordoc";
|
|
10828
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";
|
|
10829
10852
|
import {
|
|
10830
10853
|
Document,
|
|
10831
10854
|
HeadingLevel,
|
|
@@ -10837,37 +10860,37 @@ import {
|
|
|
10837
10860
|
TextRun,
|
|
10838
10861
|
WidthType
|
|
10839
10862
|
} from "docx";
|
|
10840
|
-
import { readFile as readFile6 } from "fs/promises";
|
|
10841
|
-
import { extname as extname6 } from "path";
|
|
10842
|
-
import { parse as parse2 } from "@clazic/kordoc";
|
|
10843
|
-
import { z as z6 } from "zod";
|
|
10844
10863
|
import { readFile as readFile7 } from "fs/promises";
|
|
10845
10864
|
import { extname as extname7 } from "path";
|
|
10846
|
-
import {
|
|
10847
|
-
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
10865
|
+
import { parse as parse2 } from "@clazic/kordoc";
|
|
10848
10866
|
import { z as z7 } from "zod";
|
|
10849
10867
|
import { readFile as readFile8 } from "fs/promises";
|
|
10850
10868
|
import { extname as extname8 } from "path";
|
|
10851
|
-
import
|
|
10869
|
+
import { extractFormFields, markdownToHwpx as markdownToHwpx2, parse as parse3 } from "@clazic/kordoc";
|
|
10870
|
+
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
10852
10871
|
import { z as z8 } from "zod";
|
|
10853
10872
|
import { readFile as readFile9 } from "fs/promises";
|
|
10854
10873
|
import { extname as extname9 } from "path";
|
|
10855
|
-
import
|
|
10874
|
+
import ExcelJS from "exceljs";
|
|
10856
10875
|
import { z as z9 } from "zod";
|
|
10857
|
-
import { readFile as readFile10
|
|
10876
|
+
import { readFile as readFile10 } from "fs/promises";
|
|
10858
10877
|
import { extname as extname10 } from "path";
|
|
10859
|
-
import { parse as
|
|
10878
|
+
import { parse as parse4 } from "@clazic/kordoc";
|
|
10860
10879
|
import { z as z10 } from "zod";
|
|
10861
|
-
import { readFile as
|
|
10862
|
-
import { z as z11 } from "zod";
|
|
10863
|
-
import { stat as stat5 } from "fs/promises";
|
|
10880
|
+
import { readFile as readFile11, stat as stat4 } from "fs/promises";
|
|
10864
10881
|
import { extname as extname11 } from "path";
|
|
10865
|
-
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";
|
|
10866
10885
|
import { z as z12 } from "zod";
|
|
10867
10886
|
import { stat as stat6 } from "fs/promises";
|
|
10868
10887
|
import { extname as extname12 } from "path";
|
|
10869
|
-
import
|
|
10888
|
+
import { markdownToHwpx as markdownToHwpx3 } from "@clazic/kordoc";
|
|
10870
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";
|
|
10871
10894
|
async function resolveSafePath(cwd, p) {
|
|
10872
10895
|
const normalizedCwd = normalize(cwd).normalize("NFC");
|
|
10873
10896
|
const normalizedP = p.normalize("NFC");
|
|
@@ -11004,11 +11027,220 @@ function resolveOutputPath(targetPath) {
|
|
|
11004
11027
|
}
|
|
11005
11028
|
return { outputPath: targetPath, willConvertFormat: void 0 };
|
|
11006
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
|
+
};
|
|
11007
11239
|
var MAX_MARKDOWN_LENGTH = 8e4;
|
|
11008
11240
|
var MAX_BLOCK_TEXT_LENGTH = 200;
|
|
11009
|
-
var compareDocumentsSchema =
|
|
11010
|
-
pathA:
|
|
11011
|
-
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)")
|
|
11012
11244
|
});
|
|
11013
11245
|
function bufferToArrayBuffer(buf) {
|
|
11014
11246
|
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
|
@@ -11046,13 +11278,13 @@ var compareDocumentsTool = {
|
|
|
11046
11278
|
let bufA;
|
|
11047
11279
|
let bufB;
|
|
11048
11280
|
try {
|
|
11049
|
-
bufA = await
|
|
11281
|
+
bufA = await readFile32(safePathA);
|
|
11050
11282
|
} catch (e) {
|
|
11051
11283
|
const msg = e instanceof Error ? e.message : String(e);
|
|
11052
11284
|
return `\uC624\uB958: \uCCAB \uBC88\uC9F8 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (${input.pathA}): ${msg}`;
|
|
11053
11285
|
}
|
|
11054
11286
|
try {
|
|
11055
|
-
bufB = await
|
|
11287
|
+
bufB = await readFile32(safePathB);
|
|
11056
11288
|
} catch (e) {
|
|
11057
11289
|
const msg = e instanceof Error ? e.message : String(e);
|
|
11058
11290
|
return `\uC624\uB958: \uB450 \uBC88\uC9F8 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (${input.pathB}): ${msg}`;
|
|
@@ -11500,14 +11732,14 @@ function validateHwpxBuffer(ext, buffer) {
|
|
|
11500
11732
|
}
|
|
11501
11733
|
return null;
|
|
11502
11734
|
}
|
|
11503
|
-
var listFormObjectsSchema =
|
|
11504
|
-
path:
|
|
11735
|
+
var listFormObjectsSchema = z32.object({
|
|
11736
|
+
path: z32.string().describe("\uC77D\uC744 .hwpx \uD30C\uC77C \uACBD\uB85C")
|
|
11505
11737
|
});
|
|
11506
|
-
var formEditSetSchema =
|
|
11507
|
-
caption:
|
|
11508
|
-
checked:
|
|
11509
|
-
selected:
|
|
11510
|
-
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")
|
|
11511
11743
|
}).refine(
|
|
11512
11744
|
(v) => {
|
|
11513
11745
|
const keys = ["caption", "checked", "selected", "text"].filter(
|
|
@@ -11517,24 +11749,24 @@ var formEditSetSchema = z22.object({
|
|
|
11517
11749
|
},
|
|
11518
11750
|
{ message: "set \uD544\uB4DC\uB294 caption/checked/selected/text \uC911 \uC815\uD655\uD788 \uD558\uB098\uB9CC \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4." }
|
|
11519
11751
|
);
|
|
11520
|
-
var formEditExpectedSchema =
|
|
11521
|
-
caption:
|
|
11522
|
-
checked:
|
|
11523
|
-
selected:
|
|
11524
|
-
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()
|
|
11525
11757
|
}).optional();
|
|
11526
|
-
var formEditItemSchema =
|
|
11527
|
-
name:
|
|
11528
|
-
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"),
|
|
11529
11761
|
set: formEditSetSchema.describe("\uBCC0\uACBD\uD560 \uAC12 (caption/checked/selected/text \uC911 \uD558\uB098)"),
|
|
11530
11762
|
expected: formEditExpectedSchema.describe(
|
|
11531
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."
|
|
11532
11764
|
)
|
|
11533
11765
|
});
|
|
11534
|
-
var proposeFormObjectSchema =
|
|
11535
|
-
path:
|
|
11536
|
-
edits:
|
|
11537
|
-
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)")
|
|
11538
11770
|
});
|
|
11539
11771
|
var listFormObjectsTool = {
|
|
11540
11772
|
name: "list_form_objects",
|
|
@@ -11546,10 +11778,10 @@ var listFormObjectsTool = {
|
|
|
11546
11778
|
ctx
|
|
11547
11779
|
}) => {
|
|
11548
11780
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
11549
|
-
const ext =
|
|
11781
|
+
const ext = extname3(safePath).toLowerCase();
|
|
11550
11782
|
let buffer;
|
|
11551
11783
|
try {
|
|
11552
|
-
buffer = await
|
|
11784
|
+
buffer = await readFile4(safePath);
|
|
11553
11785
|
} catch {
|
|
11554
11786
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}`;
|
|
11555
11787
|
}
|
|
@@ -11601,10 +11833,10 @@ var proposeFormObjectTool = {
|
|
|
11601
11833
|
ctx
|
|
11602
11834
|
}) => {
|
|
11603
11835
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
11604
|
-
const ext =
|
|
11836
|
+
const ext = extname3(safePath).toLowerCase();
|
|
11605
11837
|
let originalBuffer;
|
|
11606
11838
|
try {
|
|
11607
|
-
originalBuffer = await
|
|
11839
|
+
originalBuffer = await readFile4(safePath);
|
|
11608
11840
|
} catch {
|
|
11609
11841
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}`;
|
|
11610
11842
|
}
|
|
@@ -11791,14 +12023,14 @@ var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
|
11791
12023
|
]);
|
|
11792
12024
|
var MAX_DEPTH = 4;
|
|
11793
12025
|
var MAX_FILES = 500;
|
|
11794
|
-
var listFilesSchema =
|
|
11795
|
-
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)")
|
|
11796
12028
|
});
|
|
11797
12029
|
async function collectFiles(dir, cwd, depth, entries) {
|
|
11798
12030
|
if (depth > MAX_DEPTH || entries.length >= MAX_FILES) return;
|
|
11799
12031
|
let items;
|
|
11800
12032
|
try {
|
|
11801
|
-
items = await
|
|
12033
|
+
items = await readdir3(dir);
|
|
11802
12034
|
} catch {
|
|
11803
12035
|
return;
|
|
11804
12036
|
}
|
|
@@ -11806,15 +12038,15 @@ async function collectFiles(dir, cwd, depth, entries) {
|
|
|
11806
12038
|
if (entries.length >= MAX_FILES) break;
|
|
11807
12039
|
if (item.startsWith(".")) continue;
|
|
11808
12040
|
if (SKIP_DIRS.has(item)) continue;
|
|
11809
|
-
const fullPath =
|
|
12041
|
+
const fullPath = join4(dir, item);
|
|
11810
12042
|
let info;
|
|
11811
12043
|
try {
|
|
11812
|
-
info = await
|
|
12044
|
+
info = await stat3(fullPath);
|
|
11813
12045
|
} catch {
|
|
11814
12046
|
continue;
|
|
11815
12047
|
}
|
|
11816
12048
|
const relPath = relative2(cwd, fullPath);
|
|
11817
|
-
const ext =
|
|
12049
|
+
const ext = extname4(item).toLowerCase();
|
|
11818
12050
|
const isDoc = DOC_EXTENSIONS.has(ext);
|
|
11819
12051
|
if (info.isDirectory()) {
|
|
11820
12052
|
entries.push({ path: relPath + "/", isDir: true, isDoc: false });
|
|
@@ -11852,29 +12084,29 @@ var listFilesTool = {
|
|
|
11852
12084
|
return lines.join("\n") + truncateNotice;
|
|
11853
12085
|
}
|
|
11854
12086
|
};
|
|
11855
|
-
var cellEditItemSchema =
|
|
11856
|
-
tableIndex:
|
|
12087
|
+
var cellEditItemSchema = z5.object({
|
|
12088
|
+
tableIndex: z5.number().int().nonnegative().optional().describe(
|
|
11857
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)."
|
|
11858
12090
|
),
|
|
11859
|
-
row:
|
|
11860
|
-
col:
|
|
11861
|
-
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(
|
|
11862
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."
|
|
11863
12095
|
),
|
|
11864
|
-
direction:
|
|
11865
|
-
newText:
|
|
11866
|
-
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(
|
|
11867
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."
|
|
11868
12100
|
)
|
|
11869
12101
|
}).describe(
|
|
11870
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."
|
|
11871
12103
|
);
|
|
11872
|
-
var proposeCellEditSchema =
|
|
11873
|
-
path:
|
|
11874
|
-
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(
|
|
11875
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"
|
|
11876
12108
|
),
|
|
11877
|
-
summary:
|
|
12109
|
+
summary: z5.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
11878
12110
|
});
|
|
11879
12111
|
function tokenizeHwpxXml(xml) {
|
|
11880
12112
|
const tokens = [];
|
|
@@ -12209,7 +12441,7 @@ var proposeCellEditTool = {
|
|
|
12209
12441
|
ctx
|
|
12210
12442
|
}) => {
|
|
12211
12443
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
12212
|
-
const ext =
|
|
12444
|
+
const ext = extname5(safePath).toLowerCase();
|
|
12213
12445
|
if (ext === ".hwp") {
|
|
12214
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.";
|
|
12215
12447
|
}
|
|
@@ -12218,7 +12450,7 @@ var proposeCellEditTool = {
|
|
|
12218
12450
|
}
|
|
12219
12451
|
let originalBuffer;
|
|
12220
12452
|
try {
|
|
12221
|
-
originalBuffer = await
|
|
12453
|
+
originalBuffer = await readFile5(safePath);
|
|
12222
12454
|
} catch {
|
|
12223
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.`;
|
|
12224
12456
|
}
|
|
@@ -12547,10 +12779,10 @@ async function markdownToDocx(markdown) {
|
|
|
12547
12779
|
});
|
|
12548
12780
|
return Packer.toBuffer(doc);
|
|
12549
12781
|
}
|
|
12550
|
-
var proposeEditSchema =
|
|
12551
|
-
path:
|
|
12552
|
-
newMarkdown:
|
|
12553
|
-
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)")
|
|
12554
12786
|
});
|
|
12555
12787
|
var proposeEditTool = {
|
|
12556
12788
|
name: "propose_edit",
|
|
@@ -12562,10 +12794,10 @@ var proposeEditTool = {
|
|
|
12562
12794
|
ctx
|
|
12563
12795
|
}) => {
|
|
12564
12796
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
12565
|
-
const ext =
|
|
12797
|
+
const ext = extname6(safePath).toLowerCase();
|
|
12566
12798
|
let originalBuffer;
|
|
12567
12799
|
try {
|
|
12568
|
-
originalBuffer = await
|
|
12800
|
+
originalBuffer = await readFile6(safePath);
|
|
12569
12801
|
} catch {
|
|
12570
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.`;
|
|
12571
12803
|
}
|
|
@@ -12636,17 +12868,48 @@ ${diff}`;
|
|
|
12636
12868
|
};
|
|
12637
12869
|
}
|
|
12638
12870
|
};
|
|
12639
|
-
var proposeFindReplaceSchema =
|
|
12640
|
-
path:
|
|
12641
|
-
find:
|
|
12642
|
-
replace:
|
|
12643
|
-
caseSensitive:
|
|
12644
|
-
all:
|
|
12645
|
-
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)")
|
|
12646
12878
|
});
|
|
12879
|
+
var MAX_DIFF_SAMPLES = 20;
|
|
12647
12880
|
function escapeXml3(text3) {
|
|
12648
12881
|
return text3.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
12649
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
|
+
}
|
|
12650
12913
|
function replaceInSectionXml(xml, find, replace, caseSensitive, replaceAll, alreadyReplaced) {
|
|
12651
12914
|
if (!replaceAll && alreadyReplaced > 0) {
|
|
12652
12915
|
return { xml, count: 0 };
|
|
@@ -12754,7 +13017,19 @@ async function applyFindReplaceToHwpx(hwpxBuffer, find, replace, caseSensitive,
|
|
|
12754
13017
|
}
|
|
12755
13018
|
}
|
|
12756
13019
|
if (totalCount === 0) {
|
|
12757
|
-
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
|
+
}
|
|
12758
13033
|
}
|
|
12759
13034
|
const out = new import_jszip3.default();
|
|
12760
13035
|
const mimetypeEntry = zip.file("mimetype");
|
|
@@ -12773,7 +13048,8 @@ async function applyFindReplaceToHwpx(hwpxBuffer, find, replace, caseSensitive,
|
|
|
12773
13048
|
const buf = await out.generateAsync({ type: "nodebuffer", compression: "DEFLATE" });
|
|
12774
13049
|
return {
|
|
12775
13050
|
buffer: new Uint8Array(buf),
|
|
12776
|
-
count: totalCount
|
|
13051
|
+
count: totalCount,
|
|
13052
|
+
samples
|
|
12777
13053
|
};
|
|
12778
13054
|
}
|
|
12779
13055
|
var proposeFindReplaceTool = {
|
|
@@ -12786,7 +13062,7 @@ var proposeFindReplaceTool = {
|
|
|
12786
13062
|
ctx
|
|
12787
13063
|
}) => {
|
|
12788
13064
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
12789
|
-
const ext =
|
|
13065
|
+
const ext = extname7(safePath).toLowerCase();
|
|
12790
13066
|
if (ext === ".hwp") {
|
|
12791
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.";
|
|
12792
13068
|
}
|
|
@@ -12795,7 +13071,7 @@ var proposeFindReplaceTool = {
|
|
|
12795
13071
|
}
|
|
12796
13072
|
let originalBuf;
|
|
12797
13073
|
try {
|
|
12798
|
-
originalBuf = await
|
|
13074
|
+
originalBuf = await readFile7(safePath);
|
|
12799
13075
|
} catch {
|
|
12800
13076
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
|
|
12801
13077
|
}
|
|
@@ -12809,6 +13085,7 @@ var proposeFindReplaceTool = {
|
|
|
12809
13085
|
);
|
|
12810
13086
|
let newBytes;
|
|
12811
13087
|
let replacedCount;
|
|
13088
|
+
let diffSamples;
|
|
12812
13089
|
try {
|
|
12813
13090
|
const result = await applyFindReplaceToHwpx(
|
|
12814
13091
|
originalBytes,
|
|
@@ -12819,6 +13096,7 @@ var proposeFindReplaceTool = {
|
|
|
12819
13096
|
);
|
|
12820
13097
|
newBytes = result.buffer;
|
|
12821
13098
|
replacedCount = result.count;
|
|
13099
|
+
diffSamples = result.samples;
|
|
12822
13100
|
} catch (e) {
|
|
12823
13101
|
return `\uC624\uB958: \uCE58\uD658 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. ${String(e)}`;
|
|
12824
13102
|
}
|
|
@@ -12847,7 +13125,23 @@ var proposeFindReplaceTool = {
|
|
|
12847
13125
|
}
|
|
12848
13126
|
const { outputPath, willConvertFormat } = resolveOutputPath(safePath);
|
|
12849
13127
|
const allLabel = input.all ?? true ? `${replacedCount}\uACF3` : "\uCCAB \uBC88\uC9F8 1\uACF3";
|
|
12850
|
-
|
|
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
|
+
}
|
|
12851
13145
|
const stagedPath = await stageFile(ctx.sessionId, outputPath, newBytes);
|
|
12852
13146
|
const proposalId = crypto.randomUUID();
|
|
12853
13147
|
return {
|
|
@@ -12870,10 +13164,10 @@ var proposeFindReplaceTool = {
|
|
|
12870
13164
|
};
|
|
12871
13165
|
}
|
|
12872
13166
|
};
|
|
12873
|
-
var proposeFormFillSchema =
|
|
12874
|
-
path:
|
|
12875
|
-
fields:
|
|
12876
|
-
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)")
|
|
12877
13171
|
});
|
|
12878
13172
|
var proposeFormFillTool = {
|
|
12879
13173
|
name: "propose_form_fill",
|
|
@@ -12885,13 +13179,13 @@ var proposeFormFillTool = {
|
|
|
12885
13179
|
ctx
|
|
12886
13180
|
}) => {
|
|
12887
13181
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
12888
|
-
const ext =
|
|
13182
|
+
const ext = extname8(safePath).toLowerCase();
|
|
12889
13183
|
if (ext !== ".hwpx" && ext !== ".hwp") {
|
|
12890
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.`;
|
|
12891
13185
|
}
|
|
12892
13186
|
let originalBuffer;
|
|
12893
13187
|
try {
|
|
12894
|
-
originalBuffer = await
|
|
13188
|
+
originalBuffer = await readFile8(safePath);
|
|
12895
13189
|
} catch {
|
|
12896
13190
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
|
|
12897
13191
|
}
|
|
@@ -12959,16 +13253,16 @@ var proposeFormFillTool = {
|
|
|
12959
13253
|
};
|
|
12960
13254
|
}
|
|
12961
13255
|
};
|
|
12962
|
-
var proposeSheetEditSchema =
|
|
12963
|
-
path:
|
|
12964
|
-
updates:
|
|
12965
|
-
|
|
12966
|
-
sheet:
|
|
12967
|
-
cell:
|
|
12968
|
-
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")
|
|
12969
13263
|
})
|
|
12970
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"),
|
|
12971
|
-
summary:
|
|
13265
|
+
summary: z9.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
12972
13266
|
});
|
|
12973
13267
|
var proposeSheetEditTool = {
|
|
12974
13268
|
name: "propose_sheet_edit",
|
|
@@ -12980,13 +13274,13 @@ var proposeSheetEditTool = {
|
|
|
12980
13274
|
ctx
|
|
12981
13275
|
}) => {
|
|
12982
13276
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
12983
|
-
const ext =
|
|
13277
|
+
const ext = extname9(safePath).toLowerCase();
|
|
12984
13278
|
if (ext !== ".xlsx" && ext !== ".xls") {
|
|
12985
13279
|
return `\uC624\uB958: propose_sheet_edit\uC740 .xlsx/.xls \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. \uD604\uC7AC \uD30C\uC77C: ${ext}.`;
|
|
12986
13280
|
}
|
|
12987
13281
|
let originalBuffer;
|
|
12988
13282
|
try {
|
|
12989
|
-
originalBuffer = await
|
|
13283
|
+
originalBuffer = await readFile9(safePath);
|
|
12990
13284
|
} catch {
|
|
12991
13285
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
|
|
12992
13286
|
}
|
|
@@ -13077,47 +13371,47 @@ function detectStructuralLoss(beforeBlocks, afterBlocks) {
|
|
|
13077
13371
|
}
|
|
13078
13372
|
return { lost: false, detail: "" };
|
|
13079
13373
|
}
|
|
13080
|
-
var insertRowOpSchema =
|
|
13081
|
-
type:
|
|
13082
|
-
row:
|
|
13083
|
-
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")
|
|
13084
13378
|
});
|
|
13085
|
-
var deleteRowOpSchema =
|
|
13086
|
-
type:
|
|
13087
|
-
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)")
|
|
13088
13382
|
});
|
|
13089
|
-
var insertColumnOpSchema =
|
|
13090
|
-
type:
|
|
13091
|
-
col:
|
|
13092
|
-
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")
|
|
13093
13387
|
});
|
|
13094
|
-
var deleteColumnOpSchema =
|
|
13095
|
-
type:
|
|
13096
|
-
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)")
|
|
13097
13391
|
});
|
|
13098
|
-
var mergeCellsOpSchema =
|
|
13099
|
-
type:
|
|
13100
|
-
startRow:
|
|
13101
|
-
startCol:
|
|
13102
|
-
endRow:
|
|
13103
|
-
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)")
|
|
13104
13398
|
});
|
|
13105
|
-
var operationSchema =
|
|
13399
|
+
var operationSchema = z10.discriminatedUnion("type", [
|
|
13106
13400
|
insertRowOpSchema,
|
|
13107
13401
|
deleteRowOpSchema,
|
|
13108
13402
|
insertColumnOpSchema,
|
|
13109
13403
|
deleteColumnOpSchema,
|
|
13110
13404
|
mergeCellsOpSchema
|
|
13111
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.");
|
|
13112
|
-
var proposeTableStructureSchema =
|
|
13113
|
-
path:
|
|
13114
|
-
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(
|
|
13115
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."
|
|
13116
13410
|
),
|
|
13117
|
-
operations:
|
|
13411
|
+
operations: z10.array(operationSchema).min(1).describe(
|
|
13118
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."
|
|
13119
13413
|
),
|
|
13120
|
-
summary:
|
|
13414
|
+
summary: z10.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
13121
13415
|
});
|
|
13122
13416
|
function tokenizeHwpxXml2(xml) {
|
|
13123
13417
|
const tokens = [];
|
|
@@ -13792,7 +14086,7 @@ var proposeTableStructureTool = {
|
|
|
13792
14086
|
ctx
|
|
13793
14087
|
}) => {
|
|
13794
14088
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
13795
|
-
const ext =
|
|
14089
|
+
const ext = extname10(safePath).toLowerCase();
|
|
13796
14090
|
if (ext === ".hwp") {
|
|
13797
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.";
|
|
13798
14092
|
}
|
|
@@ -13801,7 +14095,7 @@ var proposeTableStructureTool = {
|
|
|
13801
14095
|
}
|
|
13802
14096
|
let originalBuf;
|
|
13803
14097
|
try {
|
|
13804
|
-
originalBuf = await
|
|
14098
|
+
originalBuf = await readFile10(safePath);
|
|
13805
14099
|
} catch {
|
|
13806
14100
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
|
|
13807
14101
|
}
|
|
@@ -13997,11 +14291,11 @@ function searchExcerpts(markdown, query) {
|
|
|
13997
14291
|
}
|
|
13998
14292
|
return result;
|
|
13999
14293
|
}
|
|
14000
|
-
var readDocumentSchema =
|
|
14001
|
-
path:
|
|
14002
|
-
pages:
|
|
14003
|
-
outline:
|
|
14004
|
-
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)")
|
|
14005
14299
|
});
|
|
14006
14300
|
function applyReadMode(body, outline, search) {
|
|
14007
14301
|
if (outline === true) {
|
|
@@ -14023,18 +14317,18 @@ var readDocumentTool = {
|
|
|
14023
14317
|
}) => {
|
|
14024
14318
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
14025
14319
|
try {
|
|
14026
|
-
const fileStat = await
|
|
14320
|
+
const fileStat = await stat4(safePath);
|
|
14027
14321
|
const guardMsg = fileSizeGuardMessage(fileStat.size, MAX_FILE_SIZE_BYTES);
|
|
14028
14322
|
if (guardMsg !== null) return guardMsg;
|
|
14029
14323
|
} catch (e) {
|
|
14030
14324
|
const msg = e instanceof Error ? e.message : String(e);
|
|
14031
14325
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${msg}`;
|
|
14032
14326
|
}
|
|
14033
|
-
const ext =
|
|
14327
|
+
const ext = extname11(safePath).toLowerCase();
|
|
14034
14328
|
if (PLAIN_TEXT_EXTS.has(ext)) {
|
|
14035
14329
|
let raw;
|
|
14036
14330
|
try {
|
|
14037
|
-
raw = await
|
|
14331
|
+
raw = await readFile11(safePath, "utf-8");
|
|
14038
14332
|
} catch (e) {
|
|
14039
14333
|
const msg = e instanceof Error ? e.message : String(e);
|
|
14040
14334
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${msg}`;
|
|
@@ -14134,8 +14428,8 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
14134
14428
|
".csv",
|
|
14135
14429
|
".log"
|
|
14136
14430
|
]);
|
|
14137
|
-
var readFileSchema =
|
|
14138
|
-
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)")
|
|
14139
14433
|
});
|
|
14140
14434
|
var readFileTool = {
|
|
14141
14435
|
name: "read_file",
|
|
@@ -14149,7 +14443,7 @@ var readFileTool = {
|
|
|
14149
14443
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
14150
14444
|
let info;
|
|
14151
14445
|
try {
|
|
14152
|
-
info = await
|
|
14446
|
+
info = await stat5(safePath);
|
|
14153
14447
|
} catch {
|
|
14154
14448
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}`;
|
|
14155
14449
|
}
|
|
@@ -14159,8 +14453,8 @@ var readFileTool = {
|
|
|
14159
14453
|
if (info.size > MAX_SIZE) {
|
|
14160
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.`;
|
|
14161
14455
|
}
|
|
14162
|
-
const { extname:
|
|
14163
|
-
const ext =
|
|
14456
|
+
const { extname: extname14 } = await import("path");
|
|
14457
|
+
const ext = extname14(safePath).toLowerCase();
|
|
14164
14458
|
if (!TEXT_EXTENSIONS.has(ext) && ext !== "") {
|
|
14165
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.`;
|
|
14166
14460
|
}
|
|
@@ -14175,9 +14469,9 @@ var readFileTool = {
|
|
|
14175
14469
|
}
|
|
14176
14470
|
};
|
|
14177
14471
|
var MAX_PREVIEW_CHARS = 1e4;
|
|
14178
|
-
var writeNewDocumentSchema =
|
|
14179
|
-
path:
|
|
14180
|
-
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)")
|
|
14181
14475
|
});
|
|
14182
14476
|
var writeNewDocumentTool = {
|
|
14183
14477
|
name: "write_new_document",
|
|
@@ -14189,9 +14483,9 @@ var writeNewDocumentTool = {
|
|
|
14189
14483
|
ctx
|
|
14190
14484
|
}) => {
|
|
14191
14485
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
14192
|
-
const ext =
|
|
14486
|
+
const ext = extname12(safePath).toLowerCase();
|
|
14193
14487
|
try {
|
|
14194
|
-
await
|
|
14488
|
+
await stat6(safePath);
|
|
14195
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.`;
|
|
14196
14490
|
} catch {
|
|
14197
14491
|
}
|
|
@@ -14239,12 +14533,12 @@ ${preview}`,
|
|
|
14239
14533
|
};
|
|
14240
14534
|
}
|
|
14241
14535
|
};
|
|
14242
|
-
var writeNewSpreadsheetSchema =
|
|
14243
|
-
path:
|
|
14244
|
-
sheets:
|
|
14245
|
-
|
|
14246
|
-
name:
|
|
14247
|
-
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)")
|
|
14248
14542
|
})
|
|
14249
14543
|
).min(1).describe("\uC0DD\uC131\uD560 \uC2DC\uD2B8 \uBAA9\uB85D")
|
|
14250
14544
|
});
|
|
@@ -14258,12 +14552,12 @@ var writeNewSpreadsheetTool = {
|
|
|
14258
14552
|
ctx
|
|
14259
14553
|
}) => {
|
|
14260
14554
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
14261
|
-
const ext =
|
|
14555
|
+
const ext = extname13(safePath).toLowerCase();
|
|
14262
14556
|
if (ext !== ".xlsx") {
|
|
14263
14557
|
return `\uC624\uB958: write_new_spreadsheet\uC740 .xlsx \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. \uD604\uC7AC \uD655\uC7A5\uC790: ${ext}.`;
|
|
14264
14558
|
}
|
|
14265
14559
|
try {
|
|
14266
|
-
await
|
|
14560
|
+
await stat7(safePath);
|
|
14267
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.`;
|
|
14268
14562
|
} catch {
|
|
14269
14563
|
}
|
|
@@ -14316,6 +14610,7 @@ function createDocTools(_ctx) {
|
|
|
14316
14610
|
readDocumentTool,
|
|
14317
14611
|
compareDocumentsTool,
|
|
14318
14612
|
listFilesTool,
|
|
14613
|
+
listBackupsTool,
|
|
14319
14614
|
readFileTool,
|
|
14320
14615
|
proposeEditTool,
|
|
14321
14616
|
proposeFormFillTool,
|
|
@@ -14326,7 +14621,8 @@ function createDocTools(_ctx) {
|
|
|
14326
14621
|
listFormObjectsTool,
|
|
14327
14622
|
proposeFormObjectTool,
|
|
14328
14623
|
writeNewDocumentTool,
|
|
14329
|
-
writeNewSpreadsheetTool
|
|
14624
|
+
writeNewSpreadsheetTool,
|
|
14625
|
+
restoreBackupTool
|
|
14330
14626
|
];
|
|
14331
14627
|
}
|
|
14332
14628
|
|
|
@@ -15130,7 +15426,7 @@ async function runOnboarding() {
|
|
|
15130
15426
|
|
|
15131
15427
|
// src/update.ts
|
|
15132
15428
|
import { spawn } from "child_process";
|
|
15133
|
-
import { mkdir as mkdir4, readFile as
|
|
15429
|
+
import { mkdir as mkdir4, readFile as readFile12, writeFile as writeFile3 } from "fs/promises";
|
|
15134
15430
|
import { dirname as dirname3 } from "path";
|
|
15135
15431
|
function compareSemver(a, b) {
|
|
15136
15432
|
const parse6 = (v) => {
|
|
@@ -15151,7 +15447,7 @@ function compareSemver(a, b) {
|
|
|
15151
15447
|
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
15152
15448
|
async function readCache(cachePath) {
|
|
15153
15449
|
try {
|
|
15154
|
-
const raw = await
|
|
15450
|
+
const raw = await readFile12(cachePath, "utf-8");
|
|
15155
15451
|
const parsed = JSON.parse(raw);
|
|
15156
15452
|
if (parsed !== null && typeof parsed === "object" && "checkedAt" in parsed && "latest" in parsed && typeof parsed.checkedAt === "string" && typeof parsed.latest === "string") {
|
|
15157
15453
|
return parsed;
|