deepseeker-code 1.0.50 → 1.0.52
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/README.md +7 -7
- package/dist/cli.mjs +556 -449
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -130,6 +130,7 @@ var init_strings = __esm({
|
|
|
130
130
|
approvalDeny: "\u62D2\u7EDD",
|
|
131
131
|
errAborted: "\u5DF2\u4E2D\u6B62\u5F53\u524D\u8F6E\u3002",
|
|
132
132
|
busyBlockSend: "\u23F3 \u6B63\u5728\u751F\u6210\uFF0C\u8BF7\u7B49\u5F85\u6216\u6309 Esc \u4E2D\u6B62\u540E\u518D\u53D1\u9001\u3002",
|
|
133
|
+
escInterrupt: "Esc \u4E2D\u6B62",
|
|
133
134
|
inboxQueued: "\u{1F4EE} \u5DF2\u6392\u961F\uFF0C\u5C06\u5728\u56DE\u5408\u8FB9\u754C\u9001\u8FBE\u6A21\u578B\uFF08Esc \u4ECD\u53EF\u4E2D\u6B62\uFF09\u3002",
|
|
134
135
|
inboxClaimed: (n) => `\u{1F4EC} \u5DF2\u9001\u8FBE\u6A21\u578B\uFF08${n} \u6761\u8865\u5145\u8F93\u5165\uFF09`,
|
|
135
136
|
inboxCarryover: (n) => `\u{1F4EC} \u672C\u8F6E\u7ED3\u675F\u65F6 ${n} \u6761\u8865\u5145\u8F93\u5165\u672A\u5728\u56DE\u5408\u8FB9\u754C\u9001\u8FBE\uFF0C\u5DF2\u5199\u5165\u4F1A\u8BDD\u5386\u53F2\uFF0C\u4E0B\u8F6E\u5BF9\u8BDD\u81EA\u52A8\u5E26\u5165\u3002`,
|
|
@@ -206,7 +207,7 @@ ${dim} \u8FD0\u884C npm i -g deepseeker-code@latest \u66F4\u65B0${reset}
|
|
|
206
207
|
return new Date(t).toLocaleDateString("zh-CN");
|
|
207
208
|
},
|
|
208
209
|
langCurrent: () => `\u5F53\u524D\u754C\u9762\u8BED\u8A00\uFF1A\u4E2D\u6587\uFF08/lang en \u5207\u6362\u82F1\u6587\uFF09`,
|
|
209
|
-
langSet: (l) => `\u754C\u9762\u8BED\u8A00\u5DF2\u5207\u6362\uFF1A${l === "zh" ? "\u4E2D\u6587" : "English"}`,
|
|
210
|
+
langSet: (l) => `\u754C\u9762\u8BED\u8A00\u5DF2\u5207\u6362\uFF1A${l === "zh" ? "\u4E2D\u6587" : "English"}\uFF08AI \u56DE\u590D\u8BED\u8A00\u9ED8\u8BA4\u8DDF\u968F\u6BCF\u8F6E\u63D0\u95EE\u81EA\u52A8\u5224\u65AD\uFF1B\u7EAF\u4EE3\u7801/\u65E0\u6587\u5B57\u8F6E\u6B21\u4EE5\u6B64\u8BED\u8A00\u4E3A\u51C6\uFF09`,
|
|
210
211
|
langInvalid: (arg) => `\u65E0\u6548\u8BED\u8A00\uFF1A${arg}\uFF08\u53EF\u9009\uFF1Azh \u4E2D\u6587 / en English\uFF09`,
|
|
211
212
|
outputStyleNone: () => `\u672A\u52A0\u8F7D\u4EFB\u4F55\u8F93\u51FA\u98CE\u683C\uFF08\u5728 ~/.deepseeker-code/output-styles/ \u653E <name>.md\uFF09\u3002`,
|
|
212
213
|
outputStyleCurrent: (cur) => `\u5F53\u524D\u8F93\u51FA\u98CE\u683C\uFF1A${cur ?? "\u9ED8\u8BA4\uFF08\u4E2D\u6027\uFF09"}\u3002\u53EF\u7528\uFF1A`,
|
|
@@ -220,10 +221,10 @@ ${cwd}
|
|
|
220
221
|
DeepSeeker-Code \u5C06\u5728\u6B64\u76EE\u5F55\u8BFB\u53D6\u3001\u7F16\u8F91\u548C\u6267\u884C\u6587\u4EF6\u3002`,
|
|
221
222
|
optTrust: "\u4FE1\u4EFB\u6B64\u76EE\u5F55",
|
|
222
223
|
optExit: "\u9000\u51FA",
|
|
223
|
-
helpText: (
|
|
224
|
+
helpText: (model, thinking, locale2) => [
|
|
224
225
|
"/help \xB7 /status \xB7 /clear \xB7 /exit",
|
|
225
226
|
"/plan \u2014 \u5207\u6362\u8BA1\u5212\u6A21\u5F0F\uFF08\u53EA\u8BFB\u8C03\u7814 \u2192 \u65B9\u6848\u5BA1\u6279 \u2192 \u5B9E\u73B0\uFF09",
|
|
226
|
-
`/model <\u6A21\u578Bid> \u2014 \u5207\u6362\u6A21\u578B\uFF08\u76F4\u8F93\uFF0C\u5F53\u524D ${
|
|
227
|
+
`/model <\u6A21\u578Bid> \u2014 \u5207\u6362\u6A21\u578B\uFF08\u76F4\u8F93\uFF0C\u5F53\u524D ${model}\uFF09`,
|
|
227
228
|
"/switch \u2014 \u5F39\u51FA\u5019\u9009\u6A21\u578B\u9009\u62E9\u5668",
|
|
228
229
|
`/thinking [off|high|max] \u2014 \u5207\u6362\u601D\u8003\u7B49\u7EA7\uFF08\u5F53\u524D ${thinking}\uFF09`,
|
|
229
230
|
`/lang [zh|en] \u2014 \u5207\u6362\u754C\u9762\u8BED\u8A00\uFF08\u5F53\u524D ${locale2}\uFF09`,
|
|
@@ -232,8 +233,8 @@ DeepSeeker-Code \u5C06\u5728\u6B64\u76EE\u5F55\u8BFB\u53D6\u3001\u7F16\u8F91\u54
|
|
|
232
233
|
"/trust \u2014 \u7BA1\u7406\u5DF2\u4FE1\u4EFB\u76EE\u5F55\uFF08\u9879\u76EE\u7EA7 hooks/skills \u7B49\u4EC5\u5728\u4FE1\u4EFB\u76EE\u5F55\u52A0\u8F7D\uFF1BCI \u7528 --trust \u663E\u5F0F\u4FE1\u4EFB\uFF09",
|
|
233
234
|
"Ctrl+C \u9000\u51FA \xB7 Esc \u4E2D\u6B62/\u6E05\u8F93\u5165 \xB7 Ctrl+G \u4E2D\u6B62 \xB7 Ctrl+T \u5C55\u5F00/\u6536\u8D77\u601D\u8003"
|
|
234
235
|
].join("\n"),
|
|
235
|
-
statusText: (
|
|
236
|
-
`\u6A21\u578B\uFF1A${
|
|
236
|
+
statusText: (model, thinking, planOn, locale2, cwd) => [
|
|
237
|
+
`\u6A21\u578B\uFF1A${model}`,
|
|
237
238
|
`\u601D\u8003\u7B49\u7EA7\uFF1A${thinking}`,
|
|
238
239
|
`\u8BA1\u5212\u6A21\u5F0F\uFF1A${planOn ? "\u5F00" : "\u5173"}`,
|
|
239
240
|
`\u754C\u9762\u8BED\u8A00\uFF1A${locale2}`,
|
|
@@ -278,6 +279,7 @@ DeepSeeker-Code \u5C06\u5728\u6B64\u76EE\u5F55\u8BFB\u53D6\u3001\u7F16\u8F91\u54
|
|
|
278
279
|
approvalDeny: "Deny",
|
|
279
280
|
errAborted: "Aborted current turn.",
|
|
280
281
|
busyBlockSend: "\u23F3 Still generating\u2014wait or press Esc to abort before sending.",
|
|
282
|
+
escInterrupt: "esc to interrupt",
|
|
281
283
|
inboxQueued: "\u{1F4EE} Queued\u2014will reach the model at the next round boundary (Esc still aborts).",
|
|
282
284
|
inboxClaimed: (n) => `\u{1F4EC} Delivered to the model (${n} supplemental input${n > 1 ? "s" : ""})`,
|
|
283
285
|
inboxCarryover: (n) => `\u{1F4EC} ${n} supplemental input${n > 1 ? "s" : ""} not claimed at a round boundary before this run ended; saved to session history and carried into the next turn.`,
|
|
@@ -354,7 +356,7 @@ Usage: /model <model-id> to switch directly, or /switch for the picker`,
|
|
|
354
356
|
return new Date(t).toLocaleDateString("en-US");
|
|
355
357
|
},
|
|
356
358
|
langCurrent: () => `Interface language: English (/lang zh for \u4E2D\u6587)`,
|
|
357
|
-
langSet: (l) => `Interface language: ${l === "zh" ? "\u4E2D\u6587" : "English"}`,
|
|
359
|
+
langSet: (l) => `Interface language: ${l === "zh" ? "\u4E2D\u6587" : "English"} (AI reply language follows each question's language automatically; this is the fallback for code-only / text-less turns)`,
|
|
358
360
|
langInvalid: (arg) => `Invalid language: ${arg} (choose zh / en)`,
|
|
359
361
|
outputStyleNone: () => `No output styles loaded (drop a <name>.md in ~/.deepseeker-code/output-styles/).`,
|
|
360
362
|
outputStyleCurrent: (cur) => `Current output style: ${cur ?? "default (neutral)"}. Available:`,
|
|
@@ -368,10 +370,10 @@ ${cwd}
|
|
|
368
370
|
DeepSeeker-Code will read, edit, and execute files here.`,
|
|
369
371
|
optTrust: "Yes, I trust this folder",
|
|
370
372
|
optExit: "No, exit",
|
|
371
|
-
helpText: (
|
|
373
|
+
helpText: (model, thinking, locale2) => [
|
|
372
374
|
"/help \xB7 /status \xB7 /clear \xB7 /exit",
|
|
373
375
|
"/plan \u2014 Toggle plan mode (read-only research \u2192 review \u2192 implement)",
|
|
374
|
-
`/model <model-id> \u2014 Switch model (direct input; current ${
|
|
376
|
+
`/model <model-id> \u2014 Switch model (direct input; current ${model})`,
|
|
375
377
|
"/switch \u2014 Open the model picker",
|
|
376
378
|
`/thinking [off|high|max] \u2014 Switch thinking level (current ${thinking})`,
|
|
377
379
|
`/lang [zh|en] \u2014 Switch interface language (current ${locale2})`,
|
|
@@ -380,8 +382,8 @@ DeepSeeker-Code will read, edit, and execute files here.`,
|
|
|
380
382
|
"/trust \u2014 Manage trusted dirs (project hooks/skills load only when trusted; CI uses --trust)",
|
|
381
383
|
"Ctrl+C exit \xB7 Esc abort/clear input \xB7 Ctrl+G abort \xB7 Ctrl+T toggle thinking"
|
|
382
384
|
].join("\n"),
|
|
383
|
-
statusText: (
|
|
384
|
-
`Model: ${
|
|
385
|
+
statusText: (model, thinking, planOn, locale2, cwd) => [
|
|
386
|
+
`Model: ${model}`,
|
|
385
387
|
`Thinking: ${thinking}`,
|
|
386
388
|
`Plan mode: ${planOn ? "on" : "off"}`,
|
|
387
389
|
`Language: ${locale2}`,
|
|
@@ -616,7 +618,7 @@ var init_common = __esm({
|
|
|
616
618
|
}
|
|
617
619
|
};
|
|
618
620
|
detectTextLocale = (text) => {
|
|
619
|
-
const stripped = (text || "").replace(/```[\s\S]*?```/g, " ").replace(/`[^`]*`/g, " ").replace(/\s+/g, " ");
|
|
621
|
+
const stripped = (text || "").replace(/```[\s\S]*?```/g, " ").replace(/`[^`]*`/g, " ").replace(/[A-Za-z]:[\\/][^\s"'`))\]},。;]*/g, " ").replace(/(?:^|[\s((【"'])\/(?:home|Users|root|var|tmp|mnt|opt|data|app)[^\s"'`))\]},。;]*/g, " ").replace(/https?:\/\/[^\s"'`))\]},。;]*/g, " ").replace(/\s+/g, " ");
|
|
620
622
|
const cjk = (stripped.match(/[㐀-䶿一-鿿]/g) || []).length;
|
|
621
623
|
const latin = (stripped.match(/[A-Za-z]/g) || []).length;
|
|
622
624
|
if (cjk === 0 && latin === 0) return null;
|
|
@@ -718,8 +720,8 @@ var init_prefs = __esm({
|
|
|
718
720
|
return p && typeof p === "object" ? p : {};
|
|
719
721
|
};
|
|
720
722
|
readModelPref = async () => {
|
|
721
|
-
const { model
|
|
722
|
-
return typeof
|
|
723
|
+
const { model } = await readPrefs();
|
|
724
|
+
return typeof model === "string" && model.trim() ? model.trim() : null;
|
|
723
725
|
};
|
|
724
726
|
readLocale = async () => {
|
|
725
727
|
const { locale: locale2 } = await readPrefs();
|
|
@@ -804,11 +806,11 @@ var init_type = __esm({
|
|
|
804
806
|
|
|
805
807
|
// ../core/src/llm/providers/deepseek/client.ts
|
|
806
808
|
import OpenAI from "openai";
|
|
807
|
-
var
|
|
809
|
+
var _model, getModel, MODEL_NAME, AUX_MODEL_NAME, REASONING_EFFORTS, clampReasoningEffort, MODEL_REASONING_EFFORT, MODEL_THINKING_ENABLED;
|
|
808
810
|
var init_client = __esm({
|
|
809
811
|
"../core/src/llm/providers/deepseek/client.ts"() {
|
|
810
812
|
"use strict";
|
|
811
|
-
|
|
813
|
+
getModel = () => _model ??= new OpenAI({
|
|
812
814
|
baseURL: process.env.DEEP_SEEK_API_URL || "https://api.deepseek.com",
|
|
813
815
|
apiKey: process.env.DEEP_SEEK_API_KEY,
|
|
814
816
|
// ★ 瞬态错误自动指数退避重试(SDK 内置:408/409/429/500/502/503/504 + 连接错误),
|
|
@@ -819,8 +821,8 @@ var init_client = __esm({
|
|
|
819
821
|
timeout: 12e4
|
|
820
822
|
// 单次请求 120s 兜底(长上下文 / 长生成场景)
|
|
821
823
|
});
|
|
822
|
-
MODEL_NAME = process.env.DEEP_SEEK_MODEL || "deepseek-
|
|
823
|
-
AUX_MODEL_NAME = process.env.DEEP_SEEK_AUX_MODEL || "deepseek-
|
|
824
|
+
MODEL_NAME = process.env.DEEP_SEEK_MODEL || "deepseek-flash";
|
|
825
|
+
AUX_MODEL_NAME = process.env.DEEP_SEEK_AUX_MODEL || "deepseek-flash";
|
|
824
826
|
REASONING_EFFORTS = ["high", "max"];
|
|
825
827
|
clampReasoningEffort = (raw) => raw && REASONING_EFFORTS.includes(raw) ? raw : "high";
|
|
826
828
|
MODEL_REASONING_EFFORT = clampReasoningEffort(process.env.DEEP_SEEK_REASONING_EFFORT);
|
|
@@ -875,7 +877,7 @@ var init_stream = __esm({
|
|
|
875
877
|
const idleAc = new AbortController();
|
|
876
878
|
const extSignal = opts.signal;
|
|
877
879
|
const combinedSignal = extSignal ? AbortSignal.any([idleAc.signal, extSignal]) : idleAc.signal;
|
|
878
|
-
const stream = await
|
|
880
|
+
const stream = await getModel().chat.completions.create(requestBody, {
|
|
879
881
|
signal: combinedSignal,
|
|
880
882
|
maxRetries: 0
|
|
881
883
|
});
|
|
@@ -935,7 +937,7 @@ var init_stream = __esm({
|
|
|
935
937
|
});
|
|
936
938
|
|
|
937
939
|
// ../core/src/llm/providers/deepseek/index.ts
|
|
938
|
-
var summarize, classifyRisk, isContextLengthError, isTransientError, buildAssistantMessage, deepseekProvider;
|
|
940
|
+
var summarize, classifyRisk, isContextLengthError, isImageUnsupportedError, isTransientError, buildAssistantMessage, deepseekProvider;
|
|
939
941
|
var init_deepseek = __esm({
|
|
940
942
|
"../core/src/llm/providers/deepseek/index.ts"() {
|
|
941
943
|
"use strict";
|
|
@@ -953,7 +955,7 @@ var init_deepseek = __esm({
|
|
|
953
955
|
thinking: { type: "disabled" },
|
|
954
956
|
stream: false
|
|
955
957
|
};
|
|
956
|
-
const completion = await
|
|
958
|
+
const completion = await getModel().chat.completions.create(requestBody, {
|
|
957
959
|
signal: opts.signal
|
|
958
960
|
});
|
|
959
961
|
if (completion && "choices" in completion) return completion;
|
|
@@ -968,7 +970,7 @@ var init_deepseek = __esm({
|
|
|
968
970
|
const timer = setTimeout(() => ac.abort(), 1e4);
|
|
969
971
|
if (signal) signal.addEventListener("abort", () => ac.abort(), { once: true });
|
|
970
972
|
try {
|
|
971
|
-
const completion = await
|
|
973
|
+
const completion = await getModel().chat.completions.create({
|
|
972
974
|
messages: [
|
|
973
975
|
{ role: "system", content: "\u4F60\u662F\u5DE5\u5177\u8C03\u7528\u98CE\u9669\u5206\u7C7B\u5668\u3002\u53EA\u56DE SAFE \u6216 RISKY\uFF0C\u4E0D\u8981\u4EFB\u4F55\u89E3\u91CA\u3002\u6309\u5DE5\u5177\u7C7B\u578B\u5224\u5B9A\uFF1A\u2460\u6587\u4EF6(edit/write/create/move_file/delete_path)\u2014\u2014\u5DE5\u4F5C\u533A\u5185\u5E38\u89C4\u6587\u4EF6\u64CD\u4F5C(\u542B\u79FB\u52A8/\u91CD\u547D\u540D)=SAFE\uFF0C\u8986\u76D6/\u5220\u9664/\u79FB\u52A8\u654F\u611F\u6587\u4EF6(.env/.git/.ssh/.aws/\u5BC6\u94A5/credentials/settings.json)\u6216\u5DE5\u4F5C\u533A\u5916=RISKY\uFF1B\u2461\u547D\u4EE4(run_command/run_in_background)\u2014\u2014\u53EA\u8BFB/\u6784\u5EFA/\u6D4B\u8BD5/\u67E5\u770B\u7C7B(ls/cat/git status/npm test/pnpm build/node -v/tsc/lint)=SAFE\uFF0C\u7834\u574F\u6027/\u5916\u5411/\u63D0\u6743(rm -rf\u3001\u683C\u5F0F\u5316\u3001curl|sh\u3001\u5916\u4F20\u6587\u4EF6\u3001chmod 777\u3001shutdown\u3001\u5199\u7CFB\u7EDF\u76EE\u5F55\u3001\u5B89\u88C5\u964C\u751F\u5305)=RISKY\uFF1B\u2462\u7F51\u7EDC(web_fetch/web_search)\u2014\u2014\u6293\u53D6\u516C\u5F00\u6587\u6863/\u5E38\u89C4 URL=SAFE\uFF0C\u5185\u7F51/\u53EF\u7591/\u672A\u77E5 URL=RISKY\uFF1B\u2463git_commit\u2014\u2014\u5E38\u89C4\u63D0\u4EA4=SAFE\uFF0C\u542B\u6076\u610F\u811A\u672C/\u5F02\u5E38\u6539\u52A8=RISKY\uFF1B\u2464MCP(mcp__*)\u2014\u2014\u9ED8\u8BA4 RISKY(\u9ED1\u76D2\u5DE5\u5177\u65E0\u6CD5\u5224\u5B9A\u5185\u90E8\u884C\u4E3A)\u3002\u4EFB\u4F55\u4E0D\u786E\u5B9A\u4E00\u5F8B RISKY\u3002" },
|
|
974
976
|
{ role: "user", content: `\u5DE5\u5177:${toolName}
|
|
@@ -995,6 +997,15 @@ var init_deepseek = __esm({
|
|
|
995
997
|
const msg = typeof e.message === "string" ? e.message : "";
|
|
996
998
|
return code === "context_length_exceeded" || /context_length|context length|maximum context|input length|too long|exceed/i.test(msg);
|
|
997
999
|
};
|
|
1000
|
+
isImageUnsupportedError = (e) => {
|
|
1001
|
+
if (!e || isContextLengthError(e)) return false;
|
|
1002
|
+
const status = e.status ?? e.response?.status;
|
|
1003
|
+
if (status !== 400 && status !== 422) return false;
|
|
1004
|
+
const code = e.error?.code ?? e.code;
|
|
1005
|
+
const msg = typeof e.message === "string" ? e.message : "";
|
|
1006
|
+
const codeStr = typeof code === "string" ? code : "";
|
|
1007
|
+
return /image|multimodal|vision|image_url/i.test(msg) || /image/i.test(codeStr);
|
|
1008
|
+
};
|
|
998
1009
|
isTransientError = (e) => {
|
|
999
1010
|
if (!e) return false;
|
|
1000
1011
|
const status = e.status ?? e.response?.status;
|
|
@@ -1017,7 +1028,8 @@ var init_deepseek = __esm({
|
|
|
1017
1028
|
classifyRisk,
|
|
1018
1029
|
buildAssistantMessage,
|
|
1019
1030
|
isContextLengthError,
|
|
1020
|
-
isTransientError
|
|
1031
|
+
isTransientError,
|
|
1032
|
+
isImageUnsupportedError
|
|
1021
1033
|
};
|
|
1022
1034
|
}
|
|
1023
1035
|
});
|
|
@@ -1028,16 +1040,67 @@ var init_createModel = __esm({
|
|
|
1028
1040
|
"../core/src/llm/createModel.ts"() {
|
|
1029
1041
|
"use strict";
|
|
1030
1042
|
init_client();
|
|
1031
|
-
SELECTABLE_MODELS = ["deepseek-
|
|
1043
|
+
SELECTABLE_MODELS = ["deepseek-flash", "deepseek-v4-pro", "deepseek-flash-vision-exp"];
|
|
1044
|
+
}
|
|
1045
|
+
});
|
|
1046
|
+
|
|
1047
|
+
// ../core/src/llm/visionCapability.ts
|
|
1048
|
+
import path6 from "path";
|
|
1049
|
+
import fs4 from "fs/promises";
|
|
1050
|
+
var CAP_FILE, MAX_ENTRIES, mem, loadPromise, ensureVisionCacheLoaded, peekVisionCapability, writeChain, persistLatest, learnVisionCapability;
|
|
1051
|
+
var init_visionCapability = __esm({
|
|
1052
|
+
"../core/src/llm/visionCapability.ts"() {
|
|
1053
|
+
"use strict";
|
|
1054
|
+
init_config();
|
|
1055
|
+
init_common();
|
|
1056
|
+
CAP_FILE = path6.join(appConfig.dataDir, "model-capabilities.json");
|
|
1057
|
+
MAX_ENTRIES = 100;
|
|
1058
|
+
mem = {};
|
|
1059
|
+
loadPromise = (async () => {
|
|
1060
|
+
const t = await readJSONFile(CAP_FILE);
|
|
1061
|
+
if (t && typeof t === "object") mem = t;
|
|
1062
|
+
})().catch(() => {
|
|
1063
|
+
});
|
|
1064
|
+
ensureVisionCacheLoaded = () => loadPromise;
|
|
1065
|
+
peekVisionCapability = (modelId) => {
|
|
1066
|
+
const e = mem[modelId?.trim()];
|
|
1067
|
+
return e && typeof e.vision === "boolean" ? e.vision : void 0;
|
|
1068
|
+
};
|
|
1069
|
+
writeChain = Promise.resolve();
|
|
1070
|
+
persistLatest = () => {
|
|
1071
|
+
writeChain = writeChain.then(async () => {
|
|
1072
|
+
try {
|
|
1073
|
+
await fs4.mkdir(appConfig.dataDir, { recursive: true });
|
|
1074
|
+
await atomicWriteJSON(CAP_FILE, mem);
|
|
1075
|
+
} catch {
|
|
1076
|
+
}
|
|
1077
|
+
});
|
|
1078
|
+
return writeChain;
|
|
1079
|
+
};
|
|
1080
|
+
learnVisionCapability = (modelId, vision) => {
|
|
1081
|
+
const id = modelId?.trim();
|
|
1082
|
+
if (!id) return;
|
|
1083
|
+
mem[id] = { vision, checkedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
1084
|
+
while (Object.keys(mem).length > MAX_ENTRIES) {
|
|
1085
|
+
let oldestKey = "";
|
|
1086
|
+
for (const k of Object.keys(mem)) {
|
|
1087
|
+
if (!oldestKey || (mem[k]?.checkedAt ?? "") < (mem[oldestKey]?.checkedAt ?? "")) oldestKey = k;
|
|
1088
|
+
}
|
|
1089
|
+
if (!oldestKey) break;
|
|
1090
|
+
delete mem[oldestKey];
|
|
1091
|
+
}
|
|
1092
|
+
void persistLatest();
|
|
1093
|
+
};
|
|
1032
1094
|
}
|
|
1033
1095
|
});
|
|
1034
1096
|
|
|
1035
1097
|
// ../core/src/session/contentParts.ts
|
|
1036
|
-
var MAX_IMAGE_BYTES, msgText, imageUrlsOf, hasImagePart,
|
|
1098
|
+
var MAX_IMAGE_BYTES, msgText, imageUrlsOf, hasImagePart, VISION_DEGRADE_NOTE, isVisionEnabled, estimateImageTokens, toWireUserContent, toIngestContents, replaceImageParts, collapseToText, degradeImagesForAux;
|
|
1037
1099
|
var init_contentParts = __esm({
|
|
1038
1100
|
"../core/src/session/contentParts.ts"() {
|
|
1039
1101
|
"use strict";
|
|
1040
1102
|
init_createModel();
|
|
1103
|
+
init_visionCapability();
|
|
1041
1104
|
MAX_IMAGE_BYTES = 8 * 1024 * 1024;
|
|
1042
1105
|
msgText = (content) => {
|
|
1043
1106
|
if (typeof content === "string") return content;
|
|
@@ -1051,13 +1114,13 @@ var init_contentParts = __esm({
|
|
|
1051
1114
|
return content.filter((p) => p?.type === "image_url" && typeof p?.image_url?.url === "string").map((p) => p.image_url.url);
|
|
1052
1115
|
};
|
|
1053
1116
|
hasImagePart = (content) => imageUrlsOf(content).length > 0;
|
|
1054
|
-
|
|
1117
|
+
VISION_DEGRADE_NOTE = "[\u56FE\u7247\u672A\u9001\u8FBE\uFF1A\u5F53\u524D\u6A21\u578B\u4E0D\u652F\u6301\u56FE\u7247\u8F93\u5165\uFF0C\u7CFB\u7EDF\u5DF2\u81EA\u52A8\u6539\u7528\u6587\u672C\u65B9\u5F0F\uFF1B\u539F\u56FE\u4ECD\u5728\u4F1A\u8BDD\u5F52\u6863\u4E2D\uFF0C\u5982\u9700\u5206\u6790\u56FE\u7247\u5185\u5BB9\u53EF\u914D\u7F6E\u56FE\u50CF\u8BC6\u522B\u5DE5\u5177\u8BFB\u53D6\u5B58\u6863\u8DEF\u5F84\uFF0C\u6216\u7531\u7528\u6237\u91CD\u65B0\u63D0\u4F9B]";
|
|
1055
1118
|
isVisionEnabled = (modelId) => {
|
|
1056
1119
|
const v = process.env.DEEP_SEEK_VISION;
|
|
1057
1120
|
if (v === "1" || v === "true") return true;
|
|
1058
1121
|
if (v === "0" || v === "false") return false;
|
|
1059
1122
|
const effective = typeof modelId === "string" && modelId.trim() ? modelId.trim() : MODEL_NAME;
|
|
1060
|
-
return
|
|
1123
|
+
return peekVisionCapability(effective) ?? true;
|
|
1061
1124
|
};
|
|
1062
1125
|
estimateImageTokens = () => {
|
|
1063
1126
|
const n = Number(process.env.DEEP_SEEK_IMAGE_TOKENS);
|
|
@@ -1082,9 +1145,9 @@ var init_contentParts = __esm({
|
|
|
1082
1145
|
skipped.push(`\u{1F5BC} \u56FE\u7247 ${name} \u5DF2\u5FFD\u7565\uFF1A\u8D85\u8FC7 ${Math.round(MAX_IMAGE_BYTES / 1024 / 1024)}MB \u4E0A\u9650`);
|
|
1083
1146
|
continue;
|
|
1084
1147
|
}
|
|
1085
|
-
accepted.push({ name, url: `data:${a.mime};base64,${b64}
|
|
1148
|
+
accepted.push({ name, url: `data:${a.mime};base64,${b64}`, path: a.path });
|
|
1086
1149
|
}
|
|
1087
|
-
const labels = accepted.map((p) => `\u{1F5BC} [\u56FE\u7247: ${p.name}]`);
|
|
1150
|
+
const labels = accepted.map((p) => `\u{1F5BC} [\u56FE\u7247: ${p.name}${p.path ? ` | \u5B58\u6863: ${p.path}` : ""}]`);
|
|
1088
1151
|
const footer = [...skipped, ...labels];
|
|
1089
1152
|
const finalText = footer.length ? `${text}
|
|
1090
1153
|
|
|
@@ -1108,7 +1171,7 @@ ${paths.join("\n")}
|
|
|
1108
1171
|
return {
|
|
1109
1172
|
wire: `${text}
|
|
1110
1173
|
|
|
1111
|
-
\u{1F5BC} \u6536\u5230\u56FE\u7247\u9644\u4EF6\uFF08${names}\uFF09\uFF1A\u5F53\u524D\u6A21\u578B\
|
|
1174
|
+
\u{1F5BC} \u6536\u5230\u56FE\u7247\u9644\u4EF6\uFF08${names}\uFF09\uFF1A\u5F53\u524D\u6A21\u578B\u4E0D\u652F\u6301\u56FE\u7247\u8F93\u5165\uFF08\u89C6\u89C9\u80FD\u529B\u5DF2\u6309\u7AEF\u70B9\u5B9E\u6D4B\u81EA\u52A8\u5224\u5B9A\uFF1B\u53EF\u5207\u6362 vision \u6A21\u578B\u6216\u8BBE DEEP_SEEK_VISION=1 \u5F3A\u5F00\uFF09\uFF1B${relay}`,
|
|
1112
1175
|
archive
|
|
1113
1176
|
};
|
|
1114
1177
|
};
|
|
@@ -1149,10 +1212,11 @@ var init_replay = __esm({
|
|
|
1149
1212
|
let attemptCounts = [];
|
|
1150
1213
|
const calls = [];
|
|
1151
1214
|
const makeFaultError = (fault) => {
|
|
1152
|
-
const msg = fault.message ?? (fault.type === "idle" ? "stream_idle_timeout" : fault.type === "context_length" ? "context_length_exceeded\uFF08\u56DE\u653E\u6CE8\u5165\uFF09" : fault.type === "transient" ? "HTTP 429 rate limit\uFF08\u56DE\u653E\u6CE8\u5165\uFF09" : "\u56DE\u653E\u81F4\u547D\u9519\u8BEF\uFF08fatal\uFF09");
|
|
1215
|
+
const msg = fault.message ?? (fault.type === "idle" ? "stream_idle_timeout" : fault.type === "context_length" ? "context_length_exceeded\uFF08\u56DE\u653E\u6CE8\u5165\uFF09" : fault.type === "transient" ? "HTTP 429 rate limit\uFF08\u56DE\u653E\u6CE8\u5165\uFF09" : fault.type === "image_unsupported" ? "This model does not support image\uFF08\u56DE\u653E\u6CE8\u5165\uFF09" : "\u56DE\u653E\u81F4\u547D\u9519\u8BEF\uFF08fatal\uFF09");
|
|
1153
1216
|
const e = new Error(msg);
|
|
1154
1217
|
e.replayFault = fault.type;
|
|
1155
1218
|
if (fault.type === "transient") e.status = 429;
|
|
1219
|
+
if (fault.type === "image_unsupported") e.status = 400;
|
|
1156
1220
|
return e;
|
|
1157
1221
|
};
|
|
1158
1222
|
const streamChat2 = async function* (messages, tools, opts) {
|
|
@@ -1208,9 +1272,10 @@ var init_replay = __esm({
|
|
|
1208
1272
|
if (parts.toolCalls?.length) m.tool_calls = parts.toolCalls;
|
|
1209
1273
|
return m;
|
|
1210
1274
|
},
|
|
1211
|
-
// 自识别回放注入的故障(streamInference 经 activeProvider
|
|
1275
|
+
// 自识别回放注入的故障(streamInference 经 activeProvider 调用这些分类器驱动重试通道)
|
|
1212
1276
|
isContextLengthError: (e) => e?.replayFault === "context_length",
|
|
1213
1277
|
isTransientError: (e) => e?.replayFault === "transient",
|
|
1278
|
+
isImageUnsupportedError: (e) => e?.replayFault === "image_unsupported",
|
|
1214
1279
|
get calls() {
|
|
1215
1280
|
return calls;
|
|
1216
1281
|
},
|
|
@@ -1369,8 +1434,8 @@ __export(store_exports, {
|
|
|
1369
1434
|
updateCalibration: () => updateCalibration,
|
|
1370
1435
|
writeStore: () => writeStore
|
|
1371
1436
|
});
|
|
1372
|
-
import
|
|
1373
|
-
import
|
|
1437
|
+
import fs5 from "fs/promises";
|
|
1438
|
+
import path7 from "path";
|
|
1374
1439
|
async function getRollingState(sessionId) {
|
|
1375
1440
|
const store = await readStore(sessionId);
|
|
1376
1441
|
if (!store) {
|
|
@@ -1418,42 +1483,42 @@ var init_store = __esm({
|
|
|
1418
1483
|
getSessionsDirPath = (mainSessionId) => {
|
|
1419
1484
|
assertSafeSessionId(mainSessionId);
|
|
1420
1485
|
const fileName = getFileName(mainSessionId);
|
|
1421
|
-
return
|
|
1486
|
+
return path7.join(appConfig.dataDir, "sessions", appConfig.userWorkspaceDir, fileName);
|
|
1422
1487
|
};
|
|
1423
|
-
getWorkspaceSessionsDir = () =>
|
|
1488
|
+
getWorkspaceSessionsDir = () => path7.join(appConfig.dataDir, "sessions", appConfig.userWorkspaceDir);
|
|
1424
1489
|
getStatePath = (sessionId) => {
|
|
1425
1490
|
assertSafeSessionId(sessionId);
|
|
1426
|
-
return
|
|
1491
|
+
return path7.join(getSessionsDirPath(sessionId), `${sessionId}.state.json`);
|
|
1427
1492
|
};
|
|
1428
1493
|
getTranscriptPath = (sessionId) => {
|
|
1429
1494
|
assertSafeSessionId(sessionId);
|
|
1430
|
-
return
|
|
1495
|
+
return path7.join(getSessionsDirPath(sessionId), `${sessionId}.jsonl`);
|
|
1431
1496
|
};
|
|
1432
1497
|
ensureSessionsDir = async (sessionId) => {
|
|
1433
|
-
await
|
|
1498
|
+
await fs5.mkdir(getSessionsDirPath(sessionId), { recursive: true });
|
|
1434
1499
|
await migrateLegacyFiles(sessionId).catch(() => {
|
|
1435
1500
|
});
|
|
1436
1501
|
};
|
|
1437
1502
|
migrateLegacyFiles = async (sessionId) => {
|
|
1438
1503
|
assertSafeSessionId(sessionId);
|
|
1439
1504
|
const dir = getSessionsDirPath(sessionId);
|
|
1440
|
-
const legacy =
|
|
1505
|
+
const legacy = path7.join(dir, `${sessionId}.json`);
|
|
1441
1506
|
const transcriptPath = getTranscriptPath(sessionId);
|
|
1442
1507
|
const statePath = getStatePath(sessionId);
|
|
1443
1508
|
let legacyText;
|
|
1444
1509
|
try {
|
|
1445
|
-
legacyText = await
|
|
1510
|
+
legacyText = await fs5.readFile(legacy, "utf-8");
|
|
1446
1511
|
} catch {
|
|
1447
1512
|
return;
|
|
1448
1513
|
}
|
|
1449
1514
|
try {
|
|
1450
|
-
await
|
|
1515
|
+
await fs5.access(transcriptPath);
|
|
1451
1516
|
return;
|
|
1452
1517
|
} catch {
|
|
1453
1518
|
}
|
|
1454
1519
|
const raw = legacyText.trim();
|
|
1455
1520
|
if (raw.length === 0) {
|
|
1456
|
-
await
|
|
1521
|
+
await fs5.rename(legacy, transcriptPath);
|
|
1457
1522
|
return;
|
|
1458
1523
|
}
|
|
1459
1524
|
const lines = raw.split("\n");
|
|
@@ -1466,13 +1531,13 @@ var init_store = __esm({
|
|
|
1466
1531
|
}
|
|
1467
1532
|
});
|
|
1468
1533
|
if (isJsonl) {
|
|
1469
|
-
await
|
|
1534
|
+
await fs5.rename(legacy, transcriptPath);
|
|
1470
1535
|
return;
|
|
1471
1536
|
}
|
|
1472
1537
|
try {
|
|
1473
1538
|
const v = JSON.parse(raw);
|
|
1474
1539
|
if (typeof v === "object" && v !== null) {
|
|
1475
|
-
await
|
|
1540
|
+
await fs5.rename(legacy, statePath);
|
|
1476
1541
|
return;
|
|
1477
1542
|
}
|
|
1478
1543
|
} catch {
|
|
@@ -1483,8 +1548,8 @@ var init_store = __esm({
|
|
|
1483
1548
|
await ensureSessionsDir(sessionId);
|
|
1484
1549
|
const finalPath = getStatePath(sessionId);
|
|
1485
1550
|
const tmpPath = `${finalPath}.${Date.now()}.tmp`;
|
|
1486
|
-
await
|
|
1487
|
-
await
|
|
1551
|
+
await fs5.writeFile(tmpPath, JSON.stringify(store, null, 2), "utf-8");
|
|
1552
|
+
await fs5.rename(tmpPath, finalPath);
|
|
1488
1553
|
};
|
|
1489
1554
|
storeLocks = /* @__PURE__ */ new Map();
|
|
1490
1555
|
withStoreLock = (sessionId, fn) => {
|
|
@@ -1524,7 +1589,7 @@ var init_store = __esm({
|
|
|
1524
1589
|
await ensureSessionsDir(sessionId);
|
|
1525
1590
|
const p = getStatePath(sessionId);
|
|
1526
1591
|
try {
|
|
1527
|
-
const raw = (await
|
|
1592
|
+
const raw = (await fs5.readFile(p, "utf-8")).trim();
|
|
1528
1593
|
if (raw.length === 0) {
|
|
1529
1594
|
return {};
|
|
1530
1595
|
}
|
|
@@ -1553,7 +1618,7 @@ var init_store = __esm({
|
|
|
1553
1618
|
const root = getWorkspaceSessionsDir();
|
|
1554
1619
|
let entries;
|
|
1555
1620
|
try {
|
|
1556
|
-
entries = await
|
|
1621
|
+
entries = await fs5.readdir(root, { withFileTypes: true });
|
|
1557
1622
|
} catch {
|
|
1558
1623
|
return [];
|
|
1559
1624
|
}
|
|
@@ -1562,12 +1627,12 @@ var init_store = __esm({
|
|
|
1562
1627
|
if (!entry.isDirectory()) continue;
|
|
1563
1628
|
const sessionId = entry.name;
|
|
1564
1629
|
if (!isSafeSessionId(sessionId)) continue;
|
|
1565
|
-
const dirPath =
|
|
1630
|
+
const dirPath = path7.join(root, sessionId);
|
|
1566
1631
|
const state = await readJSONFile(getStatePath(sessionId));
|
|
1567
1632
|
let messageCount = 0;
|
|
1568
1633
|
let preview = "";
|
|
1569
1634
|
try {
|
|
1570
|
-
const raw = await
|
|
1635
|
+
const raw = await fs5.readFile(getTranscriptPath(sessionId), "utf-8");
|
|
1571
1636
|
for (const s of raw.split("\n")) {
|
|
1572
1637
|
const line = s.trim();
|
|
1573
1638
|
if (!line) continue;
|
|
@@ -1594,7 +1659,7 @@ var init_store = __esm({
|
|
|
1594
1659
|
let updatedAt = state?.updatedAt;
|
|
1595
1660
|
if (!updatedAt) {
|
|
1596
1661
|
try {
|
|
1597
|
-
updatedAt = (await
|
|
1662
|
+
updatedAt = (await fs5.stat(dirPath)).mtime.toISOString();
|
|
1598
1663
|
} catch {
|
|
1599
1664
|
}
|
|
1600
1665
|
}
|
|
@@ -1627,13 +1692,13 @@ var init_store = __esm({
|
|
|
1627
1692
|
deleteSession = async (sessionId) => {
|
|
1628
1693
|
assertSafeSessionId(sessionId);
|
|
1629
1694
|
const dir = getSessionsDirPath(sessionId);
|
|
1630
|
-
await
|
|
1695
|
+
await fs5.rm(dir, { recursive: true, force: true });
|
|
1631
1696
|
};
|
|
1632
1697
|
}
|
|
1633
1698
|
});
|
|
1634
1699
|
|
|
1635
1700
|
// ../core/src/session/transcript.ts
|
|
1636
|
-
import
|
|
1701
|
+
import fs6 from "fs/promises";
|
|
1637
1702
|
var isEventLine, readTranscriptLines, appendLineWithRetry, appendMessage, appendEvent;
|
|
1638
1703
|
var init_transcript = __esm({
|
|
1639
1704
|
"../core/src/session/transcript.ts"() {
|
|
@@ -1646,7 +1711,7 @@ var init_transcript = __esm({
|
|
|
1646
1711
|
await ensureSessionsDir(sessionId);
|
|
1647
1712
|
const p = getTranscriptPath(sessionId);
|
|
1648
1713
|
try {
|
|
1649
|
-
const text = await
|
|
1714
|
+
const text = await fs6.readFile(p, "utf-8");
|
|
1650
1715
|
const lines = [];
|
|
1651
1716
|
for (const s of text.split("\n")) {
|
|
1652
1717
|
const line = s.trim();
|
|
@@ -1668,15 +1733,15 @@ var init_transcript = __esm({
|
|
|
1668
1733
|
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
|
|
1669
1734
|
let beforeSize = 0;
|
|
1670
1735
|
try {
|
|
1671
|
-
beforeSize = (await
|
|
1736
|
+
beforeSize = (await fs6.stat(p)).size;
|
|
1672
1737
|
} catch {
|
|
1673
1738
|
}
|
|
1674
1739
|
try {
|
|
1675
|
-
await
|
|
1740
|
+
await fs6.appendFile(p, payload, "utf-8");
|
|
1676
1741
|
return;
|
|
1677
1742
|
} catch (e) {
|
|
1678
1743
|
try {
|
|
1679
|
-
await
|
|
1744
|
+
await fs6.truncate(p, beforeSize);
|
|
1680
1745
|
} catch {
|
|
1681
1746
|
}
|
|
1682
1747
|
if (attempt === MAX_ATTEMPTS) throw e;
|
|
@@ -1739,7 +1804,7 @@ var init_types = __esm({
|
|
|
1739
1804
|
|
|
1740
1805
|
// ../core/src/hooks/shellExecutor.ts
|
|
1741
1806
|
import { spawn } from "child_process";
|
|
1742
|
-
import
|
|
1807
|
+
import path8 from "path";
|
|
1743
1808
|
var MAX_OUTPUT, DEFAULT_TIMEOUT_MS, HARD_TIMEOUT_CAP_MS, ENV_WHITELIST, truncate, MAX_STDIN_FIELD, capFieldStrings, extractFilePath, executeHookCommand;
|
|
1744
1809
|
var init_shellExecutor = __esm({
|
|
1745
1810
|
"../core/src/hooks/shellExecutor.ts"() {
|
|
@@ -1785,7 +1850,7 @@ var init_shellExecutor = __esm({
|
|
|
1785
1850
|
if (typeof rel !== "string" || !rel.trim()) return void 0;
|
|
1786
1851
|
const base = typeof p.cwd === "string" && p.cwd || process.env.WORKSPACE_ROOT || process.cwd();
|
|
1787
1852
|
try {
|
|
1788
|
-
return
|
|
1853
|
+
return path8.resolve(base, rel);
|
|
1789
1854
|
} catch {
|
|
1790
1855
|
return void 0;
|
|
1791
1856
|
}
|
|
@@ -2002,7 +2067,7 @@ var init_hooks = __esm({
|
|
|
2002
2067
|
});
|
|
2003
2068
|
|
|
2004
2069
|
// ../core/src/agent/truncate.ts
|
|
2005
|
-
import
|
|
2070
|
+
import path9 from "path";
|
|
2006
2071
|
function stripAnsi(text) {
|
|
2007
2072
|
return text.replace(ANSI_ESCAPE, "");
|
|
2008
2073
|
}
|
|
@@ -2015,7 +2080,7 @@ function microcompactTextContent(raw) {
|
|
|
2015
2080
|
function isAsyncGenerator(x) {
|
|
2016
2081
|
return x != null && typeof x[Symbol.asyncIterator] === "function";
|
|
2017
2082
|
}
|
|
2018
|
-
var ANSI_ESCAPE, getFileAccessRoots, relativizeWorkspacePathsInText, truncateToolResult, truncateApprovalDetail, batchSummaryPrompt, compactBatch, ARCHIVE_INDEX_MAX_ENTRIES, ARCHIVE_INDEX_BATCH_CAP, extractArchiveEntities, parseSummarySlot, mergeSummarySlot, CHECKPOINT_MAX_CHARS, SLOT_PLACEHOLDER, CHECKPOINT_FORMAT, checkpointRules, checkpointPrompt, checkpointDirectPrompt, assembleSlot, parseSlotNarrativeState, synthesizeSlotNarrative, synthesizeSlotNarrativeFromBatch, compactSlotNarrative, splitIntoBatches, compactBatches, ensureSummarySlot, SUMMARY_SELF_COMPACT_THRESHOLD, ensureFitsWindow, collectToolResult;
|
|
2083
|
+
var ANSI_ESCAPE, getFileAccessRoots, relativizeWorkspacePathsInText, truncateToolResult, truncateApprovalDetail, batchSummaryPrompt, compactBatch, ARCHIVE_INDEX_MAX_ENTRIES, ARCHIVE_INDEX_BATCH_CAP, extractArchiveEntities, parseSummarySlot, mergeSummarySlot, CHECKPOINT_MAX_CHARS, SLOT_PLACEHOLDER, CHECKPOINT_FORMAT, checkpointRules, checkpointPrompt, checkpointDirectPrompt, assembleSlot, parseSlotNarrativeState, synthesizeSlotNarrative, synthesizeSlotNarrativeFromBatch, compactSlotNarrative, splitIntoBatches, compactBatches, ensureSummarySlot, SUMMARY_SELF_COMPACT_THRESHOLD, persistCompaction, ensureFitsWindow, collectToolResult;
|
|
2019
2084
|
var init_truncate = __esm({
|
|
2020
2085
|
"../core/src/agent/truncate.ts"() {
|
|
2021
2086
|
"use strict";
|
|
@@ -2041,10 +2106,10 @@ var init_truncate = __esm({
|
|
|
2041
2106
|
if (!text) return text;
|
|
2042
2107
|
const roots = /* @__PURE__ */ new Set();
|
|
2043
2108
|
try {
|
|
2044
|
-
roots.add(
|
|
2109
|
+
roots.add(path9.resolve(appConfig.userWorkspaceDir));
|
|
2045
2110
|
for (const r of getFileAccessRoots()) {
|
|
2046
2111
|
try {
|
|
2047
|
-
roots.add(
|
|
2112
|
+
roots.add(path9.resolve(r));
|
|
2048
2113
|
} catch {
|
|
2049
2114
|
}
|
|
2050
2115
|
}
|
|
@@ -2232,6 +2297,19 @@ ${lines}
|
|
|
2232
2297
|
}
|
|
2233
2298
|
};
|
|
2234
2299
|
SUMMARY_SELF_COMPACT_THRESHOLD = 2e3;
|
|
2300
|
+
persistCompaction = async (sessionId, archivedMessageCount, summary) => {
|
|
2301
|
+
await setRollingState(sessionId, {
|
|
2302
|
+
archivedMessageCount,
|
|
2303
|
+
rollingSummary: summary,
|
|
2304
|
+
consecutiveFailures: 0,
|
|
2305
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2306
|
+
});
|
|
2307
|
+
await appendEvent(sessionId, {
|
|
2308
|
+
dscEvent: "compaction",
|
|
2309
|
+
archivedMessageCount,
|
|
2310
|
+
summary
|
|
2311
|
+
});
|
|
2312
|
+
};
|
|
2235
2313
|
ensureFitsWindow = async (event) => {
|
|
2236
2314
|
const correctionRatio = event.correctionRatio ?? 1.4;
|
|
2237
2315
|
const toolsTokens = event.toolsTokens ?? 0;
|
|
@@ -2283,17 +2361,7 @@ ${lines}
|
|
|
2283
2361
|
});
|
|
2284
2362
|
const store = await getRollingState(event.sessionId);
|
|
2285
2363
|
store.archivedMessageCount = (store.archivedMessageCount || 0) + toCompact.length;
|
|
2286
|
-
await
|
|
2287
|
-
archivedMessageCount: store.archivedMessageCount,
|
|
2288
|
-
rollingSummary: summaryMsg.content,
|
|
2289
|
-
consecutiveFailures: 0,
|
|
2290
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2291
|
-
});
|
|
2292
|
-
await appendEvent(event.sessionId, {
|
|
2293
|
-
dscEvent: "compaction",
|
|
2294
|
-
archivedMessageCount: store.archivedMessageCount,
|
|
2295
|
-
summary: summaryMsg.content
|
|
2296
|
-
});
|
|
2364
|
+
await persistCompaction(event.sessionId, store.archivedMessageCount, summaryMsg.content);
|
|
2297
2365
|
} else if (keep > 1) {
|
|
2298
2366
|
keep--;
|
|
2299
2367
|
continue;
|
|
@@ -2302,17 +2370,7 @@ ${lines}
|
|
|
2302
2370
|
event.messageArr.length = 0;
|
|
2303
2371
|
event.messageArr.push(systemMsg, summaryMsg, ...keepRecent);
|
|
2304
2372
|
const store = await getRollingState(event.sessionId);
|
|
2305
|
-
await
|
|
2306
|
-
archivedMessageCount: store.archivedMessageCount,
|
|
2307
|
-
rollingSummary: summaryMsg.content,
|
|
2308
|
-
consecutiveFailures: 0,
|
|
2309
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2310
|
-
});
|
|
2311
|
-
await appendEvent(event.sessionId, {
|
|
2312
|
-
dscEvent: "compaction",
|
|
2313
|
-
archivedMessageCount: store.archivedMessageCount,
|
|
2314
|
-
summary: summaryMsg.content
|
|
2315
|
-
});
|
|
2373
|
+
await persistCompaction(event.sessionId, store.archivedMessageCount, summaryMsg.content);
|
|
2316
2374
|
} else {
|
|
2317
2375
|
break;
|
|
2318
2376
|
}
|
|
@@ -2419,8 +2477,8 @@ ${lines}
|
|
|
2419
2477
|
});
|
|
2420
2478
|
|
|
2421
2479
|
// ../core/src/tool/permissions.ts
|
|
2422
|
-
import
|
|
2423
|
-
import
|
|
2480
|
+
import fs7 from "fs/promises";
|
|
2481
|
+
import path10 from "path";
|
|
2424
2482
|
var PRIMARY_ARG, rules2, trustedProject, globCache, globToRegex, DANGER_COMMAND_TOOLS, compileRule, readPermissionConfig, toolNameMatches, ruleMatches, initPermissions, checkPermission, listPermissionRules, buildScopedAllowRule, resolveSettingsPath, addPermissionRule;
|
|
2425
2483
|
var init_permissions = __esm({
|
|
2426
2484
|
"../core/src/tool/permissions.ts"() {
|
|
@@ -2482,15 +2540,15 @@ var init_permissions = __esm({
|
|
|
2482
2540
|
readPermissionConfig = async (includeProject) => {
|
|
2483
2541
|
const merged = { allow: [], deny: [], ask: [] };
|
|
2484
2542
|
const paths = [
|
|
2485
|
-
|
|
2543
|
+
path10.join(appConfig.dataDir, "settings.json"),
|
|
2486
2544
|
// 全局用户级
|
|
2487
|
-
...includeProject ? [
|
|
2545
|
+
...includeProject ? [path10.join(process.cwd(), ".deepseeker-code", "settings.json")] : []
|
|
2488
2546
|
// 项目级(叠加);未信任时省略
|
|
2489
2547
|
];
|
|
2490
2548
|
for (const configPath of paths) {
|
|
2491
2549
|
let raw;
|
|
2492
2550
|
try {
|
|
2493
|
-
raw = await
|
|
2551
|
+
raw = await fs7.readFile(configPath, "utf-8");
|
|
2494
2552
|
} catch {
|
|
2495
2553
|
continue;
|
|
2496
2554
|
}
|
|
@@ -2575,7 +2633,7 @@ var init_permissions = __esm({
|
|
|
2575
2633
|
}
|
|
2576
2634
|
return `${toolName}(${val})`;
|
|
2577
2635
|
};
|
|
2578
|
-
resolveSettingsPath = (scope) => scope === "global" ?
|
|
2636
|
+
resolveSettingsPath = (scope) => scope === "global" ? path10.join(appConfig.dataDir, "settings.json") : path10.join(process.cwd(), ".deepseeker-code", "settings.json");
|
|
2579
2637
|
addPermissionRule = async (scope, kind, ruleStr) => {
|
|
2580
2638
|
if (scope === "project" && !trustedProject) return false;
|
|
2581
2639
|
const compiled = compileRule(ruleStr, `runtime:addPermissionRule(${scope})`, kind);
|
|
@@ -2587,7 +2645,7 @@ var init_permissions = __esm({
|
|
|
2587
2645
|
const arr = Array.isArray(cfg.permissions[kind]) ? cfg.permissions[kind] : cfg.permissions[kind] = [];
|
|
2588
2646
|
if (!arr.includes(ruleStr)) {
|
|
2589
2647
|
arr.push(ruleStr);
|
|
2590
|
-
await
|
|
2648
|
+
await fs7.mkdir(path10.dirname(file), { recursive: true });
|
|
2591
2649
|
await atomicWriteJSON(file, cfg);
|
|
2592
2650
|
}
|
|
2593
2651
|
if (!rules2[kind].some((r) => r.raw === compiled.raw)) rules2[kind].push(compiled);
|
|
@@ -2625,9 +2683,9 @@ var init_sessionRegistry = __esm({
|
|
|
2625
2683
|
});
|
|
2626
2684
|
|
|
2627
2685
|
// ../core/src/tool/guard.ts
|
|
2628
|
-
import
|
|
2686
|
+
import fs8 from "fs/promises";
|
|
2629
2687
|
import fsSync from "fs";
|
|
2630
|
-
import
|
|
2688
|
+
import path11 from "path";
|
|
2631
2689
|
import ignore from "ignore";
|
|
2632
2690
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2633
2691
|
var WORKSPACE_ROOT, workspaceAls, getActiveWorkspaceRoot, runWithWorkspaceRoot, runWithSessionContext, BUILTIN_IGNORE_RULES, ignoreCache, ignoreBuilding, allowedRootsReal, getAllowedWorkspaceRoots, getContainingRoot, allowedBoundaryRoots, resolveSafePath, resolveReadablePath, assertWithinWorkspace, PROTECTED_WRITE_DIRS, COMMAND_ENV_DENYLIST, SENSITIVE_ENV_PATTERN, scrubCommandEnv, isProtectedWrite, scanIgnoreFilesRecursive, buildIgnoreEngine, getIgnoreForBase, initializeWorkspaceIgnore, checkIsPathIgnored, requestApproval;
|
|
@@ -2683,8 +2741,8 @@ var init_guard = __esm({
|
|
|
2683
2741
|
getContainingRoot = (absPath) => {
|
|
2684
2742
|
let best;
|
|
2685
2743
|
for (const r of allowedBoundaryRoots()) {
|
|
2686
|
-
const rel =
|
|
2687
|
-
if (!rel.startsWith("..") && !
|
|
2744
|
+
const rel = path11.relative(r, absPath);
|
|
2745
|
+
if (!rel.startsWith("..") && !path11.isAbsolute(rel)) {
|
|
2688
2746
|
if (!best || r.length > best.length) best = r;
|
|
2689
2747
|
}
|
|
2690
2748
|
}
|
|
@@ -2701,16 +2759,16 @@ var init_guard = __esm({
|
|
|
2701
2759
|
};
|
|
2702
2760
|
resolveSafePath = (rel, base) => {
|
|
2703
2761
|
const root = base ?? getActiveWorkspaceRoot();
|
|
2704
|
-
const candidateAbsPath =
|
|
2762
|
+
const candidateAbsPath = path11.resolve(root, rel);
|
|
2705
2763
|
let truePhysicalPath = candidateAbsPath;
|
|
2706
2764
|
try {
|
|
2707
2765
|
if (fsSync.existsSync(candidateAbsPath)) {
|
|
2708
2766
|
truePhysicalPath = fsSync.realpathSync(candidateAbsPath);
|
|
2709
2767
|
} else {
|
|
2710
|
-
const parentDir =
|
|
2768
|
+
const parentDir = path11.dirname(candidateAbsPath);
|
|
2711
2769
|
if (fsSync.existsSync(parentDir)) {
|
|
2712
2770
|
const trueParentDir = fsSync.realpathSync(parentDir);
|
|
2713
|
-
truePhysicalPath =
|
|
2771
|
+
truePhysicalPath = path11.join(trueParentDir, path11.basename(candidateAbsPath));
|
|
2714
2772
|
}
|
|
2715
2773
|
}
|
|
2716
2774
|
} catch (e) {
|
|
@@ -2724,8 +2782,8 @@ var init_guard = __esm({
|
|
|
2724
2782
|
}
|
|
2725
2783
|
})() : allowedBoundaryRoots();
|
|
2726
2784
|
const escaped = boundaryRoots.every((r) => {
|
|
2727
|
-
const rel0 =
|
|
2728
|
-
return rel0.startsWith("..") ||
|
|
2785
|
+
const rel0 = path11.relative(r, truePhysicalPath);
|
|
2786
|
+
return rel0.startsWith("..") || path11.isAbsolute(rel0);
|
|
2729
2787
|
});
|
|
2730
2788
|
if (escaped) {
|
|
2731
2789
|
throw new Error(`\u{1F6D1} [SECURITY ALERT] \u68C0\u6D4B\u5230\u6076\u610F\u7684\u7269\u7406\u8DEF\u5F84\u8DE8\u754C\u9003\u9038\uFF01\u62D2\u7EDD\u8BBF\u95EE\uFF1A${rel}`);
|
|
@@ -2734,12 +2792,12 @@ var init_guard = __esm({
|
|
|
2734
2792
|
};
|
|
2735
2793
|
resolveReadablePath = (rel) => {
|
|
2736
2794
|
const root = getActiveWorkspaceRoot();
|
|
2737
|
-
const absPath =
|
|
2795
|
+
const absPath = path11.resolve(root, rel);
|
|
2738
2796
|
if (!fsSync.existsSync(absPath)) {
|
|
2739
|
-
const rootName =
|
|
2797
|
+
const rootName = path11.basename(root);
|
|
2740
2798
|
const firstSeg = rel.split(/[\\/]/)[0];
|
|
2741
2799
|
if (rootName && firstSeg === rootName) {
|
|
2742
|
-
const alt =
|
|
2800
|
+
const alt = path11.resolve(root, rel.slice(firstSeg.length + 1));
|
|
2743
2801
|
if (fsSync.existsSync(alt)) return alt;
|
|
2744
2802
|
}
|
|
2745
2803
|
}
|
|
@@ -2752,9 +2810,9 @@ var init_guard = __esm({
|
|
|
2752
2810
|
if (fsSync.existsSync(absPath)) {
|
|
2753
2811
|
truePhysicalPath = fsSync.realpathSync(absPath);
|
|
2754
2812
|
} else {
|
|
2755
|
-
const parentDir =
|
|
2813
|
+
const parentDir = path11.dirname(absPath);
|
|
2756
2814
|
if (fsSync.existsSync(parentDir)) {
|
|
2757
|
-
truePhysicalPath =
|
|
2815
|
+
truePhysicalPath = path11.join(fsSync.realpathSync(parentDir), path11.basename(absPath));
|
|
2758
2816
|
}
|
|
2759
2817
|
}
|
|
2760
2818
|
} catch (e) {
|
|
@@ -2768,8 +2826,8 @@ var init_guard = __esm({
|
|
|
2768
2826
|
}
|
|
2769
2827
|
})() : allowedBoundaryRoots();
|
|
2770
2828
|
const escaped = boundaryRoots.every((r) => {
|
|
2771
|
-
const rel0 =
|
|
2772
|
-
return rel0.startsWith("..") ||
|
|
2829
|
+
const rel0 = path11.relative(r, truePhysicalPath);
|
|
2830
|
+
return rel0.startsWith("..") || path11.isAbsolute(rel0);
|
|
2773
2831
|
});
|
|
2774
2832
|
if (escaped) {
|
|
2775
2833
|
throw new Error(`\u{1F6D1} [SECURITY ALERT] \u4E8C\u6B21\u56F4\u680F\u590D\u68C0\u53D1\u73B0\u8D8A\u754C\uFF08\u7591\u4F3C TOCTOU \u8F6F\u94FE\u63A5\u9003\u9038\uFF09\uFF1A${absPath}`);
|
|
@@ -2796,7 +2854,7 @@ var init_guard = __esm({
|
|
|
2796
2854
|
if (!relOrAbs) return false;
|
|
2797
2855
|
try {
|
|
2798
2856
|
const base = cwd || process.env.WORKSPACE_ROOT || process.cwd();
|
|
2799
|
-
const abs =
|
|
2857
|
+
const abs = path11.isAbsolute(relOrAbs) ? relOrAbs : path11.resolve(base, relOrAbs);
|
|
2800
2858
|
const lower = abs.replace(/\\/g, "/").toLowerCase();
|
|
2801
2859
|
return PROTECTED_WRITE_DIRS.some((d) => {
|
|
2802
2860
|
const seg = ("/" + d).toLowerCase();
|
|
@@ -2808,12 +2866,12 @@ var init_guard = __esm({
|
|
|
2808
2866
|
};
|
|
2809
2867
|
scanIgnoreFilesRecursive = async (dirPath, base, engine) => {
|
|
2810
2868
|
try {
|
|
2811
|
-
const entries = await
|
|
2869
|
+
const entries = await fs8.readdir(dirPath, { withFileTypes: true });
|
|
2812
2870
|
for (const entry of entries) {
|
|
2813
2871
|
if (entry.isFile() && (entry.name === ".gitignore" || entry.name === ".agentignore")) {
|
|
2814
|
-
const fullPath =
|
|
2815
|
-
const content = await
|
|
2816
|
-
const relDir =
|
|
2872
|
+
const fullPath = path11.join(dirPath, entry.name);
|
|
2873
|
+
const content = await fs8.readFile(fullPath, "utf-8");
|
|
2874
|
+
const relDir = path11.relative(base, dirPath).replace(/\\/g, "/");
|
|
2817
2875
|
const rules3 = content.split(/\r?\n/).map((line) => {
|
|
2818
2876
|
const trimmed = line.trim();
|
|
2819
2877
|
if (!trimmed || trimmed.startsWith("#")) return "";
|
|
@@ -2824,7 +2882,7 @@ var init_guard = __esm({
|
|
|
2824
2882
|
}
|
|
2825
2883
|
for (const entry of entries) {
|
|
2826
2884
|
if (entry.isDirectory() && entry.name !== "node_modules" && entry.name !== ".git") {
|
|
2827
|
-
await scanIgnoreFilesRecursive(
|
|
2885
|
+
await scanIgnoreFilesRecursive(path11.join(dirPath, entry.name), base, engine);
|
|
2828
2886
|
}
|
|
2829
2887
|
}
|
|
2830
2888
|
} catch {
|
|
@@ -2895,7 +2953,7 @@ var init_guard = __esm({
|
|
|
2895
2953
|
// ../core/src/tool/registry/background.ts
|
|
2896
2954
|
import { spawn as spawn2, execFileSync } from "child_process";
|
|
2897
2955
|
import fsSync2 from "fs";
|
|
2898
|
-
import
|
|
2956
|
+
import path12 from "path";
|
|
2899
2957
|
function appendOutput(task, chunk) {
|
|
2900
2958
|
task.outputBuffer += chunk;
|
|
2901
2959
|
if (task.outputBuffer.length > MAX_BUFFER_CHARS) {
|
|
@@ -2920,7 +2978,7 @@ async function killTree(proc) {
|
|
|
2920
2978
|
}
|
|
2921
2979
|
}
|
|
2922
2980
|
async function killBackgroundTasksUnder(dirPath) {
|
|
2923
|
-
const norm = (p) =>
|
|
2981
|
+
const norm = (p) => path12.resolve(p).replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
|
|
2924
2982
|
const target = norm(dirPath);
|
|
2925
2983
|
let killed = 0;
|
|
2926
2984
|
for (const task of registry.values()) {
|
|
@@ -2965,9 +3023,9 @@ var init_background = __esm({
|
|
|
2965
3023
|
if (envShell && envShell.toLowerCase() !== "cmd") candidates.push(envShell);
|
|
2966
3024
|
const gitExe = whereLines("git")[0];
|
|
2967
3025
|
if (gitExe) {
|
|
2968
|
-
const dir =
|
|
2969
|
-
const root =
|
|
2970
|
-
candidates.push(
|
|
3026
|
+
const dir = path12.dirname(gitExe);
|
|
3027
|
+
const root = path12.dirname(dir);
|
|
3028
|
+
candidates.push(path12.join(root, "bin", "bash.exe"), path12.join(dir, "bash.exe"), path12.join(path12.dirname(root), "bin", "bash.exe"));
|
|
2971
3029
|
}
|
|
2972
3030
|
const bashHits = whereLines("bash").filter((p) => !/\\System32\\/i.test(p)).sort((a, b) => Number(/\\Git\\/i.test(b)) - Number(/\\Git\\/i.test(a)));
|
|
2973
3031
|
candidates.push(...bashHits);
|
|
@@ -3765,17 +3823,17 @@ ${capped || JSON.stringify(result)}`;
|
|
|
3765
3823
|
});
|
|
3766
3824
|
|
|
3767
3825
|
// ../core/src/tool/mcp/loader.ts
|
|
3768
|
-
import
|
|
3769
|
-
import
|
|
3826
|
+
import fs9 from "fs/promises";
|
|
3827
|
+
import path13 from "path";
|
|
3770
3828
|
import { homedir } from "os";
|
|
3771
3829
|
function sanitize(s) {
|
|
3772
3830
|
return s.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3773
3831
|
}
|
|
3774
3832
|
async function readMcpConfig() {
|
|
3775
|
-
const configPath = process.env.MCP_CONFIG ||
|
|
3833
|
+
const configPath = process.env.MCP_CONFIG || path13.join(appConfig.dataDir, "mcp.json");
|
|
3776
3834
|
let raw;
|
|
3777
3835
|
try {
|
|
3778
|
-
raw = await
|
|
3836
|
+
raw = await fs9.readFile(configPath, "utf-8");
|
|
3779
3837
|
} catch {
|
|
3780
3838
|
return {};
|
|
3781
3839
|
}
|
|
@@ -4423,7 +4481,7 @@ var init_toolFilter = __esm({
|
|
|
4423
4481
|
});
|
|
4424
4482
|
|
|
4425
4483
|
// ../core/src/common/registry.ts
|
|
4426
|
-
import
|
|
4484
|
+
import fs10 from "fs/promises";
|
|
4427
4485
|
var createRegistry, filterSources, scanSources;
|
|
4428
4486
|
var init_registry2 = __esm({
|
|
4429
4487
|
"../core/src/common/registry.ts"() {
|
|
@@ -4453,7 +4511,7 @@ var init_registry2 = __esm({
|
|
|
4453
4511
|
for (const s of sources) {
|
|
4454
4512
|
let entries;
|
|
4455
4513
|
try {
|
|
4456
|
-
entries = await
|
|
4514
|
+
entries = await fs10.readdir(s.dir, { withFileTypes: true });
|
|
4457
4515
|
} catch {
|
|
4458
4516
|
continue;
|
|
4459
4517
|
}
|
|
@@ -4550,8 +4608,8 @@ ${AGENT_USAGE_HINT}`);
|
|
|
4550
4608
|
});
|
|
4551
4609
|
|
|
4552
4610
|
// ../core/src/projectGuide/loader.ts
|
|
4553
|
-
import
|
|
4554
|
-
import
|
|
4611
|
+
import fs11 from "fs/promises";
|
|
4612
|
+
import path14 from "path";
|
|
4555
4613
|
var CANDIDATES, MAX_GUIDE_BYTES, cached, initProjectGuide, getProjectGuide;
|
|
4556
4614
|
var init_loader2 = __esm({
|
|
4557
4615
|
"../core/src/projectGuide/loader.ts"() {
|
|
@@ -4568,7 +4626,7 @@ var init_loader2 = __esm({
|
|
|
4568
4626
|
try {
|
|
4569
4627
|
for (const name of CANDIDATES) {
|
|
4570
4628
|
try {
|
|
4571
|
-
const raw = await
|
|
4629
|
+
const raw = await fs11.readFile(path14.join(WORKSPACE_ROOT, name), "utf-8");
|
|
4572
4630
|
const body = raw.length > MAX_GUIDE_BYTES ? raw.slice(0, MAX_GUIDE_BYTES) + `
|
|
4573
4631
|
|
|
4574
4632
|
\u2026[\u9879\u76EE\u6307\u5F15\u8D85 ${MAX_GUIDE_BYTES} \u5B57\u8282\u5DF2\u622A\u65AD\uFF0C\u5B8C\u6574\u5185\u5BB9\u53EF\u8C03\u7528 read_project_guide \u83B7\u53D6]` : raw;
|
|
@@ -4732,12 +4790,13 @@ var init_systemInjections = __esm({
|
|
|
4732
4790
|
en: "Always produce ALL user-facing output in English: your replies, interim narration, todo item titles, the plan text you submit via exit_plan_mode, code comments, and commit messages. Keep code identifiers as-is; tool results and system instructions may arrive in Chinese \u2014 quote them verbatim where needed, but your own narration and explanations must stay in English."
|
|
4733
4791
|
};
|
|
4734
4792
|
const lastUserText = (() => {
|
|
4793
|
+
const dropSyntheticLines = (t) => t.split("\n").filter((l) => !l.trimStart().startsWith("\u{1F5BC}")).join("\n").trim();
|
|
4735
4794
|
for (let i = message.length - 1; i >= 0; i--) {
|
|
4736
4795
|
const m = message[i];
|
|
4737
4796
|
if (m?.role !== "user") continue;
|
|
4738
4797
|
const c = m.content;
|
|
4739
|
-
if (typeof c === "string") return c;
|
|
4740
|
-
if (Array.isArray(c)) return c.filter((p) => typeof p?.text === "string").map((p) => p.text).join(" ");
|
|
4798
|
+
if (typeof c === "string") return dropSyntheticLines(c);
|
|
4799
|
+
if (Array.isArray(c)) return dropSyntheticLines(c.filter((p) => typeof p?.text === "string").map((p) => p.text).join(" "));
|
|
4741
4800
|
return "";
|
|
4742
4801
|
}
|
|
4743
4802
|
return "";
|
|
@@ -4810,9 +4869,9 @@ var init_agent = __esm({
|
|
|
4810
4869
|
});
|
|
4811
4870
|
|
|
4812
4871
|
// ../core/src/tool/worktree/manager.ts
|
|
4813
|
-
import
|
|
4872
|
+
import path15 from "path";
|
|
4814
4873
|
import os4 from "os";
|
|
4815
|
-
import
|
|
4874
|
+
import fs12 from "fs";
|
|
4816
4875
|
var runMainGit, worktreeRootDir, worktreeDir, isNotARepoError, createWorktree, harvestDiff, runInWorktree, removeWorktree, sweepOrphanedWorktrees, disposeAllSessionWorktrees;
|
|
4817
4876
|
var init_manager = __esm({
|
|
4818
4877
|
"../core/src/tool/worktree/manager.ts"() {
|
|
@@ -4823,8 +4882,8 @@ var init_manager = __esm({
|
|
|
4823
4882
|
init_background();
|
|
4824
4883
|
init_sessionRegistry();
|
|
4825
4884
|
runMainGit = (args, maxBuffer = 1024 * 1024 * 5) => execFileSmart("git", args, { cwd: WORKSPACE_ROOT, maxBuffer });
|
|
4826
|
-
worktreeRootDir = () =>
|
|
4827
|
-
worktreeDir = (sessionId, stepId) =>
|
|
4885
|
+
worktreeRootDir = () => path15.join(os4.tmpdir(), "deepseeker-code-worktrees", appConfig.userWorkspaceDir);
|
|
4886
|
+
worktreeDir = (sessionId, stepId) => path15.join(worktreeRootDir(), sessionId, stepId);
|
|
4828
4887
|
isNotARepoError = (e) => {
|
|
4829
4888
|
const text = `${e?.message || ""} ${e?.stderr || ""}`.toLowerCase();
|
|
4830
4889
|
return text.includes("not a git repository");
|
|
@@ -4835,12 +4894,12 @@ var init_manager = __esm({
|
|
|
4835
4894
|
const wtPath = worktreeDir(sessionId, stepId);
|
|
4836
4895
|
const shortId = sessionId.replace(/[^A-Za-z0-9-]/g, "").slice(0, 8) || "x";
|
|
4837
4896
|
const branch = `dsc-wt-${shortId}-${stepId}`;
|
|
4838
|
-
await
|
|
4897
|
+
await fs12.promises.mkdir(path15.dirname(wtPath), { recursive: true });
|
|
4839
4898
|
try {
|
|
4840
4899
|
await runMainGit(["worktree", "add", "-b", branch, wtPath, "HEAD"]);
|
|
4841
4900
|
} catch (e) {
|
|
4842
4901
|
if (e?.code === "ENOENT" || /already exists|not a working tree/i.test(`${e?.stderr || ""} ${e?.message || ""}`)) {
|
|
4843
|
-
await
|
|
4902
|
+
await fs12.promises.rm(wtPath, { recursive: true, force: true }).catch(() => {
|
|
4844
4903
|
});
|
|
4845
4904
|
await runMainGit(["worktree", "add", "-b", branch, wtPath, "HEAD"]);
|
|
4846
4905
|
} else {
|
|
@@ -4888,7 +4947,7 @@ var init_manager = __esm({
|
|
|
4888
4947
|
try {
|
|
4889
4948
|
await runMainGit(["worktree", "remove", "--force", wt.path]);
|
|
4890
4949
|
} catch (e) {
|
|
4891
|
-
await
|
|
4950
|
+
await fs12.promises.rm(wt.path, { recursive: true, force: true }).catch(() => {
|
|
4892
4951
|
});
|
|
4893
4952
|
}
|
|
4894
4953
|
try {
|
|
@@ -4905,30 +4964,30 @@ var init_manager = __esm({
|
|
|
4905
4964
|
const root = worktreeRootDir();
|
|
4906
4965
|
let entries;
|
|
4907
4966
|
try {
|
|
4908
|
-
entries = await
|
|
4967
|
+
entries = await fs12.promises.readdir(root);
|
|
4909
4968
|
} catch {
|
|
4910
4969
|
return;
|
|
4911
4970
|
}
|
|
4912
4971
|
let swept = 0;
|
|
4913
4972
|
for (const sessionIdDir of entries) {
|
|
4914
|
-
const sessionPath =
|
|
4973
|
+
const sessionPath = path15.join(root, sessionIdDir);
|
|
4915
4974
|
let stepDirs;
|
|
4916
4975
|
try {
|
|
4917
|
-
stepDirs = await
|
|
4976
|
+
stepDirs = await fs12.promises.readdir(sessionPath);
|
|
4918
4977
|
} catch {
|
|
4919
4978
|
continue;
|
|
4920
4979
|
}
|
|
4921
4980
|
for (const stepDir of stepDirs) {
|
|
4922
|
-
const wtPath =
|
|
4981
|
+
const wtPath = path15.join(sessionPath, stepDir);
|
|
4923
4982
|
try {
|
|
4924
4983
|
await runMainGit(["worktree", "remove", "--force", wtPath]);
|
|
4925
4984
|
} catch {
|
|
4926
|
-
await
|
|
4985
|
+
await fs12.promises.rm(wtPath, { recursive: true, force: true }).catch(() => {
|
|
4927
4986
|
});
|
|
4928
4987
|
}
|
|
4929
4988
|
swept++;
|
|
4930
4989
|
}
|
|
4931
|
-
await
|
|
4990
|
+
await fs12.promises.rm(sessionPath, { recursive: true, force: true }).catch(() => {
|
|
4932
4991
|
});
|
|
4933
4992
|
}
|
|
4934
4993
|
if (swept > 0) {
|
|
@@ -5196,7 +5255,7 @@ var init_workflow = __esm({
|
|
|
5196
5255
|
|
|
5197
5256
|
// ../core/src/tool/tsHost.ts
|
|
5198
5257
|
import fsSync3 from "fs";
|
|
5199
|
-
import
|
|
5258
|
+
import path16 from "path";
|
|
5200
5259
|
var _ts, _tsTried, getTs, buildDefaultOptions, findTsConfigBounded, resolveTsConfig, createProjectHost, lsCache, getLanguageService, realpathNative, posToLineCol, SUPPORTED_SOURCE_EXTS, checkSupportedSourceExt, lineColToPos;
|
|
5201
5260
|
var init_tsHost = __esm({
|
|
5202
5261
|
"../core/src/tool/tsHost.ts"() {
|
|
@@ -5229,16 +5288,16 @@ var init_tsHost = __esm({
|
|
|
5229
5288
|
strict: false
|
|
5230
5289
|
});
|
|
5231
5290
|
findTsConfigBounded = (ts, absPath) => {
|
|
5232
|
-
const root =
|
|
5233
|
-
let dir =
|
|
5291
|
+
const root = path16.resolve(getContainingRoot(absPath));
|
|
5292
|
+
let dir = path16.dirname(absPath);
|
|
5234
5293
|
while (true) {
|
|
5235
|
-
const candidate =
|
|
5294
|
+
const candidate = path16.join(dir, "tsconfig.json");
|
|
5236
5295
|
try {
|
|
5237
5296
|
if (fsSync3.existsSync(candidate)) return candidate;
|
|
5238
5297
|
} catch {
|
|
5239
5298
|
}
|
|
5240
|
-
if (
|
|
5241
|
-
const parent =
|
|
5299
|
+
if (path16.resolve(dir) === root) break;
|
|
5300
|
+
const parent = path16.dirname(dir);
|
|
5242
5301
|
if (parent === dir) break;
|
|
5243
5302
|
dir = parent;
|
|
5244
5303
|
}
|
|
@@ -5249,7 +5308,7 @@ var init_tsHost = __esm({
|
|
|
5249
5308
|
if (!tsConfigPath) {
|
|
5250
5309
|
return { options: buildDefaultOptions(ts), fileNames: [], projectRoot: getContainingRoot(absPath) };
|
|
5251
5310
|
}
|
|
5252
|
-
const basePath =
|
|
5311
|
+
const basePath = path16.dirname(tsConfigPath);
|
|
5253
5312
|
const raw = ts.readConfigFile(tsConfigPath, ts.sys.readFile);
|
|
5254
5313
|
if (raw.error) return { options: buildDefaultOptions(ts), fileNames: [], projectRoot: basePath };
|
|
5255
5314
|
const parsed = ts.parseJsonConfigFileContent(raw.config, ts.sys, basePath);
|
|
@@ -5260,7 +5319,7 @@ var init_tsHost = __esm({
|
|
|
5260
5319
|
const roots = /* @__PURE__ */ new Set();
|
|
5261
5320
|
const caseSensitive = ts.sys.useCaseSensitiveFileNames;
|
|
5262
5321
|
const canonical = (f) => caseSensitive ? f : f.toLowerCase();
|
|
5263
|
-
const keyOf = (f) => canonical(
|
|
5322
|
+
const keyOf = (f) => canonical(path16.resolve(f)).replace(/\\/g, "/");
|
|
5264
5323
|
rootFileNames.forEach((f) => roots.add(keyOf(f)));
|
|
5265
5324
|
const fresh = (fileName) => {
|
|
5266
5325
|
const key = keyOf(fileName);
|
|
@@ -5345,7 +5404,7 @@ var init_tsHost = __esm({
|
|
|
5345
5404
|
};
|
|
5346
5405
|
SUPPORTED_SOURCE_EXTS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
5347
5406
|
checkSupportedSourceExt = (displayPath) => {
|
|
5348
|
-
const ext =
|
|
5407
|
+
const ext = path16.extname(displayPath).toLowerCase();
|
|
5349
5408
|
if (SUPPORTED_SOURCE_EXTS.has(ext)) return null;
|
|
5350
5409
|
return `\u274C [\u6587\u4EF6\u7C7B\u578B\u4E0D\u652F\u6301]\uFF1A[${displayPath}] \u7684\u6269\u5C55\u540D ${ext || "(\u65E0)"} \u4E0D\u5728 TS \u5F15\u64CE\u652F\u6301\u8303\u56F4\uFF08\u4EC5 .ts/.tsx/.js/.jsx/.mjs/.cjs\uFF09\u3002\u8BF7\u6539\u7528 read_file/grep \u67E5\u770B\u5185\u5BB9\uFF1B\u7F16\u8BD1/\u7C7B\u578B\u7C7B\u9A8C\u8BC1\u7528 run_command \u8DD1\u5BF9\u5E94\u8BED\u8A00\u5DE5\u5177\u94FE\uFF08\u5982 mvn compile / tsc --noEmit\uFF09\u3002`;
|
|
5351
5410
|
};
|
|
@@ -5354,8 +5413,8 @@ var init_tsHost = __esm({
|
|
|
5354
5413
|
});
|
|
5355
5414
|
|
|
5356
5415
|
// ../core/src/tool/registry/fs.ts
|
|
5357
|
-
import
|
|
5358
|
-
import
|
|
5416
|
+
import fs13 from "fs/promises";
|
|
5417
|
+
import path17 from "path";
|
|
5359
5418
|
import { createReadStream } from "fs";
|
|
5360
5419
|
import * as readline from "readline";
|
|
5361
5420
|
var isSensitiveReadTarget, stripReadFileLineNumbers, maskSecretsInContent, makeTmpPath, ATOMIC_TMP_RE, sweepStaleAtomicTmp, assertReadable, stripEdgeBlankLines, matchLineBlockWith, diagnoseOldStr, reindentToBase, alignIndentsByAnchor, applyOneEditToContent, fsTools;
|
|
@@ -5399,7 +5458,7 @@ var init_fs = __esm({
|
|
|
5399
5458
|
return lines.map((l) => l.length === 0 ? l : l.replace(re, "")).join("\n");
|
|
5400
5459
|
};
|
|
5401
5460
|
maskSecretsInContent = (_args, output) => {
|
|
5402
|
-
return output.replace(/((?:api[_-]?key|secret|password|passwd|token|authorization|auth[_-]?token|access[_-]?key|secret[_-]?key|private[_-]?key)\s*[:=]\s*['"]
|
|
5461
|
+
return output.replace(/((?:api[_-]?key|secret|password|passwd|token|authorization|auth[_-]?token|access[_-]?key|secret[_-]?key|private[_-]?key)\s*[:=]\s*)(['"])[A-Za-z0-9_\-+/=.]{8,}\2/gi, "$1$2[MASKED_SECRET]$2").replace(/((?:authorization|auth[_-]?token)\s*[:=]\s*Bearer\s+)[A-Za-z0-9_\-+/=.]{8,}/gi, "$1[MASKED_SECRET]").replace(/-----BEGIN [A-Z ]+PRIVATE KEY-----[\s\S]*?-----END [A-Z ]+PRIVATE KEY-----/g, "[MASKED_SECRET (private key block)]");
|
|
5403
5462
|
};
|
|
5404
5463
|
makeTmpPath = (absPath) => `${absPath}.${Date.now()}.${Math.random().toString(36).slice(2, 7)}.tmp`;
|
|
5405
5464
|
ATOMIC_TMP_RE = /\.\d+\.[a-z0-9]{1,12}\.tmp$/i;
|
|
@@ -5411,21 +5470,21 @@ var init_fs = __esm({
|
|
|
5411
5470
|
const walk = async (dir) => {
|
|
5412
5471
|
let entries;
|
|
5413
5472
|
try {
|
|
5414
|
-
entries = await
|
|
5473
|
+
entries = await fs13.readdir(dir, { withFileTypes: true });
|
|
5415
5474
|
} catch {
|
|
5416
5475
|
return;
|
|
5417
5476
|
}
|
|
5418
5477
|
for (const e of entries) {
|
|
5419
|
-
const full =
|
|
5478
|
+
const full = path17.join(dir, e.name);
|
|
5420
5479
|
if (e.isDirectory()) {
|
|
5421
5480
|
if (!skipDirs.has(e.name)) await walk(full);
|
|
5422
5481
|
continue;
|
|
5423
5482
|
}
|
|
5424
5483
|
if (!e.isFile() || !ATOMIC_TMP_RE.test(e.name)) continue;
|
|
5425
5484
|
try {
|
|
5426
|
-
const st = await
|
|
5485
|
+
const st = await fs13.stat(full);
|
|
5427
5486
|
if (st.mtimeMs > cutoff) continue;
|
|
5428
|
-
await
|
|
5487
|
+
await fs13.unlink(full);
|
|
5429
5488
|
removed++;
|
|
5430
5489
|
} catch {
|
|
5431
5490
|
}
|
|
@@ -5687,11 +5746,11 @@ ${formattedCode}${hasMore ? `
|
|
|
5687
5746
|
await initializeWorkspaceIgnore();
|
|
5688
5747
|
const buildTreeText = async (currentPath, currentDepth, prefix = "") => {
|
|
5689
5748
|
if (currentDepth > maxDepth || hitScanLimit) return "";
|
|
5690
|
-
const entries = await
|
|
5749
|
+
const entries = await fs13.readdir(currentPath, { withFileTypes: true });
|
|
5691
5750
|
const validEntries = entries.filter((entry) => {
|
|
5692
5751
|
if (entry.isSymbolicLink()) return false;
|
|
5693
|
-
const fullPath =
|
|
5694
|
-
const relPath =
|
|
5752
|
+
const fullPath = path17.join(currentPath, entry.name);
|
|
5753
|
+
const relPath = path17.relative(getActiveWorkspaceRoot(), fullPath).replace(/\\/g, "/");
|
|
5695
5754
|
return !checkIsPathIgnored(entry.isDirectory() ? `${relPath}/` : relPath);
|
|
5696
5755
|
});
|
|
5697
5756
|
let output = "";
|
|
@@ -5710,7 +5769,7 @@ ${formattedCode}${hasMore ? `
|
|
|
5710
5769
|
`;
|
|
5711
5770
|
if (entry.isDirectory()) {
|
|
5712
5771
|
const nextPrefix = prefix + (isLast ? " " : "\u2502 ");
|
|
5713
|
-
const fullPath =
|
|
5772
|
+
const fullPath = path17.join(currentPath, entry.name);
|
|
5714
5773
|
const subTree = await buildTreeText(fullPath, currentDepth + 1, nextPrefix);
|
|
5715
5774
|
output += subTree;
|
|
5716
5775
|
}
|
|
@@ -5774,7 +5833,7 @@ ${patches}`;
|
|
|
5774
5833
|
return `\u274C [\u53C2\u6570\u7F3A\u5931]\uFF1A\u8BF7\u4F20\u5165 edits \u6570\u7EC4\uFF08\u6BCF\u6761\u542B old_str/new_str\uFF09\u4E00\u6B21\u5B8C\u6210\u591A\u5904\u4FEE\u6539\uFF0C\u6216\u9876\u5C42 old_str + new_str \u4FEE\u6539\u5355\u5904\u3002old_str \u4E0D\u80FD\u4E3A\u7A7A\u3002`;
|
|
5775
5834
|
}
|
|
5776
5835
|
const absPath = resolveSafePath(args.path);
|
|
5777
|
-
const rawContent = await
|
|
5836
|
+
const rawContent = await fs13.readFile(absPath, "utf-8");
|
|
5778
5837
|
const isCRLF = rawContent.includes("\r\n");
|
|
5779
5838
|
let content = rawContent.replace(/\r\n/g, "\n");
|
|
5780
5839
|
const summaries = [];
|
|
@@ -5787,7 +5846,7 @@ ${patches}`;
|
|
|
5787
5846
|
summaries.push(editList.length === 1 ? r.summary : ` ${i + 1}. ${r.summary}`);
|
|
5788
5847
|
}
|
|
5789
5848
|
assertWithinWorkspace(absPath);
|
|
5790
|
-
await
|
|
5849
|
+
await fs13.writeFile(absPath, isCRLF ? content.replace(/\n/g, "\r\n") : content, "utf-8");
|
|
5791
5850
|
return editList.length === 1 ? `\u2705 [\u4EE3\u7801\u4FEE\u8865\u6210\u529F]\uFF1A\u6587\u4EF6 [${args.path}] ${summaries[0]}` : `\u2705 [\u4EE3\u7801\u4FEE\u8865\u6210\u529F]\uFF1A\u6587\u4EF6 [${args.path}] \u5DF2\u6309\u5E8F\u5B8C\u6210 ${editList.length} \u5904\u4FEE\u6539\uFF08\u5355\u6B21\u539F\u5B50\u5199\u5165\uFF09\uFF1A
|
|
5792
5851
|
${summaries.join("\n")}`;
|
|
5793
5852
|
} catch (error) {
|
|
@@ -5817,24 +5876,24 @@ ${summaries.join("\n")}`;
|
|
|
5817
5876
|
try {
|
|
5818
5877
|
const absPath = resolveSafePath(args.path);
|
|
5819
5878
|
try {
|
|
5820
|
-
await
|
|
5879
|
+
await fs13.access(absPath);
|
|
5821
5880
|
return `\u274C [\u521B\u5EFA\u5931\u8D25]\uFF1A\u6587\u4EF6 [${args.path}] \u5DF2\u5B58\u5728\u3002create_file \u4EC5\u7528\u4E8E\u65B0\u5EFA\u6587\u4EF6\uFF1B\u5982\u9700\u4FEE\u6539\u8BF7\u7528 edit_file\uFF0C\u5982\u9700\u8986\u76D6\u8BF7\u7528 write_file\u3002`;
|
|
5822
5881
|
} catch (e) {
|
|
5823
5882
|
if (e?.code !== "ENOENT") throw e;
|
|
5824
5883
|
}
|
|
5825
5884
|
const content = args.content ?? "";
|
|
5826
5885
|
assertWithinWorkspace(absPath);
|
|
5827
|
-
await
|
|
5886
|
+
await fs13.mkdir(path17.dirname(absPath), { recursive: true });
|
|
5828
5887
|
tmpPath = makeTmpPath(absPath);
|
|
5829
|
-
await
|
|
5830
|
-
await
|
|
5888
|
+
await fs13.writeFile(tmpPath, content, "utf-8");
|
|
5889
|
+
await fs13.rename(tmpPath, absPath);
|
|
5831
5890
|
return `\u2705 [\u521B\u5EFA\u6210\u529F]\uFF1A\u65B0\u6587\u4EF6 [${args.path}] \u5DF2\u521B\u5EFA\uFF0C\u5199\u5165 ${content.length} \u5B57\u7B26\u3002`;
|
|
5832
5891
|
} catch (error) {
|
|
5833
5892
|
return `\u64CD\u4F5C\u5931\u8D25: ${error.message}`;
|
|
5834
5893
|
} finally {
|
|
5835
5894
|
if (tmpPath) {
|
|
5836
5895
|
try {
|
|
5837
|
-
await
|
|
5896
|
+
await fs13.unlink(tmpPath);
|
|
5838
5897
|
} catch {
|
|
5839
5898
|
}
|
|
5840
5899
|
}
|
|
@@ -5863,7 +5922,7 @@ ${summaries.join("\n")}`;
|
|
|
5863
5922
|
}
|
|
5864
5923
|
let rel = "";
|
|
5865
5924
|
try {
|
|
5866
|
-
rel =
|
|
5925
|
+
rel = path17.relative(getActiveWorkspaceRoot(), resolveSafePath(cleanPath));
|
|
5867
5926
|
} catch {
|
|
5868
5927
|
}
|
|
5869
5928
|
if (rel === "" || rel === "src") {
|
|
@@ -5871,7 +5930,7 @@ ${summaries.join("\n")}`;
|
|
|
5871
5930
|
}
|
|
5872
5931
|
let label = "\u6587\u4EF6\u6216\u76EE\u5F55";
|
|
5873
5932
|
try {
|
|
5874
|
-
const stat = await
|
|
5933
|
+
const stat = await fs13.stat(resolveSafePath(cleanPath));
|
|
5875
5934
|
label = stat.isDirectory() ? "\u4E00\u6574\u4E2A\u6587\u4EF6\u5939\u76EE\u5F55" : "\u7EAF\u7269\u7406\u6587\u4EF6";
|
|
5876
5935
|
} catch {
|
|
5877
5936
|
}
|
|
@@ -5884,22 +5943,22 @@ ${summaries.join("\n")}`;
|
|
|
5884
5943
|
return `\u274C [\u5B89\u5168\u7194\u65AD]\uFF1A\u7981\u6B62\u901A\u8FC7\u672C\u5DE5\u5177\u76F4\u63A5\u6467\u6BC1\u9879\u76EE\u6839\u76EE\u5F55\u6216\u4F20\u5165\u7A7A\u8DEF\u5F84\uFF01`;
|
|
5885
5944
|
}
|
|
5886
5945
|
const absPath = resolveSafePath(cleanPath);
|
|
5887
|
-
const rel =
|
|
5888
|
-
if (!rel || rel === "" || rel === "src" || rel.startsWith("..") ||
|
|
5946
|
+
const rel = path17.relative(getActiveWorkspaceRoot(), absPath);
|
|
5947
|
+
if (!rel || rel === "" || rel === "src" || rel.startsWith("..") || path17.isAbsolute(rel)) {
|
|
5889
5948
|
return `\u274C [\u5B89\u5168\u7194\u65AD]\uFF1A\u62D2\u7EDD\u9500\u6BC1\u5DE5\u4F5C\u533A\u6839\u76EE\u5F55 / src \u6E90\u7801\u6839 / \u8D8A\u754C\u8DEF\u5F84 [${cleanPath}]\uFF01`;
|
|
5890
5949
|
}
|
|
5891
5950
|
let stat;
|
|
5892
5951
|
try {
|
|
5893
|
-
stat = await
|
|
5952
|
+
stat = await fs13.stat(absPath);
|
|
5894
5953
|
} catch {
|
|
5895
5954
|
return `\u274C [\u9500\u6BC1\u5931\u8D25]\uFF1A\u5728\u5DE5\u4F5C\u533A\u5185\u672A\u627E\u5230\u6307\u5B9A\u7684\u8DEF\u5F84 [${cleanPath}]\u3002`;
|
|
5896
5955
|
}
|
|
5897
5956
|
const isDirectory = stat.isDirectory();
|
|
5898
5957
|
assertWithinWorkspace(absPath);
|
|
5899
5958
|
if (isDirectory) {
|
|
5900
|
-
await
|
|
5959
|
+
await fs13.rm(absPath, { recursive: true, force: true });
|
|
5901
5960
|
} else {
|
|
5902
|
-
await
|
|
5961
|
+
await fs13.unlink(absPath);
|
|
5903
5962
|
}
|
|
5904
5963
|
const targetTypeLabel = isDirectory ? "\u4E00\u6574\u4E2A\u6587\u4EF6\u5939\u76EE\u5F55" : "\u7EAF\u7269\u7406\u6587\u4EF6";
|
|
5905
5964
|
return `\u2705 [\u8DEF\u5F84\u9500\u6BC1\u6210\u529F]\uFF1A\u5DF2\u6210\u529F\u6C38\u4E45\u9500\u6BC1${targetTypeLabel} [${cleanPath}]\u3002`;
|
|
@@ -5930,15 +5989,15 @@ ${summaries.join("\n")}`;
|
|
|
5930
5989
|
try {
|
|
5931
5990
|
const absPath = resolveSafePath(args.path);
|
|
5932
5991
|
assertWithinWorkspace(absPath);
|
|
5933
|
-
await
|
|
5992
|
+
await fs13.mkdir(path17.dirname(absPath), { recursive: true });
|
|
5934
5993
|
tmpPath = makeTmpPath(absPath);
|
|
5935
|
-
await
|
|
5936
|
-
await
|
|
5994
|
+
await fs13.writeFile(tmpPath, args.content, "utf-8");
|
|
5995
|
+
await fs13.rename(tmpPath, absPath);
|
|
5937
5996
|
return `\u2705 [\u6587\u4EF6\u5199\u5165\u6210\u529F]\uFF1A\u5DF2\u5168\u91CF\u5199\u5165 [${args.path}]\uFF08${args.content.length} \u5B57\u7B26\uFF09\u3002`;
|
|
5938
5997
|
} catch (error) {
|
|
5939
5998
|
if (tmpPath) {
|
|
5940
5999
|
try {
|
|
5941
|
-
await
|
|
6000
|
+
await fs13.unlink(tmpPath);
|
|
5942
6001
|
} catch {
|
|
5943
6002
|
}
|
|
5944
6003
|
}
|
|
@@ -5969,11 +6028,11 @@ ${summaries.join("\n")}`;
|
|
|
5969
6028
|
if (readBlock) return readBlock;
|
|
5970
6029
|
const extBlock = checkSupportedSourceExt(args.path);
|
|
5971
6030
|
if (extBlock) return extBlock;
|
|
5972
|
-
const statForSize = await
|
|
6031
|
+
const statForSize = await fs13.stat(absPath);
|
|
5973
6032
|
if (statForSize.size > 1024 * 1024) {
|
|
5974
6033
|
return `\u26A0\uFE0F [\u6587\u4EF6\u8FC7\u5927]\uFF1A[${args.path}] \u7EA6 ${Math.round(statForSize.size / 1024)}KB\uFF0C\u8D85\u8FC7\u7B26\u53F7\u5927\u7EB2\u5206\u6790\u7684 1MB \u4E0A\u9650\uFF08\u9632\u5168\u91CF readFile + AST \u9A7B\u7559\u5403\u5185\u5B58\uFF09\u3002\u8BF7\u6539\u7528 read_file \u5206\u7247\u67E5\u770B\uFF0C\u6216\u7F29\u5C0F\u76EE\u6807\u6587\u4EF6\u3002`;
|
|
5975
6034
|
}
|
|
5976
|
-
const fileContent = await
|
|
6035
|
+
const fileContent = await fs13.readFile(absPath, "utf-8");
|
|
5977
6036
|
const TS = await getTs();
|
|
5978
6037
|
if (!TS) {
|
|
5979
6038
|
return `\u26A0\uFE0F [\u7B26\u53F7\u5927\u7EB2\u4E0D\u53EF\u7528]\uFF1Atypescript \u6A21\u5757\u672A\u5B89\u88C5\uFF08CLI \u53D1\u5E03\u7248\u672A\u5185\u8054\uFF09\u3002\u8BF7\u6539\u7528 read_file \u67E5\u770B\u6587\u4EF6\u5185\u5BB9\u3002`;
|
|
@@ -6055,19 +6114,19 @@ ${summaries.join("\n")}`;
|
|
|
6055
6114
|
const srcAbs = resolveSafePath(args.source);
|
|
6056
6115
|
const dstAbs = resolveSafePath(args.destination);
|
|
6057
6116
|
try {
|
|
6058
|
-
await
|
|
6117
|
+
await fs13.access(srcAbs);
|
|
6059
6118
|
} catch {
|
|
6060
6119
|
return `\u274C [\u79FB\u52A8\u5931\u8D25]\uFF1A\u6E90\u8DEF\u5F84 [${args.source}] \u4E0D\u5B58\u5728\u3002`;
|
|
6061
6120
|
}
|
|
6062
6121
|
try {
|
|
6063
|
-
await
|
|
6122
|
+
await fs13.access(dstAbs);
|
|
6064
6123
|
return `\u274C [\u79FB\u52A8\u5931\u8D25]\uFF1A\u76EE\u6807 [${args.destination}] \u5DF2\u5B58\u5728\u3002\u5982\u9700\u8986\u76D6\u8BF7\u5148 delete_path \u518D move_file\u3002`;
|
|
6065
6124
|
} catch {
|
|
6066
6125
|
}
|
|
6067
6126
|
assertWithinWorkspace(srcAbs);
|
|
6068
6127
|
assertWithinWorkspace(dstAbs);
|
|
6069
|
-
await
|
|
6070
|
-
await
|
|
6128
|
+
await fs13.mkdir(path17.dirname(dstAbs), { recursive: true });
|
|
6129
|
+
await fs13.rename(srcAbs, dstAbs);
|
|
6071
6130
|
return `\u2705 [\u79FB\u52A8\u6210\u529F]\uFF1A[${args.source}] \u2192 [${args.destination}]\u3002`;
|
|
6072
6131
|
} catch (error) {
|
|
6073
6132
|
return `\u64CD\u4F5C\u5931\u8D25: ${error.message}`;
|
|
@@ -6081,8 +6140,8 @@ ${summaries.join("\n")}`;
|
|
|
6081
6140
|
|
|
6082
6141
|
// ../core/src/tool/registry/search.ts
|
|
6083
6142
|
import { rgPath } from "vscode-ripgrep";
|
|
6084
|
-
import
|
|
6085
|
-
import
|
|
6143
|
+
import path18 from "path";
|
|
6144
|
+
import fs14 from "fs/promises";
|
|
6086
6145
|
function escapeRegExp(string) {
|
|
6087
6146
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6088
6147
|
}
|
|
@@ -6124,10 +6183,10 @@ var init_search = __esm({
|
|
|
6124
6183
|
const resolveSearchRoot = () => {
|
|
6125
6184
|
if (!args.path) return ctx?.cwd ?? getActiveWorkspaceRoot();
|
|
6126
6185
|
const p = args.path.trim();
|
|
6127
|
-
const looksLikeBareName = !
|
|
6186
|
+
const looksLikeBareName = !path18.isAbsolute(p) && !p.includes("/") && !p.includes("\\");
|
|
6128
6187
|
if (looksLikeBareName) {
|
|
6129
6188
|
const hit = getAllowedWorkspaceRoots().find((r) => {
|
|
6130
|
-
const bn =
|
|
6189
|
+
const bn = path18.basename(r);
|
|
6131
6190
|
return bn === p || bn.toLowerCase() === p.toLowerCase();
|
|
6132
6191
|
});
|
|
6133
6192
|
if (hit) return hit;
|
|
@@ -6216,7 +6275,7 @@ var init_search = __esm({
|
|
|
6216
6275
|
const GUIDE_CANDIDATES = ["CLAUDE.md", "AGENTS.md", "AGENT.md"];
|
|
6217
6276
|
for (const name of GUIDE_CANDIDATES) {
|
|
6218
6277
|
try {
|
|
6219
|
-
const content = await
|
|
6278
|
+
const content = await fs14.readFile(path18.join(getActiveWorkspaceRoot(), name), "utf-8");
|
|
6220
6279
|
return `[Project Guide via ${name}]
|
|
6221
6280
|
|
|
6222
6281
|
${content}`;
|
|
@@ -6503,8 +6562,8 @@ ${AUTO_BG_NOTICE}
|
|
|
6503
6562
|
});
|
|
6504
6563
|
|
|
6505
6564
|
// ../core/src/tool/registry/glob.ts
|
|
6506
|
-
import
|
|
6507
|
-
import
|
|
6565
|
+
import fs15 from "fs/promises";
|
|
6566
|
+
import path19 from "path";
|
|
6508
6567
|
var findMatchingBrace, splitTopLevel, globToRegex2, globTools;
|
|
6509
6568
|
var init_glob = __esm({
|
|
6510
6569
|
"../core/src/tool/registry/glob.ts"() {
|
|
@@ -6608,18 +6667,18 @@ var init_glob = __esm({
|
|
|
6608
6667
|
const MAX_SCAN_LIMIT = 1e4;
|
|
6609
6668
|
const scan = async (dir) => {
|
|
6610
6669
|
if (scannedCount > MAX_SCAN_LIMIT) return;
|
|
6611
|
-
const entries = await
|
|
6670
|
+
const entries = await fs15.readdir(dir, { withFileTypes: true });
|
|
6612
6671
|
const validEntries = entries.filter((e) => {
|
|
6613
|
-
const full =
|
|
6614
|
-
const rel =
|
|
6672
|
+
const full = path19.join(dir, e.name);
|
|
6673
|
+
const rel = path19.relative(activeRoot, full).replace(/\\/g, "/");
|
|
6615
6674
|
return !checkIsPathIgnored(e.isDirectory() ? `${rel}/` : rel);
|
|
6616
6675
|
});
|
|
6617
6676
|
for (const e of validEntries) {
|
|
6618
6677
|
scannedCount++;
|
|
6619
6678
|
if (scannedCount > MAX_SCAN_LIMIT) break;
|
|
6620
6679
|
if (e.isSymbolicLink()) continue;
|
|
6621
|
-
const full =
|
|
6622
|
-
const rel =
|
|
6680
|
+
const full = path19.join(dir, e.name);
|
|
6681
|
+
const rel = path19.relative(activeRoot, full).replace(/\\/g, "/");
|
|
6623
6682
|
if (e.isDirectory()) {
|
|
6624
6683
|
if (cleanPattern.endsWith("/") && re.test(`${rel}/`)) {
|
|
6625
6684
|
hits.push(`${rel}/`);
|
|
@@ -6835,8 +6894,8 @@ ${summary}`;
|
|
|
6835
6894
|
});
|
|
6836
6895
|
|
|
6837
6896
|
// ../core/src/tool/registry/inspect_dependencies.ts
|
|
6838
|
-
import * as
|
|
6839
|
-
import * as
|
|
6897
|
+
import * as fs16 from "fs/promises";
|
|
6898
|
+
import * as path20 from "path";
|
|
6840
6899
|
var dependencyTools;
|
|
6841
6900
|
var init_inspect_dependencies = __esm({
|
|
6842
6901
|
"../core/src/tool/registry/inspect_dependencies.ts"() {
|
|
@@ -6857,8 +6916,8 @@ var init_inspect_dependencies = __esm({
|
|
|
6857
6916
|
isSync: true,
|
|
6858
6917
|
async execute() {
|
|
6859
6918
|
try {
|
|
6860
|
-
const pjsPath =
|
|
6861
|
-
const raw = await
|
|
6919
|
+
const pjsPath = path20.join(getActiveWorkspaceRoot(), "package.json");
|
|
6920
|
+
const raw = await fs16.readFile(pjsPath, "utf-8");
|
|
6862
6921
|
const pjs = JSON.parse(raw);
|
|
6863
6922
|
const result = {
|
|
6864
6923
|
dependencies: pjs.dependencies || {},
|
|
@@ -7500,8 +7559,8 @@ var init_http = __esm({
|
|
|
7500
7559
|
});
|
|
7501
7560
|
|
|
7502
7561
|
// ../core/src/tool/registry/typescript.ts
|
|
7503
|
-
import
|
|
7504
|
-
import
|
|
7562
|
+
import fs17 from "fs/promises";
|
|
7563
|
+
import path21 from "path";
|
|
7505
7564
|
var MAX_FILE_BYTES, toDisplayPath, isLibFile, precheck, MAX_DIAG_ENTRIES, MAX_DIAG_FILES, MAX_REF_ENTRIES, REF_SNIPPET_MAX, diagnoseOneFile, typescriptTools;
|
|
7506
7565
|
var init_typescript = __esm({
|
|
7507
7566
|
"../core/src/tool/registry/typescript.ts"() {
|
|
@@ -7512,8 +7571,8 @@ var init_typescript = __esm({
|
|
|
7512
7571
|
init_fs();
|
|
7513
7572
|
MAX_FILE_BYTES = 1024 * 1024;
|
|
7514
7573
|
toDisplayPath = (wsRoot, abs) => {
|
|
7515
|
-
const rel =
|
|
7516
|
-
if (rel && !rel.startsWith("..") && !
|
|
7574
|
+
const rel = path21.relative(wsRoot, abs);
|
|
7575
|
+
if (rel && !rel.startsWith("..") && !path21.isAbsolute(rel)) return rel.replace(/\\/g, "/");
|
|
7517
7576
|
return abs.replace(/\\/g, "/").split("/").slice(-3).join("/");
|
|
7518
7577
|
};
|
|
7519
7578
|
isLibFile = (abs) => /(?:^|\/)node_modules\//.test(abs.replace(/\\/g, "/")) || /\.d\.ts$/i.test(abs);
|
|
@@ -7522,7 +7581,7 @@ var init_typescript = __esm({
|
|
|
7522
7581
|
if (readBlock) return readBlock;
|
|
7523
7582
|
const extBlock = checkSupportedSourceExt(displayPath);
|
|
7524
7583
|
if (extBlock) return extBlock;
|
|
7525
|
-
const stat = await
|
|
7584
|
+
const stat = await fs17.stat(absPath);
|
|
7526
7585
|
if (stat.size > MAX_FILE_BYTES) {
|
|
7527
7586
|
return `\u26A0\uFE0F [\u6587\u4EF6\u8FC7\u5927]\uFF1A[${displayPath}] \u7EA6 ${Math.round(stat.size / 1024)}KB\uFF0C\u8D85\u8FC7 ${MAX_FILE_BYTES / 1024}KB \u4E0A\u9650\uFF08\u9632\u5168\u91CF type-check \u5403\u5185\u5B58\uFF09\u3002`;
|
|
7528
7587
|
}
|
|
@@ -7738,7 +7797,7 @@ ${out.join("\n")}`;
|
|
|
7738
7797
|
let lines = lineTextCache.get(abs);
|
|
7739
7798
|
if (!lines) {
|
|
7740
7799
|
try {
|
|
7741
|
-
lines = (await
|
|
7800
|
+
lines = (await fs17.readFile(abs, "utf-8")).split(/\r?\n/);
|
|
7742
7801
|
} catch {
|
|
7743
7802
|
lines = [];
|
|
7744
7803
|
}
|
|
@@ -7867,8 +7926,8 @@ var init_todo = __esm({
|
|
|
7867
7926
|
});
|
|
7868
7927
|
|
|
7869
7928
|
// ../core/src/observability/traceCalculate.ts
|
|
7870
|
-
import
|
|
7871
|
-
import
|
|
7929
|
+
import fs18 from "fs/promises";
|
|
7930
|
+
import path22 from "path";
|
|
7872
7931
|
var getDirBytes, getTodayDateString;
|
|
7873
7932
|
var init_traceCalculate = __esm({
|
|
7874
7933
|
"../core/src/observability/traceCalculate.ts"() {
|
|
@@ -7880,17 +7939,17 @@ var init_traceCalculate = __esm({
|
|
|
7880
7939
|
const cur = stack.pop();
|
|
7881
7940
|
let entries;
|
|
7882
7941
|
try {
|
|
7883
|
-
entries = await
|
|
7942
|
+
entries = await fs18.readdir(cur, { withFileTypes: true });
|
|
7884
7943
|
} catch {
|
|
7885
7944
|
continue;
|
|
7886
7945
|
}
|
|
7887
7946
|
for (const e of entries) {
|
|
7888
|
-
const p =
|
|
7947
|
+
const p = path22.join(cur, e.name);
|
|
7889
7948
|
if (e.isDirectory()) {
|
|
7890
7949
|
stack.push(p);
|
|
7891
7950
|
} else {
|
|
7892
7951
|
try {
|
|
7893
|
-
total += (await
|
|
7952
|
+
total += (await fs18.stat(p)).size;
|
|
7894
7953
|
} catch {
|
|
7895
7954
|
}
|
|
7896
7955
|
}
|
|
@@ -7909,8 +7968,8 @@ var init_traceCalculate = __esm({
|
|
|
7909
7968
|
});
|
|
7910
7969
|
|
|
7911
7970
|
// ../core/src/tool/undo/store.ts
|
|
7912
|
-
import
|
|
7913
|
-
import
|
|
7971
|
+
import path23 from "path";
|
|
7972
|
+
import fs19 from "fs/promises";
|
|
7914
7973
|
var getUndoRootPath, getUndoClockPath, getUndoDirPath, getUndoBackupRoot, ensureUndoDir, getUndoIndexPath;
|
|
7915
7974
|
var init_store2 = __esm({
|
|
7916
7975
|
"../core/src/tool/undo/store.ts"() {
|
|
@@ -7918,33 +7977,33 @@ var init_store2 = __esm({
|
|
|
7918
7977
|
init_config();
|
|
7919
7978
|
init_common();
|
|
7920
7979
|
init_traceCalculate();
|
|
7921
|
-
getUndoRootPath = () =>
|
|
7922
|
-
getUndoClockPath = () =>
|
|
7980
|
+
getUndoRootPath = () => path23.join(appConfig.dataDir, "undo");
|
|
7981
|
+
getUndoClockPath = () => path23.join(getUndoRootPath(), "undo-cleanup-clock.json");
|
|
7923
7982
|
getUndoDirPath = (mainSessionId) => {
|
|
7924
7983
|
const rootId = getFileName(mainSessionId);
|
|
7925
7984
|
assertSafeSessionId(rootId, "undoSessionId");
|
|
7926
|
-
return
|
|
7985
|
+
return path23.join(getUndoRootPath(), appConfig.userWorkspaceDir, rootId);
|
|
7927
7986
|
};
|
|
7928
|
-
getUndoBackupRoot = (mainSessionId) =>
|
|
7987
|
+
getUndoBackupRoot = (mainSessionId) => path23.join(getUndoDirPath(mainSessionId), "backups");
|
|
7929
7988
|
ensureUndoDir = async (mainSessionId) => {
|
|
7930
|
-
await
|
|
7989
|
+
await fs19.mkdir(getUndoDirPath(mainSessionId), { recursive: true, mode: 448 });
|
|
7931
7990
|
};
|
|
7932
7991
|
getUndoIndexPath = async (mainSessionId) => {
|
|
7933
7992
|
const rootId = getFileName(mainSessionId);
|
|
7934
7993
|
assertSafeSessionId(rootId, "undoSessionId");
|
|
7935
7994
|
const dir = getUndoDirPath(mainSessionId);
|
|
7936
|
-
await
|
|
7937
|
-
const files = await
|
|
7995
|
+
await fs19.mkdir(dir, { recursive: true, mode: 448 });
|
|
7996
|
+
const files = await fs19.readdir(dir);
|
|
7938
7997
|
const existedFile = files.find((f) => f.endsWith(`__${rootId}.jsonl`));
|
|
7939
7998
|
const fileName = existedFile ?? `undo-${getTodayDateString()}__${rootId}.jsonl`;
|
|
7940
|
-
return
|
|
7999
|
+
return path23.join(dir, fileName);
|
|
7941
8000
|
};
|
|
7942
8001
|
}
|
|
7943
8002
|
});
|
|
7944
8003
|
|
|
7945
8004
|
// ../core/src/tool/undo/index.ts
|
|
7946
|
-
import
|
|
7947
|
-
import
|
|
8005
|
+
import fs20 from "fs/promises";
|
|
8006
|
+
import path24 from "path";
|
|
7948
8007
|
var undoLocks, withUndoLock, appendUndoRecord, readUndoIndex, markRestored;
|
|
7949
8008
|
var init_undo = __esm({
|
|
7950
8009
|
"../core/src/tool/undo/index.ts"() {
|
|
@@ -7974,7 +8033,7 @@ var init_undo = __esm({
|
|
|
7974
8033
|
};
|
|
7975
8034
|
const p = await getUndoIndexPath(sessionId);
|
|
7976
8035
|
const line = JSON.stringify(enriched) + "\n";
|
|
7977
|
-
await
|
|
8036
|
+
await fs20.appendFile(p, line, { encoding: "utf-8", mode: 384 });
|
|
7978
8037
|
});
|
|
7979
8038
|
};
|
|
7980
8039
|
readUndoIndex = async (sessionId) => {
|
|
@@ -7986,7 +8045,7 @@ var init_undo = __esm({
|
|
|
7986
8045
|
}
|
|
7987
8046
|
let files;
|
|
7988
8047
|
try {
|
|
7989
|
-
files = await
|
|
8048
|
+
files = await fs20.readdir(dir);
|
|
7990
8049
|
} catch {
|
|
7991
8050
|
return [];
|
|
7992
8051
|
}
|
|
@@ -7994,7 +8053,7 @@ var init_undo = __esm({
|
|
|
7994
8053
|
for (const f of files) {
|
|
7995
8054
|
if (!f.startsWith("undo-") || !f.endsWith(".jsonl")) continue;
|
|
7996
8055
|
try {
|
|
7997
|
-
const raw = await
|
|
8056
|
+
const raw = await fs20.readFile(path24.join(dir, f), "utf-8");
|
|
7998
8057
|
for (const line of raw.split("\n")) {
|
|
7999
8058
|
const trimmed = line.trim();
|
|
8000
8059
|
if (!trimmed) continue;
|
|
@@ -8019,16 +8078,16 @@ var init_undo = __esm({
|
|
|
8019
8078
|
}
|
|
8020
8079
|
let files;
|
|
8021
8080
|
try {
|
|
8022
|
-
files = await
|
|
8081
|
+
files = await fs20.readdir(dir);
|
|
8023
8082
|
} catch {
|
|
8024
8083
|
return;
|
|
8025
8084
|
}
|
|
8026
8085
|
for (const f of files) {
|
|
8027
8086
|
if (!f.startsWith("undo-") || !f.endsWith(".jsonl")) continue;
|
|
8028
|
-
const fp =
|
|
8087
|
+
const fp = path24.join(dir, f);
|
|
8029
8088
|
let raw;
|
|
8030
8089
|
try {
|
|
8031
|
-
raw = await
|
|
8090
|
+
raw = await fs20.readFile(fp, "utf-8");
|
|
8032
8091
|
} catch {
|
|
8033
8092
|
continue;
|
|
8034
8093
|
}
|
|
@@ -8052,8 +8111,8 @@ var init_undo = __esm({
|
|
|
8052
8111
|
if (changed) {
|
|
8053
8112
|
const content = lines.join("\n").replace(/\n*$/, "\n");
|
|
8054
8113
|
const tmp = fp + ".tmp";
|
|
8055
|
-
await
|
|
8056
|
-
await
|
|
8114
|
+
await fs20.writeFile(tmp, content, { encoding: "utf-8", mode: 384 });
|
|
8115
|
+
await fs20.rename(tmp, fp);
|
|
8057
8116
|
}
|
|
8058
8117
|
}
|
|
8059
8118
|
});
|
|
@@ -8062,8 +8121,8 @@ var init_undo = __esm({
|
|
|
8062
8121
|
});
|
|
8063
8122
|
|
|
8064
8123
|
// ../core/src/tool/undo/cleanup.ts
|
|
8065
|
-
import
|
|
8066
|
-
import
|
|
8124
|
+
import fs21 from "fs/promises";
|
|
8125
|
+
import path25 from "path";
|
|
8067
8126
|
async function maybeCleanupAfterUndoAppend(_sessionId) {
|
|
8068
8127
|
if (cleanupInProgress) return;
|
|
8069
8128
|
cleanupInProgress = true;
|
|
@@ -8089,8 +8148,8 @@ async function maybeCleanupAfterUndoAppend(_sessionId) {
|
|
|
8089
8148
|
lastSizeCleanupAt = now;
|
|
8090
8149
|
diskLastCleanupAt = now;
|
|
8091
8150
|
const clockPath = getUndoClockPath();
|
|
8092
|
-
await
|
|
8093
|
-
await
|
|
8151
|
+
await fs21.mkdir(path25.dirname(clockPath), { recursive: true });
|
|
8152
|
+
await fs21.writeFile(clockPath, JSON.stringify({ lastCleanupAt: now, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), "utf-8");
|
|
8094
8153
|
if (deleted > 0) console.log(`\u2728 [Undo\u8FD0\u7EF4] \u5171\u9500\u6BC1 ${deleted} \u4E2A undo \u8D44\u4EA7\uFF08\u7D22\u5F15 + \u5B64\u513F\u5185\u5BB9\uFF09\uFF0C\u78C1\u76D8\u6C34\u4F4D\u56DE\u843D\u3002`);
|
|
8095
8154
|
} catch (e) {
|
|
8096
8155
|
console.warn("\u26A0\uFE0F [Undo\u8FD0\u7EF4] \u81EA\u52A8\u6E05\u7406\u5F02\u5E38\uFF0C\u5DF2\u8DF3\u8FC7:", e?.message ?? e);
|
|
@@ -8107,23 +8166,23 @@ async function cleanupOldUndoFiles() {
|
|
|
8107
8166
|
const now = Date.now();
|
|
8108
8167
|
let relativePaths;
|
|
8109
8168
|
try {
|
|
8110
|
-
relativePaths = await
|
|
8169
|
+
relativePaths = await fs21.readdir(dir, { recursive: true });
|
|
8111
8170
|
} catch {
|
|
8112
8171
|
return 0;
|
|
8113
8172
|
}
|
|
8114
8173
|
const re = /^undo-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
|
|
8115
8174
|
let deleted = 0;
|
|
8116
8175
|
for (const rp of relativePaths) {
|
|
8117
|
-
const fileName =
|
|
8176
|
+
const fileName = path25.basename(rp);
|
|
8118
8177
|
const m = fileName.match(re);
|
|
8119
8178
|
if (!m) continue;
|
|
8120
8179
|
const fileBornDay = /* @__PURE__ */ new Date(`${m[1]}T00:00:00`);
|
|
8121
8180
|
if (fileBornDay >= cutoff) continue;
|
|
8122
|
-
const fullPath =
|
|
8181
|
+
const fullPath = path25.join(dir, rp);
|
|
8123
8182
|
try {
|
|
8124
|
-
const st = await
|
|
8183
|
+
const st = await fs21.stat(fullPath);
|
|
8125
8184
|
if (now - st.mtimeMs < ACTIVE_GRACE_MS) continue;
|
|
8126
|
-
await
|
|
8185
|
+
await fs21.unlink(fullPath);
|
|
8127
8186
|
deleted += 1;
|
|
8128
8187
|
} catch {
|
|
8129
8188
|
}
|
|
@@ -8134,17 +8193,17 @@ async function evictOldestForSize(targetBytes) {
|
|
|
8134
8193
|
const dir = getUndoRootPath();
|
|
8135
8194
|
let relativePaths;
|
|
8136
8195
|
try {
|
|
8137
|
-
relativePaths = await
|
|
8196
|
+
relativePaths = await fs21.readdir(dir, { recursive: true });
|
|
8138
8197
|
} catch {
|
|
8139
8198
|
return 0;
|
|
8140
8199
|
}
|
|
8141
8200
|
const re = /^undo-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
|
|
8142
8201
|
const candidates = [];
|
|
8143
8202
|
for (const rp of relativePaths) {
|
|
8144
|
-
if (!re.test(
|
|
8203
|
+
if (!re.test(path25.basename(rp))) continue;
|
|
8145
8204
|
try {
|
|
8146
|
-
const st = await
|
|
8147
|
-
candidates.push({ mtime: st.mtimeMs, fullPath:
|
|
8205
|
+
const st = await fs21.stat(path25.join(dir, rp));
|
|
8206
|
+
candidates.push({ mtime: st.mtimeMs, fullPath: path25.join(dir, rp), size: st.size });
|
|
8148
8207
|
} catch {
|
|
8149
8208
|
}
|
|
8150
8209
|
}
|
|
@@ -8154,7 +8213,7 @@ async function evictOldestForSize(targetBytes) {
|
|
|
8154
8213
|
for (const c of candidates) {
|
|
8155
8214
|
if (totalBytes <= targetBytes) break;
|
|
8156
8215
|
try {
|
|
8157
|
-
await
|
|
8216
|
+
await fs21.unlink(c.fullPath);
|
|
8158
8217
|
totalBytes -= c.size;
|
|
8159
8218
|
deleted += 1;
|
|
8160
8219
|
} catch {
|
|
@@ -8168,38 +8227,38 @@ async function gcOrphanBackups() {
|
|
|
8168
8227
|
let deleted = 0;
|
|
8169
8228
|
let workspaces;
|
|
8170
8229
|
try {
|
|
8171
|
-
workspaces = await
|
|
8230
|
+
workspaces = await fs21.readdir(root);
|
|
8172
8231
|
} catch {
|
|
8173
8232
|
return 0;
|
|
8174
8233
|
}
|
|
8175
8234
|
for (const ws of workspaces) {
|
|
8176
|
-
const wsDir =
|
|
8235
|
+
const wsDir = path25.join(root, ws);
|
|
8177
8236
|
let stWs;
|
|
8178
8237
|
try {
|
|
8179
|
-
stWs = await
|
|
8238
|
+
stWs = await fs21.stat(wsDir);
|
|
8180
8239
|
} catch {
|
|
8181
8240
|
continue;
|
|
8182
8241
|
}
|
|
8183
8242
|
if (!stWs.isDirectory()) continue;
|
|
8184
8243
|
let sessions2;
|
|
8185
8244
|
try {
|
|
8186
|
-
sessions2 = await
|
|
8245
|
+
sessions2 = await fs21.readdir(wsDir);
|
|
8187
8246
|
} catch {
|
|
8188
8247
|
continue;
|
|
8189
8248
|
}
|
|
8190
8249
|
for (const sess of sessions2) {
|
|
8191
|
-
const sessDir =
|
|
8250
|
+
const sessDir = path25.join(wsDir, sess);
|
|
8192
8251
|
const liveIds = /* @__PURE__ */ new Set();
|
|
8193
8252
|
let files;
|
|
8194
8253
|
try {
|
|
8195
|
-
files = await
|
|
8254
|
+
files = await fs21.readdir(sessDir);
|
|
8196
8255
|
} catch {
|
|
8197
8256
|
continue;
|
|
8198
8257
|
}
|
|
8199
8258
|
for (const f of files) {
|
|
8200
8259
|
if (!f.startsWith("undo-") || !f.endsWith(".jsonl")) continue;
|
|
8201
8260
|
try {
|
|
8202
|
-
const raw = await
|
|
8261
|
+
const raw = await fs21.readFile(path25.join(sessDir, f), "utf-8");
|
|
8203
8262
|
for (const line of raw.split("\n")) {
|
|
8204
8263
|
const t = line.trim();
|
|
8205
8264
|
if (!t) continue;
|
|
@@ -8212,17 +8271,17 @@ async function gcOrphanBackups() {
|
|
|
8212
8271
|
} catch {
|
|
8213
8272
|
}
|
|
8214
8273
|
}
|
|
8215
|
-
const backupsDir =
|
|
8274
|
+
const backupsDir = path25.join(sessDir, "backups");
|
|
8216
8275
|
let undoDirs;
|
|
8217
8276
|
try {
|
|
8218
|
-
undoDirs = await
|
|
8277
|
+
undoDirs = await fs21.readdir(backupsDir);
|
|
8219
8278
|
} catch {
|
|
8220
8279
|
continue;
|
|
8221
8280
|
}
|
|
8222
8281
|
for (const ud of undoDirs) {
|
|
8223
8282
|
if (liveIds.has(ud)) continue;
|
|
8224
8283
|
try {
|
|
8225
|
-
await
|
|
8284
|
+
await fs21.rm(path25.join(backupsDir, ud), { recursive: true, force: true });
|
|
8226
8285
|
deleted += 1;
|
|
8227
8286
|
} catch {
|
|
8228
8287
|
}
|
|
@@ -8250,7 +8309,7 @@ var init_cleanup = __esm({
|
|
|
8250
8309
|
if (clockLoaded) return;
|
|
8251
8310
|
clockLoaded = true;
|
|
8252
8311
|
try {
|
|
8253
|
-
const rawClock = await
|
|
8312
|
+
const rawClock = await fs21.readFile(getUndoClockPath(), "utf-8");
|
|
8254
8313
|
diskLastCleanupAt = JSON.parse(rawClock).lastCleanupAt || 0;
|
|
8255
8314
|
} catch {
|
|
8256
8315
|
diskLastCleanupAt = 0;
|
|
@@ -8260,17 +8319,17 @@ var init_cleanup = __esm({
|
|
|
8260
8319
|
let total = 0;
|
|
8261
8320
|
let entries;
|
|
8262
8321
|
try {
|
|
8263
|
-
entries = await
|
|
8322
|
+
entries = await fs21.readdir(dir, { withFileTypes: true });
|
|
8264
8323
|
} catch {
|
|
8265
8324
|
return 0;
|
|
8266
8325
|
}
|
|
8267
8326
|
for (const e of entries) {
|
|
8268
|
-
const full =
|
|
8327
|
+
const full = path25.join(dir, e.name);
|
|
8269
8328
|
if (e.isDirectory()) {
|
|
8270
8329
|
total += await getDirBytesRecursive(full);
|
|
8271
8330
|
} else if (e.isFile()) {
|
|
8272
8331
|
try {
|
|
8273
|
-
total += (await
|
|
8332
|
+
total += (await fs21.stat(full)).size;
|
|
8274
8333
|
} catch {
|
|
8275
8334
|
}
|
|
8276
8335
|
}
|
|
@@ -8281,8 +8340,8 @@ var init_cleanup = __esm({
|
|
|
8281
8340
|
});
|
|
8282
8341
|
|
|
8283
8342
|
// ../core/src/tool/undo/backup.ts
|
|
8284
|
-
import
|
|
8285
|
-
import
|
|
8343
|
+
import fs22 from "fs/promises";
|
|
8344
|
+
import path26 from "path";
|
|
8286
8345
|
import crypto from "crypto";
|
|
8287
8346
|
async function beforeMutationBackup(toolName, args, toolCallId, sessionId) {
|
|
8288
8347
|
if (appConfig.undoEnabled === false) return null;
|
|
@@ -8297,7 +8356,7 @@ async function beforeMutationBackup(toolName, args, toolCallId, sessionId) {
|
|
|
8297
8356
|
}
|
|
8298
8357
|
await ensureUndoDir(sessionId);
|
|
8299
8358
|
const undoId = createUUID();
|
|
8300
|
-
const undoDir =
|
|
8359
|
+
const undoDir = path26.join(getUndoBackupRoot(sessionId), undoId);
|
|
8301
8360
|
const now = /* @__PURE__ */ new Date();
|
|
8302
8361
|
const common = {
|
|
8303
8362
|
undoId,
|
|
@@ -8332,7 +8391,7 @@ async function backupFileOverwrite(common, undoDir, args) {
|
|
|
8332
8391
|
const absPath = resolveSafePath(common.relativePath);
|
|
8333
8392
|
let exists = true;
|
|
8334
8393
|
try {
|
|
8335
|
-
await
|
|
8394
|
+
await fs22.access(absPath);
|
|
8336
8395
|
} catch {
|
|
8337
8396
|
exists = false;
|
|
8338
8397
|
}
|
|
@@ -8340,15 +8399,15 @@ async function backupFileOverwrite(common, undoDir, args) {
|
|
|
8340
8399
|
return { ...common, backupKind: "creation_marker", backupPath: "", fileSizeBefore: 0 };
|
|
8341
8400
|
}
|
|
8342
8401
|
assertWithinWorkspace(absPath);
|
|
8343
|
-
const fileStat = await
|
|
8402
|
+
const fileStat = await fs22.stat(absPath);
|
|
8344
8403
|
const maxPerOp = appConfig.undoMaxBytesPerOp ?? 100 * 1024 * 1024;
|
|
8345
8404
|
if (fileStat.size > maxPerOp) {
|
|
8346
8405
|
throw new Error(`\u6587\u4EF6 [${common.relativePath}] \u4F53\u79EF\u7EA6 ${fileStat.size} \u5B57\u8282\u8D85\u8FC7\u5355\u6B21\u5907\u4EFD\u4E0A\u9650 ${maxPerOp}\uFF0C\u5199\u5165\u5DF2\u963B\u65AD\uFF08\u9632\u5185\u5B58\u62D6\u57AE\uFF1B\u53EF\u8C03 undoMaxBytesPerOp\uFF09`);
|
|
8347
8406
|
}
|
|
8348
|
-
const content = await
|
|
8349
|
-
await
|
|
8350
|
-
const contentPath =
|
|
8351
|
-
await
|
|
8407
|
+
const content = await fs22.readFile(absPath);
|
|
8408
|
+
await fs22.mkdir(undoDir, { recursive: true, mode: 448 });
|
|
8409
|
+
const contentPath = path26.join(undoDir, "content");
|
|
8410
|
+
await fs22.writeFile(contentPath, content, { mode: 384 });
|
|
8352
8411
|
return {
|
|
8353
8412
|
...common,
|
|
8354
8413
|
backupKind: "file_content",
|
|
@@ -8367,9 +8426,9 @@ async function backupFileCreate(common) {
|
|
|
8367
8426
|
}
|
|
8368
8427
|
async function backupDelete(common, undoDir, relativePath) {
|
|
8369
8428
|
const absPath = resolveSafePath(relativePath);
|
|
8370
|
-
const st = await
|
|
8429
|
+
const st = await fs22.stat(absPath);
|
|
8371
8430
|
assertWithinWorkspace(absPath);
|
|
8372
|
-
await
|
|
8431
|
+
await fs22.mkdir(undoDir, { recursive: true, mode: 448 });
|
|
8373
8432
|
if (st.isDirectory()) {
|
|
8374
8433
|
const treeBytes = await getDirTreeBytes(absPath);
|
|
8375
8434
|
const maxPerOp2 = appConfig.undoMaxBytesPerOp ?? 100 * 1024 * 1024;
|
|
@@ -8384,15 +8443,15 @@ async function backupDelete(common, undoDir, relativePath) {
|
|
|
8384
8443
|
throw new Error(`\u76EE\u5F55 [${relativePath}] \u5185\u542B\u654F\u611F\u6587\u4EF6 ${sensitiveInTree.length} \u4E2A\uFF08\u5982 ${sensitiveInTree[0]}\uFF09\uFF0C\u6309\u7B56\u7565(undoBackupSensitive=deny)\u62D2\u7EDD\u5907\u4EFD\uFF0C\u5199\u5165\u5DF2\u963B\u65AD`);
|
|
8385
8444
|
}
|
|
8386
8445
|
}
|
|
8387
|
-
const treeDest =
|
|
8446
|
+
const treeDest = path26.join(undoDir, "tree");
|
|
8388
8447
|
const sensitiveSet = new Set(sensitiveInTree);
|
|
8389
|
-
await
|
|
8448
|
+
await fs22.cp(absPath, treeDest, {
|
|
8390
8449
|
recursive: true,
|
|
8391
8450
|
force: true,
|
|
8392
8451
|
preserveTimestamps: true,
|
|
8393
8452
|
filter: (src) => {
|
|
8394
8453
|
if (src === absPath) return true;
|
|
8395
|
-
const relWithin =
|
|
8454
|
+
const relWithin = path26.relative(absPath, src).replace(/\\/g, "/");
|
|
8396
8455
|
return !sensitiveSet.has(relWithin);
|
|
8397
8456
|
}
|
|
8398
8457
|
});
|
|
@@ -8408,9 +8467,9 @@ async function backupDelete(common, undoDir, relativePath) {
|
|
|
8408
8467
|
if (st.size > maxPerOp) {
|
|
8409
8468
|
throw new Error(`\u6587\u4EF6 [${relativePath}] \u4F53\u79EF\u7EA6 ${st.size} \u5B57\u8282\u8D85\u8FC7\u5355\u6B21\u5907\u4EFD\u4E0A\u9650 ${maxPerOp}\uFF0C\u5199\u5165\u5DF2\u963B\u65AD\uFF08\u9632\u5185\u5B58\u62D6\u57AE\uFF1B\u53EF\u8C03 undoMaxBytesPerOp\uFF09`);
|
|
8410
8469
|
}
|
|
8411
|
-
const content = await
|
|
8412
|
-
const contentPath =
|
|
8413
|
-
await
|
|
8470
|
+
const content = await fs22.readFile(absPath);
|
|
8471
|
+
const contentPath = path26.join(undoDir, "content");
|
|
8472
|
+
await fs22.writeFile(contentPath, content, { mode: 384 });
|
|
8414
8473
|
return {
|
|
8415
8474
|
...common,
|
|
8416
8475
|
backupKind: "file_content",
|
|
@@ -8455,21 +8514,21 @@ var init_backup = __esm({
|
|
|
8455
8514
|
const walk = async (d) => {
|
|
8456
8515
|
let entries;
|
|
8457
8516
|
try {
|
|
8458
|
-
entries = await
|
|
8517
|
+
entries = await fs22.readdir(d, { withFileTypes: true });
|
|
8459
8518
|
} catch {
|
|
8460
8519
|
return;
|
|
8461
8520
|
}
|
|
8462
8521
|
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
8463
8522
|
for (const e of entries) {
|
|
8464
|
-
const full =
|
|
8465
|
-
const rel =
|
|
8523
|
+
const full = path26.join(d, e.name);
|
|
8524
|
+
const rel = path26.relative(dir, full).replace(/\\/g, "/");
|
|
8466
8525
|
if (e.isDirectory()) {
|
|
8467
8526
|
h.update(`D ${rel}
|
|
8468
8527
|
`);
|
|
8469
8528
|
await walk(full);
|
|
8470
8529
|
} else if (e.isFile()) {
|
|
8471
8530
|
try {
|
|
8472
|
-
h.update(`F ${rel} ${sha1Buf(await
|
|
8531
|
+
h.update(`F ${rel} ${sha1Buf(await fs22.readFile(full))}
|
|
8473
8532
|
`);
|
|
8474
8533
|
} catch {
|
|
8475
8534
|
}
|
|
@@ -8483,16 +8542,16 @@ var init_backup = __esm({
|
|
|
8483
8542
|
let total = 0;
|
|
8484
8543
|
let entries;
|
|
8485
8544
|
try {
|
|
8486
|
-
entries = await
|
|
8545
|
+
entries = await fs22.readdir(dir, { withFileTypes: true });
|
|
8487
8546
|
} catch {
|
|
8488
8547
|
return 0;
|
|
8489
8548
|
}
|
|
8490
8549
|
for (const e of entries) {
|
|
8491
|
-
const full =
|
|
8550
|
+
const full = path26.join(dir, e.name);
|
|
8492
8551
|
if (e.isDirectory()) total += await getDirTreeBytes(full);
|
|
8493
8552
|
else if (e.isFile()) {
|
|
8494
8553
|
try {
|
|
8495
|
-
total += (await
|
|
8554
|
+
total += (await fs22.stat(full)).size;
|
|
8496
8555
|
} catch {
|
|
8497
8556
|
}
|
|
8498
8557
|
}
|
|
@@ -8504,16 +8563,16 @@ var init_backup = __esm({
|
|
|
8504
8563
|
const walk = async (d) => {
|
|
8505
8564
|
let entries;
|
|
8506
8565
|
try {
|
|
8507
|
-
entries = await
|
|
8566
|
+
entries = await fs22.readdir(d, { withFileTypes: true });
|
|
8508
8567
|
} catch {
|
|
8509
8568
|
return;
|
|
8510
8569
|
}
|
|
8511
8570
|
for (const e of entries) {
|
|
8512
|
-
const full =
|
|
8571
|
+
const full = path26.join(d, e.name);
|
|
8513
8572
|
if (e.isDirectory()) {
|
|
8514
8573
|
await walk(full);
|
|
8515
8574
|
} else if (e.isFile()) {
|
|
8516
|
-
const relWithin =
|
|
8575
|
+
const relWithin = path26.relative(dir, full).replace(/\\/g, "/");
|
|
8517
8576
|
if (isSensitivePath(`${wsRelDir}/${relWithin}`)) found.push(relWithin);
|
|
8518
8577
|
}
|
|
8519
8578
|
}
|
|
@@ -8525,15 +8584,15 @@ var init_backup = __esm({
|
|
|
8525
8584
|
});
|
|
8526
8585
|
|
|
8527
8586
|
// ../core/src/tool/undo/restore.ts
|
|
8528
|
-
import
|
|
8529
|
-
import
|
|
8587
|
+
import fs23 from "fs/promises";
|
|
8588
|
+
import path27 from "path";
|
|
8530
8589
|
import crypto2 from "crypto";
|
|
8531
8590
|
async function doRestore(target, sessionId) {
|
|
8532
8591
|
if (target.backupKind === "directory_tree") {
|
|
8533
8592
|
const abs = resolveSafePath(target.relativePath);
|
|
8534
8593
|
let exists = false;
|
|
8535
8594
|
try {
|
|
8536
|
-
await
|
|
8595
|
+
await fs23.access(abs);
|
|
8537
8596
|
exists = true;
|
|
8538
8597
|
} catch {
|
|
8539
8598
|
}
|
|
@@ -8571,7 +8630,7 @@ async function ensureReverseBackup(target, sessionId) {
|
|
|
8571
8630
|
}
|
|
8572
8631
|
let exists = true;
|
|
8573
8632
|
try {
|
|
8574
|
-
await
|
|
8633
|
+
await fs23.access(absPath);
|
|
8575
8634
|
} catch {
|
|
8576
8635
|
exists = false;
|
|
8577
8636
|
}
|
|
@@ -8584,17 +8643,17 @@ async function ensureReverseBackup(target, sessionId) {
|
|
|
8584
8643
|
}
|
|
8585
8644
|
}
|
|
8586
8645
|
const reverseId = createUUID();
|
|
8587
|
-
const reverseDir =
|
|
8588
|
-
await
|
|
8646
|
+
const reverseDir = path27.join(getUndoBackupRoot(sessionId), reverseId);
|
|
8647
|
+
await fs23.mkdir(reverseDir, { recursive: true, mode: 448 });
|
|
8589
8648
|
assertWithinWorkspace(absPath);
|
|
8590
|
-
const st = await
|
|
8649
|
+
const st = await fs23.stat(absPath);
|
|
8591
8650
|
if (st.isDirectory()) {
|
|
8592
|
-
const dest2 =
|
|
8593
|
-
await
|
|
8651
|
+
const dest2 = path27.join(reverseDir, "tree");
|
|
8652
|
+
await fs23.cp(absPath, dest2, { recursive: true, force: true, preserveTimestamps: true });
|
|
8594
8653
|
return { reverseId, backupKind: "directory_tree", backupPath: dest2 };
|
|
8595
8654
|
}
|
|
8596
|
-
const dest =
|
|
8597
|
-
await
|
|
8655
|
+
const dest = path27.join(reverseDir, "content");
|
|
8656
|
+
await fs23.writeFile(dest, await fs23.readFile(absPath));
|
|
8598
8657
|
return { reverseId, backupKind: "file_content", backupPath: dest };
|
|
8599
8658
|
}
|
|
8600
8659
|
async function dispatchRestore(r) {
|
|
@@ -8602,20 +8661,20 @@ async function dispatchRestore(r) {
|
|
|
8602
8661
|
assertWithinWorkspace(absPath);
|
|
8603
8662
|
switch (r.backupKind) {
|
|
8604
8663
|
case "creation_marker": {
|
|
8605
|
-
await
|
|
8664
|
+
await fs23.rm(absPath, { force: true });
|
|
8606
8665
|
return `\u5DF2\u5220\u9664\u65B0\u5EFA\u6587\u4EF6 [${r.relativePath}]`;
|
|
8607
8666
|
}
|
|
8608
8667
|
case "file_content": {
|
|
8609
|
-
await
|
|
8610
|
-
const backupAbs =
|
|
8611
|
-
const content = await
|
|
8612
|
-
await
|
|
8668
|
+
await fs23.mkdir(path27.dirname(absPath), { recursive: true });
|
|
8669
|
+
const backupAbs = path27.join(getUndoBackupRoot(r.sessionId), r.undoId, "content");
|
|
8670
|
+
const content = await fs23.readFile(backupAbs);
|
|
8671
|
+
await fs23.writeFile(absPath, content);
|
|
8613
8672
|
return `\u5DF2\u6062\u590D [${r.relativePath}] \u81F3\u5907\u4EFD\u524D\u5185\u5BB9\uFF08${r.fileSizeBefore ?? content.byteLength} \u5B57\u8282\uFF09`;
|
|
8614
8673
|
}
|
|
8615
8674
|
case "directory_tree": {
|
|
8616
|
-
await
|
|
8617
|
-
const src =
|
|
8618
|
-
await
|
|
8675
|
+
await fs23.mkdir(path27.dirname(absPath), { recursive: true });
|
|
8676
|
+
const src = path27.join(getUndoBackupRoot(r.sessionId), r.undoId, "tree");
|
|
8677
|
+
await fs23.cp(src, absPath, { recursive: true, force: true, preserveTimestamps: true });
|
|
8619
8678
|
return `\u5DF2\u6062\u590D\u76EE\u5F55\u6811 [${r.relativePath}]\uFF08\u7EA6 ${r.fileSizeBefore ?? 0} \u5B57\u8282\uFF09`;
|
|
8620
8679
|
}
|
|
8621
8680
|
}
|
|
@@ -8648,7 +8707,7 @@ var init_restore = __esm({
|
|
|
8648
8707
|
init_common();
|
|
8649
8708
|
init_traceCalculate();
|
|
8650
8709
|
sha1File = async (absPath) => {
|
|
8651
|
-
const buf = await
|
|
8710
|
+
const buf = await fs23.readFile(absPath);
|
|
8652
8711
|
return crypto2.createHash("sha1").update(buf).digest("hex");
|
|
8653
8712
|
};
|
|
8654
8713
|
listUndoable = async (sessionId) => {
|
|
@@ -8922,7 +8981,7 @@ ${diff.slice(0, 1500)}` : "";
|
|
|
8922
8981
|
});
|
|
8923
8982
|
|
|
8924
8983
|
// ../core/src/tool/registry/notebook.ts
|
|
8925
|
-
import
|
|
8984
|
+
import fs24 from "fs/promises";
|
|
8926
8985
|
var toArraySource, encodeSource, makeCell, applyNotebookEdit, notebookTools;
|
|
8927
8986
|
var init_notebook = __esm({
|
|
8928
8987
|
"../core/src/tool/registry/notebook.ts"() {
|
|
@@ -9023,7 +9082,7 @@ ${String(args.new_source).slice(0, 500)}` : ""}`,
|
|
|
9023
9082
|
}
|
|
9024
9083
|
let raw;
|
|
9025
9084
|
try {
|
|
9026
|
-
raw = await
|
|
9085
|
+
raw = await fs24.readFile(absPath, "utf-8");
|
|
9027
9086
|
} catch (e) {
|
|
9028
9087
|
return `\u274C [notebook_edit] \u8BFB\u53D6\u5931\u8D25\uFF1A${e?.message ?? e}`;
|
|
9029
9088
|
}
|
|
@@ -9053,10 +9112,10 @@ ${String(args.new_source).slice(0, 500)}` : ""}`,
|
|
|
9053
9112
|
}
|
|
9054
9113
|
const tmpPath = makeTmpPath(absPath);
|
|
9055
9114
|
try {
|
|
9056
|
-
await
|
|
9057
|
-
await
|
|
9115
|
+
await fs24.writeFile(tmpPath, JSON.stringify(nb, null, 2), "utf-8");
|
|
9116
|
+
await fs24.rename(tmpPath, absPath);
|
|
9058
9117
|
} catch (e) {
|
|
9059
|
-
await
|
|
9118
|
+
await fs24.unlink(tmpPath).catch(() => {
|
|
9060
9119
|
});
|
|
9061
9120
|
return `\u274C [notebook_edit] \u5199\u5165\u5931\u8D25\uFF1A${e?.message ?? e}`;
|
|
9062
9121
|
}
|
|
@@ -9096,8 +9155,8 @@ var init_frontmatter = __esm({
|
|
|
9096
9155
|
});
|
|
9097
9156
|
|
|
9098
9157
|
// ../core/src/memory/loader.ts
|
|
9099
|
-
import
|
|
9100
|
-
import
|
|
9158
|
+
import fs25 from "fs/promises";
|
|
9159
|
+
import path28 from "path";
|
|
9101
9160
|
var GLOBAL_MEMORY_DIR, SOURCES, VALID_TYPES, parseMemoryAt, loadMemories, initMemories;
|
|
9102
9161
|
var init_loader3 = __esm({
|
|
9103
9162
|
"../core/src/memory/loader.ts"() {
|
|
@@ -9106,16 +9165,16 @@ var init_loader3 = __esm({
|
|
|
9106
9165
|
init_frontmatter();
|
|
9107
9166
|
init_registry6();
|
|
9108
9167
|
init_registry2();
|
|
9109
|
-
GLOBAL_MEMORY_DIR =
|
|
9168
|
+
GLOBAL_MEMORY_DIR = path28.join(appConfig.dataDir, "memory");
|
|
9110
9169
|
SOURCES = [
|
|
9111
9170
|
{ dir: GLOBAL_MEMORY_DIR, source: "global" },
|
|
9112
|
-
{ dir:
|
|
9171
|
+
{ dir: path28.join(process.cwd(), ".deepseeker-code", "memory"), source: "project" }
|
|
9113
9172
|
];
|
|
9114
9173
|
VALID_TYPES = ["user", "feedback", "project", "reference"];
|
|
9115
9174
|
parseMemoryAt = async (file, _dir, source) => {
|
|
9116
9175
|
let raw;
|
|
9117
9176
|
try {
|
|
9118
|
-
raw = await
|
|
9177
|
+
raw = await fs25.readFile(file, "utf-8");
|
|
9119
9178
|
} catch {
|
|
9120
9179
|
return null;
|
|
9121
9180
|
}
|
|
@@ -9149,7 +9208,7 @@ var init_loader3 = __esm({
|
|
|
9149
9208
|
clearMemories();
|
|
9150
9209
|
const picked = await scanSources(
|
|
9151
9210
|
filterSources(SOURCES, includeProject),
|
|
9152
|
-
(e, dir) => e.isFile() && e.name.endsWith(".md") ?
|
|
9211
|
+
(e, dir) => e.isFile() && e.name.endsWith(".md") ? path28.join(dir, e.name) : void 0,
|
|
9153
9212
|
parseMemoryAt
|
|
9154
9213
|
);
|
|
9155
9214
|
for (const { item } of picked) registerMemory(item);
|
|
@@ -9167,8 +9226,8 @@ var init_loader3 = __esm({
|
|
|
9167
9226
|
});
|
|
9168
9227
|
|
|
9169
9228
|
// ../core/src/tool/registry/memory.ts
|
|
9170
|
-
import
|
|
9171
|
-
import
|
|
9229
|
+
import fs26 from "fs/promises";
|
|
9230
|
+
import path29 from "path";
|
|
9172
9231
|
var MAX_BODY_BYTES, NAME_RE, VALID_TYPES2, memoryFilePath, sanitizeLine, buildMemoryMd, writeAndRegister, memoryTools;
|
|
9173
9232
|
var init_memory = __esm({
|
|
9174
9233
|
"../core/src/tool/registry/memory.ts"() {
|
|
@@ -9180,7 +9239,7 @@ var init_memory = __esm({
|
|
|
9180
9239
|
MAX_BODY_BYTES = 64 * 1024;
|
|
9181
9240
|
NAME_RE = /^[a-z0-9-]+$/;
|
|
9182
9241
|
VALID_TYPES2 = ["user", "feedback", "project", "reference"];
|
|
9183
|
-
memoryFilePath = (name, project) => project ?
|
|
9242
|
+
memoryFilePath = (name, project) => project ? path29.join(process.cwd(), ".deepseeker-code", "memory", `${name}.md`) : path29.join(GLOBAL_MEMORY_DIR, `${name}.md`);
|
|
9184
9243
|
sanitizeLine = (s) => String(s ?? "").replace(/[\r\n]+/g, " ").trim();
|
|
9185
9244
|
buildMemoryMd = (name, description, type, body) => `---
|
|
9186
9245
|
name: ${name}
|
|
@@ -9192,10 +9251,10 @@ ${body.trim()}
|
|
|
9192
9251
|
`;
|
|
9193
9252
|
writeAndRegister = async (name, description, type, body, project) => {
|
|
9194
9253
|
const file = memoryFilePath(name, project);
|
|
9195
|
-
await
|
|
9254
|
+
await fs26.mkdir(path29.dirname(file), { recursive: true });
|
|
9196
9255
|
const tmp = makeTmpPath(file);
|
|
9197
|
-
await
|
|
9198
|
-
await
|
|
9256
|
+
await fs26.writeFile(tmp, buildMemoryMd(name, description, type, body), "utf-8");
|
|
9257
|
+
await fs26.rename(tmp, file);
|
|
9199
9258
|
registerMemory({ name, description, type, body: body.trim(), source: project ? "project" : "global", file });
|
|
9200
9259
|
return file;
|
|
9201
9260
|
};
|
|
@@ -9311,7 +9370,7 @@ ${lines.join("\n")}`;
|
|
|
9311
9370
|
const m = getMemory(name);
|
|
9312
9371
|
if (!m) return `\u274C \u672A\u627E\u5230\u8BB0\u5FC6\uFF1A${name}\uFF08\u53EF\u80FD\u5DF2\u88AB\u5220\u9664\uFF09\u3002`;
|
|
9313
9372
|
try {
|
|
9314
|
-
await
|
|
9373
|
+
await fs26.unlink(m.file);
|
|
9315
9374
|
} catch {
|
|
9316
9375
|
}
|
|
9317
9376
|
unregisterMemory(name);
|
|
@@ -9324,8 +9383,8 @@ ${lines.join("\n")}`;
|
|
|
9324
9383
|
});
|
|
9325
9384
|
|
|
9326
9385
|
// ../core/src/tool/registry/recall.ts
|
|
9327
|
-
import
|
|
9328
|
-
import
|
|
9386
|
+
import fs27 from "fs/promises";
|
|
9387
|
+
import path30 from "path";
|
|
9329
9388
|
var escapeRegExp2, lineText, primaryPathArg, annotateStaleness, snippetAround, recallTools;
|
|
9330
9389
|
var init_recall = __esm({
|
|
9331
9390
|
"../core/src/tool/registry/recall.ts"() {
|
|
@@ -9356,9 +9415,9 @@ var init_recall = __esm({
|
|
|
9356
9415
|
annotateStaleness = async (args, observedAt) => {
|
|
9357
9416
|
const p = primaryPathArg(args);
|
|
9358
9417
|
if (!p) return "\u5FEB\u7167\uFF08\u65E0\u8DEF\u5F84\u5B9E\u4F53\uFF0C\u672A\u7ECF\u91CD\u9A8C\u2014\u2014\u636E\u4EE5\u884C\u52A8\u524D\u8BF7\u91CD\u8DD1\u9A8C\u8BC1\uFF09";
|
|
9359
|
-
const abs =
|
|
9418
|
+
const abs = path30.isAbsolute(p) ? p : path30.resolve(getActiveWorkspaceRoot(), p);
|
|
9360
9419
|
try {
|
|
9361
|
-
const st = await
|
|
9420
|
+
const st = await fs27.stat(abs);
|
|
9362
9421
|
if (observedAt && st.mtime.toISOString() > observedAt) {
|
|
9363
9422
|
return `\u26A0\uFE0F \u89C2\u5BDF\u540E\u8BE5\u6587\u4EF6\u5DF2\u88AB\u4FEE\u6539\uFF08${p}\uFF09\u2014\u2014\u5FC5\u987B\u91CD\u65B0 read_file \u540E\u624D\u80FD\u636E\u4EE5\u4FEE\u6539`;
|
|
9364
9423
|
}
|
|
@@ -9403,10 +9462,10 @@ var init_recall = __esm({
|
|
|
9403
9462
|
if (args.with_full) {
|
|
9404
9463
|
const safeId = String(args.with_full).replace(/[^A-Za-z0-9_-]/g, "");
|
|
9405
9464
|
if (!safeId) return "\u274C [recall] with_full \u542B\u975E\u6CD5\u5B57\u7B26\u3002";
|
|
9406
|
-
const sidecar =
|
|
9465
|
+
const sidecar = path30.join(getSessionsDirPath(ctx.sessionId), "tool-outputs", `${safeId}.txt`);
|
|
9407
9466
|
let full = "";
|
|
9408
9467
|
try {
|
|
9409
|
-
full = await
|
|
9468
|
+
full = await fs27.readFile(sidecar, "utf-8");
|
|
9410
9469
|
} catch {
|
|
9411
9470
|
return `\u274C [recall] \u672A\u627E\u5230\u8BE5 id \u7684\u5B58\u6863\u539F\u6587\uFF08\u53EF\u80FD\u672A\u66FE\u89E6\u53D1\u622A\u65AD\u5B58\u6863\u3001\u6216\u4F1A\u8BDD\u5DF2\u6E05\u7406\uFF09\uFF1A${args.with_full}`;
|
|
9412
9471
|
}
|
|
@@ -9615,7 +9674,7 @@ var init_spreadsheet = __esm({
|
|
|
9615
9674
|
});
|
|
9616
9675
|
|
|
9617
9676
|
// ../core/src/tool/registry/document.ts
|
|
9618
|
-
import
|
|
9677
|
+
import fs28 from "fs/promises";
|
|
9619
9678
|
var getMammoth, getUnpdf, documentTools;
|
|
9620
9679
|
var init_document = __esm({
|
|
9621
9680
|
"../core/src/tool/registry/document.ts"() {
|
|
@@ -9705,7 +9764,7 @@ var init_document = __esm({
|
|
|
9705
9764
|
}
|
|
9706
9765
|
const start = args.start_char ? Math.max(0, Math.floor(args.start_char)) : 0;
|
|
9707
9766
|
const maxChars = Math.min(args.max_chars ? Math.max(1, Math.floor(args.max_chars)) : 3e4, 5e4);
|
|
9708
|
-
const buf = await
|
|
9767
|
+
const buf = await fs28.readFile(absPath);
|
|
9709
9768
|
const unpdf = await getUnpdf();
|
|
9710
9769
|
const pdf = await unpdf.getDocumentProxy(new Uint8Array(buf));
|
|
9711
9770
|
const { text, totalPages } = await unpdf.extractText(pdf, { mergePages: true });
|
|
@@ -9911,7 +9970,7 @@ var init_backgroundTool = __esm({
|
|
|
9911
9970
|
});
|
|
9912
9971
|
|
|
9913
9972
|
// ../core/src/tool/autoPermission.ts
|
|
9914
|
-
import
|
|
9973
|
+
import path31 from "path";
|
|
9915
9974
|
var AUTO_SCOPE, AUTO_DEFAULT_EXTRA, AUTO_AGGRESSIVE_EXTRA, isMcpTool, BUILTIN_AUTO_DENY, matchBuiltinDeny, COMMAND_DENY, matchCommandDeny, hasShellMetachars, READONLY_HEADS, PKG_MGR, SCRIPT_RUNNER_HEADS, SCRIPT_RUNNER_READONLY, isScriptRunnerCommand, hasWriteModifier, SENSITIVE_FILE_ARG_RE, hasSensitiveFileArg, isReadOnlyCommand, isWithinWorkspace, runAutoCheck;
|
|
9916
9975
|
var init_autoPermission = __esm({
|
|
9917
9976
|
"../core/src/tool/autoPermission.ts"() {
|
|
@@ -10059,9 +10118,9 @@ var init_autoPermission = __esm({
|
|
|
10059
10118
|
isWithinWorkspace = (p, cwd) => {
|
|
10060
10119
|
if (!p || !cwd) return false;
|
|
10061
10120
|
try {
|
|
10062
|
-
const abs =
|
|
10063
|
-
const rel =
|
|
10064
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
10121
|
+
const abs = path31.isAbsolute(p) ? p : path31.resolve(cwd, p);
|
|
10122
|
+
const rel = path31.relative(cwd, abs);
|
|
10123
|
+
return rel === "" || !rel.startsWith("..") && !path31.isAbsolute(rel);
|
|
10065
10124
|
} catch {
|
|
10066
10125
|
return false;
|
|
10067
10126
|
}
|
|
@@ -10089,8 +10148,8 @@ var init_autoPermission = __esm({
|
|
|
10089
10148
|
});
|
|
10090
10149
|
|
|
10091
10150
|
// ../core/src/agent/toolExecution.ts
|
|
10092
|
-
import
|
|
10093
|
-
import
|
|
10151
|
+
import fs29 from "fs/promises";
|
|
10152
|
+
import path32 from "path";
|
|
10094
10153
|
var applyPrivacyMasking, processToolCall;
|
|
10095
10154
|
var init_toolExecution = __esm({
|
|
10096
10155
|
"../core/src/agent/toolExecution.ts"() {
|
|
@@ -10230,13 +10289,13 @@ var init_toolExecution = __esm({
|
|
|
10230
10289
|
const argCwd = typeof calledArgs?.cwd === "string" ? calledArgs.cwd.trim() : "";
|
|
10231
10290
|
const samePath = (a, b) => {
|
|
10232
10291
|
try {
|
|
10233
|
-
const ra =
|
|
10292
|
+
const ra = path32.resolve(a), rb = path32.resolve(b);
|
|
10234
10293
|
return process.platform === "win32" ? ra.toLowerCase() === rb.toLowerCase() : ra === rb;
|
|
10235
10294
|
} catch {
|
|
10236
10295
|
return false;
|
|
10237
10296
|
}
|
|
10238
10297
|
};
|
|
10239
|
-
const scriptRunnerCwdDrift = cmdIsScriptRunner && argCwd !== "" && !samePath(argCwd, toolCtx.cwd);
|
|
10298
|
+
const scriptRunnerCwdDrift = cmdIsScriptRunner && argCwd !== "" && !samePath(argCwd, toolCtx.cwd ?? process.cwd());
|
|
10240
10299
|
const scriptRunnerBlocked = cmdIsScriptRunner && (perm === null || scriptRunnerCwdDrift);
|
|
10241
10300
|
if (scriptRunnerCwdDrift) needApproval = true;
|
|
10242
10301
|
if (perm === null && needApproval && !denied && !scriptRunnerBlocked && calledName === "run_command" && isReadOnlyCommand(typeof calledArgs?.command === "string" ? calledArgs.command : "")) {
|
|
@@ -10345,10 +10404,10 @@ ${result}`;
|
|
|
10345
10404
|
const truncBudget = matchedTool?.function?.maxOutputCharacters ?? appConfig.MAX_TOOL_RESULT_CHARS;
|
|
10346
10405
|
if (result.length > truncBudget) {
|
|
10347
10406
|
try {
|
|
10348
|
-
const sidecarDir =
|
|
10349
|
-
await
|
|
10407
|
+
const sidecarDir = path32.join(getSessionsDirPath(sessionId), "tool-outputs");
|
|
10408
|
+
await fs29.mkdir(sidecarDir, { recursive: true });
|
|
10350
10409
|
const safeId = String(toolCall.id).replace(/[^A-Za-z0-9_-]/g, "");
|
|
10351
|
-
await
|
|
10410
|
+
await fs29.writeFile(path32.join(sidecarDir, `${safeId}.txt`), result, "utf-8");
|
|
10352
10411
|
sidecarNote = `\u5B8C\u6574\u539F\u6587\u5DF2\u5B58\u6863\uFF0Crecall \u5DE5\u5177\u4F20 with_full="${toolCall.id}" \u53EF\u53D6\u56DE`;
|
|
10353
10412
|
} catch (e) {
|
|
10354
10413
|
console.warn(`\u26A0\uFE0F [sidecar] \u5DE5\u5177\u539F\u6587\u5B58\u6863\u5931\u8D25\uFF08\u5DF2\u964D\u7EA7\u4E3A\u666E\u901A\u622A\u65AD\u63D0\u793A\uFF09:`, e instanceof Error ? e.message : e);
|
|
@@ -10499,6 +10558,8 @@ var init_streamInference = __esm({
|
|
|
10499
10558
|
init_transcript();
|
|
10500
10559
|
init_contextCore();
|
|
10501
10560
|
init_contentParts();
|
|
10561
|
+
init_visionCapability();
|
|
10562
|
+
init_createModel();
|
|
10502
10563
|
sha1short = (s) => createHash2("sha1").update(s).digest("hex").slice(0, 10);
|
|
10503
10564
|
RETRY_BACKOFF_CAP_MS = 3e4;
|
|
10504
10565
|
extractRetryAfterMs = (e) => {
|
|
@@ -10537,7 +10598,7 @@ var init_streamInference = __esm({
|
|
|
10537
10598
|
llmDecisionSource,
|
|
10538
10599
|
signal,
|
|
10539
10600
|
cleanedToolSchemas,
|
|
10540
|
-
model
|
|
10601
|
+
model,
|
|
10541
10602
|
thinkingLevel,
|
|
10542
10603
|
events,
|
|
10543
10604
|
keepRecentUnits,
|
|
@@ -10557,7 +10618,7 @@ var init_streamInference = __esm({
|
|
|
10557
10618
|
events({
|
|
10558
10619
|
sessionId,
|
|
10559
10620
|
eventType: "llm.request",
|
|
10560
|
-
metadata: { depth, decisionSource: userDecisionSource, ok: true, durationMs: performance.now() - startTime, round, ...prefixFingerprint },
|
|
10621
|
+
metadata: { depth, decisionSource: userDecisionSource, ok: true, durationMs: performance.now() - startTime, round, model, ...prefixFingerprint },
|
|
10561
10622
|
// ★ P2 口径:估算加上工具 schema 常数项(与 API 真实 prompt_tokens 同口径,trace 里 est/real 才可比)
|
|
10562
10623
|
usage: { prompt_tokens: estimateTokens(inferenceMessages) + toolsTokens },
|
|
10563
10624
|
payload: { input: msgText(message[message.length - 1].content) }
|
|
@@ -10572,9 +10633,10 @@ var init_streamInference = __esm({
|
|
|
10572
10633
|
const MAX_API_RETRIES = 3;
|
|
10573
10634
|
let apiRetries = 0;
|
|
10574
10635
|
let compactedThisRound = false;
|
|
10636
|
+
let visionDegradedThisRound = false;
|
|
10575
10637
|
for (let streamAttempt = 0; ; streamAttempt++) {
|
|
10576
10638
|
try {
|
|
10577
|
-
for await (const chunk of activeProvider.streamChat(inferenceMessages, cleanedToolSchemas, { signal, model
|
|
10639
|
+
for await (const chunk of activeProvider.streamChat(inferenceMessages, cleanedToolSchemas, { signal, model, thinkingLevel })) {
|
|
10578
10640
|
if (signal?.aborted) break;
|
|
10579
10641
|
switch (chunk.kind) {
|
|
10580
10642
|
case "text":
|
|
@@ -10672,6 +10734,26 @@ var init_streamInference = __esm({
|
|
|
10672
10734
|
lastUsage = void 0;
|
|
10673
10735
|
continue;
|
|
10674
10736
|
}
|
|
10737
|
+
if (activeProvider.isImageUnsupportedError(streamErr) && noOutputYet && !visionDegradedThisRound) {
|
|
10738
|
+
const effModel = typeof model === "string" && model.trim() ? model.trim() : MODEL_NAME;
|
|
10739
|
+
learnVisionCapability(effModel, false);
|
|
10740
|
+
for (let i = 0; i < message.length; i++) message[i] = collapseToText(message[i], VISION_DEGRADE_NOTE);
|
|
10741
|
+
inferenceMessages = withNudgeTail(message, nudgeMsg);
|
|
10742
|
+
visionDegradedThisRound = true;
|
|
10743
|
+
events({
|
|
10744
|
+
sessionId,
|
|
10745
|
+
eventType: "llm.visionDowngraded",
|
|
10746
|
+
metadata: { depth, decisionSource: llmDecisionSource, ok: true, round, model: effModel },
|
|
10747
|
+
payload: { output: streamErr instanceof Error ? streamErr.message : String(streamErr) }
|
|
10748
|
+
});
|
|
10749
|
+
yield { type: "vision.downgraded", model: effModel };
|
|
10750
|
+
console.warn(`\u26A0\uFE0F \u6A21\u578B ${effModel} \u4E0D\u652F\u6301\u56FE\u7247\u8F93\u5165\uFF08API ${streamErr?.status ?? "?"}\uFF09\uFF0C\u5DF2\u81EA\u52A8\u964D\u7EA7\u4E3A\u6587\u672C\u5360\u4F4D\u5E76\u91CD\u8BD5\uFF08\u80FD\u529B\u5DF2\u8BB0\u4F4F\uFF0C\u540E\u7EED\u6D88\u606F\u76F4\u63A5\u6309\u6587\u672C\u53D1\u9001\uFF09`);
|
|
10751
|
+
contentBuf = "";
|
|
10752
|
+
reasoningBuf = "";
|
|
10753
|
+
toolCallsBuf.clear();
|
|
10754
|
+
lastUsage = void 0;
|
|
10755
|
+
continue;
|
|
10756
|
+
}
|
|
10675
10757
|
throw streamErr;
|
|
10676
10758
|
}
|
|
10677
10759
|
}
|
|
@@ -10691,7 +10773,7 @@ var init_streamInference = __esm({
|
|
|
10691
10773
|
events({
|
|
10692
10774
|
sessionId,
|
|
10693
10775
|
eventType: "llm.response",
|
|
10694
|
-
metadata: { depth, decisionSource: llmDecisionSource, ok: true, durationMs: performance.now() - startTime, round },
|
|
10776
|
+
metadata: { depth, decisionSource: llmDecisionSource, ok: true, durationMs: performance.now() - startTime, round, model },
|
|
10695
10777
|
usage: {
|
|
10696
10778
|
prompt_tokens: lastUsage?.prompt_tokens,
|
|
10697
10779
|
completion_tokens: lastUsage?.completion_tokens,
|
|
@@ -11247,7 +11329,7 @@ var init_recovery = __esm({
|
|
|
11247
11329
|
});
|
|
11248
11330
|
|
|
11249
11331
|
// ../core/src/session/content.ts
|
|
11250
|
-
var decayOldToolResults,
|
|
11332
|
+
var decayOldToolResults, enforceVisionGate, buildContextMessages;
|
|
11251
11333
|
var init_content = __esm({
|
|
11252
11334
|
"../core/src/session/content.ts"() {
|
|
11253
11335
|
"use strict";
|
|
@@ -11256,6 +11338,7 @@ var init_content = __esm({
|
|
|
11256
11338
|
init_transcript();
|
|
11257
11339
|
init_store();
|
|
11258
11340
|
init_config();
|
|
11341
|
+
init_visionCapability();
|
|
11259
11342
|
init_recovery();
|
|
11260
11343
|
decayOldToolResults = (msgs) => {
|
|
11261
11344
|
const units = groupUnits(msgs);
|
|
@@ -11286,9 +11369,9 @@ var init_content = __esm({
|
|
|
11286
11369
|
return replaceImageParts(mm, "[\u5386\u53F2\u56FE\u7247\u5DF2\u6298\u53E0\uFF1A\u539F\u56FE\u4ECD\u5728\u4F1A\u8BDD\u5F52\u6863\u4E2D\uFF0C\u5982\u9700\u518D\u6B21\u67E5\u770B\u8BF7\u91CD\u65B0\u63D0\u4F9B\u8BE5\u56FE\u7247]");
|
|
11287
11370
|
});
|
|
11288
11371
|
};
|
|
11289
|
-
|
|
11290
|
-
enforceVisionGate = (msgs, modelId) => isVisionEnabled(modelId) ? msgs : msgs.map((m) => collapseToText(m, NO_VISION_IMAGE_NOTE));
|
|
11372
|
+
enforceVisionGate = (msgs, modelId) => isVisionEnabled(modelId) ? msgs : msgs.map((m) => collapseToText(m, VISION_DEGRADE_NOTE));
|
|
11291
11373
|
buildContextMessages = async (sessionId, currentUserMsg, systemPrompt, modelId) => {
|
|
11374
|
+
await ensureVisionCacheLoaded();
|
|
11292
11375
|
const lines = await readTranscriptLines(sessionId);
|
|
11293
11376
|
const store = await getRollingState(sessionId);
|
|
11294
11377
|
const eventAware = appConfig.transcriptEvents || lines.some(isEventLine);
|
|
@@ -11318,7 +11401,7 @@ var init_content = __esm({
|
|
|
11318
11401
|
});
|
|
11319
11402
|
|
|
11320
11403
|
// ../core/src/session/lineage.ts
|
|
11321
|
-
import
|
|
11404
|
+
import fs30 from "node:fs";
|
|
11322
11405
|
var parentOfSubsession, stringAncestorsOf, readForkedFromSync, lineageClosureOf, ownerCanApprove;
|
|
11323
11406
|
var init_lineage = __esm({
|
|
11324
11407
|
"../core/src/session/lineage.ts"() {
|
|
@@ -11341,7 +11424,7 @@ var init_lineage = __esm({
|
|
|
11341
11424
|
};
|
|
11342
11425
|
readForkedFromSync = (sessionId) => {
|
|
11343
11426
|
try {
|
|
11344
|
-
const raw =
|
|
11427
|
+
const raw = fs30.readFileSync(getStatePath(sessionId), "utf-8");
|
|
11345
11428
|
const v = JSON.parse(raw)?.forkedFrom;
|
|
11346
11429
|
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
11347
11430
|
} catch {
|
|
@@ -11538,8 +11621,8 @@ var init_subagent = __esm({
|
|
|
11538
11621
|
});
|
|
11539
11622
|
|
|
11540
11623
|
// ../core/src/hooks/loader.ts
|
|
11541
|
-
import
|
|
11542
|
-
import
|
|
11624
|
+
import fs31 from "fs/promises";
|
|
11625
|
+
import path33 from "path";
|
|
11543
11626
|
var readHooksConfig, appendValidated, validateRule, parseStdoutDecision, parseAgentDecision, compileRule2, loadHooks, initHooks;
|
|
11544
11627
|
var init_loader4 = __esm({
|
|
11545
11628
|
"../core/src/hooks/loader.ts"() {
|
|
@@ -11554,15 +11637,15 @@ var init_loader4 = __esm({
|
|
|
11554
11637
|
readHooksConfig = async (includeProject) => {
|
|
11555
11638
|
const merged = {};
|
|
11556
11639
|
const paths = [
|
|
11557
|
-
|
|
11640
|
+
path33.join(appConfig.dataDir, "settings.json"),
|
|
11558
11641
|
// 全局用户级
|
|
11559
|
-
...includeProject ? [
|
|
11642
|
+
...includeProject ? [path33.join(process.cwd(), ".deepseeker-code", "settings.json")] : []
|
|
11560
11643
|
// 项目级(叠加);未信任时省略
|
|
11561
11644
|
];
|
|
11562
11645
|
for (const configPath of paths) {
|
|
11563
11646
|
let raw;
|
|
11564
11647
|
try {
|
|
11565
|
-
raw = await
|
|
11648
|
+
raw = await fs31.readFile(configPath, "utf-8");
|
|
11566
11649
|
} catch {
|
|
11567
11650
|
continue;
|
|
11568
11651
|
}
|
|
@@ -11893,8 +11976,8 @@ ${m.context}`;
|
|
|
11893
11976
|
});
|
|
11894
11977
|
|
|
11895
11978
|
// ../core/src/skills/loader.ts
|
|
11896
|
-
import
|
|
11897
|
-
import
|
|
11979
|
+
import fs32 from "fs/promises";
|
|
11980
|
+
import path34 from "path";
|
|
11898
11981
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
11899
11982
|
var BUILTIN_DIR, SOURCES2, MAX_SKILL_BODY_BYTES, splitList, parseSkillAt, loadSkills, initSkills;
|
|
11900
11983
|
var init_loader5 = __esm({
|
|
@@ -11905,18 +11988,18 @@ var init_loader5 = __esm({
|
|
|
11905
11988
|
init_registry3();
|
|
11906
11989
|
init_skill();
|
|
11907
11990
|
init_registry2();
|
|
11908
|
-
BUILTIN_DIR =
|
|
11991
|
+
BUILTIN_DIR = path34.join(path34.dirname(fileURLToPath2(import.meta.url)), "builtin");
|
|
11909
11992
|
SOURCES2 = [
|
|
11910
11993
|
{ dir: BUILTIN_DIR, source: "builtin" },
|
|
11911
|
-
{ dir:
|
|
11912
|
-
{ dir:
|
|
11994
|
+
{ dir: path34.join(appConfig.dataDir, "skills"), source: "global" },
|
|
11995
|
+
{ dir: path34.join(process.cwd(), ".deepseeker-code", "skills"), source: "project" }
|
|
11913
11996
|
];
|
|
11914
11997
|
MAX_SKILL_BODY_BYTES = 64 * 1024;
|
|
11915
11998
|
splitList = (raw) => (raw ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
11916
11999
|
parseSkillAt = async (skillFile, dir, source) => {
|
|
11917
12000
|
let raw;
|
|
11918
12001
|
try {
|
|
11919
|
-
raw = await
|
|
12002
|
+
raw = await fs32.readFile(skillFile, "utf-8");
|
|
11920
12003
|
} catch {
|
|
11921
12004
|
return null;
|
|
11922
12005
|
}
|
|
@@ -11955,7 +12038,7 @@ var init_loader5 = __esm({
|
|
|
11955
12038
|
loadSkills = async (includeProject) => {
|
|
11956
12039
|
const picked = await scanSources(
|
|
11957
12040
|
filterSources(SOURCES2, includeProject),
|
|
11958
|
-
(e, dir) => e.isDirectory() ?
|
|
12041
|
+
(e, dir) => e.isDirectory() ? path34.join(dir, e.name, "SKILL.md") : void 0,
|
|
11959
12042
|
parseSkillAt
|
|
11960
12043
|
);
|
|
11961
12044
|
for (const { item } of picked) registerSkill(item);
|
|
@@ -11986,8 +12069,8 @@ var init_loader5 = __esm({
|
|
|
11986
12069
|
});
|
|
11987
12070
|
|
|
11988
12071
|
// ../core/src/agents/loader.ts
|
|
11989
|
-
import
|
|
11990
|
-
import
|
|
12072
|
+
import fs33 from "fs/promises";
|
|
12073
|
+
import path35 from "path";
|
|
11991
12074
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
11992
12075
|
var BUILTIN_DIR2, SOURCES3, parseAgentAt, initAgents;
|
|
11993
12076
|
var init_loader6 = __esm({
|
|
@@ -11997,16 +12080,16 @@ var init_loader6 = __esm({
|
|
|
11997
12080
|
init_frontmatter();
|
|
11998
12081
|
init_registry4();
|
|
11999
12082
|
init_registry2();
|
|
12000
|
-
BUILTIN_DIR2 =
|
|
12083
|
+
BUILTIN_DIR2 = path35.join(path35.dirname(fileURLToPath3(import.meta.url)), "builtin");
|
|
12001
12084
|
SOURCES3 = [
|
|
12002
12085
|
{ dir: BUILTIN_DIR2, source: "builtin" },
|
|
12003
|
-
{ dir:
|
|
12004
|
-
{ dir:
|
|
12086
|
+
{ dir: path35.join(appConfig.dataDir, "agents"), source: "global" },
|
|
12087
|
+
{ dir: path35.join(process.cwd(), ".deepseeker-code", "agents"), source: "project" }
|
|
12005
12088
|
];
|
|
12006
12089
|
parseAgentAt = async (file, dir, source) => {
|
|
12007
12090
|
let raw;
|
|
12008
12091
|
try {
|
|
12009
|
-
raw = await
|
|
12092
|
+
raw = await fs33.readFile(file, "utf-8");
|
|
12010
12093
|
} catch {
|
|
12011
12094
|
return null;
|
|
12012
12095
|
}
|
|
@@ -12015,7 +12098,7 @@ var init_loader6 = __esm({
|
|
|
12015
12098
|
console.warn(`\u26A0\uFE0F [agents] frontmatter \u683C\u5F0F\u65E0\u6548\uFF08${file}\uFF09\uFF0C\u5DF2\u8DF3\u8FC7`);
|
|
12016
12099
|
return null;
|
|
12017
12100
|
}
|
|
12018
|
-
const { name, description, role, tools, model
|
|
12101
|
+
const { name, description, role, tools, model } = parsed.frontmatter;
|
|
12019
12102
|
if (!name || !description) {
|
|
12020
12103
|
console.warn(`\u26A0\uFE0F [agents] \u7F3A\u5C11 name \u6216 description\uFF08${file}\uFF09\uFF0C\u5DF2\u8DF3\u8FC7`);
|
|
12021
12104
|
return null;
|
|
@@ -12030,7 +12113,7 @@ var init_loader6 = __esm({
|
|
|
12030
12113
|
description,
|
|
12031
12114
|
role: role || void 0,
|
|
12032
12115
|
tools: toolList,
|
|
12033
|
-
model:
|
|
12116
|
+
model: model || void 0,
|
|
12034
12117
|
body: parsed.body,
|
|
12035
12118
|
source,
|
|
12036
12119
|
dir
|
|
@@ -12041,7 +12124,7 @@ var init_loader6 = __esm({
|
|
|
12041
12124
|
const known = new Set(into.map((t) => t.function.name));
|
|
12042
12125
|
const picked = await scanSources(
|
|
12043
12126
|
filterSources(SOURCES3, includeProject),
|
|
12044
|
-
(e, dir) => e.isFile() && e.name.endsWith(".agent.md") ?
|
|
12127
|
+
(e, dir) => e.isFile() && e.name.endsWith(".agent.md") ? path35.join(dir, e.name) : void 0,
|
|
12045
12128
|
parseAgentAt
|
|
12046
12129
|
);
|
|
12047
12130
|
for (const { item: m, file, source } of picked) {
|
|
@@ -12078,8 +12161,8 @@ var init_registry7 = __esm({
|
|
|
12078
12161
|
});
|
|
12079
12162
|
|
|
12080
12163
|
// ../core/src/commands/loader.ts
|
|
12081
|
-
import
|
|
12082
|
-
import
|
|
12164
|
+
import fs34 from "fs/promises";
|
|
12165
|
+
import path36 from "path";
|
|
12083
12166
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
12084
12167
|
var BUILTIN_DIR3, SOURCES4, MAX_COMMAND_BODY_BYTES, parseCommandAt, loadCommands, initCommands;
|
|
12085
12168
|
var init_loader7 = __esm({
|
|
@@ -12089,17 +12172,17 @@ var init_loader7 = __esm({
|
|
|
12089
12172
|
init_frontmatter();
|
|
12090
12173
|
init_registry7();
|
|
12091
12174
|
init_registry2();
|
|
12092
|
-
BUILTIN_DIR3 =
|
|
12175
|
+
BUILTIN_DIR3 = path36.join(path36.dirname(fileURLToPath4(import.meta.url)), "builtin");
|
|
12093
12176
|
SOURCES4 = [
|
|
12094
12177
|
{ dir: BUILTIN_DIR3, source: "builtin" },
|
|
12095
|
-
{ dir:
|
|
12096
|
-
{ dir:
|
|
12178
|
+
{ dir: path36.join(appConfig.dataDir, "commands"), source: "global" },
|
|
12179
|
+
{ dir: path36.join(process.cwd(), ".deepseeker-code", "commands"), source: "project" }
|
|
12097
12180
|
];
|
|
12098
12181
|
MAX_COMMAND_BODY_BYTES = 64 * 1024;
|
|
12099
12182
|
parseCommandAt = async (file, _dir, source) => {
|
|
12100
12183
|
let raw;
|
|
12101
12184
|
try {
|
|
12102
|
-
raw = await
|
|
12185
|
+
raw = await fs34.readFile(file, "utf-8");
|
|
12103
12186
|
} catch {
|
|
12104
12187
|
return null;
|
|
12105
12188
|
}
|
|
@@ -12110,7 +12193,7 @@ var init_loader7 = __esm({
|
|
|
12110
12193
|
}
|
|
12111
12194
|
const name = parsed.frontmatter.name;
|
|
12112
12195
|
const description = parsed.frontmatter.description;
|
|
12113
|
-
const fallbackName =
|
|
12196
|
+
const fallbackName = path36.basename(file, ".md");
|
|
12114
12197
|
const finalName = name || fallbackName;
|
|
12115
12198
|
if (!description) {
|
|
12116
12199
|
console.warn(`\u26A0\uFE0F [commands] \u7F3A\u5C11 description\uFF08${file}\uFF09\uFF0C\u5DF2\u8DF3\u8FC7`);
|
|
@@ -12136,7 +12219,7 @@ var init_loader7 = __esm({
|
|
|
12136
12219
|
loadCommands = async (includeProject) => {
|
|
12137
12220
|
const picked = await scanSources(
|
|
12138
12221
|
filterSources(SOURCES4, includeProject),
|
|
12139
|
-
(e, dir) => e.isFile() && e.name.endsWith(".md") ?
|
|
12222
|
+
(e, dir) => e.isFile() && e.name.endsWith(".md") ? path36.join(dir, e.name) : void 0,
|
|
12140
12223
|
parseCommandAt
|
|
12141
12224
|
);
|
|
12142
12225
|
for (const { item } of picked) registerCommand(item);
|
|
@@ -12154,8 +12237,8 @@ var init_loader7 = __esm({
|
|
|
12154
12237
|
});
|
|
12155
12238
|
|
|
12156
12239
|
// ../core/src/outputStyles/loader.ts
|
|
12157
|
-
import
|
|
12158
|
-
import
|
|
12240
|
+
import fs35 from "fs/promises";
|
|
12241
|
+
import path37 from "path";
|
|
12159
12242
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
12160
12243
|
var BUILTIN_DIR4, MAX_STYLE_BODY_BYTES, SOURCES5, parseStyleAt, loadOutputStyles, initOutputStyles;
|
|
12161
12244
|
var init_loader8 = __esm({
|
|
@@ -12165,17 +12248,17 @@ var init_loader8 = __esm({
|
|
|
12165
12248
|
init_frontmatter();
|
|
12166
12249
|
init_registry5();
|
|
12167
12250
|
init_registry2();
|
|
12168
|
-
BUILTIN_DIR4 =
|
|
12251
|
+
BUILTIN_DIR4 = path37.join(path37.dirname(fileURLToPath5(import.meta.url)), "builtin");
|
|
12169
12252
|
MAX_STYLE_BODY_BYTES = 64 * 1024;
|
|
12170
12253
|
SOURCES5 = [
|
|
12171
12254
|
{ dir: BUILTIN_DIR4, source: "builtin" },
|
|
12172
|
-
{ dir:
|
|
12173
|
-
{ dir:
|
|
12255
|
+
{ dir: path37.join(appConfig.dataDir, "output-styles"), source: "global" },
|
|
12256
|
+
{ dir: path37.join(process.cwd(), ".deepseeker-code", "output-styles"), source: "project" }
|
|
12174
12257
|
];
|
|
12175
12258
|
parseStyleAt = async (file, _dir, source) => {
|
|
12176
12259
|
let raw;
|
|
12177
12260
|
try {
|
|
12178
|
-
raw = await
|
|
12261
|
+
raw = await fs35.readFile(file, "utf-8");
|
|
12179
12262
|
} catch {
|
|
12180
12263
|
return null;
|
|
12181
12264
|
}
|
|
@@ -12207,7 +12290,7 @@ var init_loader8 = __esm({
|
|
|
12207
12290
|
loadOutputStyles = async (includeProject) => {
|
|
12208
12291
|
const picked = await scanSources(
|
|
12209
12292
|
filterSources(SOURCES5, includeProject),
|
|
12210
|
-
(e, dir) => e.isFile() && e.name.endsWith(".md") ?
|
|
12293
|
+
(e, dir) => e.isFile() && e.name.endsWith(".md") ? path37.join(dir, e.name) : void 0,
|
|
12211
12294
|
parseStyleAt
|
|
12212
12295
|
);
|
|
12213
12296
|
for (const { item } of picked) registerOutputStyle(item);
|
|
@@ -12288,8 +12371,8 @@ var init_bootstrap = __esm({
|
|
|
12288
12371
|
});
|
|
12289
12372
|
|
|
12290
12373
|
// ../core/src/statusLine/config.ts
|
|
12291
|
-
import
|
|
12292
|
-
import
|
|
12374
|
+
import fs36 from "fs/promises";
|
|
12375
|
+
import path38 from "path";
|
|
12293
12376
|
var parseBlock, readStatusLineConfig;
|
|
12294
12377
|
var init_config2 = __esm({
|
|
12295
12378
|
"../core/src/statusLine/config.ts"() {
|
|
@@ -12305,16 +12388,16 @@ var init_config2 = __esm({
|
|
|
12305
12388
|
};
|
|
12306
12389
|
readStatusLineConfig = async (includeProject) => {
|
|
12307
12390
|
const paths = [
|
|
12308
|
-
|
|
12391
|
+
path38.join(appConfig.dataDir, "settings.json"),
|
|
12309
12392
|
// 全局用户级
|
|
12310
|
-
...includeProject ? [
|
|
12393
|
+
...includeProject ? [path38.join(process.cwd(), ".deepseeker-code", "settings.json")] : []
|
|
12311
12394
|
// 项目级(覆盖);未信任时省略
|
|
12312
12395
|
];
|
|
12313
12396
|
let result = null;
|
|
12314
12397
|
for (const configPath of paths) {
|
|
12315
12398
|
let raw;
|
|
12316
12399
|
try {
|
|
12317
|
-
raw = await
|
|
12400
|
+
raw = await fs36.readFile(configPath, "utf-8");
|
|
12318
12401
|
} catch {
|
|
12319
12402
|
continue;
|
|
12320
12403
|
}
|
|
@@ -12334,8 +12417,8 @@ var init_config2 = __esm({
|
|
|
12334
12417
|
|
|
12335
12418
|
// ../core/src/statusLine/runner.ts
|
|
12336
12419
|
import { spawn as spawn5 } from "child_process";
|
|
12337
|
-
import
|
|
12338
|
-
import
|
|
12420
|
+
import fs37 from "fs";
|
|
12421
|
+
import path39 from "path";
|
|
12339
12422
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
12340
12423
|
var STATUSLINE_TIMEOUT_MS, cachedVersion, runStatusLine;
|
|
12341
12424
|
var init_runner = __esm({
|
|
@@ -12344,16 +12427,16 @@ var init_runner = __esm({
|
|
|
12344
12427
|
init_guard();
|
|
12345
12428
|
STATUSLINE_TIMEOUT_MS = 3e3;
|
|
12346
12429
|
try {
|
|
12347
|
-
const here =
|
|
12430
|
+
const here = path39.dirname(fileURLToPath6(import.meta.url));
|
|
12348
12431
|
const candidates = [
|
|
12349
|
-
|
|
12432
|
+
path39.join(here, "../../../package.json"),
|
|
12350
12433
|
// src/core/package.json
|
|
12351
|
-
|
|
12434
|
+
path39.join(here, "../../../../package.json")
|
|
12352
12435
|
// 仓库根 package.json
|
|
12353
12436
|
];
|
|
12354
12437
|
for (const p of candidates) {
|
|
12355
12438
|
try {
|
|
12356
|
-
const pkg = JSON.parse(
|
|
12439
|
+
const pkg = JSON.parse(fs37.readFileSync(p, "utf-8"));
|
|
12357
12440
|
if (typeof pkg.version === "string" && pkg.version) {
|
|
12358
12441
|
cachedVersion = pkg.version;
|
|
12359
12442
|
break;
|
|
@@ -12404,8 +12487,8 @@ var init_runner = __esm({
|
|
|
12404
12487
|
});
|
|
12405
12488
|
|
|
12406
12489
|
// ../core/src/observability/store.ts
|
|
12407
|
-
import
|
|
12408
|
-
import
|
|
12490
|
+
import path40 from "path";
|
|
12491
|
+
import fs38 from "fs/promises";
|
|
12409
12492
|
var getTraceDirPath, getTracePath, tracePathCache, ensuredTraceDirs, ensureTraceDir, getGlobalClockPath, getTraceStorePath;
|
|
12410
12493
|
var init_store3 = __esm({
|
|
12411
12494
|
"../core/src/observability/store.ts"() {
|
|
@@ -12415,21 +12498,21 @@ var init_store3 = __esm({
|
|
|
12415
12498
|
init_common();
|
|
12416
12499
|
getTraceDirPath = (mainTraceId) => {
|
|
12417
12500
|
assertSafeSessionId(mainTraceId, "traceId");
|
|
12418
|
-
return
|
|
12501
|
+
return path40.join(appConfig.dataDir, "trace", appConfig.userWorkspaceDir, getFileName(mainTraceId));
|
|
12419
12502
|
};
|
|
12420
12503
|
getTracePath = () => {
|
|
12421
|
-
return
|
|
12504
|
+
return path40.join(appConfig.dataDir, "trace");
|
|
12422
12505
|
};
|
|
12423
12506
|
tracePathCache = /* @__PURE__ */ new Map();
|
|
12424
12507
|
ensuredTraceDirs = /* @__PURE__ */ new Set();
|
|
12425
12508
|
ensureTraceDir = async (mainTraceId) => {
|
|
12426
12509
|
const dir = getTraceDirPath(mainTraceId);
|
|
12427
12510
|
if (ensuredTraceDirs.has(dir)) return;
|
|
12428
|
-
await
|
|
12511
|
+
await fs38.mkdir(dir, { recursive: true });
|
|
12429
12512
|
ensuredTraceDirs.add(dir);
|
|
12430
12513
|
};
|
|
12431
12514
|
getGlobalClockPath = () => {
|
|
12432
|
-
return
|
|
12515
|
+
return path40.join(getTracePath(), "trace-cleanup-clock.json");
|
|
12433
12516
|
};
|
|
12434
12517
|
getTraceStorePath = async (mainTraceId) => {
|
|
12435
12518
|
assertSafeSessionId(mainTraceId, "traceId");
|
|
@@ -12438,7 +12521,7 @@ var init_store3 = __esm({
|
|
|
12438
12521
|
if (cached2) return cached2;
|
|
12439
12522
|
await ensureTraceDir(rootId);
|
|
12440
12523
|
const dir = getTraceDirPath(rootId);
|
|
12441
|
-
const files = await
|
|
12524
|
+
const files = await fs38.readdir(dir);
|
|
12442
12525
|
const existedFile = files.find((f) => f.endsWith(`__${rootId}.jsonl`));
|
|
12443
12526
|
let fileName = "";
|
|
12444
12527
|
if (existedFile) {
|
|
@@ -12447,7 +12530,7 @@ var init_store3 = __esm({
|
|
|
12447
12530
|
const todayStr = getTodayDateString();
|
|
12448
12531
|
fileName = `trace-${todayStr}__${rootId}.jsonl`;
|
|
12449
12532
|
}
|
|
12450
|
-
const resolved =
|
|
12533
|
+
const resolved = path40.join(dir, fileName);
|
|
12451
12534
|
tracePathCache.set(rootId, resolved);
|
|
12452
12535
|
return resolved;
|
|
12453
12536
|
};
|
|
@@ -12455,8 +12538,8 @@ var init_store3 = __esm({
|
|
|
12455
12538
|
});
|
|
12456
12539
|
|
|
12457
12540
|
// ../core/src/observability/trace.ts
|
|
12458
|
-
import
|
|
12459
|
-
import
|
|
12541
|
+
import fs39 from "fs/promises";
|
|
12542
|
+
import path41 from "path";
|
|
12460
12543
|
async function emitTrace(base) {
|
|
12461
12544
|
const event = {
|
|
12462
12545
|
sessionId: base.sessionId,
|
|
@@ -12478,7 +12561,7 @@ async function emitTrace(base) {
|
|
|
12478
12561
|
async function appendTraceEvent(event) {
|
|
12479
12562
|
const p = await getTraceStorePath(event.sessionId);
|
|
12480
12563
|
const line = JSON.stringify(event) + "\n";
|
|
12481
|
-
await
|
|
12564
|
+
await fs39.appendFile(p, line, "utf-8");
|
|
12482
12565
|
if (workspaceTraceBytes < 0) {
|
|
12483
12566
|
workspaceTraceBytes = await getDirBytes(getTracePath());
|
|
12484
12567
|
}
|
|
@@ -12510,8 +12593,8 @@ async function maybeCleanupAfterAppend(sessionId) {
|
|
|
12510
12593
|
lastSizeCleanupAt2 = now;
|
|
12511
12594
|
diskLastCleanupAt2 = now;
|
|
12512
12595
|
const clockPath = getGlobalClockPath();
|
|
12513
|
-
await
|
|
12514
|
-
await
|
|
12596
|
+
await fs39.mkdir(path41.dirname(clockPath), { recursive: true });
|
|
12597
|
+
await fs39.writeFile(clockPath, JSON.stringify({ lastCleanupAt: now, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), "utf-8");
|
|
12515
12598
|
if (deletedCount > 0) {
|
|
12516
12599
|
console.log(`\u2728 [Trace\u8FD0\u7EF4] \u5171\u9500\u6BC1 ${deletedCount} \u4E2A\u4F1A\u8BDD\u65E5\u5FD7\uFF08\u8F6F\u89C4\u5219\u8FC7\u671F\u6E05\u7406 + \u5BB9\u91CF\u786C\u9A71\u9010\uFF09\uFF0C\u78C1\u76D8\u6C34\u4F4D\u56DE\u843D\u3002`);
|
|
12517
12600
|
}
|
|
@@ -12531,22 +12614,22 @@ async function cleanupOldTraceFiles() {
|
|
|
12531
12614
|
let deleted = 0;
|
|
12532
12615
|
let relativePaths;
|
|
12533
12616
|
try {
|
|
12534
|
-
relativePaths = await
|
|
12617
|
+
relativePaths = await fs39.readdir(dir, { recursive: true });
|
|
12535
12618
|
} catch {
|
|
12536
12619
|
return 0;
|
|
12537
12620
|
}
|
|
12538
12621
|
const re = /^trace-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
|
|
12539
12622
|
for (const relativePath of relativePaths) {
|
|
12540
|
-
const fileName =
|
|
12623
|
+
const fileName = path41.basename(relativePath);
|
|
12541
12624
|
const m = fileName.match(re);
|
|
12542
12625
|
if (!m) continue;
|
|
12543
12626
|
const fileBornDay = /* @__PURE__ */ new Date(`${m[1]}T00:00:00`);
|
|
12544
12627
|
if (fileBornDay >= cutoff) continue;
|
|
12545
|
-
const fullPath =
|
|
12628
|
+
const fullPath = path41.join(dir, relativePath);
|
|
12546
12629
|
try {
|
|
12547
|
-
const st = await
|
|
12630
|
+
const st = await fs39.stat(fullPath);
|
|
12548
12631
|
if (now - st.mtimeMs < ACTIVE_GRACE_MS2) continue;
|
|
12549
|
-
await
|
|
12632
|
+
await fs39.unlink(fullPath);
|
|
12550
12633
|
deleted += 1;
|
|
12551
12634
|
} catch {
|
|
12552
12635
|
}
|
|
@@ -12557,18 +12640,18 @@ async function evictOldestForSize2(targetBytes) {
|
|
|
12557
12640
|
const dir = getTracePath();
|
|
12558
12641
|
let relativePaths;
|
|
12559
12642
|
try {
|
|
12560
|
-
relativePaths = await
|
|
12643
|
+
relativePaths = await fs39.readdir(dir, { recursive: true });
|
|
12561
12644
|
} catch {
|
|
12562
12645
|
return 0;
|
|
12563
12646
|
}
|
|
12564
12647
|
const re = /^trace-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
|
|
12565
12648
|
const candidates = [];
|
|
12566
12649
|
for (const relativePath of relativePaths) {
|
|
12567
|
-
const fileName =
|
|
12650
|
+
const fileName = path41.basename(relativePath);
|
|
12568
12651
|
if (!re.test(fileName)) continue;
|
|
12569
12652
|
try {
|
|
12570
|
-
const st = await
|
|
12571
|
-
candidates.push({ mtime: st.mtimeMs, fullPath:
|
|
12653
|
+
const st = await fs39.stat(path41.join(dir, relativePath));
|
|
12654
|
+
candidates.push({ mtime: st.mtimeMs, fullPath: path41.join(dir, relativePath), size: st.size });
|
|
12572
12655
|
} catch {
|
|
12573
12656
|
}
|
|
12574
12657
|
}
|
|
@@ -12578,7 +12661,7 @@ async function evictOldestForSize2(targetBytes) {
|
|
|
12578
12661
|
for (const c of candidates) {
|
|
12579
12662
|
if (totalBytes <= targetBytes) break;
|
|
12580
12663
|
try {
|
|
12581
|
-
await
|
|
12664
|
+
await fs39.unlink(c.fullPath);
|
|
12582
12665
|
totalBytes -= c.size;
|
|
12583
12666
|
deleted += 1;
|
|
12584
12667
|
} catch {
|
|
@@ -12610,7 +12693,7 @@ var init_trace = __esm({
|
|
|
12610
12693
|
if (clockLoaded2) return;
|
|
12611
12694
|
clockLoaded2 = true;
|
|
12612
12695
|
try {
|
|
12613
|
-
const rawClock = await
|
|
12696
|
+
const rawClock = await fs39.readFile(getGlobalClockPath(), "utf-8");
|
|
12614
12697
|
diskLastCleanupAt2 = JSON.parse(rawClock).lastCleanupAt || 0;
|
|
12615
12698
|
} catch {
|
|
12616
12699
|
diskLastCleanupAt2 = 0;
|
|
@@ -12757,8 +12840,8 @@ ${PLAN_MODE_AUTO_ENTER_HINT}
|
|
|
12757
12840
|
});
|
|
12758
12841
|
|
|
12759
12842
|
// ../core/src/serve/chatProcessing.ts
|
|
12760
|
-
import
|
|
12761
|
-
import
|
|
12843
|
+
import path42 from "path";
|
|
12844
|
+
import fs40 from "fs";
|
|
12762
12845
|
var handleUnifiedChat;
|
|
12763
12846
|
var init_chatProcessing = __esm({
|
|
12764
12847
|
"../core/src/serve/chatProcessing.ts"() {
|
|
@@ -12771,6 +12854,7 @@ var init_chatProcessing = __esm({
|
|
|
12771
12854
|
init_transcript();
|
|
12772
12855
|
init_content();
|
|
12773
12856
|
init_contentParts();
|
|
12857
|
+
init_visionCapability();
|
|
12774
12858
|
init_trace();
|
|
12775
12859
|
init_webHost();
|
|
12776
12860
|
init_registry();
|
|
@@ -12813,17 +12897,17 @@ ${inject}`;
|
|
|
12813
12897
|
if (roots.length > 1) {
|
|
12814
12898
|
let activeReal = getActiveWorkspaceRoot();
|
|
12815
12899
|
try {
|
|
12816
|
-
activeReal =
|
|
12900
|
+
activeReal = fs40.realpathSync(activeReal);
|
|
12817
12901
|
} catch {
|
|
12818
12902
|
}
|
|
12819
|
-
const lines = roots.map((r) => `- ${
|
|
12903
|
+
const lines = roots.map((r) => `- ${path42.basename(r) || r}: ${r}${r === activeReal ? "\uFF08\u9ED8\u8BA4\u6839\uFF1A\u76F8\u5BF9\u8DEF\u5F84/\u547D\u4EE4\u57FA\u51C6\uFF09" : "\uFF08\u53EF\u76F4\u63A5\u8BFB\u5199\uFF09"}`);
|
|
12820
12904
|
sysPrompt = sysPrompt + `
|
|
12821
12905
|
|
|
12822
12906
|
\u3010\u5DE5\u4F5C\u533A\uFF08\u591A\u9879\u76EE\uFF09\u3011
|
|
12823
12907
|
\u65E0\u9700\u5207\u6362\u9879\u76EE\uFF0C\u4EE5\u4E0B\u6240\u6709\u6839\u90FD\u53EF\u76F4\u63A5\u7528\u7EDD\u5BF9\u8DEF\u5F84\u8BBF\u95EE\uFF1B\u8DE8\u9879\u76EE\u7528\u7EDD\u5BF9\u8DEF\u5F84\u6216\u76F8\u5BF9\u9ED8\u8BA4\u6839\u7684 ../<\u5144\u5F1F\u76EE\u5F55>:
|
|
12824
12908
|
${lines.join("\n")}
|
|
12825
|
-
\u2605 \u8DEF\u5F84\u951A\u5B9A\u94C1\u5F8B\uFF1A\u5DE5\u5177\u7F3A\u7701\u53EA\u4F5C\u7528\u4E8E\u9ED8\u8BA4\u6839\uFF08${
|
|
12826
|
-
\u6CE8\u610F\uFF1A\u9879\u76EE\u7EA7\u914D\u7F6E\uFF08.deepseeker-code/\uFF09\u4EC5\u5728\u9ED8\u8BA4\u6839 ${
|
|
12909
|
+
\u2605 \u8DEF\u5F84\u951A\u5B9A\u94C1\u5F8B\uFF1A\u5DE5\u5177\u7F3A\u7701\u53EA\u4F5C\u7528\u4E8E\u9ED8\u8BA4\u6839\uFF08${path42.basename(activeReal) || activeReal} = IDE \u5934\u90E8\u6240\u793A\u6839\uFF09\u3002\u5F53\u7528\u6237\u5728\u5BF9\u8BDD\u4E2D\u6307\u660E\u4E86\u67D0\u4E2A\u9879\u76EE\uFF08\u5982\u300C\u5728 A \u9879\u76EE\u300D\u300C\u6539\u524D\u7AEF\u7684 xxx\u300D\u300C\u641C\u540E\u7AEF\u300D\uFF09\uFF0C\u8BE5\u8F6E\u6240\u6709\u5E26 path \u53C2\u6570\u7684\u5DE5\u5177\u8C03\u7528\uFF08read_file / edit_file / search_grep / glob / list_dir / read_xlsx / read_docx \u7B49\uFF09\u5FC5\u987B\u628A\u5BF9\u5E94\u9879\u76EE\u6839\u4F5C\u4E3A path \u4F20\u5165\uFF08\u7EDD\u5BF9\u8DEF\u5F84\u3001../<\u5144\u5F1F\u76EE\u5F55>\u3001\u6216\u9879\u76EE\u76EE\u5F55\u540D\uFF09\uFF0C\u5426\u5219\u53EA\u4F1A\u8BFB\u5199/\u641C\u7D22\u9ED8\u8BA4\u6839\uFF0C\u4E0E\u7528\u6237\u610F\u56FE\u4E0D\u7B26\u3002
|
|
12910
|
+
\u6CE8\u610F\uFF1A\u9879\u76EE\u7EA7\u914D\u7F6E\uFF08.deepseeker-code/\uFF09\u4EC5\u5728\u9ED8\u8BA4\u6839 ${path42.basename(activeReal) || activeReal} \u751F\u6548\u3002`;
|
|
12827
12911
|
}
|
|
12828
12912
|
const osName = process.platform === "win32" ? "Windows" : process.platform === "darwin" ? "macOS" : "Linux";
|
|
12829
12913
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -12840,6 +12924,7 @@ ${lines.join("\n")}
|
|
|
12840
12924
|
\u3010\u73AF\u5883\u3011
|
|
12841
12925
|
${envLines.join("\n")}`;
|
|
12842
12926
|
let replyText = "";
|
|
12927
|
+
await ensureVisionCacheLoaded();
|
|
12843
12928
|
const { wire: userContent, archive: archiveContent } = toIngestContents(inbound.content, inbound.attachments, opts?.model);
|
|
12844
12929
|
try {
|
|
12845
12930
|
const fullMessages = await buildContextMessages(
|
|
@@ -12927,7 +13012,7 @@ ${envLines.join("\n")}`;
|
|
|
12927
13012
|
});
|
|
12928
13013
|
|
|
12929
13014
|
// ../core/src/session/fork.ts
|
|
12930
|
-
import
|
|
13015
|
+
import fs41 from "fs/promises";
|
|
12931
13016
|
var listForkAnchors, derivePrefix, forkSession;
|
|
12932
13017
|
var init_fork = __esm({
|
|
12933
13018
|
"../core/src/session/fork.ts"() {
|
|
@@ -13000,7 +13085,7 @@ var init_fork = __esm({
|
|
|
13000
13085
|
const prefix = derivePrefix(lines, upToLineId);
|
|
13001
13086
|
const newId = createUUID();
|
|
13002
13087
|
await ensureSessionsDir(newId);
|
|
13003
|
-
const rawText = await
|
|
13088
|
+
const rawText = await fs41.readFile(getTranscriptPath(sourceId), "utf-8");
|
|
13004
13089
|
const kept = [];
|
|
13005
13090
|
let good = 0;
|
|
13006
13091
|
for (const s of rawText.split("\n")) {
|
|
@@ -13016,7 +13101,7 @@ var init_fork = __esm({
|
|
|
13016
13101
|
}
|
|
13017
13102
|
let payload = kept.join("\n");
|
|
13018
13103
|
if (payload.length > 0 && !payload.endsWith("\n")) payload += "\n";
|
|
13019
|
-
await
|
|
13104
|
+
await fs41.writeFile(getTranscriptPath(newId), payload, "utf-8");
|
|
13020
13105
|
const srcState = await readStore(sourceId);
|
|
13021
13106
|
const srcRolling = await getRollingState(sourceId);
|
|
13022
13107
|
const legacy = !lines.some(isEventLine);
|
|
@@ -13558,6 +13643,9 @@ var init_useChatState = __esm({
|
|
|
13558
13643
|
}
|
|
13559
13644
|
break;
|
|
13560
13645
|
}
|
|
13646
|
+
case "vision.downgraded":
|
|
13647
|
+
pushInfo(`\u{1F5BC} \u6A21\u578B ${String(obj.model ?? "")} \u4E0D\u652F\u6301\u56FE\u7247\uFF0C\u5DF2\u81EA\u52A8\u964D\u7EA7\u4E3A\u6587\u672C\u5904\u7406\uFF08\u5DF2\u8BB0\u4F4F\uFF0C\u540E\u7EED\u6D88\u606F\u76F4\u63A5\u6309\u6587\u672C\u53D1\u9001\uFF09`);
|
|
13648
|
+
break;
|
|
13561
13649
|
default:
|
|
13562
13650
|
break;
|
|
13563
13651
|
}
|
|
@@ -13811,9 +13899,9 @@ ${r.output.trim() || "(\u65E0\u8F93\u51FA)"}`);
|
|
|
13811
13899
|
modelRef.current = m;
|
|
13812
13900
|
void writePrefs({ model: m });
|
|
13813
13901
|
}, []);
|
|
13814
|
-
const resolveModel = useCallback((
|
|
13902
|
+
const resolveModel = useCallback((model) => {
|
|
13815
13903
|
setPendingModel((prev) => {
|
|
13816
|
-
prev?.resolve(
|
|
13904
|
+
prev?.resolve(model);
|
|
13817
13905
|
return null;
|
|
13818
13906
|
});
|
|
13819
13907
|
}, []);
|
|
@@ -13823,6 +13911,7 @@ ${r.output.trim() || "(\u65E0\u8F93\u51FA)"}`);
|
|
|
13823
13911
|
setModelOverride(picked);
|
|
13824
13912
|
pushInfo(S.modelSwitched(picked));
|
|
13825
13913
|
}
|
|
13914
|
+
return picked;
|
|
13826
13915
|
}, [pushInfo, setModelOverride]);
|
|
13827
13916
|
const setPlanMode = useCallback((on) => {
|
|
13828
13917
|
planModeRef.current = on;
|
|
@@ -14865,11 +14954,11 @@ var init_StatusStrip = __esm({
|
|
|
14865
14954
|
"use strict";
|
|
14866
14955
|
init_theme();
|
|
14867
14956
|
init_strings();
|
|
14868
|
-
StatusStrip = ({ model
|
|
14957
|
+
StatusStrip = ({ model, busy, aborting, planMode, autoMode, sessionShort, customLine }) => {
|
|
14869
14958
|
const stateText = aborting ? S.statusAborting : busy ? S.statusStreaming : S.statusIdle;
|
|
14870
14959
|
const stateColor = busy ? THEME.coralBright : THEME.gray;
|
|
14871
14960
|
const bits = [
|
|
14872
|
-
|
|
14961
|
+
model ? `model: ${model}` : "",
|
|
14873
14962
|
planMode ? S.statusPlan : "",
|
|
14874
14963
|
autoMode ? S.statusAuto : "",
|
|
14875
14964
|
`state: ${stateText}`,
|
|
@@ -14945,7 +15034,7 @@ var init_TopPanel = __esm({
|
|
|
14945
15034
|
});
|
|
14946
15035
|
|
|
14947
15036
|
// ../core/src/observability/inspect.ts
|
|
14948
|
-
import
|
|
15037
|
+
import fs42 from "fs";
|
|
14949
15038
|
var CWD, fmt, readTrace, inspectUsage, inspectContext, inspectPermissions, inspectMcp, inspectHooks, inspectDebug;
|
|
14950
15039
|
var init_inspect = __esm({
|
|
14951
15040
|
"../core/src/observability/inspect.ts"() {
|
|
@@ -14963,7 +15052,7 @@ var init_inspect = __esm({
|
|
|
14963
15052
|
if (!sessionId) return [];
|
|
14964
15053
|
try {
|
|
14965
15054
|
const p = await getTraceStorePath(sessionId);
|
|
14966
|
-
const text = await
|
|
15055
|
+
const text = await fs42.promises.readFile(p, "utf8");
|
|
14967
15056
|
const out = [];
|
|
14968
15057
|
for (const line of text.split("\n")) {
|
|
14969
15058
|
if (!line.trim()) continue;
|
|
@@ -15088,7 +15177,7 @@ __export(App_exports, {
|
|
|
15088
15177
|
import { useCallback as useCallback2, useEffect as useEffect4, useMemo, useRef as useRef2, useState as useState4 } from "react";
|
|
15089
15178
|
import { Box as Box16, Static, Text as Text18, useApp, useInput as useInput2, useStdout } from "ink";
|
|
15090
15179
|
import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
15091
|
-
var CWD2, RowView, isDynamicRow, App;
|
|
15180
|
+
var CWD2, RowView, isDynamicRow, SPINNER_FRAMES, App;
|
|
15092
15181
|
var init_App = __esm({
|
|
15093
15182
|
"src/App.tsx"() {
|
|
15094
15183
|
"use strict";
|
|
@@ -15133,6 +15222,7 @@ var init_App = __esm({
|
|
|
15133
15222
|
return /* @__PURE__ */ jsx18(MessageBlock, { row, wrapW, streamTail });
|
|
15134
15223
|
};
|
|
15135
15224
|
isDynamicRow = (r) => r.kind === "assistant" && !!r.streaming || r.kind === "thinking" && !!r.streaming || r.kind === "tool" && r.status === "running" || r.kind === "todos" && !!r.active;
|
|
15225
|
+
SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
15136
15226
|
App = ({ resumeSessionId, initialPlanMode, initialAutoMode, initialIncludeProject, engineReady }) => {
|
|
15137
15227
|
const state = useChatState(resumeSessionId, initialPlanMode, initialAutoMode);
|
|
15138
15228
|
const { exit } = useApp();
|
|
@@ -15286,6 +15376,24 @@ var init_App = __esm({
|
|
|
15286
15376
|
return menuEntries.filter((c) => c.name.toLowerCase().startsWith(q));
|
|
15287
15377
|
}, [input, menuEntries]);
|
|
15288
15378
|
const menuActive = state.pendingApproval != null || state.pendingQuestion != null || state.pendingPlan != null || state.pendingSessions != null || state.pendingFork != null || state.pendingModel != null;
|
|
15379
|
+
const [busyClock, setBusyClock] = useState4({ frame: 0, sec: 0 });
|
|
15380
|
+
const busyStartRef = useRef2(0);
|
|
15381
|
+
useEffect4(() => {
|
|
15382
|
+
if (!state.busy) {
|
|
15383
|
+
busyStartRef.current = 0;
|
|
15384
|
+
setBusyClock((c) => c.frame === 0 && c.sec === 0 ? c : { frame: 0, sec: 0 });
|
|
15385
|
+
return;
|
|
15386
|
+
}
|
|
15387
|
+
if (busyStartRef.current === 0) busyStartRef.current = Date.now();
|
|
15388
|
+
if (menuActive) return;
|
|
15389
|
+
const drive = () => setBusyClock({
|
|
15390
|
+
frame: Math.floor(Date.now() / 120) % SPINNER_FRAMES.length,
|
|
15391
|
+
sec: Math.floor((Date.now() - busyStartRef.current) / 1e3)
|
|
15392
|
+
});
|
|
15393
|
+
drive();
|
|
15394
|
+
const t = setInterval(drive, 120);
|
|
15395
|
+
return () => clearInterval(t);
|
|
15396
|
+
}, [state.busy, menuActive]);
|
|
15289
15397
|
const slashVisible = !menuActive && input.startsWith("/") && filteredCommands.length > 0;
|
|
15290
15398
|
const inputActive = !menuActive;
|
|
15291
15399
|
useEffect4(() => {
|
|
@@ -15386,7 +15494,9 @@ ${list}
|
|
|
15386
15494
|
state.pushInfo(S.modelSwitched(arg));
|
|
15387
15495
|
return true;
|
|
15388
15496
|
case "/switch":
|
|
15389
|
-
void state.openModelPicker()
|
|
15497
|
+
void state.openModelPicker().then((picked) => {
|
|
15498
|
+
if (picked) setModelDisplay(picked);
|
|
15499
|
+
});
|
|
15390
15500
|
return true;
|
|
15391
15501
|
case "/thinking": {
|
|
15392
15502
|
const lvl = arg.toLowerCase();
|
|
@@ -15632,10 +15742,7 @@ ${listText}`);
|
|
|
15632
15742
|
/* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", width: cols, children: [
|
|
15633
15743
|
menuActive ? null : /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", paddingX: 1, children: [
|
|
15634
15744
|
dynamicRows.map((row) => /* @__PURE__ */ jsx18(RowView, { row, wrapW, streamTail, showThinking: state.showThinkingText }, row.id)),
|
|
15635
|
-
state.busy ? /* @__PURE__ */ jsx18(Box16, { marginTop: 0.5, children: /* @__PURE__ */
|
|
15636
|
-
"\u25CF ",
|
|
15637
|
-
S.generating
|
|
15638
|
-
] }) }) : null
|
|
15745
|
+
state.busy ? /* @__PURE__ */ jsx18(Box16, { marginTop: 0.5, children: /* @__PURE__ */ jsx18(Text18, { color: THEME.coralBright, children: `${SPINNER_FRAMES[busyClock.frame]} ${S.generating} (${busyClock.sec}s \xB7 ${S.escInterrupt})` }) }) : null
|
|
15639
15746
|
] }),
|
|
15640
15747
|
/* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", paddingX: 1, flexShrink: 0, children: [
|
|
15641
15748
|
state.pendingApproval ? /* @__PURE__ */ jsx18(ApprovalModal, { toolName: state.pendingApproval.toolName, detail: state.pendingApproval.detail, selectedIndex: selectIdx, wrapW }) : null,
|
|
@@ -15756,7 +15863,7 @@ init_updateCheck();
|
|
|
15756
15863
|
init_trust();
|
|
15757
15864
|
import { render } from "ink";
|
|
15758
15865
|
import os5 from "os";
|
|
15759
|
-
import
|
|
15866
|
+
import path43 from "path";
|
|
15760
15867
|
import { emitKeypressEvents } from "node:readline";
|
|
15761
15868
|
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
15762
15869
|
var parseArgs = (argv) => {
|
|
@@ -15889,7 +15996,7 @@ var main = async () => {
|
|
|
15889
15996
|
process.stdout.write("\x1B[2J\x1B[3J\x1B[1;1H");
|
|
15890
15997
|
const cwdIsHome = () => {
|
|
15891
15998
|
try {
|
|
15892
|
-
return
|
|
15999
|
+
return path43.resolve(cwd).toLowerCase() === path43.resolve(os5.homedir()).toLowerCase();
|
|
15893
16000
|
} catch {
|
|
15894
16001
|
return false;
|
|
15895
16002
|
}
|