deepseeker-code 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -67,6 +67,13 @@ var init_strings = __esm({
67
67
  ${yellow} \u5DE5\u5177\u5C06\u4EE5\u8BE5\u76EE\u5F55\u4E3A\u9879\u76EE\u6839\u8BFB\u5199\u6587\u4EF6\uFF0C\u5EFA\u8BAE\u5148 cd \u5230\u5177\u4F53\u9879\u76EE\u76EE\u5F55\u518D\u8FD0\u884C\u3002${reset}
68
68
  ${dim} \u9879\u76EE\u952E\uFF1A${projectKey}${reset}
69
69
 
70
+ `;
71
+ },
72
+ updateAvailable: (latest, current) => {
73
+ const cyan = "\x1B[36m", dim = "\x1B[2m", reset = "\x1B[0m";
74
+ return `${cyan}\u21BB \u68C0\u6D4B\u5230\u65B0\u7248\u672C ${latest}${reset} ${dim}\uFF08\u5F53\u524D ${current}\uFF09${reset}
75
+ ${dim} \u8FD0\u884C npm i -g deepseeker-code@latest \u66F4\u65B0${reset}
76
+
70
77
  `;
71
78
  },
72
79
  cmdHelp: "\u67E5\u770B\u5E2E\u52A9\u4E0E\u5FEB\u6377\u952E",
@@ -188,6 +195,13 @@ Set it as an env var and retry, or start serve for the Web UI.`,
188
195
  ${yellow} Tools will read/write files with this as project root\u2014cd into the actual project first.${reset}
189
196
  ${dim} Project key: ${projectKey}${reset}
190
197
 
198
+ `;
199
+ },
200
+ updateAvailable: (latest, current) => {
201
+ const cyan = "\x1B[36m", dim = "\x1B[2m", reset = "\x1B[0m";
202
+ return `${cyan}\u21BB New version ${latest} available${reset} ${dim}(current ${current})${reset}
203
+ ${dim} Run npm i -g deepseeker-code@latest to update${reset}
204
+
191
205
  `;
192
206
  },
193
207
  cmdHelp: "Show help & shortcuts",
@@ -1947,7 +1961,7 @@ import fsSync from "fs";
1947
1961
  import path9 from "path";
1948
1962
  import ignore from "ignore";
1949
1963
  import { AsyncLocalStorage } from "node:async_hooks";
1950
- var WORKSPACE_ROOT, workspaceAls, getActiveWorkspaceRoot, runWithWorkspaceRoot, runWithSessionContext, BUILTIN_IGNORE_RULES, ignoreCache, ignoreBuilding, allowedRootsReal, getAllowedWorkspaceRoots, getContainingRoot, allowedBoundaryRoots, resolveSafePath, assertWithinWorkspace, PROTECTED_WRITE_DIRS, COMMAND_ENV_DENYLIST, SENSITIVE_ENV_PATTERN, scrubCommandEnv, isProtectedWrite, scanIgnoreFilesRecursive, buildIgnoreEngine, getIgnoreForBase, initializeWorkspaceIgnore, checkIsPathIgnored, requestApproval;
1964
+ 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;
1951
1965
  var init_guard = __esm({
1952
1966
  "../core/src/tool/guard.ts"() {
1953
1967
  "use strict";
@@ -2049,6 +2063,19 @@ var init_guard = __esm({
2049
2063
  }
2050
2064
  return truePhysicalPath;
2051
2065
  };
2066
+ resolveReadablePath = (rel) => {
2067
+ const root = getActiveWorkspaceRoot();
2068
+ const absPath = path9.resolve(root, rel);
2069
+ if (!fsSync.existsSync(absPath)) {
2070
+ const rootName = path9.basename(root);
2071
+ const firstSeg = rel.split(/[\\/]/)[0];
2072
+ if (rootName && firstSeg === rootName) {
2073
+ const alt = path9.resolve(root, rel.slice(firstSeg.length + 1));
2074
+ if (fsSync.existsSync(alt)) return alt;
2075
+ }
2076
+ }
2077
+ return absPath;
2078
+ };
2052
2079
  assertWithinWorkspace = (absPath, base) => {
2053
2080
  const root = base ?? getActiveWorkspaceRoot();
2054
2081
  let truePhysicalPath = absPath;
@@ -4544,13 +4571,17 @@ var init_fs = __esm({
4544
4571
  init_type();
4545
4572
  init_tsHost();
4546
4573
  init_guard();
4547
- isSensitiveReadTarget = (rel) => {
4548
- const p = rel.toLowerCase().replace(/\\/g, "/");
4574
+ isSensitiveReadTarget = (resolvedPath) => {
4575
+ const p = resolvedPath.toLowerCase().replace(/\\/g, "/");
4549
4576
  return [
4550
4577
  /\.env(\.|$|\/)/,
4551
4578
  // .env / .env.local / .env.production
4552
4579
  /\.npmrc$/,
4553
4580
  // npm 凭证(_authToken)
4581
+ /\.netrc$/,
4582
+ // ~/.netrc 明文 API token(跨界读暴露面增大,补拦)
4583
+ /(^|\/)\.htpasswd$/i,
4584
+ // HTTP 基本认证凭证文件
4554
4585
  /\.pem$/,
4555
4586
  /\.key$/,
4556
4587
  /\.pfx$/,
@@ -4560,7 +4591,9 @@ var init_fs = __esm({
4560
4591
  /(^|\/)id_(rsa|ecdsa|ed25519|dsa)(\.pub)?$/,
4561
4592
  // SSH 私钥(含子目录路径,如 deploy_keys/id_rsa)
4562
4593
  /(^|\/)secrets?\.(json|ya?ml|toml|ini|conf)$/i,
4563
- /(^|\/)credentials?\.(json|ya?ml|toml|ini|conf)$/i
4594
+ /(^|\/)credentials?\.(json|ya?ml|toml|ini|conf)$/i,
4595
+ /(^|\/)credentials?$/i
4596
+ // 无扩展名凭证文件(AWS ~/.aws/credentials 等)
4564
4597
  ].some((re) => re.test(p));
4565
4598
  };
4566
4599
  stripReadFileLineNumbers = (s) => {
@@ -4607,8 +4640,8 @@ var init_fs = __esm({
4607
4640
  await walk(wsRoot);
4608
4641
  return removed;
4609
4642
  };
4610
- assertReadable = async (relForCheck, displayPath, base) => {
4611
- if (isSensitiveReadTarget(relForCheck)) {
4643
+ assertReadable = async (absPath, displayPath) => {
4644
+ if (isSensitiveReadTarget(absPath)) {
4612
4645
  return `\u{1F512} [\u5B89\u5168\u62E6\u622A]\uFF1A[${displayPath}] \u5C5E\u4E8E\u654F\u611F\u51ED\u8BC1\u6587\u4EF6\uFF08.env / \u79C1\u94A5 / \u5BC6\u94A5\u5E93 / \u51ED\u8BC1\uFF09\uFF0C\u5DF2\u62D2\u7EDD\u8BFB\u53D6\u4EE5\u9632\u673A\u5BC6\u5916\u6CC4\u3002\u5982\u786E\u9700\u67E5\u770B\u8BF7\u4EBA\u5DE5\u5904\u7406\u3002`;
4613
4646
  }
4614
4647
  return null;
@@ -4638,9 +4671,19 @@ var init_fs = __esm({
4638
4671
  }
4639
4672
  if (hits.length === 0) return { ok: false, reason: "none", count: 0 };
4640
4673
  if (!replaceAll && hits.length > 1) return { ok: false, reason: "conflict", count: hits.length };
4641
- const newLines = newBlock.split("\n");
4642
4674
  const out = [...contentLines];
4643
- for (let k = hits.length - 1; k >= 0; k--) out.splice(hits[k], oldLines.length, ...newLines);
4675
+ for (let k = hits.length - 1; k >= 0; k--) {
4676
+ const start = hits[k];
4677
+ let baseIndent = "";
4678
+ for (let j = start; j < start + oldLines.length; j++) {
4679
+ if (contentLines[j].trim() !== "") {
4680
+ baseIndent = contentLines[j].match(/^[ \t]*/)?.[0] ?? "";
4681
+ break;
4682
+ }
4683
+ }
4684
+ const aligned = baseIndent ? reindentToBase(newBlock, baseIndent) : newBlock;
4685
+ out.splice(start, oldLines.length, ...aligned.split("\n"));
4686
+ }
4644
4687
  return { ok: true, content: out.join("\n"), count: hits.length };
4645
4688
  };
4646
4689
  diagnoseOldStr = (content, oldBlock) => {
@@ -4682,7 +4725,7 @@ var init_fs = __esm({
4682
4725
  parameters: {
4683
4726
  type: "object",
4684
4727
  properties: {
4685
- path: { type: "string", description: "\u6587\u4EF6\u76F8\u5BF9\u8DEF\u5F84" },
4728
+ path: { type: "string", description: "\u6587\u4EF6\u8DEF\u5F84\uFF1A\u76F8\u5BF9\u6D3B\u52A8\u5DE5\u4F5C\u533A\u6839\uFF08\u652F\u6301 ../ \u8DE8\u5144\u5F1F\u9879\u76EE\uFF09\u3001\u6216\u7EDD\u5BF9\u8DEF\u5F84" },
4686
4729
  start_line: { type: "number", description: "\u8D77\u59CB\u884C\u53F7\uFF08\u4ECE 1 \u5F00\u59CB\uFF0C\u9ED8\u8BA4 1\uFF09" },
4687
4730
  end_line: { type: "number", description: "\u7ED3\u675F\u884C\u53F7\uFF08\u9ED8\u8BA4\u6700\u591A\u5F80\u540E\u8BFB 2000 \u884C\uFF09" }
4688
4731
  },
@@ -4697,14 +4740,12 @@ var init_fs = __esm({
4697
4740
  privacyMaskingRules: maskSecretsInContent,
4698
4741
  async execute(args) {
4699
4742
  try {
4700
- const absPath = resolveSafePath(args.path);
4743
+ const absPath = resolveReadablePath(args.path);
4701
4744
  const lowerExt = absPath.toLowerCase();
4702
4745
  if (lowerExt.endsWith(".xlsx")) return `\u26A0\uFE0F [${args.path}] \u662F Excel \u4E8C\u8FDB\u5236\u6587\u4EF6\uFF0Cread_file \u8BFB\u4E0D\u4E86\uFF08UTF-8 \u89E3\u7801\u6EE1\u5C4F\u4E71\u7801\uFF09\u3002\u8BF7\u6539\u7528 read_xlsx\uFF08\u652F\u6301 sheet \u9009\u62E9 / \u7FFB\u9875 / Markdown \u8868\u683C\u8F93\u51FA\uFF09\u3002`;
4703
4746
  if (lowerExt.endsWith(".docx")) return `\u26A0\uFE0F [${args.path}] \u662F Word \u4E8C\u8FDB\u5236\u6587\u6863\uFF0Cread_file \u8BFB\u4E0D\u4E86\u3002\u8BF7\u6539\u7528 read_docx \u63D0\u53D6\u6B63\u6587\u6587\u672C\u3002`;
4704
4747
  if (lowerExt.endsWith(".pdf")) return `\u26A0\uFE0F [${args.path}] \u662F PDF \u4E8C\u8FDB\u5236\u6587\u6863\uFF0Cread_file \u8BFB\u4E0D\u4E86\u3002\u8BF7\u6539\u7528 read_pdf \u63D0\u53D6\u6587\u5B57\u5C42\u3002`;
4705
- const checkBase = getContainingRoot(absPath);
4706
- const relForCheck = path15.relative(checkBase, absPath).replace(/\\/g, "/");
4707
- const readBlock = await assertReadable(relForCheck, args.path, checkBase);
4748
+ const readBlock = await assertReadable(absPath, args.path);
4708
4749
  if (readBlock) return readBlock;
4709
4750
  const start = args.start_line ? Math.max(1, args.start_line) : 1;
4710
4751
  const maxLinesToRead = 2e3;
@@ -5052,10 +5093,8 @@ ${args.new_str}`,
5052
5093
  privacyMaskingRules: maskSecretsInContent,
5053
5094
  async execute(args) {
5054
5095
  try {
5055
- const absPath = resolveSafePath(args.path);
5056
- const checkBase = getContainingRoot(absPath);
5057
- const relForCheck = path15.relative(checkBase, absPath).replace(/\\/g, "/");
5058
- const readBlock = await assertReadable(relForCheck, args.path, checkBase);
5096
+ const absPath = resolveReadablePath(args.path);
5097
+ const readBlock = await assertReadable(absPath, args.path);
5059
5098
  if (readBlock) return readBlock;
5060
5099
  const statForSize = await fs12.stat(absPath);
5061
5100
  if (statForSize.size > 1024 * 1024) {
@@ -5219,7 +5258,7 @@ var init_search = __esm({
5219
5258
  });
5220
5259
  if (hit) return hit;
5221
5260
  }
5222
- return resolveSafePath(args.path);
5261
+ return resolveReadablePath(args.path);
5223
5262
  };
5224
5263
  const searchRoot = resolveSearchRoot().replace(/\\/g, "/");
5225
5264
  const rgArgs = [
@@ -5589,7 +5628,7 @@ var init_glob = __esm({
5589
5628
  const cleanPattern = (args.pattern || "").trim();
5590
5629
  if (!cleanPattern) return "\u274C [Glob\u5931\u8D25]\uFF1A\u4F20\u5165\u7684\u68C0\u7D22 pattern \u4E0D\u80FD\u4E3A\u7A7A\u3002";
5591
5630
  const activeRoot = ctx?.cwd ?? getActiveWorkspaceRoot();
5592
- const root = args.path ? resolveSafePath(args.path) : activeRoot;
5631
+ const root = args.path ? resolveReadablePath(args.path) : activeRoot;
5593
5632
  const re = globToRegex2(cleanPattern);
5594
5633
  await initializeWorkspaceIgnore();
5595
5634
  const hits = [];
@@ -6506,9 +6545,7 @@ var init_typescript = __esm({
6506
6545
  return abs.replace(/\\/g, "/").split("/").slice(-3).join("/");
6507
6546
  };
6508
6547
  precheck = async (displayPath, absPath) => {
6509
- const checkBase = getContainingRoot(absPath);
6510
- const relForCheck = path19.relative(checkBase, absPath).replace(/\\/g, "/");
6511
- const readBlock = await assertReadable(relForCheck, displayPath, checkBase);
6548
+ const readBlock = await assertReadable(absPath, displayPath);
6512
6549
  if (readBlock) return readBlock;
6513
6550
  const stat = await fs16.stat(absPath);
6514
6551
  if (stat.size > MAX_FILE_BYTES) {
@@ -6540,7 +6577,7 @@ var init_typescript = __esm({
6540
6577
  try {
6541
6578
  const TS = await getTs();
6542
6579
  if (!TS) return `\u26A0\uFE0F [\u7C7B\u578B\u8BCA\u65AD\u4E0D\u53EF\u7528]\uFF1Atypescript \u6A21\u5757\u672A\u52A0\u8F7D\uFF08VSCode \u6269\u5C55\u5185\u53EF\u7528\uFF1BCLI \u73AF\u5883\u672A\u5FC5\u5B89\u88C5 typescript\uFF09\u3002\u53EF\u6539\u7528 run_command \u8DD1 \`tsc --noEmit\`\u3002`;
6543
- const absPath = realpathNative(resolveSafePath(args.path));
6580
+ const absPath = realpathNative(resolveReadablePath(args.path));
6544
6581
  const block = await precheck(args.path, absPath);
6545
6582
  if (block) return block;
6546
6583
  const { ls } = await getLanguageService(TS, absPath, { checkJs: args.check_js });
@@ -6612,7 +6649,7 @@ ${body}${tail}`;
6612
6649
  try {
6613
6650
  const TS = await getTs();
6614
6651
  if (!TS) return `\u26A0\uFE0F [\u8DF3\u8F6C\u5B9A\u4E49\u4E0D\u53EF\u7528]\uFF1Atypescript \u6A21\u5757\u672A\u52A0\u8F7D\uFF08VSCode \u6269\u5C55\u5185\u53EF\u7528\uFF1BCLI \u73AF\u5883\u672A\u5FC5\u5B89\u88C5 typescript\uFF09\u3002`;
6615
- const absPath = realpathNative(resolveSafePath(displayPath));
6652
+ const absPath = realpathNative(resolveReadablePath(displayPath));
6616
6653
  const block = await precheck(displayPath, absPath);
6617
6654
  if (block) return block;
6618
6655
  const { ls } = await getLanguageService(TS, absPath);
@@ -8186,7 +8223,6 @@ ${lines.join("\n")}`;
8186
8223
  });
8187
8224
 
8188
8225
  // ../core/src/tool/registry/spreadsheet.ts
8189
- import path28 from "path";
8190
8226
  var getExcelJs, colLetter, cellToText, esc, spreadsheetTools;
8191
8227
  var init_spreadsheet = __esm({
8192
8228
  "../core/src/tool/registry/spreadsheet.ts"() {
@@ -8244,10 +8280,8 @@ var init_spreadsheet = __esm({
8244
8280
  privacyMaskingRules: maskSecretsInContent,
8245
8281
  async execute(args) {
8246
8282
  try {
8247
- const absPath = resolveSafePath(args.path);
8248
- const checkBase = getContainingRoot(absPath);
8249
- const relForCheck = path28.relative(checkBase, absPath).replace(/\\/g, "/");
8250
- const readBlock = await assertReadable(relForCheck, args.path, checkBase);
8283
+ const absPath = resolveReadablePath(args.path);
8284
+ const readBlock = await assertReadable(absPath, args.path);
8251
8285
  if (readBlock) return readBlock;
8252
8286
  if (!absPath.toLowerCase().endsWith(".xlsx")) {
8253
8287
  return `\u274C [\u683C\u5F0F\u4E0D\u652F\u6301]\uFF1A[${args.path}] \u4E0D\u662F .xlsx\u3002read_xlsx \u4EC5\u89E3\u6790 Excel \u5DE5\u4F5C\u7C3F\uFF08.xls \u8BF7\u5148\u53E6\u5B58\u4E3A .xlsx\uFF09\uFF1B\u5176\u5B83\u6587\u4EF6\u8BF7\u7528 read_file\u3002`;
@@ -8304,7 +8338,6 @@ var init_spreadsheet = __esm({
8304
8338
  });
8305
8339
 
8306
8340
  // ../core/src/tool/registry/document.ts
8307
- import path29 from "path";
8308
8341
  import fs26 from "fs/promises";
8309
8342
  var getMammoth, getUnpdf, documentTools;
8310
8343
  var init_document = __esm({
@@ -8340,10 +8373,8 @@ var init_document = __esm({
8340
8373
  privacyMaskingRules: maskSecretsInContent,
8341
8374
  async execute(args) {
8342
8375
  try {
8343
- const absPath = resolveSafePath(args.path);
8344
- const checkBase = getContainingRoot(absPath);
8345
- const relForCheck = path29.relative(checkBase, absPath).replace(/\\/g, "/");
8346
- const readBlock = await assertReadable(relForCheck, args.path, checkBase);
8376
+ const absPath = resolveReadablePath(args.path);
8377
+ const readBlock = await assertReadable(absPath, args.path);
8347
8378
  if (readBlock) return readBlock;
8348
8379
  if (!absPath.toLowerCase().endsWith(".docx")) {
8349
8380
  return `\u274C [\u683C\u5F0F\u4E0D\u652F\u6301]\uFF1A[${args.path}] \u4E0D\u662F .docx\u3002read_docx \u4EC5\u89E3\u6790 Word \u6587\u6863\uFF08.doc \u8001\u683C\u5F0F\u8BF7\u5148\u53E6\u5B58\u4E3A .docx\uFF09\uFF1B\u5176\u5B83\u6587\u4EF6\u7528 read_file\u3002`;
@@ -8389,10 +8420,8 @@ var init_document = __esm({
8389
8420
  privacyMaskingRules: maskSecretsInContent,
8390
8421
  async execute(args) {
8391
8422
  try {
8392
- const absPath = resolveSafePath(args.path);
8393
- const checkBase = getContainingRoot(absPath);
8394
- const relForCheck = path29.relative(checkBase, absPath).replace(/\\/g, "/");
8395
- const readBlock = await assertReadable(relForCheck, args.path, checkBase);
8423
+ const absPath = resolveReadablePath(args.path);
8424
+ const readBlock = await assertReadable(absPath, args.path);
8396
8425
  if (readBlock) return readBlock;
8397
8426
  if (!absPath.toLowerCase().endsWith(".pdf")) {
8398
8427
  return `\u274C [\u683C\u5F0F\u4E0D\u652F\u6301]\uFF1A[${args.path}] \u4E0D\u662F .pdf\u3002read_pdf \u4EC5\u89E3\u6790 PDF \u6587\u6863\uFF1B\u5176\u5B83\u6587\u4EF6\u7528 read_file\u3002`;
@@ -8604,7 +8633,7 @@ var init_backgroundTool = __esm({
8604
8633
  });
8605
8634
 
8606
8635
  // ../core/src/tool/autoPermission.ts
8607
- import path30 from "path";
8636
+ import path28 from "path";
8608
8637
  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;
8609
8638
  var init_autoPermission = __esm({
8610
8639
  "../core/src/tool/autoPermission.ts"() {
@@ -8739,9 +8768,9 @@ var init_autoPermission = __esm({
8739
8768
  isWithinWorkspace = (p, cwd) => {
8740
8769
  if (!p || !cwd) return false;
8741
8770
  try {
8742
- const abs = path30.isAbsolute(p) ? p : path30.resolve(cwd, p);
8743
- const rel = path30.relative(cwd, abs);
8744
- return rel === "" || !rel.startsWith("..") && !path30.isAbsolute(rel);
8771
+ const abs = path28.isAbsolute(p) ? p : path28.resolve(cwd, p);
8772
+ const rel = path28.relative(cwd, abs);
8773
+ return rel === "" || !rel.startsWith("..") && !path28.isAbsolute(rel);
8745
8774
  } catch {
8746
8775
  return false;
8747
8776
  }
@@ -9887,7 +9916,7 @@ var init_subagent = __esm({
9887
9916
 
9888
9917
  // ../core/src/hooks/loader.ts
9889
9918
  import fs27 from "fs/promises";
9890
- import path31 from "path";
9919
+ import path29 from "path";
9891
9920
  var readHooksConfig, appendValidated, validateRule, parseAgentDecision, compileRule2, loadHooks, initHooks;
9892
9921
  var init_loader4 = __esm({
9893
9922
  "../core/src/hooks/loader.ts"() {
@@ -9902,9 +9931,9 @@ var init_loader4 = __esm({
9902
9931
  readHooksConfig = async (includeProject) => {
9903
9932
  const merged = {};
9904
9933
  const paths = [
9905
- path31.join(appConfig.dataDir, "settings.json"),
9934
+ path29.join(appConfig.dataDir, "settings.json"),
9906
9935
  // 全局用户级
9907
- ...includeProject ? [path31.join(process.cwd(), ".deepseeker-code", "settings.json")] : []
9936
+ ...includeProject ? [path29.join(process.cwd(), ".deepseeker-code", "settings.json")] : []
9908
9937
  // 项目级(叠加);未信任时省略
9909
9938
  ];
9910
9939
  for (const configPath of paths) {
@@ -10213,7 +10242,7 @@ ${m.context}`;
10213
10242
 
10214
10243
  // ../core/src/skills/loader.ts
10215
10244
  import fs28 from "fs/promises";
10216
- import path32 from "path";
10245
+ import path30 from "path";
10217
10246
  import { fileURLToPath } from "url";
10218
10247
  var BUILTIN_DIR, SOURCES2, MAX_SKILL_BODY_BYTES, splitList, parseSkillAt, loadSkills, initSkills;
10219
10248
  var init_loader5 = __esm({
@@ -10224,11 +10253,11 @@ var init_loader5 = __esm({
10224
10253
  init_registry3();
10225
10254
  init_skill();
10226
10255
  init_registry2();
10227
- BUILTIN_DIR = path32.join(path32.dirname(fileURLToPath(import.meta.url)), "builtin");
10256
+ BUILTIN_DIR = path30.join(path30.dirname(fileURLToPath(import.meta.url)), "builtin");
10228
10257
  SOURCES2 = [
10229
10258
  { dir: BUILTIN_DIR, source: "builtin" },
10230
- { dir: path32.join(appConfig.dataDir, "skills"), source: "global" },
10231
- { dir: path32.join(process.cwd(), ".deepseeker-code", "skills"), source: "project" }
10259
+ { dir: path30.join(appConfig.dataDir, "skills"), source: "global" },
10260
+ { dir: path30.join(process.cwd(), ".deepseeker-code", "skills"), source: "project" }
10232
10261
  ];
10233
10262
  MAX_SKILL_BODY_BYTES = 64 * 1024;
10234
10263
  splitList = (raw) => (raw ?? "").split(",").map((s) => s.trim()).filter(Boolean);
@@ -10274,7 +10303,7 @@ var init_loader5 = __esm({
10274
10303
  loadSkills = async (includeProject) => {
10275
10304
  const picked = await scanSources(
10276
10305
  filterSources(SOURCES2, includeProject),
10277
- (e, dir) => e.isDirectory() ? path32.join(dir, e.name, "SKILL.md") : void 0,
10306
+ (e, dir) => e.isDirectory() ? path30.join(dir, e.name, "SKILL.md") : void 0,
10278
10307
  parseSkillAt
10279
10308
  );
10280
10309
  for (const { item } of picked) registerSkill(item);
@@ -10306,7 +10335,7 @@ var init_loader5 = __esm({
10306
10335
 
10307
10336
  // ../core/src/agents/loader.ts
10308
10337
  import fs29 from "fs/promises";
10309
- import path33 from "path";
10338
+ import path31 from "path";
10310
10339
  import { fileURLToPath as fileURLToPath2 } from "url";
10311
10340
  var BUILTIN_DIR2, SOURCES3, parseAgentAt, initAgents;
10312
10341
  var init_loader6 = __esm({
@@ -10316,11 +10345,11 @@ var init_loader6 = __esm({
10316
10345
  init_frontmatter();
10317
10346
  init_registry4();
10318
10347
  init_registry2();
10319
- BUILTIN_DIR2 = path33.join(path33.dirname(fileURLToPath2(import.meta.url)), "builtin");
10348
+ BUILTIN_DIR2 = path31.join(path31.dirname(fileURLToPath2(import.meta.url)), "builtin");
10320
10349
  SOURCES3 = [
10321
10350
  { dir: BUILTIN_DIR2, source: "builtin" },
10322
- { dir: path33.join(appConfig.dataDir, "agents"), source: "global" },
10323
- { dir: path33.join(process.cwd(), ".deepseeker-code", "agents"), source: "project" }
10351
+ { dir: path31.join(appConfig.dataDir, "agents"), source: "global" },
10352
+ { dir: path31.join(process.cwd(), ".deepseeker-code", "agents"), source: "project" }
10324
10353
  ];
10325
10354
  parseAgentAt = async (file, dir, source) => {
10326
10355
  let raw;
@@ -10360,7 +10389,7 @@ var init_loader6 = __esm({
10360
10389
  const known = new Set(into.map((t) => t.function.name));
10361
10390
  const picked = await scanSources(
10362
10391
  filterSources(SOURCES3, includeProject),
10363
- (e, dir) => e.isFile() && e.name.endsWith(".agent.md") ? path33.join(dir, e.name) : void 0,
10392
+ (e, dir) => e.isFile() && e.name.endsWith(".agent.md") ? path31.join(dir, e.name) : void 0,
10364
10393
  parseAgentAt
10365
10394
  );
10366
10395
  for (const { item: m, file, source } of picked) {
@@ -10398,7 +10427,7 @@ var init_registry7 = __esm({
10398
10427
 
10399
10428
  // ../core/src/commands/loader.ts
10400
10429
  import fs30 from "fs/promises";
10401
- import path34 from "path";
10430
+ import path32 from "path";
10402
10431
  import { fileURLToPath as fileURLToPath3 } from "url";
10403
10432
  var BUILTIN_DIR3, SOURCES4, MAX_COMMAND_BODY_BYTES, parseCommandAt, loadCommands, initCommands;
10404
10433
  var init_loader7 = __esm({
@@ -10408,11 +10437,11 @@ var init_loader7 = __esm({
10408
10437
  init_frontmatter();
10409
10438
  init_registry7();
10410
10439
  init_registry2();
10411
- BUILTIN_DIR3 = path34.join(path34.dirname(fileURLToPath3(import.meta.url)), "builtin");
10440
+ BUILTIN_DIR3 = path32.join(path32.dirname(fileURLToPath3(import.meta.url)), "builtin");
10412
10441
  SOURCES4 = [
10413
10442
  { dir: BUILTIN_DIR3, source: "builtin" },
10414
- { dir: path34.join(appConfig.dataDir, "commands"), source: "global" },
10415
- { dir: path34.join(process.cwd(), ".deepseeker-code", "commands"), source: "project" }
10443
+ { dir: path32.join(appConfig.dataDir, "commands"), source: "global" },
10444
+ { dir: path32.join(process.cwd(), ".deepseeker-code", "commands"), source: "project" }
10416
10445
  ];
10417
10446
  MAX_COMMAND_BODY_BYTES = 64 * 1024;
10418
10447
  parseCommandAt = async (file, _dir, source) => {
@@ -10429,7 +10458,7 @@ var init_loader7 = __esm({
10429
10458
  }
10430
10459
  const name = parsed.frontmatter.name;
10431
10460
  const description = parsed.frontmatter.description;
10432
- const fallbackName = path34.basename(file, ".md");
10461
+ const fallbackName = path32.basename(file, ".md");
10433
10462
  const finalName = name || fallbackName;
10434
10463
  if (!description) {
10435
10464
  console.warn(`\u26A0\uFE0F [commands] \u7F3A\u5C11 description\uFF08${file}\uFF09\uFF0C\u5DF2\u8DF3\u8FC7`);
@@ -10455,7 +10484,7 @@ var init_loader7 = __esm({
10455
10484
  loadCommands = async (includeProject) => {
10456
10485
  const picked = await scanSources(
10457
10486
  filterSources(SOURCES4, includeProject),
10458
- (e, dir) => e.isFile() && e.name.endsWith(".md") ? path34.join(dir, e.name) : void 0,
10487
+ (e, dir) => e.isFile() && e.name.endsWith(".md") ? path32.join(dir, e.name) : void 0,
10459
10488
  parseCommandAt
10460
10489
  );
10461
10490
  for (const { item } of picked) registerCommand(item);
@@ -10474,7 +10503,7 @@ var init_loader7 = __esm({
10474
10503
 
10475
10504
  // ../core/src/outputStyles/loader.ts
10476
10505
  import fs31 from "fs/promises";
10477
- import path35 from "path";
10506
+ import path33 from "path";
10478
10507
  import { fileURLToPath as fileURLToPath4 } from "url";
10479
10508
  var BUILTIN_DIR4, MAX_STYLE_BODY_BYTES, SOURCES5, parseStyleAt, loadOutputStyles, initOutputStyles;
10480
10509
  var init_loader8 = __esm({
@@ -10484,12 +10513,12 @@ var init_loader8 = __esm({
10484
10513
  init_frontmatter();
10485
10514
  init_registry5();
10486
10515
  init_registry2();
10487
- BUILTIN_DIR4 = path35.join(path35.dirname(fileURLToPath4(import.meta.url)), "builtin");
10516
+ BUILTIN_DIR4 = path33.join(path33.dirname(fileURLToPath4(import.meta.url)), "builtin");
10488
10517
  MAX_STYLE_BODY_BYTES = 64 * 1024;
10489
10518
  SOURCES5 = [
10490
10519
  { dir: BUILTIN_DIR4, source: "builtin" },
10491
- { dir: path35.join(appConfig.dataDir, "output-styles"), source: "global" },
10492
- { dir: path35.join(process.cwd(), ".deepseeker-code", "output-styles"), source: "project" }
10520
+ { dir: path33.join(appConfig.dataDir, "output-styles"), source: "global" },
10521
+ { dir: path33.join(process.cwd(), ".deepseeker-code", "output-styles"), source: "project" }
10493
10522
  ];
10494
10523
  parseStyleAt = async (file, _dir, source) => {
10495
10524
  let raw;
@@ -10526,7 +10555,7 @@ var init_loader8 = __esm({
10526
10555
  loadOutputStyles = async (includeProject) => {
10527
10556
  const picked = await scanSources(
10528
10557
  filterSources(SOURCES5, includeProject),
10529
- (e, dir) => e.isFile() && e.name.endsWith(".md") ? path35.join(dir, e.name) : void 0,
10558
+ (e, dir) => e.isFile() && e.name.endsWith(".md") ? path33.join(dir, e.name) : void 0,
10530
10559
  parseStyleAt
10531
10560
  );
10532
10561
  for (const { item } of picked) registerOutputStyle(item);
@@ -10568,16 +10597,26 @@ var init_bootstrap = __esm({
10568
10597
  if (typeof AbortSignal.any !== "function" || typeof AbortSignal.timeout !== "function") {
10569
10598
  console.error("\u274C \u5F53\u524D Node \u7248\u672C\u7F3A\u5C11 AbortSignal.any/timeout\uFF08\u9700 Node 20.3+\uFF09\uFF0Cweb_fetch \u76F8\u5173\u80FD\u529B\u5C06\u4E0D\u53EF\u7528\uFF0C\u5EFA\u8BAE\u5347\u7EA7 Node\u3002");
10570
10599
  }
10571
- await sweepOrphanedWorktrees().catch((e) => console.warn(`\u26A0\uFE0F [worktree] \u542F\u52A8\u671F\u6E05\u626B\u5931\u8D25\uFF08\u5DF2\u5FFD\u7565\uFF09: ${e?.message ?? e}`));
10572
- await initMcpTools(into);
10573
- await initHooks(includeProject);
10574
- await initPermissions(includeProject);
10600
+ await Promise.all([
10601
+ // P2-13 worktree 孤儿清扫:进程重启 = 上次 run_workflow 未清理的 worktree 全是孤儿。best-effort,失败不阻断。
10602
+ sweepOrphanedWorktrees().catch((e) => console.warn(`worktree \u542F\u52A8\u671F\u6E05\u626B\u5931\u8D25\uFF08\u5DF2\u5FFD\u7565\uFF09: ${e?.message ?? e}`)),
10603
+ // 连接配置的 MCP 服务器并注入其工具(★ 通常最慢:spawn 子进程 + stdio 握手;无配置静默跳过)。仅读全局 mcp.json,不受 includeProject 影响。
10604
+ initMcpTools(into),
10605
+ // 加载声明式 hooks(settings.json;无配置时静默跳过)。未信任时跳过项目级(hooks 会 spawn 执行命令,高风险)
10606
+ initHooks(includeProject),
10607
+ // 加载细粒度权限规则(settings.json permissions.{allow,deny,ask};无配置时静默跳过)。未信任时跳过项目级(防 auto-approve 绕审批)
10608
+ initPermissions(includeProject),
10609
+ // 缓存项目指引(CLAUDE.md/AGENTS.md/AGENT.md)到内存,供每轮自动注入 system prompt。未信任时整体跳过(无全局源,防提示注入)
10610
+ initProjectGuide(includeProject),
10611
+ // 加载斜杠命令(builtin/global/project;用户输入 /<name> 时前置展开)。未信任时跳过项目级
10612
+ initCommands(includeProject),
10613
+ // 加载输出风格(builtin/global/project;用户经 CLI /output-style <name> 选用,runAgent 注入 persona)。未信任时跳过项目级
10614
+ initOutputStyles(includeProject),
10615
+ // 加载持久记忆(global/project;runAgent 注入一行索引,memory_read 按需召回全文)。未信任时跳过项目级(防提示注入)
10616
+ initMemories(includeProject)
10617
+ ]);
10575
10618
  await initSkills(into, includeProject);
10576
10619
  await initAgents(into, includeProject);
10577
- await initProjectGuide(includeProject);
10578
- await initCommands(includeProject);
10579
- await initOutputStyles(includeProject);
10580
- await initMemories(includeProject);
10581
10620
  return () => {
10582
10621
  try {
10583
10622
  disposeAllMcpClients();
@@ -10598,7 +10637,7 @@ var init_bootstrap = __esm({
10598
10637
 
10599
10638
  // ../core/src/statusLine/config.ts
10600
10639
  import fs32 from "fs/promises";
10601
- import path36 from "path";
10640
+ import path34 from "path";
10602
10641
  var parseBlock, readStatusLineConfig;
10603
10642
  var init_config2 = __esm({
10604
10643
  "../core/src/statusLine/config.ts"() {
@@ -10614,9 +10653,9 @@ var init_config2 = __esm({
10614
10653
  };
10615
10654
  readStatusLineConfig = async (includeProject) => {
10616
10655
  const paths = [
10617
- path36.join(appConfig.dataDir, "settings.json"),
10656
+ path34.join(appConfig.dataDir, "settings.json"),
10618
10657
  // 全局用户级
10619
- ...includeProject ? [path36.join(process.cwd(), ".deepseeker-code", "settings.json")] : []
10658
+ ...includeProject ? [path34.join(process.cwd(), ".deepseeker-code", "settings.json")] : []
10620
10659
  // 项目级(覆盖);未信任时省略
10621
10660
  ];
10622
10661
  let result = null;
@@ -10644,7 +10683,7 @@ var init_config2 = __esm({
10644
10683
  // ../core/src/statusLine/runner.ts
10645
10684
  import { spawn as spawn5 } from "child_process";
10646
10685
  import fs33 from "fs";
10647
- import path37 from "path";
10686
+ import path35 from "path";
10648
10687
  import { fileURLToPath as fileURLToPath5 } from "url";
10649
10688
  var STATUSLINE_TIMEOUT_MS, cachedVersion, runStatusLine;
10650
10689
  var init_runner = __esm({
@@ -10653,11 +10692,11 @@ var init_runner = __esm({
10653
10692
  init_guard();
10654
10693
  STATUSLINE_TIMEOUT_MS = 3e3;
10655
10694
  try {
10656
- const here = path37.dirname(fileURLToPath5(import.meta.url));
10695
+ const here = path35.dirname(fileURLToPath5(import.meta.url));
10657
10696
  const candidates = [
10658
- path37.join(here, "../../../package.json"),
10697
+ path35.join(here, "../../../package.json"),
10659
10698
  // src/core/package.json
10660
- path37.join(here, "../../../../package.json")
10699
+ path35.join(here, "../../../../package.json")
10661
10700
  // 仓库根 package.json
10662
10701
  ];
10663
10702
  for (const p of candidates) {
@@ -10721,7 +10760,7 @@ var init_createModel = __esm({
10721
10760
  });
10722
10761
 
10723
10762
  // ../core/src/observability/store.ts
10724
- import path38 from "path";
10763
+ import path36 from "path";
10725
10764
  import fs34 from "fs/promises";
10726
10765
  var getTraceDirPath, getTracePath, tracePathCache, ensuredTraceDirs, ensureTraceDir, getGlobalClockPath, getTraceStorePath;
10727
10766
  var init_store3 = __esm({
@@ -10732,10 +10771,10 @@ var init_store3 = __esm({
10732
10771
  init_common();
10733
10772
  getTraceDirPath = (mainTraceId) => {
10734
10773
  assertSafeSessionId(mainTraceId, "traceId");
10735
- return path38.join(appConfig.dataDir, "trace", appConfig.userWorkspaceDir, getFileName(mainTraceId));
10774
+ return path36.join(appConfig.dataDir, "trace", appConfig.userWorkspaceDir, getFileName(mainTraceId));
10736
10775
  };
10737
10776
  getTracePath = () => {
10738
- return path38.join(appConfig.dataDir, "trace");
10777
+ return path36.join(appConfig.dataDir, "trace");
10739
10778
  };
10740
10779
  tracePathCache = /* @__PURE__ */ new Map();
10741
10780
  ensuredTraceDirs = /* @__PURE__ */ new Set();
@@ -10746,7 +10785,7 @@ var init_store3 = __esm({
10746
10785
  ensuredTraceDirs.add(dir);
10747
10786
  };
10748
10787
  getGlobalClockPath = () => {
10749
- return path38.join(getTracePath(), "trace-cleanup-clock.json");
10788
+ return path36.join(getTracePath(), "trace-cleanup-clock.json");
10750
10789
  };
10751
10790
  getTraceStorePath = async (mainTraceId) => {
10752
10791
  assertSafeSessionId(mainTraceId, "traceId");
@@ -10764,7 +10803,7 @@ var init_store3 = __esm({
10764
10803
  const todayStr = getTodayDateString();
10765
10804
  fileName = `trace-${todayStr}__${rootId}.jsonl`;
10766
10805
  }
10767
- const resolved = path38.join(dir, fileName);
10806
+ const resolved = path36.join(dir, fileName);
10768
10807
  tracePathCache.set(rootId, resolved);
10769
10808
  return resolved;
10770
10809
  };
@@ -10773,7 +10812,7 @@ var init_store3 = __esm({
10773
10812
 
10774
10813
  // ../core/src/observability/trace.ts
10775
10814
  import fs35 from "fs/promises";
10776
- import path39 from "path";
10815
+ import path37 from "path";
10777
10816
  async function emitTrace(base) {
10778
10817
  const event = {
10779
10818
  sessionId: base.sessionId,
@@ -10827,7 +10866,7 @@ async function maybeCleanupAfterAppend(sessionId) {
10827
10866
  lastSizeCleanupAt2 = now;
10828
10867
  diskLastCleanupAt2 = now;
10829
10868
  const clockPath = getGlobalClockPath();
10830
- await fs35.mkdir(path39.dirname(clockPath), { recursive: true });
10869
+ await fs35.mkdir(path37.dirname(clockPath), { recursive: true });
10831
10870
  await fs35.writeFile(clockPath, JSON.stringify({ lastCleanupAt: now, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), "utf-8");
10832
10871
  if (deletedCount > 0) {
10833
10872
  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`);
@@ -10854,12 +10893,12 @@ async function cleanupOldTraceFiles() {
10854
10893
  }
10855
10894
  const re = /^trace-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
10856
10895
  for (const relativePath of relativePaths) {
10857
- const fileName = path39.basename(relativePath);
10896
+ const fileName = path37.basename(relativePath);
10858
10897
  const m = fileName.match(re);
10859
10898
  if (!m) continue;
10860
10899
  const fileBornDay = /* @__PURE__ */ new Date(`${m[1]}T00:00:00`);
10861
10900
  if (fileBornDay >= cutoff) continue;
10862
- const fullPath = path39.join(dir, relativePath);
10901
+ const fullPath = path37.join(dir, relativePath);
10863
10902
  try {
10864
10903
  const st = await fs35.stat(fullPath);
10865
10904
  if (now - st.mtimeMs < ACTIVE_GRACE_MS2) continue;
@@ -10881,11 +10920,11 @@ async function evictOldestForSize2(targetBytes) {
10881
10920
  const re = /^trace-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
10882
10921
  const candidates = [];
10883
10922
  for (const relativePath of relativePaths) {
10884
- const fileName = path39.basename(relativePath);
10923
+ const fileName = path37.basename(relativePath);
10885
10924
  if (!re.test(fileName)) continue;
10886
10925
  try {
10887
- const st = await fs35.stat(path39.join(dir, relativePath));
10888
- candidates.push({ mtime: st.mtimeMs, fullPath: path39.join(dir, relativePath), size: st.size });
10926
+ const st = await fs35.stat(path37.join(dir, relativePath));
10927
+ candidates.push({ mtime: st.mtimeMs, fullPath: path37.join(dir, relativePath), size: st.size });
10889
10928
  } catch {
10890
10929
  }
10891
10930
  }
@@ -11072,7 +11111,7 @@ ${PLAN_MODE_AUTO_ENTER_HINT}
11072
11111
  });
11073
11112
 
11074
11113
  // ../core/src/serve/chatProcessing.ts
11075
- import path40 from "path";
11114
+ import path38 from "path";
11076
11115
  import fs36 from "fs";
11077
11116
  var handleUnifiedChat;
11078
11117
  var init_chatProcessing = __esm({
@@ -11130,14 +11169,14 @@ ${inject}`;
11130
11169
  activeReal = fs36.realpathSync(activeReal);
11131
11170
  } catch {
11132
11171
  }
11133
- const lines = roots.map((r) => `- ${path40.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"}`);
11172
+ const lines = roots.map((r) => `- ${path38.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"}`);
11134
11173
  sysPrompt = sysPrompt + `
11135
11174
 
11136
11175
  \u3010\u5DE5\u4F5C\u533A\uFF08\u591A\u9879\u76EE\uFF09\u3011
11137
11176
  \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>:
11138
11177
  ${lines.join("\n")}
11139
- \u2605 \u8DEF\u5F84\u951A\u5B9A\u94C1\u5F8B\uFF1A\u5DE5\u5177\u7F3A\u7701\u53EA\u4F5C\u7528\u4E8E\u9ED8\u8BA4\u6839\uFF08${path40.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
11140
- \u6CE8\u610F\uFF1A\u9879\u76EE\u7EA7\u914D\u7F6E\uFF08.deepseeker-code/\uFF09\u4EC5\u5728\u9ED8\u8BA4\u6839 ${path40.basename(activeReal) || activeReal} \u751F\u6548\u3002`;
11178
+ \u2605 \u8DEF\u5F84\u951A\u5B9A\u94C1\u5F8B\uFF1A\u5DE5\u5177\u7F3A\u7701\u53EA\u4F5C\u7528\u4E8E\u9ED8\u8BA4\u6839\uFF08${path38.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
11179
+ \u6CE8\u610F\uFF1A\u9879\u76EE\u7EA7\u914D\u7F6E\uFF08.deepseeker-code/\uFF09\u4EC5\u5728\u9ED8\u8BA4\u6839 ${path38.basename(activeReal) || activeReal} \u751F\u6548\u3002`;
11141
11180
  }
11142
11181
  let replyText = "";
11143
11182
  try {
@@ -13256,6 +13295,81 @@ ${listText}`);
13256
13295
  }
13257
13296
  });
13258
13297
 
13298
+ // src/updateCheck.ts
13299
+ var updateCheck_exports = {};
13300
+ __export(updateCheck_exports, {
13301
+ getCachedLatestIfNewer: () => getCachedLatestIfNewer,
13302
+ readLocalVersion: () => readLocalVersion,
13303
+ refreshUpdateCache: () => refreshUpdateCache
13304
+ });
13305
+ import { readFileSync as readFileSync3, writeFileSync, mkdirSync } from "node:fs";
13306
+ import path39 from "node:path";
13307
+ import os4 from "os";
13308
+ import { fileURLToPath as fileURLToPath6 } from "node:url";
13309
+ var PKG_NAME, REGISTRY, CACHE_TTL_MS, FETCH_TIMEOUT_MS2, cacheFile, readLocalVersion, parseSemver, compareVersion, readCache, writeCache, getCachedLatestIfNewer, refreshUpdateCache;
13310
+ var init_updateCheck = __esm({
13311
+ "src/updateCheck.ts"() {
13312
+ "use strict";
13313
+ PKG_NAME = "deepseeker-code";
13314
+ REGISTRY = "https://registry.npmjs.org";
13315
+ CACHE_TTL_MS = 6 * 60 * 60 * 1e3;
13316
+ FETCH_TIMEOUT_MS2 = 3e3;
13317
+ cacheFile = () => path39.join(os4.homedir(), ".deepseeker-code", "update-check.json");
13318
+ readLocalVersion = () => {
13319
+ try {
13320
+ const here = path39.dirname(fileURLToPath6(import.meta.url));
13321
+ return JSON.parse(readFileSync3(path39.join(here, "..", "package.json"), "utf8")).version ?? "0.0.0";
13322
+ } catch {
13323
+ return "0.0.0";
13324
+ }
13325
+ };
13326
+ parseSemver = (v) => {
13327
+ const m = String(v ?? "").match(/^(\d+)\.(\d+)\.(\d+)/);
13328
+ return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : [0, 0, 0];
13329
+ };
13330
+ compareVersion = (a, b) => {
13331
+ const [a1, a2, a3] = parseSemver(a);
13332
+ const [b1, b2, b3] = parseSemver(b);
13333
+ return a1 - b1 || a2 - b2 || a3 - b3;
13334
+ };
13335
+ readCache = () => {
13336
+ try {
13337
+ const obj = JSON.parse(readFileSync3(cacheFile(), "utf8"));
13338
+ return typeof obj.latestVersion === "string" && typeof obj.lastCheck === "number" ? obj : null;
13339
+ } catch {
13340
+ return null;
13341
+ }
13342
+ };
13343
+ writeCache = (latestVersion) => {
13344
+ try {
13345
+ mkdirSync(path39.dirname(cacheFile()), { recursive: true });
13346
+ writeFileSync(cacheFile(), JSON.stringify({ lastCheck: Date.now(), latestVersion }), "utf8");
13347
+ } catch {
13348
+ }
13349
+ };
13350
+ getCachedLatestIfNewer = (currentVersion) => {
13351
+ const cache = readCache();
13352
+ if (!cache) return null;
13353
+ return compareVersion(cache.latestVersion, currentVersion) > 0 ? cache.latestVersion : null;
13354
+ };
13355
+ refreshUpdateCache = () => {
13356
+ const cache = readCache();
13357
+ if (cache && Date.now() - cache.lastCheck < CACHE_TTL_MS) return;
13358
+ void (async () => {
13359
+ try {
13360
+ const res = await fetch(`${REGISTRY}/${PKG_NAME}/latest`, {
13361
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS2)
13362
+ });
13363
+ if (!res.ok) return;
13364
+ const info = await res.json();
13365
+ if (info.version) writeCache(info.version);
13366
+ } catch {
13367
+ }
13368
+ })();
13369
+ };
13370
+ }
13371
+ });
13372
+
13259
13373
  // src/preload-config.ts
13260
13374
  import { readFileSync } from "node:fs";
13261
13375
  import path from "node:path";
@@ -13305,8 +13419,8 @@ init_strings();
13305
13419
  init_prefs();
13306
13420
  init_trust();
13307
13421
  import { render } from "ink";
13308
- import os4 from "os";
13309
- import path41 from "path";
13422
+ import os5 from "os";
13423
+ import path40 from "path";
13310
13424
  import { emitKeypressEvents } from "node:readline";
13311
13425
  import { jsx as jsx17 } from "react/jsx-runtime";
13312
13426
  var parseArgs = (argv) => {
@@ -13318,6 +13432,7 @@ var parseArgs = (argv) => {
13318
13432
  else if (a === "--auto" || a === "-a") out.auto = true;
13319
13433
  else if (a === "--continue" || a === "-c") out.continue = true;
13320
13434
  else if (a === "--trust") out.trust = true;
13435
+ else if (a === "--no-update-check") out.noUpdateCheck = true;
13321
13436
  }
13322
13437
  return out;
13323
13438
  };
@@ -13432,12 +13547,19 @@ var main = async () => {
13432
13547
  process.stdout.write("\x1B[2J\x1B[3J\x1B[1;1H");
13433
13548
  const cwdIsHome = () => {
13434
13549
  try {
13435
- return path41.resolve(cwd).toLowerCase() === path41.resolve(os4.homedir()).toLowerCase();
13550
+ return path40.resolve(cwd).toLowerCase() === path40.resolve(os5.homedir()).toLowerCase();
13436
13551
  } catch {
13437
13552
  return false;
13438
13553
  }
13439
13554
  };
13440
13555
  process.stdout.write(S.startupBanner(cwd, appConfig2.userWorkspaceDir, cwdIsHome()));
13556
+ if (!args.noUpdateCheck) {
13557
+ const { readLocalVersion: readLocalVersion2, getCachedLatestIfNewer: getCachedLatestIfNewer2, refreshUpdateCache: refreshUpdateCache2 } = await Promise.resolve().then(() => (init_updateCheck(), updateCheck_exports));
13558
+ const current = readLocalVersion2();
13559
+ const latest = getCachedLatestIfNewer2(current);
13560
+ if (latest) process.stdout.write(S.updateAvailable(latest, current));
13561
+ refreshUpdateCache2();
13562
+ }
13441
13563
  let resumeId = args.resume;
13442
13564
  if (!resumeId && args.continue) {
13443
13565
  const { getMostRecentSessionId: getMostRecentSessionId2 } = await Promise.resolve().then(() => (init_store(), store_exports));