@kodocagent/cli 0.4.2 → 0.4.4
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 +490 -175
- 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");
|
|
@@ -10999,16 +11022,227 @@ async function cleanOldBackups(maxAgeDays = 30, baseDir) {
|
|
|
10999
11022
|
function resolveOutputPath(targetPath) {
|
|
11000
11023
|
const ext = extname(targetPath).toLowerCase();
|
|
11001
11024
|
if (ext === ".hwp") {
|
|
11002
|
-
|
|
11003
|
-
|
|
11025
|
+
return { outputPath: targetPath.slice(0, -4) + ".hwpx", willConvertFormat: ".hwp \u2192 .hwpx" };
|
|
11026
|
+
}
|
|
11027
|
+
if (ext === ".xls") {
|
|
11028
|
+
return { outputPath: targetPath.slice(0, -4) + ".xlsx", willConvertFormat: ".xls \u2192 .xlsx" };
|
|
11004
11029
|
}
|
|
11005
11030
|
return { outputPath: targetPath, willConvertFormat: void 0 };
|
|
11006
11031
|
}
|
|
11032
|
+
function parseBackupFilename(filename) {
|
|
11033
|
+
const m = filename.match(/^(\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d{3}Z)-(.+)$/);
|
|
11034
|
+
if (!m) return null;
|
|
11035
|
+
return { tsToken: m[1], origBasename: m[2] };
|
|
11036
|
+
}
|
|
11037
|
+
function formatTimestamp(tsToken) {
|
|
11038
|
+
const restored = tsToken.replace(
|
|
11039
|
+
/^(\d{4}-\d{2}-\d{2})T(\d{2})-(\d{2})-(\d{2})-(\d{3})Z$/,
|
|
11040
|
+
"$1T$2:$3:$4.$5Z"
|
|
11041
|
+
);
|
|
11042
|
+
try {
|
|
11043
|
+
const d = new Date(restored);
|
|
11044
|
+
if (Number.isNaN(d.getTime())) return tsToken;
|
|
11045
|
+
return d.toISOString().replace("T", " ").slice(0, 19);
|
|
11046
|
+
} catch {
|
|
11047
|
+
return tsToken;
|
|
11048
|
+
}
|
|
11049
|
+
}
|
|
11050
|
+
var MAX_BACKUP_LIST = 50;
|
|
11051
|
+
var listBackupsSchema = z3.object({
|
|
11052
|
+
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)")
|
|
11053
|
+
});
|
|
11054
|
+
var listBackupsTool = {
|
|
11055
|
+
name: "list_backups",
|
|
11056
|
+
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.",
|
|
11057
|
+
inputSchema: listBackupsSchema,
|
|
11058
|
+
requiresApproval: false,
|
|
11059
|
+
execute: async ({
|
|
11060
|
+
input
|
|
11061
|
+
}) => {
|
|
11062
|
+
const backupsDir = KODOC_PATHS.backups;
|
|
11063
|
+
let allEntries;
|
|
11064
|
+
try {
|
|
11065
|
+
allEntries = await readdir22(backupsDir);
|
|
11066
|
+
} catch {
|
|
11067
|
+
return "\uBC31\uC5C5\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.";
|
|
11068
|
+
}
|
|
11069
|
+
if (allEntries.length === 0) {
|
|
11070
|
+
return "\uBC31\uC5C5\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.";
|
|
11071
|
+
}
|
|
11072
|
+
const parsed = [];
|
|
11073
|
+
for (const filename of allEntries) {
|
|
11074
|
+
const info = parseBackupFilename(filename);
|
|
11075
|
+
if (!info) continue;
|
|
11076
|
+
const fullPath = join32(backupsDir, filename);
|
|
11077
|
+
let mtimeMs = 0;
|
|
11078
|
+
try {
|
|
11079
|
+
const s = await stat22(fullPath);
|
|
11080
|
+
mtimeMs = s.mtimeMs;
|
|
11081
|
+
} catch {
|
|
11082
|
+
mtimeMs = 0;
|
|
11083
|
+
}
|
|
11084
|
+
parsed.push({ filename, fullPath, ...info, mtimeMs });
|
|
11085
|
+
}
|
|
11086
|
+
let filtered = parsed;
|
|
11087
|
+
if (input.path) {
|
|
11088
|
+
const targetBase = basename3(input.path);
|
|
11089
|
+
filtered = parsed.filter((e) => e.origBasename === targetBase);
|
|
11090
|
+
}
|
|
11091
|
+
if (filtered.length === 0) {
|
|
11092
|
+
if (input.path) {
|
|
11093
|
+
return `\uD574\uB2F9 \uD30C\uC77C\uC758 \uBC31\uC5C5\uC774 \uC5C6\uC2B5\uB2C8\uB2E4: ${basename3(input.path)}`;
|
|
11094
|
+
}
|
|
11095
|
+
return "\uBC31\uC5C5\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.";
|
|
11096
|
+
}
|
|
11097
|
+
filtered.sort((a, b) => {
|
|
11098
|
+
if (b.mtimeMs !== a.mtimeMs) return b.mtimeMs - a.mtimeMs;
|
|
11099
|
+
return b.tsToken.localeCompare(a.tsToken);
|
|
11100
|
+
});
|
|
11101
|
+
const total = filtered.length;
|
|
11102
|
+
const truncated = filtered.length > MAX_BACKUP_LIST;
|
|
11103
|
+
const display = filtered.slice(0, MAX_BACKUP_LIST);
|
|
11104
|
+
const lines = display.map(
|
|
11105
|
+
(e, i) => `${i + 1}. ${e.origBasename} [${formatTimestamp(e.tsToken)}] ${e.fullPath}`
|
|
11106
|
+
);
|
|
11107
|
+
const notice = truncated ? `
|
|
11108
|
+
(\uCD1D ${total}\uAC74 \uC911 \uCD5C\uC2E0 ${MAX_BACKUP_LIST}\uAC74\uB9CC \uD45C\uC2DC\uB429\uB2C8\uB2E4.)` : "";
|
|
11109
|
+
return lines.join("\n") + notice;
|
|
11110
|
+
}
|
|
11111
|
+
};
|
|
11112
|
+
var restoreBackupSchema = z3.object({
|
|
11113
|
+
path: z3.string().describe("\uBCF5\uC6D0\uD560 \uB300\uC0C1 \uD30C\uC77C \uACBD\uB85C"),
|
|
11114
|
+
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)"),
|
|
11115
|
+
summary: z3.string().optional().describe("\uBCF5\uC6D0 \uC0AC\uC720/\uC694\uC57D")
|
|
11116
|
+
});
|
|
11117
|
+
var restoreBackupTool = {
|
|
11118
|
+
name: "restore_backup",
|
|
11119
|
+
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.",
|
|
11120
|
+
inputSchema: restoreBackupSchema,
|
|
11121
|
+
requiresApproval: true,
|
|
11122
|
+
propose: async ({
|
|
11123
|
+
input,
|
|
11124
|
+
ctx
|
|
11125
|
+
}) => {
|
|
11126
|
+
let safePath;
|
|
11127
|
+
try {
|
|
11128
|
+
safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
11129
|
+
} catch (e) {
|
|
11130
|
+
return `\uACBD\uB85C \uC624\uB958: ${e instanceof Error ? e.message : String(e)}`;
|
|
11131
|
+
}
|
|
11132
|
+
const targetBase = basename3(safePath);
|
|
11133
|
+
const backupsDir = KODOC_PATHS.backups;
|
|
11134
|
+
let allEntries;
|
|
11135
|
+
try {
|
|
11136
|
+
allEntries = await readdir22(backupsDir);
|
|
11137
|
+
} catch {
|
|
11138
|
+
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.`;
|
|
11139
|
+
}
|
|
11140
|
+
const candidates = [];
|
|
11141
|
+
for (const filename of allEntries) {
|
|
11142
|
+
const info = parseBackupFilename(filename);
|
|
11143
|
+
if (!info) continue;
|
|
11144
|
+
if (info.origBasename !== targetBase) continue;
|
|
11145
|
+
const fullPath = join32(backupsDir, filename);
|
|
11146
|
+
let mtimeMs = 0;
|
|
11147
|
+
try {
|
|
11148
|
+
const s = await stat22(fullPath);
|
|
11149
|
+
mtimeMs = s.mtimeMs;
|
|
11150
|
+
} catch {
|
|
11151
|
+
mtimeMs = 0;
|
|
11152
|
+
}
|
|
11153
|
+
candidates.push({ filename, fullPath, tsToken: info.tsToken, mtimeMs });
|
|
11154
|
+
}
|
|
11155
|
+
if (candidates.length === 0) {
|
|
11156
|
+
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.`;
|
|
11157
|
+
}
|
|
11158
|
+
let chosen;
|
|
11159
|
+
if (input.backup) {
|
|
11160
|
+
const found = candidates.find(
|
|
11161
|
+
(c) => c.filename === input.backup || c.fullPath.endsWith(input.backup)
|
|
11162
|
+
);
|
|
11163
|
+
if (!found) {
|
|
11164
|
+
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.`;
|
|
11165
|
+
}
|
|
11166
|
+
chosen = found;
|
|
11167
|
+
} else {
|
|
11168
|
+
candidates.sort(
|
|
11169
|
+
(a, b) => b.mtimeMs !== a.mtimeMs ? b.mtimeMs - a.mtimeMs : b.tsToken.localeCompare(a.tsToken)
|
|
11170
|
+
);
|
|
11171
|
+
chosen = candidates[0];
|
|
11172
|
+
}
|
|
11173
|
+
let backupBytes;
|
|
11174
|
+
try {
|
|
11175
|
+
backupBytes = await readFile22(chosen.fullPath);
|
|
11176
|
+
} catch {
|
|
11177
|
+
return `\uBC31\uC5C5 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${chosen.fullPath}`;
|
|
11178
|
+
}
|
|
11179
|
+
const stagedPath = await stageFile(ctx.sessionId, targetBase, backupBytes);
|
|
11180
|
+
const ext = extname2(targetBase).toLowerCase();
|
|
11181
|
+
const isText = ext === ".md" || ext === ".txt";
|
|
11182
|
+
let diff;
|
|
11183
|
+
if (isText) {
|
|
11184
|
+
let currentText = "";
|
|
11185
|
+
try {
|
|
11186
|
+
currentText = await readFile22(safePath, "utf-8");
|
|
11187
|
+
} catch {
|
|
11188
|
+
currentText = "";
|
|
11189
|
+
}
|
|
11190
|
+
const backupText = backupBytes.toString("utf-8");
|
|
11191
|
+
diff = markdownDiff(currentText, backupText, targetBase);
|
|
11192
|
+
} else {
|
|
11193
|
+
let currentSize = "\uD30C\uC77C \uC5C6\uC74C";
|
|
11194
|
+
try {
|
|
11195
|
+
const s = await stat22(safePath);
|
|
11196
|
+
currentSize = `${s.size} bytes`;
|
|
11197
|
+
} catch {
|
|
11198
|
+
currentSize = "\uD30C\uC77C \uC5C6\uC74C";
|
|
11199
|
+
}
|
|
11200
|
+
const backupSize = `${backupBytes.length} bytes`;
|
|
11201
|
+
diff = [
|
|
11202
|
+
`\uBCF5\uC6D0 \uB300\uC0C1: ${safePath}`,
|
|
11203
|
+
`\uD604\uC7AC \uD30C\uC77C: ${currentSize}`,
|
|
11204
|
+
`\uBC31\uC5C5 \uD30C\uC77C: ${chosen.fullPath}`,
|
|
11205
|
+
`\uBC31\uC5C5 \uC2DC\uAC01: ${formatTimestamp(chosen.tsToken)}`,
|
|
11206
|
+
`\uBC31\uC5C5 \uD06C\uAE30: ${backupSize}`,
|
|
11207
|
+
`\u2192 \uD604\uC7AC \uD30C\uC77C\uC744 \uC704 \uBC31\uC5C5\uC73C\uB85C \uB418\uB3CC\uB9BD\uB2C8\uB2E4.`
|
|
11208
|
+
].join("\n");
|
|
11209
|
+
}
|
|
11210
|
+
const warnings = [];
|
|
11211
|
+
const autoSelected = !input.backup && candidates.length > 1;
|
|
11212
|
+
if (autoSelected) {
|
|
11213
|
+
warnings.push(
|
|
11214
|
+
`\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.`
|
|
11215
|
+
);
|
|
11216
|
+
}
|
|
11217
|
+
warnings.push(
|
|
11218
|
+
"\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)."
|
|
11219
|
+
);
|
|
11220
|
+
const summary = input.summary ?? `\uBC31\uC5C5\uC73C\uB85C \uB418\uB3CC\uB9AC\uAE30: ${targetBase}`;
|
|
11221
|
+
const chosenBackupPath = chosen.fullPath;
|
|
11222
|
+
return {
|
|
11223
|
+
proposal: {
|
|
11224
|
+
id: crypto.randomUUID(),
|
|
11225
|
+
kind: "restore",
|
|
11226
|
+
targetPath: safePath,
|
|
11227
|
+
stagedPath,
|
|
11228
|
+
summary,
|
|
11229
|
+
diff,
|
|
11230
|
+
warnings
|
|
11231
|
+
},
|
|
11232
|
+
commit: async () => {
|
|
11233
|
+
const safetyBackup = await backupFile(safePath);
|
|
11234
|
+
await commitStaged(stagedPath, safePath);
|
|
11235
|
+
const safetyNote = safetyBackup ? ` (\uBCF5\uC6D0 \uC804 \uD604\uC7AC \uC0C1\uD0DC \uBC31\uC5C5: ${safetyBackup})` : "";
|
|
11236
|
+
return `\uBCF5\uC6D0 \uC644\uB8CC: ${safePath} \u2190 ${chosenBackupPath}${safetyNote}`;
|
|
11237
|
+
}
|
|
11238
|
+
};
|
|
11239
|
+
}
|
|
11240
|
+
};
|
|
11007
11241
|
var MAX_MARKDOWN_LENGTH = 8e4;
|
|
11008
11242
|
var MAX_BLOCK_TEXT_LENGTH = 200;
|
|
11009
|
-
var compareDocumentsSchema =
|
|
11010
|
-
pathA:
|
|
11011
|
-
pathB:
|
|
11243
|
+
var compareDocumentsSchema = z22.object({
|
|
11244
|
+
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)"),
|
|
11245
|
+
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
11246
|
});
|
|
11013
11247
|
function bufferToArrayBuffer(buf) {
|
|
11014
11248
|
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
|
@@ -11046,13 +11280,13 @@ var compareDocumentsTool = {
|
|
|
11046
11280
|
let bufA;
|
|
11047
11281
|
let bufB;
|
|
11048
11282
|
try {
|
|
11049
|
-
bufA = await
|
|
11283
|
+
bufA = await readFile32(safePathA);
|
|
11050
11284
|
} catch (e) {
|
|
11051
11285
|
const msg = e instanceof Error ? e.message : String(e);
|
|
11052
11286
|
return `\uC624\uB958: \uCCAB \uBC88\uC9F8 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (${input.pathA}): ${msg}`;
|
|
11053
11287
|
}
|
|
11054
11288
|
try {
|
|
11055
|
-
bufB = await
|
|
11289
|
+
bufB = await readFile32(safePathB);
|
|
11056
11290
|
} catch (e) {
|
|
11057
11291
|
const msg = e instanceof Error ? e.message : String(e);
|
|
11058
11292
|
return `\uC624\uB958: \uB450 \uBC88\uC9F8 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 (${input.pathB}): ${msg}`;
|
|
@@ -11500,14 +11734,14 @@ function validateHwpxBuffer(ext, buffer) {
|
|
|
11500
11734
|
}
|
|
11501
11735
|
return null;
|
|
11502
11736
|
}
|
|
11503
|
-
var listFormObjectsSchema =
|
|
11504
|
-
path:
|
|
11737
|
+
var listFormObjectsSchema = z32.object({
|
|
11738
|
+
path: z32.string().describe("\uC77D\uC744 .hwpx \uD30C\uC77C \uACBD\uB85C")
|
|
11505
11739
|
});
|
|
11506
|
-
var formEditSetSchema =
|
|
11507
|
-
caption:
|
|
11508
|
-
checked:
|
|
11509
|
-
selected:
|
|
11510
|
-
text:
|
|
11740
|
+
var formEditSetSchema = z32.object({
|
|
11741
|
+
caption: z32.string().optional().describe("PushButton \uCEA1\uC158 \uD14D\uC2A4\uD2B8"),
|
|
11742
|
+
checked: z32.boolean().optional().describe("CheckBox/RadioButton \uCCB4\uD06C \uC0C1\uD0DC (true=CHECKED)"),
|
|
11743
|
+
selected: z32.string().optional().describe("ComboBox \uC120\uD0DD \uAC12 (listItem \uC911 \uD558\uB098\uC5EC\uC57C \uD568)"),
|
|
11744
|
+
text: z32.string().optional().describe("Edit \uD14D\uC2A4\uD2B8 \uB0B4\uC6A9")
|
|
11511
11745
|
}).refine(
|
|
11512
11746
|
(v) => {
|
|
11513
11747
|
const keys = ["caption", "checked", "selected", "text"].filter(
|
|
@@ -11517,24 +11751,24 @@ var formEditSetSchema = z22.object({
|
|
|
11517
11751
|
},
|
|
11518
11752
|
{ message: "set \uD544\uB4DC\uB294 caption/checked/selected/text \uC911 \uC815\uD655\uD788 \uD558\uB098\uB9CC \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4." }
|
|
11519
11753
|
);
|
|
11520
|
-
var formEditExpectedSchema =
|
|
11521
|
-
caption:
|
|
11522
|
-
checked:
|
|
11523
|
-
selected:
|
|
11524
|
-
text:
|
|
11754
|
+
var formEditExpectedSchema = z32.object({
|
|
11755
|
+
caption: z32.string().optional(),
|
|
11756
|
+
checked: z32.boolean().optional(),
|
|
11757
|
+
selected: z32.string().optional(),
|
|
11758
|
+
text: z32.string().optional()
|
|
11525
11759
|
}).optional();
|
|
11526
|
-
var formEditItemSchema =
|
|
11527
|
-
name:
|
|
11528
|
-
index:
|
|
11760
|
+
var formEditItemSchema = z32.object({
|
|
11761
|
+
name: z32.string().describe("\uC591\uC2DD \uAC1C\uCCB4\uC758 name \uC18D\uC131 \uAC12"),
|
|
11762
|
+
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
11763
|
set: formEditSetSchema.describe("\uBCC0\uACBD\uD560 \uAC12 (caption/checked/selected/text \uC911 \uD558\uB098)"),
|
|
11530
11764
|
expected: formEditExpectedSchema.describe(
|
|
11531
11765
|
"\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
11766
|
)
|
|
11533
11767
|
});
|
|
11534
|
-
var proposeFormObjectSchema =
|
|
11535
|
-
path:
|
|
11536
|
-
edits:
|
|
11537
|
-
summary:
|
|
11768
|
+
var proposeFormObjectSchema = z32.object({
|
|
11769
|
+
path: z32.string().describe("\uC218\uC815\uD560 .hwpx \uD30C\uC77C \uACBD\uB85C"),
|
|
11770
|
+
edits: z32.array(formEditItemSchema).min(1).describe("\uC591\uC2DD \uAC1C\uCCB4 \uD3B8\uC9D1 \uBAA9\uB85D"),
|
|
11771
|
+
summary: z32.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
11538
11772
|
});
|
|
11539
11773
|
var listFormObjectsTool = {
|
|
11540
11774
|
name: "list_form_objects",
|
|
@@ -11546,10 +11780,10 @@ var listFormObjectsTool = {
|
|
|
11546
11780
|
ctx
|
|
11547
11781
|
}) => {
|
|
11548
11782
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
11549
|
-
const ext =
|
|
11783
|
+
const ext = extname3(safePath).toLowerCase();
|
|
11550
11784
|
let buffer;
|
|
11551
11785
|
try {
|
|
11552
|
-
buffer = await
|
|
11786
|
+
buffer = await readFile4(safePath);
|
|
11553
11787
|
} catch {
|
|
11554
11788
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}`;
|
|
11555
11789
|
}
|
|
@@ -11601,10 +11835,10 @@ var proposeFormObjectTool = {
|
|
|
11601
11835
|
ctx
|
|
11602
11836
|
}) => {
|
|
11603
11837
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
11604
|
-
const ext =
|
|
11838
|
+
const ext = extname3(safePath).toLowerCase();
|
|
11605
11839
|
let originalBuffer;
|
|
11606
11840
|
try {
|
|
11607
|
-
originalBuffer = await
|
|
11841
|
+
originalBuffer = await readFile4(safePath);
|
|
11608
11842
|
} catch {
|
|
11609
11843
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}`;
|
|
11610
11844
|
}
|
|
@@ -11791,14 +12025,14 @@ var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
|
11791
12025
|
]);
|
|
11792
12026
|
var MAX_DEPTH = 4;
|
|
11793
12027
|
var MAX_FILES = 500;
|
|
11794
|
-
var listFilesSchema =
|
|
11795
|
-
dir:
|
|
12028
|
+
var listFilesSchema = z4.object({
|
|
12029
|
+
dir: z4.string().optional().describe("\uBAA9\uB85D\uC744 \uC870\uD68C\uD560 \uB514\uB809\uD130\uB9AC (\uBBF8\uC9C0\uC815 \uC2DC cwd \uC804\uCCB4)")
|
|
11796
12030
|
});
|
|
11797
12031
|
async function collectFiles(dir, cwd, depth, entries) {
|
|
11798
12032
|
if (depth > MAX_DEPTH || entries.length >= MAX_FILES) return;
|
|
11799
12033
|
let items;
|
|
11800
12034
|
try {
|
|
11801
|
-
items = await
|
|
12035
|
+
items = await readdir3(dir);
|
|
11802
12036
|
} catch {
|
|
11803
12037
|
return;
|
|
11804
12038
|
}
|
|
@@ -11806,15 +12040,15 @@ async function collectFiles(dir, cwd, depth, entries) {
|
|
|
11806
12040
|
if (entries.length >= MAX_FILES) break;
|
|
11807
12041
|
if (item.startsWith(".")) continue;
|
|
11808
12042
|
if (SKIP_DIRS.has(item)) continue;
|
|
11809
|
-
const fullPath =
|
|
12043
|
+
const fullPath = join4(dir, item);
|
|
11810
12044
|
let info;
|
|
11811
12045
|
try {
|
|
11812
|
-
info = await
|
|
12046
|
+
info = await stat3(fullPath);
|
|
11813
12047
|
} catch {
|
|
11814
12048
|
continue;
|
|
11815
12049
|
}
|
|
11816
12050
|
const relPath = relative2(cwd, fullPath);
|
|
11817
|
-
const ext =
|
|
12051
|
+
const ext = extname4(item).toLowerCase();
|
|
11818
12052
|
const isDoc = DOC_EXTENSIONS.has(ext);
|
|
11819
12053
|
if (info.isDirectory()) {
|
|
11820
12054
|
entries.push({ path: relPath + "/", isDir: true, isDoc: false });
|
|
@@ -11852,29 +12086,29 @@ var listFilesTool = {
|
|
|
11852
12086
|
return lines.join("\n") + truncateNotice;
|
|
11853
12087
|
}
|
|
11854
12088
|
};
|
|
11855
|
-
var cellEditItemSchema =
|
|
11856
|
-
tableIndex:
|
|
12089
|
+
var cellEditItemSchema = z5.object({
|
|
12090
|
+
tableIndex: z5.number().int().nonnegative().optional().describe(
|
|
11857
12091
|
"\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
12092
|
),
|
|
11859
|
-
row:
|
|
11860
|
-
col:
|
|
11861
|
-
label:
|
|
12093
|
+
row: z5.number().int().nonnegative().optional().describe("\uC88C\uD45C \uBAA8\uB4DC: \uC140\uC758 rowAddr (0-based)"),
|
|
12094
|
+
col: z5.number().int().nonnegative().optional().describe("\uC88C\uD45C \uBAA8\uB4DC: \uC140\uC758 colAddr (0-based)"),
|
|
12095
|
+
label: z5.string().optional().describe(
|
|
11862
12096
|
"\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
12097
|
),
|
|
11864
|
-
direction:
|
|
11865
|
-
newText:
|
|
11866
|
-
expectedText:
|
|
12098
|
+
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."),
|
|
12099
|
+
newText: z5.string().describe("\uC140\uC5D0 \uC4F8 \uC0C8 \uD14D\uC2A4\uD2B8"),
|
|
12100
|
+
expectedText: z5.string().optional().describe(
|
|
11867
12101
|
"\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
12102
|
)
|
|
11869
12103
|
}).describe(
|
|
11870
12104
|
"\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
12105
|
);
|
|
11872
|
-
var proposeCellEditSchema =
|
|
11873
|
-
path:
|
|
11874
|
-
edits:
|
|
12106
|
+
var proposeCellEditSchema = z5.object({
|
|
12107
|
+
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)"),
|
|
12108
|
+
edits: z5.array(cellEditItemSchema).min(1).describe(
|
|
11875
12109
|
"\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
12110
|
),
|
|
11877
|
-
summary:
|
|
12111
|
+
summary: z5.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
11878
12112
|
});
|
|
11879
12113
|
function tokenizeHwpxXml(xml) {
|
|
11880
12114
|
const tokens = [];
|
|
@@ -12209,7 +12443,7 @@ var proposeCellEditTool = {
|
|
|
12209
12443
|
ctx
|
|
12210
12444
|
}) => {
|
|
12211
12445
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
12212
|
-
const ext =
|
|
12446
|
+
const ext = extname5(safePath).toLowerCase();
|
|
12213
12447
|
if (ext === ".hwp") {
|
|
12214
12448
|
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
12449
|
}
|
|
@@ -12218,7 +12452,7 @@ var proposeCellEditTool = {
|
|
|
12218
12452
|
}
|
|
12219
12453
|
let originalBuffer;
|
|
12220
12454
|
try {
|
|
12221
|
-
originalBuffer = await
|
|
12455
|
+
originalBuffer = await readFile5(safePath);
|
|
12222
12456
|
} catch {
|
|
12223
12457
|
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
12458
|
}
|
|
@@ -12547,10 +12781,10 @@ async function markdownToDocx(markdown) {
|
|
|
12547
12781
|
});
|
|
12548
12782
|
return Packer.toBuffer(doc);
|
|
12549
12783
|
}
|
|
12550
|
-
var proposeEditSchema =
|
|
12551
|
-
path:
|
|
12552
|
-
newMarkdown:
|
|
12553
|
-
summary:
|
|
12784
|
+
var proposeEditSchema = z6.object({
|
|
12785
|
+
path: z6.string().describe("\uC218\uC815\uD560 \uBB38\uC11C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)"),
|
|
12786
|
+
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"),
|
|
12787
|
+
summary: z6.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
12554
12788
|
});
|
|
12555
12789
|
var proposeEditTool = {
|
|
12556
12790
|
name: "propose_edit",
|
|
@@ -12562,10 +12796,10 @@ var proposeEditTool = {
|
|
|
12562
12796
|
ctx
|
|
12563
12797
|
}) => {
|
|
12564
12798
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
12565
|
-
const ext =
|
|
12799
|
+
const ext = extname6(safePath).toLowerCase();
|
|
12566
12800
|
let originalBuffer;
|
|
12567
12801
|
try {
|
|
12568
|
-
originalBuffer = await
|
|
12802
|
+
originalBuffer = await readFile6(safePath);
|
|
12569
12803
|
} catch {
|
|
12570
12804
|
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
12805
|
}
|
|
@@ -12636,17 +12870,48 @@ ${diff}`;
|
|
|
12636
12870
|
};
|
|
12637
12871
|
}
|
|
12638
12872
|
};
|
|
12639
|
-
var proposeFindReplaceSchema =
|
|
12640
|
-
path:
|
|
12641
|
-
find:
|
|
12642
|
-
replace:
|
|
12643
|
-
caseSensitive:
|
|
12644
|
-
all:
|
|
12645
|
-
summary:
|
|
12873
|
+
var proposeFindReplaceSchema = z7.object({
|
|
12874
|
+
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)"),
|
|
12875
|
+
find: z7.string().min(1).describe("\uCC3E\uC744 \uD14D\uC2A4\uD2B8"),
|
|
12876
|
+
replace: z7.string().describe("\uBC14\uAFC0 \uD14D\uC2A4\uD2B8"),
|
|
12877
|
+
caseSensitive: z7.boolean().optional().default(false).describe("\uB300\uC18C\uBB38\uC790 \uAD6C\uBD84 (\uAE30\uBCF8\uAC12: false)"),
|
|
12878
|
+
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"),
|
|
12879
|
+
summary: z7.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
12646
12880
|
});
|
|
12881
|
+
var MAX_DIFF_SAMPLES = 20;
|
|
12647
12882
|
function escapeXml3(text3) {
|
|
12648
12883
|
return text3.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
12649
12884
|
}
|
|
12885
|
+
function unescapeXml(text3) {
|
|
12886
|
+
return text3.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&");
|
|
12887
|
+
}
|
|
12888
|
+
function makeChangeSnippet(before, after, ctx = 24) {
|
|
12889
|
+
let p = 0;
|
|
12890
|
+
while (p < before.length && p < after.length && before[p] === after[p]) p++;
|
|
12891
|
+
const maxSuffix = Math.min(before.length - p, after.length - p);
|
|
12892
|
+
let s = 0;
|
|
12893
|
+
while (s < maxSuffix && before[before.length - 1 - s] === after[after.length - 1 - s]) s++;
|
|
12894
|
+
const slice = (str) => {
|
|
12895
|
+
const start = Math.max(0, p - ctx);
|
|
12896
|
+
const end = Math.min(str.length, str.length - s + ctx);
|
|
12897
|
+
return (start > 0 ? "\u2026" : "") + str.slice(start, end) + (end < str.length ? "\u2026" : "");
|
|
12898
|
+
};
|
|
12899
|
+
return { before: slice(before), after: slice(after) };
|
|
12900
|
+
}
|
|
12901
|
+
function collectChangedSnippets(beforeXml, afterXml, maxSamples) {
|
|
12902
|
+
const re = /<hp:t>([\s\S]*?)<\/hp:t>/g;
|
|
12903
|
+
const beforeNodes = [...beforeXml.matchAll(re)].map((m) => m[1] ?? "");
|
|
12904
|
+
const afterNodes = [...afterXml.matchAll(re)].map((m) => m[1] ?? "");
|
|
12905
|
+
const out = [];
|
|
12906
|
+
const n = Math.min(beforeNodes.length, afterNodes.length);
|
|
12907
|
+
for (let i = 0; i < n && out.length < maxSamples; i++) {
|
|
12908
|
+
if (beforeNodes[i] !== afterNodes[i]) {
|
|
12909
|
+
const snip = makeChangeSnippet(unescapeXml(beforeNodes[i]), unescapeXml(afterNodes[i]));
|
|
12910
|
+
out.push(snip);
|
|
12911
|
+
}
|
|
12912
|
+
}
|
|
12913
|
+
return out;
|
|
12914
|
+
}
|
|
12650
12915
|
function replaceInSectionXml(xml, find, replace, caseSensitive, replaceAll, alreadyReplaced) {
|
|
12651
12916
|
if (!replaceAll && alreadyReplaced > 0) {
|
|
12652
12917
|
return { xml, count: 0 };
|
|
@@ -12754,7 +13019,19 @@ async function applyFindReplaceToHwpx(hwpxBuffer, find, replace, caseSensitive,
|
|
|
12754
13019
|
}
|
|
12755
13020
|
}
|
|
12756
13021
|
if (totalCount === 0) {
|
|
12757
|
-
return { buffer: hwpxBuffer, count: 0 };
|
|
13022
|
+
return { buffer: hwpxBuffer, count: 0, samples: [] };
|
|
13023
|
+
}
|
|
13024
|
+
const samples = [];
|
|
13025
|
+
for (let si = 0; si < sectionFiles.length && samples.length < MAX_DIFF_SAMPLES; si++) {
|
|
13026
|
+
const remaining = MAX_DIFF_SAMPLES - samples.length;
|
|
13027
|
+
const snippets = collectChangedSnippets(
|
|
13028
|
+
sectionXmls[si] ?? "",
|
|
13029
|
+
newSectionXmls[si] ?? "",
|
|
13030
|
+
remaining
|
|
13031
|
+
);
|
|
13032
|
+
for (const snip of snippets) {
|
|
13033
|
+
samples.push(snip);
|
|
13034
|
+
}
|
|
12758
13035
|
}
|
|
12759
13036
|
const out = new import_jszip3.default();
|
|
12760
13037
|
const mimetypeEntry = zip.file("mimetype");
|
|
@@ -12773,7 +13050,8 @@ async function applyFindReplaceToHwpx(hwpxBuffer, find, replace, caseSensitive,
|
|
|
12773
13050
|
const buf = await out.generateAsync({ type: "nodebuffer", compression: "DEFLATE" });
|
|
12774
13051
|
return {
|
|
12775
13052
|
buffer: new Uint8Array(buf),
|
|
12776
|
-
count: totalCount
|
|
13053
|
+
count: totalCount,
|
|
13054
|
+
samples
|
|
12777
13055
|
};
|
|
12778
13056
|
}
|
|
12779
13057
|
var proposeFindReplaceTool = {
|
|
@@ -12786,7 +13064,7 @@ var proposeFindReplaceTool = {
|
|
|
12786
13064
|
ctx
|
|
12787
13065
|
}) => {
|
|
12788
13066
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
12789
|
-
const ext =
|
|
13067
|
+
const ext = extname7(safePath).toLowerCase();
|
|
12790
13068
|
if (ext === ".hwp") {
|
|
12791
13069
|
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
13070
|
}
|
|
@@ -12795,7 +13073,7 @@ var proposeFindReplaceTool = {
|
|
|
12795
13073
|
}
|
|
12796
13074
|
let originalBuf;
|
|
12797
13075
|
try {
|
|
12798
|
-
originalBuf = await
|
|
13076
|
+
originalBuf = await readFile7(safePath);
|
|
12799
13077
|
} catch {
|
|
12800
13078
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
|
|
12801
13079
|
}
|
|
@@ -12809,6 +13087,7 @@ var proposeFindReplaceTool = {
|
|
|
12809
13087
|
);
|
|
12810
13088
|
let newBytes;
|
|
12811
13089
|
let replacedCount;
|
|
13090
|
+
let diffSamples;
|
|
12812
13091
|
try {
|
|
12813
13092
|
const result = await applyFindReplaceToHwpx(
|
|
12814
13093
|
originalBytes,
|
|
@@ -12819,6 +13098,7 @@ var proposeFindReplaceTool = {
|
|
|
12819
13098
|
);
|
|
12820
13099
|
newBytes = result.buffer;
|
|
12821
13100
|
replacedCount = result.count;
|
|
13101
|
+
diffSamples = result.samples;
|
|
12822
13102
|
} catch (e) {
|
|
12823
13103
|
return `\uC624\uB958: \uCE58\uD658 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. ${String(e)}`;
|
|
12824
13104
|
}
|
|
@@ -12838,7 +13118,7 @@ var proposeFindReplaceTool = {
|
|
|
12838
13118
|
const remaining = countOccurrences(normAfter, normFind);
|
|
12839
13119
|
if (remaining > 0) {
|
|
12840
13120
|
warnings.push(
|
|
12841
|
-
`\uC77C\uBD80 "${input.find}"(${remaining}\uACF3)\uC774 \uAD50\uCCB4\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uD14D\uC2A4\uD2B8\uAC00 \uC5EC\uB7EC \uC11C\uC2DD \uB7F0\uC5D0 \uB098\uB258\uC5B4 \uC788\uC5B4 \uACBD\uACC4\uB97C \uAC00\uB85C\uC9C0\uB974\uB294 \uD328\uD134\uC740 \uAD50\uCCB4\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(\uC11C\uC2DD\uC774 \uB098\uB25C \uD14D\uC2A4\uD2B8). \uC774\uBBF8 \uAD50\uCCB4\uB41C ${replacedCount}\uACF3\uC740 \uC815\uC0C1 \uBC18\uC601\uB418\uC5C8\uC2B5\uB2C8\uB2E4.`
|
|
13121
|
+
`\uC77C\uBD80 "${input.find}"(${remaining}\uACF3)\uC774 \uAD50\uCCB4\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uD14D\uC2A4\uD2B8\uAC00 \uC5EC\uB7EC \uC11C\uC2DD \uB7F0\uC5D0 \uB098\uB258\uC5B4 \uC788\uC5B4 \uACBD\uACC4\uB97C \uAC00\uB85C\uC9C0\uB974\uB294 \uD328\uD134\uC740 \uAD50\uCCB4\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(\uC11C\uC2DD\uC774 \uB098\uB25C \uD14D\uC2A4\uD2B8). \uC774\uBBF8 \uAD50\uCCB4\uB41C ${replacedCount}\uACF3\uC740 \uC815\uC0C1 \uBC18\uC601\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uB0A8\uC740 ${remaining}\uACF3\uC740 \uD45C \uC548\uC758 \uC140\uC774\uBA74 propose_cell_edit\uC73C\uB85C \uD55C \uACF3\uC529 \uC218\uC815\uD558\uAC70\uB098, \uD55C\uAE00 \uD504\uB85C\uADF8\uB7A8\uC5D0\uC11C \uC9C1\uC811 \uCC3E\uAE30\xB7\uBC14\uAFB8\uAE30\uB85C \uCC98\uB9AC\uD558\uC138\uC694.`
|
|
12842
13122
|
);
|
|
12843
13123
|
}
|
|
12844
13124
|
}
|
|
@@ -12847,7 +13127,23 @@ var proposeFindReplaceTool = {
|
|
|
12847
13127
|
}
|
|
12848
13128
|
const { outputPath, willConvertFormat } = resolveOutputPath(safePath);
|
|
12849
13129
|
const allLabel = input.all ?? true ? `${replacedCount}\uACF3` : "\uCCAB \uBC88\uC9F8 1\uACF3";
|
|
12850
|
-
|
|
13130
|
+
let diff;
|
|
13131
|
+
if (diffSamples.length === 0) {
|
|
13132
|
+
diff = `\uCC3E\uAE30: "${input.find}" \u2192 \uBC14\uAFB8\uAE30: "${input.replace}" (${allLabel} \uAD50\uCCB4\uB428)`;
|
|
13133
|
+
} else {
|
|
13134
|
+
const lines = [`${replacedCount}\uACF3 \uAD50\uCCB4: "${input.find}" \u2192 "${input.replace}"`];
|
|
13135
|
+
for (let i = 0; i < diffSamples.length; i++) {
|
|
13136
|
+
const sample = diffSamples[i];
|
|
13137
|
+
lines.push(` ${i + 1}. - ${sample.before}`);
|
|
13138
|
+
lines.push(` + ${sample.after}`);
|
|
13139
|
+
}
|
|
13140
|
+
if (replacedCount > diffSamples.length) {
|
|
13141
|
+
lines.push(
|
|
13142
|
+
` \u2026 \uC678 ${replacedCount - diffSamples.length}\uACF3 (\uBBF8\uB9AC\uBCF4\uAE30\uB294 \uCD5C\uB300 ${MAX_DIFF_SAMPLES}\uACF3)`
|
|
13143
|
+
);
|
|
13144
|
+
}
|
|
13145
|
+
diff = lines.join("\n");
|
|
13146
|
+
}
|
|
12851
13147
|
const stagedPath = await stageFile(ctx.sessionId, outputPath, newBytes);
|
|
12852
13148
|
const proposalId = crypto.randomUUID();
|
|
12853
13149
|
return {
|
|
@@ -12870,10 +13166,10 @@ var proposeFindReplaceTool = {
|
|
|
12870
13166
|
};
|
|
12871
13167
|
}
|
|
12872
13168
|
};
|
|
12873
|
-
var proposeFormFillSchema =
|
|
12874
|
-
path:
|
|
12875
|
-
fields:
|
|
12876
|
-
summary:
|
|
13169
|
+
var proposeFormFillSchema = z8.object({
|
|
13170
|
+
path: z8.string().describe("\uC591\uC2DD \uBB38\uC11C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)"),
|
|
13171
|
+
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"),
|
|
13172
|
+
summary: z8.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
12877
13173
|
});
|
|
12878
13174
|
var proposeFormFillTool = {
|
|
12879
13175
|
name: "propose_form_fill",
|
|
@@ -12885,13 +13181,13 @@ var proposeFormFillTool = {
|
|
|
12885
13181
|
ctx
|
|
12886
13182
|
}) => {
|
|
12887
13183
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
12888
|
-
const ext =
|
|
13184
|
+
const ext = extname8(safePath).toLowerCase();
|
|
12889
13185
|
if (ext !== ".hwpx" && ext !== ".hwp") {
|
|
12890
13186
|
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
13187
|
}
|
|
12892
13188
|
let originalBuffer;
|
|
12893
13189
|
try {
|
|
12894
|
-
originalBuffer = await
|
|
13190
|
+
originalBuffer = await readFile8(safePath);
|
|
12895
13191
|
} catch {
|
|
12896
13192
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
|
|
12897
13193
|
}
|
|
@@ -12959,16 +13255,16 @@ var proposeFormFillTool = {
|
|
|
12959
13255
|
};
|
|
12960
13256
|
}
|
|
12961
13257
|
};
|
|
12962
|
-
var proposeSheetEditSchema =
|
|
12963
|
-
path:
|
|
12964
|
-
updates:
|
|
12965
|
-
|
|
12966
|
-
sheet:
|
|
12967
|
-
cell:
|
|
12968
|
-
value:
|
|
13258
|
+
var proposeSheetEditSchema = z9.object({
|
|
13259
|
+
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)"),
|
|
13260
|
+
updates: z9.array(
|
|
13261
|
+
z9.object({
|
|
13262
|
+
sheet: z9.string().describe("\uC2DC\uD2B8 \uC774\uB984"),
|
|
13263
|
+
cell: z9.string().describe("\uC140 \uC8FC\uC18C (\uC608: A1, B3)"),
|
|
13264
|
+
value: z9.union([z9.string(), z9.number()]).describe("\uC0C8 \uAC12")
|
|
12969
13265
|
})
|
|
12970
13266
|
).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:
|
|
13267
|
+
summary: z9.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
12972
13268
|
});
|
|
12973
13269
|
var proposeSheetEditTool = {
|
|
12974
13270
|
name: "propose_sheet_edit",
|
|
@@ -12980,13 +13276,13 @@ var proposeSheetEditTool = {
|
|
|
12980
13276
|
ctx
|
|
12981
13277
|
}) => {
|
|
12982
13278
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
12983
|
-
const ext =
|
|
13279
|
+
const ext = extname9(safePath).toLowerCase();
|
|
12984
13280
|
if (ext !== ".xlsx" && ext !== ".xls") {
|
|
12985
13281
|
return `\uC624\uB958: propose_sheet_edit\uC740 .xlsx/.xls \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. \uD604\uC7AC \uD30C\uC77C: ${ext}.`;
|
|
12986
13282
|
}
|
|
12987
13283
|
let originalBuffer;
|
|
12988
13284
|
try {
|
|
12989
|
-
originalBuffer = await
|
|
13285
|
+
originalBuffer = await readFile9(safePath);
|
|
12990
13286
|
} catch {
|
|
12991
13287
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
|
|
12992
13288
|
}
|
|
@@ -13025,23 +13321,25 @@ var proposeSheetEditTool = {
|
|
|
13025
13321
|
return `\uC624\uB958: \uC6CC\uD06C\uBD81 \uC800\uC7A5 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4: ${msg}`;
|
|
13026
13322
|
}
|
|
13027
13323
|
const stagedData = modifiedBuffer;
|
|
13028
|
-
const
|
|
13324
|
+
const { outputPath, willConvertFormat } = resolveOutputPath(safePath);
|
|
13325
|
+
const stagedPath = await stageFile(ctx.sessionId, outputPath, stagedData);
|
|
13029
13326
|
const proposalId = crypto.randomUUID();
|
|
13030
13327
|
return {
|
|
13031
13328
|
proposal: {
|
|
13032
13329
|
id: proposalId,
|
|
13033
13330
|
kind: "sheet-edit",
|
|
13034
|
-
targetPath:
|
|
13331
|
+
targetPath: outputPath,
|
|
13035
13332
|
stagedPath,
|
|
13036
13333
|
summary: input.summary,
|
|
13037
13334
|
diff,
|
|
13038
|
-
warnings: []
|
|
13335
|
+
warnings: [],
|
|
13336
|
+
willConvertFormat
|
|
13039
13337
|
},
|
|
13040
13338
|
commit: async () => {
|
|
13041
|
-
const backupPath = await backupFile(
|
|
13042
|
-
await commitStaged(stagedPath,
|
|
13339
|
+
const backupPath = await backupFile(outputPath);
|
|
13340
|
+
await commitStaged(stagedPath, outputPath);
|
|
13043
13341
|
const backupInfo = backupPath ? ` (\uBC31\uC5C5: ${backupPath})` : "";
|
|
13044
|
-
return `\uC800\uC7A5 \uC644\uB8CC: ${
|
|
13342
|
+
return `\uC800\uC7A5 \uC644\uB8CC: ${outputPath}${backupInfo}`;
|
|
13045
13343
|
}
|
|
13046
13344
|
};
|
|
13047
13345
|
}
|
|
@@ -13077,47 +13375,47 @@ function detectStructuralLoss(beforeBlocks, afterBlocks) {
|
|
|
13077
13375
|
}
|
|
13078
13376
|
return { lost: false, detail: "" };
|
|
13079
13377
|
}
|
|
13080
|
-
var insertRowOpSchema =
|
|
13081
|
-
type:
|
|
13082
|
-
row:
|
|
13083
|
-
position:
|
|
13378
|
+
var insertRowOpSchema = z10.object({
|
|
13379
|
+
type: z10.literal("insertRow"),
|
|
13380
|
+
row: z10.number().int().nonnegative().describe("\uAE30\uC900 \uD589 \uC778\uB371\uC2A4 (0-based)"),
|
|
13381
|
+
position: z10.enum(["above", "below"]).describe("\uC0BD\uC785 \uC704\uCE58: above=row \uC704\uC5D0, below=row \uC544\uB798\uC5D0")
|
|
13084
13382
|
});
|
|
13085
|
-
var deleteRowOpSchema =
|
|
13086
|
-
type:
|
|
13087
|
-
row:
|
|
13383
|
+
var deleteRowOpSchema = z10.object({
|
|
13384
|
+
type: z10.literal("deleteRow"),
|
|
13385
|
+
row: z10.number().int().nonnegative().describe("\uC0AD\uC81C\uD560 \uD589 \uC778\uB371\uC2A4 (0-based)")
|
|
13088
13386
|
});
|
|
13089
|
-
var insertColumnOpSchema =
|
|
13090
|
-
type:
|
|
13091
|
-
col:
|
|
13092
|
-
position:
|
|
13387
|
+
var insertColumnOpSchema = z10.object({
|
|
13388
|
+
type: z10.literal("insertColumn"),
|
|
13389
|
+
col: z10.number().int().nonnegative().describe("\uAE30\uC900 \uC5F4 \uC778\uB371\uC2A4 (0-based)"),
|
|
13390
|
+
position: z10.enum(["left", "right"]).describe("\uC0BD\uC785 \uC704\uCE58: left=col \uC67C\uCABD\uC5D0, right=col \uC624\uB978\uCABD\uC5D0")
|
|
13093
13391
|
});
|
|
13094
|
-
var deleteColumnOpSchema =
|
|
13095
|
-
type:
|
|
13096
|
-
col:
|
|
13392
|
+
var deleteColumnOpSchema = z10.object({
|
|
13393
|
+
type: z10.literal("deleteColumn"),
|
|
13394
|
+
col: z10.number().int().nonnegative().describe("\uC0AD\uC81C\uD560 \uC5F4 \uC778\uB371\uC2A4 (0-based)")
|
|
13097
13395
|
});
|
|
13098
|
-
var mergeCellsOpSchema =
|
|
13099
|
-
type:
|
|
13100
|
-
startRow:
|
|
13101
|
-
startCol:
|
|
13102
|
-
endRow:
|
|
13103
|
-
endCol:
|
|
13396
|
+
var mergeCellsOpSchema = z10.object({
|
|
13397
|
+
type: z10.literal("mergeCells"),
|
|
13398
|
+
startRow: z10.number().int().nonnegative().describe("\uBCD1\uD569 \uC2DC\uC791 \uD589 (0-based)"),
|
|
13399
|
+
startCol: z10.number().int().nonnegative().describe("\uBCD1\uD569 \uC2DC\uC791 \uC5F4 (0-based)"),
|
|
13400
|
+
endRow: z10.number().int().nonnegative().describe("\uBCD1\uD569 \uB05D \uD589 (0-based, \uD3EC\uD568)"),
|
|
13401
|
+
endCol: z10.number().int().nonnegative().describe("\uBCD1\uD569 \uB05D \uC5F4 (0-based, \uD3EC\uD568)")
|
|
13104
13402
|
});
|
|
13105
|
-
var operationSchema =
|
|
13403
|
+
var operationSchema = z10.discriminatedUnion("type", [
|
|
13106
13404
|
insertRowOpSchema,
|
|
13107
13405
|
deleteRowOpSchema,
|
|
13108
13406
|
insertColumnOpSchema,
|
|
13109
13407
|
deleteColumnOpSchema,
|
|
13110
13408
|
mergeCellsOpSchema
|
|
13111
13409
|
]).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:
|
|
13410
|
+
var proposeTableStructureSchema = z10.object({
|
|
13411
|
+
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)"),
|
|
13412
|
+
anchor: z10.string().min(1).describe(
|
|
13115
13413
|
"\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
13414
|
),
|
|
13117
|
-
operations:
|
|
13415
|
+
operations: z10.array(operationSchema).min(1).describe(
|
|
13118
13416
|
"\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
13417
|
),
|
|
13120
|
-
summary:
|
|
13418
|
+
summary: z10.string().describe("\uBCC0\uACBD \uC694\uC57D (\uD55C\uAD6D\uC5B4 1-2\uBB38\uC7A5)")
|
|
13121
13419
|
});
|
|
13122
13420
|
function tokenizeHwpxXml2(xml) {
|
|
13123
13421
|
const tokens = [];
|
|
@@ -13792,7 +14090,7 @@ var proposeTableStructureTool = {
|
|
|
13792
14090
|
ctx
|
|
13793
14091
|
}) => {
|
|
13794
14092
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
13795
|
-
const ext =
|
|
14093
|
+
const ext = extname10(safePath).toLowerCase();
|
|
13796
14094
|
if (ext === ".hwp") {
|
|
13797
14095
|
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
14096
|
}
|
|
@@ -13801,7 +14099,7 @@ var proposeTableStructureTool = {
|
|
|
13801
14099
|
}
|
|
13802
14100
|
let originalBuf;
|
|
13803
14101
|
try {
|
|
13804
|
-
originalBuf = await
|
|
14102
|
+
originalBuf = await readFile10(safePath);
|
|
13805
14103
|
} catch {
|
|
13806
14104
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}. \uACBD\uB85C\uB97C \uD655\uC778\uD558\uC138\uC694.`;
|
|
13807
14105
|
}
|
|
@@ -13997,11 +14295,11 @@ function searchExcerpts(markdown, query) {
|
|
|
13997
14295
|
}
|
|
13998
14296
|
return result;
|
|
13999
14297
|
}
|
|
14000
|
-
var readDocumentSchema =
|
|
14001
|
-
path:
|
|
14002
|
-
pages:
|
|
14003
|
-
outline:
|
|
14004
|
-
search:
|
|
14298
|
+
var readDocumentSchema = z11.object({
|
|
14299
|
+
path: z11.string().describe("\uC77D\uC744 \uBB38\uC11C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)"),
|
|
14300
|
+
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'),
|
|
14301
|
+
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)"),
|
|
14302
|
+
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
14303
|
});
|
|
14006
14304
|
function applyReadMode(body, outline, search) {
|
|
14007
14305
|
if (outline === true) {
|
|
@@ -14023,18 +14321,18 @@ var readDocumentTool = {
|
|
|
14023
14321
|
}) => {
|
|
14024
14322
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
14025
14323
|
try {
|
|
14026
|
-
const fileStat = await
|
|
14324
|
+
const fileStat = await stat4(safePath);
|
|
14027
14325
|
const guardMsg = fileSizeGuardMessage(fileStat.size, MAX_FILE_SIZE_BYTES);
|
|
14028
14326
|
if (guardMsg !== null) return guardMsg;
|
|
14029
14327
|
} catch (e) {
|
|
14030
14328
|
const msg = e instanceof Error ? e.message : String(e);
|
|
14031
14329
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${msg}`;
|
|
14032
14330
|
}
|
|
14033
|
-
const ext =
|
|
14331
|
+
const ext = extname11(safePath).toLowerCase();
|
|
14034
14332
|
if (PLAIN_TEXT_EXTS.has(ext)) {
|
|
14035
14333
|
let raw;
|
|
14036
14334
|
try {
|
|
14037
|
-
raw = await
|
|
14335
|
+
raw = await readFile11(safePath, "utf-8");
|
|
14038
14336
|
} catch (e) {
|
|
14039
14337
|
const msg = e instanceof Error ? e.message : String(e);
|
|
14040
14338
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${msg}`;
|
|
@@ -14134,8 +14432,8 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
14134
14432
|
".csv",
|
|
14135
14433
|
".log"
|
|
14136
14434
|
]);
|
|
14137
|
-
var readFileSchema =
|
|
14138
|
-
path:
|
|
14435
|
+
var readFileSchema = z12.object({
|
|
14436
|
+
path: z12.string().describe("\uC77D\uC744 \uD30C\uC77C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)")
|
|
14139
14437
|
});
|
|
14140
14438
|
var readFileTool = {
|
|
14141
14439
|
name: "read_file",
|
|
@@ -14149,7 +14447,7 @@ var readFileTool = {
|
|
|
14149
14447
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
14150
14448
|
let info;
|
|
14151
14449
|
try {
|
|
14152
|
-
info = await
|
|
14450
|
+
info = await stat5(safePath);
|
|
14153
14451
|
} catch {
|
|
14154
14452
|
return `\uC624\uB958: \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input.path}`;
|
|
14155
14453
|
}
|
|
@@ -14159,8 +14457,8 @@ var readFileTool = {
|
|
|
14159
14457
|
if (info.size > MAX_SIZE) {
|
|
14160
14458
|
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
14459
|
}
|
|
14162
|
-
const { extname:
|
|
14163
|
-
const ext =
|
|
14460
|
+
const { extname: extname14 } = await import("path");
|
|
14461
|
+
const ext = extname14(safePath).toLowerCase();
|
|
14164
14462
|
if (!TEXT_EXTENSIONS.has(ext) && ext !== "") {
|
|
14165
14463
|
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
14464
|
}
|
|
@@ -14175,9 +14473,9 @@ var readFileTool = {
|
|
|
14175
14473
|
}
|
|
14176
14474
|
};
|
|
14177
14475
|
var MAX_PREVIEW_CHARS = 1e4;
|
|
14178
|
-
var writeNewDocumentSchema =
|
|
14179
|
-
path:
|
|
14180
|
-
markdown:
|
|
14476
|
+
var writeNewDocumentSchema = z13.object({
|
|
14477
|
+
path: z13.string().describe("\uC0DD\uC131\uD560 \uBB38\uC11C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)"),
|
|
14478
|
+
markdown: z13.string().describe("\uC0C8 \uBB38\uC11C \uB0B4\uC6A9 (\uB9C8\uD06C\uB2E4\uC6B4 \uD615\uC2DD)")
|
|
14181
14479
|
});
|
|
14182
14480
|
var writeNewDocumentTool = {
|
|
14183
14481
|
name: "write_new_document",
|
|
@@ -14189,9 +14487,9 @@ var writeNewDocumentTool = {
|
|
|
14189
14487
|
ctx
|
|
14190
14488
|
}) => {
|
|
14191
14489
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
14192
|
-
const ext =
|
|
14490
|
+
const ext = extname12(safePath).toLowerCase();
|
|
14193
14491
|
try {
|
|
14194
|
-
await
|
|
14492
|
+
await stat6(safePath);
|
|
14195
14493
|
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
14494
|
} catch {
|
|
14197
14495
|
}
|
|
@@ -14239,12 +14537,12 @@ ${preview}`,
|
|
|
14239
14537
|
};
|
|
14240
14538
|
}
|
|
14241
14539
|
};
|
|
14242
|
-
var writeNewSpreadsheetSchema =
|
|
14243
|
-
path:
|
|
14244
|
-
sheets:
|
|
14245
|
-
|
|
14246
|
-
name:
|
|
14247
|
-
rows:
|
|
14540
|
+
var writeNewSpreadsheetSchema = z14.object({
|
|
14541
|
+
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)"),
|
|
14542
|
+
sheets: z14.array(
|
|
14543
|
+
z14.object({
|
|
14544
|
+
name: z14.string().describe("\uC2DC\uD2B8 \uC774\uB984"),
|
|
14545
|
+
rows: z14.array(z14.array(z14.string())).describe("\uD589 \uB370\uC774\uD130 \uBC30\uC5F4 (\uAC01 \uD589\uC740 \uC140 \uAC12 \uBC30\uC5F4)")
|
|
14248
14546
|
})
|
|
14249
14547
|
).min(1).describe("\uC0DD\uC131\uD560 \uC2DC\uD2B8 \uBAA9\uB85D")
|
|
14250
14548
|
});
|
|
@@ -14258,12 +14556,12 @@ var writeNewSpreadsheetTool = {
|
|
|
14258
14556
|
ctx
|
|
14259
14557
|
}) => {
|
|
14260
14558
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
14261
|
-
const ext =
|
|
14559
|
+
const ext = extname13(safePath).toLowerCase();
|
|
14262
14560
|
if (ext !== ".xlsx") {
|
|
14263
14561
|
return `\uC624\uB958: write_new_spreadsheet\uC740 .xlsx \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. \uD604\uC7AC \uD655\uC7A5\uC790: ${ext}.`;
|
|
14264
14562
|
}
|
|
14265
14563
|
try {
|
|
14266
|
-
await
|
|
14564
|
+
await stat7(safePath);
|
|
14267
14565
|
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
14566
|
} catch {
|
|
14269
14567
|
}
|
|
@@ -14316,6 +14614,7 @@ function createDocTools(_ctx) {
|
|
|
14316
14614
|
readDocumentTool,
|
|
14317
14615
|
compareDocumentsTool,
|
|
14318
14616
|
listFilesTool,
|
|
14617
|
+
listBackupsTool,
|
|
14319
14618
|
readFileTool,
|
|
14320
14619
|
proposeEditTool,
|
|
14321
14620
|
proposeFormFillTool,
|
|
@@ -14326,7 +14625,8 @@ function createDocTools(_ctx) {
|
|
|
14326
14625
|
listFormObjectsTool,
|
|
14327
14626
|
proposeFormObjectTool,
|
|
14328
14627
|
writeNewDocumentTool,
|
|
14329
|
-
writeNewSpreadsheetTool
|
|
14628
|
+
writeNewSpreadsheetTool,
|
|
14629
|
+
restoreBackupTool
|
|
14330
14630
|
];
|
|
14331
14631
|
}
|
|
14332
14632
|
|
|
@@ -14415,6 +14715,14 @@ function createCliApprovalHandler() {
|
|
|
14415
14715
|
|
|
14416
14716
|
// src/chat.ts
|
|
14417
14717
|
var HELP_TEXT = `
|
|
14718
|
+
\uD560 \uC218 \uC788\uB294 \uC77C:
|
|
14719
|
+
\u2022 \uBB38\uC11C \uC77D\uAE30\xB7\uC694\uC57D\xB7\uAC80\uD1A0 \u2014 .hwp/.hwpx/.docx/.xlsx/.pdf (\uC608: "\uC774 \uBCF4\uB3C4\uC790\uB8CC \uC694\uC57D\uD574\uC918")
|
|
14720
|
+
\u2022 \uD45C\xB7\uC591\uC2DD \uC218\uC815 \u2014 \uC140 \uAC12, \uC591\uC2DD \uBE48\uCE78, \uD589\xB7\uC5F4 \uCD94\uAC00/\uC0AD\uC81C (\uC608: "\uC774 \uD45C\uC758 \uAE08\uC561\uC744 30000\uC73C\uB85C \uACE0\uCCD0\uC918")
|
|
14721
|
+
\u2022 \uBB38\uC11C \uC804\uCCB4 \uCC3E\uAE30\xB7\uBC14\uAFB8\uAE30 (\uC608: "'\uAD6D\uBBFC\uC8FC\uAD8C'\uC744 '\uAD6D\uBBFC\uC911\uC2EC'\uC73C\uB85C \uB2E4 \uBC14\uAFD4\uC918")
|
|
14722
|
+
\u2022 \uB418\uB3CC\uB9AC\uAE30 \u2014 \uC9C1\uC804 \uBCC0\uACBD\uC744 \uBC31\uC5C5\uC73C\uB85C \uBCF5\uC6D0 (\uC608: "\uBC29\uAE08 \uC218\uC815 \uB418\uB3CC\uB824\uC918")
|
|
14723
|
+
\u2022 \uD55C\uAD6D \uBC95\uB839 \uAE30\uBC18 \uAC80\uD1A0 (\uC608: "\uC774 \uCDE8\uC5C5\uADDC\uCE59\uC774 \uADFC\uB85C\uAE30\uC900\uBC95\uC5D0 \uB9DE\uB294\uC9C0 \uBD10\uC918")
|
|
14724
|
+
\u203B .hwp\uB294 \uD55C\uAE00\uC5D0\uC11C .hwpx\uB85C \uC800\uC7A5\uD55C \uD6C4 \uC218\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.
|
|
14725
|
+
|
|
14418
14726
|
\uC2AC\uB798\uC2DC \uBA85\uB839:
|
|
14419
14727
|
/model \u2014 \uD504\uB85C\uBC14\uC774\uB354/\uBAA8\uB378 \uC804\uD658
|
|
14420
14728
|
/context \u2014 \uD604\uC7AC \uCEE8\uD14D\uC2A4\uD2B8 \uC0AC\uC6A9\uB7C9 \uD45C\uC2DC
|
|
@@ -14537,6 +14845,11 @@ async function runChat(opts) {
|
|
|
14537
14845
|
|
|
14538
14846
|
`)
|
|
14539
14847
|
);
|
|
14848
|
+
process.stdout.write(
|
|
14849
|
+
chalk2.dim(
|
|
14850
|
+
'\uBB38\uC11C\uB97C \uC77D\uACE0 \uD45C\xB7\uC591\uC2DD \uC218\uC815, \uCC3E\uAE30\xB7\uBC14\uAFB8\uAE30, \uB418\uB3CC\uB9AC\uAE30\uAE4C\uC9C0 \uC790\uC5F0\uC5B4\uB85C \uC694\uCCAD\uD558\uC138\uC694. \uC608: "\uC774 \uD45C\uC758 \uD569\uACC4\uB97C \uB2E4\uC2DC \uACC4\uC0B0\uD574\uC918", "\uBC29\uAE08 \uC218\uC815 \uB418\uB3CC\uB824\uC918". \uC790\uC138\uD788: /help\n'
|
|
14851
|
+
)
|
|
14852
|
+
);
|
|
14540
14853
|
while (true) {
|
|
14541
14854
|
let clearActiveSpinner2 = function() {
|
|
14542
14855
|
if (!sharedActiveInterval) return;
|
|
@@ -15130,7 +15443,7 @@ async function runOnboarding() {
|
|
|
15130
15443
|
|
|
15131
15444
|
// src/update.ts
|
|
15132
15445
|
import { spawn } from "child_process";
|
|
15133
|
-
import { mkdir as mkdir4, readFile as
|
|
15446
|
+
import { mkdir as mkdir4, readFile as readFile12, writeFile as writeFile3 } from "fs/promises";
|
|
15134
15447
|
import { dirname as dirname3 } from "path";
|
|
15135
15448
|
function compareSemver(a, b) {
|
|
15136
15449
|
const parse6 = (v) => {
|
|
@@ -15151,7 +15464,7 @@ function compareSemver(a, b) {
|
|
|
15151
15464
|
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
15152
15465
|
async function readCache(cachePath) {
|
|
15153
15466
|
try {
|
|
15154
|
-
const raw = await
|
|
15467
|
+
const raw = await readFile12(cachePath, "utf-8");
|
|
15155
15468
|
const parsed = JSON.parse(raw);
|
|
15156
15469
|
if (parsed !== null && typeof parsed === "object" && "checkedAt" in parsed && "latest" in parsed && typeof parsed.checkedAt === "string" && typeof parsed.latest === "string") {
|
|
15157
15470
|
return parsed;
|
|
@@ -15434,7 +15747,9 @@ async function runSingleTurn(prompt) {
|
|
|
15434
15747
|
});
|
|
15435
15748
|
const tools = new ToolRegistry();
|
|
15436
15749
|
for (const tool2 of createDocTools({ cwd })) {
|
|
15437
|
-
|
|
15750
|
+
const t = tool2;
|
|
15751
|
+
if (t.requiresApproval) continue;
|
|
15752
|
+
tools.register(t);
|
|
15438
15753
|
}
|
|
15439
15754
|
for (const mcpTool of mcpManager.getToolDefinitions()) {
|
|
15440
15755
|
tools.register(mcpTool);
|