deepseeker-code 1.0.0 → 1.0.2
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/LICENSE +21 -21
- package/README.md +267 -267
- package/dist/builtin/tdd/SKILL.md +35 -35
- package/dist/cli.mjs +87 -91
- package/package.json +56 -56
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: tdd
|
|
3
|
-
description: 测试驱动开发工作流。当用户要求实现新功能、修复 bug、或明确提到 TDD/测试驱动/先写测试时激活。
|
|
4
|
-
version: 1
|
|
5
|
-
triggers: TDD, 测试驱动, 先写测试, 红绿重构
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# 测试驱动开发(TDD)
|
|
9
|
-
|
|
10
|
-
收到本指令后,对所有代码变更严格遵循 **红-绿-重构** 循环,禁止"先写实现再补测试"。
|
|
11
|
-
|
|
12
|
-
## 步骤
|
|
13
|
-
|
|
14
|
-
1. **探测测试运行器**(不要假设):
|
|
15
|
-
- 调 read_file 读 package.json。若 `scripts.test` 存在且非占位(非 "no test specified"),用它(`npm test` / `npm run test`)。
|
|
16
|
-
- 否则按 devDependencies 判定:vitest→`npx vitest run`;jest→`npx jest`;mocha→`npx mocha`;playwright→`npx playwright test`。
|
|
17
|
-
- Python 项目:pytest→`pytest`;unittest→`python -m pytest`。
|
|
18
|
-
- 都没有:先用 run_command 安装一个(征得用户同意,DANGER 工具会走审批),再继续。
|
|
19
|
-
|
|
20
|
-
2. **红——先写一个会失败的测试**:
|
|
21
|
-
- 针对目标行为写最小测试,描述期望的输入/输出。
|
|
22
|
-
- 调 run_command 跑测试,确认它因"功能未实现"而失败(红)。若意外通过,说明测试无效,重写。
|
|
23
|
-
|
|
24
|
-
3. **绿——写最小实现让测试通过**:
|
|
25
|
-
- 只写让测试通过的最少代码,不要过度设计。
|
|
26
|
-
- 再跑测试,确认全绿。
|
|
27
|
-
|
|
28
|
-
4. **重构——在测试保护下清理**:
|
|
29
|
-
- 改善命名/结构/去重,每次小步重构后重跑测试,保持绿。
|
|
30
|
-
|
|
31
|
-
## 硬约束
|
|
32
|
-
- 每次实现/修复前,先有失败测试;任何"写完再补测试"的念头都要拒绝并向用户说明。
|
|
33
|
-
- 跑测试一律用 run_command,传入探测到的确切命令;禁止臆造命令。
|
|
34
|
-
- 测试失败时,读完整 stderr 定位原因,不要乐观假设成功。
|
|
35
|
-
- 注:run_command 在子 agent 中被禁用(SUBAGENT_DENYLIST),故本技能仅在主 agent 生效——测试应在主上下文执行。
|
|
1
|
+
---
|
|
2
|
+
name: tdd
|
|
3
|
+
description: 测试驱动开发工作流。当用户要求实现新功能、修复 bug、或明确提到 TDD/测试驱动/先写测试时激活。
|
|
4
|
+
version: 1
|
|
5
|
+
triggers: TDD, 测试驱动, 先写测试, 红绿重构
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 测试驱动开发(TDD)
|
|
9
|
+
|
|
10
|
+
收到本指令后,对所有代码变更严格遵循 **红-绿-重构** 循环,禁止"先写实现再补测试"。
|
|
11
|
+
|
|
12
|
+
## 步骤
|
|
13
|
+
|
|
14
|
+
1. **探测测试运行器**(不要假设):
|
|
15
|
+
- 调 read_file 读 package.json。若 `scripts.test` 存在且非占位(非 "no test specified"),用它(`npm test` / `npm run test`)。
|
|
16
|
+
- 否则按 devDependencies 判定:vitest→`npx vitest run`;jest→`npx jest`;mocha→`npx mocha`;playwright→`npx playwright test`。
|
|
17
|
+
- Python 项目:pytest→`pytest`;unittest→`python -m pytest`。
|
|
18
|
+
- 都没有:先用 run_command 安装一个(征得用户同意,DANGER 工具会走审批),再继续。
|
|
19
|
+
|
|
20
|
+
2. **红——先写一个会失败的测试**:
|
|
21
|
+
- 针对目标行为写最小测试,描述期望的输入/输出。
|
|
22
|
+
- 调 run_command 跑测试,确认它因"功能未实现"而失败(红)。若意外通过,说明测试无效,重写。
|
|
23
|
+
|
|
24
|
+
3. **绿——写最小实现让测试通过**:
|
|
25
|
+
- 只写让测试通过的最少代码,不要过度设计。
|
|
26
|
+
- 再跑测试,确认全绿。
|
|
27
|
+
|
|
28
|
+
4. **重构——在测试保护下清理**:
|
|
29
|
+
- 改善命名/结构/去重,每次小步重构后重跑测试,保持绿。
|
|
30
|
+
|
|
31
|
+
## 硬约束
|
|
32
|
+
- 每次实现/修复前,先有失败测试;任何"写完再补测试"的念头都要拒绝并向用户说明。
|
|
33
|
+
- 跑测试一律用 run_command,传入探测到的确切命令;禁止臆造命令。
|
|
34
|
+
- 测试失败时,读完整 stderr 定位原因,不要乐观假设成功。
|
|
35
|
+
- 注:run_command 在子 agent 中被禁用(SUBAGENT_DENYLIST),故本技能仅在主 agent 生效——测试应在主上下文执行。
|
package/dist/cli.mjs
CHANGED
|
@@ -1947,7 +1947,7 @@ import fsSync from "fs";
|
|
|
1947
1947
|
import path9 from "path";
|
|
1948
1948
|
import ignore from "ignore";
|
|
1949
1949
|
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;
|
|
1950
|
+
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
1951
|
var init_guard = __esm({
|
|
1952
1952
|
"../core/src/tool/guard.ts"() {
|
|
1953
1953
|
"use strict";
|
|
@@ -2049,6 +2049,10 @@ var init_guard = __esm({
|
|
|
2049
2049
|
}
|
|
2050
2050
|
return truePhysicalPath;
|
|
2051
2051
|
};
|
|
2052
|
+
resolveReadablePath = (rel) => {
|
|
2053
|
+
const root = getActiveWorkspaceRoot();
|
|
2054
|
+
return path9.resolve(root, rel);
|
|
2055
|
+
};
|
|
2052
2056
|
assertWithinWorkspace = (absPath, base) => {
|
|
2053
2057
|
const root = base ?? getActiveWorkspaceRoot();
|
|
2054
2058
|
let truePhysicalPath = absPath;
|
|
@@ -4544,13 +4548,17 @@ var init_fs = __esm({
|
|
|
4544
4548
|
init_type();
|
|
4545
4549
|
init_tsHost();
|
|
4546
4550
|
init_guard();
|
|
4547
|
-
isSensitiveReadTarget = (
|
|
4548
|
-
const p =
|
|
4551
|
+
isSensitiveReadTarget = (resolvedPath) => {
|
|
4552
|
+
const p = resolvedPath.toLowerCase().replace(/\\/g, "/");
|
|
4549
4553
|
return [
|
|
4550
4554
|
/\.env(\.|$|\/)/,
|
|
4551
4555
|
// .env / .env.local / .env.production
|
|
4552
4556
|
/\.npmrc$/,
|
|
4553
4557
|
// npm 凭证(_authToken)
|
|
4558
|
+
/\.netrc$/,
|
|
4559
|
+
// ~/.netrc 明文 API token(跨界读暴露面增大,补拦)
|
|
4560
|
+
/(^|\/)\.htpasswd$/i,
|
|
4561
|
+
// HTTP 基本认证凭证文件
|
|
4554
4562
|
/\.pem$/,
|
|
4555
4563
|
/\.key$/,
|
|
4556
4564
|
/\.pfx$/,
|
|
@@ -4560,7 +4568,9 @@ var init_fs = __esm({
|
|
|
4560
4568
|
/(^|\/)id_(rsa|ecdsa|ed25519|dsa)(\.pub)?$/,
|
|
4561
4569
|
// SSH 私钥(含子目录路径,如 deploy_keys/id_rsa)
|
|
4562
4570
|
/(^|\/)secrets?\.(json|ya?ml|toml|ini|conf)$/i,
|
|
4563
|
-
/(^|\/)credentials?\.(json|ya?ml|toml|ini|conf)$/i
|
|
4571
|
+
/(^|\/)credentials?\.(json|ya?ml|toml|ini|conf)$/i,
|
|
4572
|
+
/(^|\/)credentials?$/i
|
|
4573
|
+
// 无扩展名凭证文件(AWS ~/.aws/credentials 等)
|
|
4564
4574
|
].some((re) => re.test(p));
|
|
4565
4575
|
};
|
|
4566
4576
|
stripReadFileLineNumbers = (s) => {
|
|
@@ -4607,8 +4617,8 @@ var init_fs = __esm({
|
|
|
4607
4617
|
await walk(wsRoot);
|
|
4608
4618
|
return removed;
|
|
4609
4619
|
};
|
|
4610
|
-
assertReadable = async (
|
|
4611
|
-
if (isSensitiveReadTarget(
|
|
4620
|
+
assertReadable = async (absPath, displayPath) => {
|
|
4621
|
+
if (isSensitiveReadTarget(absPath)) {
|
|
4612
4622
|
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
4623
|
}
|
|
4614
4624
|
return null;
|
|
@@ -4682,7 +4692,7 @@ var init_fs = __esm({
|
|
|
4682
4692
|
parameters: {
|
|
4683
4693
|
type: "object",
|
|
4684
4694
|
properties: {
|
|
4685
|
-
path: { type: "string", description: "\u6587\u4EF6\u76F8\u5BF9\u8DEF\u5F84" },
|
|
4695
|
+
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
4696
|
start_line: { type: "number", description: "\u8D77\u59CB\u884C\u53F7\uFF08\u4ECE 1 \u5F00\u59CB\uFF0C\u9ED8\u8BA4 1\uFF09" },
|
|
4687
4697
|
end_line: { type: "number", description: "\u7ED3\u675F\u884C\u53F7\uFF08\u9ED8\u8BA4\u6700\u591A\u5F80\u540E\u8BFB 2000 \u884C\uFF09" }
|
|
4688
4698
|
},
|
|
@@ -4697,14 +4707,12 @@ var init_fs = __esm({
|
|
|
4697
4707
|
privacyMaskingRules: maskSecretsInContent,
|
|
4698
4708
|
async execute(args) {
|
|
4699
4709
|
try {
|
|
4700
|
-
const absPath =
|
|
4710
|
+
const absPath = resolveReadablePath(args.path);
|
|
4701
4711
|
const lowerExt = absPath.toLowerCase();
|
|
4702
4712
|
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
4713
|
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
4714
|
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
|
|
4706
|
-
const relForCheck = path15.relative(checkBase, absPath).replace(/\\/g, "/");
|
|
4707
|
-
const readBlock = await assertReadable(relForCheck, args.path, checkBase);
|
|
4715
|
+
const readBlock = await assertReadable(absPath, args.path);
|
|
4708
4716
|
if (readBlock) return readBlock;
|
|
4709
4717
|
const start = args.start_line ? Math.max(1, args.start_line) : 1;
|
|
4710
4718
|
const maxLinesToRead = 2e3;
|
|
@@ -5052,10 +5060,8 @@ ${args.new_str}`,
|
|
|
5052
5060
|
privacyMaskingRules: maskSecretsInContent,
|
|
5053
5061
|
async execute(args) {
|
|
5054
5062
|
try {
|
|
5055
|
-
const absPath =
|
|
5056
|
-
const
|
|
5057
|
-
const relForCheck = path15.relative(checkBase, absPath).replace(/\\/g, "/");
|
|
5058
|
-
const readBlock = await assertReadable(relForCheck, args.path, checkBase);
|
|
5063
|
+
const absPath = resolveReadablePath(args.path);
|
|
5064
|
+
const readBlock = await assertReadable(absPath, args.path);
|
|
5059
5065
|
if (readBlock) return readBlock;
|
|
5060
5066
|
const statForSize = await fs12.stat(absPath);
|
|
5061
5067
|
if (statForSize.size > 1024 * 1024) {
|
|
@@ -5219,7 +5225,7 @@ var init_search = __esm({
|
|
|
5219
5225
|
});
|
|
5220
5226
|
if (hit) return hit;
|
|
5221
5227
|
}
|
|
5222
|
-
return
|
|
5228
|
+
return resolveReadablePath(args.path);
|
|
5223
5229
|
};
|
|
5224
5230
|
const searchRoot = resolveSearchRoot().replace(/\\/g, "/");
|
|
5225
5231
|
const rgArgs = [
|
|
@@ -5589,7 +5595,7 @@ var init_glob = __esm({
|
|
|
5589
5595
|
const cleanPattern = (args.pattern || "").trim();
|
|
5590
5596
|
if (!cleanPattern) return "\u274C [Glob\u5931\u8D25]\uFF1A\u4F20\u5165\u7684\u68C0\u7D22 pattern \u4E0D\u80FD\u4E3A\u7A7A\u3002";
|
|
5591
5597
|
const activeRoot = ctx?.cwd ?? getActiveWorkspaceRoot();
|
|
5592
|
-
const root = args.path ?
|
|
5598
|
+
const root = args.path ? resolveReadablePath(args.path) : activeRoot;
|
|
5593
5599
|
const re = globToRegex2(cleanPattern);
|
|
5594
5600
|
await initializeWorkspaceIgnore();
|
|
5595
5601
|
const hits = [];
|
|
@@ -6506,9 +6512,7 @@ var init_typescript = __esm({
|
|
|
6506
6512
|
return abs.replace(/\\/g, "/").split("/").slice(-3).join("/");
|
|
6507
6513
|
};
|
|
6508
6514
|
precheck = async (displayPath, absPath) => {
|
|
6509
|
-
const
|
|
6510
|
-
const relForCheck = path19.relative(checkBase, absPath).replace(/\\/g, "/");
|
|
6511
|
-
const readBlock = await assertReadable(relForCheck, displayPath, checkBase);
|
|
6515
|
+
const readBlock = await assertReadable(absPath, displayPath);
|
|
6512
6516
|
if (readBlock) return readBlock;
|
|
6513
6517
|
const stat = await fs16.stat(absPath);
|
|
6514
6518
|
if (stat.size > MAX_FILE_BYTES) {
|
|
@@ -6540,7 +6544,7 @@ var init_typescript = __esm({
|
|
|
6540
6544
|
try {
|
|
6541
6545
|
const TS = await getTs();
|
|
6542
6546
|
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(
|
|
6547
|
+
const absPath = realpathNative(resolveReadablePath(args.path));
|
|
6544
6548
|
const block = await precheck(args.path, absPath);
|
|
6545
6549
|
if (block) return block;
|
|
6546
6550
|
const { ls } = await getLanguageService(TS, absPath, { checkJs: args.check_js });
|
|
@@ -6612,7 +6616,7 @@ ${body}${tail}`;
|
|
|
6612
6616
|
try {
|
|
6613
6617
|
const TS = await getTs();
|
|
6614
6618
|
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(
|
|
6619
|
+
const absPath = realpathNative(resolveReadablePath(displayPath));
|
|
6616
6620
|
const block = await precheck(displayPath, absPath);
|
|
6617
6621
|
if (block) return block;
|
|
6618
6622
|
const { ls } = await getLanguageService(TS, absPath);
|
|
@@ -8186,7 +8190,6 @@ ${lines.join("\n")}`;
|
|
|
8186
8190
|
});
|
|
8187
8191
|
|
|
8188
8192
|
// ../core/src/tool/registry/spreadsheet.ts
|
|
8189
|
-
import path28 from "path";
|
|
8190
8193
|
var getExcelJs, colLetter, cellToText, esc, spreadsheetTools;
|
|
8191
8194
|
var init_spreadsheet = __esm({
|
|
8192
8195
|
"../core/src/tool/registry/spreadsheet.ts"() {
|
|
@@ -8244,10 +8247,8 @@ var init_spreadsheet = __esm({
|
|
|
8244
8247
|
privacyMaskingRules: maskSecretsInContent,
|
|
8245
8248
|
async execute(args) {
|
|
8246
8249
|
try {
|
|
8247
|
-
const absPath =
|
|
8248
|
-
const
|
|
8249
|
-
const relForCheck = path28.relative(checkBase, absPath).replace(/\\/g, "/");
|
|
8250
|
-
const readBlock = await assertReadable(relForCheck, args.path, checkBase);
|
|
8250
|
+
const absPath = resolveReadablePath(args.path);
|
|
8251
|
+
const readBlock = await assertReadable(absPath, args.path);
|
|
8251
8252
|
if (readBlock) return readBlock;
|
|
8252
8253
|
if (!absPath.toLowerCase().endsWith(".xlsx")) {
|
|
8253
8254
|
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 +8305,6 @@ var init_spreadsheet = __esm({
|
|
|
8304
8305
|
});
|
|
8305
8306
|
|
|
8306
8307
|
// ../core/src/tool/registry/document.ts
|
|
8307
|
-
import path29 from "path";
|
|
8308
8308
|
import fs26 from "fs/promises";
|
|
8309
8309
|
var getMammoth, getUnpdf, documentTools;
|
|
8310
8310
|
var init_document = __esm({
|
|
@@ -8340,10 +8340,8 @@ var init_document = __esm({
|
|
|
8340
8340
|
privacyMaskingRules: maskSecretsInContent,
|
|
8341
8341
|
async execute(args) {
|
|
8342
8342
|
try {
|
|
8343
|
-
const absPath =
|
|
8344
|
-
const
|
|
8345
|
-
const relForCheck = path29.relative(checkBase, absPath).replace(/\\/g, "/");
|
|
8346
|
-
const readBlock = await assertReadable(relForCheck, args.path, checkBase);
|
|
8343
|
+
const absPath = resolveReadablePath(args.path);
|
|
8344
|
+
const readBlock = await assertReadable(absPath, args.path);
|
|
8347
8345
|
if (readBlock) return readBlock;
|
|
8348
8346
|
if (!absPath.toLowerCase().endsWith(".docx")) {
|
|
8349
8347
|
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 +8387,8 @@ var init_document = __esm({
|
|
|
8389
8387
|
privacyMaskingRules: maskSecretsInContent,
|
|
8390
8388
|
async execute(args) {
|
|
8391
8389
|
try {
|
|
8392
|
-
const absPath =
|
|
8393
|
-
const
|
|
8394
|
-
const relForCheck = path29.relative(checkBase, absPath).replace(/\\/g, "/");
|
|
8395
|
-
const readBlock = await assertReadable(relForCheck, args.path, checkBase);
|
|
8390
|
+
const absPath = resolveReadablePath(args.path);
|
|
8391
|
+
const readBlock = await assertReadable(absPath, args.path);
|
|
8396
8392
|
if (readBlock) return readBlock;
|
|
8397
8393
|
if (!absPath.toLowerCase().endsWith(".pdf")) {
|
|
8398
8394
|
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 +8600,7 @@ var init_backgroundTool = __esm({
|
|
|
8604
8600
|
});
|
|
8605
8601
|
|
|
8606
8602
|
// ../core/src/tool/autoPermission.ts
|
|
8607
|
-
import
|
|
8603
|
+
import path28 from "path";
|
|
8608
8604
|
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
8605
|
var init_autoPermission = __esm({
|
|
8610
8606
|
"../core/src/tool/autoPermission.ts"() {
|
|
@@ -8739,9 +8735,9 @@ var init_autoPermission = __esm({
|
|
|
8739
8735
|
isWithinWorkspace = (p, cwd) => {
|
|
8740
8736
|
if (!p || !cwd) return false;
|
|
8741
8737
|
try {
|
|
8742
|
-
const abs =
|
|
8743
|
-
const rel =
|
|
8744
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
8738
|
+
const abs = path28.isAbsolute(p) ? p : path28.resolve(cwd, p);
|
|
8739
|
+
const rel = path28.relative(cwd, abs);
|
|
8740
|
+
return rel === "" || !rel.startsWith("..") && !path28.isAbsolute(rel);
|
|
8745
8741
|
} catch {
|
|
8746
8742
|
return false;
|
|
8747
8743
|
}
|
|
@@ -9887,7 +9883,7 @@ var init_subagent = __esm({
|
|
|
9887
9883
|
|
|
9888
9884
|
// ../core/src/hooks/loader.ts
|
|
9889
9885
|
import fs27 from "fs/promises";
|
|
9890
|
-
import
|
|
9886
|
+
import path29 from "path";
|
|
9891
9887
|
var readHooksConfig, appendValidated, validateRule, parseAgentDecision, compileRule2, loadHooks, initHooks;
|
|
9892
9888
|
var init_loader4 = __esm({
|
|
9893
9889
|
"../core/src/hooks/loader.ts"() {
|
|
@@ -9902,9 +9898,9 @@ var init_loader4 = __esm({
|
|
|
9902
9898
|
readHooksConfig = async (includeProject) => {
|
|
9903
9899
|
const merged = {};
|
|
9904
9900
|
const paths = [
|
|
9905
|
-
|
|
9901
|
+
path29.join(appConfig.dataDir, "settings.json"),
|
|
9906
9902
|
// 全局用户级
|
|
9907
|
-
...includeProject ? [
|
|
9903
|
+
...includeProject ? [path29.join(process.cwd(), ".deepseeker-code", "settings.json")] : []
|
|
9908
9904
|
// 项目级(叠加);未信任时省略
|
|
9909
9905
|
];
|
|
9910
9906
|
for (const configPath of paths) {
|
|
@@ -10213,7 +10209,7 @@ ${m.context}`;
|
|
|
10213
10209
|
|
|
10214
10210
|
// ../core/src/skills/loader.ts
|
|
10215
10211
|
import fs28 from "fs/promises";
|
|
10216
|
-
import
|
|
10212
|
+
import path30 from "path";
|
|
10217
10213
|
import { fileURLToPath } from "url";
|
|
10218
10214
|
var BUILTIN_DIR, SOURCES2, MAX_SKILL_BODY_BYTES, splitList, parseSkillAt, loadSkills, initSkills;
|
|
10219
10215
|
var init_loader5 = __esm({
|
|
@@ -10224,11 +10220,11 @@ var init_loader5 = __esm({
|
|
|
10224
10220
|
init_registry3();
|
|
10225
10221
|
init_skill();
|
|
10226
10222
|
init_registry2();
|
|
10227
|
-
BUILTIN_DIR =
|
|
10223
|
+
BUILTIN_DIR = path30.join(path30.dirname(fileURLToPath(import.meta.url)), "builtin");
|
|
10228
10224
|
SOURCES2 = [
|
|
10229
10225
|
{ dir: BUILTIN_DIR, source: "builtin" },
|
|
10230
|
-
{ dir:
|
|
10231
|
-
{ dir:
|
|
10226
|
+
{ dir: path30.join(appConfig.dataDir, "skills"), source: "global" },
|
|
10227
|
+
{ dir: path30.join(process.cwd(), ".deepseeker-code", "skills"), source: "project" }
|
|
10232
10228
|
];
|
|
10233
10229
|
MAX_SKILL_BODY_BYTES = 64 * 1024;
|
|
10234
10230
|
splitList = (raw) => (raw ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
@@ -10274,7 +10270,7 @@ var init_loader5 = __esm({
|
|
|
10274
10270
|
loadSkills = async (includeProject) => {
|
|
10275
10271
|
const picked = await scanSources(
|
|
10276
10272
|
filterSources(SOURCES2, includeProject),
|
|
10277
|
-
(e, dir) => e.isDirectory() ?
|
|
10273
|
+
(e, dir) => e.isDirectory() ? path30.join(dir, e.name, "SKILL.md") : void 0,
|
|
10278
10274
|
parseSkillAt
|
|
10279
10275
|
);
|
|
10280
10276
|
for (const { item } of picked) registerSkill(item);
|
|
@@ -10306,7 +10302,7 @@ var init_loader5 = __esm({
|
|
|
10306
10302
|
|
|
10307
10303
|
// ../core/src/agents/loader.ts
|
|
10308
10304
|
import fs29 from "fs/promises";
|
|
10309
|
-
import
|
|
10305
|
+
import path31 from "path";
|
|
10310
10306
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
10311
10307
|
var BUILTIN_DIR2, SOURCES3, parseAgentAt, initAgents;
|
|
10312
10308
|
var init_loader6 = __esm({
|
|
@@ -10316,11 +10312,11 @@ var init_loader6 = __esm({
|
|
|
10316
10312
|
init_frontmatter();
|
|
10317
10313
|
init_registry4();
|
|
10318
10314
|
init_registry2();
|
|
10319
|
-
BUILTIN_DIR2 =
|
|
10315
|
+
BUILTIN_DIR2 = path31.join(path31.dirname(fileURLToPath2(import.meta.url)), "builtin");
|
|
10320
10316
|
SOURCES3 = [
|
|
10321
10317
|
{ dir: BUILTIN_DIR2, source: "builtin" },
|
|
10322
|
-
{ dir:
|
|
10323
|
-
{ dir:
|
|
10318
|
+
{ dir: path31.join(appConfig.dataDir, "agents"), source: "global" },
|
|
10319
|
+
{ dir: path31.join(process.cwd(), ".deepseeker-code", "agents"), source: "project" }
|
|
10324
10320
|
];
|
|
10325
10321
|
parseAgentAt = async (file, dir, source) => {
|
|
10326
10322
|
let raw;
|
|
@@ -10360,7 +10356,7 @@ var init_loader6 = __esm({
|
|
|
10360
10356
|
const known = new Set(into.map((t) => t.function.name));
|
|
10361
10357
|
const picked = await scanSources(
|
|
10362
10358
|
filterSources(SOURCES3, includeProject),
|
|
10363
|
-
(e, dir) => e.isFile() && e.name.endsWith(".agent.md") ?
|
|
10359
|
+
(e, dir) => e.isFile() && e.name.endsWith(".agent.md") ? path31.join(dir, e.name) : void 0,
|
|
10364
10360
|
parseAgentAt
|
|
10365
10361
|
);
|
|
10366
10362
|
for (const { item: m, file, source } of picked) {
|
|
@@ -10398,7 +10394,7 @@ var init_registry7 = __esm({
|
|
|
10398
10394
|
|
|
10399
10395
|
// ../core/src/commands/loader.ts
|
|
10400
10396
|
import fs30 from "fs/promises";
|
|
10401
|
-
import
|
|
10397
|
+
import path32 from "path";
|
|
10402
10398
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
10403
10399
|
var BUILTIN_DIR3, SOURCES4, MAX_COMMAND_BODY_BYTES, parseCommandAt, loadCommands, initCommands;
|
|
10404
10400
|
var init_loader7 = __esm({
|
|
@@ -10408,11 +10404,11 @@ var init_loader7 = __esm({
|
|
|
10408
10404
|
init_frontmatter();
|
|
10409
10405
|
init_registry7();
|
|
10410
10406
|
init_registry2();
|
|
10411
|
-
BUILTIN_DIR3 =
|
|
10407
|
+
BUILTIN_DIR3 = path32.join(path32.dirname(fileURLToPath3(import.meta.url)), "builtin");
|
|
10412
10408
|
SOURCES4 = [
|
|
10413
10409
|
{ dir: BUILTIN_DIR3, source: "builtin" },
|
|
10414
|
-
{ dir:
|
|
10415
|
-
{ dir:
|
|
10410
|
+
{ dir: path32.join(appConfig.dataDir, "commands"), source: "global" },
|
|
10411
|
+
{ dir: path32.join(process.cwd(), ".deepseeker-code", "commands"), source: "project" }
|
|
10416
10412
|
];
|
|
10417
10413
|
MAX_COMMAND_BODY_BYTES = 64 * 1024;
|
|
10418
10414
|
parseCommandAt = async (file, _dir, source) => {
|
|
@@ -10429,7 +10425,7 @@ var init_loader7 = __esm({
|
|
|
10429
10425
|
}
|
|
10430
10426
|
const name = parsed.frontmatter.name;
|
|
10431
10427
|
const description = parsed.frontmatter.description;
|
|
10432
|
-
const fallbackName =
|
|
10428
|
+
const fallbackName = path32.basename(file, ".md");
|
|
10433
10429
|
const finalName = name || fallbackName;
|
|
10434
10430
|
if (!description) {
|
|
10435
10431
|
console.warn(`\u26A0\uFE0F [commands] \u7F3A\u5C11 description\uFF08${file}\uFF09\uFF0C\u5DF2\u8DF3\u8FC7`);
|
|
@@ -10455,7 +10451,7 @@ var init_loader7 = __esm({
|
|
|
10455
10451
|
loadCommands = async (includeProject) => {
|
|
10456
10452
|
const picked = await scanSources(
|
|
10457
10453
|
filterSources(SOURCES4, includeProject),
|
|
10458
|
-
(e, dir) => e.isFile() && e.name.endsWith(".md") ?
|
|
10454
|
+
(e, dir) => e.isFile() && e.name.endsWith(".md") ? path32.join(dir, e.name) : void 0,
|
|
10459
10455
|
parseCommandAt
|
|
10460
10456
|
);
|
|
10461
10457
|
for (const { item } of picked) registerCommand(item);
|
|
@@ -10474,7 +10470,7 @@ var init_loader7 = __esm({
|
|
|
10474
10470
|
|
|
10475
10471
|
// ../core/src/outputStyles/loader.ts
|
|
10476
10472
|
import fs31 from "fs/promises";
|
|
10477
|
-
import
|
|
10473
|
+
import path33 from "path";
|
|
10478
10474
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
10479
10475
|
var BUILTIN_DIR4, MAX_STYLE_BODY_BYTES, SOURCES5, parseStyleAt, loadOutputStyles, initOutputStyles;
|
|
10480
10476
|
var init_loader8 = __esm({
|
|
@@ -10484,12 +10480,12 @@ var init_loader8 = __esm({
|
|
|
10484
10480
|
init_frontmatter();
|
|
10485
10481
|
init_registry5();
|
|
10486
10482
|
init_registry2();
|
|
10487
|
-
BUILTIN_DIR4 =
|
|
10483
|
+
BUILTIN_DIR4 = path33.join(path33.dirname(fileURLToPath4(import.meta.url)), "builtin");
|
|
10488
10484
|
MAX_STYLE_BODY_BYTES = 64 * 1024;
|
|
10489
10485
|
SOURCES5 = [
|
|
10490
10486
|
{ dir: BUILTIN_DIR4, source: "builtin" },
|
|
10491
|
-
{ dir:
|
|
10492
|
-
{ dir:
|
|
10487
|
+
{ dir: path33.join(appConfig.dataDir, "output-styles"), source: "global" },
|
|
10488
|
+
{ dir: path33.join(process.cwd(), ".deepseeker-code", "output-styles"), source: "project" }
|
|
10493
10489
|
];
|
|
10494
10490
|
parseStyleAt = async (file, _dir, source) => {
|
|
10495
10491
|
let raw;
|
|
@@ -10526,7 +10522,7 @@ var init_loader8 = __esm({
|
|
|
10526
10522
|
loadOutputStyles = async (includeProject) => {
|
|
10527
10523
|
const picked = await scanSources(
|
|
10528
10524
|
filterSources(SOURCES5, includeProject),
|
|
10529
|
-
(e, dir) => e.isFile() && e.name.endsWith(".md") ?
|
|
10525
|
+
(e, dir) => e.isFile() && e.name.endsWith(".md") ? path33.join(dir, e.name) : void 0,
|
|
10530
10526
|
parseStyleAt
|
|
10531
10527
|
);
|
|
10532
10528
|
for (const { item } of picked) registerOutputStyle(item);
|
|
@@ -10598,7 +10594,7 @@ var init_bootstrap = __esm({
|
|
|
10598
10594
|
|
|
10599
10595
|
// ../core/src/statusLine/config.ts
|
|
10600
10596
|
import fs32 from "fs/promises";
|
|
10601
|
-
import
|
|
10597
|
+
import path34 from "path";
|
|
10602
10598
|
var parseBlock, readStatusLineConfig;
|
|
10603
10599
|
var init_config2 = __esm({
|
|
10604
10600
|
"../core/src/statusLine/config.ts"() {
|
|
@@ -10614,9 +10610,9 @@ var init_config2 = __esm({
|
|
|
10614
10610
|
};
|
|
10615
10611
|
readStatusLineConfig = async (includeProject) => {
|
|
10616
10612
|
const paths = [
|
|
10617
|
-
|
|
10613
|
+
path34.join(appConfig.dataDir, "settings.json"),
|
|
10618
10614
|
// 全局用户级
|
|
10619
|
-
...includeProject ? [
|
|
10615
|
+
...includeProject ? [path34.join(process.cwd(), ".deepseeker-code", "settings.json")] : []
|
|
10620
10616
|
// 项目级(覆盖);未信任时省略
|
|
10621
10617
|
];
|
|
10622
10618
|
let result = null;
|
|
@@ -10644,7 +10640,7 @@ var init_config2 = __esm({
|
|
|
10644
10640
|
// ../core/src/statusLine/runner.ts
|
|
10645
10641
|
import { spawn as spawn5 } from "child_process";
|
|
10646
10642
|
import fs33 from "fs";
|
|
10647
|
-
import
|
|
10643
|
+
import path35 from "path";
|
|
10648
10644
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
10649
10645
|
var STATUSLINE_TIMEOUT_MS, cachedVersion, runStatusLine;
|
|
10650
10646
|
var init_runner = __esm({
|
|
@@ -10653,11 +10649,11 @@ var init_runner = __esm({
|
|
|
10653
10649
|
init_guard();
|
|
10654
10650
|
STATUSLINE_TIMEOUT_MS = 3e3;
|
|
10655
10651
|
try {
|
|
10656
|
-
const here =
|
|
10652
|
+
const here = path35.dirname(fileURLToPath5(import.meta.url));
|
|
10657
10653
|
const candidates = [
|
|
10658
|
-
|
|
10654
|
+
path35.join(here, "../../../package.json"),
|
|
10659
10655
|
// src/core/package.json
|
|
10660
|
-
|
|
10656
|
+
path35.join(here, "../../../../package.json")
|
|
10661
10657
|
// 仓库根 package.json
|
|
10662
10658
|
];
|
|
10663
10659
|
for (const p of candidates) {
|
|
@@ -10721,7 +10717,7 @@ var init_createModel = __esm({
|
|
|
10721
10717
|
});
|
|
10722
10718
|
|
|
10723
10719
|
// ../core/src/observability/store.ts
|
|
10724
|
-
import
|
|
10720
|
+
import path36 from "path";
|
|
10725
10721
|
import fs34 from "fs/promises";
|
|
10726
10722
|
var getTraceDirPath, getTracePath, tracePathCache, ensuredTraceDirs, ensureTraceDir, getGlobalClockPath, getTraceStorePath;
|
|
10727
10723
|
var init_store3 = __esm({
|
|
@@ -10732,10 +10728,10 @@ var init_store3 = __esm({
|
|
|
10732
10728
|
init_common();
|
|
10733
10729
|
getTraceDirPath = (mainTraceId) => {
|
|
10734
10730
|
assertSafeSessionId(mainTraceId, "traceId");
|
|
10735
|
-
return
|
|
10731
|
+
return path36.join(appConfig.dataDir, "trace", appConfig.userWorkspaceDir, getFileName(mainTraceId));
|
|
10736
10732
|
};
|
|
10737
10733
|
getTracePath = () => {
|
|
10738
|
-
return
|
|
10734
|
+
return path36.join(appConfig.dataDir, "trace");
|
|
10739
10735
|
};
|
|
10740
10736
|
tracePathCache = /* @__PURE__ */ new Map();
|
|
10741
10737
|
ensuredTraceDirs = /* @__PURE__ */ new Set();
|
|
@@ -10746,7 +10742,7 @@ var init_store3 = __esm({
|
|
|
10746
10742
|
ensuredTraceDirs.add(dir);
|
|
10747
10743
|
};
|
|
10748
10744
|
getGlobalClockPath = () => {
|
|
10749
|
-
return
|
|
10745
|
+
return path36.join(getTracePath(), "trace-cleanup-clock.json");
|
|
10750
10746
|
};
|
|
10751
10747
|
getTraceStorePath = async (mainTraceId) => {
|
|
10752
10748
|
assertSafeSessionId(mainTraceId, "traceId");
|
|
@@ -10764,7 +10760,7 @@ var init_store3 = __esm({
|
|
|
10764
10760
|
const todayStr = getTodayDateString();
|
|
10765
10761
|
fileName = `trace-${todayStr}__${rootId}.jsonl`;
|
|
10766
10762
|
}
|
|
10767
|
-
const resolved =
|
|
10763
|
+
const resolved = path36.join(dir, fileName);
|
|
10768
10764
|
tracePathCache.set(rootId, resolved);
|
|
10769
10765
|
return resolved;
|
|
10770
10766
|
};
|
|
@@ -10773,7 +10769,7 @@ var init_store3 = __esm({
|
|
|
10773
10769
|
|
|
10774
10770
|
// ../core/src/observability/trace.ts
|
|
10775
10771
|
import fs35 from "fs/promises";
|
|
10776
|
-
import
|
|
10772
|
+
import path37 from "path";
|
|
10777
10773
|
async function emitTrace(base) {
|
|
10778
10774
|
const event = {
|
|
10779
10775
|
sessionId: base.sessionId,
|
|
@@ -10827,7 +10823,7 @@ async function maybeCleanupAfterAppend(sessionId) {
|
|
|
10827
10823
|
lastSizeCleanupAt2 = now;
|
|
10828
10824
|
diskLastCleanupAt2 = now;
|
|
10829
10825
|
const clockPath = getGlobalClockPath();
|
|
10830
|
-
await fs35.mkdir(
|
|
10826
|
+
await fs35.mkdir(path37.dirname(clockPath), { recursive: true });
|
|
10831
10827
|
await fs35.writeFile(clockPath, JSON.stringify({ lastCleanupAt: now, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), "utf-8");
|
|
10832
10828
|
if (deletedCount > 0) {
|
|
10833
10829
|
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 +10850,12 @@ async function cleanupOldTraceFiles() {
|
|
|
10854
10850
|
}
|
|
10855
10851
|
const re = /^trace-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
|
|
10856
10852
|
for (const relativePath of relativePaths) {
|
|
10857
|
-
const fileName =
|
|
10853
|
+
const fileName = path37.basename(relativePath);
|
|
10858
10854
|
const m = fileName.match(re);
|
|
10859
10855
|
if (!m) continue;
|
|
10860
10856
|
const fileBornDay = /* @__PURE__ */ new Date(`${m[1]}T00:00:00`);
|
|
10861
10857
|
if (fileBornDay >= cutoff) continue;
|
|
10862
|
-
const fullPath =
|
|
10858
|
+
const fullPath = path37.join(dir, relativePath);
|
|
10863
10859
|
try {
|
|
10864
10860
|
const st = await fs35.stat(fullPath);
|
|
10865
10861
|
if (now - st.mtimeMs < ACTIVE_GRACE_MS2) continue;
|
|
@@ -10881,11 +10877,11 @@ async function evictOldestForSize2(targetBytes) {
|
|
|
10881
10877
|
const re = /^trace-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
|
|
10882
10878
|
const candidates = [];
|
|
10883
10879
|
for (const relativePath of relativePaths) {
|
|
10884
|
-
const fileName =
|
|
10880
|
+
const fileName = path37.basename(relativePath);
|
|
10885
10881
|
if (!re.test(fileName)) continue;
|
|
10886
10882
|
try {
|
|
10887
|
-
const st = await fs35.stat(
|
|
10888
|
-
candidates.push({ mtime: st.mtimeMs, fullPath:
|
|
10883
|
+
const st = await fs35.stat(path37.join(dir, relativePath));
|
|
10884
|
+
candidates.push({ mtime: st.mtimeMs, fullPath: path37.join(dir, relativePath), size: st.size });
|
|
10889
10885
|
} catch {
|
|
10890
10886
|
}
|
|
10891
10887
|
}
|
|
@@ -11028,11 +11024,11 @@ var init_systemPrompt = __esm({
|
|
|
11028
11024
|
"../core/src/agent/systemPrompt.ts"() {
|
|
11029
11025
|
"use strict";
|
|
11030
11026
|
init_planMode();
|
|
11031
|
-
buildSystemPrompt = (p) => `\u4F60\u662F ${p.displayName}\u2014\u2014\u4E00\u4E2A\u57FA\u4E8E ${p.modelLabel} \u5927\u6A21\u578B\u7684\u7EC8\u7AEF AI \u7F16\u7A0B\u52A9\u624B\
|
|
11027
|
+
buildSystemPrompt = (p) => `\u4F60\u662F ${p.displayName}\u2014\u2014\u4E00\u4E2A\u57FA\u4E8E ${p.modelLabel} \u5927\u6A21\u578B\u7684\u7EC8\u7AEF AI \u7F16\u7A0B\u52A9\u624B\u3002\u4F60\u8FD0\u884C\u5728\u7528\u6237\u7684\u7EC8\u7AEF\u4E2D\uFF0C\u80FD\u8C03\u7528\u4E00\u7CFB\u5217\u5DE5\u5177\uFF08\u8BFB\u5199\u6587\u4EF6\u3001\u641C\u7D22\u4EE3\u7801\u3001\u6267\u884C\u547D\u4EE4\u3001\u8054\u7F51\u68C0\u7D22\u3001\u4EFB\u52A1\u7BA1\u7406\u7B49\uFF09\u76F4\u63A5\u5728\u7528\u6237\u5DE5\u4F5C\u533A\u5B8C\u6210\u5F00\u53D1\u4EFB\u52A1\u3002
|
|
11032
11028
|
|
|
11033
11029
|
\u3010\u8EAB\u4EFD\u3011
|
|
11034
11030
|
- \u4F60\u7684\u540D\u5B57\u662F ${p.displayName}\uFF0C\u7531 ${p.modelLabel} \u6A21\u578B\u9A71\u52A8\u3002
|
|
11035
|
-
- \u88AB\u95EE"\u4F60\u662F\u8C01"\u65F6\u636E\u5B9E\u56DE\u7B54\uFF1A\u4F60\u662F ${p.displayName}\u3002\u5207\u52FF\u81EA\u79F0
|
|
11031
|
+
- \u88AB\u95EE"\u4F60\u662F\u8C01"\u65F6\u636E\u5B9E\u56DE\u7B54\uFF1A\u4F60\u662F ${p.displayName}\u3002\u5207\u52FF\u81EA\u79F0 ChatGPT\u3001GPT \u6216\u4EFB\u4F55\u5176\u4ED6\u516C\u53F8\u7684\u5927\u6A21\u578B/AI \u4EA7\u54C1\u3002
|
|
11036
11032
|
|
|
11037
11033
|
\u3010\u56DE\u7B54\u51C6\u5219 / \u5B8C\u6210\u5224\u5B9A\u3011
|
|
11038
11034
|
- \u4EFB\u52A1\u5B8C\u6210\u540E\u76F4\u63A5\u7528\u81EA\u7136\u8BED\u8A00\u7ED9\u51FA\u6700\u7EC8\u7B54\u6848\uFF0C\u4E0D\u8981\u518D\u8C03\u7528\u5DE5\u5177\u3002
|
|
@@ -11072,7 +11068,7 @@ ${PLAN_MODE_AUTO_ENTER_HINT}
|
|
|
11072
11068
|
});
|
|
11073
11069
|
|
|
11074
11070
|
// ../core/src/serve/chatProcessing.ts
|
|
11075
|
-
import
|
|
11071
|
+
import path38 from "path";
|
|
11076
11072
|
import fs36 from "fs";
|
|
11077
11073
|
var handleUnifiedChat;
|
|
11078
11074
|
var init_chatProcessing = __esm({
|
|
@@ -11130,14 +11126,14 @@ ${inject}`;
|
|
|
11130
11126
|
activeReal = fs36.realpathSync(activeReal);
|
|
11131
11127
|
} catch {
|
|
11132
11128
|
}
|
|
11133
|
-
const lines = roots.map((r) => `- ${
|
|
11129
|
+
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
11130
|
sysPrompt = sysPrompt + `
|
|
11135
11131
|
|
|
11136
11132
|
\u3010\u5DE5\u4F5C\u533A\uFF08\u591A\u9879\u76EE\uFF09\u3011
|
|
11137
11133
|
\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
11134
|
${lines.join("\n")}
|
|
11139
|
-
\u2605 \u8DEF\u5F84\u951A\u5B9A\u94C1\u5F8B\uFF1A\u5DE5\u5177\u7F3A\u7701\u53EA\u4F5C\u7528\u4E8E\u9ED8\u8BA4\u6839\uFF08${
|
|
11140
|
-
\u6CE8\u610F\uFF1A\u9879\u76EE\u7EA7\u914D\u7F6E\uFF08.deepseeker-code/\uFF09\u4EC5\u5728\u9ED8\u8BA4\u6839 ${
|
|
11135
|
+
\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
|
|
11136
|
+
\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
11137
|
}
|
|
11142
11138
|
let replyText = "";
|
|
11143
11139
|
try {
|
|
@@ -13306,7 +13302,7 @@ init_prefs();
|
|
|
13306
13302
|
init_trust();
|
|
13307
13303
|
import { render } from "ink";
|
|
13308
13304
|
import os4 from "os";
|
|
13309
|
-
import
|
|
13305
|
+
import path39 from "path";
|
|
13310
13306
|
import { emitKeypressEvents } from "node:readline";
|
|
13311
13307
|
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
13312
13308
|
var parseArgs = (argv) => {
|
|
@@ -13432,7 +13428,7 @@ var main = async () => {
|
|
|
13432
13428
|
process.stdout.write("\x1B[2J\x1B[3J\x1B[1;1H");
|
|
13433
13429
|
const cwdIsHome = () => {
|
|
13434
13430
|
try {
|
|
13435
|
-
return
|
|
13431
|
+
return path39.resolve(cwd).toLowerCase() === path39.resolve(os4.homedir()).toLowerCase();
|
|
13436
13432
|
} catch {
|
|
13437
13433
|
return false;
|
|
13438
13434
|
}
|