@kodocagent/cli 0.4.4 → 0.4.5
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 +194 -35
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9851,6 +9851,49 @@ var KODOC_PATHS = {
|
|
|
9851
9851
|
function projectMcpConfigPath(cwd) {
|
|
9852
9852
|
return join(cwd, ".kodocagent", "mcp.json");
|
|
9853
9853
|
}
|
|
9854
|
+
var PATTERNS = [
|
|
9855
|
+
{
|
|
9856
|
+
type: "\uC8FC\uBBFC\uB4F1\uB85D\uBC88\uD638",
|
|
9857
|
+
re: /\b\d{6}-[1-4]\d{6}\b/g,
|
|
9858
|
+
mask: (m) => `${m.slice(0, 8)}******`
|
|
9859
|
+
},
|
|
9860
|
+
{
|
|
9861
|
+
type: "\uC2E0\uC6A9\uCE74\uB4DC\uBC88\uD638",
|
|
9862
|
+
re: /\b\d{4}-\d{4}-\d{4}-\d{4}\b/g,
|
|
9863
|
+
mask: (m) => `${m.slice(0, 4)}-****-****-${m.slice(-4)}`
|
|
9864
|
+
},
|
|
9865
|
+
{
|
|
9866
|
+
type: "\uC804\uD654\uBC88\uD638",
|
|
9867
|
+
re: /\b0\d{1,2}-\d{3,4}-\d{4}\b/g,
|
|
9868
|
+
mask: (m) => {
|
|
9869
|
+
const p = m.split("-");
|
|
9870
|
+
return `${p[0]}-${"*".repeat((p[1] ?? "").length)}-${p[2]}`;
|
|
9871
|
+
}
|
|
9872
|
+
},
|
|
9873
|
+
{
|
|
9874
|
+
type: "\uC774\uBA54\uC77C",
|
|
9875
|
+
re: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
|
|
9876
|
+
mask: (m) => {
|
|
9877
|
+
const [u, d] = m.split("@");
|
|
9878
|
+
return `${u?.[0] ?? ""}***@${d}`;
|
|
9879
|
+
}
|
|
9880
|
+
}
|
|
9881
|
+
];
|
|
9882
|
+
function detectPii(text3) {
|
|
9883
|
+
if (!text3) return [];
|
|
9884
|
+
const out = [];
|
|
9885
|
+
for (const { type, re, mask } of PATTERNS) {
|
|
9886
|
+
const matches = text3.match(re);
|
|
9887
|
+
if (matches && matches.length > 0) {
|
|
9888
|
+
const uniq = [...new Set(matches)];
|
|
9889
|
+
out.push({ type, count: matches.length, masked: uniq.slice(0, 5).map(mask) });
|
|
9890
|
+
}
|
|
9891
|
+
}
|
|
9892
|
+
return out;
|
|
9893
|
+
}
|
|
9894
|
+
function summarizePii(findings) {
|
|
9895
|
+
return findings.map((f) => `${f.type} ${f.count}\uAC74`).join(", ");
|
|
9896
|
+
}
|
|
9854
9897
|
|
|
9855
9898
|
// ../core/dist/index.js
|
|
9856
9899
|
import { stepCountIs, streamText } from "ai";
|
|
@@ -9869,7 +9912,12 @@ import { appendFile, mkdir as mkdir2, readdir, readFile as readFile2, stat } fro
|
|
|
9869
9912
|
import { join as join2 } from "path";
|
|
9870
9913
|
import { tool } from "ai";
|
|
9871
9914
|
function buildSystemPrompt(ctx) {
|
|
9872
|
-
const stable = [
|
|
9915
|
+
const stable = [
|
|
9916
|
+
ROLE_SECTION,
|
|
9917
|
+
DOCUMENT_RULES_SECTION,
|
|
9918
|
+
EDIT_SAFETY_SECTION,
|
|
9919
|
+
LAW_RULES_SECTION
|
|
9920
|
+
].join("\n\n");
|
|
9873
9921
|
const dynamic = buildDynamicContext(ctx);
|
|
9874
9922
|
return `${stable}
|
|
9875
9923
|
|
|
@@ -9892,6 +9940,15 @@ var DOCUMENT_RULES_SECTION = `## \uBB38\uC11C \uADDC\uCE59
|
|
|
9892
9940
|
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
9941
|
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
9942
|
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.`;
|
|
9943
|
+
var EDIT_SAFETY_SECTION = `## \uD3B8\uC9D1 \uC548\uC804 \uADDC\uCE59
|
|
9944
|
+
|
|
9945
|
+
1. \uC694\uCCAD\uBC1B\uC740 \uBD80\uBD84\uB9CC \uC218\uC815\uD558\uACE0, \uC694\uCCAD\uD558\uC9C0 \uC54A\uC740 \uBB38\uC7A5\xB7\uC11C\uC2DD\xB7\uAD6C\uC870\xB7\uD45C\uD604\uC740 \uADF8\uB300\uB85C \uB461\uB2C8\uB2E4. \uBB38\uC11C \uC804\uCCB4\uB97C \uC784\uC758\uB85C \uC7AC\uC791\uC131\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
|
9946
|
+
2. \uBB38\uC11C\uC5D0 \uC5C6\uB294 \uC815\uBCF4\uB97C \uB9CC\uB4E4\uC5B4\uB0B4\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC218\uCE58\xB7\uAE08\uC561\xB7\uB0A0\uC9DC\xB7\uC778\uBA85\xB7\uAE30\uAD00\uBA85\xB7\uACC4\uC57D \uC870\uD56D \uB4F1\uC744 \uCD94\uCE21\uD574 \uC0C8\uB85C \uC4F0\uAC70\uB098 \uBC14\uAFB8\uC9C0 \uC54A\uC73C\uBA70, \uBD88\uD655\uC2E4\uD558\uBA74 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uD655\uC778\uD569\uB2C8\uB2E4.
|
|
9947
|
+
3. \uC0AC\uC6A9\uC790\uAC00 \uBA85\uC2DC\uC801\uC73C\uB85C \uBC14\uAFB8\uB77C\uACE0 \uD558\uC9C0 \uC54A\uC740 \uD55C \uC22B\uC790\xB7\uAE08\uC561\xB7\uB0A0\uC9DC\xB7\uB2E8\uC704\xB7\uACE0\uC720\uBA85\uC0AC\xB7\uBC95\uB839 \uC870\uBB38 \uBC88\uD638\uC640 \uC778\uC6A9\uBD80\uD638(" ", ' ', \u300C \u300D) \uB0B4\uBD80 \uB0B4\uC6A9\uC740 \uBCF4\uC874\uD569\uB2C8\uB2E4.
|
|
9948
|
+
4. \uC804\uBB38 \uC6A9\uC5B4\uB294 \uC784\uC758\uB85C \uB2E4\uB978 \uD45C\uD604\uC73C\uB85C \uBC14\uAFB8\uC9C0 \uC54A\uACE0 \uBB38\uC11C \uC804\uCCB4\uC5D0\uC11C \uC77C\uAD00\uB418\uAC8C \uC720\uC9C0\uD569\uB2C8\uB2E4.
|
|
9949
|
+
5. \uACC4\uC57D\uC11C\xB7\uC57D\uAD00\xB7\uACF5\uC2DC\xB7\uB17C\uBB38 \uB4F1 \uBC95\uC801\xB7\uACF5\uC2DD \uBB38\uC11C\uB294 \uB2E8\uC5B4 \uD558\uB098\uAC00 \uC758\uBBF8\uB97C \uBC14\uAFC0 \uC218 \uC788\uC73C\uBBC0\uB85C, \uD45C\uD604\uC744 \uC790\uB3D9\uC73C\uB85C \uB2E4\uB4EC\uC9C0 \uB9D0\uACE0 \uC0AC\uC6A9\uC790\uAC00 \uC9C0\uC815\uD55C \uBCC0\uACBD\uB9CC \uC218\uD589\uD569\uB2C8\uB2E4.
|
|
9950
|
+
6. \uC758\uBBF8\uAC00 \uBC14\uB014 \uC218 \uC788\uB294 \uC218\uC815\uC740 \uC2E4\uD589 \uC804\uC5D0 \uADF8 \uC0AC\uC2E4\uC744 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uC54C\uB9AC\uACE0, \uC218\uC815 \uC81C\uC548\uC758 \uC694\uC57D(summary)\uC5D0\uB294 \uBB34\uC5C7\uC744\xB7\uC65C \uBC14\uAFB8\uB294\uC9C0 \uD568\uAED8 \uC801\uC2B5\uB2C8\uB2E4.
|
|
9951
|
+
7. \uAC1C\uC778\uC815\uBCF4(\uC8FC\uBBFC\uB4F1\uB85D\uBC88\uD638\xB7\uC804\uD654\uBC88\uD638\xB7\uC774\uBA54\uC77C\xB7\uACC4\uC88C\xB7\uCE74\uB4DC\uBC88\uD638 \uB4F1)\uAC00 \uC788\uC744 \uC218 \uC788\uB294 \uBB38\uC11C\uB97C \uB2E4\uB8F0 \uB54C \uC8FC\uC758\uD558\uACE0, \uC0AC\uC6A9\uC790\uAC00 \uAC1C\uC778\uC815\uBCF4 \uC810\uAC80\uC744 \uC694\uCCAD\uD558\uBA74 \`scan_pii\` \uB3C4\uAD6C\uB85C \uD655\uC778\uD569\uB2C8\uB2E4.`;
|
|
9895
9952
|
var LAW_RULES_SECTION = `## \uBC95\uB839 \uADDC\uCE59
|
|
9896
9953
|
|
|
9897
9954
|
1. \uBC95\uB839 \uC778\uC6A9 \uD615\uC2DD: \u300C\uBC95\uB839\uBA85\u300D \uC81CN\uC870 \uC81CN\uD56D \uC81CN\uD638
|
|
@@ -10017,6 +10074,26 @@ var AgentSession = class {
|
|
|
10017
10074
|
this.openDocuments.push(p);
|
|
10018
10075
|
}
|
|
10019
10076
|
}
|
|
10077
|
+
/**
|
|
10078
|
+
* 저장된 메시지(어시스턴트 tool-call 파트)에서 열람·작성한 문서 경로를 도출해 기록한다.
|
|
10079
|
+
* 세션이 턴마다 재생성되므로, 시스템 프롬프트("열람한 문서")가 이전 턴의 열람 기록을
|
|
10080
|
+
* 반영하려면 히스토리에서 다시 복원해야 한다.
|
|
10081
|
+
*/
|
|
10082
|
+
recordOpenDocumentsFromMessage(msg) {
|
|
10083
|
+
const content = msg.content;
|
|
10084
|
+
if (!Array.isArray(content)) return;
|
|
10085
|
+
for (const part of content) {
|
|
10086
|
+
if (!part || typeof part !== "object") continue;
|
|
10087
|
+
const p = part;
|
|
10088
|
+
if (p.type !== "tool-call" || !p.input) continue;
|
|
10089
|
+
if (p.toolName === "read_document" || p.toolName === "write_new_document" || p.toolName === "write_new_spreadsheet") {
|
|
10090
|
+
this.recordOpenDocument(p.input.path);
|
|
10091
|
+
} else if (p.toolName === "compare_documents") {
|
|
10092
|
+
this.recordOpenDocument(p.input.pathA);
|
|
10093
|
+
this.recordOpenDocument(p.input.pathB);
|
|
10094
|
+
}
|
|
10095
|
+
}
|
|
10096
|
+
}
|
|
10020
10097
|
/** approval-required 이벤트를 run() 스트림에 전달하기 위한 큐 */
|
|
10021
10098
|
pendingApprovalEvents = [];
|
|
10022
10099
|
/**
|
|
@@ -10025,6 +10102,9 @@ var AgentSession = class {
|
|
|
10025
10102
|
async loadHistory() {
|
|
10026
10103
|
const msgs = await this.opts.store.loadMessages();
|
|
10027
10104
|
this.messages.push(...msgs);
|
|
10105
|
+
for (const msg of msgs) {
|
|
10106
|
+
this.recordOpenDocumentsFromMessage(msg);
|
|
10107
|
+
}
|
|
10028
10108
|
}
|
|
10029
10109
|
/**
|
|
10030
10110
|
* 사용자 메시지를 처리하고 에이전트 이벤트를 스트리밍한다.
|
|
@@ -10079,7 +10159,7 @@ var AgentSession = class {
|
|
|
10079
10159
|
} else if (part.toolName === "compare_documents") {
|
|
10080
10160
|
this.recordOpenDocument(inp.pathA);
|
|
10081
10161
|
this.recordOpenDocument(inp.pathB);
|
|
10082
|
-
} else if (part.toolName === "write_new_document") {
|
|
10162
|
+
} else if (part.toolName === "write_new_document" || part.toolName === "write_new_spreadsheet") {
|
|
10083
10163
|
this.recordOpenDocument(inp.path);
|
|
10084
10164
|
}
|
|
10085
10165
|
} catch {
|
|
@@ -10788,6 +10868,13 @@ var ToolRegistry = class {
|
|
|
10788
10868
|
return outcome;
|
|
10789
10869
|
}
|
|
10790
10870
|
const { proposal, commit } = outcome;
|
|
10871
|
+
const piiFindings = detectPii(proposal.diff ?? "");
|
|
10872
|
+
if (piiFindings.length > 0) {
|
|
10873
|
+
proposal.warnings = [
|
|
10874
|
+
...proposal.warnings ?? [],
|
|
10875
|
+
`\uAC1C\uC778\uC815\uBCF4 \uD3EC\uD568: \uC774\uBC88 \uBCC0\uACBD \uC601\uC5ED\uC5D0 ${summarizePii(piiFindings)}\uC774(\uAC00) \uC788\uC2B5\uB2C8\uB2E4. \uC678\uBD80 \uACF5\uC720 \uC2DC \uC8FC\uC758\uD558\uC138\uC694.`
|
|
10876
|
+
];
|
|
10877
|
+
}
|
|
10791
10878
|
getEventEmitter()?.(proposal);
|
|
10792
10879
|
const approvalResult = await approvalHandler(proposal);
|
|
10793
10880
|
if (!approvalResult.approved) {
|
|
@@ -10883,14 +10970,18 @@ import { parse as parse5 } from "@clazic/kordoc";
|
|
|
10883
10970
|
import { z as z11 } from "zod";
|
|
10884
10971
|
import { readFile as fsReadFile, stat as stat5 } from "fs/promises";
|
|
10885
10972
|
import { z as z12 } from "zod";
|
|
10886
|
-
import {
|
|
10973
|
+
import { readFile as readFile12 } from "fs/promises";
|
|
10887
10974
|
import { extname as extname12 } from "path";
|
|
10888
|
-
import {
|
|
10975
|
+
import { parse as parse6 } from "@clazic/kordoc";
|
|
10889
10976
|
import { z as z13 } from "zod";
|
|
10890
|
-
import { stat as
|
|
10977
|
+
import { stat as stat6 } from "fs/promises";
|
|
10891
10978
|
import { extname as extname13 } from "path";
|
|
10892
|
-
import
|
|
10979
|
+
import { markdownToHwpx as markdownToHwpx3 } from "@clazic/kordoc";
|
|
10893
10980
|
import { z as z14 } from "zod";
|
|
10981
|
+
import { stat as stat7 } from "fs/promises";
|
|
10982
|
+
import { extname as extname14 } from "path";
|
|
10983
|
+
import ExcelJS2 from "exceljs";
|
|
10984
|
+
import { z as z15 } from "zod";
|
|
10894
10985
|
async function resolveSafePath(cwd, p) {
|
|
10895
10986
|
const normalizedCwd = normalize(cwd).normalize("NFC");
|
|
10896
10987
|
const normalizedP = p.normalize("NFC");
|
|
@@ -11155,19 +11246,29 @@ var restoreBackupTool = {
|
|
|
11155
11246
|
if (candidates.length === 0) {
|
|
11156
11247
|
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
11248
|
}
|
|
11249
|
+
const byNewest = (a, b) => b.mtimeMs !== a.mtimeMs ? b.mtimeMs - a.mtimeMs : b.tsToken.localeCompare(a.tsToken);
|
|
11158
11250
|
let chosen;
|
|
11159
|
-
|
|
11160
|
-
|
|
11161
|
-
|
|
11162
|
-
);
|
|
11163
|
-
if (
|
|
11164
|
-
|
|
11251
|
+
let ambiguityNote = null;
|
|
11252
|
+
const requested = input.backup?.trim();
|
|
11253
|
+
if (requested) {
|
|
11254
|
+
const exact = candidates.find((c) => c.filename === requested);
|
|
11255
|
+
if (exact) {
|
|
11256
|
+
chosen = exact;
|
|
11257
|
+
} else {
|
|
11258
|
+
const matches = candidates.filter(
|
|
11259
|
+
(c) => c.filename.endsWith(requested) || c.fullPath.endsWith(requested)
|
|
11260
|
+
);
|
|
11261
|
+
if (matches.length === 0) {
|
|
11262
|
+
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\uC758 \uC815\uD655\uD55C \uD30C\uC77C\uBA85\uC744 \uD655\uC778\uD558\uC138\uC694.`;
|
|
11263
|
+
}
|
|
11264
|
+
matches.sort(byNewest);
|
|
11265
|
+
chosen = matches[0];
|
|
11266
|
+
if (matches.length > 1) {
|
|
11267
|
+
ambiguityNote = `'${input.backup}'\uC640 \uC77C\uCE58\uD558\uB294 \uBC31\uC5C5\uC774 ${matches.length}\uAC1C\uC5EC\uC11C \uAC00\uC7A5 \uCD5C\uADFC(${formatTimestamp(chosen.tsToken)}) \uAC83\uC744 \uC120\uD0DD\uD588\uC2B5\uB2C8\uB2E4. \uD2B9\uC815 \uBC31\uC5C5\uC744 \uC6D0\uD558\uBA74 list_backups\uC758 \uC804\uCCB4 \uD30C\uC77C\uBA85\uC744 \uC9C0\uC815\uD558\uC138\uC694.`;
|
|
11268
|
+
}
|
|
11165
11269
|
}
|
|
11166
|
-
chosen = found;
|
|
11167
11270
|
} else {
|
|
11168
|
-
candidates.sort(
|
|
11169
|
-
(a, b) => b.mtimeMs !== a.mtimeMs ? b.mtimeMs - a.mtimeMs : b.tsToken.localeCompare(a.tsToken)
|
|
11170
|
-
);
|
|
11271
|
+
candidates.sort(byNewest);
|
|
11171
11272
|
chosen = candidates[0];
|
|
11172
11273
|
}
|
|
11173
11274
|
let backupBytes;
|
|
@@ -11208,12 +11309,15 @@ var restoreBackupTool = {
|
|
|
11208
11309
|
].join("\n");
|
|
11209
11310
|
}
|
|
11210
11311
|
const warnings = [];
|
|
11211
|
-
const autoSelected = !
|
|
11312
|
+
const autoSelected = !requested && candidates.length > 1;
|
|
11212
11313
|
if (autoSelected) {
|
|
11213
11314
|
warnings.push(
|
|
11214
11315
|
`\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
11316
|
);
|
|
11216
11317
|
}
|
|
11318
|
+
if (ambiguityNote) {
|
|
11319
|
+
warnings.push(ambiguityNote);
|
|
11320
|
+
}
|
|
11217
11321
|
warnings.push(
|
|
11218
11322
|
"\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
11323
|
);
|
|
@@ -14457,8 +14561,8 @@ var readFileTool = {
|
|
|
14457
14561
|
if (info.size > MAX_SIZE) {
|
|
14458
14562
|
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.`;
|
|
14459
14563
|
}
|
|
14460
|
-
const { extname:
|
|
14461
|
-
const ext =
|
|
14564
|
+
const { extname: extname15 } = await import("path");
|
|
14565
|
+
const ext = extname15(safePath).toLowerCase();
|
|
14462
14566
|
if (!TEXT_EXTENSIONS.has(ext) && ext !== "") {
|
|
14463
14567
|
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.`;
|
|
14464
14568
|
}
|
|
@@ -14472,10 +14576,64 @@ var readFileTool = {
|
|
|
14472
14576
|
return content;
|
|
14473
14577
|
}
|
|
14474
14578
|
};
|
|
14579
|
+
var PLAIN_TEXT_EXTS2 = /* @__PURE__ */ new Set([".md", ".markdown", ".txt", ".text"]);
|
|
14580
|
+
var scanPiiSchema = z13.object({
|
|
14581
|
+
path: z13.string().describe("\uAC1C\uC778\uC815\uBCF4\uB97C \uC810\uAC80\uD560 \uBB38\uC11C \uACBD\uB85C")
|
|
14582
|
+
});
|
|
14583
|
+
var scanPiiTool = {
|
|
14584
|
+
name: "scan_pii",
|
|
14585
|
+
description: "\uBB38\uC11C\uC5D0\uC11C \uD55C\uAD6D \uAC1C\uC778\uC815\uBCF4(\uC8FC\uBBFC\uB4F1\uB85D\uBC88\uD638\xB7\uC2E0\uC6A9\uCE74\uB4DC\uBC88\uD638\xB7\uC804\uD654\uBC88\uD638\xB7\uC774\uBA54\uC77C)\uB97C \uD0D0\uC9C0\uD569\uB2C8\uB2E4. \uC6D0\uBB38 \uAC12\uC740 \uBC18\uD658\uD558\uC9C0 \uC54A\uACE0 \uB9C8\uC2A4\uD0B9\uB41C \uC608\uC2DC\uB9CC \uD45C\uC2DC\uD569\uB2C8\uB2E4. \uC678\uBD80 \uACF5\uC720 \uC804 \uAC80\uD1A0\uC5D0 \uD65C\uC6A9\uD558\uC138\uC694.",
|
|
14586
|
+
inputSchema: scanPiiSchema,
|
|
14587
|
+
requiresApproval: false,
|
|
14588
|
+
execute: async ({
|
|
14589
|
+
input,
|
|
14590
|
+
ctx
|
|
14591
|
+
}) => {
|
|
14592
|
+
let safePath;
|
|
14593
|
+
try {
|
|
14594
|
+
safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
14595
|
+
} catch (e) {
|
|
14596
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
14597
|
+
return `\uC624\uB958: \uACBD\uB85C\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${msg}`;
|
|
14598
|
+
}
|
|
14599
|
+
const ext = extname12(safePath).toLowerCase();
|
|
14600
|
+
let text3;
|
|
14601
|
+
if (PLAIN_TEXT_EXTS2.has(ext)) {
|
|
14602
|
+
try {
|
|
14603
|
+
text3 = await readFile12(safePath, "utf-8");
|
|
14604
|
+
} catch (e) {
|
|
14605
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
14606
|
+
return `\uC624\uB958: \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${msg}`;
|
|
14607
|
+
}
|
|
14608
|
+
} else {
|
|
14609
|
+
let parseResult;
|
|
14610
|
+
try {
|
|
14611
|
+
parseResult = await parse6(safePath);
|
|
14612
|
+
} catch (e) {
|
|
14613
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
14614
|
+
return `\uC624\uB958: \uBB38\uC11C\uB97C \uD30C\uC2F1\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${msg}`;
|
|
14615
|
+
}
|
|
14616
|
+
if (!parseResult.success) {
|
|
14617
|
+
return `\uC624\uB958: \uBB38\uC11C\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${parseResult.error ?? "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`;
|
|
14618
|
+
}
|
|
14619
|
+
text3 = parseResult.markdown;
|
|
14620
|
+
}
|
|
14621
|
+
const findings = detectPii(text3);
|
|
14622
|
+
if (findings.length === 0) {
|
|
14623
|
+
return `\uAC1C\uC778\uC815\uBCF4\uAC00 \uBC1C\uACAC\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4: ${input.path}`;
|
|
14624
|
+
}
|
|
14625
|
+
const lines = [`\uBC1C\uACAC\uB41C \uAC1C\uC778\uC815\uBCF4 (${input.path}):`];
|
|
14626
|
+
for (const f of findings) {
|
|
14627
|
+
lines.push(`- ${f.type}: ${f.count}\uAC74 (\uC608: ${f.masked.join(", ")})`);
|
|
14628
|
+
}
|
|
14629
|
+
lines.push("\u203B \uB9C8\uC2A4\uD0B9\uB41C \uC608\uC2DC\uC774\uBA70 \uC6D0\uBB38 \uAC12\uC740 \uD45C\uC2DC\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC678\uBD80 \uACF5\uC720 \uC804 \uD655\uC778\uD558\uC138\uC694.");
|
|
14630
|
+
return lines.join("\n");
|
|
14631
|
+
}
|
|
14632
|
+
};
|
|
14475
14633
|
var MAX_PREVIEW_CHARS = 1e4;
|
|
14476
|
-
var writeNewDocumentSchema =
|
|
14477
|
-
path:
|
|
14478
|
-
markdown:
|
|
14634
|
+
var writeNewDocumentSchema = z14.object({
|
|
14635
|
+
path: z14.string().describe("\uC0DD\uC131\uD560 \uBB38\uC11C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)"),
|
|
14636
|
+
markdown: z14.string().describe("\uC0C8 \uBB38\uC11C \uB0B4\uC6A9 (\uB9C8\uD06C\uB2E4\uC6B4 \uD615\uC2DD)")
|
|
14479
14637
|
});
|
|
14480
14638
|
var writeNewDocumentTool = {
|
|
14481
14639
|
name: "write_new_document",
|
|
@@ -14487,7 +14645,7 @@ var writeNewDocumentTool = {
|
|
|
14487
14645
|
ctx
|
|
14488
14646
|
}) => {
|
|
14489
14647
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
14490
|
-
const ext =
|
|
14648
|
+
const ext = extname13(safePath).toLowerCase();
|
|
14491
14649
|
try {
|
|
14492
14650
|
await stat6(safePath);
|
|
14493
14651
|
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.`;
|
|
@@ -14537,12 +14695,12 @@ ${preview}`,
|
|
|
14537
14695
|
};
|
|
14538
14696
|
}
|
|
14539
14697
|
};
|
|
14540
|
-
var writeNewSpreadsheetSchema =
|
|
14541
|
-
path:
|
|
14542
|
-
sheets:
|
|
14543
|
-
|
|
14544
|
-
name:
|
|
14545
|
-
rows:
|
|
14698
|
+
var writeNewSpreadsheetSchema = z15.object({
|
|
14699
|
+
path: z15.string().describe("\uC0DD\uC131\uD560 XLSX \uD30C\uC77C \uACBD\uB85C (cwd \uAE30\uC900 \uC0C1\uB300 \uACBD\uB85C \uB610\uB294 \uC808\uB300 \uACBD\uB85C)"),
|
|
14700
|
+
sheets: z15.array(
|
|
14701
|
+
z15.object({
|
|
14702
|
+
name: z15.string().describe("\uC2DC\uD2B8 \uC774\uB984"),
|
|
14703
|
+
rows: z15.array(z15.array(z15.string())).describe("\uD589 \uB370\uC774\uD130 \uBC30\uC5F4 (\uAC01 \uD589\uC740 \uC140 \uAC12 \uBC30\uC5F4)")
|
|
14546
14704
|
})
|
|
14547
14705
|
).min(1).describe("\uC0DD\uC131\uD560 \uC2DC\uD2B8 \uBAA9\uB85D")
|
|
14548
14706
|
});
|
|
@@ -14556,7 +14714,7 @@ var writeNewSpreadsheetTool = {
|
|
|
14556
14714
|
ctx
|
|
14557
14715
|
}) => {
|
|
14558
14716
|
const safePath = await resolveSafePath(ctx.cwd, input.path);
|
|
14559
|
-
const ext =
|
|
14717
|
+
const ext = extname14(safePath).toLowerCase();
|
|
14560
14718
|
if (ext !== ".xlsx") {
|
|
14561
14719
|
return `\uC624\uB958: write_new_spreadsheet\uC740 .xlsx \uD30C\uC77C\uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4. \uD604\uC7AC \uD655\uC7A5\uC790: ${ext}.`;
|
|
14562
14720
|
}
|
|
@@ -14616,6 +14774,7 @@ function createDocTools(_ctx) {
|
|
|
14616
14774
|
listFilesTool,
|
|
14617
14775
|
listBackupsTool,
|
|
14618
14776
|
readFileTool,
|
|
14777
|
+
scanPiiTool,
|
|
14619
14778
|
proposeEditTool,
|
|
14620
14779
|
proposeFormFillTool,
|
|
14621
14780
|
proposeCellEditTool,
|
|
@@ -15443,10 +15602,10 @@ async function runOnboarding() {
|
|
|
15443
15602
|
|
|
15444
15603
|
// src/update.ts
|
|
15445
15604
|
import { spawn } from "child_process";
|
|
15446
|
-
import { mkdir as mkdir4, readFile as
|
|
15605
|
+
import { mkdir as mkdir4, readFile as readFile13, writeFile as writeFile3 } from "fs/promises";
|
|
15447
15606
|
import { dirname as dirname3 } from "path";
|
|
15448
15607
|
function compareSemver(a, b) {
|
|
15449
|
-
const
|
|
15608
|
+
const parse7 = (v) => {
|
|
15450
15609
|
const clean = v.replace(/^v/, "").split("-")[0] ?? "";
|
|
15451
15610
|
const parts = clean.split(".").map((p) => {
|
|
15452
15611
|
const n = parseInt(p, 10);
|
|
@@ -15454,8 +15613,8 @@ function compareSemver(a, b) {
|
|
|
15454
15613
|
});
|
|
15455
15614
|
return [parts[0] ?? 0, parts[1] ?? 0, parts[2] ?? 0];
|
|
15456
15615
|
};
|
|
15457
|
-
const [aMaj, aMin, aPat] =
|
|
15458
|
-
const [bMaj, bMin, bPat] =
|
|
15616
|
+
const [aMaj, aMin, aPat] = parse7(a);
|
|
15617
|
+
const [bMaj, bMin, bPat] = parse7(b);
|
|
15459
15618
|
if (aMaj !== bMaj) return aMaj < bMaj ? -1 : 1;
|
|
15460
15619
|
if (aMin !== bMin) return aMin < bMin ? -1 : 1;
|
|
15461
15620
|
if (aPat !== bPat) return aPat < bPat ? -1 : 1;
|
|
@@ -15464,7 +15623,7 @@ function compareSemver(a, b) {
|
|
|
15464
15623
|
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
15465
15624
|
async function readCache(cachePath) {
|
|
15466
15625
|
try {
|
|
15467
|
-
const raw = await
|
|
15626
|
+
const raw = await readFile13(cachePath, "utf-8");
|
|
15468
15627
|
const parsed = JSON.parse(raw);
|
|
15469
15628
|
if (parsed !== null && typeof parsed === "object" && "checkedAt" in parsed && "latest" in parsed && typeof parsed.checkedAt === "string" && typeof parsed.latest === "string") {
|
|
15470
15629
|
return parsed;
|