deepseeker-code 1.0.41 → 1.0.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +525 -374
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -9,12 +9,88 @@ var __export = (target, all) => {
|
|
|
9
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
// src/updateCheck.ts
|
|
13
|
+
var updateCheck_exports = {};
|
|
14
|
+
__export(updateCheck_exports, {
|
|
15
|
+
getCachedLatestIfNewer: () => getCachedLatestIfNewer,
|
|
16
|
+
readLocalVersion: () => readLocalVersion,
|
|
17
|
+
refreshUpdateCache: () => refreshUpdateCache
|
|
18
|
+
});
|
|
19
|
+
import { readFileSync as readFileSync2, writeFileSync, mkdirSync } from "node:fs";
|
|
20
|
+
import path2 from "node:path";
|
|
21
|
+
import os2 from "os";
|
|
22
|
+
import { fileURLToPath } from "node:url";
|
|
23
|
+
var PKG_NAME, REGISTRY, CACHE_TTL_MS, FETCH_TIMEOUT_MS, cacheFile, readLocalVersion, parseSemver, compareVersion, readCache, writeCache, getCachedLatestIfNewer, refreshUpdateCache;
|
|
24
|
+
var init_updateCheck = __esm({
|
|
25
|
+
"src/updateCheck.ts"() {
|
|
26
|
+
"use strict";
|
|
27
|
+
PKG_NAME = "deepseeker-code";
|
|
28
|
+
REGISTRY = "https://registry.npmjs.org";
|
|
29
|
+
CACHE_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
30
|
+
FETCH_TIMEOUT_MS = 3e3;
|
|
31
|
+
cacheFile = () => path2.join(os2.homedir(), ".deepseeker-code", "update-check.json");
|
|
32
|
+
readLocalVersion = () => {
|
|
33
|
+
try {
|
|
34
|
+
const here = path2.dirname(fileURLToPath(import.meta.url));
|
|
35
|
+
return JSON.parse(readFileSync2(path2.join(here, "..", "package.json"), "utf8")).version ?? "0.0.0";
|
|
36
|
+
} catch {
|
|
37
|
+
return "0.0.0";
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
parseSemver = (v) => {
|
|
41
|
+
const m = String(v ?? "").match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
42
|
+
return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : [0, 0, 0];
|
|
43
|
+
};
|
|
44
|
+
compareVersion = (a, b) => {
|
|
45
|
+
const [a1, a2, a3] = parseSemver(a);
|
|
46
|
+
const [b1, b2, b3] = parseSemver(b);
|
|
47
|
+
return a1 - b1 || a2 - b2 || a3 - b3;
|
|
48
|
+
};
|
|
49
|
+
readCache = () => {
|
|
50
|
+
try {
|
|
51
|
+
const obj = JSON.parse(readFileSync2(cacheFile(), "utf8"));
|
|
52
|
+
return typeof obj.latestVersion === "string" && typeof obj.lastCheck === "number" ? obj : null;
|
|
53
|
+
} catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
writeCache = (latestVersion) => {
|
|
58
|
+
try {
|
|
59
|
+
mkdirSync(path2.dirname(cacheFile()), { recursive: true });
|
|
60
|
+
writeFileSync(cacheFile(), JSON.stringify({ lastCheck: Date.now(), latestVersion }), "utf8");
|
|
61
|
+
} catch {
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
getCachedLatestIfNewer = (currentVersion) => {
|
|
65
|
+
const cache = readCache();
|
|
66
|
+
if (!cache) return null;
|
|
67
|
+
return compareVersion(cache.latestVersion, currentVersion) > 0 ? cache.latestVersion : null;
|
|
68
|
+
};
|
|
69
|
+
refreshUpdateCache = () => {
|
|
70
|
+
const cache = readCache();
|
|
71
|
+
if (cache && Date.now() - cache.lastCheck < CACHE_TTL_MS) return;
|
|
72
|
+
void (async () => {
|
|
73
|
+
try {
|
|
74
|
+
const res = await fetch(`${REGISTRY}/${PKG_NAME}/latest`, {
|
|
75
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
|
|
76
|
+
});
|
|
77
|
+
if (!res.ok) return;
|
|
78
|
+
const info = await res.json();
|
|
79
|
+
if (info.version) writeCache(info.version);
|
|
80
|
+
} catch {
|
|
81
|
+
}
|
|
82
|
+
})();
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
12
87
|
// src/strings.ts
|
|
13
88
|
var VERSION, STRINGS, locale, getLocale, setLocale, S, LOCAL_COMMAND_NAMES;
|
|
14
89
|
var init_strings = __esm({
|
|
15
90
|
"src/strings.ts"() {
|
|
16
91
|
"use strict";
|
|
17
|
-
|
|
92
|
+
init_updateCheck();
|
|
93
|
+
VERSION = `v${readLocalVersion()}`;
|
|
18
94
|
STRINGS = {
|
|
19
95
|
zh: {
|
|
20
96
|
brand: "DeepSeeker-Code",
|
|
@@ -317,15 +393,15 @@ __export(config_exports, {
|
|
|
317
393
|
appConfig: () => appConfig,
|
|
318
394
|
configSources: () => configSources
|
|
319
395
|
});
|
|
320
|
-
import
|
|
321
|
-
import
|
|
322
|
-
import { readFileSync as
|
|
396
|
+
import path3 from "path";
|
|
397
|
+
import os3 from "os";
|
|
398
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
323
399
|
import { createHash } from "crypto";
|
|
324
400
|
var _DataDir, appConfig, ENV_SOURCES, configSources, ENGINE_OVERRIDE_VALIDATORS, ENGINE_OVERRIDE_KEYS, applyEngineOverrides;
|
|
325
401
|
var init_config = __esm({
|
|
326
402
|
"../core/src/config/index.ts"() {
|
|
327
403
|
"use strict";
|
|
328
|
-
_DataDir = process.env.DEEPSEEKER_CODE_DATA_DIR ?
|
|
404
|
+
_DataDir = process.env.DEEPSEEKER_CODE_DATA_DIR ? path3.resolve(process.env.DEEPSEEKER_CODE_DATA_DIR) : path3.join(os3.homedir(), ".deepseeker-code");
|
|
329
405
|
appConfig = {
|
|
330
406
|
dataDir: _DataDir,
|
|
331
407
|
maxReasoningRounds: 3,
|
|
@@ -352,8 +428,8 @@ var init_config = __esm({
|
|
|
352
428
|
if (/^[a-z]:/i.test(cwd)) {
|
|
353
429
|
cwd = cwd.charAt(0).toUpperCase() + cwd.slice(1);
|
|
354
430
|
}
|
|
355
|
-
const currentFolder =
|
|
356
|
-
const parentFolder =
|
|
431
|
+
const currentFolder = path3.basename(cwd);
|
|
432
|
+
const parentFolder = path3.basename(path3.dirname(cwd));
|
|
357
433
|
const hash = createHash("sha256").update(cwd).digest("hex").slice(0, 8);
|
|
358
434
|
return `${parentFolder}-${currentFolder}-${hash}`;
|
|
359
435
|
})(),
|
|
@@ -451,15 +527,15 @@ var init_config = __esm({
|
|
|
451
527
|
ENGINE_OVERRIDE_KEYS = Object.keys(ENGINE_OVERRIDE_VALIDATORS);
|
|
452
528
|
applyEngineOverrides = (cfg) => {
|
|
453
529
|
const paths = [
|
|
454
|
-
{ scope: "settings.global", configPath:
|
|
530
|
+
{ scope: "settings.global", configPath: path3.join(cfg.dataDir, "settings.json") },
|
|
455
531
|
// 全局用户级
|
|
456
|
-
{ scope: "settings.project", configPath:
|
|
532
|
+
{ scope: "settings.project", configPath: path3.join(process.cwd(), ".deepseeker-code", "settings.json") }
|
|
457
533
|
// 项目级(覆盖全局)
|
|
458
534
|
];
|
|
459
535
|
for (const { scope, configPath } of paths) {
|
|
460
536
|
let raw;
|
|
461
537
|
try {
|
|
462
|
-
raw =
|
|
538
|
+
raw = readFileSync3(configPath, "utf-8");
|
|
463
539
|
} catch {
|
|
464
540
|
continue;
|
|
465
541
|
}
|
|
@@ -493,7 +569,7 @@ import { randomUUID } from "node:crypto";
|
|
|
493
569
|
import fs from "fs/promises";
|
|
494
570
|
import { execFile } from "node:child_process";
|
|
495
571
|
import { promisify } from "node:util";
|
|
496
|
-
var getFileName, createUUID, SAFE_SESSION_ID_RE, isSafeSessionId, assertSafeSessionId, readJSONFile, atomicWriteJSON, createSemaphore, injectMarkedBlock, decodeProcessOutput, execFileSmart;
|
|
572
|
+
var getFileName, createUUID, SAFE_SESSION_ID_RE, isSafeSessionId, assertSafeSessionId, detectTextLocale, readJSONFile, atomicWriteJSON, createSemaphore, injectMarkedBlock, decodeProcessOutput, execFileSmart;
|
|
497
573
|
var init_common = __esm({
|
|
498
574
|
"../core/src/common/index.ts"() {
|
|
499
575
|
"use strict";
|
|
@@ -516,6 +592,15 @@ var init_common = __esm({
|
|
|
516
592
|
throw new Error(`\u{1F6D1} [SECURITY] \u975E\u6CD5 ${label}: ${JSON.stringify(sessionId.slice(0, 48))}\uFF08\u4EC5\u5141\u8BB8\u5B57\u6BCD/\u6570\u5B57/\u4E0B\u5212\u7EBF/\u8FDE\u5B57\u7B26\uFF09`);
|
|
517
593
|
}
|
|
518
594
|
};
|
|
595
|
+
detectTextLocale = (text) => {
|
|
596
|
+
const stripped = (text || "").replace(/```[\s\S]*?```/g, " ").replace(/`[^`]*`/g, " ").replace(/\s+/g, " ");
|
|
597
|
+
const cjk = (stripped.match(/[㐀-䶿一-鿿]/g) || []).length;
|
|
598
|
+
const latin = (stripped.match(/[A-Za-z]/g) || []).length;
|
|
599
|
+
if (cjk === 0 && latin === 0) return null;
|
|
600
|
+
if (cjk === 0) return "en";
|
|
601
|
+
if (latin === 0) return "zh";
|
|
602
|
+
return cjk / (cjk + latin) >= 0.2 ? "zh" : "en";
|
|
603
|
+
};
|
|
519
604
|
readJSONFile = async (file, fallback = null) => {
|
|
520
605
|
try {
|
|
521
606
|
const raw = await fs.readFile(file, "utf-8");
|
|
@@ -596,7 +681,7 @@ ${body}`) return;
|
|
|
596
681
|
});
|
|
597
682
|
|
|
598
683
|
// src/prefs.ts
|
|
599
|
-
import
|
|
684
|
+
import path4 from "path";
|
|
600
685
|
import fs2 from "fs/promises";
|
|
601
686
|
var PREFS_FILE, readPrefs, readLocale, writePrefs, writeLocale;
|
|
602
687
|
var init_prefs = __esm({
|
|
@@ -604,7 +689,7 @@ var init_prefs = __esm({
|
|
|
604
689
|
"use strict";
|
|
605
690
|
init_config();
|
|
606
691
|
init_common();
|
|
607
|
-
PREFS_FILE =
|
|
692
|
+
PREFS_FILE = path4.join(appConfig.dataDir, "prefs.json");
|
|
608
693
|
readPrefs = async () => {
|
|
609
694
|
const p = await readJSONFile(PREFS_FILE);
|
|
610
695
|
return p && typeof p === "object" ? p : {};
|
|
@@ -625,7 +710,7 @@ var init_prefs = __esm({
|
|
|
625
710
|
});
|
|
626
711
|
|
|
627
712
|
// ../core/src/trust/index.ts
|
|
628
|
-
import
|
|
713
|
+
import path5 from "path";
|
|
629
714
|
import fs3 from "fs/promises";
|
|
630
715
|
var TRUSTED_FILE, normalizeDir, readTrustedDirs, isTrustedDir, trustDir, untrustDir;
|
|
631
716
|
var init_trust = __esm({
|
|
@@ -633,9 +718,9 @@ var init_trust = __esm({
|
|
|
633
718
|
"use strict";
|
|
634
719
|
init_config();
|
|
635
720
|
init_common();
|
|
636
|
-
TRUSTED_FILE =
|
|
721
|
+
TRUSTED_FILE = path5.join(appConfig.dataDir, "trusted_dirs.json");
|
|
637
722
|
normalizeDir = (dir) => {
|
|
638
|
-
let d =
|
|
723
|
+
let d = path5.resolve(dir).replace(/\\/g, "/");
|
|
639
724
|
if (/^[a-z]:/i.test(d)) d = d.charAt(0).toUpperCase() + d.slice(1);
|
|
640
725
|
return d;
|
|
641
726
|
};
|
|
@@ -978,7 +1063,7 @@ var init_replay = __esm({
|
|
|
978
1063
|
});
|
|
979
1064
|
|
|
980
1065
|
// ../core/src/llm/model.ts
|
|
981
|
-
import { readFileSync as
|
|
1066
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
982
1067
|
var resolveInitialProvider, activeProvider, chatWithModelWithSummary, classifyToolRisk;
|
|
983
1068
|
var init_model = __esm({
|
|
984
1069
|
"../core/src/llm/model.ts"() {
|
|
@@ -993,7 +1078,7 @@ var init_model = __esm({
|
|
|
993
1078
|
}
|
|
994
1079
|
let raw;
|
|
995
1080
|
try {
|
|
996
|
-
raw = JSON.parse(
|
|
1081
|
+
raw = JSON.parse(readFileSync4(scriptPath, "utf-8"));
|
|
997
1082
|
} catch (e) {
|
|
998
1083
|
throw new Error(`\u56DE\u653E\u5267\u672C\u52A0\u8F7D\u5931\u8D25\uFF08${scriptPath}\uFF09: ${e?.message ?? e}`);
|
|
999
1084
|
}
|
|
@@ -1113,7 +1198,7 @@ __export(store_exports, {
|
|
|
1113
1198
|
writeStore: () => writeStore
|
|
1114
1199
|
});
|
|
1115
1200
|
import fs4 from "fs/promises";
|
|
1116
|
-
import
|
|
1201
|
+
import path6 from "path";
|
|
1117
1202
|
async function getRollingState(sessionId) {
|
|
1118
1203
|
const store = await readStore(sessionId);
|
|
1119
1204
|
if (!store) {
|
|
@@ -1160,16 +1245,16 @@ var init_store = __esm({
|
|
|
1160
1245
|
getSessionsDirPath = (mainSessionId) => {
|
|
1161
1246
|
assertSafeSessionId(mainSessionId);
|
|
1162
1247
|
const fileName = getFileName(mainSessionId);
|
|
1163
|
-
return
|
|
1248
|
+
return path6.join(appConfig.dataDir, "sessions", appConfig.userWorkspaceDir, fileName);
|
|
1164
1249
|
};
|
|
1165
|
-
getWorkspaceSessionsDir = () =>
|
|
1250
|
+
getWorkspaceSessionsDir = () => path6.join(appConfig.dataDir, "sessions", appConfig.userWorkspaceDir);
|
|
1166
1251
|
getStatePath = (sessionId) => {
|
|
1167
1252
|
assertSafeSessionId(sessionId);
|
|
1168
|
-
return
|
|
1253
|
+
return path6.join(getSessionsDirPath(sessionId), `${sessionId}.state.json`);
|
|
1169
1254
|
};
|
|
1170
1255
|
getTranscriptPath = (sessionId) => {
|
|
1171
1256
|
assertSafeSessionId(sessionId);
|
|
1172
|
-
return
|
|
1257
|
+
return path6.join(getSessionsDirPath(sessionId), `${sessionId}.jsonl`);
|
|
1173
1258
|
};
|
|
1174
1259
|
ensureSessionsDir = async (sessionId) => {
|
|
1175
1260
|
await fs4.mkdir(getSessionsDirPath(sessionId), { recursive: true });
|
|
@@ -1179,7 +1264,7 @@ var init_store = __esm({
|
|
|
1179
1264
|
migrateLegacyFiles = async (sessionId) => {
|
|
1180
1265
|
assertSafeSessionId(sessionId);
|
|
1181
1266
|
const dir = getSessionsDirPath(sessionId);
|
|
1182
|
-
const legacy =
|
|
1267
|
+
const legacy = path6.join(dir, `${sessionId}.json`);
|
|
1183
1268
|
const transcriptPath = getTranscriptPath(sessionId);
|
|
1184
1269
|
const statePath = getStatePath(sessionId);
|
|
1185
1270
|
let legacyText;
|
|
@@ -1304,7 +1389,7 @@ var init_store = __esm({
|
|
|
1304
1389
|
if (!entry.isDirectory()) continue;
|
|
1305
1390
|
const sessionId = entry.name;
|
|
1306
1391
|
if (!isSafeSessionId(sessionId)) continue;
|
|
1307
|
-
const dirPath =
|
|
1392
|
+
const dirPath = path6.join(root, sessionId);
|
|
1308
1393
|
const state = await readJSONFile(getStatePath(sessionId));
|
|
1309
1394
|
let messageCount = 0;
|
|
1310
1395
|
let preview = "";
|
|
@@ -1481,7 +1566,7 @@ var init_types = __esm({
|
|
|
1481
1566
|
|
|
1482
1567
|
// ../core/src/hooks/shellExecutor.ts
|
|
1483
1568
|
import { spawn } from "child_process";
|
|
1484
|
-
import
|
|
1569
|
+
import path7 from "path";
|
|
1485
1570
|
var MAX_OUTPUT, DEFAULT_TIMEOUT_MS, HARD_TIMEOUT_CAP_MS, ENV_WHITELIST, truncate, MAX_STDIN_FIELD, capFieldStrings, extractFilePath, executeHookCommand;
|
|
1486
1571
|
var init_shellExecutor = __esm({
|
|
1487
1572
|
"../core/src/hooks/shellExecutor.ts"() {
|
|
@@ -1527,7 +1612,7 @@ var init_shellExecutor = __esm({
|
|
|
1527
1612
|
if (typeof rel !== "string" || !rel.trim()) return void 0;
|
|
1528
1613
|
const base = typeof p.cwd === "string" && p.cwd || process.env.WORKSPACE_ROOT || process.cwd();
|
|
1529
1614
|
try {
|
|
1530
|
-
return
|
|
1615
|
+
return path7.resolve(base, rel);
|
|
1531
1616
|
} catch {
|
|
1532
1617
|
return void 0;
|
|
1533
1618
|
}
|
|
@@ -1732,7 +1817,7 @@ var init_hooks = __esm({
|
|
|
1732
1817
|
});
|
|
1733
1818
|
|
|
1734
1819
|
// ../core/src/agent/truncate.ts
|
|
1735
|
-
import
|
|
1820
|
+
import path8 from "path";
|
|
1736
1821
|
function stripAnsi(text) {
|
|
1737
1822
|
return text.replace(ANSI_ESCAPE, "");
|
|
1738
1823
|
}
|
|
@@ -1771,10 +1856,10 @@ var init_truncate = __esm({
|
|
|
1771
1856
|
if (!text) return text;
|
|
1772
1857
|
const roots = /* @__PURE__ */ new Set();
|
|
1773
1858
|
try {
|
|
1774
|
-
roots.add(
|
|
1859
|
+
roots.add(path8.resolve(appConfig.userWorkspaceDir));
|
|
1775
1860
|
for (const r of getFileAccessRoots()) {
|
|
1776
1861
|
try {
|
|
1777
|
-
roots.add(
|
|
1862
|
+
roots.add(path8.resolve(r));
|
|
1778
1863
|
} catch {
|
|
1779
1864
|
}
|
|
1780
1865
|
}
|
|
@@ -2041,7 +2126,7 @@ ${line}` : line;
|
|
|
2041
2126
|
|
|
2042
2127
|
// ../core/src/tool/permissions.ts
|
|
2043
2128
|
import fs6 from "fs/promises";
|
|
2044
|
-
import
|
|
2129
|
+
import path9 from "path";
|
|
2045
2130
|
var PRIMARY_ARG, rules2, trustedProject, globCache, globToRegex, DANGER_COMMAND_TOOLS, compileRule, readPermissionConfig, toolNameMatches, ruleMatches, initPermissions, checkPermission, listPermissionRules, buildScopedAllowRule, resolveSettingsPath, addPermissionRule;
|
|
2046
2131
|
var init_permissions = __esm({
|
|
2047
2132
|
"../core/src/tool/permissions.ts"() {
|
|
@@ -2103,9 +2188,9 @@ var init_permissions = __esm({
|
|
|
2103
2188
|
readPermissionConfig = async (includeProject) => {
|
|
2104
2189
|
const merged = { allow: [], deny: [], ask: [] };
|
|
2105
2190
|
const paths = [
|
|
2106
|
-
|
|
2191
|
+
path9.join(appConfig.dataDir, "settings.json"),
|
|
2107
2192
|
// 全局用户级
|
|
2108
|
-
...includeProject ? [
|
|
2193
|
+
...includeProject ? [path9.join(process.cwd(), ".deepseeker-code", "settings.json")] : []
|
|
2109
2194
|
// 项目级(叠加);未信任时省略
|
|
2110
2195
|
];
|
|
2111
2196
|
for (const configPath of paths) {
|
|
@@ -2196,7 +2281,7 @@ var init_permissions = __esm({
|
|
|
2196
2281
|
}
|
|
2197
2282
|
return `${toolName}(${val})`;
|
|
2198
2283
|
};
|
|
2199
|
-
resolveSettingsPath = (scope) => scope === "global" ?
|
|
2284
|
+
resolveSettingsPath = (scope) => scope === "global" ? path9.join(appConfig.dataDir, "settings.json") : path9.join(process.cwd(), ".deepseeker-code", "settings.json");
|
|
2200
2285
|
addPermissionRule = async (scope, kind, ruleStr) => {
|
|
2201
2286
|
if (scope === "project" && !trustedProject) return false;
|
|
2202
2287
|
const compiled = compileRule(ruleStr, `runtime:addPermissionRule(${scope})`, kind);
|
|
@@ -2208,7 +2293,7 @@ var init_permissions = __esm({
|
|
|
2208
2293
|
const arr = Array.isArray(cfg.permissions[kind]) ? cfg.permissions[kind] : cfg.permissions[kind] = [];
|
|
2209
2294
|
if (!arr.includes(ruleStr)) {
|
|
2210
2295
|
arr.push(ruleStr);
|
|
2211
|
-
await fs6.mkdir(
|
|
2296
|
+
await fs6.mkdir(path9.dirname(file), { recursive: true });
|
|
2212
2297
|
await atomicWriteJSON(file, cfg);
|
|
2213
2298
|
}
|
|
2214
2299
|
if (!rules2[kind].some((r) => r.raw === compiled.raw)) rules2[kind].push(compiled);
|
|
@@ -2248,7 +2333,7 @@ var init_sessionRegistry = __esm({
|
|
|
2248
2333
|
// ../core/src/tool/guard.ts
|
|
2249
2334
|
import fs7 from "fs/promises";
|
|
2250
2335
|
import fsSync from "fs";
|
|
2251
|
-
import
|
|
2336
|
+
import path10 from "path";
|
|
2252
2337
|
import ignore from "ignore";
|
|
2253
2338
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2254
2339
|
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;
|
|
@@ -2304,8 +2389,8 @@ var init_guard = __esm({
|
|
|
2304
2389
|
getContainingRoot = (absPath) => {
|
|
2305
2390
|
let best;
|
|
2306
2391
|
for (const r of allowedBoundaryRoots()) {
|
|
2307
|
-
const rel =
|
|
2308
|
-
if (!rel.startsWith("..") && !
|
|
2392
|
+
const rel = path10.relative(r, absPath);
|
|
2393
|
+
if (!rel.startsWith("..") && !path10.isAbsolute(rel)) {
|
|
2309
2394
|
if (!best || r.length > best.length) best = r;
|
|
2310
2395
|
}
|
|
2311
2396
|
}
|
|
@@ -2322,16 +2407,16 @@ var init_guard = __esm({
|
|
|
2322
2407
|
};
|
|
2323
2408
|
resolveSafePath = (rel, base) => {
|
|
2324
2409
|
const root = base ?? getActiveWorkspaceRoot();
|
|
2325
|
-
const candidateAbsPath =
|
|
2410
|
+
const candidateAbsPath = path10.resolve(root, rel);
|
|
2326
2411
|
let truePhysicalPath = candidateAbsPath;
|
|
2327
2412
|
try {
|
|
2328
2413
|
if (fsSync.existsSync(candidateAbsPath)) {
|
|
2329
2414
|
truePhysicalPath = fsSync.realpathSync(candidateAbsPath);
|
|
2330
2415
|
} else {
|
|
2331
|
-
const parentDir =
|
|
2416
|
+
const parentDir = path10.dirname(candidateAbsPath);
|
|
2332
2417
|
if (fsSync.existsSync(parentDir)) {
|
|
2333
2418
|
const trueParentDir = fsSync.realpathSync(parentDir);
|
|
2334
|
-
truePhysicalPath =
|
|
2419
|
+
truePhysicalPath = path10.join(trueParentDir, path10.basename(candidateAbsPath));
|
|
2335
2420
|
}
|
|
2336
2421
|
}
|
|
2337
2422
|
} catch (e) {
|
|
@@ -2345,8 +2430,8 @@ var init_guard = __esm({
|
|
|
2345
2430
|
}
|
|
2346
2431
|
})() : allowedBoundaryRoots();
|
|
2347
2432
|
const escaped = boundaryRoots.every((r) => {
|
|
2348
|
-
const rel0 =
|
|
2349
|
-
return rel0.startsWith("..") ||
|
|
2433
|
+
const rel0 = path10.relative(r, truePhysicalPath);
|
|
2434
|
+
return rel0.startsWith("..") || path10.isAbsolute(rel0);
|
|
2350
2435
|
});
|
|
2351
2436
|
if (escaped) {
|
|
2352
2437
|
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}`);
|
|
@@ -2355,12 +2440,12 @@ var init_guard = __esm({
|
|
|
2355
2440
|
};
|
|
2356
2441
|
resolveReadablePath = (rel) => {
|
|
2357
2442
|
const root = getActiveWorkspaceRoot();
|
|
2358
|
-
const absPath =
|
|
2443
|
+
const absPath = path10.resolve(root, rel);
|
|
2359
2444
|
if (!fsSync.existsSync(absPath)) {
|
|
2360
|
-
const rootName =
|
|
2445
|
+
const rootName = path10.basename(root);
|
|
2361
2446
|
const firstSeg = rel.split(/[\\/]/)[0];
|
|
2362
2447
|
if (rootName && firstSeg === rootName) {
|
|
2363
|
-
const alt =
|
|
2448
|
+
const alt = path10.resolve(root, rel.slice(firstSeg.length + 1));
|
|
2364
2449
|
if (fsSync.existsSync(alt)) return alt;
|
|
2365
2450
|
}
|
|
2366
2451
|
}
|
|
@@ -2373,9 +2458,9 @@ var init_guard = __esm({
|
|
|
2373
2458
|
if (fsSync.existsSync(absPath)) {
|
|
2374
2459
|
truePhysicalPath = fsSync.realpathSync(absPath);
|
|
2375
2460
|
} else {
|
|
2376
|
-
const parentDir =
|
|
2461
|
+
const parentDir = path10.dirname(absPath);
|
|
2377
2462
|
if (fsSync.existsSync(parentDir)) {
|
|
2378
|
-
truePhysicalPath =
|
|
2463
|
+
truePhysicalPath = path10.join(fsSync.realpathSync(parentDir), path10.basename(absPath));
|
|
2379
2464
|
}
|
|
2380
2465
|
}
|
|
2381
2466
|
} catch (e) {
|
|
@@ -2389,8 +2474,8 @@ var init_guard = __esm({
|
|
|
2389
2474
|
}
|
|
2390
2475
|
})() : allowedBoundaryRoots();
|
|
2391
2476
|
const escaped = boundaryRoots.every((r) => {
|
|
2392
|
-
const rel0 =
|
|
2393
|
-
return rel0.startsWith("..") ||
|
|
2477
|
+
const rel0 = path10.relative(r, truePhysicalPath);
|
|
2478
|
+
return rel0.startsWith("..") || path10.isAbsolute(rel0);
|
|
2394
2479
|
});
|
|
2395
2480
|
if (escaped) {
|
|
2396
2481
|
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}`);
|
|
@@ -2417,7 +2502,7 @@ var init_guard = __esm({
|
|
|
2417
2502
|
if (!relOrAbs) return false;
|
|
2418
2503
|
try {
|
|
2419
2504
|
const base = cwd || process.env.WORKSPACE_ROOT || process.cwd();
|
|
2420
|
-
const abs =
|
|
2505
|
+
const abs = path10.isAbsolute(relOrAbs) ? relOrAbs : path10.resolve(base, relOrAbs);
|
|
2421
2506
|
const lower = abs.replace(/\\/g, "/").toLowerCase();
|
|
2422
2507
|
return PROTECTED_WRITE_DIRS.some((d) => {
|
|
2423
2508
|
const seg = ("/" + d).toLowerCase();
|
|
@@ -2432,9 +2517,9 @@ var init_guard = __esm({
|
|
|
2432
2517
|
const entries = await fs7.readdir(dirPath, { withFileTypes: true });
|
|
2433
2518
|
for (const entry of entries) {
|
|
2434
2519
|
if (entry.isFile() && (entry.name === ".gitignore" || entry.name === ".agentignore")) {
|
|
2435
|
-
const fullPath =
|
|
2520
|
+
const fullPath = path10.join(dirPath, entry.name);
|
|
2436
2521
|
const content = await fs7.readFile(fullPath, "utf-8");
|
|
2437
|
-
const relDir =
|
|
2522
|
+
const relDir = path10.relative(base, dirPath).replace(/\\/g, "/");
|
|
2438
2523
|
const rules3 = content.split(/\r?\n/).map((line) => {
|
|
2439
2524
|
const trimmed = line.trim();
|
|
2440
2525
|
if (!trimmed || trimmed.startsWith("#")) return "";
|
|
@@ -2445,7 +2530,7 @@ var init_guard = __esm({
|
|
|
2445
2530
|
}
|
|
2446
2531
|
for (const entry of entries) {
|
|
2447
2532
|
if (entry.isDirectory() && entry.name !== "node_modules" && entry.name !== ".git") {
|
|
2448
|
-
await scanIgnoreFilesRecursive(
|
|
2533
|
+
await scanIgnoreFilesRecursive(path10.join(dirPath, entry.name), base, engine);
|
|
2449
2534
|
}
|
|
2450
2535
|
}
|
|
2451
2536
|
} catch {
|
|
@@ -2516,7 +2601,7 @@ var init_guard = __esm({
|
|
|
2516
2601
|
// ../core/src/tool/registry/background.ts
|
|
2517
2602
|
import { spawn as spawn2, execFileSync } from "child_process";
|
|
2518
2603
|
import fsSync2 from "fs";
|
|
2519
|
-
import
|
|
2604
|
+
import path11 from "path";
|
|
2520
2605
|
function appendOutput(task, chunk) {
|
|
2521
2606
|
task.outputBuffer += chunk;
|
|
2522
2607
|
if (task.outputBuffer.length > MAX_BUFFER_CHARS) {
|
|
@@ -2541,7 +2626,7 @@ async function killTree(proc) {
|
|
|
2541
2626
|
}
|
|
2542
2627
|
}
|
|
2543
2628
|
async function killBackgroundTasksUnder(dirPath) {
|
|
2544
|
-
const norm = (p) =>
|
|
2629
|
+
const norm = (p) => path11.resolve(p).replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
|
|
2545
2630
|
const target = norm(dirPath);
|
|
2546
2631
|
let killed = 0;
|
|
2547
2632
|
for (const task of registry.values()) {
|
|
@@ -2586,9 +2671,9 @@ var init_background = __esm({
|
|
|
2586
2671
|
if (envShell && envShell.toLowerCase() !== "cmd") candidates.push(envShell);
|
|
2587
2672
|
const gitExe = whereLines("git")[0];
|
|
2588
2673
|
if (gitExe) {
|
|
2589
|
-
const dir =
|
|
2590
|
-
const root =
|
|
2591
|
-
candidates.push(
|
|
2674
|
+
const dir = path11.dirname(gitExe);
|
|
2675
|
+
const root = path11.dirname(dir);
|
|
2676
|
+
candidates.push(path11.join(root, "bin", "bash.exe"), path11.join(dir, "bash.exe"), path11.join(path11.dirname(root), "bin", "bash.exe"));
|
|
2592
2677
|
}
|
|
2593
2678
|
const bashHits = whereLines("bash").filter((p) => !/\\System32\\/i.test(p)).sort((a, b) => Number(/\\Git\\/i.test(b)) - Number(/\\Git\\/i.test(a)));
|
|
2594
2679
|
candidates.push(...bashHits);
|
|
@@ -2729,12 +2814,13 @@ task_id: ${taskId}
|
|
|
2729
2814
|
type: "function",
|
|
2730
2815
|
function: {
|
|
2731
2816
|
name: "get_background_output",
|
|
2732
|
-
description: "\u67E5\u770B\u6307\u5B9A\u540E\u53F0\u4EFB\u52A1\u7684\u6700\u8FD1\u8F93\u51FA\u65E5\u5FD7\u4E0E\u8FD0\u884C\u72B6\u6001\uFF08running/exited/killed + \u9000\u51FA\u7801\uFF09\u3002\u7EAF\u8BFB\uFF0C\u514D\u5BA1\u6279\u3002\u7528\u4E8E\u786E\u8BA4 dev server \u662F\u5426\u542F\u52A8\u6210\u529F\u3001\u67E5\u770B\u62A5\u9519\u7B49\u3002",
|
|
2817
|
+
description: "\u67E5\u770B\u6307\u5B9A\u540E\u53F0\u4EFB\u52A1\u7684\u6700\u8FD1\u8F93\u51FA\u65E5\u5FD7\u4E0E\u8FD0\u884C\u72B6\u6001\uFF08running/exited/killed + \u9000\u51FA\u7801\uFF09\u3002\u7EAF\u8BFB\uFF0C\u514D\u5BA1\u6279\u3002\u7528\u4E8E\u786E\u8BA4 dev server \u662F\u5426\u542F\u52A8\u6210\u529F\u3001\u67E5\u770B\u62A5\u9519\u7B49\u3002\u7B49\u957F\u4EFB\u52A1\uFF08\u6784\u5EFA/\u6D4B\u8BD5\uFF09\u8DD1\u5B8C\uFF1A\u5E26 wait_seconds \u963B\u585E\u7B49\u5F85\u4EFB\u52A1\u9000\u51FA\u540E\u518D\u8FD4\u56DE\uFF08\u4ECD\u5728\u8DD1\u5219\u7B49\u5230\u8D85\u65F6\u8FD4\u56DE\u5F53\u524D\u72B6\u6001\uFF09\u2014\u2014\u7528\u5B83\u7B49\uFF0C\u4E0D\u8981\u4E0D\u5E26 wait \u53CD\u590D\u8F6E\u8BE2\u67E5\u8BE2\u3002",
|
|
2733
2818
|
parameters: {
|
|
2734
2819
|
type: "object",
|
|
2735
2820
|
properties: {
|
|
2736
2821
|
task_id: { type: "string", description: "run_in_background \u8FD4\u56DE\u7684 task_id" },
|
|
2737
|
-
tail_lines: { type: "number", description: "\u53EA\u8FD4\u56DE\u6700\u540E N \u884C\u65E5\u5FD7\uFF08\u9ED8\u8BA4 50\uFF0C\u907F\u514D\u4E00\u6B21\u704C\u5165\u8FC7\u591A\uFF09" }
|
|
2822
|
+
tail_lines: { type: "number", description: "\u53EA\u8FD4\u56DE\u6700\u540E N \u884C\u65E5\u5FD7\uFF08\u9ED8\u8BA4 50\uFF0C\u907F\u514D\u4E00\u6B21\u704C\u5165\u8FC7\u591A\uFF09" },
|
|
2823
|
+
wait_seconds: { type: "number", description: "\u963B\u585E\u7B49\u5F85\u4EFB\u52A1\u9000\u51FA\uFF08\u6216\u5230\u8FBE\u6B64\u65F6\u957F\uFF09\u540E\u518D\u8FD4\u56DE\uFF0C\u4E0A\u9650 120 \u79D2\uFF1B\u4EFB\u52A1\u5DF2\u5728\u8DD1\u4E14\u9700\u8981\u7B49\u7ED3\u679C\u65F6\u4F7F\u7528\uFF0C\u4E0D\u9700\u8981\u7B49\u5C31\u7701\u7565" }
|
|
2738
2824
|
},
|
|
2739
2825
|
required: ["task_id"]
|
|
2740
2826
|
},
|
|
@@ -2745,6 +2831,13 @@ task_id: ${taskId}
|
|
|
2745
2831
|
if (!task || task.sessionId !== ctx?.sessionId) {
|
|
2746
2832
|
return `\u274C [\u67E5\u8BE2\u5931\u8D25]\uFF1A\u672A\u627E\u5230 task_id=${args.task_id}\uFF08\u53EF\u80FD\u5DF2\u968F\u670D\u52A1\u91CD\u542F\u4E22\u5931\uFF0C\u6216\u4E0D\u5C5E\u4E8E\u5F53\u524D\u4F1A\u8BDD\uFF09\u3002`;
|
|
2747
2833
|
}
|
|
2834
|
+
const waitMs = Math.min(Math.max(0, args.wait_seconds ?? 0), 120) * 1e3;
|
|
2835
|
+
if (waitMs > 0 && task.status === "running") {
|
|
2836
|
+
const deadline = Date.now() + waitMs;
|
|
2837
|
+
while (task.status === "running" && Date.now() < deadline && !ctx?.abortSignal?.aborted) {
|
|
2838
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2748
2841
|
const tail = Math.max(1, args.tail_lines ?? 50);
|
|
2749
2842
|
const allLines = task.outputBuffer.split("\n");
|
|
2750
2843
|
const tailText = allLines.slice(-tail).join("\n").trim();
|
|
@@ -3331,13 +3424,13 @@ ${capped || JSON.stringify(result)}`;
|
|
|
3331
3424
|
|
|
3332
3425
|
// ../core/src/tool/mcp/loader.ts
|
|
3333
3426
|
import fs8 from "fs/promises";
|
|
3334
|
-
import
|
|
3427
|
+
import path12 from "path";
|
|
3335
3428
|
import { homedir } from "os";
|
|
3336
3429
|
function sanitize(s) {
|
|
3337
3430
|
return s.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3338
3431
|
}
|
|
3339
3432
|
async function readMcpConfig() {
|
|
3340
|
-
const configPath = process.env.MCP_CONFIG ||
|
|
3433
|
+
const configPath = process.env.MCP_CONFIG || path12.join(appConfig.dataDir, "mcp.json");
|
|
3341
3434
|
let raw;
|
|
3342
3435
|
try {
|
|
3343
3436
|
raw = await fs8.readFile(configPath, "utf-8");
|
|
@@ -3807,26 +3900,31 @@ var init_repeatBreaker = __esm({
|
|
|
3807
3900
|
const recentSignatures = [];
|
|
3808
3901
|
const recentPollTargets = [];
|
|
3809
3902
|
const POLL_TARGET_KEYS = { get_background_output: ["task_id"] };
|
|
3903
|
+
const parseArgs2 = (tc) => {
|
|
3904
|
+
try {
|
|
3905
|
+
return JSON.parse(tc?.function?.arguments || "{}") ?? {};
|
|
3906
|
+
} catch {
|
|
3907
|
+
return {};
|
|
3908
|
+
}
|
|
3909
|
+
};
|
|
3810
3910
|
const pollTarget = (tc) => {
|
|
3811
3911
|
const name = tc?.function?.name;
|
|
3812
3912
|
const keys = name ? POLL_TARGET_KEYS[name] : void 0;
|
|
3813
3913
|
if (!keys) return null;
|
|
3814
|
-
|
|
3815
|
-
try {
|
|
3816
|
-
args = JSON.parse(tc?.function?.arguments || "{}");
|
|
3817
|
-
} catch {
|
|
3818
|
-
}
|
|
3914
|
+
const args = parseArgs2(tc);
|
|
3819
3915
|
const picked = {};
|
|
3820
3916
|
for (const k of keys) if (k in args) picked[k] = args[k];
|
|
3821
3917
|
return `${name}:${JSON.stringify(picked)}`;
|
|
3822
3918
|
};
|
|
3919
|
+
const isWaitPoll = (tc) => tc?.function?.name === "get_background_output" && Number(parseArgs2(tc).wait_seconds ?? 0) > 0;
|
|
3823
3920
|
const check = (toolCalls, round, lastContent) => {
|
|
3824
|
-
const
|
|
3921
|
+
const effCalls = toolCalls.filter((t) => !isWaitPoll(t));
|
|
3922
|
+
const sig = effCalls.map((t) => `${t.function.name}:${t.function.arguments}`).join("|");
|
|
3825
3923
|
const tooName = toolCalls.map((t) => `${t.function.name}`).join("|");
|
|
3826
3924
|
recentSignatures.push(sig);
|
|
3827
3925
|
if (recentSignatures.length > 6) recentSignatures.shift();
|
|
3828
3926
|
const last3 = recentSignatures.slice(-3);
|
|
3829
|
-
if (last3.length === 3 && last3.every((s) => s ===
|
|
3927
|
+
if (sig && last3.length === 3 && last3.every((s) => s === sig)) {
|
|
3830
3928
|
const text = (lastContent || "") + "\n\uFF08\u68C0\u6D4B\u5230\u91CD\u590D\u5DE5\u5177\u8C03\u7528\uFF0C\u5DF2\u505C\u6B62\uFF09";
|
|
3831
3929
|
events({
|
|
3832
3930
|
sessionId,
|
|
@@ -3845,31 +3943,28 @@ var init_repeatBreaker = __esm({
|
|
|
3845
3943
|
});
|
|
3846
3944
|
return { tripped: true, kind: "full", text, toolName: tooName };
|
|
3847
3945
|
}
|
|
3848
|
-
const
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
const
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
});
|
|
3871
|
-
return { tripped: true, kind: "names", text, toolName: tooName };
|
|
3872
|
-
}
|
|
3946
|
+
const pollSig = effCalls.map(pollTarget).filter(Boolean).join("|");
|
|
3947
|
+
recentPollTargets.push(pollSig);
|
|
3948
|
+
if (recentPollTargets.length > 8) recentPollTargets.shift();
|
|
3949
|
+
const last4 = recentPollTargets.slice(-4);
|
|
3950
|
+
if (pollSig && last4.length === 4 && last4.every((s) => s === pollSig)) {
|
|
3951
|
+
const text = (lastContent || "") + "\n\uFF08\u68C0\u6D4B\u5230\u540E\u53F0\u4EFB\u52A1\u8F6E\u8BE2\u6B7B\u5FAA\u73AF\uFF08\u53CD\u590D\u67E5\u8BE2\u540C\u4E00\u4EFB\u52A1\uFF09\uFF0C\u5DF2\u505C\u6B62\uFF09";
|
|
3952
|
+
events({
|
|
3953
|
+
sessionId,
|
|
3954
|
+
eventType: "tool.repeat_break",
|
|
3955
|
+
metadata: {
|
|
3956
|
+
depth,
|
|
3957
|
+
decisionSource: llmDecisionSource,
|
|
3958
|
+
durationMs: performance.now() - startTime,
|
|
3959
|
+
round,
|
|
3960
|
+
toolName: tooName,
|
|
3961
|
+
toolSource: "builtin",
|
|
3962
|
+
ok: false,
|
|
3963
|
+
attempt: round
|
|
3964
|
+
},
|
|
3965
|
+
payload: { output: text }
|
|
3966
|
+
});
|
|
3967
|
+
return { tripped: true, kind: "names", text, toolName: tooName };
|
|
3873
3968
|
}
|
|
3874
3969
|
events({
|
|
3875
3970
|
sessionId,
|
|
@@ -4112,7 +4207,7 @@ ${AGENT_USAGE_HINT}`);
|
|
|
4112
4207
|
|
|
4113
4208
|
// ../core/src/projectGuide/loader.ts
|
|
4114
4209
|
import fs10 from "fs/promises";
|
|
4115
|
-
import
|
|
4210
|
+
import path13 from "path";
|
|
4116
4211
|
var CANDIDATES, MAX_GUIDE_BYTES, cached, initProjectGuide, getProjectGuide;
|
|
4117
4212
|
var init_loader2 = __esm({
|
|
4118
4213
|
"../core/src/projectGuide/loader.ts"() {
|
|
@@ -4129,7 +4224,7 @@ var init_loader2 = __esm({
|
|
|
4129
4224
|
try {
|
|
4130
4225
|
for (const name of CANDIDATES) {
|
|
4131
4226
|
try {
|
|
4132
|
-
const raw = await fs10.readFile(
|
|
4227
|
+
const raw = await fs10.readFile(path13.join(WORKSPACE_ROOT, name), "utf-8");
|
|
4133
4228
|
const body = raw.length > MAX_GUIDE_BYTES ? raw.slice(0, MAX_GUIDE_BYTES) + `
|
|
4134
4229
|
|
|
4135
4230
|
\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;
|
|
@@ -4287,10 +4382,23 @@ var init_systemInjections = __esm({
|
|
|
4287
4382
|
function: { name: t.function.name, description: t.function.description, parameters: t.function.parameters }
|
|
4288
4383
|
}));
|
|
4289
4384
|
ensureSummarySlot(message);
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
}
|
|
4385
|
+
const LOCALE_HINTS = {
|
|
4386
|
+
zh: "\u59CB\u7EC8\u7528\u4E2D\u6587\u8F93\u51FA\u6240\u6709\u9762\u5411\u7528\u6237\u7684\u5185\u5BB9\uFF1A\u4F60\u7684\u56DE\u590D\u3001\u4E2D\u95F4\u53D9\u8FF0\u3001todo \u4EFB\u52A1\u9879\u6807\u9898\u3001\u901A\u8FC7 exit_plan_mode \u63D0\u4EA4\u7684\u65B9\u6848\u6587\u672C\u3001\u4EE3\u7801\u6CE8\u91CA\u4E0E\u63D0\u4EA4\u4FE1\u606F\u3002\u4EE3\u7801\u6807\u8BC6\u7B26\u4FDD\u6301\u539F\u6837\uFF1B\u5DE5\u5177\u7ED3\u679C\u4E0E\u7CFB\u7EDF\u6307\u4EE4\u53EF\u80FD\u5939\u6742\u5176\u4ED6\u8BED\u8A00\u2014\u2014\u5FC5\u8981\u65F6\u7167\u5F15\u539F\u6587\uFF0C\u4F46\u4F60\u81EA\u5DF1\u7684\u53D9\u8FF0\u4E0E\u89E3\u91CA\u4E00\u5F8B\u7528\u4E2D\u6587\u3002",
|
|
4387
|
+
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."
|
|
4388
|
+
};
|
|
4389
|
+
const lastUserText = (() => {
|
|
4390
|
+
for (let i = message.length - 1; i >= 0; i--) {
|
|
4391
|
+
const m = message[i];
|
|
4392
|
+
if (m?.role !== "user") continue;
|
|
4393
|
+
const c = m.content;
|
|
4394
|
+
if (typeof c === "string") return c;
|
|
4395
|
+
if (Array.isArray(c)) return c.filter((p) => typeof p?.text === "string").map((p) => p.text).join(" ");
|
|
4396
|
+
return "";
|
|
4397
|
+
}
|
|
4398
|
+
return "";
|
|
4399
|
+
})();
|
|
4400
|
+
const effLocale = detectTextLocale(lastUserText) ?? locale2;
|
|
4401
|
+
if (effLocale) injectMarkedBlock(message, "\u27E6DSC:LOCALE\u27E7", LOCALE_HINTS[effLocale]);
|
|
4294
4402
|
injectOutputStyle(message, outputStyle);
|
|
4295
4403
|
injectSkillCatalog(message);
|
|
4296
4404
|
injectAgentCatalog(message);
|
|
@@ -4313,13 +4421,14 @@ var init_agent = __esm({
|
|
|
4313
4421
|
type: "function",
|
|
4314
4422
|
function: {
|
|
4315
4423
|
name: "spawn_agent",
|
|
4316
|
-
description: "\u521B\u5EFA\u4E00\u4E2A\u62E5\u6709\u72EC\u7ACB\u6267\u884C\u73AF\u5883\u7684\u5B50 agent \u5904\u7406\u9694\u79BB\u7684\u7279\u5B9A\u5B50\u4EFB\u52A1\uFF0C\u5B50\u4EFB\u52A1\u5B8C\u6210\u540E\u81EA\u52A8\u6C47\u603B\u6539\u52A8\u70B9\u4E0E\u7ED3\u8BBA\u8FD4\u56DE\u3002\u53EF\u901A\u8FC7 name \u6307\u5B9A\u58F0\u660E\u5F0F\u5B50 Agent\uFF08\u89C1\u7CFB\u7EDF\u63D0\u793A\u8BCD\u3010\u53EF\u7528\u5B50 Agent \u76EE\u5F55\u3011\uFF09\u4EE5\u5957\u7528\u5176\u4E13\u957F\u7CFB\u7EDF\u8BCD/\u5DE5\u5177\u767D\u540D\u5355/model\uFF1B\u4E0D\u4F20 name \u8D70\u9ED8\u8BA4\u901A\u7528\u5B50 agent\u3002",
|
|
4424
|
+
description: "\u521B\u5EFA\u4E00\u4E2A\u62E5\u6709\u72EC\u7ACB\u6267\u884C\u73AF\u5883\u7684\u5B50 agent \u5904\u7406\u9694\u79BB\u7684\u7279\u5B9A\u5B50\u4EFB\u52A1\uFF0C\u5B50\u4EFB\u52A1\u5B8C\u6210\u540E\u81EA\u52A8\u6C47\u603B\u6539\u52A8\u70B9\u4E0E\u7ED3\u8BBA\u8FD4\u56DE\u3002\u53EF\u901A\u8FC7 name \u6307\u5B9A\u58F0\u660E\u5F0F\u5B50 Agent\uFF08\u89C1\u7CFB\u7EDF\u63D0\u793A\u8BCD\u3010\u53EF\u7528\u5B50 Agent \u76EE\u5F55\u3011\uFF09\u4EE5\u5957\u7528\u5176\u4E13\u957F\u7CFB\u7EDF\u8BCD/\u5DE5\u5177\u767D\u540D\u5355/model\uFF1B\u4E0D\u4F20 name \u8D70\u9ED8\u8BA4\u901A\u7528\u5B50 agent\u3002\u652F\u6301\u7EED\u8DD1\uFF1A\u4F20 resume_session_id\uFF08\u6B64\u524D\u8FD4\u56DE\u7684 agent_id\uFF09\u590D\u7528\u8BE5\u5B50 Agent \u7684\u5B8C\u6574\u5386\u53F2\u8BB0\u5FC6\uFF0C\u9002\u5408\u8FFD\u95EE\u3001\u7EE7\u7EED\u672A\u5B8C\u6210\u7684\u4EFB\u52A1\u3002",
|
|
4317
4425
|
parameters: {
|
|
4318
4426
|
type: "object",
|
|
4319
4427
|
properties: {
|
|
4320
|
-
task: { type: "string", description: "\u4EA4\u7ED9\u5B50 agent \u7684\u5177\u4F53\u5FAE\u89C2\u4EFB\u52A1\u63CF\u8FF0\uFF08\u5982 '\u7F16\u5199 Button \u7EC4\u4EF6\u7684\u5355\u5143\u6D4B\u8BD5'\uFF09" },
|
|
4428
|
+
task: { type: "string", description: "\u4EA4\u7ED9\u5B50 agent \u7684\u5177\u4F53\u5FAE\u89C2\u4EFB\u52A1\u63CF\u8FF0\uFF08\u5982 '\u7F16\u5199 Button \u7EC4\u4EF6\u7684\u5355\u5143\u6D4B\u8BD5'\uFF09\uFF1B\u7EED\u8DD1\u65F6\u4E3A\u65B0\u6307\u4EE4\uFF08\u5982 '\u7EE7\u7EED\u5B8C\u6210\u5269\u4F59\u7528\u4F8B'\uFF09" },
|
|
4321
4429
|
name: { type: "string", description: "\u58F0\u660E\u5F0F\u5B50 Agent \u540D\u79F0\uFF08\u987B\u4E0E\u7CFB\u7EDF\u63D0\u793A\u8BCD\u4E2D\u3010\u53EF\u7528\u5B50 Agent \u76EE\u5F55\u3011\u4E00\u81F4\uFF09\u3002\u63D0\u4F9B\u65F6\u6309\u5176\u58F0\u660E\u52A0\u8F7D\u7CFB\u7EDF\u8BCD/\u5DE5\u5177\u767D\u540D\u5355/model\uFF1B\u4E0D\u63D0\u4F9B\u5219\u8D70\u9ED8\u8BA4\u901A\u7528\u5B50 agent\u3002" },
|
|
4322
|
-
role: { type: "string", description: "\u5B50 agent \u7684\u89D2\u8272/\u4E13\u957F\uFF08\u53EF\u9009\uFF0C\u5982 '\u6D4B\u8BD5\u4E13\u5BB6'\u3001'\u91CD\u6784\u5148\u950B'\uFF09\u3002\u58F0\u660E\u5F0F agent \u81EA\u5E26 role \u65F6\u4F5C\u8865\u5145\u3002" }
|
|
4430
|
+
role: { type: "string", description: "\u5B50 agent \u7684\u89D2\u8272/\u4E13\u957F\uFF08\u53EF\u9009\uFF0C\u5982 '\u6D4B\u8BD5\u4E13\u5BB6'\u3001'\u91CD\u6784\u5148\u950B'\uFF09\u3002\u58F0\u660E\u5F0F agent \u81EA\u5E26 role \u65F6\u4F5C\u8865\u5145\u3002" },
|
|
4431
|
+
resume_session_id: { type: "string", description: "\u7EED\u8DD1\u65E2\u6709\u5B50 Agent\uFF1A\u4F20\u6B64\u524D spawn_agent \u8FD4\u56DE\u7684 agent_id\uFF0C\u5176\u78C1\u76D8\u4E0A\u7684\u5386\u53F2\u4E0E\u8BB0\u5FC6\u5C06\u5B8C\u6574\u6062\u590D\u3002\u6CE8\u610F\uFF1A\u5B50 Agent \u72B6\u6001\u4E0D\u968F\u4E3B\u4F1A\u8BDD fork \u56DE\u6EDA\u2014\u2014fork \u53EA\u5206\u53C9\u5BF9\u8BDD\uFF0C\u7EED\u8DD1\u62FF\u5230\u7684\u662F\u5B50\u4F1A\u8BDD\u78C1\u76D8\u6700\u65B0\u72B6\u6001\u3002\u7F3A\u7701\u5219\u65B0\u5EFA\u5B50 Agent\u3002" }
|
|
4323
4432
|
},
|
|
4324
4433
|
required: ["task"]
|
|
4325
4434
|
},
|
|
@@ -4327,10 +4436,17 @@ var init_agent = __esm({
|
|
|
4327
4436
|
isSync: true,
|
|
4328
4437
|
async execute(args, ctx) {
|
|
4329
4438
|
if (!ctx) return "\u274C [\u6D3E\u751F\u5931\u8D25]\uFF1Aspawn_agent \u7F3A\u5C11\u5FC5\u987B\u7684\u667A\u80FD\u4F53\u8FD0\u884C\u4E0A\u4E0B\u6587\u3002";
|
|
4330
|
-
const res = await runSubagent(
|
|
4439
|
+
const res = await runSubagent(
|
|
4440
|
+
{ task: args.task, name: args.name, role: args.role, resumeSessionId: args.resume_session_id },
|
|
4441
|
+
ctx,
|
|
4442
|
+
getGlobalTools
|
|
4443
|
+
);
|
|
4331
4444
|
if (!res.ok) return res.output;
|
|
4332
4445
|
return [
|
|
4333
|
-
`\u{1F389} [\u5B50 Agent \u6267\u884C\u5B8C\u6BD5] \u6D3E\u751F\u5B50\u4EFB\u52A1\u6C47\u62A5\u5982\u4E0B\uFF1A
|
|
4446
|
+
`\u{1F389} [\u5B50 Agent \u6267\u884C\u5B8C\u6BD5${args.resume_session_id ? "\xB7\u7EED\u8DD1" : ""}] \u6D3E\u751F\u5B50\u4EFB\u52A1\u6C47\u62A5\u5982\u4E0B\uFF1A
|
|
4447
|
+
`,
|
|
4448
|
+
`\u{1F194} agent_id: ${res.sessionId}
|
|
4449
|
+
\uFF08\u9700\u8981\u7EE7\u7EED\u8BE5\u5B50 Agent \u7684\u4EFB\u52A1\u6216\u8FFD\u95EE\u65F6\uFF0C\u8C03\u7528 spawn_agent \u4F20 resume_session_id=${res.sessionId}\uFF0C\u5176\u5386\u53F2\u8BB0\u5FC6\u5B8C\u6574\u4FDD\u7559\uFF09
|
|
4334
4450
|
`,
|
|
4335
4451
|
`==================================================
|
|
4336
4452
|
`,
|
|
@@ -4349,8 +4465,8 @@ var init_agent = __esm({
|
|
|
4349
4465
|
});
|
|
4350
4466
|
|
|
4351
4467
|
// ../core/src/tool/worktree/manager.ts
|
|
4352
|
-
import
|
|
4353
|
-
import
|
|
4468
|
+
import path14 from "path";
|
|
4469
|
+
import os4 from "os";
|
|
4354
4470
|
import fs11 from "fs";
|
|
4355
4471
|
var runMainGit, worktreeRootDir, worktreeDir, isNotARepoError, createWorktree, harvestDiff, runInWorktree, removeWorktree, sweepOrphanedWorktrees, disposeAllSessionWorktrees;
|
|
4356
4472
|
var init_manager = __esm({
|
|
@@ -4362,8 +4478,8 @@ var init_manager = __esm({
|
|
|
4362
4478
|
init_background();
|
|
4363
4479
|
init_sessionRegistry();
|
|
4364
4480
|
runMainGit = (args, maxBuffer = 1024 * 1024 * 5) => execFileSmart("git", args, { cwd: WORKSPACE_ROOT, maxBuffer });
|
|
4365
|
-
worktreeRootDir = () =>
|
|
4366
|
-
worktreeDir = (sessionId, stepId) =>
|
|
4481
|
+
worktreeRootDir = () => path14.join(os4.tmpdir(), "deepseeker-code-worktrees", appConfig.userWorkspaceDir);
|
|
4482
|
+
worktreeDir = (sessionId, stepId) => path14.join(worktreeRootDir(), sessionId, stepId);
|
|
4367
4483
|
isNotARepoError = (e) => {
|
|
4368
4484
|
const text = `${e?.message || ""} ${e?.stderr || ""}`.toLowerCase();
|
|
4369
4485
|
return text.includes("not a git repository");
|
|
@@ -4374,7 +4490,7 @@ var init_manager = __esm({
|
|
|
4374
4490
|
const wtPath = worktreeDir(sessionId, stepId);
|
|
4375
4491
|
const shortId = sessionId.replace(/[^A-Za-z0-9-]/g, "").slice(0, 8) || "x";
|
|
4376
4492
|
const branch = `dsc-wt-${shortId}-${stepId}`;
|
|
4377
|
-
await fs11.promises.mkdir(
|
|
4493
|
+
await fs11.promises.mkdir(path14.dirname(wtPath), { recursive: true });
|
|
4378
4494
|
try {
|
|
4379
4495
|
await runMainGit(["worktree", "add", "-b", branch, wtPath, "HEAD"]);
|
|
4380
4496
|
} catch (e) {
|
|
@@ -4450,7 +4566,7 @@ var init_manager = __esm({
|
|
|
4450
4566
|
}
|
|
4451
4567
|
let swept = 0;
|
|
4452
4568
|
for (const sessionIdDir of entries) {
|
|
4453
|
-
const sessionPath =
|
|
4569
|
+
const sessionPath = path14.join(root, sessionIdDir);
|
|
4454
4570
|
let stepDirs;
|
|
4455
4571
|
try {
|
|
4456
4572
|
stepDirs = await fs11.promises.readdir(sessionPath);
|
|
@@ -4458,7 +4574,7 @@ var init_manager = __esm({
|
|
|
4458
4574
|
continue;
|
|
4459
4575
|
}
|
|
4460
4576
|
for (const stepDir of stepDirs) {
|
|
4461
|
-
const wtPath =
|
|
4577
|
+
const wtPath = path14.join(sessionPath, stepDir);
|
|
4462
4578
|
try {
|
|
4463
4579
|
await runMainGit(["worktree", "remove", "--force", wtPath]);
|
|
4464
4580
|
} catch {
|
|
@@ -4739,7 +4855,7 @@ var init_workflow = __esm({
|
|
|
4739
4855
|
|
|
4740
4856
|
// ../core/src/tool/tsHost.ts
|
|
4741
4857
|
import fsSync3 from "fs";
|
|
4742
|
-
import
|
|
4858
|
+
import path15 from "path";
|
|
4743
4859
|
var _ts, _tsTried, getTs, buildDefaultOptions, findTsConfigBounded, resolveTsConfig, createProjectHost, lsCache, getLanguageService, realpathNative, posToLineCol, lineColToPos;
|
|
4744
4860
|
var init_tsHost = __esm({
|
|
4745
4861
|
"../core/src/tool/tsHost.ts"() {
|
|
@@ -4772,16 +4888,16 @@ var init_tsHost = __esm({
|
|
|
4772
4888
|
strict: false
|
|
4773
4889
|
});
|
|
4774
4890
|
findTsConfigBounded = (ts, absPath) => {
|
|
4775
|
-
const root =
|
|
4776
|
-
let dir =
|
|
4891
|
+
const root = path15.resolve(getContainingRoot(absPath));
|
|
4892
|
+
let dir = path15.dirname(absPath);
|
|
4777
4893
|
while (true) {
|
|
4778
|
-
const candidate =
|
|
4894
|
+
const candidate = path15.join(dir, "tsconfig.json");
|
|
4779
4895
|
try {
|
|
4780
4896
|
if (fsSync3.existsSync(candidate)) return candidate;
|
|
4781
4897
|
} catch {
|
|
4782
4898
|
}
|
|
4783
|
-
if (
|
|
4784
|
-
const parent =
|
|
4899
|
+
if (path15.resolve(dir) === root) break;
|
|
4900
|
+
const parent = path15.dirname(dir);
|
|
4785
4901
|
if (parent === dir) break;
|
|
4786
4902
|
dir = parent;
|
|
4787
4903
|
}
|
|
@@ -4792,7 +4908,7 @@ var init_tsHost = __esm({
|
|
|
4792
4908
|
if (!tsConfigPath) {
|
|
4793
4909
|
return { options: buildDefaultOptions(ts), fileNames: [], projectRoot: getContainingRoot(absPath) };
|
|
4794
4910
|
}
|
|
4795
|
-
const basePath =
|
|
4911
|
+
const basePath = path15.dirname(tsConfigPath);
|
|
4796
4912
|
const raw = ts.readConfigFile(tsConfigPath, ts.sys.readFile);
|
|
4797
4913
|
if (raw.error) return { options: buildDefaultOptions(ts), fileNames: [], projectRoot: basePath };
|
|
4798
4914
|
const parsed = ts.parseJsonConfigFileContent(raw.config, ts.sys, basePath);
|
|
@@ -4803,7 +4919,7 @@ var init_tsHost = __esm({
|
|
|
4803
4919
|
const roots = /* @__PURE__ */ new Set();
|
|
4804
4920
|
const caseSensitive = ts.sys.useCaseSensitiveFileNames;
|
|
4805
4921
|
const canonical = (f) => caseSensitive ? f : f.toLowerCase();
|
|
4806
|
-
const keyOf = (f) => canonical(
|
|
4922
|
+
const keyOf = (f) => canonical(path15.resolve(f)).replace(/\\/g, "/");
|
|
4807
4923
|
rootFileNames.forEach((f) => roots.add(keyOf(f)));
|
|
4808
4924
|
const fresh = (fileName) => {
|
|
4809
4925
|
const key = keyOf(fileName);
|
|
@@ -4892,7 +5008,7 @@ var init_tsHost = __esm({
|
|
|
4892
5008
|
|
|
4893
5009
|
// ../core/src/tool/registry/fs.ts
|
|
4894
5010
|
import fs12 from "fs/promises";
|
|
4895
|
-
import
|
|
5011
|
+
import path16 from "path";
|
|
4896
5012
|
import { createReadStream } from "fs";
|
|
4897
5013
|
import * as readline from "readline";
|
|
4898
5014
|
var isSensitiveReadTarget, stripReadFileLineNumbers, maskSecretsInContent, makeTmpPath, ATOMIC_TMP_RE, sweepStaleAtomicTmp, assertReadable, stripEdgeBlankLines, matchLineBlockWith, diagnoseOldStr, reindentToBase, alignIndentsByAnchor, applyOneEditToContent, fsTools;
|
|
@@ -4953,7 +5069,7 @@ var init_fs = __esm({
|
|
|
4953
5069
|
return;
|
|
4954
5070
|
}
|
|
4955
5071
|
for (const e of entries) {
|
|
4956
|
-
const full =
|
|
5072
|
+
const full = path16.join(dir, e.name);
|
|
4957
5073
|
if (e.isDirectory()) {
|
|
4958
5074
|
if (!skipDirs.has(e.name)) await walk(full);
|
|
4959
5075
|
continue;
|
|
@@ -5227,8 +5343,8 @@ ${formattedCode}${hasMore ? `
|
|
|
5227
5343
|
const entries = await fs12.readdir(currentPath, { withFileTypes: true });
|
|
5228
5344
|
const validEntries = entries.filter((entry) => {
|
|
5229
5345
|
if (entry.isSymbolicLink()) return false;
|
|
5230
|
-
const fullPath =
|
|
5231
|
-
const relPath =
|
|
5346
|
+
const fullPath = path16.join(currentPath, entry.name);
|
|
5347
|
+
const relPath = path16.relative(getActiveWorkspaceRoot(), fullPath).replace(/\\/g, "/");
|
|
5232
5348
|
return !checkIsPathIgnored(entry.isDirectory() ? `${relPath}/` : relPath);
|
|
5233
5349
|
});
|
|
5234
5350
|
let output = "";
|
|
@@ -5247,7 +5363,7 @@ ${formattedCode}${hasMore ? `
|
|
|
5247
5363
|
`;
|
|
5248
5364
|
if (entry.isDirectory()) {
|
|
5249
5365
|
const nextPrefix = prefix + (isLast ? " " : "\u2502 ");
|
|
5250
|
-
const fullPath =
|
|
5366
|
+
const fullPath = path16.join(currentPath, entry.name);
|
|
5251
5367
|
const subTree = await buildTreeText(fullPath, currentDepth + 1, nextPrefix);
|
|
5252
5368
|
output += subTree;
|
|
5253
5369
|
}
|
|
@@ -5361,7 +5477,7 @@ ${summaries.join("\n")}`;
|
|
|
5361
5477
|
}
|
|
5362
5478
|
const content = args.content ?? "";
|
|
5363
5479
|
assertWithinWorkspace(absPath);
|
|
5364
|
-
await fs12.mkdir(
|
|
5480
|
+
await fs12.mkdir(path16.dirname(absPath), { recursive: true });
|
|
5365
5481
|
tmpPath = makeTmpPath(absPath);
|
|
5366
5482
|
await fs12.writeFile(tmpPath, content, "utf-8");
|
|
5367
5483
|
await fs12.rename(tmpPath, absPath);
|
|
@@ -5400,7 +5516,7 @@ ${summaries.join("\n")}`;
|
|
|
5400
5516
|
}
|
|
5401
5517
|
let rel = "";
|
|
5402
5518
|
try {
|
|
5403
|
-
rel =
|
|
5519
|
+
rel = path16.relative(getActiveWorkspaceRoot(), resolveSafePath(cleanPath));
|
|
5404
5520
|
} catch {
|
|
5405
5521
|
}
|
|
5406
5522
|
if (rel === "" || rel === "src") {
|
|
@@ -5421,8 +5537,8 @@ ${summaries.join("\n")}`;
|
|
|
5421
5537
|
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`;
|
|
5422
5538
|
}
|
|
5423
5539
|
const absPath = resolveSafePath(cleanPath);
|
|
5424
|
-
const rel =
|
|
5425
|
-
if (!rel || rel === "" || rel === "src" || rel.startsWith("..") ||
|
|
5540
|
+
const rel = path16.relative(getActiveWorkspaceRoot(), absPath);
|
|
5541
|
+
if (!rel || rel === "" || rel === "src" || rel.startsWith("..") || path16.isAbsolute(rel)) {
|
|
5426
5542
|
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`;
|
|
5427
5543
|
}
|
|
5428
5544
|
let stat;
|
|
@@ -5467,7 +5583,7 @@ ${summaries.join("\n")}`;
|
|
|
5467
5583
|
try {
|
|
5468
5584
|
const absPath = resolveSafePath(args.path);
|
|
5469
5585
|
assertWithinWorkspace(absPath);
|
|
5470
|
-
await fs12.mkdir(
|
|
5586
|
+
await fs12.mkdir(path16.dirname(absPath), { recursive: true });
|
|
5471
5587
|
tmpPath = makeTmpPath(absPath);
|
|
5472
5588
|
await fs12.writeFile(tmpPath, args.content, "utf-8");
|
|
5473
5589
|
await fs12.rename(tmpPath, absPath);
|
|
@@ -5601,7 +5717,7 @@ ${summaries.join("\n")}`;
|
|
|
5601
5717
|
}
|
|
5602
5718
|
assertWithinWorkspace(srcAbs);
|
|
5603
5719
|
assertWithinWorkspace(dstAbs);
|
|
5604
|
-
await fs12.mkdir(
|
|
5720
|
+
await fs12.mkdir(path16.dirname(dstAbs), { recursive: true });
|
|
5605
5721
|
await fs12.rename(srcAbs, dstAbs);
|
|
5606
5722
|
return `\u2705 [\u79FB\u52A8\u6210\u529F]\uFF1A[${args.source}] \u2192 [${args.destination}]\u3002`;
|
|
5607
5723
|
} catch (error) {
|
|
@@ -5616,7 +5732,7 @@ ${summaries.join("\n")}`;
|
|
|
5616
5732
|
|
|
5617
5733
|
// ../core/src/tool/registry/search.ts
|
|
5618
5734
|
import { rgPath } from "vscode-ripgrep";
|
|
5619
|
-
import
|
|
5735
|
+
import path17 from "path";
|
|
5620
5736
|
import fs13 from "fs/promises";
|
|
5621
5737
|
function escapeRegExp(string) {
|
|
5622
5738
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -5659,10 +5775,10 @@ var init_search = __esm({
|
|
|
5659
5775
|
const resolveSearchRoot = () => {
|
|
5660
5776
|
if (!args.path) return ctx?.cwd ?? getActiveWorkspaceRoot();
|
|
5661
5777
|
const p = args.path.trim();
|
|
5662
|
-
const looksLikeBareName = !
|
|
5778
|
+
const looksLikeBareName = !path17.isAbsolute(p) && !p.includes("/") && !p.includes("\\");
|
|
5663
5779
|
if (looksLikeBareName) {
|
|
5664
5780
|
const hit = getAllowedWorkspaceRoots().find((r) => {
|
|
5665
|
-
const bn =
|
|
5781
|
+
const bn = path17.basename(r);
|
|
5666
5782
|
return bn === p || bn.toLowerCase() === p.toLowerCase();
|
|
5667
5783
|
});
|
|
5668
5784
|
if (hit) return hit;
|
|
@@ -5751,7 +5867,7 @@ var init_search = __esm({
|
|
|
5751
5867
|
const GUIDE_CANDIDATES = ["CLAUDE.md", "AGENTS.md", "AGENT.md"];
|
|
5752
5868
|
for (const name of GUIDE_CANDIDATES) {
|
|
5753
5869
|
try {
|
|
5754
|
-
const content = await fs13.readFile(
|
|
5870
|
+
const content = await fs13.readFile(path17.join(getActiveWorkspaceRoot(), name), "utf-8");
|
|
5755
5871
|
return `[Project Guide via ${name}]
|
|
5756
5872
|
|
|
5757
5873
|
${content}`;
|
|
@@ -5984,7 +6100,7 @@ ${tail}`,
|
|
|
5984
6100
|
|
|
5985
6101
|
// ../core/src/tool/registry/glob.ts
|
|
5986
6102
|
import fs14 from "fs/promises";
|
|
5987
|
-
import
|
|
6103
|
+
import path18 from "path";
|
|
5988
6104
|
var findMatchingBrace, splitTopLevel, globToRegex2, globTools;
|
|
5989
6105
|
var init_glob = __esm({
|
|
5990
6106
|
"../core/src/tool/registry/glob.ts"() {
|
|
@@ -6090,16 +6206,16 @@ var init_glob = __esm({
|
|
|
6090
6206
|
if (scannedCount > MAX_SCAN_LIMIT) return;
|
|
6091
6207
|
const entries = await fs14.readdir(dir, { withFileTypes: true });
|
|
6092
6208
|
const validEntries = entries.filter((e) => {
|
|
6093
|
-
const full =
|
|
6094
|
-
const rel =
|
|
6209
|
+
const full = path18.join(dir, e.name);
|
|
6210
|
+
const rel = path18.relative(activeRoot, full).replace(/\\/g, "/");
|
|
6095
6211
|
return !checkIsPathIgnored(e.isDirectory() ? `${rel}/` : rel);
|
|
6096
6212
|
});
|
|
6097
6213
|
for (const e of validEntries) {
|
|
6098
6214
|
scannedCount++;
|
|
6099
6215
|
if (scannedCount > MAX_SCAN_LIMIT) break;
|
|
6100
6216
|
if (e.isSymbolicLink()) continue;
|
|
6101
|
-
const full =
|
|
6102
|
-
const rel =
|
|
6217
|
+
const full = path18.join(dir, e.name);
|
|
6218
|
+
const rel = path18.relative(activeRoot, full).replace(/\\/g, "/");
|
|
6103
6219
|
if (e.isDirectory()) {
|
|
6104
6220
|
if (cleanPattern.endsWith("/") && re.test(`${rel}/`)) {
|
|
6105
6221
|
hits.push(`${rel}/`);
|
|
@@ -6316,7 +6432,7 @@ ${summary}`;
|
|
|
6316
6432
|
|
|
6317
6433
|
// ../core/src/tool/registry/inspect_dependencies.ts
|
|
6318
6434
|
import * as fs15 from "fs/promises";
|
|
6319
|
-
import * as
|
|
6435
|
+
import * as path19 from "path";
|
|
6320
6436
|
var dependencyTools;
|
|
6321
6437
|
var init_inspect_dependencies = __esm({
|
|
6322
6438
|
"../core/src/tool/registry/inspect_dependencies.ts"() {
|
|
@@ -6337,7 +6453,7 @@ var init_inspect_dependencies = __esm({
|
|
|
6337
6453
|
isSync: true,
|
|
6338
6454
|
async execute() {
|
|
6339
6455
|
try {
|
|
6340
|
-
const pjsPath =
|
|
6456
|
+
const pjsPath = path19.join(getActiveWorkspaceRoot(), "package.json");
|
|
6341
6457
|
const raw = await fs15.readFile(pjsPath, "utf-8");
|
|
6342
6458
|
const pjs = JSON.parse(raw);
|
|
6343
6459
|
const result = {
|
|
@@ -6639,13 +6755,13 @@ async function safeFetchFollow(startUrl, baseHeaders, signals, allowPrivate = fa
|
|
|
6639
6755
|
return res;
|
|
6640
6756
|
}
|
|
6641
6757
|
}
|
|
6642
|
-
var
|
|
6758
|
+
var FETCH_TIMEOUT_MS2, SEARCH_TIMEOUT_MS, DEFAULT_MAX_CHARS, USER_AGENT, BROWSER_UA, TAVILY_ENDPOINT, formatHostBlockMessage, MAX_REDIRECTS, pinnedSsrfDispatcher, pinnedMetadataGuardDispatcher, readBodyCapped, webTools;
|
|
6643
6759
|
var init_web = __esm({
|
|
6644
6760
|
"../core/src/tool/registry/web.ts"() {
|
|
6645
6761
|
"use strict";
|
|
6646
6762
|
init_type();
|
|
6647
6763
|
init_config();
|
|
6648
|
-
|
|
6764
|
+
FETCH_TIMEOUT_MS2 = 15e3;
|
|
6649
6765
|
SEARCH_TIMEOUT_MS = 2e4;
|
|
6650
6766
|
DEFAULT_MAX_CHARS = 16e3;
|
|
6651
6767
|
USER_AGENT = "DeepSeeker-Code-Agent/1.0 (+web_fetch tool)";
|
|
@@ -6775,7 +6891,7 @@ var init_web = __esm({
|
|
|
6775
6891
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
6776
6892
|
return `\u274C [\u5B89\u5168\u7194\u65AD]\uFF1A\u4EC5\u5141\u8BB8 http/https \u534F\u8BAE\uFF0C\u62D2\u7EDD ${parsed.protocol}`;
|
|
6777
6893
|
}
|
|
6778
|
-
const signals = [AbortSignal.timeout(
|
|
6894
|
+
const signals = [AbortSignal.timeout(FETCH_TIMEOUT_MS2)];
|
|
6779
6895
|
if (ctx?.abortSignal) signals.push(ctx.abortSignal);
|
|
6780
6896
|
try {
|
|
6781
6897
|
const res = await safeFetchFollow(parsed.href, {
|
|
@@ -6812,7 +6928,7 @@ var init_web = __esm({
|
|
|
6812
6928
|
${body}${truncNote}`;
|
|
6813
6929
|
} catch (error) {
|
|
6814
6930
|
if (error?.name === "TimeoutError") {
|
|
6815
|
-
return `\u274C [\u6293\u53D6\u8D85\u65F6]\uFF1A${
|
|
6931
|
+
return `\u274C [\u6293\u53D6\u8D85\u65F6]\uFF1A${FETCH_TIMEOUT_MS2 / 1e3}s \u5185\u672A\u54CD\u5E94\uFF1A${parsed.href}`;
|
|
6816
6932
|
}
|
|
6817
6933
|
if (error?.name === "AbortError") {
|
|
6818
6934
|
return `\u23F9\uFE0F [\u5DF2\u4E2D\u6B62]\uFF1A\u7528\u6237\u4E2D\u65AD\u4E86\u6293\u53D6\uFF1A${parsed.href}`;
|
|
@@ -6981,7 +7097,7 @@ var init_http = __esm({
|
|
|
6981
7097
|
|
|
6982
7098
|
// ../core/src/tool/registry/typescript.ts
|
|
6983
7099
|
import fs16 from "fs/promises";
|
|
6984
|
-
import
|
|
7100
|
+
import path20 from "path";
|
|
6985
7101
|
var MAX_FILE_BYTES, toDisplayPath, precheck, MAX_DIAG_ENTRIES, MAX_DIAG_FILES, diagnoseOneFile, typescriptTools;
|
|
6986
7102
|
var init_typescript = __esm({
|
|
6987
7103
|
"../core/src/tool/registry/typescript.ts"() {
|
|
@@ -6992,8 +7108,8 @@ var init_typescript = __esm({
|
|
|
6992
7108
|
init_fs();
|
|
6993
7109
|
MAX_FILE_BYTES = 1024 * 1024;
|
|
6994
7110
|
toDisplayPath = (wsRoot, abs) => {
|
|
6995
|
-
const rel =
|
|
6996
|
-
if (rel && !rel.startsWith("..") && !
|
|
7111
|
+
const rel = path20.relative(wsRoot, abs);
|
|
7112
|
+
if (rel && !rel.startsWith("..") && !path20.isAbsolute(rel)) return rel.replace(/\\/g, "/");
|
|
6997
7113
|
return abs.replace(/\\/g, "/").split("/").slice(-3).join("/");
|
|
6998
7114
|
};
|
|
6999
7115
|
precheck = async (displayPath, absPath) => {
|
|
@@ -7252,7 +7368,7 @@ var init_todo = __esm({
|
|
|
7252
7368
|
|
|
7253
7369
|
// ../core/src/observability/traceCalculate.ts
|
|
7254
7370
|
import fs17 from "fs/promises";
|
|
7255
|
-
import
|
|
7371
|
+
import path21 from "path";
|
|
7256
7372
|
var getDirBytes, getTodayDateString;
|
|
7257
7373
|
var init_traceCalculate = __esm({
|
|
7258
7374
|
"../core/src/observability/traceCalculate.ts"() {
|
|
@@ -7269,7 +7385,7 @@ var init_traceCalculate = __esm({
|
|
|
7269
7385
|
continue;
|
|
7270
7386
|
}
|
|
7271
7387
|
for (const e of entries) {
|
|
7272
|
-
const p =
|
|
7388
|
+
const p = path21.join(cur, e.name);
|
|
7273
7389
|
if (e.isDirectory()) {
|
|
7274
7390
|
stack.push(p);
|
|
7275
7391
|
} else {
|
|
@@ -7293,7 +7409,7 @@ var init_traceCalculate = __esm({
|
|
|
7293
7409
|
});
|
|
7294
7410
|
|
|
7295
7411
|
// ../core/src/tool/undo/store.ts
|
|
7296
|
-
import
|
|
7412
|
+
import path22 from "path";
|
|
7297
7413
|
import fs18 from "fs/promises";
|
|
7298
7414
|
var getUndoRootPath, getUndoClockPath, getUndoDirPath, getUndoBackupRoot, ensureUndoDir, getUndoIndexPath;
|
|
7299
7415
|
var init_store2 = __esm({
|
|
@@ -7302,14 +7418,14 @@ var init_store2 = __esm({
|
|
|
7302
7418
|
init_config();
|
|
7303
7419
|
init_common();
|
|
7304
7420
|
init_traceCalculate();
|
|
7305
|
-
getUndoRootPath = () =>
|
|
7306
|
-
getUndoClockPath = () =>
|
|
7421
|
+
getUndoRootPath = () => path22.join(appConfig.dataDir, "undo");
|
|
7422
|
+
getUndoClockPath = () => path22.join(getUndoRootPath(), "undo-cleanup-clock.json");
|
|
7307
7423
|
getUndoDirPath = (mainSessionId) => {
|
|
7308
7424
|
const rootId = getFileName(mainSessionId);
|
|
7309
7425
|
assertSafeSessionId(rootId, "undoSessionId");
|
|
7310
|
-
return
|
|
7426
|
+
return path22.join(getUndoRootPath(), appConfig.userWorkspaceDir, rootId);
|
|
7311
7427
|
};
|
|
7312
|
-
getUndoBackupRoot = (mainSessionId) =>
|
|
7428
|
+
getUndoBackupRoot = (mainSessionId) => path22.join(getUndoDirPath(mainSessionId), "backups");
|
|
7313
7429
|
ensureUndoDir = async (mainSessionId) => {
|
|
7314
7430
|
await fs18.mkdir(getUndoDirPath(mainSessionId), { recursive: true, mode: 448 });
|
|
7315
7431
|
};
|
|
@@ -7321,14 +7437,14 @@ var init_store2 = __esm({
|
|
|
7321
7437
|
const files = await fs18.readdir(dir);
|
|
7322
7438
|
const existedFile = files.find((f) => f.endsWith(`__${rootId}.jsonl`));
|
|
7323
7439
|
const fileName = existedFile ?? `undo-${getTodayDateString()}__${rootId}.jsonl`;
|
|
7324
|
-
return
|
|
7440
|
+
return path22.join(dir, fileName);
|
|
7325
7441
|
};
|
|
7326
7442
|
}
|
|
7327
7443
|
});
|
|
7328
7444
|
|
|
7329
7445
|
// ../core/src/tool/undo/index.ts
|
|
7330
7446
|
import fs19 from "fs/promises";
|
|
7331
|
-
import
|
|
7447
|
+
import path23 from "path";
|
|
7332
7448
|
var undoLocks, withUndoLock, appendUndoRecord, readUndoIndex, markRestored;
|
|
7333
7449
|
var init_undo = __esm({
|
|
7334
7450
|
"../core/src/tool/undo/index.ts"() {
|
|
@@ -7378,7 +7494,7 @@ var init_undo = __esm({
|
|
|
7378
7494
|
for (const f of files) {
|
|
7379
7495
|
if (!f.startsWith("undo-") || !f.endsWith(".jsonl")) continue;
|
|
7380
7496
|
try {
|
|
7381
|
-
const raw = await fs19.readFile(
|
|
7497
|
+
const raw = await fs19.readFile(path23.join(dir, f), "utf-8");
|
|
7382
7498
|
for (const line of raw.split("\n")) {
|
|
7383
7499
|
const trimmed = line.trim();
|
|
7384
7500
|
if (!trimmed) continue;
|
|
@@ -7409,7 +7525,7 @@ var init_undo = __esm({
|
|
|
7409
7525
|
}
|
|
7410
7526
|
for (const f of files) {
|
|
7411
7527
|
if (!f.startsWith("undo-") || !f.endsWith(".jsonl")) continue;
|
|
7412
|
-
const fp =
|
|
7528
|
+
const fp = path23.join(dir, f);
|
|
7413
7529
|
let raw;
|
|
7414
7530
|
try {
|
|
7415
7531
|
raw = await fs19.readFile(fp, "utf-8");
|
|
@@ -7447,7 +7563,7 @@ var init_undo = __esm({
|
|
|
7447
7563
|
|
|
7448
7564
|
// ../core/src/tool/undo/cleanup.ts
|
|
7449
7565
|
import fs20 from "fs/promises";
|
|
7450
|
-
import
|
|
7566
|
+
import path24 from "path";
|
|
7451
7567
|
async function maybeCleanupAfterUndoAppend(_sessionId) {
|
|
7452
7568
|
if (cleanupInProgress) return;
|
|
7453
7569
|
cleanupInProgress = true;
|
|
@@ -7473,7 +7589,7 @@ async function maybeCleanupAfterUndoAppend(_sessionId) {
|
|
|
7473
7589
|
lastSizeCleanupAt = now;
|
|
7474
7590
|
diskLastCleanupAt = now;
|
|
7475
7591
|
const clockPath = getUndoClockPath();
|
|
7476
|
-
await fs20.mkdir(
|
|
7592
|
+
await fs20.mkdir(path24.dirname(clockPath), { recursive: true });
|
|
7477
7593
|
await fs20.writeFile(clockPath, JSON.stringify({ lastCleanupAt: now, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), "utf-8");
|
|
7478
7594
|
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`);
|
|
7479
7595
|
} catch (e) {
|
|
@@ -7498,12 +7614,12 @@ async function cleanupOldUndoFiles() {
|
|
|
7498
7614
|
const re = /^undo-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
|
|
7499
7615
|
let deleted = 0;
|
|
7500
7616
|
for (const rp of relativePaths) {
|
|
7501
|
-
const fileName =
|
|
7617
|
+
const fileName = path24.basename(rp);
|
|
7502
7618
|
const m = fileName.match(re);
|
|
7503
7619
|
if (!m) continue;
|
|
7504
7620
|
const fileBornDay = /* @__PURE__ */ new Date(`${m[1]}T00:00:00`);
|
|
7505
7621
|
if (fileBornDay >= cutoff) continue;
|
|
7506
|
-
const fullPath =
|
|
7622
|
+
const fullPath = path24.join(dir, rp);
|
|
7507
7623
|
try {
|
|
7508
7624
|
const st = await fs20.stat(fullPath);
|
|
7509
7625
|
if (now - st.mtimeMs < ACTIVE_GRACE_MS) continue;
|
|
@@ -7525,10 +7641,10 @@ async function evictOldestForSize(targetBytes) {
|
|
|
7525
7641
|
const re = /^undo-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
|
|
7526
7642
|
const candidates = [];
|
|
7527
7643
|
for (const rp of relativePaths) {
|
|
7528
|
-
if (!re.test(
|
|
7644
|
+
if (!re.test(path24.basename(rp))) continue;
|
|
7529
7645
|
try {
|
|
7530
|
-
const st = await fs20.stat(
|
|
7531
|
-
candidates.push({ mtime: st.mtimeMs, fullPath:
|
|
7646
|
+
const st = await fs20.stat(path24.join(dir, rp));
|
|
7647
|
+
candidates.push({ mtime: st.mtimeMs, fullPath: path24.join(dir, rp), size: st.size });
|
|
7532
7648
|
} catch {
|
|
7533
7649
|
}
|
|
7534
7650
|
}
|
|
@@ -7557,7 +7673,7 @@ async function gcOrphanBackups() {
|
|
|
7557
7673
|
return 0;
|
|
7558
7674
|
}
|
|
7559
7675
|
for (const ws of workspaces) {
|
|
7560
|
-
const wsDir =
|
|
7676
|
+
const wsDir = path24.join(root, ws);
|
|
7561
7677
|
let stWs;
|
|
7562
7678
|
try {
|
|
7563
7679
|
stWs = await fs20.stat(wsDir);
|
|
@@ -7572,7 +7688,7 @@ async function gcOrphanBackups() {
|
|
|
7572
7688
|
continue;
|
|
7573
7689
|
}
|
|
7574
7690
|
for (const sess of sessions2) {
|
|
7575
|
-
const sessDir =
|
|
7691
|
+
const sessDir = path24.join(wsDir, sess);
|
|
7576
7692
|
const liveIds = /* @__PURE__ */ new Set();
|
|
7577
7693
|
let files;
|
|
7578
7694
|
try {
|
|
@@ -7583,7 +7699,7 @@ async function gcOrphanBackups() {
|
|
|
7583
7699
|
for (const f of files) {
|
|
7584
7700
|
if (!f.startsWith("undo-") || !f.endsWith(".jsonl")) continue;
|
|
7585
7701
|
try {
|
|
7586
|
-
const raw = await fs20.readFile(
|
|
7702
|
+
const raw = await fs20.readFile(path24.join(sessDir, f), "utf-8");
|
|
7587
7703
|
for (const line of raw.split("\n")) {
|
|
7588
7704
|
const t = line.trim();
|
|
7589
7705
|
if (!t) continue;
|
|
@@ -7596,7 +7712,7 @@ async function gcOrphanBackups() {
|
|
|
7596
7712
|
} catch {
|
|
7597
7713
|
}
|
|
7598
7714
|
}
|
|
7599
|
-
const backupsDir =
|
|
7715
|
+
const backupsDir = path24.join(sessDir, "backups");
|
|
7600
7716
|
let undoDirs;
|
|
7601
7717
|
try {
|
|
7602
7718
|
undoDirs = await fs20.readdir(backupsDir);
|
|
@@ -7606,7 +7722,7 @@ async function gcOrphanBackups() {
|
|
|
7606
7722
|
for (const ud of undoDirs) {
|
|
7607
7723
|
if (liveIds.has(ud)) continue;
|
|
7608
7724
|
try {
|
|
7609
|
-
await fs20.rm(
|
|
7725
|
+
await fs20.rm(path24.join(backupsDir, ud), { recursive: true, force: true });
|
|
7610
7726
|
deleted += 1;
|
|
7611
7727
|
} catch {
|
|
7612
7728
|
}
|
|
@@ -7649,7 +7765,7 @@ var init_cleanup = __esm({
|
|
|
7649
7765
|
return 0;
|
|
7650
7766
|
}
|
|
7651
7767
|
for (const e of entries) {
|
|
7652
|
-
const full =
|
|
7768
|
+
const full = path24.join(dir, e.name);
|
|
7653
7769
|
if (e.isDirectory()) {
|
|
7654
7770
|
total += await getDirBytesRecursive(full);
|
|
7655
7771
|
} else if (e.isFile()) {
|
|
@@ -7666,7 +7782,7 @@ var init_cleanup = __esm({
|
|
|
7666
7782
|
|
|
7667
7783
|
// ../core/src/tool/undo/backup.ts
|
|
7668
7784
|
import fs21 from "fs/promises";
|
|
7669
|
-
import
|
|
7785
|
+
import path25 from "path";
|
|
7670
7786
|
import crypto from "crypto";
|
|
7671
7787
|
async function beforeMutationBackup(toolName, args, toolCallId, sessionId) {
|
|
7672
7788
|
if (appConfig.undoEnabled === false) return null;
|
|
@@ -7681,7 +7797,7 @@ async function beforeMutationBackup(toolName, args, toolCallId, sessionId) {
|
|
|
7681
7797
|
}
|
|
7682
7798
|
await ensureUndoDir(sessionId);
|
|
7683
7799
|
const undoId = createUUID();
|
|
7684
|
-
const undoDir =
|
|
7800
|
+
const undoDir = path25.join(getUndoBackupRoot(sessionId), undoId);
|
|
7685
7801
|
const now = /* @__PURE__ */ new Date();
|
|
7686
7802
|
const common = {
|
|
7687
7803
|
undoId,
|
|
@@ -7731,7 +7847,7 @@ async function backupFileOverwrite(common, undoDir, args) {
|
|
|
7731
7847
|
}
|
|
7732
7848
|
const content = await fs21.readFile(absPath);
|
|
7733
7849
|
await fs21.mkdir(undoDir, { recursive: true, mode: 448 });
|
|
7734
|
-
const contentPath =
|
|
7850
|
+
const contentPath = path25.join(undoDir, "content");
|
|
7735
7851
|
await fs21.writeFile(contentPath, content, { mode: 384 });
|
|
7736
7852
|
return {
|
|
7737
7853
|
...common,
|
|
@@ -7768,7 +7884,7 @@ async function backupDelete(common, undoDir, relativePath) {
|
|
|
7768
7884
|
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`);
|
|
7769
7885
|
}
|
|
7770
7886
|
}
|
|
7771
|
-
const treeDest =
|
|
7887
|
+
const treeDest = path25.join(undoDir, "tree");
|
|
7772
7888
|
const sensitiveSet = new Set(sensitiveInTree);
|
|
7773
7889
|
await fs21.cp(absPath, treeDest, {
|
|
7774
7890
|
recursive: true,
|
|
@@ -7776,7 +7892,7 @@ async function backupDelete(common, undoDir, relativePath) {
|
|
|
7776
7892
|
preserveTimestamps: true,
|
|
7777
7893
|
filter: (src) => {
|
|
7778
7894
|
if (src === absPath) return true;
|
|
7779
|
-
const relWithin =
|
|
7895
|
+
const relWithin = path25.relative(absPath, src).replace(/\\/g, "/");
|
|
7780
7896
|
return !sensitiveSet.has(relWithin);
|
|
7781
7897
|
}
|
|
7782
7898
|
});
|
|
@@ -7793,7 +7909,7 @@ async function backupDelete(common, undoDir, relativePath) {
|
|
|
7793
7909
|
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`);
|
|
7794
7910
|
}
|
|
7795
7911
|
const content = await fs21.readFile(absPath);
|
|
7796
|
-
const contentPath =
|
|
7912
|
+
const contentPath = path25.join(undoDir, "content");
|
|
7797
7913
|
await fs21.writeFile(contentPath, content, { mode: 384 });
|
|
7798
7914
|
return {
|
|
7799
7915
|
...common,
|
|
@@ -7845,8 +7961,8 @@ var init_backup = __esm({
|
|
|
7845
7961
|
}
|
|
7846
7962
|
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
7847
7963
|
for (const e of entries) {
|
|
7848
|
-
const full =
|
|
7849
|
-
const rel =
|
|
7964
|
+
const full = path25.join(d, e.name);
|
|
7965
|
+
const rel = path25.relative(dir, full).replace(/\\/g, "/");
|
|
7850
7966
|
if (e.isDirectory()) {
|
|
7851
7967
|
h.update(`D ${rel}
|
|
7852
7968
|
`);
|
|
@@ -7872,7 +7988,7 @@ var init_backup = __esm({
|
|
|
7872
7988
|
return 0;
|
|
7873
7989
|
}
|
|
7874
7990
|
for (const e of entries) {
|
|
7875
|
-
const full =
|
|
7991
|
+
const full = path25.join(dir, e.name);
|
|
7876
7992
|
if (e.isDirectory()) total += await getDirTreeBytes(full);
|
|
7877
7993
|
else if (e.isFile()) {
|
|
7878
7994
|
try {
|
|
@@ -7893,11 +8009,11 @@ var init_backup = __esm({
|
|
|
7893
8009
|
return;
|
|
7894
8010
|
}
|
|
7895
8011
|
for (const e of entries) {
|
|
7896
|
-
const full =
|
|
8012
|
+
const full = path25.join(d, e.name);
|
|
7897
8013
|
if (e.isDirectory()) {
|
|
7898
8014
|
await walk(full);
|
|
7899
8015
|
} else if (e.isFile()) {
|
|
7900
|
-
const relWithin =
|
|
8016
|
+
const relWithin = path25.relative(dir, full).replace(/\\/g, "/");
|
|
7901
8017
|
if (isSensitivePath(`${wsRelDir}/${relWithin}`)) found.push(relWithin);
|
|
7902
8018
|
}
|
|
7903
8019
|
}
|
|
@@ -7910,7 +8026,7 @@ var init_backup = __esm({
|
|
|
7910
8026
|
|
|
7911
8027
|
// ../core/src/tool/undo/restore.ts
|
|
7912
8028
|
import fs22 from "fs/promises";
|
|
7913
|
-
import
|
|
8029
|
+
import path26 from "path";
|
|
7914
8030
|
import crypto2 from "crypto";
|
|
7915
8031
|
async function doRestore(target, sessionId) {
|
|
7916
8032
|
if (target.backupKind === "directory_tree") {
|
|
@@ -7968,16 +8084,16 @@ async function ensureReverseBackup(target, sessionId) {
|
|
|
7968
8084
|
}
|
|
7969
8085
|
}
|
|
7970
8086
|
const reverseId = createUUID();
|
|
7971
|
-
const reverseDir =
|
|
8087
|
+
const reverseDir = path26.join(getUndoBackupRoot(sessionId), reverseId);
|
|
7972
8088
|
await fs22.mkdir(reverseDir, { recursive: true, mode: 448 });
|
|
7973
8089
|
assertWithinWorkspace(absPath);
|
|
7974
8090
|
const st = await fs22.stat(absPath);
|
|
7975
8091
|
if (st.isDirectory()) {
|
|
7976
|
-
const dest2 =
|
|
8092
|
+
const dest2 = path26.join(reverseDir, "tree");
|
|
7977
8093
|
await fs22.cp(absPath, dest2, { recursive: true, force: true, preserveTimestamps: true });
|
|
7978
8094
|
return { reverseId, backupKind: "directory_tree", backupPath: dest2 };
|
|
7979
8095
|
}
|
|
7980
|
-
const dest =
|
|
8096
|
+
const dest = path26.join(reverseDir, "content");
|
|
7981
8097
|
await fs22.writeFile(dest, await fs22.readFile(absPath));
|
|
7982
8098
|
return { reverseId, backupKind: "file_content", backupPath: dest };
|
|
7983
8099
|
}
|
|
@@ -7990,15 +8106,15 @@ async function dispatchRestore(r) {
|
|
|
7990
8106
|
return `\u5DF2\u5220\u9664\u65B0\u5EFA\u6587\u4EF6 [${r.relativePath}]`;
|
|
7991
8107
|
}
|
|
7992
8108
|
case "file_content": {
|
|
7993
|
-
await fs22.mkdir(
|
|
7994
|
-
const backupAbs =
|
|
8109
|
+
await fs22.mkdir(path26.dirname(absPath), { recursive: true });
|
|
8110
|
+
const backupAbs = path26.join(getUndoBackupRoot(r.sessionId), r.undoId, "content");
|
|
7995
8111
|
const content = await fs22.readFile(backupAbs);
|
|
7996
8112
|
await fs22.writeFile(absPath, content);
|
|
7997
8113
|
return `\u5DF2\u6062\u590D [${r.relativePath}] \u81F3\u5907\u4EFD\u524D\u5185\u5BB9\uFF08${r.fileSizeBefore ?? content.byteLength} \u5B57\u8282\uFF09`;
|
|
7998
8114
|
}
|
|
7999
8115
|
case "directory_tree": {
|
|
8000
|
-
await fs22.mkdir(
|
|
8001
|
-
const src =
|
|
8116
|
+
await fs22.mkdir(path26.dirname(absPath), { recursive: true });
|
|
8117
|
+
const src = path26.join(getUndoBackupRoot(r.sessionId), r.undoId, "tree");
|
|
8002
8118
|
await fs22.cp(src, absPath, { recursive: true, force: true, preserveTimestamps: true });
|
|
8003
8119
|
return `\u5DF2\u6062\u590D\u76EE\u5F55\u6811 [${r.relativePath}]\uFF08\u7EA6 ${r.fileSizeBefore ?? 0} \u5B57\u8282\uFF09`;
|
|
8004
8120
|
}
|
|
@@ -8482,7 +8598,7 @@ var init_frontmatter = __esm({
|
|
|
8482
8598
|
|
|
8483
8599
|
// ../core/src/memory/loader.ts
|
|
8484
8600
|
import fs24 from "fs/promises";
|
|
8485
|
-
import
|
|
8601
|
+
import path27 from "path";
|
|
8486
8602
|
var GLOBAL_MEMORY_DIR, SOURCES, VALID_TYPES, parseMemoryAt, loadMemories, initMemories;
|
|
8487
8603
|
var init_loader3 = __esm({
|
|
8488
8604
|
"../core/src/memory/loader.ts"() {
|
|
@@ -8491,10 +8607,10 @@ var init_loader3 = __esm({
|
|
|
8491
8607
|
init_frontmatter();
|
|
8492
8608
|
init_registry6();
|
|
8493
8609
|
init_registry2();
|
|
8494
|
-
GLOBAL_MEMORY_DIR =
|
|
8610
|
+
GLOBAL_MEMORY_DIR = path27.join(appConfig.dataDir, "memory");
|
|
8495
8611
|
SOURCES = [
|
|
8496
8612
|
{ dir: GLOBAL_MEMORY_DIR, source: "global" },
|
|
8497
|
-
{ dir:
|
|
8613
|
+
{ dir: path27.join(process.cwd(), ".deepseeker-code", "memory"), source: "project" }
|
|
8498
8614
|
];
|
|
8499
8615
|
VALID_TYPES = ["user", "feedback", "project", "reference"];
|
|
8500
8616
|
parseMemoryAt = async (file, _dir, source) => {
|
|
@@ -8534,7 +8650,7 @@ var init_loader3 = __esm({
|
|
|
8534
8650
|
clearMemories();
|
|
8535
8651
|
const picked = await scanSources(
|
|
8536
8652
|
filterSources(SOURCES, includeProject),
|
|
8537
|
-
(e, dir) => e.isFile() && e.name.endsWith(".md") ?
|
|
8653
|
+
(e, dir) => e.isFile() && e.name.endsWith(".md") ? path27.join(dir, e.name) : void 0,
|
|
8538
8654
|
parseMemoryAt
|
|
8539
8655
|
);
|
|
8540
8656
|
for (const { item } of picked) registerMemory(item);
|
|
@@ -8553,7 +8669,7 @@ var init_loader3 = __esm({
|
|
|
8553
8669
|
|
|
8554
8670
|
// ../core/src/tool/registry/memory.ts
|
|
8555
8671
|
import fs25 from "fs/promises";
|
|
8556
|
-
import
|
|
8672
|
+
import path28 from "path";
|
|
8557
8673
|
var MAX_BODY_BYTES, NAME_RE, VALID_TYPES2, memoryFilePath, sanitizeLine, buildMemoryMd, writeAndRegister, memoryTools;
|
|
8558
8674
|
var init_memory = __esm({
|
|
8559
8675
|
"../core/src/tool/registry/memory.ts"() {
|
|
@@ -8565,7 +8681,7 @@ var init_memory = __esm({
|
|
|
8565
8681
|
MAX_BODY_BYTES = 64 * 1024;
|
|
8566
8682
|
NAME_RE = /^[a-z0-9-]+$/;
|
|
8567
8683
|
VALID_TYPES2 = ["user", "feedback", "project", "reference"];
|
|
8568
|
-
memoryFilePath = (name, project) => project ?
|
|
8684
|
+
memoryFilePath = (name, project) => project ? path28.join(process.cwd(), ".deepseeker-code", "memory", `${name}.md`) : path28.join(GLOBAL_MEMORY_DIR, `${name}.md`);
|
|
8569
8685
|
sanitizeLine = (s) => String(s ?? "").replace(/[\r\n]+/g, " ").trim();
|
|
8570
8686
|
buildMemoryMd = (name, description, type, body) => `---
|
|
8571
8687
|
name: ${name}
|
|
@@ -8577,7 +8693,7 @@ ${body.trim()}
|
|
|
8577
8693
|
`;
|
|
8578
8694
|
writeAndRegister = async (name, description, type, body, project) => {
|
|
8579
8695
|
const file = memoryFilePath(name, project);
|
|
8580
|
-
await fs25.mkdir(
|
|
8696
|
+
await fs25.mkdir(path28.dirname(file), { recursive: true });
|
|
8581
8697
|
const tmp = makeTmpPath(file);
|
|
8582
8698
|
await fs25.writeFile(tmp, buildMemoryMd(name, description, type, body), "utf-8");
|
|
8583
8699
|
await fs25.rename(tmp, file);
|
|
@@ -9117,7 +9233,7 @@ var init_backgroundTool = __esm({
|
|
|
9117
9233
|
});
|
|
9118
9234
|
|
|
9119
9235
|
// ../core/src/tool/autoPermission.ts
|
|
9120
|
-
import
|
|
9236
|
+
import path29 from "path";
|
|
9121
9237
|
var AUTO_SCOPE, AUTO_DEFAULT_EXTRA, AUTO_AGGRESSIVE_EXTRA, isMcpTool, BUILTIN_AUTO_DENY, matchBuiltinDeny, COMMAND_DENY, matchCommandDeny, hasShellMetachars, READONLY_HEADS, hasWriteModifier, SENSITIVE_FILE_ARG_RE, hasSensitiveFileArg, isReadOnlyCommand, isWithinWorkspace, runAutoCheck;
|
|
9122
9238
|
var init_autoPermission = __esm({
|
|
9123
9239
|
"../core/src/tool/autoPermission.ts"() {
|
|
@@ -9252,9 +9368,9 @@ var init_autoPermission = __esm({
|
|
|
9252
9368
|
isWithinWorkspace = (p, cwd) => {
|
|
9253
9369
|
if (!p || !cwd) return false;
|
|
9254
9370
|
try {
|
|
9255
|
-
const abs =
|
|
9256
|
-
const rel =
|
|
9257
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
9371
|
+
const abs = path29.isAbsolute(p) ? p : path29.resolve(cwd, p);
|
|
9372
|
+
const rel = path29.relative(cwd, abs);
|
|
9373
|
+
return rel === "" || !rel.startsWith("..") && !path29.isAbsolute(rel);
|
|
9258
9374
|
} catch {
|
|
9259
9375
|
return false;
|
|
9260
9376
|
}
|
|
@@ -9902,6 +10018,7 @@ var init_agentNudges = __esm({
|
|
|
9902
10018
|
createNudgeScheduler = (opts = {}) => {
|
|
9903
10019
|
const firstPrompt = opts.firstPrompt ?? "";
|
|
9904
10020
|
const planMode = !!opts.planMode;
|
|
10021
|
+
const noEarlyFinal = !!opts.noEarlyFinal;
|
|
9905
10022
|
let phantomRetries = 0;
|
|
9906
10023
|
let phantomPending = null;
|
|
9907
10024
|
let earlyFinalNudges = 0;
|
|
@@ -9964,7 +10081,7 @@ ${TOOL_DIGEST_TEXT}` };
|
|
|
9964
10081
|
${PHANTOM_TEXT}` };
|
|
9965
10082
|
return true;
|
|
9966
10083
|
}
|
|
9967
|
-
if (text !== "" && round <= EARLY_FINAL_TURN_THRESHOLD && earlyFinalNudges < EARLY_FINAL_MAX && !looksComplete(finalText)) {
|
|
10084
|
+
if (!noEarlyFinal && text !== "" && round <= EARLY_FINAL_TURN_THRESHOLD && earlyFinalNudges < EARLY_FINAL_MAX && !looksComplete(finalText)) {
|
|
9968
10085
|
earlyFinalNudges++;
|
|
9969
10086
|
earlyFinalPending = { role: "system", content: `${EARLY_FINAL_FENCE}
|
|
9970
10087
|
${EARLY_FINAL_TEXT(round)}` };
|
|
@@ -10049,7 +10166,7 @@ async function* runAgent(message, options) {
|
|
|
10049
10166
|
const m = message.find((x) => x?.role === "user");
|
|
10050
10167
|
return typeof m?.content === "string" ? m.content : "";
|
|
10051
10168
|
})();
|
|
10052
|
-
const nudges = createNudgeScheduler({ firstPrompt, planMode: !!options.planMode });
|
|
10169
|
+
const nudges = createNudgeScheduler({ firstPrompt, planMode: !!options.planMode, noEarlyFinal: !!options.noEarlyFinal });
|
|
10053
10170
|
const userDecisionSource = depth > 0 ? "spawn_agent" : "user";
|
|
10054
10171
|
const llmDecisionSource = depth > 0 ? "llm_spawn_agent" : "llm";
|
|
10055
10172
|
const startTime = performance.now();
|
|
@@ -10178,7 +10295,6 @@ async function* runAgent(message, options) {
|
|
|
10178
10295
|
if (assistantMessage.content) {
|
|
10179
10296
|
lastContent = assistantMessage.content;
|
|
10180
10297
|
}
|
|
10181
|
-
const tcCount = assistantMessage.tool_calls?.length ?? 0;
|
|
10182
10298
|
if (!assistantMessage.tool_calls || assistantMessage.tool_calls.length === 0) {
|
|
10183
10299
|
await appendEvent(sessionId, { dscEvent: "round.end", runId, round, usage: infResult.usage });
|
|
10184
10300
|
const finalText = (typeof assistantMessage.content === "string" ? assistantMessage.content : "") || "";
|
|
@@ -10423,8 +10539,61 @@ var init_content = __esm({
|
|
|
10423
10539
|
}
|
|
10424
10540
|
});
|
|
10425
10541
|
|
|
10542
|
+
// ../core/src/session/lineage.ts
|
|
10543
|
+
import fs27 from "node:fs";
|
|
10544
|
+
var parentOfSubsession, stringAncestorsOf, readForkedFromSync, lineageClosureOf, ownerCanApprove;
|
|
10545
|
+
var init_lineage = __esm({
|
|
10546
|
+
"../core/src/session/lineage.ts"() {
|
|
10547
|
+
"use strict";
|
|
10548
|
+
init_store();
|
|
10549
|
+
parentOfSubsession = (sessionId) => {
|
|
10550
|
+
const i = sessionId.lastIndexOf("__sub__");
|
|
10551
|
+
return i > 0 ? sessionId.slice(0, i) : void 0;
|
|
10552
|
+
};
|
|
10553
|
+
stringAncestorsOf = (sessionId) => {
|
|
10554
|
+
const out = [sessionId];
|
|
10555
|
+
let cur = sessionId;
|
|
10556
|
+
for (; ; ) {
|
|
10557
|
+
const p = parentOfSubsession(cur);
|
|
10558
|
+
if (p === void 0) break;
|
|
10559
|
+
out.push(p);
|
|
10560
|
+
cur = p;
|
|
10561
|
+
}
|
|
10562
|
+
return out;
|
|
10563
|
+
};
|
|
10564
|
+
readForkedFromSync = (sessionId) => {
|
|
10565
|
+
try {
|
|
10566
|
+
const raw = fs27.readFileSync(getStatePath(sessionId), "utf-8");
|
|
10567
|
+
const v = JSON.parse(raw)?.forkedFrom;
|
|
10568
|
+
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
10569
|
+
} catch {
|
|
10570
|
+
return void 0;
|
|
10571
|
+
}
|
|
10572
|
+
};
|
|
10573
|
+
lineageClosureOf = (sessionId) => {
|
|
10574
|
+
const closure = /* @__PURE__ */ new Set();
|
|
10575
|
+
const expand = (id) => {
|
|
10576
|
+
if (closure.has(id)) return;
|
|
10577
|
+
const ancestors = stringAncestorsOf(id);
|
|
10578
|
+
for (const a of ancestors) closure.add(a);
|
|
10579
|
+
const root = ancestors[ancestors.length - 1];
|
|
10580
|
+
const from = readForkedFromSync(root);
|
|
10581
|
+
if (from && !closure.has(from)) expand(from);
|
|
10582
|
+
};
|
|
10583
|
+
expand(sessionId);
|
|
10584
|
+
return closure;
|
|
10585
|
+
};
|
|
10586
|
+
ownerCanApprove = (entrySessionId, approverSessionId) => {
|
|
10587
|
+
if (entrySessionId === approverSessionId) return true;
|
|
10588
|
+
if (!entrySessionId.includes("__sub__")) return false;
|
|
10589
|
+
const closure = lineageClosureOf(approverSessionId);
|
|
10590
|
+
return stringAncestorsOf(entrySessionId).some((a, i) => i > 0 && closure.has(a));
|
|
10591
|
+
};
|
|
10592
|
+
}
|
|
10593
|
+
});
|
|
10594
|
+
|
|
10426
10595
|
// ../core/src/agent/subagent.ts
|
|
10427
|
-
var SUBAGENT_DENYLIST, runSubagent;
|
|
10596
|
+
var SUBAGENT_DENYLIST, activeSubagents, RESUME_NOTE, runSubagent;
|
|
10428
10597
|
var init_subagent = __esm({
|
|
10429
10598
|
"../core/src/agent/subagent.ts"() {
|
|
10430
10599
|
"use strict";
|
|
@@ -10435,9 +10604,18 @@ var init_subagent = __esm({
|
|
|
10435
10604
|
init_type();
|
|
10436
10605
|
init_registry4();
|
|
10437
10606
|
init_hooks();
|
|
10607
|
+
init_lineage();
|
|
10438
10608
|
SUBAGENT_DENYLIST = /* @__PURE__ */ new Set(["run_command", "delete_path"]);
|
|
10609
|
+
activeSubagents = /* @__PURE__ */ new Set();
|
|
10610
|
+
RESUME_NOTE = [
|
|
10611
|
+
`
|
|
10612
|
+
# \u3010\u7EED\u8DD1\u8BF4\u660E\u3011`,
|
|
10613
|
+
`\u4F60\u6B64\u524D\u7684\u5DE5\u4F5C\u5386\u53F2\u5DF2\u5B8C\u6574\u6062\u590D\u5230\u672C\u6B21\u4E0A\u4E0B\u6587\uFF08\u78C1\u76D8\u6700\u65B0\u72B6\u6001\uFF0C\u53EF\u80FD\u6BD4\u4F60\u4E0A\u6B21\u8BB0\u5FC6\u66F4\u65B0\uFF09\u3002`,
|
|
10614
|
+
`\u8BF7\u5148\u5BF9\u7167\u5386\u53F2\u7B80\u8981\u56DE\u987E\u5DF2\u5B8C\u6210 / \u672A\u5B8C\u6210\u90E8\u5206\uFF0C\u518D\u7EE7\u7EED\u6267\u884C\u65B0\u4EFB\u52A1\uFF1B\u6700\u7EC8\u6C47\u62A5\u4E5F\u8BF7\u5148\u6982\u8FF0\u6B64\u524D\u8FDB\u5C55\u3002`
|
|
10615
|
+
].join("\n");
|
|
10439
10616
|
runSubagent = async (spec, ctx, getGlobalTools) => {
|
|
10440
|
-
const { task, name, role } = spec;
|
|
10617
|
+
const { task, name, role, resumeSessionId } = spec;
|
|
10618
|
+
const resuming = typeof resumeSessionId === "string" && resumeSessionId.length > 0;
|
|
10441
10619
|
if (ctx.depth >= MAX_AGENT_DEPTH) {
|
|
10442
10620
|
return {
|
|
10443
10621
|
ok: false,
|
|
@@ -10445,7 +10623,39 @@ var init_subagent = __esm({
|
|
|
10445
10623
|
sessionId: ""
|
|
10446
10624
|
};
|
|
10447
10625
|
}
|
|
10448
|
-
|
|
10626
|
+
if (resuming) {
|
|
10627
|
+
const target = resumeSessionId;
|
|
10628
|
+
if (!target.includes("__sub__")) {
|
|
10629
|
+
return {
|
|
10630
|
+
ok: false,
|
|
10631
|
+
output: `\u274C [\u7EED\u8DD1\u5931\u8D25]\uFF1A${target} \u4E0D\u662F\u5B50 Agent \u4F1A\u8BDD ID\uFF08\u5E94\u5F62\u5982 <\u4F1A\u8BDD>__sub__<uuid>\uFF0C\u6765\u81EA\u6B64\u524D spawn_agent \u8FD4\u56DE\u7684 agent_id\uFF09\u3002`,
|
|
10632
|
+
sessionId: ""
|
|
10633
|
+
};
|
|
10634
|
+
}
|
|
10635
|
+
if (!ownerCanApprove(target, ctx.sessionId)) {
|
|
10636
|
+
return {
|
|
10637
|
+
ok: false,
|
|
10638
|
+
output: `\u274C [\u7EED\u8DD1\u5931\u8D25]\uFF1A\u5B50\u4F1A\u8BDD ${target} \u4E0D\u5C5E\u4E8E\u5F53\u524D\u4F1A\u8BDD\uFF08\u53CA\u5176 fork \u8840\u7F18\uFF09\uFF0C\u7981\u6B62\u8DE8\u4F1A\u8BDD\u590D\u6D3B\u3002\u8BF7\u6838\u5BF9 agent_id \u6216\u6539\u7528\u65B0\u5EFA\u6D3E\u751F\u3002`,
|
|
10639
|
+
sessionId: ""
|
|
10640
|
+
};
|
|
10641
|
+
}
|
|
10642
|
+
if (activeSubagents.has(target)) {
|
|
10643
|
+
return {
|
|
10644
|
+
ok: false,
|
|
10645
|
+
output: `\u274C [\u7EED\u8DD1\u5931\u8D25]\uFF1A\u5B50 Agent ${target} \u6B63\u5728\u6267\u884C\u4E2D\uFF0C\u7981\u6B62\u5E76\u53D1\u7EED\u8DD1\u540C\u4E00\u5B50\u4F1A\u8BDD\uFF08\u4F1A\u4EA4\u53C9\u5199\u574F\u8F6C\u5F55\uFF09\u3002\u8BF7\u7B49\u5F85\u5176\u5B8C\u6210\u540E\u518D\u8BD5\u3002`,
|
|
10646
|
+
sessionId: ""
|
|
10647
|
+
};
|
|
10648
|
+
}
|
|
10649
|
+
const existing = await readTranscriptLines(target);
|
|
10650
|
+
if (existing.length === 0) {
|
|
10651
|
+
return {
|
|
10652
|
+
ok: false,
|
|
10653
|
+
output: `\u274C [\u7EED\u8DD1\u5931\u8D25]\uFF1A\u5B50\u4F1A\u8BDD ${target} \u7684\u8F6C\u5F55\u4E0D\u5B58\u5728\u6216\u4E3A\u7A7A\uFF0C\u65E0\u6CD5\u7EED\u8DD1\u3002\u8BF7\u6539\u7528\u65B0\u5EFA\u6D3E\u751F\u3002`,
|
|
10654
|
+
sessionId: ""
|
|
10655
|
+
};
|
|
10656
|
+
}
|
|
10657
|
+
}
|
|
10658
|
+
const subSessionId = resuming ? resumeSessionId : `${ctx.sessionId}__sub__${createUUID()}`;
|
|
10449
10659
|
const parentSystemPrompt = ctx.parentSystemPrompt || "";
|
|
10450
10660
|
const manifest = name ? getAgent(name) : void 0;
|
|
10451
10661
|
if (name && !manifest) {
|
|
@@ -10455,7 +10665,7 @@ var init_subagent = __esm({
|
|
|
10455
10665
|
sessionId: ""
|
|
10456
10666
|
};
|
|
10457
10667
|
}
|
|
10458
|
-
const subSystem = manifest ? [
|
|
10668
|
+
const subSystem = (manifest ? [
|
|
10459
10669
|
`# \u5B50 Agent \u8EAB\u4EFD\uFF1A${manifest.name}`,
|
|
10460
10670
|
manifest.body,
|
|
10461
10671
|
`
|
|
@@ -10478,11 +10688,12 @@ var init_subagent = __esm({
|
|
|
10478
10688
|
`
|
|
10479
10689
|
# \u3010\u7EE7\u627F\u7684\u5168\u5C40\u4EE3\u7801\u89C4\u8303\u3011`,
|
|
10480
10690
|
parentSystemPrompt
|
|
10481
|
-
].join("\n");
|
|
10691
|
+
].join("\n")) + (resuming ? RESUME_NOTE : "");
|
|
10482
10692
|
const allTools = getGlobalTools();
|
|
10483
10693
|
const wantsMcp = manifest?.tools.some((t) => t === "mcp_call" || t === "mcp_list_tools" || t.startsWith("mcp__")) ?? false;
|
|
10484
10694
|
const toolSchemas = manifest && manifest.tools.length > 0 ? allTools.filter((t) => manifest.tools.includes(t.function.name) || wantsMcp && (t.function.name === "mcp_call" || t.function.name === "mcp_list_tools")) : allTools.filter((t) => !SUBAGENT_DENYLIST.has(t.function.name));
|
|
10485
|
-
console.log(
|
|
10695
|
+
console.log(`${resuming ? "\u{1F501} \u7EED\u8DD1" : "\u{1F423} \u6D3E\u751F"}\u5B50 Agent [\u6DF1\u5EA6: ${ctx.depth + 1}/${MAX_AGENT_DEPTH}][${subSessionId}]${manifest ? ` \u58F0\u660E\u5F0F=${manifest.name}` : ""} \u4EFB\u52A1: "${task.slice(0, 50)}..."`);
|
|
10696
|
+
activeSubagents.add(subSessionId);
|
|
10486
10697
|
try {
|
|
10487
10698
|
const subMessages = await buildContextMessages(subSessionId, { role: "user", content: task }, subSystem);
|
|
10488
10699
|
await appendMessage({ sessionId: subSessionId, role: "user", content: task });
|
|
@@ -10506,6 +10717,8 @@ var init_subagent = __esm({
|
|
|
10506
10717
|
// ★ 同步透传宿主审批钩子,子 agent 高危工具仍走同一审批通道
|
|
10507
10718
|
permissionMode: ctx.permissionMode,
|
|
10508
10719
|
// ★ P1-6 透传:子 agent 工作区文件编辑也走 auto 分类器
|
|
10720
|
+
noEarlyFinal: true,
|
|
10721
|
+
// ★ 子 agent final 是交付父级的汇报,EARLY_FINAL 误推一轮纯浪费;父可经续跑纠错
|
|
10509
10722
|
model: manifest?.model
|
|
10510
10723
|
// ★ per-agent 模型覆盖;undefined 时 model.ts 回退全局 MODEL_NAME
|
|
10511
10724
|
};
|
|
@@ -10539,14 +10752,16 @@ var init_subagent = __esm({
|
|
|
10539
10752
|
return result ?? { ok: false, output: `\u274C [\u6D3E\u751F\u6267\u884C\u5931\u8D25]: \u672A\u77E5\u9519\u8BEF`, sessionId: subSessionId, manifestName: manifest?.name };
|
|
10540
10753
|
} catch (error) {
|
|
10541
10754
|
return { ok: false, output: `\u274C [\u6D3E\u751F\u6267\u884C\u5931\u8D25]: ${error.message}`, sessionId: subSessionId, manifestName: manifest?.name };
|
|
10755
|
+
} finally {
|
|
10756
|
+
activeSubagents.delete(subSessionId);
|
|
10542
10757
|
}
|
|
10543
10758
|
};
|
|
10544
10759
|
}
|
|
10545
10760
|
});
|
|
10546
10761
|
|
|
10547
10762
|
// ../core/src/hooks/loader.ts
|
|
10548
|
-
import
|
|
10549
|
-
import
|
|
10763
|
+
import fs28 from "fs/promises";
|
|
10764
|
+
import path30 from "path";
|
|
10550
10765
|
var readHooksConfig, appendValidated, validateRule, parseStdoutDecision, parseAgentDecision, compileRule2, loadHooks, initHooks;
|
|
10551
10766
|
var init_loader4 = __esm({
|
|
10552
10767
|
"../core/src/hooks/loader.ts"() {
|
|
@@ -10561,15 +10776,15 @@ var init_loader4 = __esm({
|
|
|
10561
10776
|
readHooksConfig = async (includeProject) => {
|
|
10562
10777
|
const merged = {};
|
|
10563
10778
|
const paths = [
|
|
10564
|
-
|
|
10779
|
+
path30.join(appConfig.dataDir, "settings.json"),
|
|
10565
10780
|
// 全局用户级
|
|
10566
|
-
...includeProject ? [
|
|
10781
|
+
...includeProject ? [path30.join(process.cwd(), ".deepseeker-code", "settings.json")] : []
|
|
10567
10782
|
// 项目级(叠加);未信任时省略
|
|
10568
10783
|
];
|
|
10569
10784
|
for (const configPath of paths) {
|
|
10570
10785
|
let raw;
|
|
10571
10786
|
try {
|
|
10572
|
-
raw = await
|
|
10787
|
+
raw = await fs28.readFile(configPath, "utf-8");
|
|
10573
10788
|
} catch {
|
|
10574
10789
|
continue;
|
|
10575
10790
|
}
|
|
@@ -10899,9 +11114,9 @@ ${m.context}`;
|
|
|
10899
11114
|
});
|
|
10900
11115
|
|
|
10901
11116
|
// ../core/src/skills/loader.ts
|
|
10902
|
-
import
|
|
10903
|
-
import
|
|
10904
|
-
import { fileURLToPath } from "url";
|
|
11117
|
+
import fs29 from "fs/promises";
|
|
11118
|
+
import path31 from "path";
|
|
11119
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
10905
11120
|
var BUILTIN_DIR, SOURCES2, MAX_SKILL_BODY_BYTES, splitList, parseSkillAt, loadSkills, initSkills;
|
|
10906
11121
|
var init_loader5 = __esm({
|
|
10907
11122
|
"../core/src/skills/loader.ts"() {
|
|
@@ -10911,18 +11126,18 @@ var init_loader5 = __esm({
|
|
|
10911
11126
|
init_registry3();
|
|
10912
11127
|
init_skill();
|
|
10913
11128
|
init_registry2();
|
|
10914
|
-
BUILTIN_DIR =
|
|
11129
|
+
BUILTIN_DIR = path31.join(path31.dirname(fileURLToPath2(import.meta.url)), "builtin");
|
|
10915
11130
|
SOURCES2 = [
|
|
10916
11131
|
{ dir: BUILTIN_DIR, source: "builtin" },
|
|
10917
|
-
{ dir:
|
|
10918
|
-
{ dir:
|
|
11132
|
+
{ dir: path31.join(appConfig.dataDir, "skills"), source: "global" },
|
|
11133
|
+
{ dir: path31.join(process.cwd(), ".deepseeker-code", "skills"), source: "project" }
|
|
10919
11134
|
];
|
|
10920
11135
|
MAX_SKILL_BODY_BYTES = 64 * 1024;
|
|
10921
11136
|
splitList = (raw) => (raw ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
10922
11137
|
parseSkillAt = async (skillFile, dir, source) => {
|
|
10923
11138
|
let raw;
|
|
10924
11139
|
try {
|
|
10925
|
-
raw = await
|
|
11140
|
+
raw = await fs29.readFile(skillFile, "utf-8");
|
|
10926
11141
|
} catch {
|
|
10927
11142
|
return null;
|
|
10928
11143
|
}
|
|
@@ -10961,7 +11176,7 @@ var init_loader5 = __esm({
|
|
|
10961
11176
|
loadSkills = async (includeProject) => {
|
|
10962
11177
|
const picked = await scanSources(
|
|
10963
11178
|
filterSources(SOURCES2, includeProject),
|
|
10964
|
-
(e, dir) => e.isDirectory() ?
|
|
11179
|
+
(e, dir) => e.isDirectory() ? path31.join(dir, e.name, "SKILL.md") : void 0,
|
|
10965
11180
|
parseSkillAt
|
|
10966
11181
|
);
|
|
10967
11182
|
for (const { item } of picked) registerSkill(item);
|
|
@@ -10992,9 +11207,9 @@ var init_loader5 = __esm({
|
|
|
10992
11207
|
});
|
|
10993
11208
|
|
|
10994
11209
|
// ../core/src/agents/loader.ts
|
|
10995
|
-
import
|
|
10996
|
-
import
|
|
10997
|
-
import { fileURLToPath as
|
|
11210
|
+
import fs30 from "fs/promises";
|
|
11211
|
+
import path32 from "path";
|
|
11212
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
10998
11213
|
var BUILTIN_DIR2, SOURCES3, parseAgentAt, initAgents;
|
|
10999
11214
|
var init_loader6 = __esm({
|
|
11000
11215
|
"../core/src/agents/loader.ts"() {
|
|
@@ -11003,16 +11218,16 @@ var init_loader6 = __esm({
|
|
|
11003
11218
|
init_frontmatter();
|
|
11004
11219
|
init_registry4();
|
|
11005
11220
|
init_registry2();
|
|
11006
|
-
BUILTIN_DIR2 =
|
|
11221
|
+
BUILTIN_DIR2 = path32.join(path32.dirname(fileURLToPath3(import.meta.url)), "builtin");
|
|
11007
11222
|
SOURCES3 = [
|
|
11008
11223
|
{ dir: BUILTIN_DIR2, source: "builtin" },
|
|
11009
|
-
{ dir:
|
|
11010
|
-
{ dir:
|
|
11224
|
+
{ dir: path32.join(appConfig.dataDir, "agents"), source: "global" },
|
|
11225
|
+
{ dir: path32.join(process.cwd(), ".deepseeker-code", "agents"), source: "project" }
|
|
11011
11226
|
];
|
|
11012
11227
|
parseAgentAt = async (file, dir, source) => {
|
|
11013
11228
|
let raw;
|
|
11014
11229
|
try {
|
|
11015
|
-
raw = await
|
|
11230
|
+
raw = await fs30.readFile(file, "utf-8");
|
|
11016
11231
|
} catch {
|
|
11017
11232
|
return null;
|
|
11018
11233
|
}
|
|
@@ -11047,7 +11262,7 @@ var init_loader6 = __esm({
|
|
|
11047
11262
|
const known = new Set(into.map((t) => t.function.name));
|
|
11048
11263
|
const picked = await scanSources(
|
|
11049
11264
|
filterSources(SOURCES3, includeProject),
|
|
11050
|
-
(e, dir) => e.isFile() && e.name.endsWith(".agent.md") ?
|
|
11265
|
+
(e, dir) => e.isFile() && e.name.endsWith(".agent.md") ? path32.join(dir, e.name) : void 0,
|
|
11051
11266
|
parseAgentAt
|
|
11052
11267
|
);
|
|
11053
11268
|
for (const { item: m, file, source } of picked) {
|
|
@@ -11084,9 +11299,9 @@ var init_registry7 = __esm({
|
|
|
11084
11299
|
});
|
|
11085
11300
|
|
|
11086
11301
|
// ../core/src/commands/loader.ts
|
|
11087
|
-
import
|
|
11088
|
-
import
|
|
11089
|
-
import { fileURLToPath as
|
|
11302
|
+
import fs31 from "fs/promises";
|
|
11303
|
+
import path33 from "path";
|
|
11304
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
11090
11305
|
var BUILTIN_DIR3, SOURCES4, MAX_COMMAND_BODY_BYTES, parseCommandAt, loadCommands, initCommands;
|
|
11091
11306
|
var init_loader7 = __esm({
|
|
11092
11307
|
"../core/src/commands/loader.ts"() {
|
|
@@ -11095,17 +11310,17 @@ var init_loader7 = __esm({
|
|
|
11095
11310
|
init_frontmatter();
|
|
11096
11311
|
init_registry7();
|
|
11097
11312
|
init_registry2();
|
|
11098
|
-
BUILTIN_DIR3 =
|
|
11313
|
+
BUILTIN_DIR3 = path33.join(path33.dirname(fileURLToPath4(import.meta.url)), "builtin");
|
|
11099
11314
|
SOURCES4 = [
|
|
11100
11315
|
{ dir: BUILTIN_DIR3, source: "builtin" },
|
|
11101
|
-
{ dir:
|
|
11102
|
-
{ dir:
|
|
11316
|
+
{ dir: path33.join(appConfig.dataDir, "commands"), source: "global" },
|
|
11317
|
+
{ dir: path33.join(process.cwd(), ".deepseeker-code", "commands"), source: "project" }
|
|
11103
11318
|
];
|
|
11104
11319
|
MAX_COMMAND_BODY_BYTES = 64 * 1024;
|
|
11105
11320
|
parseCommandAt = async (file, _dir, source) => {
|
|
11106
11321
|
let raw;
|
|
11107
11322
|
try {
|
|
11108
|
-
raw = await
|
|
11323
|
+
raw = await fs31.readFile(file, "utf-8");
|
|
11109
11324
|
} catch {
|
|
11110
11325
|
return null;
|
|
11111
11326
|
}
|
|
@@ -11116,7 +11331,7 @@ var init_loader7 = __esm({
|
|
|
11116
11331
|
}
|
|
11117
11332
|
const name = parsed.frontmatter.name;
|
|
11118
11333
|
const description = parsed.frontmatter.description;
|
|
11119
|
-
const fallbackName =
|
|
11334
|
+
const fallbackName = path33.basename(file, ".md");
|
|
11120
11335
|
const finalName = name || fallbackName;
|
|
11121
11336
|
if (!description) {
|
|
11122
11337
|
console.warn(`\u26A0\uFE0F [commands] \u7F3A\u5C11 description\uFF08${file}\uFF09\uFF0C\u5DF2\u8DF3\u8FC7`);
|
|
@@ -11142,7 +11357,7 @@ var init_loader7 = __esm({
|
|
|
11142
11357
|
loadCommands = async (includeProject) => {
|
|
11143
11358
|
const picked = await scanSources(
|
|
11144
11359
|
filterSources(SOURCES4, includeProject),
|
|
11145
|
-
(e, dir) => e.isFile() && e.name.endsWith(".md") ?
|
|
11360
|
+
(e, dir) => e.isFile() && e.name.endsWith(".md") ? path33.join(dir, e.name) : void 0,
|
|
11146
11361
|
parseCommandAt
|
|
11147
11362
|
);
|
|
11148
11363
|
for (const { item } of picked) registerCommand(item);
|
|
@@ -11160,9 +11375,9 @@ var init_loader7 = __esm({
|
|
|
11160
11375
|
});
|
|
11161
11376
|
|
|
11162
11377
|
// ../core/src/outputStyles/loader.ts
|
|
11163
|
-
import
|
|
11164
|
-
import
|
|
11165
|
-
import { fileURLToPath as
|
|
11378
|
+
import fs32 from "fs/promises";
|
|
11379
|
+
import path34 from "path";
|
|
11380
|
+
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
11166
11381
|
var BUILTIN_DIR4, MAX_STYLE_BODY_BYTES, SOURCES5, parseStyleAt, loadOutputStyles, initOutputStyles;
|
|
11167
11382
|
var init_loader8 = __esm({
|
|
11168
11383
|
"../core/src/outputStyles/loader.ts"() {
|
|
@@ -11171,17 +11386,17 @@ var init_loader8 = __esm({
|
|
|
11171
11386
|
init_frontmatter();
|
|
11172
11387
|
init_registry5();
|
|
11173
11388
|
init_registry2();
|
|
11174
|
-
BUILTIN_DIR4 =
|
|
11389
|
+
BUILTIN_DIR4 = path34.join(path34.dirname(fileURLToPath5(import.meta.url)), "builtin");
|
|
11175
11390
|
MAX_STYLE_BODY_BYTES = 64 * 1024;
|
|
11176
11391
|
SOURCES5 = [
|
|
11177
11392
|
{ dir: BUILTIN_DIR4, source: "builtin" },
|
|
11178
|
-
{ dir:
|
|
11179
|
-
{ dir:
|
|
11393
|
+
{ dir: path34.join(appConfig.dataDir, "output-styles"), source: "global" },
|
|
11394
|
+
{ dir: path34.join(process.cwd(), ".deepseeker-code", "output-styles"), source: "project" }
|
|
11180
11395
|
];
|
|
11181
11396
|
parseStyleAt = async (file, _dir, source) => {
|
|
11182
11397
|
let raw;
|
|
11183
11398
|
try {
|
|
11184
|
-
raw = await
|
|
11399
|
+
raw = await fs32.readFile(file, "utf-8");
|
|
11185
11400
|
} catch {
|
|
11186
11401
|
return null;
|
|
11187
11402
|
}
|
|
@@ -11213,7 +11428,7 @@ var init_loader8 = __esm({
|
|
|
11213
11428
|
loadOutputStyles = async (includeProject) => {
|
|
11214
11429
|
const picked = await scanSources(
|
|
11215
11430
|
filterSources(SOURCES5, includeProject),
|
|
11216
|
-
(e, dir) => e.isFile() && e.name.endsWith(".md") ?
|
|
11431
|
+
(e, dir) => e.isFile() && e.name.endsWith(".md") ? path34.join(dir, e.name) : void 0,
|
|
11217
11432
|
parseStyleAt
|
|
11218
11433
|
);
|
|
11219
11434
|
for (const { item } of picked) registerOutputStyle(item);
|
|
@@ -11294,8 +11509,8 @@ var init_bootstrap = __esm({
|
|
|
11294
11509
|
});
|
|
11295
11510
|
|
|
11296
11511
|
// ../core/src/statusLine/config.ts
|
|
11297
|
-
import
|
|
11298
|
-
import
|
|
11512
|
+
import fs33 from "fs/promises";
|
|
11513
|
+
import path35 from "path";
|
|
11299
11514
|
var parseBlock, readStatusLineConfig;
|
|
11300
11515
|
var init_config2 = __esm({
|
|
11301
11516
|
"../core/src/statusLine/config.ts"() {
|
|
@@ -11311,16 +11526,16 @@ var init_config2 = __esm({
|
|
|
11311
11526
|
};
|
|
11312
11527
|
readStatusLineConfig = async (includeProject) => {
|
|
11313
11528
|
const paths = [
|
|
11314
|
-
|
|
11529
|
+
path35.join(appConfig.dataDir, "settings.json"),
|
|
11315
11530
|
// 全局用户级
|
|
11316
|
-
...includeProject ? [
|
|
11531
|
+
...includeProject ? [path35.join(process.cwd(), ".deepseeker-code", "settings.json")] : []
|
|
11317
11532
|
// 项目级(覆盖);未信任时省略
|
|
11318
11533
|
];
|
|
11319
11534
|
let result = null;
|
|
11320
11535
|
for (const configPath of paths) {
|
|
11321
11536
|
let raw;
|
|
11322
11537
|
try {
|
|
11323
|
-
raw = await
|
|
11538
|
+
raw = await fs33.readFile(configPath, "utf-8");
|
|
11324
11539
|
} catch {
|
|
11325
11540
|
continue;
|
|
11326
11541
|
}
|
|
@@ -11340,9 +11555,9 @@ var init_config2 = __esm({
|
|
|
11340
11555
|
|
|
11341
11556
|
// ../core/src/statusLine/runner.ts
|
|
11342
11557
|
import { spawn as spawn5 } from "child_process";
|
|
11343
|
-
import
|
|
11344
|
-
import
|
|
11345
|
-
import { fileURLToPath as
|
|
11558
|
+
import fs34 from "fs";
|
|
11559
|
+
import path36 from "path";
|
|
11560
|
+
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
11346
11561
|
var STATUSLINE_TIMEOUT_MS, cachedVersion, runStatusLine;
|
|
11347
11562
|
var init_runner = __esm({
|
|
11348
11563
|
"../core/src/statusLine/runner.ts"() {
|
|
@@ -11350,16 +11565,16 @@ var init_runner = __esm({
|
|
|
11350
11565
|
init_guard();
|
|
11351
11566
|
STATUSLINE_TIMEOUT_MS = 3e3;
|
|
11352
11567
|
try {
|
|
11353
|
-
const here =
|
|
11568
|
+
const here = path36.dirname(fileURLToPath6(import.meta.url));
|
|
11354
11569
|
const candidates = [
|
|
11355
|
-
|
|
11570
|
+
path36.join(here, "../../../package.json"),
|
|
11356
11571
|
// src/core/package.json
|
|
11357
|
-
|
|
11572
|
+
path36.join(here, "../../../../package.json")
|
|
11358
11573
|
// 仓库根 package.json
|
|
11359
11574
|
];
|
|
11360
11575
|
for (const p of candidates) {
|
|
11361
11576
|
try {
|
|
11362
|
-
const pkg = JSON.parse(
|
|
11577
|
+
const pkg = JSON.parse(fs34.readFileSync(p, "utf-8"));
|
|
11363
11578
|
if (typeof pkg.version === "string" && pkg.version) {
|
|
11364
11579
|
cachedVersion = pkg.version;
|
|
11365
11580
|
break;
|
|
@@ -11418,8 +11633,8 @@ var init_createModel = __esm({
|
|
|
11418
11633
|
});
|
|
11419
11634
|
|
|
11420
11635
|
// ../core/src/observability/store.ts
|
|
11421
|
-
import
|
|
11422
|
-
import
|
|
11636
|
+
import path37 from "path";
|
|
11637
|
+
import fs35 from "fs/promises";
|
|
11423
11638
|
var getTraceDirPath, getTracePath, tracePathCache, ensuredTraceDirs, ensureTraceDir, getGlobalClockPath, getTraceStorePath;
|
|
11424
11639
|
var init_store3 = __esm({
|
|
11425
11640
|
"../core/src/observability/store.ts"() {
|
|
@@ -11429,21 +11644,21 @@ var init_store3 = __esm({
|
|
|
11429
11644
|
init_common();
|
|
11430
11645
|
getTraceDirPath = (mainTraceId) => {
|
|
11431
11646
|
assertSafeSessionId(mainTraceId, "traceId");
|
|
11432
|
-
return
|
|
11647
|
+
return path37.join(appConfig.dataDir, "trace", appConfig.userWorkspaceDir, getFileName(mainTraceId));
|
|
11433
11648
|
};
|
|
11434
11649
|
getTracePath = () => {
|
|
11435
|
-
return
|
|
11650
|
+
return path37.join(appConfig.dataDir, "trace");
|
|
11436
11651
|
};
|
|
11437
11652
|
tracePathCache = /* @__PURE__ */ new Map();
|
|
11438
11653
|
ensuredTraceDirs = /* @__PURE__ */ new Set();
|
|
11439
11654
|
ensureTraceDir = async (mainTraceId) => {
|
|
11440
11655
|
const dir = getTraceDirPath(mainTraceId);
|
|
11441
11656
|
if (ensuredTraceDirs.has(dir)) return;
|
|
11442
|
-
await
|
|
11657
|
+
await fs35.mkdir(dir, { recursive: true });
|
|
11443
11658
|
ensuredTraceDirs.add(dir);
|
|
11444
11659
|
};
|
|
11445
11660
|
getGlobalClockPath = () => {
|
|
11446
|
-
return
|
|
11661
|
+
return path37.join(getTracePath(), "trace-cleanup-clock.json");
|
|
11447
11662
|
};
|
|
11448
11663
|
getTraceStorePath = async (mainTraceId) => {
|
|
11449
11664
|
assertSafeSessionId(mainTraceId, "traceId");
|
|
@@ -11452,7 +11667,7 @@ var init_store3 = __esm({
|
|
|
11452
11667
|
if (cached2) return cached2;
|
|
11453
11668
|
await ensureTraceDir(rootId);
|
|
11454
11669
|
const dir = getTraceDirPath(rootId);
|
|
11455
|
-
const files = await
|
|
11670
|
+
const files = await fs35.readdir(dir);
|
|
11456
11671
|
const existedFile = files.find((f) => f.endsWith(`__${rootId}.jsonl`));
|
|
11457
11672
|
let fileName = "";
|
|
11458
11673
|
if (existedFile) {
|
|
@@ -11461,7 +11676,7 @@ var init_store3 = __esm({
|
|
|
11461
11676
|
const todayStr = getTodayDateString();
|
|
11462
11677
|
fileName = `trace-${todayStr}__${rootId}.jsonl`;
|
|
11463
11678
|
}
|
|
11464
|
-
const resolved =
|
|
11679
|
+
const resolved = path37.join(dir, fileName);
|
|
11465
11680
|
tracePathCache.set(rootId, resolved);
|
|
11466
11681
|
return resolved;
|
|
11467
11682
|
};
|
|
@@ -11469,8 +11684,8 @@ var init_store3 = __esm({
|
|
|
11469
11684
|
});
|
|
11470
11685
|
|
|
11471
11686
|
// ../core/src/observability/trace.ts
|
|
11472
|
-
import
|
|
11473
|
-
import
|
|
11687
|
+
import fs36 from "fs/promises";
|
|
11688
|
+
import path38 from "path";
|
|
11474
11689
|
async function emitTrace(base) {
|
|
11475
11690
|
const event = {
|
|
11476
11691
|
sessionId: base.sessionId,
|
|
@@ -11492,7 +11707,7 @@ async function emitTrace(base) {
|
|
|
11492
11707
|
async function appendTraceEvent(event) {
|
|
11493
11708
|
const p = await getTraceStorePath(event.sessionId);
|
|
11494
11709
|
const line = JSON.stringify(event) + "\n";
|
|
11495
|
-
await
|
|
11710
|
+
await fs36.appendFile(p, line, "utf-8");
|
|
11496
11711
|
if (workspaceTraceBytes < 0) {
|
|
11497
11712
|
workspaceTraceBytes = await getDirBytes(getTracePath());
|
|
11498
11713
|
}
|
|
@@ -11524,8 +11739,8 @@ async function maybeCleanupAfterAppend(sessionId) {
|
|
|
11524
11739
|
lastSizeCleanupAt2 = now;
|
|
11525
11740
|
diskLastCleanupAt2 = now;
|
|
11526
11741
|
const clockPath = getGlobalClockPath();
|
|
11527
|
-
await
|
|
11528
|
-
await
|
|
11742
|
+
await fs36.mkdir(path38.dirname(clockPath), { recursive: true });
|
|
11743
|
+
await fs36.writeFile(clockPath, JSON.stringify({ lastCleanupAt: now, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), "utf-8");
|
|
11529
11744
|
if (deletedCount > 0) {
|
|
11530
11745
|
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`);
|
|
11531
11746
|
}
|
|
@@ -11545,22 +11760,22 @@ async function cleanupOldTraceFiles() {
|
|
|
11545
11760
|
let deleted = 0;
|
|
11546
11761
|
let relativePaths;
|
|
11547
11762
|
try {
|
|
11548
|
-
relativePaths = await
|
|
11763
|
+
relativePaths = await fs36.readdir(dir, { recursive: true });
|
|
11549
11764
|
} catch {
|
|
11550
11765
|
return 0;
|
|
11551
11766
|
}
|
|
11552
11767
|
const re = /^trace-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
|
|
11553
11768
|
for (const relativePath of relativePaths) {
|
|
11554
|
-
const fileName =
|
|
11769
|
+
const fileName = path38.basename(relativePath);
|
|
11555
11770
|
const m = fileName.match(re);
|
|
11556
11771
|
if (!m) continue;
|
|
11557
11772
|
const fileBornDay = /* @__PURE__ */ new Date(`${m[1]}T00:00:00`);
|
|
11558
11773
|
if (fileBornDay >= cutoff) continue;
|
|
11559
|
-
const fullPath =
|
|
11774
|
+
const fullPath = path38.join(dir, relativePath);
|
|
11560
11775
|
try {
|
|
11561
|
-
const st = await
|
|
11776
|
+
const st = await fs36.stat(fullPath);
|
|
11562
11777
|
if (now - st.mtimeMs < ACTIVE_GRACE_MS2) continue;
|
|
11563
|
-
await
|
|
11778
|
+
await fs36.unlink(fullPath);
|
|
11564
11779
|
deleted += 1;
|
|
11565
11780
|
} catch {
|
|
11566
11781
|
}
|
|
@@ -11571,18 +11786,18 @@ async function evictOldestForSize2(targetBytes) {
|
|
|
11571
11786
|
const dir = getTracePath();
|
|
11572
11787
|
let relativePaths;
|
|
11573
11788
|
try {
|
|
11574
|
-
relativePaths = await
|
|
11789
|
+
relativePaths = await fs36.readdir(dir, { recursive: true });
|
|
11575
11790
|
} catch {
|
|
11576
11791
|
return 0;
|
|
11577
11792
|
}
|
|
11578
11793
|
const re = /^trace-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
|
|
11579
11794
|
const candidates = [];
|
|
11580
11795
|
for (const relativePath of relativePaths) {
|
|
11581
|
-
const fileName =
|
|
11796
|
+
const fileName = path38.basename(relativePath);
|
|
11582
11797
|
if (!re.test(fileName)) continue;
|
|
11583
11798
|
try {
|
|
11584
|
-
const st = await
|
|
11585
|
-
candidates.push({ mtime: st.mtimeMs, fullPath:
|
|
11799
|
+
const st = await fs36.stat(path38.join(dir, relativePath));
|
|
11800
|
+
candidates.push({ mtime: st.mtimeMs, fullPath: path38.join(dir, relativePath), size: st.size });
|
|
11586
11801
|
} catch {
|
|
11587
11802
|
}
|
|
11588
11803
|
}
|
|
@@ -11592,7 +11807,7 @@ async function evictOldestForSize2(targetBytes) {
|
|
|
11592
11807
|
for (const c of candidates) {
|
|
11593
11808
|
if (totalBytes <= targetBytes) break;
|
|
11594
11809
|
try {
|
|
11595
|
-
await
|
|
11810
|
+
await fs36.unlink(c.fullPath);
|
|
11596
11811
|
totalBytes -= c.size;
|
|
11597
11812
|
deleted += 1;
|
|
11598
11813
|
} catch {
|
|
@@ -11624,7 +11839,7 @@ var init_trace = __esm({
|
|
|
11624
11839
|
if (clockLoaded2) return;
|
|
11625
11840
|
clockLoaded2 = true;
|
|
11626
11841
|
try {
|
|
11627
|
-
const rawClock = await
|
|
11842
|
+
const rawClock = await fs36.readFile(getGlobalClockPath(), "utf-8");
|
|
11628
11843
|
diskLastCleanupAt2 = JSON.parse(rawClock).lastCleanupAt || 0;
|
|
11629
11844
|
} catch {
|
|
11630
11845
|
diskLastCleanupAt2 = 0;
|
|
@@ -11643,6 +11858,7 @@ var pendingLocks, waitForUserApproval, resolveUserApprovalLock;
|
|
|
11643
11858
|
var init_approvalGate = __esm({
|
|
11644
11859
|
"../core/src/tool/approvalGate.ts"() {
|
|
11645
11860
|
"use strict";
|
|
11861
|
+
init_lineage();
|
|
11646
11862
|
pendingLocks = /* @__PURE__ */ new Map();
|
|
11647
11863
|
waitForUserApproval = async (sessionId, toolsId, signal) => {
|
|
11648
11864
|
if (signal?.aborted) return "deny";
|
|
@@ -11670,7 +11886,7 @@ var init_approvalGate = __esm({
|
|
|
11670
11886
|
resolveUserApprovalLock = (sessionId, toolsId, decision) => {
|
|
11671
11887
|
const entry = pendingLocks.get(toolsId);
|
|
11672
11888
|
if (!entry) return false;
|
|
11673
|
-
const isOwner = entry.sessionId
|
|
11889
|
+
const isOwner = ownerCanApprove(entry.sessionId, sessionId);
|
|
11674
11890
|
if (!isOwner) return false;
|
|
11675
11891
|
entry.resolver(decision);
|
|
11676
11892
|
pendingLocks.delete(toolsId);
|
|
@@ -11769,8 +11985,8 @@ ${PLAN_MODE_AUTO_ENTER_HINT}
|
|
|
11769
11985
|
});
|
|
11770
11986
|
|
|
11771
11987
|
// ../core/src/serve/chatProcessing.ts
|
|
11772
|
-
import
|
|
11773
|
-
import
|
|
11988
|
+
import path39 from "path";
|
|
11989
|
+
import fs37 from "fs";
|
|
11774
11990
|
var handleUnifiedChat;
|
|
11775
11991
|
var init_chatProcessing = __esm({
|
|
11776
11992
|
"../core/src/serve/chatProcessing.ts"() {
|
|
@@ -11824,17 +12040,17 @@ ${inject}`;
|
|
|
11824
12040
|
if (roots.length > 1) {
|
|
11825
12041
|
let activeReal = getActiveWorkspaceRoot();
|
|
11826
12042
|
try {
|
|
11827
|
-
activeReal =
|
|
12043
|
+
activeReal = fs37.realpathSync(activeReal);
|
|
11828
12044
|
} catch {
|
|
11829
12045
|
}
|
|
11830
|
-
const lines = roots.map((r) => `- ${
|
|
12046
|
+
const lines = roots.map((r) => `- ${path39.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"}`);
|
|
11831
12047
|
sysPrompt = sysPrompt + `
|
|
11832
12048
|
|
|
11833
12049
|
\u3010\u5DE5\u4F5C\u533A\uFF08\u591A\u9879\u76EE\uFF09\u3011
|
|
11834
12050
|
\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>:
|
|
11835
12051
|
${lines.join("\n")}
|
|
11836
|
-
\u2605 \u8DEF\u5F84\u951A\u5B9A\u94C1\u5F8B\uFF1A\u5DE5\u5177\u7F3A\u7701\u53EA\u4F5C\u7528\u4E8E\u9ED8\u8BA4\u6839\uFF08${
|
|
11837
|
-
\u6CE8\u610F\uFF1A\u9879\u76EE\u7EA7\u914D\u7F6E\uFF08.deepseeker-code/\uFF09\u4EC5\u5728\u9ED8\u8BA4\u6839 ${
|
|
12052
|
+
\u2605 \u8DEF\u5F84\u951A\u5B9A\u94C1\u5F8B\uFF1A\u5DE5\u5177\u7F3A\u7701\u53EA\u4F5C\u7528\u4E8E\u9ED8\u8BA4\u6839\uFF08${path39.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
|
|
12053
|
+
\u6CE8\u610F\uFF1A\u9879\u76EE\u7EA7\u914D\u7F6E\uFF08.deepseeker-code/\uFF09\u4EC5\u5728\u9ED8\u8BA4\u6839 ${path39.basename(activeReal) || activeReal} \u751F\u6548\u3002`;
|
|
11838
12054
|
}
|
|
11839
12055
|
let replyText = "";
|
|
11840
12056
|
try {
|
|
@@ -11921,7 +12137,7 @@ ${lines.join("\n")}
|
|
|
11921
12137
|
});
|
|
11922
12138
|
|
|
11923
12139
|
// ../core/src/session/fork.ts
|
|
11924
|
-
import
|
|
12140
|
+
import fs38 from "fs/promises";
|
|
11925
12141
|
var listForkAnchors, derivePrefix, forkSession;
|
|
11926
12142
|
var init_fork = __esm({
|
|
11927
12143
|
"../core/src/session/fork.ts"() {
|
|
@@ -11993,7 +12209,7 @@ var init_fork = __esm({
|
|
|
11993
12209
|
const prefix = derivePrefix(lines, upToLineId);
|
|
11994
12210
|
const newId = createUUID();
|
|
11995
12211
|
await ensureSessionsDir(newId);
|
|
11996
|
-
const rawText = await
|
|
12212
|
+
const rawText = await fs38.readFile(getTranscriptPath(sourceId), "utf-8");
|
|
11997
12213
|
const kept = [];
|
|
11998
12214
|
let good = 0;
|
|
11999
12215
|
for (const s of rawText.split("\n")) {
|
|
@@ -12009,7 +12225,7 @@ var init_fork = __esm({
|
|
|
12009
12225
|
}
|
|
12010
12226
|
let payload = kept.join("\n");
|
|
12011
12227
|
if (payload.length > 0 && !payload.endsWith("\n")) payload += "\n";
|
|
12012
|
-
await
|
|
12228
|
+
await fs38.writeFile(getTranscriptPath(newId), payload, "utf-8");
|
|
12013
12229
|
const srcState = await readStore(sourceId);
|
|
12014
12230
|
const srcRolling = await getRollingState(sourceId);
|
|
12015
12231
|
const legacy = !lines.some(isEventLine);
|
|
@@ -12025,6 +12241,9 @@ var init_fork = __esm({
|
|
|
12025
12241
|
rollingSummary,
|
|
12026
12242
|
consecutiveFailures: 0,
|
|
12027
12243
|
title: `${srcTitle}(\u5206\u53C9)`.slice(0, 200),
|
|
12244
|
+
// ★ fork 血缘元数据:新 ID 是纯 UUID(字符串上无痕),血缘回溯全靠此字段
|
|
12245
|
+
// (session/lineage.ts 消费:审批网关归属 / 子 Agent 续跑归属)。
|
|
12246
|
+
forkedFrom: sourceId,
|
|
12028
12247
|
// ★ 校准数据透传:fork 首轮压缩判定不从 1.4 重来(纯收益,语义同源会话续接)
|
|
12029
12248
|
calibRatio: srcRolling.calibRatio,
|
|
12030
12249
|
lastRealPromptTokens: srcRolling.lastRealPromptTokens,
|
|
@@ -13703,7 +13922,7 @@ var init_TopPanel = __esm({
|
|
|
13703
13922
|
});
|
|
13704
13923
|
|
|
13705
13924
|
// src/inspect.ts
|
|
13706
|
-
import
|
|
13925
|
+
import fs39 from "fs";
|
|
13707
13926
|
var CWD, fmt, readTrace, inspectUsage, inspectContext, inspectPermissions, inspectMcp, inspectHooks, inspectDebug;
|
|
13708
13927
|
var init_inspect = __esm({
|
|
13709
13928
|
"src/inspect.ts"() {
|
|
@@ -13721,7 +13940,7 @@ var init_inspect = __esm({
|
|
|
13721
13940
|
if (!sessionId) return [];
|
|
13722
13941
|
try {
|
|
13723
13942
|
const p = await getTraceStorePath(sessionId);
|
|
13724
|
-
const text = await
|
|
13943
|
+
const text = await fs39.promises.readFile(p, "utf8");
|
|
13725
13944
|
const out = [];
|
|
13726
13945
|
for (const line of text.split("\n")) {
|
|
13727
13946
|
if (!line.trim()) continue;
|
|
@@ -14412,81 +14631,6 @@ ${listText}`);
|
|
|
14412
14631
|
}
|
|
14413
14632
|
});
|
|
14414
14633
|
|
|
14415
|
-
// src/updateCheck.ts
|
|
14416
|
-
var updateCheck_exports = {};
|
|
14417
|
-
__export(updateCheck_exports, {
|
|
14418
|
-
getCachedLatestIfNewer: () => getCachedLatestIfNewer,
|
|
14419
|
-
readLocalVersion: () => readLocalVersion,
|
|
14420
|
-
refreshUpdateCache: () => refreshUpdateCache
|
|
14421
|
-
});
|
|
14422
|
-
import { readFileSync as readFileSync4, writeFileSync, mkdirSync } from "node:fs";
|
|
14423
|
-
import path39 from "node:path";
|
|
14424
|
-
import os4 from "os";
|
|
14425
|
-
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
14426
|
-
var PKG_NAME, REGISTRY, CACHE_TTL_MS, FETCH_TIMEOUT_MS2, cacheFile, readLocalVersion, parseSemver, compareVersion, readCache, writeCache, getCachedLatestIfNewer, refreshUpdateCache;
|
|
14427
|
-
var init_updateCheck = __esm({
|
|
14428
|
-
"src/updateCheck.ts"() {
|
|
14429
|
-
"use strict";
|
|
14430
|
-
PKG_NAME = "deepseeker-code";
|
|
14431
|
-
REGISTRY = "https://registry.npmjs.org";
|
|
14432
|
-
CACHE_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
14433
|
-
FETCH_TIMEOUT_MS2 = 3e3;
|
|
14434
|
-
cacheFile = () => path39.join(os4.homedir(), ".deepseeker-code", "update-check.json");
|
|
14435
|
-
readLocalVersion = () => {
|
|
14436
|
-
try {
|
|
14437
|
-
const here = path39.dirname(fileURLToPath6(import.meta.url));
|
|
14438
|
-
return JSON.parse(readFileSync4(path39.join(here, "..", "package.json"), "utf8")).version ?? "0.0.0";
|
|
14439
|
-
} catch {
|
|
14440
|
-
return "0.0.0";
|
|
14441
|
-
}
|
|
14442
|
-
};
|
|
14443
|
-
parseSemver = (v) => {
|
|
14444
|
-
const m = String(v ?? "").match(/^(\d+)\.(\d+)\.(\d+)/);
|
|
14445
|
-
return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : [0, 0, 0];
|
|
14446
|
-
};
|
|
14447
|
-
compareVersion = (a, b) => {
|
|
14448
|
-
const [a1, a2, a3] = parseSemver(a);
|
|
14449
|
-
const [b1, b2, b3] = parseSemver(b);
|
|
14450
|
-
return a1 - b1 || a2 - b2 || a3 - b3;
|
|
14451
|
-
};
|
|
14452
|
-
readCache = () => {
|
|
14453
|
-
try {
|
|
14454
|
-
const obj = JSON.parse(readFileSync4(cacheFile(), "utf8"));
|
|
14455
|
-
return typeof obj.latestVersion === "string" && typeof obj.lastCheck === "number" ? obj : null;
|
|
14456
|
-
} catch {
|
|
14457
|
-
return null;
|
|
14458
|
-
}
|
|
14459
|
-
};
|
|
14460
|
-
writeCache = (latestVersion) => {
|
|
14461
|
-
try {
|
|
14462
|
-
mkdirSync(path39.dirname(cacheFile()), { recursive: true });
|
|
14463
|
-
writeFileSync(cacheFile(), JSON.stringify({ lastCheck: Date.now(), latestVersion }), "utf8");
|
|
14464
|
-
} catch {
|
|
14465
|
-
}
|
|
14466
|
-
};
|
|
14467
|
-
getCachedLatestIfNewer = (currentVersion) => {
|
|
14468
|
-
const cache = readCache();
|
|
14469
|
-
if (!cache) return null;
|
|
14470
|
-
return compareVersion(cache.latestVersion, currentVersion) > 0 ? cache.latestVersion : null;
|
|
14471
|
-
};
|
|
14472
|
-
refreshUpdateCache = () => {
|
|
14473
|
-
const cache = readCache();
|
|
14474
|
-
if (cache && Date.now() - cache.lastCheck < CACHE_TTL_MS) return;
|
|
14475
|
-
void (async () => {
|
|
14476
|
-
try {
|
|
14477
|
-
const res = await fetch(`${REGISTRY}/${PKG_NAME}/latest`, {
|
|
14478
|
-
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS2)
|
|
14479
|
-
});
|
|
14480
|
-
if (!res.ok) return;
|
|
14481
|
-
const info = await res.json();
|
|
14482
|
-
if (info.version) writeCache(info.version);
|
|
14483
|
-
} catch {
|
|
14484
|
-
}
|
|
14485
|
-
})();
|
|
14486
|
-
};
|
|
14487
|
-
}
|
|
14488
|
-
});
|
|
14489
|
-
|
|
14490
14634
|
// src/preload-config.ts
|
|
14491
14635
|
import { readFileSync } from "node:fs";
|
|
14492
14636
|
import path from "node:path";
|
|
@@ -14534,6 +14678,7 @@ applyConfigToEnv(loadConfigFile());
|
|
|
14534
14678
|
// src/main.tsx
|
|
14535
14679
|
init_strings();
|
|
14536
14680
|
init_prefs();
|
|
14681
|
+
init_updateCheck();
|
|
14537
14682
|
init_trust();
|
|
14538
14683
|
import { render } from "ink";
|
|
14539
14684
|
import os5 from "os";
|
|
@@ -14550,6 +14695,7 @@ var parseArgs = (argv) => {
|
|
|
14550
14695
|
else if (a === "--continue" || a === "-c") out.continue = true;
|
|
14551
14696
|
else if (a === "--trust") out.trust = true;
|
|
14552
14697
|
else if (a === "--no-update-check") out.noUpdateCheck = true;
|
|
14698
|
+
else if (a === "--version" || a === "-v") out.version = true;
|
|
14553
14699
|
}
|
|
14554
14700
|
return out;
|
|
14555
14701
|
};
|
|
@@ -14610,6 +14756,11 @@ var main = async () => {
|
|
|
14610
14756
|
console.debug = silence;
|
|
14611
14757
|
console.warn = silence;
|
|
14612
14758
|
const args = parseArgs(process.argv.slice(2));
|
|
14759
|
+
if (args.version) {
|
|
14760
|
+
process.stdout.write(`deepseeker-code v${readLocalVersion()}
|
|
14761
|
+
`);
|
|
14762
|
+
process.exit(0);
|
|
14763
|
+
}
|
|
14613
14764
|
if (!process.env.DEEP_SEEK_API_KEY) {
|
|
14614
14765
|
console.error(S.noApiKey("DEEP_SEEK_API_KEY"));
|
|
14615
14766
|
process.exit(1);
|